Algorithm to initiate a disconnect for USB & 1394 Storage devices

Hi to all,

First a heart felt thank you to all of the folks that respond to this thread. Having been a passive reader for over a year, I have found an uncomparable wealth of information here. Thank you all.

Now my question: I want to complete a utility that can initate a USB or 1394 disconnect request much as the tray icon “remove device” function.

I issue the following IOCTL/FSCTL functions:
FSCTL_LOCK_VOLUME
FSCTL_DISMOUNT_VOLUME
IOCTL_STORAGE_RELEASE
FSCTL_UNLOCK_VOLUME

It would appear that I succeed in unmounting the file system, but I cannot get the device to disconnect. In fact the IOCTL_STORAGE_RELEASE generates an OS error of “Incorrect Function”.

Any help would be greatly appreciated. What follows is a very simpleton console based example. Drive “J:” is a USB attached hard disk drive.

Thanks again,

John Suykerbuyk

int main (char** argv,int argc)
{
HANDLE DevHandle = NULL;
BOOL bResult = FALSE;
DWORD ReturnBytes = 0;
SetLastError(NOERROR);
DevHandle = CreateFile
(“\\.\J:”, //Device Name
GENERIC_READ | GENERIC_WRITE , //Desired Access (neither read nor write)
FILE_SHARE_READ | FILE_SHARE_WRITE, //Share Mode (none)
NULL, //pointer to security attributes
OPEN_EXISTING, //How to create
0, //file attributes
NULL); //file handle whose attribs are to be copied.

if (INVALID_HANDLE_VALUE == DevHandle)
{
printf(“Device Open Failed:”);
PrintErrMsg();
return(FALSE);
}

bResult = DeviceIoControl(DevHandle, // device to be queried
FSCTL_LOCK_VOLUME, // operation to perform
NULL, // lpInBuffer is not used; must be NULL
0, // nInBufferSize is not used; must be zero
NULL, // lpOutBuffer is not used; must be NULL
0, // nOutBufferSize is not used;
// must be zero
(LPDWORD) &ReturnBytes, // pointer to variable to receive
// output byte count
(LPOVERLAPPED) NULL);// pointer to OVERLAPPED structure
// for asynchronous operation

if (!bResult)
{
printf(“Lock failed:”);
PrintErrMsg();
}

bResult = DeviceIoControl(DevHandle, // device to be queried
FSCTL_DISMOUNT_VOLUME, // operation to perform
NULL, // lpInBuffer is not used; must be NULL
0, // nInBufferSize is not used; must be zero
NULL, // lpOutBuffer is not used; must be NULL
0, // nOutBufferSize is not used;
// must be zero
(LPDWORD) &ReturnBytes, // pointer to variable to receive
// output byte count
(LPOVERLAPPED) NULL);// pointer to OVERLAPPED structure
// for asynchronous operation

if (!bResult)
{
printf(“Dismount failed:”);
PrintErrMsg();
}

else
{
bResult = DeviceIoControl(DevHandle, // device to be queried
IOCTL_STORAGE_RELEASE, // operation to perform //IOCTL_STORAGE_RELEASE
NULL, // lpInBuffer is not used; must be NULL
0, // nInBufferSize is not used; must be zero
NULL, // lpOutBuffer is not used; must be NULL
0, // nOutBufferSize is not used;
// must be zero
(LPDWORD) &ReturnBytes, // pointer to variable to receive
// output byte count
(LPOVERLAPPED) NULL); // pointer to OVERLAPPED structure
// for asynchronous operation

if (!bResult)
{
printf(“Eject failed:”);
PrintErrMsg();
}
}

bResult = DeviceIoControl(DevHandle, // device to be queried
FSCTL_UNLOCK_VOLUME, // operation to perform
NULL, // lpInBuffer is not used; must be NULL
0, // nInBufferSize is not used; must be zero
NULL, // lpOutBuffer is not used; must be NULL
0, // nOutBufferSize is not used;
// must be zero
(LPDWORD) &ReturnBytes, // pointer to variable to receive
// output byte count
(LPOVERLAPPED) NULL);// pointer to OVERLAPPED structure
// for asynchronous operation

if (!bResult)
{
printf(“UnLock failed:”);
PrintErrMsg();
}

CloseHandle(DevHandle);
return (bResult);

}

John Suykerbuyk wrote:

Now my question: I want to complete a utility that can initate a USB or 1394 disconnect request much as the tray icon “remove device” function.

I issue the following IOCTL/FSCTL functions:
FSCTL_LOCK_VOLUME
FSCTL_DISMOUNT_VOLUME

And at this point, you no longer have a valid handle to the volume. The
MSDN says:

A dismounted volume has the following properties:

* There are no open files.
* The operating system does not “know” about the volume.

No surprise that subsequent calls fail.

John,

you wrote on Tuesday, September 23, 2003, 21:58:18:

JS> Now my question: I want to complete a utility that can initate a USB
JS> or 1394 disconnect request much as the tray icon “remove device”
JS> function.

I believe you should be looking into CM_Request_Device_Eject(). It
should not be mandatory to lock/dismount the volume.

Ralf.

Thank you. The MSDN that I got with our VC6 install makes no mention of
any of the CM_ functions. For others who search for this information, the
MSDN site at this link describes the family of functions to solve this
problem:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/install/hh/install/cfgmgrfn_029e.asp

Thanks again,

John Suykerbuyk

John,

you wrote on Tuesday, September 23, 2003, 21:58:18:

JS> Now my question: I want to complete a utility that can initate a USB
JS> or 1394 disconnect request much as the tray icon “remove device”
JS> function.

I believe you should be looking into CM_Request_Device_Eject(). It
should not be mandatory to lock/dismount the volume.

Ralf.

John,

you wrote on Tuesday, September 23, 2003, 23:23:21:

> I believe you should be looking into CM_Request_Device_Eject(). It
> should not be mandatory to lock/dismount the volume.

JS> Thank you. The MSDN that I got with our VC6 install makes no mention of
JS> any of the CM_ functions. For others who search for this information, the
JS> MSDN site at this link describes the family of functions to solve this
JS> problem:
JS> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/install/hh/install/cfgmgrfn_029e.asp

All the CM_* functions are documented in the DDK.

Ralf.

> Now my question: I want to complete a utility that can initate a USB or 1394
disconnect

request much as the tray icon “remove device” function.

Try using CM_Request_Device_Eject.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com