INVALID_FUNCTION error when writing to HID file - c++

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?

Related

How to find all connected removable USB storage devices in Windows?

I'm writing a program that processes USB drives, to get information about connecting a new device, I signed up for a window message WM_DEVICECHANGE. But I, of course, do not receive messages about the devices that were connected before my program was launched. To process such devices, I wrote a search function, but I get a strange result. It finds my flash drive, but does not recognize it to be removable. Why?
Function
bool FindConnectedRemovableUsbstorDevices(std::list<std::wstring>& UsbList)
{
std::wstring ClassGuidString(L"{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}");
GUID ClassGuid;
BYTE buf[1024];
PSP_DEVICE_INTERFACE_DETAIL_DATA_W pspdidd = reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA_W>(buf);
SP_DEVICE_INTERFACE_DATA spdid;
SP_DEVINFO_DATA spdd;
DWORD size;
SP_DEVINFO_DATA dev_data;
DWORD properties;
if(NOERROR != CLSIDFromString(ClassGuidString.c_str(), &ClassGuid))
return false;
HDEVINFO dev_info = INVALID_HANDLE_VALUE;
dev_info = SetupDiGetClassDevs(&ClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (dev_info == INVALID_HANDLE_VALUE)
return false;
DWORD index = 0;
BOOL ret = FALSE;
spdid.cbSize = sizeof(spdid);
while (true)
{
ret = SetupDiEnumDeviceInterfaces(dev_info, NULL, &ClassGuid, index, &spdid);
if (!ret)
break;
size = 0;
SetupDiGetDeviceInterfaceDetail(dev_info, &spdid, NULL, 0, &size, NULL);
//Get required size
if (size == 0 || size >= sizeof(buf))
continue;
//prepare structs
ZeroMemory(reinterpret_cast<PVOID>(pspdidd), 1024);
pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!
ZeroMemory(reinterpret_cast<PVOID>(&spdd), sizeof(spdd));
spdd.cbSize = sizeof(spdd);
BOOL res = SetupDiGetDeviceInterfaceDetail(dev_info, &spdid, pspdidd, size, &size, &spdd);
//Get info
if (!res)
continue;
HANDLE drive = CreateFileW(pspdidd->DevicePath, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);//open device
if (drive == INVALID_HANDLE_VALUE)
continue;
printf("\n%S\r\n", pspdidd->DevicePath);
DWORD bytes_returned = 0;
BOOL b = DeviceIoControl(drive, IOCTL_STORAGE_CHECK_VERIFY2, NULL, 0, NULL, 0, &bytes_returned, NULL);
if (!b) //check is card reader?
{
printf("IOCTL_STORAGE_CHECK_VERIFY2 error = %d\r\n", GetLastError());
goto stop_process_device;
}
bytes_returned = 0;
STORAGE_DEVICE_NUMBER sdn;
//Get Drive number
b = DeviceIoControl(drive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &bytes_returned, NULL);
if (!b)
goto stop_process_device;
RtlZeroMemory(&dev_data, sizeof(SP_DEVINFO_DATA));
dev_data.cbSize = sizeof(dev_data);
if (SetupDiEnumDeviceInfo(dev_info, sdn.DeviceNumber, &dev_data))
{
//check property
b = SetupDiGetDeviceRegistryProperty(dev_info, &dev_data, SPDRP_REMOVAL_POLICY, NULL,
reinterpret_cast<PBYTE>(&properties), sizeof(properties), NULL);
if (b && properties != CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL)
{
UsbList.push_back(pspdidd->DevicePath);
printf("REMOVAL\r\n");
}
}
stop_process_device:
CloseHandle(drive);
index++;
}
SetupDiDestroyDeviceInfoList(dev_info);
return true;
}
And output
\\?\usbstor#disk&ven_generic-&prod_ms#ms-pro#hg&rev_1.00#20090703819900000&1#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
IOCTL_STORAGE_CHECK_VERIFY2 error = 21
\\?\ide#diskst3500418as_____________________________cc38____#5&5c6cfd6&0&1.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
REMOVAL
\\?\usbstor#disk&ven_generic-&prod_sd#mmc&rev_1.00#20090703819900000&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
IOCTL_STORAGE_CHECK_VERIFY2 error = 21
\\?\scsi#disk&ven_ocz&prod_revodrive3_x2#5&19ad1f72&0&000000#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
\\?\ide#diskst1000lm014-1ej164______________________sm30____#5&2ea7e938&0&0.1.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
\\?\usbstor#disk&ven_sandisk&prod_extreme&rev_0001#aa010823150434152862&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
\\?\ide#diskwdc_wd1002fbys-02a6b0___________________03.00c06#5&2ea7e938&0&0.0.0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
REMOVAL
Error 21 is empty card reader.
Sandisk is my flash. In Debug i saw that SetupDiGetDeviceRegistryProperty return property CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL, but i really don't know why...
If you just want to find the connected removable devices, there's a much simpler alternative using GetLogicalDriveStrings() and GetDriveType():
#define MAX_DRIVES 256
bool FindConnectedRemovableUsbstorDevices(std::list<std::wstring>& UsbList)
{
wchar_t drives[MAX_DRIVES];
wchar_t* temp = drives;
if (GetLogicalDriveStringsW(MAX_DRIVES, drives) == 0)
return false;
while (*temp != NULL)
{
if (GetDriveTypeW(temp) == 2 /* DRIVE_REMOVABLE */)
UsbList.push_back(temp);
// Go to the next drive
temp += lstrlenW(temp) + 1;
}
return true;
}
I don't know why my fisrt method of detection removable media works so strange, but method of RbMm works great. I send IOCTL query to every found device with IOCTL_STORAGE_QUERY_PROPERTY with StorageDeviceProperty and look for STORAGE_DEVICE_DESCRIPTOR.RemovableMedia field. All my devices recognized successfully and right.

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

CreateFileMapping for Directory

I have this function which gives the full file name(path) from the file handle. The only problem is CreateFileMapping fails for directory handles. Is there a workaround for it?
I get the handle using NtCreateFile()
ULONG status = NtCreatefile(&f, GENERIC_ALL, &oa, iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_OPEN_BY_FILE_ID , NULL, 0);
printf("status: %X, handle: %x\n", status, f);
AND
BOOL CHouseKeeper::GetFileNameFromHandle(HANDLE hFile)
{
BOOL bSuccess = FALSE;
TCHAR pszFilename[MAX_PATH+1];
HANDLE hFileMap;
// Get the file size.
DWORD dwFileSizeHi = 0;
DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);
if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
{
_tprintf(TEXT("Cannot map a file with a length of zero.\n"));
return FALSE;
}
// Create a file mapping object.
//It fails here if a directory handle is passed, it returns 0
hFileMap = CreateFileMapping(hFile,
NULL,
PAGE_READONLY,
0,
1,
NULL);
if (hFileMap)
{
// Create a file mapping to get the file name.
void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
if (pMem)
{
if (GetMappedFileName (GetCurrentProcess(),
pMem,
pszFilename,
MAX_PATH))
{
// Translate path with device name to drive letters.
TCHAR szTemp[BUFSIZE];
szTemp[0] = '\0';
if (GetLogicalDriveStrings(BUFSIZE-1, szTemp))
{
TCHAR szName[MAX_PATH];
TCHAR szDrive[3] = TEXT(" :");
BOOL bFound = FALSE;
TCHAR* p = szTemp;
do
{
// Copy the drive letter to the template string
*szDrive = *p;
// Look up each device name
if (QueryDosDevice(szDrive, szName, MAX_PATH))
{
size_t uNameLen = _tcslen(szName);
if (uNameLen < MAX_PATH)
{
bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0
&& *(pszFilename + uNameLen) == _T('\\');
if (bFound)
{
// Reconstruct pszFilename using szTempFile
// Replace device path with DOS path
TCHAR szTempFile[MAX_PATH];
StringCchPrintf(szTempFile,
MAX_PATH,
TEXT("%s%s"),
szDrive,
pszFilename+uNameLen);
StringCchCopyN(pszFilename, MAX_PATH+1, szTempFile, _tcslen(szTempFile));
}
}
}
// Go to the next NULL character.
while (*p++);
} while (!bFound && *p); // end of string
}
}
bSuccess = TRUE;
UnmapViewOfFile(pMem);
}
CloseHandle(hFileMap);
}else {
wcout<<GetLastError()<<endl;
}
_tprintf(TEXT("File name is %s\n"), pszFilename);
return(bSuccess);
}
You can use NtQueryInformationFile with FileNameInformation to retrieve the name associated with a file handle.

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}