Click to See Complete Forum and Search --> : about use DeviceIoControl() question


Goldbach
September 5th, 2008, 01:37 AM
I am try to use the following code to get information from CF card that plugs into USB card reader.
DeviceIoControl() return FALSE and GetLastError() return ERROR_SHARING_VIOLATION (32)
If I try to create PhysicalDrive1 (Fixed Hard Drive) and run the same code,
DeviceIoControl() return TRUE.
I don't know why there was a sharing violation error?


struct IDENTIFY_DEVICE_OUTDATA
{
SENDCMDOUTPARAMS SendCmdOutParam;
BYTE Data[IDENTIFY_BUFFER_SIZE - 1];
};

HANDLE hDevice = CreateFile(_T("\\\\.\\PhysicalDrive4"), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
return ;

IDENTIFY_DEVICE_OUTDATA sendCmdOutParam = {0};
SENDCMDINPARAMS sendCmd = {0};
sendCmd.irDriveRegs.bCommandReg = ID_CMD;
sendCmd.cBufferSize = IDENTIFY_BUFFER_SIZE;

const DWORD DFP_RECEIVE_DRIVE_DATA = 0x0007C088;
DWORD dwReturned = 0;
BOOL bRet = DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, &sendCmd, sizeof(SENDCMDINPARAMS),
&sendCmdOutParam, sizeof(IDENTIFY_DEVICE_OUTDATA), &dwReturned, NULL);

DWORD dwErr = 0;
if (bRet == FALSE)
dwErr = GetLastError();

CloseHandle(hDevice);

egawtry
September 5th, 2008, 09:42 AM
When using CreateFile directly on a device (not going through OS translation), you should NOT use GENERIC_READ or GENERIC_WRITE. Just put a 0 (zero) into the field. This is documented somewhere by MS, but I don't remember where.

I don't know if that will solve your problem, but it struck me immediately and solved a similar problem for me.

-Erik

Goldbach
September 7th, 2008, 09:25 PM
Thanks for your reply. I put 0 to instead GENERIC_READ | GENERIC_WRITE field, but DeviceIoControl() still return FALSE and GetLastError() return ERROR_ACCESS_DENIED (5).

egawtry
September 8th, 2008, 10:21 AM
Here is a chunk of code where I open a device:



// Get the device ID
HANDLE hDevice = ::CreateFileW(szDevice,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if( hDevice && hDevice != INVALID_HANDLE_VALUE )
{
DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(STORAGE_DEVICE_NUMBER), &dwRead, NULL);
CloseHandle(hDevice);

TRACE(_T("Link: Enum: Device Number: %lu\n"), sdn.DeviceNumber);

TRACE(_T("Link: Enum: Device Type: %lu\n"), (ULONG)sdn.DeviceType);

}
else
{
DWORD dwError = GetLastError();

TRACE(_T("Link: Enum: Device Type: %s %d:%s\n"), _T("Error! Cannot open Device!"), dwError, _GetLastErrorMessage(dwError));

}



It looks the same, so it may be the device path. I have noticed that sometimes a device will open with one name but not another. From Control Panel, look up the device, check the list of alternate names and try one of those. (It may be a full GUID based name.)

-Erik