BUG: Int 21 Read/Write Track on Logical Drive Fails on OSR2Last reviewed: October 2, 1997Article ID: Q174569 |
The information in this article applies to:
SYMPTOMSOn Windows 95 OEM Service Release2 (OSR2), Read Track on Logical Drive (Int 21h function 440Dh minor code 61h) and Write Track on Logical Drive (Int 21h function 440Dh minor code 41h), do not work when called through the DeviceIoControl API. When these functions are called, both DeviceIoControl and the Int 21h functions succeed, but the data is not read or written. However, both functions work correctly when called from Win16-based and MS- DOS based applications. On the retail version of Windows 95, both functions work when called through DeviceIOControl as well as Win16-based and MS-DOS based applications.
CAUSEWindows 95 OEM Service Release 2 has a bug that affects Int 21h function 440Dh minor codes 61h and 41h only when called through DeviceIoControl.
RESOLUTIONThere are two ways to work around this bug:
STATUSMicrosoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.
MORE INFORMATIONWin32 and console applications running on Windows 95 and its successors use the DeviceIoControl() API to issue MS-DOS Interrupt 21h functions to perform low-level disk I/O. Such applications usually are disk utilities that must bypass the file system in order to perform activities such as formatting and defragmenting disks. Windows 95 and its successors provides several functions to access sectors on a logical drive. These functions correspond to those available to MS-DOS and Win16-based applications, including Int 21h function 440Dh functions, Int 25h, and Int 26h. In addition, Windows 95 OEM Service Release 2 (OSR2) includes a new function, Int 21h function 7305h. If your application must be compatible with the retail release version of Windows 95, but still support FAT32, then it should check the operating system version. If Windows 95 OSR2 is running, your application can call Int 21h function 7305h. If it is running on the retail release of Windows 95, it should use Int 25h and Int 26h. The following code demonstrates how to call these functions.
Sample Code
#include <windows.h> #define VWIN32_DIOC_DOS_INT25 2 #define VWIN32_DIOC_DOS_INT26 3 #define VWIN32_DIOC_DOS_DRIVEINFO 6 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, *PDIOC_REGISTERS; #define CARRY_FLAG 1 #pragma pack(1) typedef struct _DISKIO { DWORD dwStartSector; // starting logical sector number WORD wSectors; // number of sectors DWORD dwBuffer; // address of read/write buffer } DISKIO, * PDISKIO; #pragma pack() /*------------------------------------------------------------------ ReadLogicalSectors (hDev, bDrive, dwStartSector, wSectors, lpSectBuff) Purpose: Reads sectors from a logical drive. Uses Int 25h. Parameters: hDev Handle of VWIN32 bDrive The MS-DOS logical drive number. 1 = A, 2 = B, 3 = C, etc. dwStartSector The first logical sector to read wSectors The number of sectors to read lpSectBuff The caller-supplied buffer that will contain the sector data Return Value: Returns TRUE if successful, or FALSE if failure. Comments: This function does not validate its parameters. ------------------------------------------------------------------*/ BOOL ReadLogicalSectors (HANDLE hDev, BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff) { BOOL fResult; DWORD cb; DIOC_REGISTERS reg = {0}; DISKIO dio = {0}; dio.dwStartSector = dwStartSector; dio.wSectors = wSectors; dio.dwBuffer = (DWORD)lpSectBuff; reg.reg_EAX = bDrive - 1; // Int 25h drive numbers are 0-based. reg.reg_EBX = (DWORD)&dio; reg.reg_ECX = 0xFFFF; // use DISKIO struct fResult = DeviceIoControl(hDev, VWIN32_DIOC_DOS_INT25, ®, sizeof(reg), ®, sizeof(reg), &cb, 0); // Determine if the DeviceIoControl call and the read succeeded. fResult = fResult && !(reg.reg_Flags & CARRY_FLAG); return fResult; } /*------------------------------------------------------------------ WriteLogicalSectors (hDev, bDrive, dwStartSector, wSectors, lpSectBuff) Purpose: Writes sectors to a logical drive. Uses Int 26h Parameters: hDev Handle of VWIN32 bDrive The MS-DOS logical drive number. 1 = A, 2 = B, 3 = C, etc. dwStartSector The first logical sector to write wSectors The number of sectors to write lpSectBuff The caller-supplied buffer that contains the sector data Return Value: Returns TRUE if successful, or FALSE if failure. Comments: This function does not validate its parameters. ------------------------------------------------------------------*/ BOOL WriteLogicalSectors (HANDLE hDev, BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff) { BOOL fResult; DWORD cb; DIOC_REGISTERS reg = {0}; DISKIO dio = {0}; dio.dwStartSector = dwStartSector; dio.wSectors = wSectors; dio.dwBuffer = (DWORD)lpSectBuff; reg.reg_EAX = bDrive - 1; // Int 26h drive numbers are 0-based. reg.reg_EBX = (DWORD)&dio; reg.reg_ECX = 0xFFFF; // use DISKIO struct fResult = DeviceIoControl(hDev, VWIN32_DIOC_DOS_INT26, ®, sizeof(reg), ®, sizeof(reg), &cb, 0); // Determine if the DeviceIoControl call and the write succeeded. fResult = fResult && !(reg.reg_Flags & CARRY_FLAG); return fResult; } /*------------------------------------------------------------------ NewReadSectors(hDev, bDrive, dwStartSector, wSectors, lpSectBuff) Purpose: Reads the specified number of sectors into a caller-supplied buffer. Uses Int 21h function 7305h Parameters: hDev Handle of VWIN32 bDrive The MS-DOS logical drive number. 0 = default, 1 = A, 2 = B, 3 = C, etc. dwStartSector The first sector to read. wSectors The number of sectors to read. lpSectBuff The caller-supplied buffer to read into. Return Value: Returns TRUE if successful, or FALSE if failure. Comments: This function does not validate its parameters. It assumes that lpSectBuff is allocated by the caller and is large enough to hold all of the data from all of the sectors being read. ------------------------------------------------------------------*/ BOOL NewReadSectors (HANDLE hDev, BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff) { BOOL fResult; DWORD cb; DIOC_REGISTERS reg = {0}; DISKIO dio; dio.dwStartSector = dwStartSector; dio.wSectors = wSectors; dio.lpBuffer = (DWORD)lpSectBuff; reg.reg_EAX = 0x7305; // Ext_ABSDiskReadWrite reg.reg_EBX = (DWORD)&dio; reg.reg_ECX = -1; reg.reg_EDX = bDrive; // Int 21h, fn 7305h drive numbers are 1-based fResult = DeviceIoControl(hDev, VWIN32_DIOC_DOS_DRIVEINFO, ®, sizeof(reg), ®, sizeof(reg), &cb, 0); // Determine if the DeviceIoControl call and the read succeeded. fResult = fResult && !(reg.reg_Flags & CARRY_FLAG); return fResult; } /*------------------------------------------------------------------ NewWriteSectors(hDev, bDrive, dwStartSector, wSectors, lpSectBuff) Purpose: Writes the specified number of sectors from a caller-supplied buffer. Uses Int 21h function 7305h Parameters: hDev Handle of VWIN32 bDrive The MS-DOS logical drive number. 0 = default, 1 = A, 2 = B, 3 = C, etc. dwStartSector The first sector to write. wSectors The number of sectors to write. lpSectBuff The caller-supplied buffer from which to write. Return Value: Returns TRUE if successful, or FALSE if failure. Comments: This function does not validate its parameters. It assumes that lpSectBuff is allocated by the caller and is large enough to hold all of the data to be written. ------------------------------------------------------------------*/ BOOL NewWriteSectors (HANDLE hDev, BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff) { BOOL fResult; DWORD cb; DIOC_REGISTERS reg = {0}; DISKIO dio; dio.dwStartSector = dwStartSector; dio.wSectors = wSectors; dio.lpBuffer = (DWORD)lpSectBuff; reg.reg_EAX = 0x7305; // Ext_ABSDiskReadWrite reg.reg_EBX = (DWORD)&dio; reg.reg_ECX = -1; reg.reg_EDX = bDrive; // Int 21h, fn 7305h drive numbers are 1-based reg.reg_ESI = 0x6001; // Normal file data (See function // documentation for other values) fResult = DeviceIoControl(hDev, VWIN32_DIOC_DOS_DRIVEINFO, ®, sizeof(reg), ®, sizeof(reg), &cb, 0); // Determine if the DeviceIoControl call and the write succeeded. fResult = fResult && !(reg.reg_Flags & CARRY_FLAG); return fResult; } REFERENCES"Microsoft MS-DOS Programmer's Reference", Version 6.0, pages 140-144, 313- 314, 321-322. Online Documentation: Microsoft Win32 SDK, Programming Tools and Guides; Programmer's Guide to Windows 95; Windows 95 Reference; FAT32 API Reference; Functions; Int 21h Function 7305h Ext_AbsDiskReadWrite (FAT32)
|
Additional query words: format logical drive low level ioctl bios
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |