// JP opened flex table

Click to See Complete Forum and Search --> : Question about CreateFile(), DevicePath, and IOCTLs


njuneardave
June 4th, 2008, 01:24 PM
So, I am trying to call CreateFile() to create a handle to communicate with a USB device, but once the handle is created, none of the IOCTL calls work (they all return with "request is not supported").

Here is the devicepath that is used as a parameter for CreateFile(). I found it using SetupDiGetDeviceInterfaceDetail():

\\?\usb#vid_0781&pid_5150#sndk4045240cd2300707#{a5dcbf10-6530-11d2-901f-00c04fb951ed}



The GUID i used on SetupDiGetClassDevs was: { 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
This is the USB Interface Class GUID

I then looped through HDEVINFO (retrieved from SetupDiGetClassDevs) with SetupDiEnumDeviceInfo, looking for the following GUID: { 0x36FC9E60, 0xC465, 0x11CF, { 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 } };
This is the class GUID for the USB drive itself


Once I find the matched GUID, I call SetupDiEnumDeviceInterfaces (using the USB interface GUID -- the first one i listed -- and the PSP_DEVINFO_DATA retrieved from SetupDiEnumDeviceInfo) to get the SP_DEVICE_INTERFACE_DATA.


the rest is pretty standard to get the devicepath. if I call CreateFile() explicitly ("\\\\.\E"), the IOCTL calls work fine. So, why won't they work if the device path is a pid/vid/guid? What can I do to fix the problem?



Thanks so much.



edit: here's some of the code:

static /*const*/ GUID GUID_DEVINTERFACE_USB_DEVICE =
{ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
static GUID GUID_USB_DRIVE =
{ 0x36FC9E60, 0xC465, 0x11CF, { 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 } };

const char* DEVICE_PID_VID = "vid_0781&pid_5150";

int main(int argc, char* argv[])
{
// Get device interface info set handle for all devices attached to system
HDEVINFO hDevInfo = SetupDiGetClassDevs(
&GUID_DEVINTERFACE_USB_DEVICE, /* CONST GUID * ClassGuid - USB class GUID */
NULL, /* PCTSTR Enumerator */
NULL, /* HWND hwndParent */
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE /* DWORD Flags */
);

// couldn't access HDEVINFO for present USB devices, so stop processing
if (hDevInfo == INVALID_HANDLE_VALUE)
{
printf("SetupDiClassDevs() failed. GetLastError() " \
"returns: 0x%x\n", GetLastError());
return 1;
}

printf("Device info set handle for all devices attached to " \
"system: 0x%x\n", hDevInfo);



////////////////////////////////////////////////////////////////////////
int index = 0;
SP_DEVINFO_DATA pDevInfoData;
ZeroMemory(&pDevInfoData, sizeof(SP_DEVINFO_DATA));
pDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

while (SetupDiEnumDeviceInfo(hDevInfo,index,&pDevInfoData))
{
if (pDevInfoData.ClassGuid == GUID_USB_DRIVE)
{
HANDLE hDevice;
HANDLE hEvent;
// Retrieve a context structure for a device interface of a device
// information set.
DWORD dwIndex = 0;
// contains interface GUID
SP_DEVICE_INTERFACE_DATA devInterfaceData;
// clear any preexisting data and reserve a block of data of required size
// defined by SP_DEVICE_INTERFACE_DATA. if this buffer is of any
// other size, SetupDiEnumDeviceInterfaces() will fail.
ZeroMemory(&devInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA));
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

while( SetupDiEnumDeviceInterfaces(
hDevInfo, /* HDEVINFO DeviceInfoSet */
&pDevInfoData, /* PSP_DEVINFO_DATA DeviceInfoData */
&GUID_DEVINTERFACE_USB_DEVICE, /* CONST GUID * InterfaceClassGuid */
dwIndex, /* DWORD member index */
&devInterfaceData /* PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData */
) )
{
dwIndex++;

ULONG devDetailDataSize;
/* Initial call to retrieve size of detail data buffer. First call is designed to fail
in order to obtain necessary buffer size. This is how the method was designed. */
SetupDiGetDeviceInterfaceDetail(
hDevInfo,
&devInterfaceData,
NULL,
0,
&devDetailDataSize,
NULL);

// using the returned value "devDetailDataSize", prepare devDetailData for insertion into SetupDiGetDeviceInterfaceDetail()
// points to struct which contains the device path
PSP_INTERFACE_DEVICE_DETAIL_DATA devDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc (devDetailDataSize);
if (devDetailData)
{
SP_DEVINFO_DATA devInfoData;

// set the cbSize of the two data structs to the required size for method to work
devDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

DWORD reqSize;

// get the information (namely, DevicePath) of the USB interface device
if ( !SetupDiGetDeviceInterfaceDetail(
hDevInfo,
&devInterfaceData,
devDetailData,
devDetailDataSize,
&reqSize,
NULL) )
{
SetupDiDestroyDeviceInfoList (hDevInfo);
return 1;
}

size_t nLength = strlen (devDetailData->DevicePath) + 1;
LPTSTR lpDevicePath = (LPTSTR)malloc (nLength * sizeof(TCHAR));
if (lpDevicePath)
{
StringCchCopy (lpDevicePath, nLength, devDetailData->DevicePath);
}
else
{
//bSuccess = FALSE;
}

// if the function call worked, we need to do some resizing and appending to prepare
// the DevicePath parameter for use in the CreateFile() method
if (NULL != _tcsstr(devDetailData->DevicePath, _T(DEVICE_PID_VID)))
{
hDevice = CreateFile(
lpDevicePath, //devDetailData->DevicePath, //"\\\\.\\E:"
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);

if (hDevice == INVALID_HANDLE_VALUE)
{
// error checking
printf("Failed to find or open the device.\n\n");
ShowError( GetLastError() );
return 1;
}

/* DWORD dwFileSize = GetFileSize(hDevice, 0);
LPBYTE lpBuffer = new BYTE[dwFileSize];
*/

printf("found device!\n\n");

free(devDetailData);

DWORD nBytesRead;
DWORD dwError;
CHAR pBuf[3];
//first byte specifies report ID
pBuf[0] = 0;
BOOL bResult;
OVERLAPPED gOverLapped;
DISK_GEOMETRY diskGeometry;

hEvent = CreateEvent(
NULL,
FALSE,
TRUE,
NULL);
if (hEvent == NULL)
{
printf("CreateEvent Failed!");
ShowError( GetLastError() );
CloseHandle(hDevice);
return 1;
}

// set up overlapped structure fields
gOverLapped.Offset = 0;
gOverLapped.OffsetHigh = 0;
gOverLapped.hEvent = hEvent;

// verify that sizeof(inBuffer >= nBytestoRead)
WaitForSingleObject(hEvent, 2000);
DWORD dwBytes;
bResult = DeviceIoControl(
hDevice,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&diskGeometry,
sizeof(DISK_GEOMETRY),
&dwBytes,
NULL);

njuneardave
June 5th, 2008, 03:51 PM
any help at all?

DreamShore
June 6th, 2008, 03:06 AM
Maybe, just maybe... You were trying to do some volume operations on a flash drive.

//JP added flex table