Seite 1 von 1

mbr von usb-stick switchen

Verfasst: Samstag 28. Juli 2018, 18:44
von xoric_pthy
Hallo,

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

Re: mbr von usb-stick switchen

Verfasst: Samstag 28. Juli 2018, 23:02
von __blackjack__
@xoric_pthy: Idee/Vorschlag: Wegwerfen. Sorry wenn das etwas hart klingt, aber der Code ist total unübersichtlich, es werden komische Sachen gemacht, und Fehler beim Schreiben von Partitionstabellen können grossen Schaden anrichten.

Das ganze ist viel zu lang um an einem Stück gelesen und verstanden zu werden. → Funktionen.

`subprocess` und `win32api` werden importiert, aber nicht verwendet.

Literale Zeichenketten sind keine Kommentare und sollten nicht als solche missbraucht werden.

Ungarische Notation ist Murks, Datentypen gehören nicht als kryptische Kürzel vor den eigentlichen Namen und Grunddatentypen gehören grundsätzlich nicht in Namen. Extrem witzlos ist der Präfix `obj` weil in Python *alles* was man an einen Namen binden kann ein Objekt ist. Das noch mal im Namen zu schreiben bringt dem Leser genau Null Mehrwert.

Die Namenskonvention in Python ist alles ausser Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase) wird klein_mit_unterstrichen geschrieben.

Bei dem `win32com`-Kram am Anfang werden Dinge doppelt gemacht.

Wenn in literalen Zeichenketten doppelte Anführungszeichen vorkommen sollen, ist es nicht so günstig die Zeichenkette selbst in doppelte Anführungszeichen zu setzen. Wenn man einfache nimmt, muss man die doppelten *in* der Zeichenkette nicht escapen.

Falls kein USB-Massenspeicher angeschlossen ist, bekommt man recht früh eine Ausnahme um die Ohren.

Bei SQL-Abfragen sollte man konkret angeben aus welchen Spalten man Werte haben möchte. Das macht es dem Leser deutlicher und es ist robuster gegen eine Änderung der Reihenfolge der Spalten.

`VolmeCptn` und `VolmeNme` werden so bestimmt das der Code nicht garantieren kann, dass die beiden Namen auch zum gleichen Gerät gehören. Und diese Abfrage muss nicht zum gleichen USB-Gerät gehören wie das was in der ersten SELECT-Abfrage bestimmt wurde. Dort wird der erste Datensatz genommen, bei der zweiten der letzte auf den die Bedingung zutrifft. An der Stelle ist das schon so kaputt als das ich das auf MBRs loslassen wollen würde. Das ist gefährlich, weil's nur durch Glück läuft!

Was sind `VolmeCptn` () und `VolmeNme` überhaupt für Namen? Wer oder was ist ein „Volme Captain“? Du lässt immer wieder, scheinbar wahllos irgendwelche Konsonanten weg‽ Was soll das? Das ist schlecht lesbar und verwirrend.

`abspath` und `dname` werden definiert, aber nicht verwendet. Weg damit. Der Import von `os` wird damit auch überflüssig.

`gof`? `ins`? `inss`? Ich wüsste nicht einmal wo ich anfangen sollte zu raten was die Namen bedeuten sollen.

Die Programmlogik bezüglich `gof` ist auch mehr als intransparent formuliert. Wenn der Benutzer drei Eingabemöglichkeiten hat, sollte man den Test linear formulieren und nicht so eigenartig verschachteln.

Der Rückgabewert von `raw_input()` ist bereits eine Zeichenkette, der wird durch einen `str()`-Aufruf nicht zeichenkettiger.

Wenn der Benutzer 'c' eingibt, kann er zwar eine weitere Eingabe machen, die hat aber letztlich keinen Einfluss auf den weiteren Programmablauf weil sie später an einen anderen Wert gebunden wird.

Super ist dann auch das hier:

