Code :
- //////////////////////////////////////////////////////////////////////
- //
- // RawDisk - Direct Disk Read/Write Access for NT/2000/XP
- // Copyright (c) 2003 Jan Kiszka
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; either version 2 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Version.h"
- #define BUFFER_SIZE 1024*1024
- int lock_volume(HANDLE hDisk)
- {
- DWORD dummy;
- return DeviceIoControl(hDisk, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0,
- &dummy, NULL);
- }
- int unlock_volume(HANDLE hDisk)
- {
- DWORD dummy;
- return DeviceIoControl(hDisk, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0,
- &dummy, NULL);
- }
- void usage(void)
- {
- printf(" Usage: rawdisk [-r|-w] diskno imagefilen"
- " rawdisk -i disknonn"
- "t-r tread from diskn"
- "t-w twrite to diskn"
- "t-i tprint disk parameters onlyn"
- "tdiskno tnumber of harddisk to read or write (0 for first disk)n"
- "timagefiletname of the image filenn" );
- exit(1);
- }
- void error(char* msg)
- {
- char* pMsgBuf;
- printf(msg);
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&pMsgBuf,
- 0, NULL);
- printf(pMsgBuf);
- LocalFree(pMsgBuf);
- exit(1);
- }
- int main(int argc, char* argv[])
- {
- enum {read, write, info} mode;
- unsigned int diskno;
- char diskname[] = "\\.\PhysicalDrive0";
- HANDLE hDisk;
- HANDLE hFile;
- DWORD count;
- DISK_GEOMETRY geometry;
- LONGLONG totalSize;
- LONGLONG bufSize;
- PVOID pBuffer;
- DWORD blockSize;
- DWORD i;
- DWORD blocks;
- printf("RawDisk " VER_FILEVERSION_STR ", Copyright (c) 2003 Jan Kiszkan" );
- if ((argc < 3) || (argc > 4))
- usage();
- if (strcmp(argv[1], "-r" ) == 0)
- mode = read;
- else if (strcmp(argv[1], "-w" ) == 0)
- mode = write;
- else if (strcmp(argv[1], "-i" ) == 0)
- mode = info;
- else
- usage();
- if ((mode != info) && (argc !=4))
- usage();
- if (sscanf(argv[2], "%ud", &diskno) != 1)
- usage();
- if ((diskno == 0) && (mode == write))
- {
- printf(" To avoid damage, writing to the first disk - which is most "
- "likely your systemn hard disk - is currently disabled.n" );
- exit(1);
- }
- diskname[strlen(diskname)-1] += diskno;
- pBuffer = VirtualAlloc(NULL, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
- if (pBuffer == NULL)
- error(" Error allocating a buffer: " );
- hDisk = CreateFile(diskname, (mode == read) ? GENERIC_READ : GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
- if (hDisk == INVALID_HANDLE_VALUE)
- error(" Error opening disk: " );
- if (mode != info)
- {
- hFile = CreateFile(argv[3], (mode == write) ? GENERIC_READ : GENERIC_WRITE,
- 0, NULL, (mode == write) ? OPEN_EXISTING : CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- error(" Error opening image file: " );
- }
- if (!DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
- &geometry, sizeof(geometry), &count, NULL))
- error(" Error reading disk parameters: " );
- totalSize = geometry.Cylinders.QuadPart * geometry.TracksPerCylinder *
- geometry.SectorsPerTrack * geometry.BytesPerSector;
- printf(" Disk Size: t%.1f MB (%I64u bytes)n",
- ((float)totalSize)/(1024*1024), totalSize);
- if (mode == info)
- {
- printf(" Cylinders: t%I64un"
- " Tracks per Cylinder:t%un"
- " Sectors per Track: t%un"
- " Byte per Sector: t%un", geometry.Cylinders.QuadPart,
- geometry.TracksPerCylinder, geometry.SectorsPerTrack,
- geometry.BytesPerSector);
- CloseHandle(hDisk);
- return 0;
- }
- if (!lock_volume(hDisk))
- error(" Error locking disk: " );
- i = 0;
- bufSize = BUFFER_SIZE;
- blocks = (DWORD)((totalSize + BUFFER_SIZE-1) / bufSize);
- if (mode == read)
- {
- while (totalSize > 0)
- {
- printf("r Reading Disk %d: t%u/%u", diskno, i, blocks);
- blockSize = BUFFER_SIZE;
- if (totalSize < blockSize)
- blockSize = (DWORD)totalSize;
- if (!ReadFile(hDisk, pBuffer, blockSize, &count, NULL))
- {
- count = GetLastError();
- unlock_volume(hDisk);
- SetLastError(count);
- error(" Error reading from disk: " );
- }
- if (!WriteFile(hFile, pBuffer, blockSize, &count, NULL))
- {
- count = GetLastError();
- unlock_volume(hDisk);
- SetLastError(count);
- error(" Error writing to image file: " );
- }
- totalSize -= blockSize;
- i++;
- }
- printf("r Reading Disk %d: t%u/%un", diskno, i, blocks);
- }
- else
- {
- while (totalSize > 0)
- {
- printf("r Writing Disk %d: t%u/%u", diskno, i, blocks);
- blockSize = BUFFER_SIZE;
- if (totalSize < blockSize)
- blockSize = (DWORD)totalSize;
- if (!ReadFile(hFile, pBuffer, blockSize, &count, NULL))
- {
- count = GetLastError();
- unlock_volume(hDisk);
- SetLastError(count);
- error(" Error reading from image file: " );
- }
- if (!WriteFile(hDisk, pBuffer, blockSize, &count, NULL))
- {
- count = GetLastError();
- unlock_volume(hDisk);
- SetLastError(count);
- error(" Error writing to disk: " );
- }
- totalSize -= blockSize;
- i++;
- }
- printf("r Writing Disk %d: t%u/%un", diskno, i, blocks);
- }
- unlock_volume(hDisk);
- CloseHandle(hDisk);
- CloseHandle(hFile);
- return 0;
- }
|