🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #11017

Re: Problems writing boot record to removable media under WinME

#11017
From: Walt Morrey
Date: Thu, 04 Mar 2004 13:05
335 lines
11608 bytes
Here's the full code for SetLock and WriteSectors.  A very similar ReadSectors is also included and 
works fine!!


BOOL SetLock( BYTE UnLock, HANDLE hDevice, int drive )
{
    DEVIOCTL_REGISTERS reg1;
    BOOL  fResult ;
    DWORD cb ;
    #pragma pack(1)
    struct
    {
       BYTE Operation;
       BYTE NumLocks;
    } ParamBlock;
    #pragma pack()

    ParamBlock.Operation = UnLock;    // 0 to lock volume in the drive
    reg1.reg_Flags = 0x8000;
    reg1.reg_EAX = 0x440D;
    reg1.reg_EBX = drive + 1;    // 1 = A, 2 = B, etc
    reg1.reg_ECX = 0x4848;       // try upper=48 for FAT32
    reg1.reg_EDX = (DWORD)&ParamBlock;
    fResult = DeviceIoControl ( hDevice, VWIN32_DIOC_DOS_IOCTL,
       &(reg1), sizeof (reg1),
       &(reg1), sizeof (reg1),
       &cb, 0);
    if ( !fResult )
    {
       reg1.reg_Flags = 0x8000;
       reg1.reg_EAX = 0x440D;
       reg1.reg_EBX = drive + 1;    // 1 = A, 2 = B, etc
       reg1.reg_EDX = (DWORD)&ParamBlock;
       reg1.reg_ECX = 0x0848;        // try FAT16, or 12 & Write - 0x41
       fResult = DeviceIoControl ( hDevice, VWIN32_DIOC_DOS_IOCTL,
          &(reg1), sizeof (reg1),
          &(reg1), sizeof (reg1),
          &cb, 0);
       if ( !fResult )
       {
          return FALSE;
       }
    }
    return TRUE;
}

//-----------------------------------------------------------------
//Code to write disk sectors from win 9x/NT/2K/XP
//
//Writes [numberofsectors] disk sectors from
//      [drive {0=A, 1=B, 2=C, ...}] drive
//      starting from [startinglogicalsector]
//
//To write sectors from win 9x int 21h's 7305h extention is used
//      (Extended Absolute Disk Read/Write).
//      For more info about int 21h's 7305h extention refer
//      Ralf Brown's interrupt list.
//------------------------------------------------------------------
BOOL WriteSectors(int drive, DWORD startinglogicalsector, int numberofsectors, char*buffer)
{

// 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)
    struct
    {
       BYTE SpecFunc;
       WORD Head;
       WORD Cylinder;
       WORD FirstSector;
       WORD Sectors;
       DWORD Buffer;
    } RwBlock;
    #pragma pack()

//char* buffer = (char*)malloc (512*numberofsectors);
    HANDLE hDevice ;
    DEVIOCTL_REGISTERS reg;
    BOOL  fResult ;
    DWORD cb ;

    if( Win32Platform == VER_PLATFORM_WIN32_NT )
    {
       // win NT/2K/XP code
       HANDLE hDevice;
       DWORD bytesread;

       char _devicename[] = "\\\\.\\A:";
       _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 FALSE;

   // Setting the pointer to point to the start of the sector we want to read ..
       SetFilePointer (hDevice, (startinglogicalsector*512), NULL, FILE_BEGIN);

       if (!WriteFile (hDevice, buffer, 512*numberofsectors, &bytesread, NULL) )
       {
          CloseHandle(hDevice);
          return FALSE;
       }
       return TRUE;
    }
    else
    {
   // code for win 95/98
// 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 )
          return FALSE ;

       if( !SetLock( 0, hDevice, drive ) )        // 0 to Lock
       {
          CloseHandle(hDevice);
          return FALSE;
       }

       ControlBlock.StartingSector = (DWORD)startinglogicalsector;
       ControlBlock.NumberOfSectors = (DWORD)numberofsectors ;
       ControlBlock.pBuffer = (DWORD)buffer ;

//------------------- Int 21h Function 7305h
       //-----------------------------------------------------------
       // SI contains read/write mode flags
       // SI=0h for read and SI = 6001h for write Normal file data
       //                    SI = 0001h for write Other/unknown
       //                    SI = 2001h for FAT data
       //                    SI = 4001h for Directory data
       // CX must be equal to ffffh for
       // int 21h's 7305h extension
       // DS:BX -> base addr of the
       // control block structure
       // DL must contain the drive number
       // (01h=A:, 02h=B: etc)
       //-----------------------------------------------------------
       reg.reg_ESI = 0x0001 ;          // for write BOOT
       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, VWIN32_DIOC_DOS_DRIVEINFO,
          &(reg), sizeof (reg),
          &(reg), sizeof (reg),
          &cb,0);
       if ( !fResult )
       {
          SetLock( 1, hDevice, drive );        // 0 to Lock
          CloseHandle(hDevice);
          return FALSE;
       }


//------------------- Int 26h
//      reg.reg_EAX = drive;    // Int 26h drive numbers are 0-based.
//      reg.reg_EBX = (DWORD)(&ControlBlock);
//      reg.reg_ECX = 0xFFFF;        // use DISKIO struct
//      fResult = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_INT26,
//         &reg, sizeof(reg),
//         &reg, sizeof(reg),
//         &cb, 0);
//      if ( !fResult )
//      {
//         SetLock( 1, hDevice, drive );        // 0 to Lock
//         CloseHandle(hDevice);
//         return FALSE;
//      }


//------------------- Int 21h Function 440Dh Minor Code 41h
//      RwBlock.SpecFunc = 0;
//      RwBlock.Head = 0;
//      RwBlock.Cylinder = 0;
//      RwBlock.FirstSector = (DWORD)startinglogicalsector;
//      RwBlock.Sectors = (DWORD)numberofsectors ;
//      RwBlock.Buffer = (DWORD)buffer ;
//      reg.reg_EBX = drive + 1;     // 1 = A, 2 = B, etc
//      reg.reg_ECX = 0x4841;        // FAT32, 16, or 12 & Write - 0x41
//      reg.reg_EDX = (DWORD)(&RwBlock);
//      reg.reg_EAX = 0x440d;
//      fResult = DeviceIoControl ( hDevice, VWIN32_DIOC_DOS_IOCTL,
//         &(reg), sizeof (reg),
//         &(reg), sizeof (reg),
//         &cb, 0);
//      if ( !fResult )
//      {
//         reg.reg_ECX = 0x0841;        // try FAT16, or 12 & Write - 0x41
//         fResult = DeviceIoControl ( hDevice, VWIN32_DIOC_DOS_IOCTL,
//            &(reg), sizeof (reg),
//            &(reg), sizeof (reg),
//            &cb, 0);
//         if ( !fResult )
//         {
//            SetLock( 1, hDevice, drive );        // 0 to Lock
//            CloseHandle(hDevice);
//            return FALSE;
//         }
//      }

       SetLock( 1, hDevice, drive );        // 0 to Lock
       CloseHandle(hDevice);
       return TRUE;
    }
}