Code: Alles auswählen

    mbr_new = VolmeNme
    mbr_flew = "mbr-" + mbr_new + ".bin"
    mbr_fle = DiskDrive_DeviceID
    mbr_dd = "mbr_wrt.bat"
    mbr_f = mbr_flew
Werte die an schlechte Namen gebunden sind, auch noch mal an andere schlechte Namen binden. Und teilweise im Folgenden dann mal den einen und mal den anderen verwenden, obwohl die sich auf den selben Wert beziehen. Gar nicht verwirrend… :roll:

Zwei von den Namen werden auch meilenweit von der Stelle definiert wo sie dann tatsächlich verwendet werden. An der Stelle wo es verwendet wird, darf man dann erst einmal suchen wo es definiert wird. Und eines ist eine Konstante die eher an den Anfang des Programms gehört.

Wenn man die Umettikettierungen sein lässt und den Rest an die richtige Stelle verschiebt, bleibt von den sechs Zeilen keine einzige mehr dort.

Der Kommentar beim prüfen der MBR-Signatur beschreibt etwas anderes als der Code tatsächlich macht. Der prüft nur ein Byte der Signatur und auch nur auf einen Wert.

Die Namen für den Start und das Ende eines Eintrags in der Partitionstabelle sind immer an Werte gebunden die sich genau um 16, also die Länge eines Eintrags unterscheiden. Dafür braucht man also keine zwei Namen.

Zusammengehörende Daten in ”parallelen” Listen zu halten ist schlecht, da fehleranfällig. Wenn man nicht aufpasst, dann passen die Daten nicht mehr zusammen. Bei dem Programm hier zum Beispiel nach dem Einträge in `part_tble` vertauscht wurden. Danach gehören die Einträge in `part_sktr` und `bootI` nicht mehr zu dem Eintrag in `part_tble` am gleichen Index. Und die Namen sind schon wieder…

Um ein Byte aus einer Bytezeichenkette zu holen braucht man kein „slicing“, da greift man einfach auf den Index zu. Und um einen Bytewert aus einer Bytezeichenkette in eine Zahl umzuwandeln, braucht man kein `struct.unpack()`, da reicht `ord()`. Bei Bytes ist '<' auch sinnfrei, denn die haben ja keine ”endianess”.

Die vielen ”magischen” Zahlen sollte man durch Konstanten ersetzen.

Mitten drin steht ein sinnloses ``f.close()``.

Falls nur zwei Partitionen gefunden werden, dann vertauscht das Programm die ersten beiden Partitionen. Blöd falls die zweite Partition einen leeren Eintrag hat.

Für den Fall das der Benutzer gefragt werden soll steht da eine ``while``-Schleife die einfacher und sicherer als ``for``-Schleife formuliert wäre. Und zwar nicht über Zahlen, sondern über Einträge in `part_tble`. Die Zahl die man zusätzlich für die Ausgabe benötigt, bekommt man über die `enumerate()`-Funktion.

Niemals nicht Benutzereingaben mit `input()` entgegennehmen in Python 2. Damit kann der Benutzer beliebige Python-Ausdrücke eingeben und auswerten lassen. Hier sogar noch mit Adminrechten wenn das Programm die benötigt.

Auch wenn der neue MBR nicht in einer Datei gespeichert wurde, wird trotzdem die Batchdatei erzeugt? Das macht keinen Sinn.

Die ``with``-Anweisung verwendet man damit Dateien sicher geschlossen werden. Die braucht man dann nicht noch mal schliessen.

Den Inhalt der Batchdatei würde ich auch als Konstante mit Platzhaltern für `format()` definieren. Wesentlich übersichtlicher und leichter zu ändern.

Zwischenstand, völlig ungetestet, viel zu lang für eine einzige Funktion und immer noch mit diversen der angesprochenen Fehler, könnte dann so aussehen:

Code: Alles auswählen

"""
    mbr switch v 0.01
    Switch any_to_first partition entry in mbr
"""
import struct
import sys

import win32com.client

MBR_SIZE = 512
MBR_PARTITION_TABLE_OFFSET = 446
MBR_PARTITION_ENTRY_SIZE = 16
MBR_SIGNATURE = '\x55\xaa'

BATCH_FILENAME = 'mbr_wrt.bat'
# 
# TODO Really just the last character of `drive_device_id`?
#   That looks suspicious.
# 
BATCH_TEMPLATE = '''\
@echo off
cd /d %~dp0
dd.exe if={mbr_filename} of=\\\\?\\Device\\Harddisk{drive_device_id[-1]}\\Partition0 bs={mbr_size} count=1
pause
'''


def main():
    print 'WARNING! Connect only USB-Stick to switch MBR!'

    wbem_locator = win32com.client.Dispatch('WbemScripting.SWbemLocator')
    wbem_server = wbem_locator.ConnectServer('.', r'root\cimv2')
    # 
    # TODO Replace ``*`` by actual column names we are interested in.
    # 
    rows = wbem_server.ExecQuery(
        'SELECT * FROM Win32_DiskDrive WHERE InterfaceType = "USB"'
    )
    # 
    # FIXME `IndexError` if there is no USB drive connected.
    # 
    drive_device_id = rows[0].DeviceID
    drive_caption = rows[0].Caption

    print drive_device_id, '-', drive_caption
    # 
    # FIXME This query needs a clause to make sure the result belongs to the
    #   first query's result.
    # 
    # TODO Replace ``*`` by actual column names we are interested in.
    # 
    rows = wbem_server.ExecQuery(
        'SELECT * FROM Win32_LogicalDisk WHERE DriveType = 2'
    )
    #
    # FIXME `NameError` after loop if `rows` is empty.
    # 
    for row in rows:
        if (row.Caption, row.VolumeName) != (None, None):
            volume_caption = row.Caption
            volume_name = row.VolumeName
            break
    print 'Name: %s on %s ' % (volume_name, volume_caption)

    answer = raw_input('Proceed with switching to MBR? [y] Abort [n]: ')
    if answer != 'y':
        sys.exit(0)

    with open(drive_device_id, 'rb') as raw_device:
        mbr = raw_device.read(MBR_SIZE)
    
    if mbr[-2:] != MBR_SIGNATURE:
        print 'I go, bye'
        sys.exit(0)

    empty_entry = '\x00' * MBR_PARTITION_ENTRY_SIZE
    partition_count = 0
    partition_table_entries = list()
    for i in xrange(4):
        offset = MBR_PARTITION_TABLE_OFFSET + i * MBR_PARTITION_ENTRY_SIZE
        entry = mbr[offset:offset + MBR_PARTITION_ENTRY_SIZE]
        partition_table_entries.append(entry)
        if entry != empty_entry:
            partition_count += 1

    if partition_count == 1:
        # 
        # Only 1 Partition --> nothing to switch.
        # 
        sys.exit(0)
    elif partition_count == 2:
        # 
        # FIXME Super uncool if second partiton entry is empty!
        # 
        switch_index = 1
    else:
        print 'Number of Partititions:', partition_count
        for i, entry in enumerate(partition_table_entries, 1):
            start_sector = struct.unpack('<HH', entry[8:12])[0]
            if start_sector != 0:
                is_bootable = (ord(entry[0]) & 127) != 0
                print "Partition: '%d'   StartSektor:  '%d' Boot: %s " % (
                    i, start_sector, '+' if is_bootable else '-'
                )
        #
        # FIXME Check user input!  Really!
        # 
        switch_index = int(raw_input('which partiton to switch? ')) - 1

    partition_table_entries.insert(
            0, partition_table_entries.pop(switch_index)
    )

    answer = raw_input('Write switch to MBR? [y/n]: ')
    if answer == 'y':
        mbr_filename = 'mbr-{}.bin'.format(volume_name)
        
        with open(mbr_filename, 'wb') as mbr_file:
            new_mbr = (
                mbr[:MBR_PARTITION_TABLE_OFFSET]
                + ''.join(partition_table_entries)
                + MBR_SIGNATURE
            )
            assert len(new_mbr) == MBR_SIZE
            mbr_file.write(new_mbr)

        with open(BATCH_FILENAME, 'w') as batch_file:
            batch_file.write(
                BATCH_TEMPLATE.format(
                    drive_device_id=drive_device_id,
                    mbr_filename=mbr_filename,
                    mbr_size=MBR_SIZE,
                )
            )

        print BATCH_FILENAME, 'is ready to start dd.exe!'


