0

c/c++ IOCTL 呼び出しの経験がある人はいますか? 基本的に、USB メモリ スティックが接続されているポートを特定しようとしています。すべての USB 情報とボリューム情報があります。どうやら、これら 2 つの情報ブロックをリンクするには、ドライバー キーまたはシリアル番号が必要です。ただし、DeviceIoControl を呼び出すと、「最後のエラー コード」として無効なハンドルが表示されます

私のドライブ c:\ のディレクトリにマウントされた USB ドライブ (ドライブ文字ではありません) 以下を参照してください

//get a handle on the volume
HANDLE hVolume;
DWORD dwAccessFlags;

dwAccessFlags = GENERIC_READ | GENERIC_WRITE;  

hVolume = CreateFile(L"C:\_USB\MP1",
    dwAccessFlags,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    0,
    NULL );
if (hVolume == INVALID_HANDLE_VALUE) {
    printf("Invalid Handle");
}

//use the handle
MEDIA_SERIAL_NUMBER_DATA* pserialNumberData = new MEDIA_SERIAL_NUMBER_DATA;
wstring result;
//HANDLE hVolume = OpenVolume(vname.substr(0, vname.length() - 1).c_str());
DWORD   bytesReturned = 0;
LPDWORD lpBytesReturned = &bytesReturned;

OVERLAPPED over;
LPOVERLAPPED lpOver = &over;
BOOL success = 1;
success = DeviceIoControl(
    (HANDLE) hVolume,                      // handle to device
     IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, // dwIoControlCode
     NULL,                                  // lpInBuffer
     0,                                     // nInBufferSize
    (LPVOID) pserialNumberData,                  // output buffer
    (DWORD) sizeof(MEDIA_SERIAL_NUMBER_DATA),                       // size of output buffer
    (LPDWORD) lpBytesReturned,             // number of bytes returned
    (LPOVERLAPPED) lpOver            // OVERLAPPED structure
    );
wcout << L"--> GetSn() DeviceIoControl success " << success << endl;
wcout << L"--> GetSn() DeviceIoControl Last error number " << GetLastError() << endl;
wcout << L"--> GetSn() DeviceIoControl Bytes Returned " << bytesReturned << endl;
wcout << L"--> GetSn() DeviceIoControl struct size " << sizeof(MEDIA_SERIAL_NUMBER_DATA) << endl;
4

3 に答える 3

2

DeviceIoControl関数の備考セクションを見ると、次のように書かれています。

デバイスへのハンドルを取得するにはCreateFile、デバイスの名前またはデバイスに関連付けられているドライバーの名前を指定して関数を呼び出す必要があります。デバイス名を指定するには、次の形式を使用します。
\\.\DeviceName

DeviceIoControl は、特定のデバイスへのハンドルを受け入れることができます。たとえば、論理ドライブ A: のハンドルを開く場合はCreateFile、 を指定します\\.\a:\\.\PhysicalDrive0または、 、 などの名前を使用し\\.\PhysicalDrive1て、システム上の物理ドライブへのハンドルを開くこともできます。

デバイス ハンドルを開いていないため、DeviceIoControl はその場合には機能しません。

于 2012-03-21T16:44:12.180 に答える
2

最初の大きな問題は、ディレクトリへの有効なハンドルを取得するために、CreateFile 関数を FILE_FLAG_BACKUP_SEMANTICS フラグを指定して呼び出す必要があることです。したがって、まず、次のことを試してください。

hVolume = CreateFile( L"C:\_USB\MP1",  
                      dwAccessFlags,  
                      FILE_SHARE_READ | FILE_SHARE_WRITE,  
                      NULL,  
                      OPEN_EXISTING,  
                      FILE_FLAG_BACKUP_SEMANTICS,  
                      NULL );
于 2012-06-14T16:52:27.330 に答える
0

うーん...CreateFileから取得するハンドルは、ドライブ自体ではなく、ドライブをマウントしたディレクトリへのハンドルだと思います。必要なデバイスへのハンドルを確実に取得するには、デバイスパスを使用する必要があります\\.\Device\HarddiskVolume1WinObjまたはDeviceTreeは、おそらくUSBドライブへのパスを見つけるのに役立ちます。

于 2012-03-21T16:40:21.200 に答える