使用CreateFile访问USB以弹出 - 无法正常工作

时间:2015-01-09 20:12:41

标签: visual-studio-2010 winapi usb windows-7-x64 access-denied

我正在编写代码,使用Win32 API(我通常不使用)以编程方式在用户请求中弹出USB设备。从上下搜索网络,下面的代码是我提出的。

正如您所看到的,我对CreateFile()的调用曾用于为dwIoControlCode参数传递GENERIC_READ | GENERIC_WRITE,但是当我调试时,我得到了一个值为INVALID_HANDLE_VALUE的句柄。在我对FormatMessage()的调用中,GetLastError()调用返回了一个转换为“Access is denied”的代码。环顾四周,我看到有人说传递0而不是GENERIC_READ | GENERIC_WRITE。我试过了,我得到了一个句柄,不再是一个糟糕的句柄值。使用非坏句柄值,我继续使用后续代码。

接下来的调用是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);
}

1 个答案:

答案 0 :(得分:0)

我在我的项目中使用了一个解决方案,我在this SO answer中详细介绍。

但是,我确实根据今年早些时候的SO问题修改了对CreateFile的调用 - 以下签名:

// C#
hVolume = CreateFile(@"\\.\A:", GENERIC_READ,
                                FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero,
                                OPEN_EXISTING, 0, IntPtr.Zero);

我的应用程序调用它在没有提升权限的情况下运行,并成功弹出驱动器。

相关问题