InternetOpenUrl error 87 - c++

I call InternetOpenUrl in 2 other places in my program and it works flawlessly. But the last time I call it, it fails with error 87 (the parameter is incorrect). It's odd because the parameters are exactly the same except the url.
This is my code:
wchar_t url[] = {'h','t','t','p','s',':','/','/','w','w','w','.','e','x','a','m','p','l','e','.','c','o','m', 0};
HINTERNET hFile = NULL;
hOpen = InternetOpenW(L"MyAgent", NULL, NULL, NULL, NULL);
if (!hOpen)
ret = EXIT_FAILURE;
DWORD dwRequestFlags =
INTERNET_FLAG_NO_UI
| INTERNET_FLAG_NO_AUTH
| INTERNET_FLAG_PRAGMA_NOCACHE
| INTERNET_FLAG_NO_CACHE_WRITE;
hFile = InternetOpenUrlW(hOpen, url, NULL, NULL, dwRequestFlags, NULL);
Then I use GetLastError() to find out it's 87.

You are calling InternetOpenUrl() even if InternetOpen() fails, so hOpen would be invalid. Do something like this instead:
hOpen = InternetOpenW(L"MyAgent", NULL, NULL, NULL, NULL);
if (!hOpen)
ret = EXIT_FAILURE;
else
{
DWORD dwRequestFlags =
INTERNET_FLAG_NO_UI
| INTERNET_FLAG_NO_AUTH
| INTERNET_FLAG_PRAGMA_NOCACHE
| INTERNET_FLAG_NO_CACHE_WRITE;
hFile = InternetOpenUrlW(hOpen, url, NULL, NULL, dwRequestFlags, NULL);
if (!hFile)
ret = EXIT_FAILURE;
else
// and so on...
}
Or:
ret = 0;
hOpen = InternetOpenW(L"MyAgent", NULL, NULL, NULL, NULL);
if (!hOpen)
ret = EXIT_FAILURE;
if (ret == 0)
{
DWORD dwRequestFlags =
INTERNET_FLAG_NO_UI
| INTERNET_FLAG_NO_AUTH
| INTERNET_FLAG_PRAGMA_NOCACHE
| INTERNET_FLAG_NO_CACHE_WRITE;
hFile = InternetOpenUrlW(hOpen, url, NULL, NULL, dwRequestFlags, NULL);
if (!hFile)
ret = EXIT_FAILURE;
}
if (ret == 0)
{
// and so on...
}
Also, this line:
wchar_t url[] = {'h','t','t','p','s',':','/','/','w','w','w','.','e','x','a','m','p','l','e','.','c','o','m', 0};
Can be re-written like this instead:
wchar_t url[] = L"https://www.example.com";
Or even this (since there so no need to make a local copy of the literal data):
const wchar_t *url = L"https://www.example.com";

Related

AcquireCredentialsHandleA() returns 0x8009030e (No credentials are available in the security package) for PFX file

