c ++ - Ugyldigt håndtag, når du ringer til IOCTL\_STORAGE\_GET\_MEDIA\_SERIAL\_NUMBER

Indlæg af Hanne Mølgaard Plasc

Problem



Enhver derude har erfaring med c/c ++ IOCTL opkald?
Dybest set prøver jeg at identificere, hvilken port en USB-hukommelse er tilsluttet.
Jeg har alle USB info og har volumen info. Angiveligt at forbinde disse 2 blokke med info Jeg har brug for enten driver-nøgle eller serienummer.
Men når jeg ringer DeviceIoControl får jeg et ugyldigt håndtag som 'sidste fejlkode'


Min drive USB-drev monteret på en mappe i c: \ (ikke et drevbogstav) Se nedenfor


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

dwAccessFlags = GENERIC\_READ | GENERIC\_WRITE;  

hVolume = CreateFile(L"C:\_USBMP1",
    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;

Bedste reference


Hvis du ser afsnittet Oplysninger om DeviceIoControl-funktionen, står det: [10]



  For at hente et håndtag til enheden skal du ringe til CreateFile -funktionen med enten navnet på en enhed eller navnet på den driver, der er forbundet med en enhed. For at angive et enhedsnavn skal du bruge følgende format:

  \.DeviceName

  
  DeviceIoControl kan acceptere et håndtag til en bestemt enhed. For eksempel at åbne et håndtag til det logiske drev A: med CreateFile, angiv \.a:. Alternativt kan du bruge navnene \.PhysicalDrive0, \.PhysicalDrive1 og så videre til at åbne håndtag til de fysiske drev på et system.



Du åbner ikke et enhedshåndtag, og derfor vil DeviceIoControl ikke fungere for den pågældende sag.

Andre referencer 1


Det første store problem, jeg ser, er, at CreateFile-funktionen skal kaldes med FILE\_FLAG\_BACKUP\_SEMANTICS-flag for at få et gyldigt håndtag til en mappe. Så, for det første, prøv:


hVolume = CreateFile( L"C:\_USBMP1",  
                      dwAccessFlags,  
                      FILE\_SHARE\_READ | FILE\_SHARE\_WRITE,  
                      NULL,  
                      OPEN\_EXISTING,  
                      FILE\_FLAG\_BACKUP\_SEMANTICS,  
                      NULL );

Andre referencer 2


Hmmm ... Jeg tror, ​​at håndtaget, du får fra CreateFile, er håndtaget til den mappe, du har monteret dit drev til, i stedet for selve drevet. For at være sikker på at du får håndtaget til enheden, du ønsker, skal du bruge en enhedsvej, f.eks. \.DeviceHarddiskVolume1. WinObj eller DeviceTree kan sikkert hjælpe dig med at finde vejen til dit USB-drev. [11] [12]