Article ID: 137176
Article Last Modified on 11/21/2006
//--------------------------------------------------------------------
// Code in the 32-bit DLL
// Prototype for function in 16-bit DLL.
BOOL FAR PASCAL ReadPhysicalSector1 (BYTE bDrive,
LPBYTE lpBuffer,
DWORD cbBuffSize);
/*--------------------------------------------------------------------
CallReadPhysicalSector1()
Reads the first sector of the first hard disk.
Return Value
Returns TRUE if the first sector was read, and FALSE if it
wasn't.
--------------------------------------------------------------------*/
__declspec(dllexport) BOOL WINAPI CallReadPhysicalSector1()
{
char lpBuff[512];
BOOL fResult;
// Read the first sector of the first hard disk.
fResult = ReadPhysicalSector1 (0x80, lpBuff, 512);
if (fResult)
{
// lpBuff contains the sector data. Use it here
}
return fResult;
}
//--------------------------------------------------------------------
// Thunk Script
enablemapdirect3216 = true;
typedef unsigned long DWORD;
typedef unsigned char BYTE, * LPBYTE;
typedef bool BOOL;
BOOL ReadPhysicalSector1 (BYTE bDrive,
LPBYTE lpBuffer,
DWORD cbBuffSize)
{
lpBuffer = inout;
}
//--------------------------------------------------------------------
// Code in the 16-bit DLL
// Converts two BYTEs into a WORD. This is useful for working with
// a RMCS, but was not provided in WINDOWS.H.
//#define MAKEWORD(low, high) \
((WORD)((((WORD)(high)) << 8) | ((BYTE)(low))))
#define SECTOR_SIZE 512 // Size, in bytes, of a disk sector
#define CARRY_FLAG 0x0001
typedef BYTE FAR *LPBYTE;
typedef struct tagRMCS
{
DWORD edi, esi, ebp, RESERVED, ebx, edx, ecx, eax;
WORD wFlags, es, ds, fs, gs, ip, cs, sp, ss;
} RMCS, FAR* LPRMCS;
BOOL FAR PASCAL SimulateRM_Int (BYTE bIntNum, LPRMCS lpCallStruct);
void FAR PASCAL BuildRMCS (LPRMCS lpCallStruct);
BOOL FAR PASCAL __export ReadPhysicalSector1 (BYTE bDrive,
LPBYTE lpBuffer,
DWORD cbBuffSize);
/*--------------------------------------------------------------------
ReadPhysicalSector1()
Calls DPMI to call the BIOS Int 13h Read Track function to read the
first physical sector of a physical drive. This function is used to
read partition tables, for example.
Parameters
bDrive
The Int 13h device unit,
0x00 for floppy drive 0
0x00 for floppy drive 1
0x80 for physical hard disk 0
0x81 for physical hard disk 1
etc.
lpBuffer
Pointer to a buffer that receives the sector data. The buffer
must be at least SECTOR_SIZE bytes long.
cbBuffSize
Actual size of lpBuffer.
Return Value
Returns TRUE if the first sector was read into the buffer pointed
to by lpBuffer, or FALSE otherwise.
Assumptions
Assumes that sectors are at least SECTOR_SIZE bytes long.
--------------------------------------------------------------------*/
BOOL FAR PASCAL __export ReadPhysicalSector1 (BYTE bDrive,
LPBYTE lpBuffer,
DWORD cbBuffSize)
{
BOOL fResult;
RMCS callStruct;
DWORD gdaBuffer; // Return value of GlobalDosAlloc().
LPBYTE RMlpBuffer; // Real-mode buffer pointer
LPBYTE PMlpBuffer; // Protected-mode buffer pointer
/*
Validate params:
bDrive should be int 13h device unit -- let the BIOS validate
this parameter -- user could have a special controller with
its own BIOS.
lpBuffer must not be NULL
cbBuffSize must be large enough to hold a single sector
*/
if (lpBuffer == NULL || cbBuffSize < SECTOR_SIZE)
return FALSE;
/*
Allocate the buffer that the Int 13h function will put the sector
data into. As this function uses DPMI to call the real-mode BIOS, it
must allocate the buffer below 1 MB, and must use a real-mode
paragraph-segment address.
After the memory has been allocated, create real-mode and
protected-mode pointers to the buffer. The real-mode pointer
will be used by the BIOS, and the protected-mode pointer will be
used by this function because it resides in a Windows 16-bit DLL,
which runs in protected mode.
*/
gdaBuffer = GlobalDosAlloc (cbBuffSize);
if (!gdaBuffer)
return FALSE;
RMlpBuffer = (LPBYTE)MAKELONG(0, HIWORD(gdaBuffer));
PMlpBuffer = (LPBYTE)MAKELONG(0, LOWORD(gdaBuffer));
/*
Initialize the real-mode call structure and set all values needed
to read the first sector of the specified physical drive.
*/
BuildRMCS (&callStruct);
callStruct.eax = 0x0201; // BIOS read, 1 sector
callStruct.ecx = 0x0001; // Sector 1, Cylinder 0
callStruct.edx = MAKEWORD(bDrive, 0); // Head 0, Drive #
callStruct.ebx = LOWORD(RMlpBuffer); // Offset of sector buffer
callStruct.es = HIWORD(RMlpBuffer); // Segment of sector buffer
/*
Call Int 13h BIOS Read Track and check both the DPMI call
itself and the BIOS Read Track function result for success. If
successful, copy the sector data retrieved by the BIOS into the
caller's buffer.
*/
if (fResult = SimulateRM_Int (0x13, &callStruct))
if (!(callStruct.wFlags & CARRY_FLAG))
{
_fmemcpy (lpBuffer, PMlpBuffer, (size_t)cbBuffSize);
fResult = TRUE;
}
else
fResult = FALSE;
// Free the sector data buffer this function allocated
GlobalDosFree (LOWORD(gdaBuffer));
return fResult;
}
/*--------------------------------------------------------------------
SimulateRM_Int()
Allows protected mode software to execute real mode interrupts such
as calls to DOS TSRs, DOS device drivers, etc.
This function implements the "Simulate Real Mode Interrupt" function
of the DPMI specification v0.9.
Parameters
bIntNum
Number of the interrupt to simulate
lpCallStruct
Call structure that contains params (register values) for
bIntNum.
Return Value
SimulateRM_Int returns TRUE if it succeeded or FALSE if it
failed.
Comments
lpCallStruct is a protected-mode selector:offset address, not a
real-mode segment:offset address.
--------------------------------------------------------------------*/
BOOL FAR PASCAL SimulateRM_Int (BYTE bIntNum, LPRMCS lpCallStruct)
{
BOOL fRetVal = FALSE; // Assume failure
_asm {
push di
mov ax, 0300h ; DPMI Simulate Real Mode Int
mov bl, bIntNum ; Number of the interrupt to simulate
mov bh, 01h ; Bit 0 = 1; all other bits must be 0
xor cx, cx ; No words to copy
les di, lpCallStruct
int 31h ; Call DPMI
jc END1 ; CF set if error occurred
mov fRetVal, TRUE
END1:
pop di
}
return (fRetVal);
}
/*--------------------------------------------------------------------
BuildRMCS()
Initializes a real mode call structure to contain zeros in all its
members.
Parameters:
lpCallStruct
Points to a real mode call structure
Comments:
lpCallStruct is a protected-mode selector:offset address, not a
real-mode segment:offset address.
--------------------------------------------------------------------*/
void FAR PASCAL BuildRMCS (LPRMCS lpCallStruct)
{
_fmemset (lpCallStruct, 0, sizeof (RMCS));
}
Additional query words: Windows sector table physical
Keywords: kbapi kbkernbase KB137176