I'm trying to setup server-side encryption using SSPI. I'm successfully (as far as I can tell) loading a certificate stored as a PFX file, but the call to m_pSSPI->AcquireCredentialsHandleA() returns 0x8009030e.
This method seems to successfully load the file and return a CERT_CONTEXT object.
HRESULT CTLSPackage::LoadCertContextFromFilePFX (PCWSTR pcwzFile, PCWSTR pcwzPassword, __deref_out PCCERT_CONTEXT* ppctxCert)
{
HRESULT hr;
HANDLE hFile, hSection = NULL;
BOOL (WINAPI* pfnPFXIsPFXBlob)(CRYPT_DATA_BLOB*);
HCERTSTORE (WINAPI* pfnPFXImportCertStore)(CRYPT_DATA_BLOB*, LPCWSTR, DWORD);
PCCERT_CONTEXT (WINAPI* pfnCertEnumCertificatesInStore)(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);
CRYPT_DATA_BLOB blob; blob.pbData = NULL;
HCERTSTORE pfxStore = NULL;
hFile = CreateFile(pcwzFile, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
CheckIfGetLastError(INVALID_HANDLE_VALUE == hFile);
blob.cbData = GetFileSize(hFile, NULL);
hSection = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
CheckIfGetLastError(NULL == hSection);
blob.pbData = reinterpret_cast<PBYTE>(MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0));
CheckIfGetLastError(NULL == blob.pbData);
Check(TGetFunction(m_hCrypt32, "PFXIsPFXBlob", &pfnPFXIsPFXBlob));
Check(TGetFunction(m_hCrypt32, "PFXImportCertStore", &pfnPFXImportCertStore));
Check(TGetFunction(m_hCrypt32, "CertEnumCertificatesInStore", &pfnCertEnumCertificatesInStore));
CheckIf(!pfnPFXIsPFXBlob(&blob), E_FAIL);
pfxStore = pfnPFXImportCertStore(&blob, pcwzPassword, CRYPT_MACHINE_KEYSET | CRYPT_EXPORTABLE);
CheckIf(NULL == pfxStore, SEC_E_NO_CREDENTIALS);
*ppctxCert = pfnCertEnumCertificatesInStore(pfxStore, NULL);
CheckIf(NULL == *ppctxCert, SEC_E_NO_CREDENTIALS);
Cleanup:
if(pfxStore)
{
BOOL (WINAPI* pfnCertCloseStore)(HCERTSTORE, DWORD);
if(SUCCEEDED(TGetFunction(m_hCrypt32, "CertCloseStore", &pfnCertCloseStore)))
pfnCertCloseStore(pfxStore, 0);
}
if(blob.pbData)
UnmapViewOfFile(blob.pbData);
SafeCloseHandle(hSection);
SafeCloseFileHandle(hFile);
return hr;
}
The result is immediately passed to another class method, which makes the failing AcquireCredentialsHandleA() call.
HRESULT CTLSPackage::AcquireCredentials (__in_opt PCCERT_CONTEXT pCertContext, PCredHandle phCreds)
{
SCHANNEL_CRED SchannelCred;
TimeStamp tsExpiry;
ZeroMemory(&SchannelCred, sizeof(SchannelCred));
SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
if(pCertContext)
{
SchannelCred.cCreds = 1;
SchannelCred.paCred = &pCertContext;
}
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2;
if(!m_fServer)
SchannelCred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS | SCH_USE_STRONG_CRYPTO;
//
// Create an SSPI credential.
//
return m_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
m_fServer ? NEGOSSP_NAME_A : UNISP_NAME_A, // Name of package
m_fServer ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
NULL, // Pointer to logon ID
&SchannelCred, // Package specific data
NULL, // Pointer to GetKey() func
NULL, // Value to pass to GetKey()
phCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime (optional)
}
My CTLSPackage::AcquireCredentials() code path is also used for setting up client-side encryption, and that works. For the server-side path, m_fServer is TRUE. The m_hCrypt32 member was loaded from Crypt32.dll.
I've cobbled together this code from samples, but I must be missing something for the server case. I only need to setup SSL/TLS-style encryption, so the "No credentials are available in the security package" error is weird because I have no need for credential authentication.
Does anyone know what might be missing? Thanks!
With a hint from RbMm, I then found this article:
https://www.codeproject.com/articles/125124/how-to-use-certificate-from-disk-with-microsoft-cr
The short answer is that CryptAcquireCertificatePrivateKey() needed to be used when loading a PFX from a file, and UNISP_NAME_A needed to be passed to AcquireCredentialsHandleA().
For reference, here is the revised code:
HRESULT CTLSPackage::LoadCertContextFromFilePFX (PCWSTR pcwzFile, PCWSTR pcwzPassword, __deref_out PCCERT_CONTEXT* ppctxCert)
{
HRESULT hr;
HANDLE hFile, hSection = NULL;
BOOL (WINAPI* pfnPFXIsPFXBlob)(CRYPT_DATA_BLOB*);
HCERTSTORE (WINAPI* pfnPFXImportCertStore)(CRYPT_DATA_BLOB*, LPCWSTR, DWORD);
PCCERT_CONTEXT (WINAPI* pfnCertFindCertificateInStore)(HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, const void* pvFindPara, PCCERT_CONTEXT pPrevCertContext);
BOOL (WINAPI* pfnCryptAcquireCertificatePrivateKey)(PCCERT_CONTEXT pCert, DWORD dwFlags, void* pvReserved, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProvOrNCryptKey, DWORD* pdwKeySpec, BOOL* pfCallerFreeProvOrNCryptKey);
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv;
DWORD dwKeySpec;
BOOL fFreeProv = FALSE;
CRYPT_DATA_BLOB blob; blob.pbData = NULL;
HCERTSTORE hpfxStore = NULL;
hFile = CreateFile(pcwzFile, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
CheckIfGetLastError(INVALID_HANDLE_VALUE == hFile);
blob.cbData = GetFileSize(hFile, NULL);
hSection = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
CheckIfGetLastError(NULL == hSection);
blob.pbData = reinterpret_cast<PBYTE>(MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0));
CheckIfGetLastError(NULL == blob.pbData);
Check(TGetFunction(m_hCrypt32, "PFXIsPFXBlob", &pfnPFXIsPFXBlob));
Check(TGetFunction(m_hCrypt32, "PFXImportCertStore", &pfnPFXImportCertStore));
Check(TGetFunction(m_hCrypt32, "CertFindCertificateInStore", &pfnCertFindCertificateInStore));
Check(TGetFunction(m_hCrypt32, "CryptAcquireCertificatePrivateKey", &pfnCryptAcquireCertificatePrivateKey));
CheckIf(!pfnPFXIsPFXBlob(&blob), HRESULT_FROM_WIN32(ERROR_BAD_FORMAT));
hpfxStore = pfnPFXImportCertStore(&blob, pcwzPassword, 0);
if(NULL == hpfxStore && pcwzPassword && L'\0' == *pcwzPassword)
{
hpfxStore = pfnPFXImportCertStore(&blob, NULL, 0);
CheckIf(NULL == hpfxStore, SEC_E_NO_CREDENTIALS);
}
*ppctxCert = pfnCertFindCertificateInStore(hpfxStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);
CheckIfGetLastError(NULL == *ppctxCert);
// Acquire the private key and make it available for the later AcquireCredentalsHandle() call.
if(!pfnCryptAcquireCertificatePrivateKey(*ppctxCert, 0, NULL, &hProv, &dwKeySpec, &fFreeProv))
{
DWORD dwError = GetLastError();
FreeCertificateContext(*ppctxCert);
*ppctxCert = NULL;
CheckWin32Error(dwError);
}
Cleanup:
if(fFreeProv)
FreeProvOrNCryptKey(hProv, dwKeySpec);
if(hpfxStore)
{
BOOL (WINAPI* pfnCertCloseStore)(HCERTSTORE, DWORD);
if(SUCCEEDED(TGetFunction(m_hCrypt32, "CertCloseStore", &pfnCertCloseStore)))
pfnCertCloseStore(hpfxStore, 0);
}
if(blob.pbData)
UnmapViewOfFile(blob.pbData);
SafeCloseHandle(hSection);
SafeCloseFileHandle(hFile);
return hr;
}
HRESULT CTLSPackage::AcquireCredentials (__in_opt PCCERT_CONTEXT pCertContext, PCredHandle phCreds)
{
SCHANNEL_CRED SchannelCred;
TimeStamp tsExpiry;
ZeroMemory(&SchannelCred, sizeof(SchannelCred));
SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
if(pCertContext)
{
SchannelCred.cCreds = 1;
SchannelCred.paCred = &pCertContext;
}
SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3 | SP_PROT_TLS1 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2;
SchannelCred.dwFlags = SCH_USE_STRONG_CRYPTO;
if(!m_fServer)
SchannelCred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
//
// Create an SSPI credential.
//
return m_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
UNISP_NAME_A, // Name of package
m_fServer ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
NULL, // Pointer to logon ID
&SchannelCred, // Package specific data
NULL, // Pointer to GetKey() func
NULL, // Value to pass to GetKey()
phCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime (optional)
}

INVALID_FUNCTION error when writing to HID file

I am writing a program to send data to an HID device. I followed the following page from Microsoft's documentation: Finding and Opening a HID Collection and I get the file handle successfully, but when I try to write using WriteFile, I get an INVALID_FUNCTION error (1). I have sent the same data to the device through a Hyperterminal and it worked, so I'm sure that the information I am sending is correct.
Here is my code:
HANDLE m_hCommPort;
GUID guid = GUID_DEVINTERFACE_USB_DEVICE;
HDEVINFO hinfo;
DWORD index = 0;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
SP_DEVINFO_DATA deviceInfoData;
BOOL result;
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
DWORD requiredSize;
DWORD deviceIndex = 0;
hinfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
result = SetupDiEnumDeviceInterfaces(hinfo, NULL, &guid, deviceIndex, &deviceInterfaceData);
while (result == TRUE) {
deviceInfoData.cbSize = sizeof(deviceInfoData);
SetupDiGetDeviceInterfaceDetail(hinfo, &deviceInterfaceData, NULL, 0, &requiredSize, &deviceInfoData);
deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize);
deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail(hinfo, &deviceInterfaceData, deviceInterfaceDetailData, requiredSize, NULL, &deviceInfoData);
Trace(TEXT(deviceInterfaceDetailData->DevicePath));
if (_tcsstr(deviceInterfaceDetailData->DevicePath, "vid_0c2e&pid_0be7")) {
Trace(TEXT(deviceInterfaceDetailData->DevicePath));
break;
}
result = SetupDiEnumDeviceInterfaces(hinfo, NULL, &guid, ++deviceIndex, &deviceInterfaceData);
}
if (result == FALSE) {
ErrorExit("SetupDiEnumDeviceInterfaces ");
}
else if(deviceInterfaceDetailData != NULL){
m_hCommPort = CreateFile(deviceInterfaceDetailData->DevicePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if (m_hCommPort == INVALID_HANDLE_VALUE) {
ErrorExit("CreateFile");
}
else {
DWORD bytesWritten;
char scanCommand[] = { 22,77,13,'I','M','G','S','N','P','1','B' };
DWORD size = sizeof(scanCommand);
BOOL fileWritten = WriteFile(m_hCommPort, scanCommand, size, &bytesWritten, NULL);
if (fileWritten == TRUE) {
Trace(TEXT("Wrote %d files to device"), bytesWritten);
}
else {
ErrorExit("Error writing to file");
}
}
}
Can someone help me to understand why I am getting this error please?

HInternet works only one time

This code is in a C++ DLL injected in a game. (This is on a private server so it is legal). The code has to be executed multiple times. However, it works only the first time. It could be on the WCF end but I managed to send 2 and 5 successful requests from a .net dll loaded from the c++ dll before.
Since I didn't figure out why it was blocked after 2 and 5 requests, I decided to go all native but now I'm blocked after one request. I have a feeling it now has to do with the way I'm parsing the response.
The first execution gets a 200 code status and the second one gets a 0.
edit : my fire wall is turned off.
HINTERNET hInternet = InternetOpen(_T("MyApp"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET hConnect = InternetConnect(hInternet, _T("localhost"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
LPCSTR rgpszAcceptTypes[] = { _T("application/json"), NULL };
HINTERNET hRequest = HttpOpenRequest(hConnect, _T("POST"), _T("/xxxBackend/service1.svc/SaveDataVoid"), NULL, NULL, rgpszAcceptTypes, 0, 0);
HttpAddRequestHeaders(hRequest, _T("Content-Type: application/json\r\n"), -1, HTTP_ADDREQ_FLAG_ADD);
char *JsonData = "{\"data\":{\"AccountName\":\"\",\"CharName\":\"SilverDeth-IV\",\"GameDiff\":\"1\",\"CompressedData\":[8228138568842941382,8247906688399250381,8244242016143283142]}}";
HttpSendRequest(hRequest, NULL, 0, JsonData, strlen(JsonData));
DWORD StatusCode = 0;
DWORD StatusCodeLen = sizeof(StatusCode);
HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &StatusCode, &StatusCodeLen, NULL);
if (StatusCode == 200)
{
char *lpBuffer[2000];
DWORD lpdwNumberOfBytesRead = 0;
InternetQueryDataAvailable(hRequest, &StatusCodeLen, 0, 0);
bool bRetval = InternetReadFile(hRequest, lpBuffer, 2000, &lpdwNumberOfBytesRead);
}
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
The code you have shown is not doing ANY error handling at all. Add that in, and then see where the failure is really occurring. The fact that StatusCode is 0 means HttpQueryInfo() is failing, which could happen if you did not obtain a valid hRequest to begin with.
BTW, rgpszAcceptTypes needs to be declared as LPCTSTR instead of LPCSTR, and you should be using the TEXT() macro instead of the _T() macro. TEXT() belongs to the Win32 API, but _T() belongs to the C runtime library, which you are not using in this code.
Try this:
void InetError(LPCTSTR msg)
{
DWORD dwErr = GetLastError();
if (dwErr == ERROR_INTERNET_EXTENDED_ERROR)
{
DWORD dwInetErr = 0;
LPTSTR szResp = NULL;
DWORD dwLength = 0;
InternetGetLastResponseInfo(&dwInetErr, NULL, &dwLength);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
szResp = new TCHAR[dwLength+1];
InternetGetLastResponseInfo(&dwInetErr, szResp, &dwLength);
}
// use msg, szResp, and dwInetErr as needed...
delete[] szResp;
}
else
{
// use msg and dwErr as needed...
}
}
...
HINTERNET hInternet = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
hInternet = InternetOpen(TEXT("MyApp"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!hInternet)
{
InetError(TEXT("InternetOpen failed"));
goto done;
}
hConnect = InternetConnect(hInternet, TEXT("localhost"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (!hConnect)
{
InetError(TEXT("InternetConnect failed"));
goto done;
}
LPCTSTR rgpszAcceptTypes[] = { TEXT("application/json"), NULL };
hRequest = HttpOpenRequest(hConnect, TEXT("POST"), TEXT("/xxxBackend/service1.svc/SaveDataVoid"), NULL, NULL, rgpszAcceptTypes, 0, 0);
if (!hRequest)
{
InetError(TEXT("HttpOpenRequest failed"));
goto done;
}
if (!HttpAddRequestHeaders(hRequest, TEXT("Content-Type: application/json\r\n"), -1, HTTP_ADDREQ_FLAG_ADD))
{
InetError(TEXT("HttpAddRequestHeaders failed"));
goto done;
}
char *JsonData = "{\"data\":{\"AccountName\":\"\",\"CharName\":\"SilverDeth-IV\",\"GameDiff\":\"1\",\"CompressedData\":[8228138568842941382,8247906688399250381,8244242016143283142]}}";
if (!HttpSendRequest(hRequest, NULL, 0, JsonData, strlen(JsonData)))
{
InetError(TEXT("HttpSendRequest failed"));
goto done;
}
DWORD StatusCode = 0;
DWORD StatusCodeLen = sizeof(StatusCode);
if (!HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &StatusCode, &StatusCodeLen, NULL))
{
InetError(TEXT("HttpQueryInfo failed"));
goto done;
}
if (StatusCode == 200)
{
BYTE Buffer[2000];
DWORD dwNumberOfBytes = 0;
DWORD dwNumberOfBytesRead = 0;
if (!InternetQueryDataAvailable(hRequest, &dwNumberOfBytes, 0, 0))
{
InetError(TEXT("InternetQueryDataAvailable failed"));
goto done;
}
if (!InternetReadFile(hRequest, Buffer, min(dwNumberOfBytes, sizeof(Buffer)), &dwNumberOfBytesRead))
{
InetError(TEXT("InternetReadFile failed"));
goto done;
}
//...
}
done:
if (hRequest) InternetCloseHandle(hRequest);
if (hConnect) InternetCloseHandle(hConnect);
if (hInternet) InternetCloseHandle(hInternet);

How to get services and characteristics from bluetooth LE device

I'm writing desktop app in Windows 8.1, and I need to get services from paired device using BluetoothGATTGetServices function. To make it I need to get handle to the device, that I've done and get handle using CreateFile function. But when I try to get service function return error: HRESULT_FROM_WIN32(ERROR_NOT_SUPORTED). Does anyone know how to fix it or tell what I'm doing wrong.
My device I'm trying to get services is iPhone 5s.
Here is code example:
HRESULT WinBluetoothDeviceProvider::GetBleHandle(OUT HANDLE* hBluetooth, WinBluetoothDevice* blDev)
{
GUID bthGuid;
CLSIDFromString(TEXT(BLE_INTERFACE_GUID), &bthGuid); // BLE_INTERFACE_GUID this is GUID of my Device Interface GUID
//#define BLE_INTERFACE_GUID "{00f40965-e89d-4487-9890-87c3abb211f4}"
HRESULT result = S_OK;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA devInfoData;
HANDLE hBle;
hDevInfo = SetupDiGetClassDevs(&bthGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE)
return E_FAIL;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SP_DEVICE_INTERFACE_DATA devInterfData = { 0 };
devInterfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
DWORD DataT;
LPTSTR buffer = NULL;
DWORD buffersize = 0;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &bthGuid, i, &devInterfData); i++)
{
DWORD d = GetLastError();
DWORD size = 0;
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfData, NULL, 0, &size, 0))
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
{
result = S_OK;
break;
}
PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, size);
pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfData, pInterfaceDetailData, size, &size, &devInfoData))
{
result = E_FAIL;
break;
}
hBle = CreateFile(pInterfaceDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
USHORT serviceBuffActual;
PBTH_LE_GATT_SERVICE servicesBuff = new _BTH_LE_GATT_SERVICE;
HRESULT result = S_OK;
result = BluetoothGATTGetServices(hBle,
0, NULL, &serviceBuffActual, BLUETOOTH_GATT_FLAG_NONE);
// this function always retunr ERROR_NOT_SUPPORTED
LocalFree(pInterfaceDetailData);
}
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return result;
}
Try https://gist.github.com/programmarchy/c9d02e22d58bfab3f8bb#file-gistfile1-cpp-L110-L117, without FILE_ATTRIBUTE_NORMAL
hComm = CreateFile(
pInterfaceDetailData->DevicePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);

Using IOCTL_MOUNTMGR_QUERY_POINTS

I am not able to know how to use the IOCTL_MOUNTMGR_QUERY_POINTS .
I have searched the internet and found some sample code to try with.
but i am not sure whether its correct or not....
can you please let me know how to use the IOCTL_MOUNTMGR_QUERY_POINTS to get the drive letter
Thank you for your time
below is my source coode
HANDLE hUsbDevice = CreateFile( pDetData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
UCHAR Bytes[10000];
PMOUNTMGR_MOUNT_POINTS pMntPoints = (PMOUNTMGR_MOUNT_POINTS) Bytes;
MOUNTMGR_MOUNT_POINT mntPoint, *pmnt;
DWORD bytesReturned;
if (hUsbDevice == INVALID_HANDLE_VALUE) {
qDebug()<<"CreateFile failed with error: %d\n"<<GetLastError();
}
else {
qDebug ()<<"VALID DEVICE";
BOOL status = DeviceIoControl( hUsbDevice,
IOCTL_MOUNTMGR_QUERY_POINTS,
&mntPoint,
sizeof(MOUNTMGR_MOUNT_POINT),
pMntPoints,
10000,
&bytesReturned,
NULL);
wprintf(L"\tBOOL VALUE : %d\n", status);
qDebug ()<<pMntPoints->MountPoints;
}
OK! Here is a code example, but written without any error control to make it shorter:
#include <windows.h>
#include <C:\WinDDK\7600.16385.1\inc\ddk\mountmgr.h>
#include <tchar.h>
#include <stdio.h>
#pragma comment(lib, "Crypt32.lib")
int main()
{
TCHAR chDrive = 'N', szUniqueId[128];
TCHAR szDeviceName[7] = _T("\\\\.\\");
HANDLE hDevice, hMountMgr;
BYTE byBuffer[1024];
PMOUNTDEV_NAME pMountDevName;
DWORD cbBytesReturned, dwInBuffer, dwOutBuffer, ccb;
PMOUNTMGR_MOUNT_POINT pMountPoint;
BOOL bSuccess;
PBYTE pbyInBuffer, pbyOutBuffer;
LPTSTR pszLogicalDrives, pszDriveRoot;
// MOUNTMGR_DOS_DEVICE_NAME is defined as L"\\\\.\\MountPointManager"
hMountMgr = CreateFile (MOUNTMGR_DOS_DEVICE_NAME,
0, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hMountMgr == INVALID_HANDLE_VALUE)
return 1;
cbBytesReturned = GetLogicalDriveStrings (0, NULL);
pszLogicalDrives = (LPTSTR) LocalAlloc (LMEM_ZEROINIT,
cbBytesReturned*sizeof(TCHAR));
cbBytesReturned = GetLogicalDriveStrings (cbBytesReturned,
pszLogicalDrives);
for (pszDriveRoot = pszLogicalDrives; *pszDriveRoot != TEXT('\0');
pszDriveRoot += lstrlen(pszDriveRoot) + 1) {
szDeviceName[4] = pszDriveRoot[0];
szDeviceName[5] = _T(':');
szDeviceName[6] = _T('\0');
//lstrcpy (&szDeviceName[4], TEXT("\\??\\USBSTOR\\DISK&VEN_SANDISK&PROD_CRUZER&REV_8.01\\1740030578903736&0"));
hDevice = CreateFile (szDeviceName, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
return 1;
bSuccess = DeviceIoControl (hDevice,
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
NULL, 0,
(LPVOID)byBuffer, sizeof(byBuffer),
&cbBytesReturned,
(LPOVERLAPPED) NULL);
pMountDevName = (PMOUNTDEV_NAME) byBuffer;
_tprintf (TEXT("\n%.*ls\n"), pMountDevName->NameLength/sizeof(WCHAR),
pMountDevName->Name);
bSuccess = CloseHandle (hDevice);
dwInBuffer = pMountDevName->NameLength + sizeof(MOUNTMGR_MOUNT_POINT);
pbyInBuffer = (PBYTE) LocalAlloc (LMEM_ZEROINIT, dwInBuffer);
pMountPoint = (PMOUNTMGR_MOUNT_POINT) pbyInBuffer;
pMountPoint->DeviceNameLength = pMountDevName->NameLength;
pMountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
CopyMemory (pbyInBuffer + sizeof(MOUNTMGR_MOUNT_POINT),
pMountDevName->Name, pMountDevName->NameLength);
dwOutBuffer = 1024 + sizeof(MOUNTMGR_MOUNT_POINTS);
pbyOutBuffer = (PBYTE) LocalAlloc (LMEM_ZEROINIT, dwOutBuffer);
bSuccess = DeviceIoControl (hMountMgr,
IOCTL_MOUNTMGR_QUERY_POINTS,
pbyInBuffer, dwInBuffer,
(LPVOID)pbyOutBuffer, dwOutBuffer,
&cbBytesReturned,
(LPOVERLAPPED) NULL);
if (bSuccess) {
ULONG i;
PMOUNTMGR_MOUNT_POINTS pMountPoints = (PMOUNTMGR_MOUNT_POINTS) pbyOutBuffer;
for (i=0; i<pMountPoints->NumberOfMountPoints; i++) {
_tprintf (TEXT("#%i:\n"), i);
_tprintf (TEXT(" Device=%.*ls\n"),
pMountPoints->MountPoints[i].DeviceNameLength/sizeof(WCHAR),
pbyOutBuffer + pMountPoints->MountPoints[i].DeviceNameOffset);
_tprintf (TEXT(" SymbolicLink=%.*ls\n"),
pMountPoints->MountPoints[i].SymbolicLinkNameLength/sizeof(WCHAR),
pbyOutBuffer + pMountPoints->MountPoints[i].SymbolicLinkNameOffset);
ccb = sizeof(szUniqueId)/sizeof(szUniqueId[0]);
if (CryptBinaryToString (pbyOutBuffer + pMountPoints->MountPoints[i].UniqueIdOffset,
pMountPoints->MountPoints[i].UniqueIdLength,
CRYPT_STRING_BASE64,
szUniqueId, &ccb))
_tprintf (TEXT(" UniqueId=%s\n"), szUniqueId);
else
_tprintf (TEXT(" UniqueId=%.*ls\n"),
pMountPoints->MountPoints[i].UniqueIdLength/sizeof(WCHAR),
pbyOutBuffer + pMountPoints->MountPoints[i].UniqueIdOffset);
}
}
pbyInBuffer = (PBYTE) LocalFree (pbyInBuffer);
pbyOutBuffer = (PBYTE) LocalFree (pbyOutBuffer);
}
pszLogicalDrives = (LPTSTR) LocalFree (pszLogicalDrives);
bSuccess = CloseHandle (hMountMgr);
return 0;
}
if produce on my computer the output like
\Device\HarddiskVolume3
#0:
Device=\Device\HarddiskVolume3
SymbolicLink=\DosDevices\C:
UniqueId=O5TWlQAAwBRIAAAA
#1:
Device=\Device\HarddiskVolume3
SymbolicLink=\??\Volume{12703dc4-bf56-11db-8c6c-806e6f6e6963}
UniqueId=O5TWlQAAwBRIAAAA
...
\Device\CdRom2
#0:
Device=\Device\CdRom2
SymbolicLink=\DosDevices\L:
UniqueId=\??\USBSTOR#CdRom&Ven_HL-DT-ST&Prod_DVDRAM_GE20LU11&Rev_CL01#0010101640008B615&0#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
#1:
Device=\Device\CdRom2
SymbolicLink=\??\Volume{2c5f6a93-2b50-11df-aa6a-005056c00008}
UniqueId=\??\USBSTOR#CdRom&Ven_HL-DT-ST&Prod_DVDRAM_GE20LU11&Rev_CL01#0010101640008B615&0#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
\Device\HarddiskVolume8
#0:
Device=\Device\HarddiskVolume8
SymbolicLink=\DosDevices\N:
UniqueId=_??_USBSTOR#Disk&Ven_SanDisk&Prod_Cruzer&Rev_8.01#1740030578903736&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
#1:
Device=\Device\HarddiskVolume8
SymbolicLink=\??\Volume{ae08a3c8-71cf-11de-bc1d-005056c00008}
UniqueId=_??_USBSTOR#Disk&Ven_SanDisk&Prod_Cruzer&Rev_8.01#1740030578903736&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}