Newsgroup: it.comp.programmare.win32
Titolo: API gestione MBR (Master Boot Record) dell' hard disk

Salve a tutti,
Mi chiedevo, quali sono (e come utilizzarle) le API di Windows per la 
gestione del MBR dell' hard disk?
Ad esempio per cancellare l' MBR, modificare l' MBR ecc...
Ho provato a cercare un pò in rete ma non ho trovato nulla...
Grazie in anticipo,
-- 
Carmine ( 
pikachu...@gmail.com
 (Togli la scritta NOSPAM) )
Webmaster di The Total Site: 
http://www.thetotalsite.it
My Blog: 
http://blog.thetotalsite.it

 Ad esempio per cancellare l' MBR, modificare l' MBR ecc...
Non sono a conoscenza di syscall specifiche per questo argomento.
Se vuoi paciugare l'MBR procurati della documentazione sulla sua
struttura, dopodiché apri il device con CreateFile e ci fai quello che
devi (sui primi 512 bytes).
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
	**ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
 -<! Woe to you, oh Earth and Sea, for the Devil sends the Beast with
      wrath, because He knows the time is short... !>- Revelations, XIII - 18

 devi (sui primi 512 bytes).
In che senso "paciugare"?
Comunque... come faccio ad aprirlo con createfile? L' MBR non rappresenta 
nessuna partizione o file specifico... è solo il settore iniziale dell' 
HD...
Ad esempio, i programmi di gestione dell' MBR (ad esempio quelli per 
configurare i boot loader) come funzionano?
Bye,


 configurare i boot loader) come funzionano?
Di che programmi parli? Io oltre a Lilo e Grub non conosco altro.
Ma sono sicuro che per cominciare ti serve sapere la struttura dell'MBR:
penso che si possa trovare documentazione nel pacchetto di Lilo
-- 
  Giuseppe "Cowo" Corbelli ~\/~ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
-<! Evitate di contribuire alla diffusione della musica cattiva; cercate
      anzi di sopprimerla con tutte le vostre forze. - R.Schumann !>-

 penso che si possa trovare documentazione nel pacchetto di Lilo
No, aspetta... non dico I bootloader, quanto piuttosto i programmi per 
l'installazione e la configurazione dei bootloader.
Lilo e Grub sono quelli "opensource", ma ad esempio windows ha il bootloader 
proprietario.


 proprietario.
Qui bisogna capirsi.
Per "Installazione" si intende copiare un po' di byte qua e là. MBR,
primo settore della partizione...
Per "Configurazione", grub legge direttamente dal filesystem quanto va
bootato, lilo usa una mappa interna, e forse é questo quello che ti
interessa.
Non so come funzioni il loader di windows.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail** 
-<! At first there was nothing. Then God said 'Let there be light!' Then
		there was still nothing. But you could see it. !>-

 wrote:
Auguri.
// SectorDiskRW.cpp : Defines the entry point for the console
application.
//
/*++ 
 
Module Name: 
 
    mfmt.c 
 
Abstract: 
 
    This program is designed to show how to access a physical floppy 
    disk using the Win32 API set. 
 
    This program has two major functions. 
 
        - It can be used to display the geometry of a disk 
 
            mfmt -g a: 
 
        - It can be used to produce a disk image, or to write a disk 
          image to a floppy. 
 
            mfmt -c a: bootdisk         - produce a disk image of a: 
 
            mfmt -c bootdisk a:         - make a: identical to
bootdisk image 
 
    This program is very very simple. Minimal error checking is done.
It is 
    meant to provide an example of how to: 
 
        - Open a physical disk 
 
        - Read a disk's geometry 
 
        - Perform a low level format operation 
 
        - read and write physical sectors 
 
--*/ 
#include "stdafx.h"
#include <stdlib.h> 
#include <stdio.h> 
#include <windows.h> 
#include <winioctl.h> 
#include <string.h> 
#include <ctype.h> 
#include <memory.h> 
 
DISK_GEOMETRY SupportedGeometry[20]; 
DWORD SupportedGeometryCount; 
 
BOOL 
GetDiskGeometry( 
    HANDLE hDisk, 
    PDISK_GEOMETRY lpGeometry 
    ) 
 
{ 
    DWORD ReturnedByteCount; 
 
    return DeviceIoControl( 
                hDisk, 
                IOCTL_DISK_GET_DRIVE_GEOMETRY, 
                NULL, 
                0, 
                lpGeometry, 
                sizeof(*lpGeometry), 
                &ReturnedByteCount, 
                NULL 
                ); 
} 
 