//-----------------------------------------------------------------
//Code to read disk sectors from win 9x/NT/2K/XP
//
//Reads [numberofsectors] disk sectors from
//      [drive {0=A, 1=B, 2=C, ...}] drive
//      starting from [startinglogicalsector]
//
//To read sectors from win 9x int 21h's 7305h extention is used
//      (Extended Absolute Disk Read/Write).
//      For more info about int 21h's 7305h extention refer
//      Ralf Brown's interrupt list.
//------------------------------------------------------------------
BOOL ReadSectors(int drive, DWORD startinglogicalsector, int numberofsectors, char*buffer)
{

// 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 ()

//char* buffer = (char*)malloc (512*numberofsectors);
HANDLE hDevice ;
DEVIOCTL_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[] = "\\\\.\\A:";
   _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 FALSE;

   // 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) )
      {
         CloseHandle(hDevice);
         return FALSE;
      }
}
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=6001h 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_Flags = 0x8000;
   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))
    {
       CloseHandle(hDevice);
       return FALSE;
    }
}

CloseHandle(hDevice);
return TRUE;
}
Technical Details
Message-ID: <404729a6@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <40437604@newsgroups.borland.com> <404380f3$1@newsgroups.borland.com> <40439482$1@newsgroups.borland.com> <40439fa5$1@newsgroups.borland.com> <4043a4e7$1@newsgroups.borland.com> <4043ae8f$2@newsgroups.borland.com> <4043b610@newsgroups.borland.com> <kbs7409ien56crro53tr9i26s1p6n3cv44@4ax.com> <404408ea$1@newsgroups.borland.com> <4046725d@newsgroups.borland.com> <4046860c$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10cc67,5a57fca3b977b3f5
X-Google-Attributes: gid10cc67,public
X-Google-ArrivalTime: 2004-03-04 05:10:06 PST
Date: Thu, 04 Mar 2004 08:05:19 -0500
From: Walt Morrey <dadinc@bellsouth.net>
User-Agent: Mozilla/5.0 (Windows; U; Win 9x 4.90; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)
X-Accept-Language: en-us, en
MIME-Version: 1.0
Newsgroups: borland.public.cppbuilder.nativeapi
Subject: Re: Problems writing boot record to removable media under WinME
References: <40437604@newsgroups.borland.com> <404380f3$1@newsgroups.borland.com> <40439482$1@newsgroups.borland.com> <40439fa5$1@newsgroups.borland.com> <4043a4e7$1@newsgroups.borland.com> <4043ae8f$2@newsgroups.borland.com> <4043b610@newsgroups.borland.com> <kbs7409ien56crro53tr9i26s1p6n3cv44@4ax.com> <404408ea$1@newsgroups.borland.com> <4046725d@newsgroups.borland.com> <4046860c$1@newsgroups.borland.com>
In-Reply-To: <4046860c$1@newsgroups.borland.com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 66.157.248.28
Message-ID: <404729a6@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1078405542 66.157.248.28 (4 Mar 2004 05:05:42 -0800)
Lines: 336
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail