我正在使用Win32 API(我通常不使用它)在用户请求上以编程方式弹出USB设备。从上下搜索网页,下面的代码就是我想到的。你可以看到,我的CreateFile()调用用于为dwIoControlCode参数传递GENERIC_READ | GENERIC_WRITE,但是当我调试时,我得到了一个值为INVALID_HANDLE_VALUE的句柄。在我对FormatMessage()的调用中,GetLastError()调用返回了一个代码,该代码翻译为“访问被拒绝”。环顾四周,我看到有人说通过0而不是GENERIC_READ | GENERIC_WRITE。我试过了,我得到了一个句柄,不再是一个不好的句柄值。使用非错误句柄值,我继续使用后续代码。使用CreateFile访问USB以弹出 - 不能正常工作
下一次调用DeviceIoControl()(GetHandleInformation()和DeviceIoControl稍后出于调试目的),将dwIoControlCode参数传递给FSCTL_LOCK_VOLUME,并将调用返回false,并将GetLastError( )返回代码翻译为“错误的功能”。我在此之前插入了调用GetHandleInformation()和DeviceIoControl(...,IOCTL_STORAGE_CHECK_VERIFY,...)以检查我的句柄。 GetHandleInformation()返回true,所以听起来不错。但是,DeviceIoControl(...,IOCTL_STORAGE_CHECK_VERIFY,...)返回false,GetLastError()返回代码转换为“Access is denied”。我还没有能够通过这一点。
这个代码或其变种,是由互联网上的许多人建议,但它不适合我。我希望有人能指出我要去哪里错了。我使用MSVC2010编译器在Win7 64位上进行编译。
感谢您的任何帮助。
#include <windows.h>
void ejectDrive(char driveletter)
{
DWORD dwRet = 0;
DWORD retSize;
LPTSTR pTemp=NULL;
bool ok = false;
char devicepath[7];
char format[] = "\\\\.\\?:";
wchar_t wtext[7];
strcpy_s(devicepath, format);
devicepath[4] = driveletter;
mbstowcs(wtext, devicepath,strlen(devicepath)+1);
HANDLE hVol = CreateFile(wtext, 0 /*GENERIC_READ | GENERIC_WRITE*/,
FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (hVol == INVALID_HANDLE_VALUE)
{
retSize=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_FROM_SYSTEM|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&pTemp,
0,
NULL);
return;
}
LPDWORD lpdwFlags;
ok = GetHandleInformation(hVol, lpdwFlags);
retSize=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_FROM_SYSTEM|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&pTemp,
0,
NULL);
ok = DeviceIoControl(hVol, IOCTL_STORAGE_CHECK_VERIFY, NULL,0,NULL, 0, lpdwFlags, 0);
if(!ok)
{
retSize=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_FROM_SYSTEM|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&pTemp,
0,
NULL);
return;
}
ok = DeviceIoControl(hVol, FSCTL_LOCK_VOLUME, 0, 0, 0, 0, &dwRet, 0);
if(!ok)
{
retSize=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_FROM_SYSTEM|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&pTemp,
0,
NULL);
return;
}
if(!DeviceIoControl(hVol, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0, &dwRet, 0))
{
return;
}
DeviceIoControl(hVol, IOCTL_STORAGE_EJECT_MEDIA, 0, 0, 0, 0, &dwRet, 0);
CloseHandle(hVol);
}
尝试用'GENERIC_READ'打开句柄。另请注意,只有媒体可访问时,DeviceIoControl才会返回true(根据[IOCTL_STORAGE_CHECK_VERIFY文档](http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa363404%28v=vs)。 85%29.aspx))。 – 2015-01-09 20:24:39
根据http://stackoverflow.com/q/3918248/103167您将需要'GENERIC_READ | GENERIC_WRITE'来执行弹出操作。因此,通过在具有足够设备权限的用户上下文中运行而不是通过打开0访问来解决'CreateFile'故障。 – 2015-01-09 20:36:42
另外,您可能需要打开PhysicalDrive设备,而不是音量。 – 2015-01-09 20:37:29