My question is about cryptoAPI interface.
Look, CertEnumSystemStoreLocation() is a function to enumerate all certificate store locations available in system. It returns (using callback) enumerated location as wide string (LPCWSTR).
CertEnumSystemStore() enumerates stores by the given location. It takes integer constant for location (DWORD) as argument.
I tried to enumerate locations and the result was a list of strings, that semantically is equal to the list of DWORD location constants from CryptoAPI import module.
And my question is: what should i do to translate wide string representation of store location to DWORD constant? Is there a cryptoAPI function (or, at least, commonly used method) for it?
It looks like the dwFlags passed to your CertEnumSystemStoreLocationCallback callback function actually gives you the store location constant, although this is incredibly badly documented.
The example shown here for Listing System and Physical Stores handles the dwFlags value in its callback like this:
dwFlags &= CERT_SYSTEM_STORE_MASK;
dwFlags |= pEnumArg->dwFlags & ~CERT_SYSTEM_STORE_LOCATION_MASK;
CertEnumSystemStore(dwFlags, ...);
So I think if you do that masking you'll be left with the location constant in dwFlags equivalent to the string passed in the pvszStoreLocation parameter.
The dwFlags argument passed to the CertEnumSystemStoreLocationCallback callback function contains the store location encoded in the bits CERT_SYSTEM_STORE_LOCATION_MASK. Shifting those to the right by CERT_SYSTEM_STORE_LOCATION_SHIFT turns it into the numeric store ID.
The following code retrieves the list of store locations alongside the numeric store IDs:
Structure for communication:
#include <SDKDDKVer.h>
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "Crypt32.lib")
#include <vector>
#include <string>
#include <iostream>
struct Location {
DWORD StoreId;
std::wstring Name;
};
typedef std::vector<Location> StoreLocationsContainer;
Callback:
BOOL WINAPI CertEnumSystemStoreLocationCallback( LPCWSTR pvszStoreLocations,
DWORD dwFlags,
void* pvReserved,
void* pvArg
) {
StoreLocationsContainer& locations = *reinterpret_cast<StoreLocationsContainer*>( pvArg );
DWORD StoreId = ( dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK )
>> CERT_SYSTEM_STORE_LOCATION_SHIFT;
Location location = { StoreId, std::wstring( pvszStoreLocations ) };
locations.push_back( location );
return TRUE;
}
Implementation:
StoreLocationsContainer GetStoreLocations() {
StoreLocationsContainer locations;
if ( !::CertEnumSystemStoreLocation( 0x0,
&locations,
CertEnumSystemStoreLocationCallback ) ) {
throw std::runtime_error( "CertEnumSystemStoreLocation" );
}
return locations;
}
For completeness, here is the remaining code to dump all stores across all locations:
BOOL WINAPI CertEnumSystemStoreCallback( const void* pvSystemStore,
DWORD dwFlags,
PCERT_SYSTEM_STORE_INFO pStoreInfo,
void* pvReserved,
void* pvArg ) {
std::wcout << L" " << static_cast<const wchar_t*>( pvSystemStore ) << std::endl;
return TRUE;
}
void PrintStores( const StoreLocationsContainer& locations ) {
for ( const Location& loc : locations ) {
std::wcout << loc.Name << std::endl;
DWORD dwFlags = ( loc.StoreId << CERT_SYSTEM_STORE_LOCATION_SHIFT )
& CERT_SYSTEM_STORE_LOCATION_MASK;
::CertEnumSystemStore( dwFlags, nullptr, nullptr, CertEnumSystemStoreCallback );
}
}
int main() {
StoreLocationsContainer locations = GetStoreLocations();
PrintStores( locations );
return 0;
}
Related
(https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses)
Why are some of the user friendly names in PIP_ADAPTER_ADDRESSES unprintable? (aswell as a few other attributes such as dns suffix)
By unprintable, I mean containing non-printable characters. for exmaple, the first character in one of the friendly names I tested had a unicode value fo 8207 (decimal)
A minimal complete viable example
#include <winsock2.h>
#include <iphlpapi.h>
#include <vector>
#include <iostream>
int main()
{
PIP_ADAPTER_ADDRESSES adapterAddresses;
DWORD dwReqSize;
DWORD retVal;
DWORD count = 0;
std::string tempForWstringConv;
retVal = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &dwReqSize); // for knowing the required size
if (retVal != ERROR_BUFFER_OVERFLOW) {
return -1;
}
adapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc(dwReqSize);
retVal = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, adapterAddresses, &dwReqSize); // this time actually getting the desired content
if (retVal != ERROR_SUCCESS) {
return -1;
}
for (PIP_ADAPTER_ADDRESSES adapter = adapterAddresses; adapter != NULL; adapter = adapter->Next)
{
//outLog.push_back(Adapter());
printf("\tFriendly name: %ls\n", adapter->FriendlyName);
}
return 0;
}
I finally found A solution!
meet _setmode(_fileno(stdout), _O_U16TEXT);
the problem was that the output buffer wasn't allowing these characters because the mode was incorrect. Alas, our desired output:
inorder to use this you MUST A: switch all occurences of cout to wcou; B: switch all occurences of printf to wprintf. C: include and
I'd like to change the presence state in an App automatically to DND when Focus Assist is turned on.
So two questions basically:
Is it possible to check Focus Assist state through e.g. Windows 10 SDK?
There is a similar question for Quiet Hours in Windows 8 here: Get windows Quiet hours from Win32 or C# API, though it's not clear whether it also still applies to "Focus Assist" since this is no longer a true or false value.
Quiet hours had only ON/OFF state while Focus Assist can be OFF/PRIORITY/ALARMS.
The more interesting question though, which is not answered in the post mentioned above: is there an event I could register to, to get notified about state changes?
The goal is to get notified right away, when Focus Assist status changes in order to not have to query the registry on a regular basis.
As far as I know there is no officially documented way of getting the Focus assist status.
It still can be accessed by querying the WNF State of the feature, although this is completely undocumented and not officially supported.
The various states for WNF Data have been reverse engineered, so the one for Focus Assist is WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED.
The C++ sample below shows how to get the state of Focus Assist feature (mostly off, priority_only and alarm_only).
Once again, be wary that this is not officially supported by Microsoft:
#include <Windows.h>
#include <iostream>
#include <string>
#include <map>
// from ntdef.h
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
// from ntdef.h
typedef struct _WNF_STATE_NAME
{
ULONG Data[2];
} WNF_STATE_NAME;
typedef struct _WNF_STATE_NAME* PWNF_STATE_NAME;
typedef const struct _WNF_STATE_NAME* PCWNF_STATE_NAME;
typedef struct _WNF_TYPE_ID
{
GUID TypeId;
} WNF_TYPE_ID, *PWNF_TYPE_ID;
typedef const WNF_TYPE_ID* PCWNF_TYPE_ID;
typedef ULONG WNF_CHANGE_STAMP, *PWNF_CHANGE_STAMP;
enum FocusAssistResult
{
not_supported = -2,
failed = -1,
off = 0,
priority_only = 1,
alarms_only = 2
};
std::map<int, std::string> result_map = {
{-2, "Not Supported"},
{-1, "Failed"},
{0, "Off"},
{1, "Priority Only"},
{2, "Alarm Only"}
};
typedef NTSTATUS (NTAPI *PNTQUERYWNFSTATEDATA)(
_In_ PWNF_STATE_NAME StateName,
_In_opt_ PWNF_TYPE_ID TypeId,
_In_opt_ const VOID* ExplicitScope,
_Out_ PWNF_CHANGE_STAMP ChangeStamp,
_Out_writes_bytes_to_opt_(*BufferSize, *BufferSize) PVOID Buffer,
_Inout_ PULONG BufferSize);
int main(int argc, CHAR** argv)
{
// note: ntdll is guaranteed to be in the process address space.
const auto h_ntdll = GetModuleHandle(_T("ntdll"));
// get pointer to function
const auto pNtQueryWnfStateData = PNTQUERYWNFSTATEDATA(GetProcAddress(h_ntdll, "NtQueryWnfStateData"));
if (!pNtQueryWnfStateData)
{
std::cerr << "[-] Error: couldn't get pointer to NtQueryWnfStateData() function." << std::endl;
return -1;
}
// state name for active hours (Focus Assist)
WNF_STATE_NAME WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED{0xA3BF1C75, 0xD83063E};
// note: we won't use it but it's required
WNF_CHANGE_STAMP change_stamp = {0};
// on output buffer will tell us the status of Focus Assist
DWORD buffer = 0;
ULONG buffer_size = sizeof(buffer);
if (NT_SUCCESS(pNtQueryWnfStateData(&WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED, nullptr, nullptr, &change_stamp,
&buffer, &buffer_size)))
{
// check if the result is one of FocusAssistResult
if (result_map.count(buffer) == 0)
{
std::cout << "Focus Assist result is unknown." << std::endl;
}
else
{
std::cout << "Focus assist state: " << result_map[buffer] << std::endl;
}
}
else
{
std::cerr << "[-] Error while calling NtQueryWnfStateData." << std::endl;
return -1;
}
return 0;
}
The last member WCHAR Name[1] is assumed to be a string. It's a well-known technic.
// c:\Program Files (x86)\Windows Kits\8.0\Include\um\DbgHelp.h
typedef struct _SYMBOL_INFOW {
ULONG SizeOfStruct;
ULONG TypeIndex; // Type Index of symbol
ULONG64 Reserved[2];
ULONG Index;
ULONG Size;
ULONG64 ModBase; // Base Address of module comtaining this symbol
ULONG Flags;
ULONG64 Value; // Value of symbol, ValuePresent should be 1
ULONG64 Address; // Address of symbol including base address of module
ULONG Register; // register holding value or pointer to value
ULONG Scope; // scope of the symbol
ULONG Tag; // pdb classification
ULONG NameLen; // Actual length of name
ULONG MaxNameLen;
WCHAR Name[1]; // Name of symbol
} SYMBOL_INFOW, *PSYMBOL_INFOW;
But the following code generates V641. Why?
PSYMBOL_INFOW pSym = NULL;
pSym = (PSYMBOL_INFOW) malloc(sizeof(SYMBOL_INFOW) + MAX_SYM_NAME);
Thank you for the interest to our product and the issues you described. We will examine the provided code fragments and will try to fix these issues.
I want to make like a function with an argument stdvector::<std::string> of process names and std::vector<std::string> of .dll's to find in them and feed it into a function and get like PROCESSENTRY32 info std::vector<PROCESSENTRY32> returned of anything that matches the names.
You can google but won't find much as I have thanks for helping new to winapi but not to figuring things out
There is a perfect example to do exactly what you want on MSDN here. The relevant code is copied below. As the introduction to the sample says
To determine which processes have loaded a particular DLL, you must enumerate the modules for each process. The following sample code uses the EnumProcessModules function to enumerate the modules of current processes in the system.
Now the sample code
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>
// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1
int PrintModules( DWORD processID )
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
// Print the process identifier.
printf( "\nProcess ID: %u\n", processID );
// Get a handle to the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
return 1;
// Get a list of all the modules in this process.
if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
TCHAR szModName[MAX_PATH];
// Get the full path to the module's file.
if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,
sizeof(szModName) / sizeof(TCHAR)))
{
// Print the module name and handle value.
_tprintf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );
}
}
}
// Release the handle to the process.
CloseHandle( hProcess );
return 0;
}
int main( void )
{
DWORD aProcesses[1024];
DWORD cbNeeded;
DWORD cProcesses;
unsigned int i;
// Get the list of process identifiers.
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return 1;
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the names of the modules for each process.
for ( i = 0; i < cProcesses; i++ )
{
PrintModules( aProcesses[i] );
}
return 0;
}
The only change you will need to make is to push-back the module names of interest to your std::vector<std::string> beforehand and then search that vector with the enumerated module names instead of printing them.
I wrote a simple application on Qt4 that modifier network adapter parameters, for that I have a slot called setInterfaceParams, implemented as so:
DWORD WinNetInterface::setInterfaceParams(QString index, QString ip, QString netmask, QString gateway)
{
DWORD res = NULL;
HINSTANCE lib = (HINSTANCE) LoadLibrary((WCHAR *)"iphlpapi.dll");
_SetAdapterIpAddress SetAdapterIpAddress = (_SetAdapterIpAddress) GetProcAddress(lib, "SetAdapterIpAddress");
PWSTR pszGUID = NULL;
//char *szGUID = (char *)index.toStdString().c_str();
QByteArray a = index.toLocal8Bit();
char *szGUID = a.data();
WideCharToMultiByte(CP_ACP, 0, pszGUID, -1, szGUID, sizeof(szGUID), NULL, NULL);
// Method 01
res = SetAdapterIpAddress(szGUID,
0,
inet_addr(ip.toStdString().c_str()),
inet_addr(netmask.toStdString().c_str()),
inet_addr(gateway.toStdString().c_str()));
// End of method 01
// Method 02
/*res = SetAdapterIpAddress("{422C5689-A17B-402D-A6A2-22CE13E857B5}",
0,
inet_addr("192.168.1.10"),
inet_addr("255.255.255.0"),
inet_addr("192.168.1.1"));*/
// End of method 02
return res;
}
When I click on button that connected to slot setInterfaceParams, I get segmentation fault. If I comment method01, nothing happen, the some thing happen when I use method02.
I tried this function on a simple c++ application and it is work fine, test on Windows XP SP3.
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <iostream>
typedef DWORD (WINAPI *_SetAdapterIpAddress )(char *szAdapterGUID,
DWORD dwDHCP,
DWORD dwIP,
DWORD dwMask,
DWORD dwGateway);
int main()
{
HINSTANCE lib = (HINSTANCE) LoadLibrary("iphlpapi.dll");
_SetAdapterIpAddress SetAdapterIpAddress = (_SetAdapterIpAddress) GetProcAddress(lib, "SetAdapterIpAddress");
PWSTR pszGUID = NULL;
char szGUID[] = "{422C5689-A17B-402D-A6A2-22CE13E857B5}";
DWORD dwSize = 0;
WideCharToMultiByte(CP_ACP, 0, pszGUID, -1, szGUID, sizeof(szGUID), NULL, NULL);
DWORD res = SetAdapterIpAddress(szGUID,
0,
inet_addr("192.168.1.10"),
inet_addr("255.255.255.0"),
inet_addr("192.168.1.1"));
std::cout << res;
return 0;
}
LoadLibrary((WCHAR *)"iphlpapi.dll");
That can't work, the literal string is in 8-bits, casting it without real conversion doesn't make it wide, so the dll loading probably failed.
You should use the TEXT or _T macro around most of the literal strings passed to WinAPI functions to make them regular or wide depending on the compilation options:
LoadLibrary(_T("iphlpapi.dll"));
which will translate to either LoadLibrary("iphlpapi.dll"); or LoadLibrary(L"iphlpapi.dll");.
Also you should always check the value returned by the LoadLibrary and GetProcAddress functions, which return NULL if the call is unsuccessful.