My recent project is to write a raw image file into CFast card, and I was looking for a physical disk writer on google. Finally I found this http://m0n0.ch/wall/physdiskwrite.php, but it doesn’t work properly.
- GUI is not Englisht
- When image size is too big, it doesn’t show the correct size.
Then I decide to make my own physical disk image writer in C.
Be extremely careful to use this tool, incorrect disk number can completely corrupt your disk data! I am not responsible for this.
Download
PhyDiskWrite.zip (4k)
#include <windows.h>
void PrintHelp()
{
printf("Usage: phydiskwrite [imagefile]\r\n\r\n");
}
HANDLE OpenDisk(int deviceID)
{
HANDLE hDisk;
TCHAR diskName[MAX_PATH];
_stprintf_s(diskName, _T("\\\\.\\PhysicalDrive%d"), deviceID);
hDisk = CreateFile(diskName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
return hDisk;
}
int PrintDisks()
{
printf("Searching for physical drives...\r\n\r\n");
DWORD bytes;
TCHAR diskName[MAX_PATH];
HANDLE hDisk;
int selectedDisk = -1;
for (int i = 0; i < 255; i++)
{
hDisk = OpenDisk(i);
if (hDisk == INVALID_HANDLE_VALUE)
continue;
printf("Information for Device %d\r\n", i);
DISK_GEOMETRY pdg = { 0 };
if (!DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &pdg, sizeof(pdg), &bytes, NULL))
{
printf("error: Get disk info failed %d\r\n", GetLastError());
continue;
}
ULONGLONG DiskSize = pdg.Cylinders.QuadPart
* (ULONG)pdg.TracksPerCylinder
* (ULONG)pdg.SectorsPerTrack
* (ULONG)pdg.BytesPerSector;
CloseHandle(hDisk);
printf("\tByte/Sec %d, Cylinders: %d, Sector/Track %d, Track/Cylinder %d\r\n",
pdg.BytesPerSector, pdg.Cylinders, pdg.SectorsPerTrack, pdg.TracksPerCylinder);
printf("\tDevice:%d, Media Type:%d Disk Size: %.2f (Gb)\r\n\r\n",
i, pdg.MediaType, (double)DiskSize / (1024.0f * 1024.0f * 1024.0f));
}
printf("Which disk do you want to write?\r\n");
printf("(Be careful, wrong disk number could corrupt your entire disk!)\r\n");
scanf("%d", &selectedDisk);
return selectedDisk;
}
int _tmain(int argc, _TCHAR* argv[])
{
if (argc != 2)
{
PrintHelp();
return 0;
}
int devID = PrintDisks();
if (devID != -1)
{
HANDLE hDisk = OpenDisk(devID);
BYTE buffer[65536];
DWORD byteRead, byteWrite, status;
ULONGLONG totalWrite = 0;
LARGE_INTEGER fileSize;
HANDLE hImage = CreateFile(argv[1],
GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hImage == INVALID_HANDLE_VALUE)
{
printf("error: Open file failed %d", GetLastError());
return -1;
}
GetFileSizeEx(hImage, &fileSize);
while (ReadFile(hImage, buffer, 65536, &byteRead, NULL) && byteRead > 0)
{
if (!WriteFile(hDisk, buffer, byteRead, &byteWrite, NULL))
{
printf("error: Write to disk failed %d", GetLastError());
break;
}
else
{
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
totalWrite += byteRead;
printf("%f%%", totalWrite * 100.0f / fileSize.QuadPart);
}
}
CloseHandle(hImage);
CloseHandle(hDisk);
}
return 0;
}