bekanntlich zeigt windows nur eine Partition auf einem USB-Stick. Tatsächlich wird immer nur der erste Partition-Eintrag der Partitionstabelle des mbr gezeigt und ist in windooof zugreifbar.
Also liegt die Idee nahe dieses Manko zu beseitigen, wenn mehrere Partitionen in windoof verwendet werden sollen. Hierzu habe ich zwei Partitionen auf einen USB-Stick angelegt und Mithilfe eines hexeditors die Einträge geändert, anschließend mit dd auf den Stick geschrieben.
Der Wunsch ist aber das zu automatisieren. So ist also die Idee für mein erstes Python-Script entstanden:
Anforderungen an das Script:
1. - Usb-Stick im System finden
2. - mbr auslesen
3. - Partitonseintrag ändern/tauschen
4. - Änderungen in mbr schreiben
5. - das Script ausführbar machen, damit es auch auch ohne Python-Umgebung läuft
Im Prinzip sind die oben aufgeführten Forderungen erfüllt, doch sind Einschränkungen vorhanden.
Grenzen des Scripts:
a : Der ganze Vorgang muss als "Administrator" ausgeführt werden. Ich habe keine Fehlerbehandlung eingebaut, um ein unbeabsichtigtes starten zu verhindern.
b : Nur der Usb-Stick sollte eingesteckt sein, wenn das Script verwendet wird.
c : Ich habe keine Fenster verwendet, das Script läuft in der Konsole (cmd.exe)
d : Python kann nicht die mbr schreiben. Also habe ich auf dd.exe zurückgegriffen.
e : Das starten der dd.exe über subprocess habe ich nicht hinbekommen. Ich lasse das Script eine Batch-Datei erstellen, der ebenfalls als "Administrator" gestartet werden muss.
Die Programmierung ist etwas holprig, da dies mein erstes Python-Script ist und Funktionalität vorrangig war. So habe ich auch auf eine Struktur durch class und def verzichtet. Hier gibt einiges zu verbessern.
Über Ideen und Vorschläge wäre ich sehr froh.
Viele Grüße
Hier mein Code:
Code: Alles auswählen
"""
mbr switch v 0.01
Switch any_to_first partition entry in mbr
"""
import struct
import sys
import win32api
import os
import win32com.client
import subprocess
import time
"""
give user some information and ask to proceed
"""
print "WARNING!! Connect only USB-Stick to switch MBR !!"
# 1. Win32_DiskDrive
strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2")
colItems = objSWbemServices.ExecQuery("SELECT * FROM Win32_DiskDrive WHERE InterfaceType = \"USB\"")
DiskDrive_DeviceID = colItems[0].DeviceID
DiskDrive_Caption = colItems[0].Caption
print DiskDrive_DeviceID, " - ", DiskDrive_Caption
strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2")
colItems = objSWbemServices.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE DriveType = 2")
for objItem in colItems:
if objItem.Caption != None:
VolmeCptn = objItem.Caption
if objItem.VolumeName != None:
VolmeNme = objItem.VolumeName
print "Name: %s on %s " % (VolmeNme, VolmeCptn)
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
gof = raw_input('Proceed with switching to MBR? [y] Insert number of Stick? [c] Abort {n] : ')
if gof != 'y':
if gof == 'c':
ins = raw_input("Insert number \\.\PhysicalDrive: ")
inss = str(ins)
mbr_fle = "\\\\.\\PhysicalDrive" + inss
else:
sys.exit(0) # stopped
# --filenames--------------------------------------------------------------------------
mbr_new = VolmeNme
mbr_flew = "mbr-" + mbr_new + ".bin"
mbr_fle = DiskDrive_DeviceID
mbr_dd = "mbr_wrt.bat"
mbr_f = mbr_flew
# --read/write data--------------------------------------------------------------------
with open(mbr_fle, 'rb') as f: # read mbr in binary mode
mbr = f.read(512) # 512 if mbr
# --class mbr--------------------------------------------------------------------------
sgntr = mbr[510:]
if struct.unpack('<BB', sgntr)[0] != 85: # check if: 55AA or AA55
print 'I go, bye'
sys.exit(0) # no mbr --> nothing to do
prtswt = 0
strt = 446
end = 462
boot_strct = mbr[0:446] # read to fill data for write
part_tble = [] # part. entry go in
part_sktr = [] # start sector of every part.
bootI = [] # maybe important later version
x = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
for prttn in range(4): # read part entry in list (Array)
bt = struct.unpack('<B', mbr[strt:strt + 1])[0]
if bt == 128:
bootI.append("+") # Check if bootable
else:
bootI.append("-") # or not
part_tble.append(mbr[strt:end]) # read Partitiontable
part_sktr.append(mbr[strt + 8:strt + 12]) # read startsectors of partitions
strt = end # change start and end number
end = end + 16
if part_tble[prttn] != x: # drop empty partition values
prtswt += 1 # increase for next loop
# -------------------------------------------------------------------------------------
f.close()
# --switch data------------------------------------------------------------------------
if prtswt < 2:
sys.exit(0) # only 1 Partition --> nothing to switch
elif prtswt < 3:
ins = 1 # 2 Partitions --> switch 1, 2 => 2, 1
elif prtswt > 2:
n = 0
print 'Num of Partititions:', prtswt # >2 Partitions --> ask than switch
while n <= 3:
sektors = struct.unpack("<HH", part_sktr[n])[0]
boot = bootI[n]
nm = n + 1
if sektors != 0:
print "Partition: '%d' StartSektor: '%d' Boot: %s " % (nm, sektors, boot)
n += 1
ins = input("which partiton to switch?: ")
ins -= 1 # list goes 0 - 3, so reduce ins
# --execute switching------------------------------------------------------------------
part_tble.insert(0, part_tble[ins]) # [0,ins, 2, 3] --> [ins, 0, 1, 2, 3] --> [ins, 1, 2, 3, 4]
del part_tble[ins + 1] # [ins, 1,"", 3, 4] --> [ins, 0, 1, 2, 3] --> [0, 1, 2, 3]
# --writing----------------------------------------------------------------------------
data = boot_strct + part_tble[0] + part_tble[1] + part_tble[2] + part_tble[3] + sgntr
ans = raw_input('Successfully switched. Write to MBR? [y/n] : ')
if ans == 'y':
with open(mbr_flew, 'wb') as wrf:
wrf.write(data)
wrf.close()
# --write batch for dd.exe-------------------------------------------------------------
par1 = "dd.exe if=" + mbr_f + " of=\\\\?\Device\Harddisk" + \
DiskDrive_DeviceID[-1] + "\Partition0 bs=512 count=1\n"
with open(mbr_dd, 'w') as cpy:
seq = ["@echo off\n", "cd /d %~dp0\n", par1, "pause"]
cpy.writelines( seq )
cpy.close()
print mbr_dd, " is ready to start dd.exe!"
time.sleep(3)
# --ToDo: run dd.exe with parameters: subprocess---------------------------------------
# --compile with pyinstaller------------------------------------------------------------
#C:\>pyinstaller -F swtchparttions_usb.py