1 /* nt4_dev.c - routines for direct drive access in Windows NT 4.0
3 * Copyright 1999 by Dan Sutherland <dan@chromerhino.demon.co.uk>
5 * These routines only currently work with drives <2GB and 512 bytes per sector
13 HANDLE
NT4OpenDrive(char *lpstrDrive
)
15 char strDriveFile
[40];
19 switch (lpstrDrive
[0]) {
21 sprintf(strDriveFile
, "\\\\.\\PhysicalDrive%c", lpstrDrive
[1]);
23 /* add support for other device types here */
28 hDrv
= CreateFile(strDriveFile
, GENERIC_READ
| GENERIC_WRITE
,
29 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
32 if (hDrv
== INVALID_HANDLE_VALUE
)
35 if (! DeviceIoControl(hDrv
, FSCTL_LOCK_VOLUME
, NULL
, 0, NULL
, 0,
42 BOOL
NT4CloseDrive(HANDLE hDrv
)
46 if (! DeviceIoControl(hDrv
, FSCTL_UNLOCK_VOLUME
, NULL
, 0, NULL
, 0,
50 if (! CloseHandle(hDrv
))
56 BOOL
NT4ReadSector(HANDLE hDrv
, long iSect
, int iSize
, void *lpvoidBuf
)
61 lpvoidTempBuf
= VirtualAlloc(NULL
, 512, MEM_COMMIT
, PAGE_READWRITE
);
63 if (SetFilePointer(hDrv
, iSect
* 512, NULL
, FILE_BEGIN
) == 0xFFFFFFFF) {
64 VirtualFree(lpvoidTempBuf
, 0, MEM_RELEASE
);
68 if (! ReadFile(hDrv
, lpvoidTempBuf
, 512, &dwActual
, NULL
)) {
69 VirtualFree(lpvoidTempBuf
, 0, MEM_RELEASE
);
73 memcpy(lpvoidBuf
, lpvoidTempBuf
, iSize
);
74 VirtualFree(lpvoidTempBuf
, 0, MEM_RELEASE
);
79 BOOL
NT4WriteSector(HANDLE hDrv
, long iSect
, int iSize
, void *lpvoidBuf
)
87 lpvoidTempBuf
= VirtualAlloc(NULL
, 512, MEM_COMMIT
, PAGE_READWRITE
);
89 if (SetFilePointer(hDrv
, iSect
* 512, NULL
, FILE_BEGIN
) == 0xFFFFFFFF) {
90 VirtualFree(lpvoidTempBuf
, 0, MEM_RELEASE
);
94 memcpy(lpvoidTempBuf
, lpvoidBuf
, iSize
);
96 if (! WriteFile(hDrv
, lpvoidTempBuf
, 512, &dwActual
, NULL
)) {
97 VirtualFree(lpvoidTempBuf
, 0, MEM_RELEASE
);
101 VirtualFree(lpvoidTempBuf
, 0, MEM_RELEASE
);
106 ULONG
NT4GetDriveSize(HANDLE hDrv
)
109 DISK_GEOMETRY dgGeom
;
112 DeviceIoControl(hDrv
, IOCTL_DISK_GET_DRIVE_GEOMETRY
, NULL
, 0,
113 &dgGeom
, sizeof(DISK_GEOMETRY
), &dwActual
, NULL
);
115 size
= dgGeom
.Cylinders
.LowPart
* dgGeom
.TracksPerCylinder
*
116 dgGeom
.SectorsPerTrack
* dgGeom
.BytesPerSector
;
118 printf("Total sectors: %i\n", dgGeom
.Cylinders
.LowPart
* dgGeom
.TracksPerCylinder
* dgGeom
.SectorsPerTrack
);
119 printf("Byte size: %i\n", size
);