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
DeviceIoControlGetVolumeNameForVolumeMountPoint
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.aspxZur 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?