if __name__ == '__main__':
    main()

Re: mbr von usb-stick switchen

Verfasst: Sonntag 29. Juli 2018, 07:31
von ThomasL
@blackjack
Wollte dir mal meine Hochachtung aussprechen :!: , dafür das du mitten in der Nacht von Samstag auf Sonntag die Muße findest,
dir diesen Code anzutun, der mir beim Lesen Kopfschmerzen verursacht hat. :shock:

Re: mbr von usb-stick switchen

Verfasst: Sonntag 29. Juli 2018, 10:22
von xoric_pthy
@__blackjack__: Erstmal danke für die Mühe, zu zeigen, wie es besser geht. Auch wenns noch nicht geht, ist der Code beim nächsten Projekt ein gutes Beispiel für mich. Es ist für einem Profi immer sehr einfach einen Neuling runter zu putzen. Soll für mich auch eine Warnung sein, nicht sofort jeden Code vorzustellen.
Eigentlich ging es mir um die Grenzen:
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.
Daraus ergeben sich einige Fragen:
1.) kann mit Python ein low-lewel Zugriff zum Schreiben erreicht werden? Beim Lesen ist es ja möglich
2.) wie kann direkt aus Python das Programm dd.exe mit 'subprocess' gestartet werden?

Wenn 1.) gehen sollte erübrigt sich 2.) und wenn 2.) gehen würde, erübrigt sich das Erstellen der Batch.

SQL-Abfragen sind mir neu. Diese habe ich aus dem Netz https://www.activexperts.com/admin/scri ... thon/0054/. Übrigens die Firma gibt den Code zum Kopieren und verwenden frei. Von da kommt auch das 'obj'. In VBA wird empfohlen Variablennamen mit Typ zu versehen...
Hardware ist in Linux definitiv einfacher und eleganter aus dem System zu 'erfragen'. Es gibt auch mächtigere Werkzeuge, wo die Fehleranfälligkeit auch weitaus geringer ist. Nur besteht das mbr-Problem in Windows, also auch alle schwachsinnigen Grenzen des Systems. Ich kriege mit einer Abfrage nicht alle wichtigen Informationen, wie Index, Buchstabe, Label etc. aus SQL heraus, weil vermutlich diese in verschiedenen Tabellen abgelegt sind. Und dann kommen solche gefährlichen Konstellationen heraus, dass der Stick nicht eindeutig bestimmt werden kann. Die einzige Lösung, die mir einfiele, wäre diese in einer Datei abzulegen und Abfragen dahingehend zu prüfen. Soviel zur Allmacht von $MS

Wie gesagt: Das ist mein erster Python Code. Ich hab mal mit VBA und mit Linux-Script kleine Makros geschrieben, aber oop ist ein komplett neues Feld. Aus dieser Sicht ist mir jede Hilfe nützlich, auch wenn sie eher nach Tiraden, als nach konstruktiver Kritik klingen. Das könnte alles anders (freundlicher) formuliert sein.

Zur Motivation:
Ich möchte Python lernen, da kam mir diese Idee gerade recht. Das Script ist nur für mich, falls ich einen Stick mit mehreren Partitionen brauche (z.B. eine versteckte Partition, oder eine Ablage für große Dateien. Wobei beim zweiten ich eher 'split' einsetzen würde. Für einen DAU habe ich dieses Tool nicht geschrieben. Die interessieren sich eher für ihren Facebook Status.

Nochmal vielen Dank an __blackjack__ für die Mühe. Ich werde alle Infos zu Python-Programmierung beherzigen. Vorallem hast du Lösungen eingesetzt, die ich so nirgends gesehen habe, also mir nie in den Sinn gekommen wären.

Viele Grüße

Re: mbr von usb-stick switchen

Verfasst: Sonntag 29. Juli 2018, 16:18
von __blackjack__
@xoric_pthy: Ich sehe nicht warum es grundsätzlich nicht möglich sein sollte mit Python den MBR auch zu schreiben. Man müsste halt schauen woran es hakt.

Bei StackOverflow gibt es beispielsweise das hier: https://stackoverflow.com/questions/402 ... descriptor

Vielleicht reicht es für's schreiben ja schon den Modus 'r+b' zu verwenden, denn der MBR liegt ja ausserhalb eventuell eingehängter Partitionen.

Die Typpräfixe bei Namen waren mal so eine Microsoft-Erfindung, davon sind die aber mittlerweile auch grösstenteils weg. Zumindest bei moderneren Sprachen als VisualBasic(.NET).

Die Verbindung zwischen `Win32_DiskDrive` und `Win32_LogicalDisk` ist wohl über `Win32_DiskDriveToDiskPartition` und `Win32_LogicalDiskToPartition` zu finden. Mit einem Zwischenschritt über `Win32_DiskPartition`.

Wenn man die ``sys.exit(0)``-Aufrufe durch ``return`` ersetzt, kann man noch den Import von `sys` loswerden.

Man sollte es wie gesagt auf jeden Fall sinnvoll auf Funktionen aufteilen. Dann sieht man vielleicht auch einfach(er) was davon in einer Klasse Sinn machen würde.

Re: mbr von usb-stick switchen

Verfasst: Sonntag 29. Juli 2018, 18:08
von xoric_pthy
@__blackjack__ : 'r+b' hatte ich getestet, hatte nicht gefunzt. Der einzige Unterschied zu meinem Test ist diese Zeile:

Code: Alles auswählen

with lock_volume(disk):
Das werde ich testen, wenns klappt, kann ich den ganzen Block um dd.exe sparen, gleichzeitig muss ich mir Gedanken über die Struktur machen, insbesondere um oop muss ich viel lernen. Dein Code kann helfen.

Die Nomenklatur in Python werde ich noch verinnerlichen, um Prefixe zusparen.

`Win32_DiskDriveToDiskPartition` hatte ich gestestet, `Win32_LogicalDiskToPartition` habe ich eben getestet. Beide geben keine Verbindung zwischen Laufwerk Buchstabe zu Disknummer direkt aus. Man muss wieder etwas konstruieren, aber eine Lösung ist das alles nicht, den Stick automatisiert zu identifizieren. Am einfachsten wäre mit `Win32_LogicalDisk` die Anzahl der Partitonen ausgeben zu lassen (>1) oder eben eine Datei auf dem Stick. Auch der Gedanke direkt im mbr eine Signatur zu hinterlassen, ist mir gekommen (das ist aber Blödsinn, da zu gefährlich). Möglichkeiten gibt es viele, doch ist es am Besten alle anderen Sticks zu entfernen, denn alles andere erfordert den Eingriff des Benutzers.

Aber das alles hat keinen Sinn, denn 1. darf der Stick nicht gemountet sein, also muss das Script auf dem Host-Rechner kopiert werden und 2. Laufwerkszugriffe darf nur der Administrator vornehmen. Was ist, wenn das nicht möglich ist?

Letztenendes sind wir wieder da, wo wir losgegangen sind: Dem Sinn des Ganzen.

Windoof sieht nur den ersten Eintrag in der Psrtitiontable. Alles andere ist rein Akademisch und hat nur den Sinn des Lerneffektes. Da konzentriere ich mich lieber auf meine andere Idee mit sqlite und einem Kontainer für persönliche Daten, denn das Script funktioniert und reicht für meine Bedürfnisse.

Viele Grüße

Re: mbr von usb-stick switchen

Verfasst: Montag 30. Juli 2018, 00:47
von __blackjack__
@xoric_pthy: Das direkte Zugriffe auf die ”rohen” Blöcke eines Massenspeichers nur mit erhöhten Rechten möglich sind, ist ja logisch. Wenn jeder an MBRs rumschrauben dürfte, kann man Zugriffsrechte auch gleich ganz sein lassen. :-)

Ich hab mal ein wenig im Netz gelesen und es scheint es gibt auch USB-Sticks die sich als „fixed disk“ ausgeben, und Hersteller die Software bieten mit denen man ihre Sticks zwischen „removable“ und „fixed disk“ umschalten kann. *Und* in Windows 10 mit dem Creators Update hat Microsoft anscheinend eingesehen, dass man bei heutigen Speichergrössen vielleicht auch Partitionen auf USB-Sticks anlegen möchte. :-)

Re: mbr von usb-stick switchen

Verfasst: Montag 30. Juli 2018, 17:49
von xoric_pthy
@__blackjack__: Hast ja recht, ich wollte nur über $MS herziehen. Es ist fraglich, ob ich so ein Tool überhaupt häufig brauchen werde. Mir gings nur um die Machbarkeit und ich wollte Python lernen.
Auf jedenfall bin dir Dankbar, dass deinen Samstag geopfert und mir gezeigt hast wie es richtig gemacht wird.
.. und es scheint es gibt auch USB-Sticks die sich als „fixed disk“ ausgeben, und Hersteller die Software bieten mit denen man ihre Sticks zwischen „removable“ und „fixed disk“ umschalten kann. *Und* in Windows 10 mit dem Creators Update hat Microsoft anscheinend eingesehen, dass man bei heutigen Speichergrössen vielleicht auch Partitionen auf USB-Sticks anlegen möchte. :-)
ja die gibt es, aber hast du dir mal die Preise von den Dingern angesehen? Ausserdem geht das nur mit zertifizierten Sticks und die Zertifikate lässt sich $MS vor den Herstellern teuer bezahlen, die am Ende der Verbraucher, also wir, tragen müssen.
So ein schwachsinn. Ich Zahl doch für eine Funktionalität, die in anderen OS selbstverständlich ist, kein Geld ...
Über solche Abzocke könnte ich mich den ganzen Tag ärgern. Da erweitere ich lieber mein Horizont und lerne Python. :mrgreen:

Re: mbr von usb-stick switchen

Verfasst: Samstag 4. August 2018, 12:29
von xoric_pthy
nachtrag:
@__blackjack__: dein Vorschlag mit
Bei StackOverflow gibt es beispielsweise das hier: https://stackoverflow.com/questions/402 ... descriptor
ist genau das, was ich gesucht und nicht gefunden hatte. Jetzt klappt es ohne dd.exe und sogar direkt aus dem Stick heraus.

Perfekt! Vielen Dank nochmal für den Tipp. Das hat super geklappt. Eine ausführbare Datei (.exe), die direkt ausgeführt wird und die Partition auf dem Stick wechselt.

Demnächst nehme ich mir den Code nochmal vor, um eine Struktur hinein zu bringen, wie du in deinem Vorschlag es gemacht hast. Aber ich denke an class (z.B. Usb und Mbr).
Vorher werde ich sicher meine andere Idee umsetzen, um auch mehr über class zu lernen.

viele Grüße
xoric_pthy