define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / tools / adflib / Win32 / nt4_dev.c
blob1e87bff41c3a5bc5de48b81096e95b957118d49d
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
6 */
8 #include <windows.h>
9 #include <winioctl.h>
10 #include <stdio.h>
11 #include "nt4_dev.h"
13 HANDLE NT4OpenDrive(char *lpstrDrive)
15 char strDriveFile[40];
16 HANDLE hDrv;
17 DWORD dwRet;
19 switch (lpstrDrive[0]) {
20 case 'H':
21 sprintf(strDriveFile, "\\\\.\\PhysicalDrive%c", lpstrDrive[1]);
22 break;
23 /* add support for other device types here */
24 default:
25 return NULL;
28 hDrv = CreateFile(strDriveFile, GENERIC_READ | GENERIC_WRITE,
29 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
30 0, NULL);
32 if (hDrv == INVALID_HANDLE_VALUE)
33 return NULL;
35 if (! DeviceIoControl(hDrv, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0,
36 &dwRet, NULL))
37 return NULL;
39 return hDrv;
42 BOOL NT4CloseDrive(HANDLE hDrv)
44 DWORD dwRet;
46 if (! DeviceIoControl(hDrv, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0,
47 &dwRet, NULL))
48 return FALSE;
50 if (! CloseHandle(hDrv))
51 return FALSE;
53 return TRUE;
56 BOOL NT4ReadSector(HANDLE hDrv, long iSect, int iSize, void *lpvoidBuf)
58 void *lpvoidTempBuf;
59 DWORD dwActual;
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);
65 return FALSE;
68 if (! ReadFile(hDrv, lpvoidTempBuf, 512, &dwActual, NULL)) {
69 VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
70 return FALSE;
73 memcpy(lpvoidBuf, lpvoidTempBuf, iSize);
74 VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
76 return TRUE;
79 BOOL NT4WriteSector(HANDLE hDrv, long iSect, int iSize, void *lpvoidBuf)
81 void *lpvoidTempBuf;
82 DWORD dwActual;
84 if (iSize != 512)
85 return FALSE;
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);
91 return FALSE;
94 memcpy(lpvoidTempBuf, lpvoidBuf, iSize);
96 if (! WriteFile(hDrv, lpvoidTempBuf, 512, &dwActual, NULL)) {
97 VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
98 return FALSE;
101 VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
103 return TRUE;
106 ULONG NT4GetDriveSize(HANDLE hDrv)
108 DWORD dwActual;
109 DISK_GEOMETRY dgGeom;
110 long size;
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);
121 return size;