mbr eines usb-sticks lesen/schreiben



  • Ich suche eine Möglichkeit, die mir direkten Zugriff auf den MBR gibt. Kann mir da einer helfen?

    ralf



  • Wenn das Volume bekannt ist, kann man mit CreateFile, ReadFile und WriteFile darauf zugreifen. Die ersten 512 Byte sollten dann der Bootsektor sein. Falls das Volume noch nicht bekannt ist, hier ein paar Funktionen, um USB-Devices zu ermitteln und Volumes zuzuordnen:

    SetupDiGetClassDevs
    SetupDiEnumDeviceInterfaces
    SetupDiGetDeviceInterfaceDetail
    SetupDiGetDeviceRegistryProperty
    SetupDiGetDeviceInstanceId
    DeviceIoControl

    GetVolumeNameForVolumeMountPoint
    GetVolumeInformation
    GetVolumePathNamesForVolumeName



  • Mit Createfile kann man lediglich auf den Bootsector aber nicht auf den MBR zugreifen. Gibt es denn keine elegante Möglichkeit ähnlich dieser?



  • Wenn Du den Device-Namen hast, dann kannst Du auch auf den MBR zugreifen, oder?



  • Also ich bin mir da nicht ganz sicher, aber ein USB-Sick sollte eigentlich keinen MBR haben, sondern nur einen einfachen Bootsector, da sich auf dem Stick auch nur eine Partition (idR FAT formatiert) befindet. Gegenteiliges wäre mir jetzt nicht bekannt. Ich kenne MBRs eigentlich nur bei Festplatten.

    Der Link in meiner Signatur weist auf meine Homepage, auf der ein von mit geschriebenes USB Image Tool zum Download steht, welches komplette Images von einem USB-Stick liest. Die ersten 512 Byte des Image sollten dabei der Bootsector sein. Der Zugriff erfolgt in meinem Tool auch wie oben beschrieben.

    -edit-
    Habe mal ein wenig weitergesucht. Scheinbar kann ein USB-Stick auch als Festplatte formatiert werden. Dies ist aber wohl nicht mit Windows-Bordmitteln möglich und wohl auch eher ungewöhnlich.

    Siehe: http://www.wintotal.de/Artikel/usbstick/usbstick.php (ganz unten)

    Werde ich mir auch mal genauer ansehen. MBR auf USB-Sticks kannte ich auch noch nicht. Muss dann auch mal probieren, ob der Zugriff über das Device-Handle funktioniert, da dann ja mehrere Volumes auf dem Stick sein können. Ich habe so in Erinnerung, dass dies irgendwie nicht ganz so klappte, wie ich wollte.



  • Also ich hab jetzt eine ganze Weile mit dem Beispiel hier herumgespielt:

    http://msdn2.microsoft.com/en-us/library/aa363250.aspx
    

    Zur Identifikiation des Laufwerks habe ich den "SPDRP_DEVTYPE" Parameter mit der Funktion "SetupDiGetDeviceRegistryProperty" probiert was aber nicht funktioniert hat. Mit dem Parameter "SPDRP_CLASS" kann ich aber schonmal auf "DiskDrive" testen um das Laufwerk (oder die Laufwerke) zu identifizieren.

    Mit der Funktion "SetupDiEnumDeviceInterfaces" komme ich allerdings überhaupt nicht weiter. Was muss ich hier beim 3. Parameter angeben? Ich habe die GUID der "SP_DEVINFO_DATA" Struktur genommen, was aber nicht funktioniert. Ist es möglich ein Beispiel für diese Funktion zu bekommen? Bin leider zu neu für die Windows API.

    ralf



  • Ich bin mal so frei und poste mal einen entscheidenden Teil meines Programms als Anschauungsobjekt. Nicht erschrecken, vielleicht hilft es ja weiter. Habe damals alles selber ausprobiert und im Internet zusammengesucht. Nach den richtigen GUIDs habe ich auch lange gesucht. Ein MBR auf USB-Sticks ist aber nicht unterstützt. Da muss ich auch erstmal schauen.

    typedef struct STRUCT_USB_DEVICE_INFO
    {
       DWORD                            dwDevice;
       TCHAR                            szFriendlyname [MAX_NAME];
       TCHAR                            szDeviceID     [MAX_NAME];
       TCHAR                            szVolumename1  [MAX_NAME];
       TCHAR                            szVolumename2  [MAX_NAME];
       TCHAR                            szVolumeFS     [MAX_NAME];
       TCHAR                            szVolumePath   [MAX_PATH];
       TCHAR                            szDevicePath   [MAX_PATH];
    
       DWORD                            dwSerial;
       DWORD                            dwComponentlength;
       DWORD                            dwFilesystemflags;
    
       DISK_GEOMETRY                    disk_geo;
    
       LARGE_INTEGER                    iBytes_physical;
       ULARGE_INTEGER                   iBytes_available;
       ULARGE_INTEGER                   iBytes_total;
       ULARGE_INTEGER                   iBytes_free;
    
       struct STRUCT_USB_DEVICE_INFO   *next;
    } USB_DEVICE_INFO;
    
    /*---------------------------------------------------------------------------*\
      FindDevices - USB-Geräte suchen
    \*---------------------------------------------------------------------------*/
    BOOL CALLBACK FindDevices()
    {
       GUID                             l_guid = { 0x53f56307L, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } };
    
       HANDLE                           l_hFile = 0;
       HDEVINFO                         l_hDevInfo = 0;
    
       SP_DEVINFO_DATA                  l_devinfo;
       SP_DEVICE_INTERFACE_DATA         l_devdata;
       SP_DEVICE_INTERFACE_DETAIL_DATA  l_devdata_detail;
       PSP_DEVICE_INTERFACE_DETAIL_DATA l_pdevdata_detail = NULL;
       GET_LENGTH_INFORMATION           l_length_info;
    
       USB_DEVICE_INFO                  l_usb;
    
       DWORD                            l_dwEnum = 0;
       DWORD                            l_dwType = 0;
       DWORD                            l_dwSize = 0;
       DWORD                            l_dwSize_Detail = 0;
    
       //--- Deviceliste ermitteln
       l_dwEnum = 0;
       l_hDevInfo = SetupDiGetClassDevs(&l_guid, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
       if(l_hDevInfo != INVALID_HANDLE_VALUE)
       {
          //--- Groessen der Strukturen belegen
          l_devinfo.cbSize = sizeof(l_devinfo);
          l_devdata.cbSize = sizeof(l_devdata);
    
          //--- Devices enumerieren
          while(SetupDiEnumDeviceInterfaces(l_hDevInfo, NULL, &l_guid, l_dwEnum, &l_devdata) == TRUE)
          {
             //--- Puffer initialisieren
             memset(&l_usb, 0, sizeof(l_usb));
    
             //--- Benoetigte Bytes fuer Detaildaten ermitteln
             if(SetupDiGetDeviceInterfaceDetail(l_hDevInfo, &l_devdata, NULL, 0, &l_dwSize_Detail, NULL) == FALSE)
             {
                if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
                {
                   l_pdevdata_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(l_dwSize_Detail);
                   l_pdevdata_detail->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);
    
                   //--- DeviceDetail und DeviceInfo ermitteln
                   if(SetupDiGetDeviceInterfaceDetail(l_hDevInfo, &l_devdata, l_pdevdata_detail, l_dwSize_Detail, &l_dwSize_Detail, &l_devinfo) == TRUE)
                   {
                      //--- Registryinformationen auslesen
                      l_dwSize = _countof(l_usb.szFriendlyname);
                      SetupDiGetDeviceRegistryProperty(l_hDevInfo, &l_devinfo, SPDRP_FRIENDLYNAME, &l_dwType, (UCHAR*)l_usb.szFriendlyname, l_dwSize, NULL);
    
                      //--- Handle auf das Gerät öffnen
                      l_hFile = CreateFile(l_pdevdata_detail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
                      if(l_hFile != INVALID_HANDLE_VALUE)
                      {      
                         //--- Device-ID ermitteln
                         if(SetupDiGetDeviceInstanceId(l_hDevInfo, &l_devinfo, l_usb.szDeviceID, _countof(l_usb.szDeviceID), &l_dwSize) == TRUE)
                         {
                            if(DeviceIoControl(l_hFile, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &l_usb.disk_geo, sizeof(l_usb.disk_geo), &l_dwSize, NULL) > 0)
                            {
                               //--- Prüfung af entfernbares Laufwerk
                               if(l_usb.disk_geo.MediaType == RemovableMedia)
                               {  
                                  l_usb.dwDevice = l_devinfo.DevInst;
    
                                  //--- Größe des Laufwerks ermitteln
                                  if(DeviceIoControl(l_hFile, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &l_length_info, sizeof(l_length_info), &l_dwSize, NULL) > 0)
                                  {
                                     l_usb.iBytes_physical  = l_length_info.Length;
                                     StringCchCopy(l_usb.szDevicePath, _countof(l_usb.szDevicePath), l_pdevdata_detail->DevicePath);
    
                                     //--- Listenelement hinzufügen
                                     if(usb_anchor == NULL)
                                     {
                                        usb_anchor = (USB_DEVICE_INFO *) malloc(sizeof(l_usb));
                                        memcpy(usb_anchor, &l_usb, sizeof(l_usb));
                                        usb_anchor->next = NULL;
                                     }
                                     else
                                     {
                                        usb_current = usb_anchor;
                                        while(usb_current->next != NULL)
                                        {
                                           usb_current = usb_current->next;
                                        }
                                        usb_current->next = (USB_DEVICE_INFO *) malloc(sizeof(l_usb));
                                        memcpy(usb_current->next, &l_usb, sizeof(l_usb));
                                        usb_current->next->next = NULL;
                                     }
                                  }
                               }
                            }
                         }
                         CloseHandle(l_hFile);
                         l_hFile = 0;
                      }
                   }
                   free(l_pdevdata_detail);
                   l_pdevdata_detail = NULL;
                }
             }
    
             //--- Naechstes Device prüfen
             l_dwEnum++;
          }
    
          //--- Deviceliste wieder feigeben
          SetupDiDestroyDeviceInfoList(l_hDevInfo);
          return TRUE;
       }
       else
       {
          return FALSE;
       }
    }
    /*---------------------------------------------------------------------------*\
      FindVolumes - USB-Laufwerke zu den USB-Geräten suchen
    \*---------------------------------------------------------------------------*/
    BOOL CALLBACK FindVolumes()
    {
       GUID                             l_guid_vol = { 0x53f5630dL, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } };
    
       HDEVINFO                         l_hDevInfo;
       DEVINST                          l_DevParent;
    
       SP_DEVINFO_DATA                  l_devinfo;
       SP_DEVICE_INTERFACE_DATA         l_devdata;
       PSP_DEVICE_INTERFACE_DETAIL_DATA l_pdevdata_detail;
    
       BOOL                             l_dwReturn;
       DWORD                            l_dwEnum = 0;
       DWORD                            l_dwSize = 0;
       DWORD                            l_dwSize_Detail = 0;
    
       TCHAR                            l_szBuffer[MAX_NAME];
    
       //--- Deviceliste
       l_dwEnum = 0;
       l_hDevInfo = SetupDiGetClassDevs(&l_guid_vol, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
       if(l_hDevInfo != INVALID_HANDLE_VALUE)
       {
    
          //--- Groessen der Strukturen belegen
          l_devinfo.cbSize = sizeof(l_devinfo);
          l_devdata.cbSize = sizeof(l_devdata);
    
         //--- Volumes enumerieren
          while(SetupDiEnumDeviceInterfaces(l_hDevInfo, NULL, &l_guid_vol, l_dwEnum, &l_devdata) == TRUE)
          {     
             //--- Benoetigte Bytes fuer Detaildaten ermitteln
             if(SetupDiGetDeviceInterfaceDetail(l_hDevInfo, &l_devdata, NULL, 0, &l_dwSize_Detail, NULL) == FALSE)
             {
                if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
                {
                   l_pdevdata_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(l_dwSize_Detail);
                   l_pdevdata_detail->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);
    
                   //--- DeviceDetail und DeviceInfo ermitteln
                   if(SetupDiGetDeviceInterfaceDetail(l_hDevInfo, &l_devdata, l_pdevdata_detail, l_dwSize_Detail, &l_dwSize_Detail, &l_devinfo) == TRUE)
                   {
                      //--- DeviceInfo und DeviceID ermitteln
                      if(SetupDiGetDeviceInstanceId(l_hDevInfo, &l_devinfo, l_szBuffer, _countof(l_szBuffer), &l_dwSize) == TRUE)
                      {
                         CM_Get_Parent(&l_DevParent,l_devinfo.DevInst, 0);
                         CM_Get_Device_ID(l_DevParent, l_szBuffer, _countof(l_szBuffer), 0);
    
                         usb_current = usb_anchor; 
                         while(usb_current != NULL)
                         {
                            if(lstrcmp(l_szBuffer, usb_current->szDeviceID) == 0)
                            {
                               StringCchCopy(l_szBuffer, _countof(l_szBuffer), l_pdevdata_detail->DevicePath);
                               StringCchCat(l_szBuffer, _countof(l_szBuffer), TEXT("\\"));
    
                               GetVolumeNameForVolumeMountPoint(l_szBuffer, usb_current->szVolumename1, _countof(usb_current->szVolumename1));
                               GetVolumeInformation(l_szBuffer, usb_current->szVolumename2, _countof(usb_current->szVolumename2), &usb_current->dwSerial, &usb_current->dwComponentlength, &usb_current->dwFilesystemflags, usb_current->szVolumeFS, _countof(usb_current->szVolumeFS));
    
                               //--- Funktion unter Win2000 nicht verfügbar
                               if((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0))
                               {
                                  StringCchCopy(usb_current->szVolumePath, _countof(usb_current->szVolumePath), TEXT(""));
                                  usb_current->iBytes_available.QuadPart = 0;
                                  usb_current->iBytes_total.QuadPart = 0;
                                  usb_current->iBytes_free.QuadPart = 0;
                               }
                               else
                               {
                                  GetVolumePathNamesForVolumeName(usb_current->szVolumename1, usb_current->szVolumePath, _countof(usb_current->szVolumePath), &l_dwSize);
                                  GetDiskFreeSpaceEx(usb_current->szVolumePath, &usb_current->iBytes_available, &usb_current->iBytes_total, &usb_current->iBytes_free);
                               }
                            }
    
                            usb_current = usb_current->next;
                         }
                      }
                   }
                   free(l_pdevdata_detail);
                }
             }
             l_dwEnum++;
          }
    
          SetupDiDestroyDeviceInfoList(l_hDevInfo);
    
          return TRUE;
       }
       else
       {
          return FALSE;
       }
    


  • Deine Beispiel war sehr aufschlussreich - danke. Allerdings hatte ich am Anfang Probleme mit dem sizeof Parameter für die "SetupDiGetDeviceInterfaceDetail"-Funktion. Aufgrund der Datenausrichtung lieferte der Compiler einen anderen Wert wie die Funktion eigentlich erwartet hat. Dadurch ist diese dauernd fehlgeschlagen. Auf jeden Fall habe ich jetzt Zugriff auf den MBR.

    Dank' an euch alle :)!



  • Was hast du denn nun entscheidendes geändert? 😕


Anmelden zum Antworten