1 /* 2 * FreeLoader - volume.c 3 * 4 * Copyright (C) 2001 Brian Palmer <brianp@sginet.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 #include <windows.h> 22 #include <stdio.h> 23 #include <tchar.h> 24 #include "volume.h" 25 26 static HANDLE hDiskVolume = NULL; 27 28 BOOL OpenVolume(LPCTSTR lpszVolumeName) 29 { 30 TCHAR RealVolumeName[MAX_PATH]; 31 32 // 33 // If they passed in a drive letter (e.g. "A:") 34 // then try to open the physical device volume, 35 // otherwise we will assume it is a disk image 36 // file they are writing to. (not fully supported yet) 37 // 38 if ((_tcslen(lpszVolumeName) == 2) && (lpszVolumeName[1] == _T(':'))) 39 { 40 _tcscpy(RealVolumeName, _T("\\\\.\\")); 41 _tcscat(RealVolumeName, lpszVolumeName); 42 } 43 else 44 { 45 _tcscpy(RealVolumeName, lpszVolumeName); 46 } 47 48 _tprintf(_T("Opening volume \'%s\'\n"), lpszVolumeName); 49 50 hDiskVolume = CreateFile(RealVolumeName, 51 GENERIC_READ | GENERIC_WRITE, 52 FILE_SHARE_READ | FILE_SHARE_WRITE, 53 NULL, 54 OPEN_EXISTING, 55 0, 56 NULL); 57 58 if (hDiskVolume == INVALID_HANDLE_VALUE) 59 { 60 _tprintf(_T("%s:%d: "), __FILE__, __LINE__); 61 _tprintf(_T("Failed. Error code %ld.\n"), GetLastError()); 62 return FALSE; 63 } 64 65 return TRUE; 66 } 67 68 void CloseVolume(void) 69 { 70 CloseHandle(hDiskVolume); 71 } 72 73 BOOL ReadVolumeSector(ULONG SectorNumber, PVOID SectorBuffer) 74 { 75 DWORD dwNumberOfBytesRead; 76 DWORD dwFilePosition; 77 BOOL bRetVal; 78 79 // 80 // FIXME: this doesn't seem to handle the situation 81 // properly when SectorNumber is bigger than the 82 // amount of sectors on the disk. Seems to me that 83 // the call to SetFilePointer() should just give an 84 // out of bounds error or something but it doesn't. 85 // 86 dwFilePosition = SetFilePointer(hDiskVolume, (SectorNumber * 512), NULL, FILE_BEGIN); 87 if (dwFilePosition != (SectorNumber * 512)) 88 { 89 _tprintf(_T("%s:%d: "), __FILE__, __LINE__); 90 _tprintf(_T("SetFilePointer() failed. Error code %ld.\n"), GetLastError()); 91 return FALSE; 92 } 93 94 bRetVal = ReadFile(hDiskVolume, SectorBuffer, 512, &dwNumberOfBytesRead, NULL); 95 if (!bRetVal || (dwNumberOfBytesRead != 512)) 96 { 97 _tprintf(_T("%s:%d: "), __FILE__, __LINE__); 98 _tprintf(_T("ReadFile() failed. Error code %ld.\n"), GetLastError()); 99 return FALSE; 100 } 101 102 return TRUE; 103 } 104 105 BOOL WriteVolumeSector(ULONG SectorNumber, PVOID SectorBuffer) 106 { 107 DWORD dwNumberOfBytesWritten; 108 DWORD dwFilePosition; 109 BOOL bRetVal; 110 111 // 112 // FIXME: this doesn't seem to handle the situation 113 // properly when SectorNumber is bigger than the 114 // amount of sectors on the disk. Seems to me that 115 // the call to SetFilePointer() should just give an 116 // out of bounds error or something but it doesn't. 117 // 118 dwFilePosition = SetFilePointer(hDiskVolume, (SectorNumber * 512), NULL, FILE_BEGIN); 119 if (dwFilePosition != (SectorNumber * 512)) 120 { 121 _tprintf(_T("%s:%d: "), __FILE__, __LINE__); 122 _tprintf(_T("SetFilePointer() failed. Error code %ld.\n"), GetLastError()); 123 return FALSE; 124 } 125 126 bRetVal = WriteFile(hDiskVolume, SectorBuffer, 512, &dwNumberOfBytesWritten, NULL); 127 if (!bRetVal || (dwNumberOfBytesWritten != 512)) 128 { 129 _tprintf(_T("%s:%d: "), __FILE__, __LINE__); 130 _tprintf(_T("WriteFile() failed. Error code %ld.\n"), GetLastError()); 131 return FALSE; 132 } 133 134 return TRUE; 135 } 136