0
我編寫了一個C++函數,該函數通過WMI查詢獲取USB驅動器的PNPDeviceID並在Win32-Console-Application中對其進行測試。它完美地工作,但是當我將代碼放入CredentialProvider-DLL時,CoInitialize()
和CoInitializeSecurity()
函數失敗,因爲DLL調用進程(Windows CredUI-Subsystem)已經調用該函數。那麼如何讓WMI查詢在該DLL上工作?我需要重置COM安全設置,默認情況下似乎不可行。CredentialProvider DLL中的WMI查詢
下面是函數代碼:
std::wstring GetHardwareID(char driveLetter)
{
std::wstring returnString = L"";
wchar_t volumeAccessPath[] = L"\\\\.\\X:";
volumeAccessPath[4] = driveLetter;
HANDLE deviceHandle = CreateFileW(volumeAccessPath,
0, // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
DWORD bytes;
STORAGE_DEVICE_NUMBER devd;
STORAGE_BUS_TYPE busType = BusTypeUnknown;
if (DeviceIoControl(deviceHandle,
IOCTL_STORAGE_GET_DEVICE_NUMBER ,
NULL, 0,
&devd, sizeof(devd),
&bytes, NULL))
{
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
{
return returnString;
}
IWbemLocator* pLocator = NULL;
if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
{ return returnString;}
IWbemServices* pService = NULL;
if(FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
{
pLocator->Release();
dbg(convertInt(hRes).c_str());
return returnString;
}
IEnumWbemClassObject* pEnumerator = NULL;
if(FAILED(hRes = pService->ExecQuery(L"WQL", L"SELECT * FROM Win32_DiskDrive ", WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
{
pLocator->Release();
pService->Release();
dbg(convertInt(hRes).c_str());
return returnString;
}
IWbemClassObject* clsObj = NULL;
int numElems;
while((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
{
if(FAILED(hRes))
break;
VARIANT vRet;
VariantInit(&vRet);
if(SUCCEEDED(clsObj->Get(L"DeviceID", 0, &vRet, NULL, NULL)) && vRet.vt == VT_BSTR)
{
bool found = false;
std::wstring ws(vRet.bstrVal);
if (ws[17] == '0' + devd.DeviceNumber)
found = true;
VariantClear(&vRet);
if(SUCCEEDED(clsObj->Get(L"PNPDeviceID", 0, &vRet, NULL, NULL)) && vRet.vt == VT_BSTR && found)
{
std::wstring retStr(vRet.bstrVal);
VariantClear(&vRet);
std::wstring k(L"&");
int pos =retStr.rfind(k);
returnString = retStr.substr(0, pos);
}
}
clsObj->Release();
}
pEnumerator->Release();
pService->Release();
pLocator->Release();
}
return returnString;
}
在此先感謝
謝謝,但我以不同的方式解決了這個問題。我只是簡單地刪除了'CoInitializeSecurity()'調用(因爲這是全過程設置的)並且使用'CoSetProxyBlanket()'來代替,它可以在特定的COM-Proxy上使用。 但我會保存你的解決方案,以便將來的問題不會那麼容易解決...... – Adrian 2012-08-04 15:20:27
也謝謝你=)你的解決方案也很好,在這種情況下,我沒有想過CoSetProxyBlanket()。 – Apokal 2012-08-05 17:52:04
你能幫我解答我的下一個問題嗎? http://stackoverflow.com/questions/11810046/is-the-pnpdeviceid-unique – Adrian 2012-08-06 11:32:45