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;
}