DWORD 
GetSupportedGeometrys( 
    HANDLE hDisk 
    ) 
{ 
    DWORD ReturnedByteCount; 
    BOOL b; 
    DWORD NumberSupported; 
 
    b = DeviceIoControl( 
                hDisk, 
                IOCTL_DISK_GET_MEDIA_TYPES, 
                NULL, 
                0, 
                SupportedGeometry, 
                sizeof(SupportedGeometry), 
                &ReturnedByteCount, 
                NULL 
                ); 
    if ( b ) { 
        NumberSupported = ReturnedByteCount / sizeof(DISK_GEOMETRY); 
        } 
    else { 
        NumberSupported = 0; 
        } 
    SupportedGeometryCount = NumberSupported; 
 
    return NumberSupported; 
} 
 
VOID 
PrintGeometry( 
    LPSTR lpDriveName, 
    PDISK_GEOMETRY lpGeometry 
    ) 
{ 
    LPSTR MediaType; 
 
    if (lpDriveName) { 
        printf("Geometry for Drive %s\n",lpDriveName); 
        } 
 
    switch ( lpGeometry->MediaType ) { 
        case F5_1Pt2_512:  MediaType = "5.25, 1.2MB,  512
bytes/sector";break; 
        case F3_1Pt44_512: MediaType = "3.5,  1.44MB, 512
bytes/sector";break; 
        case F3_2Pt88_512: MediaType = "3.5,  2.88MB, 512
bytes/sector";break; 
        case F3_20Pt8_512: MediaType = "3.5,  20.8MB, 512
bytes/sector";break; 
        case F3_720_512:   MediaType = "3.5,  720KB,  512
bytes/sector";break; 
        case F5_360_512:   MediaType = "5.25, 360KB,  512
bytes/sector";break; 
        case F5_320_512:   MediaType = "5.25, 320KB,  512
bytes/sector";break; 
        case F5_320_1024:  MediaType = "5.25, 320KB,  1024
bytes/sector";break; 
        case F5_180_512:   MediaType = "5.25, 180KB,  512
bytes/sector";break; 
        case F5_160_512:   MediaType = "5.25, 160KB,  512
bytes/sector";break; 
        case RemovableMedia: MediaType = "Removable media other than
floppy";break; 
        case FixedMedia:   MediaType = "Fixed hard disk media";break; 
        default:           MediaType = "Unknown";break; 
    } 
    printf("    Media Type %s\n",MediaType); 
    printf("    Cylinders %d Tracks/Cylinder %d Sectors/Track %d\n", 
        lpGeometry->Cylinders.LowPart, 
        lpGeometry->TracksPerCylinder, 
        lpGeometry->SectorsPerTrack 
        ); 
} 
 
BOOL 
LowLevelFormat( 
    HANDLE hDisk, 
    PDISK_GEOMETRY lpGeometry 
    ) 
{ 
    FORMAT_PARAMETERS FormatParameters; 
    PBAD_TRACK_NUMBER lpBadTrack; 
    UINT i; 
    BOOL b; 
    DWORD ReturnedByteCount; 
 
    FormatParameters.MediaType = lpGeometry->MediaType; 
    FormatParameters.StartHeadNumber = 0; 
    FormatParameters.EndHeadNumber = lpGeometry->TracksPerCylinder -
1; 
    lpBadTrack = (PBAD_TRACK_NUMBER)
LocalAlloc(LMEM_ZEROINIT,lpGeometry->TracksPerCylinder*sizeof(*lpBadTrack));
    for (i = 0; i < lpGeometry->Cylinders.LowPart; i++) { 
 
        FormatParameters.StartCylinderNumber = i; 
        FormatParameters.EndCylinderNumber = i; 
 
        b = DeviceIoControl( 
                hDisk, 
                IOCTL_DISK_FORMAT_TRACKS, 
                &FormatParameters, 
                sizeof(FormatParameters), 
                lpBadTrack, 
                lpGeometry->TracksPerCylinder*sizeof(*lpBadTrack), 
                &ReturnedByteCount, 
                NULL 
                ); 
 
        if (!b ) { 
            LocalFree(lpBadTrack); 
            return b; 
            } 
        } 
 
    LocalFree(lpBadTrack); 
 
    return TRUE; 
} 
 
BOOL 
LockVolume( 
    HANDLE hDisk 
    ) 
{ 
    DWORD ReturnedByteCount; 
 
    return DeviceIoControl( 
                hDisk, 
                FSCTL_LOCK_VOLUME, 
                NULL, 
                0, 
                NULL, 
                0, 
                &ReturnedByteCount, 
                NULL 
                ); 
} 
 
BOOL 
UnlockVolume( 
    HANDLE hDisk 
    ) 
{ 
    DWORD ReturnedByteCount; 
 
    return DeviceIoControl( 
                hDisk, 
                FSCTL_UNLOCK_VOLUME, 
                NULL, 
                0, 
                NULL, 
                0, 
                &ReturnedByteCount, 
                NULL 
                ); 
} 
 
BOOL 
DismountVolume( 
    HANDLE hDisk 
    ) 
{ 
    DWORD ReturnedByteCount; 
 
    return DeviceIoControl( 
                hDisk, 
                FSCTL_DISMOUNT_VOLUME, 
                NULL, 
                0, 
                NULL, 
                0, 
                &ReturnedByteCount, 
                NULL 
                ); 
} 
 
DWORD 
_cdecl 
main( 
    int argc, 
    char *argv[], 
    char *envp[] 
    ) 
{ 
    char Drive[MAX_PATH]; 
    HANDLE hDrive, hDiskImage; 
    DISK_GEOMETRY Geometry; 
    UINT i; 
    char c, *p; 
    LPSTR DriveName; 
    BOOL fUsage = TRUE; 
    BOOL fShowGeometry = FALSE; 
    BOOL fDiskImage = FALSE; 
    BOOL SourceIsDrive; 
    LPSTR Source, Destination, DiskImage; 
 
    if ( argc > 1 ) { 
        fUsage = FALSE; 
        while (--argc > 0 ) { 
            p = *++argv; 
            if (*p == '/' || *p == '-') { 
                while (c = *++p) 
                switch (toupper( c )) { 
                case '?': 
                    fUsage = TRUE; 
                    break; 
 
                case 'C': 
                    fDiskImage = TRUE; 
                    argc--, argv++; 
                    Source = *argv; 
                    argc--, argv++; 
                    Destination = *argv; 
                    break; 
 
                case 'G': 
                    argc--, argv++; 
                    if ( (DriveName = *argv ) && *DriveName &&  
                         isalpha(*DriveName) ) 
                        fShowGeometry = TRUE; 
                    else 
                                                { 
                        printf( "MFMT: Missing drive letter after
-G\n" ); 
                                    DriveName = NULL; 
                        fUsage = TRUE; 
                        } 
                            break; 
 
                default: 
                    printf("MFMT: Invalid switch - /%c\n", c ); 
                    fUsage = TRUE; 
                    break; 
                    } 
                } 
            } 
        } 
 
    if ( fUsage ) { 
        printf("usage: MFMT switches \n" ); 
        printf("            [-?] display this message\n" ); 
        printf("            [-g drive] shows disk geometry\n" ); 
        printf("            [-c source destination] produce
diskimage\n" ); 
        ExitProcess(1); 
        } 
 
    if ( fShowGeometry ) { 
        sprintf(Drive,"\\\\.\\%s",DriveName); 
        hDrive = CreateFile( 
                    Drive, 
                    GENERIC_READ | GENERIC_WRITE, 
                    FILE_SHARE_READ|FILE_SHARE_WRITE, 
                    NULL, 
                    OPEN_EXISTING, 
                    0, 
                    NULL 
                    ); 
        if ( hDrive == INVALID_HANDLE_VALUE ) { 
            printf("MFMT: Open %s failed
%d\n",DriveName,GetLastError()); 
            ExitProcess(1); 
            } 
 
        if ( LockVolume(hDrive) == FALSE ) { 
            printf("MFMT:Locking volume %s failed %d\n", DriveName,
GetLastError()); 
            ExitProcess(1); 
            } 
 
        if ( !GetDiskGeometry(hDrive,&Geometry) ) { 
            printf("MFMT: GetDiskGeometry %s failed
%d\n",DriveName,GetLastError()); 
            ExitProcess(1); 
            } 
        PrintGeometry(DriveName,&Geometry); 
 
        if ( !GetSupportedGeometrys(hDrive) ) { 
            printf("MFMT: GetSupportedGeometrys %s failed
%d\n",DriveName,GetLastError()); 
            ExitProcess(1); 
            } 
        printf("\nDrive %s supports the following disk
geometries\n",DriveName); 
 
        for(i=0;i<SupportedGeometryCount;i++) { 
            printf("\n"); 
            PrintGeometry(NULL,&SupportedGeometry[i]); 
            } 
 
        printf("\n"); 
        ExitProcess(0); 
        } 
 
    if ( fDiskImage ) { 
        SourceIsDrive = FALSE; 
        if ( Source[strlen(Source)-1] == ':' ) { 
            SourceIsDrive = TRUE; 
            sprintf(Drive,"\\\\.\\%s",Source); 
            DriveName=Source; 
            DiskImage = Destination; 
            } 
        if ( Destination[strlen(Destination)-1] == ':' ) { 
            if ( SourceIsDrive ) { 
                printf("MFMT: Source and Destination cannot both be
drives\n"); 
                ExitProcess(1); 
                } 
            SourceIsDrive = FALSE; 
            sprintf(Drive,"\\\\.\\%s",Destination); 
            DriveName=Destination; 
            DiskImage = Source; 
            } 
        else { 
            if ( !SourceIsDrive ) { 
                printf("MFMT: Either Source or Destination must be a
drive\n"); 
                ExitProcess(1); 
                } 
            } 
 
        // 
        // Open and Lock the drive 
        // 
 
        hDrive = CreateFile( 
                    Drive, 
                    GENERIC_READ | GENERIC_WRITE, 
                    FILE_SHARE_READ|FILE_SHARE_WRITE, 
                    NULL, 
                    OPEN_EXISTING, 
                    0, 
                    NULL 
                    ); 
        if ( hDrive == INVALID_HANDLE_VALUE ) { 
            printf("MFMT: Open %s failed
%d\n",DriveName,GetLastError()); 
            ExitProcess(1); 
            } 
        if ( LockVolume(hDrive) == FALSE ) { 
            printf("MFMT: LockVolume %s failed
%d\n",DriveName,GetLastError()); 
            ExitProcess(1); 
            } 
 
        if ( !GetDiskGeometry(hDrive,&Geometry) ) { 
            printf("MFMT: GetDiskGeometry %s failed
%d\n",DriveName,GetLastError()); 
            ExitProcess(1); 
            } 
 
        if ( !GetSupportedGeometrys(hDrive) ) { 
            printf("MFMT: GetSupportedGeometrys %s failed
%d\n",DriveName,GetLastError()); 
            ExitProcess(1); 
            } 
 
        // 
        // Open the disk image file 
        // 
 
        hDiskImage = CreateFile( 
                        DiskImage, 
                        GENERIC_READ | GENERIC_WRITE, 
                        0, 
                        NULL, 
                        SourceIsDrive ? CREATE_ALWAYS : OPEN_EXISTING,
0, 
                        NULL 
                        ); 
        if ( hDiskImage == INVALID_HANDLE_VALUE ) { 
            printf("MFMT: Open %s failed
%d\n",DiskImage,GetLastError()); 
            ExitProcess(1); 
            } 
 
        // 
        // Now do the copy 
        // 
        { 
            LPVOID IoBuffer; 
            BOOL b; 
            DWORD BytesRead, BytesWritten; 
            DWORD FileSize; 
            DWORD VirtBufSize; 
            DWORD NumBufs; 
 
            // 
            // If we are copying from floppy to file, just do the copy
// Otherwise, we might have to format the floppy first 
            // 
 
            if ( SourceIsDrive ) { 
 
                // 
                // Device reads must be sector aligned. VirtualAlloc
will 
                // garuntee alignment 
                // 
 
                NumBufs = Geometry.Cylinders.LowPart; 
                VirtBufSize =  Geometry.TracksPerCylinder * 
                               Geometry.SectorsPerTrack * 
                               Geometry.BytesPerSector; 
 
                IoBuffer =
VirtualAlloc(NULL,VirtBufSize,MEM_COMMIT,PAGE_READWRITE); 
 
                if ( !IoBuffer ) { 
                    printf("MFMT: Buffer Allocation Failed\n"); 
                    ExitProcess(1); 
                    } 
 
                for ( ;NumBufs > 0; NumBufs-- ) 
                    { 
                    b = ReadFile(hDrive,IoBuffer, VirtBufSize,
&BytesRead, NULL); 
                    if (b && BytesRead){ 
                        b = WriteFile(hDiskImage,IoBuffer, BytesRead,
&BytesWritten, NULL); 
                        if ( !b || ( BytesRead != BytesWritten ) ) { 
                            printf("MFMT: Fatal Write Error
%d\n",GetLastError()); 
                            ExitProcess(1); 
                            } 
                        } 
                    else { 
                        printf("MFMT: Fatal Read Error
%d\n",GetLastError()); 
                        ExitProcess(1); 
                        } 
                    } 
                } 
            else { 
 
                // 
                // Check to see if the image will fit on the floppy.
If it 
                // will, then LowLevelFormat the floppy and press on 
                // 
 
                FileSize = GetFileSize(hDiskImage,NULL); 
 
                b = FALSE; 
                for(i=0;i<SupportedGeometryCount;i++) { 
                    NumBufs = SupportedGeometry[i].Cylinders.LowPart; 
                    VirtBufSize =
SupportedGeometry[i].TracksPerCylinder * 
 SupportedGeometry[i].SectorsPerTrack * 
 SupportedGeometry[i].BytesPerSector; 
                    if ( VirtBufSize*NumBufs >= FileSize ) { 
 
                        IoBuffer =
VirtualAlloc(NULL,VirtBufSize,MEM_COMMIT,PAGE_READWRITE); 
 
                        if ( !IoBuffer ) { 
                            printf("MFMT: Buffer Allocation
Failed\n"); 
                            ExitProcess(1); 
                            } 
 
                        // 
                        // Format the floppy 
                        // 
 
                        LowLevelFormat(hDrive,&SupportedGeometry[i]); 
 
                        for ( ;NumBufs > 0; NumBufs-- ) 
                            { 
                            b = ReadFile(hDiskImage,IoBuffer,
VirtBufSize, &BytesRead, NULL); 
                            if (b && BytesRead){ 
                                b = WriteFile(hDrive,IoBuffer,
BytesRead, &BytesWritten, NULL); 
                                if ( !b || ( BytesRead != BytesWritten
) ) { 
                                    printf("MFMT: Fatal Write Error
%d\n",GetLastError()); 
                                    ExitProcess(1); 
                                    } 
                                } 
                            else { 
                                printf("MFMT: Fatal Read Error
%d\n",GetLastError()); 
                                ExitProcess(1); 
                                } 
                            } 
                        b = TRUE; 
                        break; 
                    } 
                    } 
 
                if ( !b ) { 
                    printf("MFMT: FileSize %d is not supported on
drive %s\n",FileSize,DriveName); 
                    ExitProcess(1); 
                    } 
                } 
        } 
 
        // 
        // Dismounting forces the filesystem to re-evaluate the media
id 
        // and geometry. This is the same as popping the floppy in and
out 
        // of the disk drive 
        // 
 
        DismountVolume(hDrive); 
        UnlockVolume(hDrive); 
 
        ExitProcess(0); 
        } 
    return (0); 
} 

Mhm ma ad esempio, cosa c'è di preciso in quei 512 byte di hard disk?
Ovvero, il computer, leggendo quei dati, come fa a capire dove "prendere" 
l'elenco dei sistemi operativi ad esempio?


Argh... :-|
Ma è terribile...
E comunque, a quanto pare questo serve per il floppy disk mhm...
Non c'è un esempio specifico per l' MBR?


Ecco, appunto.
Ma come è possibile accedere direttamente a quei 512 byte e ad esempio 
leggerli o modificarli?
Ad esempio è possibile accedere al disco in modalità "raw" ottenendo un 
intero stream senza dover passare per il file system?


 leggerli o modificarli?
Certo, con un normale editor binario con l'accesso alla struttura del disco. 
Esempio: WinHex, come tantissimi altri.
Feci un mio personalissimo boot-manager prima dell'avvento di PartitionMagic 
e simili, dopo aver studiato il formato dell'MBR in rete, e usavo un gestore 
scritto da me in assembler per fare copie e ricopie dei settori principali. 
Una bomba! :-)

 intero stream senza dover passare per il file system?
MSDN -> CreateFile
When opening a physical drive, x, the lpFileName string should be of the form 
\\.\PHYSICALDRIVE<x>. Hard disk numbers start at zero. The following table 
shows some example physical drive strings.
Es.
\\.\PHYSICALDRIVE0
-- 
         Giuseppe "Cowo" Corbelli ~\/~ My software: 
http://cowo.yoda2000.net
-<! Non c'e' niente da dire in proposito. Tutto quello che uno deve fare e'
   colpire i tasti giusti al momento giusto, e lo strumento suona da solo. !>-
                                 J.S. Bach

 Mhm ma ad esempio, cosa c'č di preciso in quei 512 byte di hard disk?
http://en.wikipedia.org/wiki/Master_boot_record
-- 
         Giuseppe "Cowo" Corbelli ~\/~ My software: 
http://cowo.yoda2000.net
