/* nt4_dev.c - routines for direct drive access in Windows NT 4.0 * * Copyright 1999 by Dan Sutherland * * These routines only currently work with drives <2GB and 512 bytes per sector */ #include #include #include #include "nt4_dev.h" HANDLE NT4OpenDrive(char *lpstrDrive) { char strDriveFile[40]; HANDLE hDrv; DWORD dwRet; switch (lpstrDrive[0]) { case 'H': sprintf(strDriveFile, "\\\\.\\PhysicalDrive%c", lpstrDrive[1]); break; /* add support for other device types here */ default: return NULL; } hDrv = CreateFile(strDriveFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDrv == INVALID_HANDLE_VALUE) return NULL; if (! DeviceIoControl(hDrv, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwRet, NULL)) return NULL; return hDrv; } BOOL NT4CloseDrive(HANDLE hDrv) { DWORD dwRet; if (! DeviceIoControl(hDrv, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwRet, NULL)) return FALSE; if (! CloseHandle(hDrv)) return FALSE; return TRUE; } BOOL NT4ReadSector(HANDLE hDrv, long iSect, int iSize, void *lpvoidBuf) { void *lpvoidTempBuf; DWORD dwActual; lpvoidTempBuf = VirtualAlloc(NULL, 512, MEM_COMMIT, PAGE_READWRITE); if (SetFilePointer(hDrv, iSect * 512, NULL, FILE_BEGIN) == 0xFFFFFFFF) { VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE); return FALSE; } if (! ReadFile(hDrv, lpvoidTempBuf, 512, &dwActual, NULL)) { VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE); return FALSE; } memcpy(lpvoidBuf, lpvoidTempBuf, iSize); VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE); return TRUE; } BOOL NT4WriteSector(HANDLE hDrv, long iSect, int iSize, void *lpvoidBuf) { void *lpvoidTempBuf; DWORD dwActual; if (iSize != 512) return FALSE; lpvoidTempBuf = VirtualAlloc(NULL, 512, MEM_COMMIT, PAGE_READWRITE); if (SetFilePointer(hDrv, iSect * 512, NULL, FILE_BEGIN) == 0xFFFFFFFF) { VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE); return FALSE; } memcpy(lpvoidTempBuf, lpvoidBuf, iSize); if (! WriteFile(hDrv, lpvoidTempBuf, 512, &dwActual, NULL)) { VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE); return FALSE; } VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE); return TRUE; } ULONG NT4GetDriveSize(HANDLE hDrv) { DWORD dwActual; DISK_GEOMETRY dgGeom; long size; DeviceIoControl(hDrv, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dgGeom, sizeof(DISK_GEOMETRY), &dwActual, NULL); size = dgGeom.Cylinders.LowPart * dgGeom.TracksPerCylinder * dgGeom.SectorsPerTrack * dgGeom.BytesPerSector; printf("Total sectors: %i\n", dgGeom.Cylinders.LowPart * dgGeom.TracksPerCylinder * dgGeom.SectorsPerTrack); printf("Byte size: %i\n", size); return size; }