@@ -27,7 +27,7 @@ DBG_DEFAULT_CHANNEL(DISK);
2727/* Enable this line if you want to support multi-drive caching (increases FreeLdr size!) */
2828// #define CACHE_MULTI_DRIVES
2929
30- #include <pshpack2 .h>
30+ #include <pshpack1 .h>
3131
3232typedef struct
3333{
@@ -74,6 +74,22 @@ typedef struct
7474 UCHAR Reserved ;
7575} I386_CDROM_SPEC_PACKET , * PI386_CDROM_SPEC_PACKET ;
7676
77+ /*
78+ * Extended disk geometry (Int13 / AH=48h)
79+ * See also ntdddisk.h DISK_EX_INT13_INFO
80+ */
81+ typedef struct _EXTENDED_GEOMETRY
82+ {
83+ USHORT Size ;
84+ USHORT Flags ;
85+ ULONG Cylinders ;
86+ ULONG Heads ;
87+ ULONG SectorsPerTrack ;
88+ ULONGLONG Sectors ;
89+ USHORT BytesPerSector ;
90+ ULONG PDPTE ;
91+ } EXTENDED_GEOMETRY , * PEXTENDED_GEOMETRY ;
92+
7793#include <poppack.h>
7894
7995typedef struct _PC_DISK_DRIVE
@@ -295,21 +311,27 @@ DiskInt13ExtensionsSupported(IN UCHAR DriveNumber)
295311
296312static BOOLEAN
297313DiskGetExtendedDriveParameters (
298- IN UCHAR DriveNumber ,
299- IN PPC_DISK_DRIVE DiskDrive ,
300- OUT PVOID Buffer ,
301- IN USHORT BufferSize )
314+ _In_ UCHAR DriveNumber ,
315+ _In_ PPC_DISK_DRIVE DiskDrive ,
316+ _Out_ PVOID Buffer ,
317+ _In_ USHORT BufferSize )
302318{
319+ PEXTENDED_GEOMETRY Ptr = (PEXTENDED_GEOMETRY )BIOSCALLBUFFER ;
303320 REGS RegsIn , RegsOut ;
304- PUSHORT Ptr = (PUSHORT )(BIOSCALLBUFFER );
305321
306322 TRACE ("DiskGetExtendedDriveParameters(0x%x)\n" , DriveNumber );
307323
308- if (!DiskDrive -> Int13ExtensionsSupported )
324+ if (!DiskDrive -> Int13ExtensionsSupported || ( BufferSize < sizeof ( * Ptr )) )
309325 return FALSE;
310326
311- /* Initialize transfer buffer */
312- * Ptr = BufferSize ;
327+ /*
328+ * Initialize the transfer buffer.
329+ * NOTE: Zeroing out the buffer also helps avoiding the bug where Dell
330+ * machines using PhoenixBIOS 4.0 Release 6.0 fail to correctly handle
331+ * this function if Ptr->Flags is not 0 on entry.
332+ */
333+ RtlZeroMemory (Ptr , sizeof (* Ptr )); // BufferSize;
334+ Ptr -> Size = BufferSize ;
313335
314336 /*
315337 * BIOS Int 13h, function 48h - Get drive parameters
@@ -325,7 +347,7 @@ DiskGetExtendedDriveParameters(
325347 */
326348 RegsIn .b .ah = 0x48 ;
327349 RegsIn .b .dl = DriveNumber ;
328- RegsIn .x .ds = BIOSCALLBUFSEGMENT ; // DS:SI -> result buffer
350+ RegsIn .x .ds = BIOSCALLBUFSEGMENT ;
329351 RegsIn .w .si = BIOSCALLBUFOFFSET ;
330352
331353 /* Get drive parameters */
@@ -336,22 +358,25 @@ DiskGetExtendedDriveParameters(
336358 RtlCopyMemory (Buffer , Ptr , BufferSize );
337359
338360#if DBG
339- TRACE ("Size of buffer: 0x%x\n" , Ptr [ 0 ] );
340- TRACE ("Information flags: 0x%x\n" , Ptr [ 1 ] );
341- TRACE ("Number of physical cylinders on drive: %u\n" , * ( PULONG ) & Ptr [ 2 ] );
342- TRACE ("Number of physical heads on drive: %u\n" , * ( PULONG ) & Ptr [ 4 ] );
343- TRACE ("Number of physical sectors per track: %u\n" , * ( PULONG ) & Ptr [ 6 ] );
344- TRACE ("Total number of sectors on drive: %I64u\n" , * ( PULONGLONG ) & Ptr [ 8 ] );
345- TRACE ("Bytes per sector: %u\n" , Ptr [ 12 ] );
346- if (Ptr [ 0 ] >= 0x1e )
361+ TRACE ("Size of buffer: 0x%x\n" , Ptr -> Size );
362+ TRACE ("Information flags: 0x%x\n" , Ptr -> Flags );
363+ TRACE ("Number of physical cylinders on drive: %u\n" , Ptr -> Cylinders );
364+ TRACE ("Number of physical heads on drive: %u\n" , Ptr -> Heads );
365+ TRACE ("Number of physical sectors per track: %u\n" , Ptr -> SectorsPerTrack );
366+ TRACE ("Total number of sectors on drive: %I64u\n" , Ptr -> Sectors );
367+ TRACE ("Bytes per sector: %u\n" , Ptr -> BytesPerSector );
368+ if (Ptr -> Size >= 0x1E )
347369 {
348- // Ptr[13]: offset, Ptr[14]: segment
349- TRACE ("EDD configuration parameters (DPTE): %x:%x\n" , Ptr [14 ], Ptr [13 ]);
370+ // LOWORD(Ptr->PDPTE): offset, HIWORD(Ptr->PDPTE): segment
371+ USHORT Off = (USHORT )(Ptr -> PDPTE & 0xFFFF ); // ((PUSHORT)&Ptr->PDPTE)[0];
372+ USHORT Seg = (USHORT )((Ptr -> PDPTE >> 16 ) & 0xFFFF ); // ((PUSHORT)&Ptr->PDPTE)[1];
373+ TRACE ("EDD configuration parameters (DPTE): %x:%x\n" , Seg , Off );
374+
350375 /* The DPTE pointer is valid if it's != FFFF:FFFF (per the Enhanced Disk
351376 * Drive Specification), but also, when it's != 0000:0000 (broken BIOSes) */
352- if (!( Ptr [ 13 ] == 0xFFFF && Ptr [ 14 ] == 0xFFFF ) && !( Ptr [ 13 ] == 0 && Ptr [ 14 ] == 0 ) )
377+ if (Ptr -> PDPTE != 0xFFFFFFFF && Ptr -> PDPTE != 0 )
353378 {
354- PUCHAR SpecPtr = (PUCHAR )(ULONG_PTR )((Ptr [ 14 ] << 4 ) + Ptr [ 13 ] );
379+ PUCHAR SpecPtr = (PUCHAR )(ULONG_PTR )((Seg << 4 ) + Off );
355380 TRACE ("SpecPtr: 0x%x\n" , SpecPtr );
356381 TRACE ("Physical I/O port base address: 0x%x\n" , * (PUSHORT )& SpecPtr [0 ]);
357382 TRACE ("Disk-drive control port address: 0x%x\n" , * (PUSHORT )& SpecPtr [2 ]);
@@ -364,9 +389,9 @@ DiskGetExtendedDriveParameters(
364389 TRACE ("Drive options: 0x%x\n" , * (PUSHORT )& SpecPtr [10 ]);
365390 }
366391 }
367- if (Ptr [ 0 ] >= 0x42 )
392+ if (Ptr -> Size >= 0x42 )
368393 {
369- TRACE ("Signature: 0x%x\n" , Ptr [15 ]);
394+ TRACE ("Signature: 0x%x\n" , (( PUSHORT ) Ptr ) [15 ]);
370395 }
371396#endif // DBG
372397
@@ -383,16 +408,11 @@ InitDriveGeometry(
383408 ULONG Cylinders ;
384409
385410 /* Get the extended geometry first */
386- DiskDrive -> ExtGeometry . Size = sizeof (DiskDrive -> ExtGeometry );
411+ RtlZeroMemory ( & DiskDrive -> ExtGeometry , sizeof (DiskDrive -> ExtGeometry ) );
387412 Success = DiskGetExtendedDriveParameters (DriveNumber , DiskDrive ,
388413 & DiskDrive -> ExtGeometry ,
389- DiskDrive -> ExtGeometry .Size );
390- if (!Success )
391- {
392- /* Failed, zero it out */
393- RtlZeroMemory (& DiskDrive -> ExtGeometry , sizeof (DiskDrive -> ExtGeometry ));
394- }
395- else
414+ sizeof (DiskDrive -> ExtGeometry ));
415+ if (Success )
396416 {
397417 TRACE ("DiskGetExtendedDriveParameters(0x%x) returned:\n"
398418 "Cylinders : 0x%x\n"
@@ -575,9 +595,9 @@ PcDiskReadLogicalSectorsLBA(
575595 IN ULONG SectorCount ,
576596 OUT PVOID Buffer )
577597{
598+ PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET )BIOSCALLBUFFER ;
578599 REGS RegsIn , RegsOut ;
579600 ULONG RetryCount ;
580- PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET )(BIOSCALLBUFFER );
581601
582602 /* Setup disk address packet */
583603 RtlZeroMemory (Packet , sizeof (* Packet ));
0 commit comments