Ich würd da mal an die API-Funktion CreateFile() denken, anscheinend kann man
damit auch direkt auf Laufwerke zugreifen (siehe unten, CodeZeile 51).
Hab´ unter
http://www.codeguru.com/cpp/w-p/system/ ... dWrite.htm
folgenden C-Code gefunden, der mit nem bischen Glück und sehr viel Fleis
(Umsetzung zu PB) zum Ziel führen könnte:
Code: Alles auswählen
char * ReadSectors(int drive, DWORD startinglogicalsector, int numberofsectors)
{
// All msdos data structures must be packed on a 1 byte boundary
#pragma pack (1)
struct
{
DWORD StartingSector ;
WORD NumberOfSectors ;
DWORD pBuffer;
}ControlBlock;
#pragma pack ()
#pragma pack (1)
typedef struct _DIOC_REGISTERS
{
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
} DIOC_REGISTERS ;
#pragma pack ()
char* buffer = (char*)malloc (512*numberofsectors);
HANDLE hDevice ;
DIOC_REGISTERS reg ;
BOOL fResult ;
DWORD cb ;
// Creating handle to vwin32.vxd (win 9x)
hDevice = CreateFile ( "\\\\.\\vwin32",
0,
0,
NULL,
0,
FILE_FLAG_DELETE_ON_CLOSE,
NULL );
if ( hDevice == INVALID_HANDLE_VALUE )
{
// win NT/2K/XP code
HANDLE hDevice;
DWORD bytesread;
char _devicename[] = "\\\\.\\C:"; // <---- so sollte es gehen !?!?!?
_devicename[4] += drive;
// Creating a handle to disk drive using CreateFile () function ..
hDevice = CreateFile(_devicename,
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
return NULL;
// Setting the pointer to point to the start of the sector we want to read ..
SetFilePointer (hDevice, (startinglogicalsector*512), NULL, FILE_BEGIN);
if (!ReadFile (hDevice, buffer, 512*numberofsectors, &bytesread, NULL) )
return NULL;
}
else
{
// code for win 95/98
ControlBlock.StartingSector = (DWORD)startinglogicalsector;
ControlBlock.NumberOfSectors = (DWORD)numberofsectors ;
ControlBlock.pBuffer = (DWORD)buffer ;
//-----------------------------------------------------------
// SI contains read/write mode flags
// SI=0h for read and SI=1h for write
// CX must be equal to ffffh for
// int 21h's 7305h extention
// DS:BX -> base addr of the
// control block structure
// DL must contain the drive number
// (01h=A:, 02h=B: etc)
//-----------------------------------------------------------
reg.reg_ESI = 0x00 ;
reg.reg_ECX = -1 ;
reg.reg_EBX = (DWORD)(&ControlBlock);
reg.reg_EDX = drive+1;
reg.reg_EAX = 0x7305 ;
// 6 == VWIN32_DIOC_DOS_DRIVEINFO
fResult = DeviceIoControl ( hDevice,
6,
&(reg),
sizeof (reg),
&(reg),
sizeof (reg),
&cb,
0);
if (!fResult || (reg.reg_Flags & 0x0001)) return NULL;
}
CloseHandle(hDevice);
return buffer;
}
Und hier vielleicht noch ´n bischen allgemeine Doc zur PartitionsTabelle
in Form von´nem Uralt-QBasicCode...
Code: Alles auswählen
SUB DriveSpecs (D$) 'D$=nackter LaufwerksBuchstabe !!!
IF LTRIM$(D$) = "" THEN GOTO DriveError
Drive$ = "'" + D$ + ":'"
DriveNr% = ASC(UCASE$(D$)) - 65
IF DriveNr% < 0 OR DriveNr% > 3 THEN
DriveError:
PRINT Drive$; ": ungltige Laufwerks-Angabe"
END
END IF
Drive% = DriveNr%
IF Drive% > 1 THEN Drive% = Drive% + 126
'----- Laufwerks-Daten holen -----
ClearReg
reg.AX = CVI(CHR$(0) + CHR$(8)) 'AH=8 AL=0
reg.DX = CVI(CHR$(Drive%) + CHR$(0))'DH=0 DL=Drive%
CALL INTERRUPTX(&H13, reg, reg)
'----- splitt in ?L% und ?H% -----
AX$ = MKI$(reg.AX): AL% = ASC(AX$): ah% = ASC(MID$(AX$, 2))
BX$ = MKI$(reg.BX): BL% = ASC(BX$): BH% = ASC(MID$(BX$, 2))
CX$ = MKI$(reg.CX): CL% = ASC(CX$): CH% = ASC(MID$(CX$, 2))
DX$ = MKI$(reg.DX): DL% = ASC(DX$): DH% = ASC(MID$(DX$, 2))
'----- Register anzeigen -----
IF Show > 1 THEN
PRINT "AX="; bin(ah% + 0, 8); "_"; bin(AL% + 0, 8); " AH="; ah%; " AL="; AL%
PRINT "BX="; bin(BH% + 0, 8); "_"; bin(BL% + 0, 8); " BH="; BH%; " BL="; BL%
PRINT "CX="; bin(CH% + 0, 8); "_"; bin(CL% + 0, 8); " CH="; CH%; " CL="; CL%
PRINT "DX="; bin(DH% + 0, 8); "_"; bin(DL% + 0, 8); " DH="; DH%; " DL="; DL%
END IF
'----- Daten auspacken -----
DriveStatus = ah%
DriveTyp = BL%
'CX: 76543210 76543210
' ³ ³ ³³ÀÄÄÄÄÁÄÄÄ Anz. Sektoren
' ³ ³ ÀÁÄÄÄÄÄÄÄÄÄ HighBits of Anz. Cylinder
' ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄ LowBits of Anz. Cylinder
CL$ = bin(CL% + 0, 8)
maxSect% = bin2dez(MID$(CL$, 3))
maxCyl& = CH% + bin2dez(LEFT$(CL$, 2)) * 256
maxHead% = DH% + 1
maxDrive = DL%
'----- Daten anzeigen -----
IF Show > 1 THEN
PRINT "Fehlerstatus="; DriveStatus; " [AX]"
PRINT "DriveNum= "; DriveNr%; "(von"; maxDrive; ")"
PRINT "Cyinder= "; maxCyl& + 1; " [CH]"
PRINT "Sectors= "; maxSect%; " [CL]"
PRINT "Heads= "; maxHead%; " [DH]"
IF DriveType THEN
PRINT "DriveTyp= "; DriveTyp; " [BL] (";
SELECT CASE DriveTyp
CASE 1: PRINT "5.25"; CHR$(34); " 360 KB)"
CASE 2: PRINT "5.25"; CHR$(34); " 1.2 MB)"
CASE 3: PRINT "3.5"; CHR$(34); " 720 KB)"
CASE 4: PRINT "3.5"; CHR$(34); " 1.44 MB)"
CASE ELSE:
PRINT ; "???) [" + LTRIM$(STR$(DriveTyp)) + "]"
END SELECT
END IF
END IF
FUNCTION LBA& (Cyl&, Head%, Sect%) 'CHS --> LBA umrechnen
LBA& = Cyl& * maxHead% * maxSect% + Head% * maxSect% + Sect%
END FUNCTION
SUB PartitionsTabelle
readSector 0, 0, 1 'Part.-Table, muá mit $55AA (dez 85 170) enden
IF ASC(MID$(Buffer$, 511)) <> 85 OR ASC(MID$(Buffer$, 512)) <> 170 THEN
PRINT "Lauferk "; Drive$; ": keine Partitions-Tabelle gefunden !!!"
END
END IF
StartPos% = 446
such.Partitionen:
IF StartPos% + 15 > LEN(Buffer$) THEN
PRINT "Lauferk "; Drive$; ": keine Partition gefunden !!!"
END
END IF
sysID% = ASC(MID$(Buffer$, StartPos% + 5, 1))
IF sysID% > 0 THEN
ptc% = ptc% + 1
pt.id%(ptc%) = sysID%
active% = ASC(Buffer$)
IF active% THEN act.part% = ptc%
PRINT sysID%; "("; STR$(ASC(Buffer$)); ")"
' END IF
ELSE
StartPos% = StartPos% + 16
IF StartPos% + 16 < LEN(Buffer$) THEN GOTO such.Partitionen
END IF
StartHead% = BufferBytes(StartPos% + 2, 1)
StartSect% = BufferBytes(StartPos% + 3, 1)
StartCyl& = BufferBytes(StartPos% + 4, 1)
endhead% = BufferBytes(StartPos% + 6, 1)
endsect% = BufferBytes(StartPos% + 7, 1)
endCyl& = BufferBytes(StartPos% + 8, 1)
IF Show THEN
PRINT "Lauferk "; Drive$; ": Start lt. MBR="; CHS.Show$(StartCyl&, StartHead%, StartSect%);
END IF
END SUB
SUB readSector (CylNr&, HeadNr%, SectNr%)
' einlesen eines Festplatten-Sektor's (512 Bytes) in Buffer$
restart:
ClearReg
reg.AX = CVI(CHR$(1) + CHR$(2)) '1 Sektor, Int13-Fnc=02 (readSector)
'CX: 76543210 76543210
' ³ ³ ³³ÀÄÄÄÄÁÄÄÄ Sektor-Nr
' ³ ³ ÀÁÄÄÄÄÄÄÄÄÄ HighBits Cylinder-Nr
' ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄ LowBits Cylinder-Nr
CH% = INT(CylNr& / 256)
CX$ = bin$((CylNr& - CH% * 256), 8) + bin$(CH% + 0, 2) + bin$(SectNr% + 0, 6)
CX& = bin2dez(CX$): IF CX& > 32767 THEN CX& = CX& - 65536
reg.CX = CX&
reg.DX = CVI(CHR$(Drive%) + CHR$(HeadNr%))
reg.ES = VARSEG(Buffer)
reg.BX = VARPTR(Buffer)
CALL INTERRUPTX(&H13, reg, reg)
AX$ = MKI$(reg.AX): AL% = ASC(AX$): ah% = ASC(MID$(AX$, 2))
IF ah% THEN
PRINT "read Sector "; CHS.Show$(CylNr&, HeadNr%, SectNr%); ": Fehler "; ah%
IF ah% = 4 AND ErrCnt% < 5 THEN
ErrCnt% = ErrCnt% + 1
GOTO restart
END IF
END
END IF
' IF ((Reg.flags AND 2048) > 0 AND (Reg.flags AND 128) = 0) THEN
' PRINT "Disk not found in drive "; CHR$(65 + DriveNum); ":"
' END
' END IF
IF Show THEN
OPEN "HD.blk" FOR OUTPUT AS #9
PRINT #9, "CHS= "; CHS.Show$(CylNr&, HeadNr%, SectNr%); " (LBA="; LBA(CylNr&, HeadNr%, SectNr%); ")"
PRINT #9, Buffer
CLOSE #9
END IF
END SUB
viel Glück !!!