2015-08-21 66 views
0

我的问题是关于cryptoAPI接口。从CertEnumSystemStoreLocation()到CertEnumSystemStore()的步骤

Look,CertEnumSystemStoreLocation()是枚举系统中可用的所有证书存储位置的函数。它返回(使用回调)枚举位置作为宽字符串(LPCWSTR)。

CertEnumSystemStore()根据给定的位置枚举商店。它将位置(DWORD)的整数常量用作参数。

我试图枚举位置,结果是一个字符串列表,它的语义等价于来自CryptoAPI导入模块的DWORD位置常量列表。

而我的问题是:我该如何将商店位置的宽字符串表示转换为DWORD常量?是否有cryptoAPI函数(或者至少是常用的方法)?

回答

0

传递给CertEnumSystemStoreLocationCallback callback functiondwFlags参数包含编码在位CERT_SYSTEM_STORE_LOCATION_MASK中的存储位置。将这些向右移动CERT_SYSTEM_STORE_LOCATION_SHIFT将其转换为数字商店ID。

下面的代码检索商店位置的旁边的数字商店的ID名单:

结构来进行通信:

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

回调:

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

实现:

StoreLocationsContainer GetStoreLocations() { 
    StoreLocationsContainer locations; 
    if (!::CertEnumSystemStoreLocation(0x0, 
             &locations, 
             CertEnumSystemStoreLocationCallback)) { 
     throw std::runtime_error("CertEnumSystemStoreLocation"); 
    } 
    return 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; 
} 
+0

谢谢!我怎么能在回调中看不到dwFlags! – MrCat

1

它看起来像dwFlags传递给你的CertEnumSystemStoreLocationCallback回调函数实际上给你的商店位置不变,虽然这是令人难以置信的严重记录。

这里显示的Listing System and Physical Stores的示例处理在其回调像这样dwFlags值:

dwFlags &= CERT_SYSTEM_STORE_MASK; 
dwFlags |= pEnumArg->dwFlags & ~CERT_SYSTEM_STORE_LOCATION_MASK; 
CertEnumSystemStore(dwFlags, ...); 

所以我觉得如果你这样做,你屏蔽会留下的位置不断在dwFlags等价的字符串传入参数pvszStoreLocation

+0

谢谢,这个答案是正确的too.Unfortunatly,不可能标记多个答案 – MrCat