{"id":647,"date":"2016-11-09T09:08:10","date_gmt":"2016-11-08T22:08:10","guid":{"rendered":"http:\/\/www.nickdu.com\/?p=647"},"modified":"2016-11-09T09:08:10","modified_gmt":"2016-11-08T22:08:10","slug":"windows-physical-disk-image-writer-in-c","status":"publish","type":"post","link":"https:\/\/nickdu.com\/?p=647","title":{"rendered":"Windows physical disk image writer in C"},"content":{"rendered":"<p>My recent project is to write a raw image file into CFast card, and I was looking for a physical disk writer on <a href=\"http:\/\/www.google.com\" target=\"_blank\">google<\/a>. Finally I found this <a href=\"http:\/\/m0n0.ch\/wall\/physdiskwrite.php\" target=\"_blank\">http:\/\/m0n0.ch\/wall\/physdiskwrite.php<\/a>, but it doesn&#8217;t work properly.<\/p>\n<ol>\n<li>GUI is not Englisht<\/li>\n<li>When image size is too big, it doesn&#8217;t show the correct size.<\/li>\n<\/ol>\n<p>Then I decide to make my own physical disk image writer in C.<\/p>\n<p><span style=\"color: #ff0000;\"><strong>Be extremely careful to use this tool, incorrect disk number can completely corrupt your disk data! I am not responsible for this.<\/strong><\/span><\/p>\n<h2><strong>Download<\/strong><\/h2>\n<p><span style=\"text-decoration: underline;\"><a href=\"http:\/\/www.nickdu.com\/tools\/PhyDiskWrite.zip\">PhyDiskWrite.zip<\/a><\/span> (4k)<\/p>\n<pre lang=\"c\">#include &lt;windows.h&gt;\n\nvoid PrintHelp()\n{\n\u00a0\u00a0\u00a0 printf(\"Usage: phydiskwrite [imagefile]\\r\\n\\r\\n\");\n}\n\nHANDLE OpenDisk(int deviceID)\n{\n\u00a0\u00a0\u00a0 HANDLE hDisk;\n\u00a0\u00a0\u00a0 TCHAR diskName[MAX_PATH];\n\u00a0\u00a0\u00a0 _stprintf_s(diskName, _T(\"\\\\\\\\.\\\\PhysicalDrive%d\"), deviceID);\n\u00a0\u00a0\u00a0 hDisk = CreateFile(diskName, \n        GENERIC_READ | GENERIC_WRITE, \n        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);\n\u00a0\u00a0\u00a0 return hDisk;\n}\n\nint PrintDisks()\n{\n\u00a0\u00a0\u00a0 printf(\"Searching for physical drives...\\r\\n\\r\\n\");\n\u00a0\u00a0\u00a0 DWORD bytes;\n\u00a0\u00a0\u00a0 TCHAR diskName[MAX_PATH];\n\u00a0\u00a0\u00a0 HANDLE hDisk;\n\u00a0\u00a0\u00a0 int selectedDisk = -1;\n\u00a0\u00a0\u00a0 for (int i = 0; i &lt; 255; i++)\n\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 hDisk = OpenDisk(i);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (hDisk == INVALID_HANDLE_VALUE)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 continue;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"Information for Device %d\\r\\n\", i);\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DISK_GEOMETRY pdg = { 0 };\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (!DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &amp;pdg, sizeof(pdg), &amp;bytes, NULL))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"error: Get disk info failed %d\\r\\n\", GetLastError());\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 continue;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ULONGLONG DiskSize = pdg.Cylinders.QuadPart \n            * (ULONG)pdg.TracksPerCylinder \n            * (ULONG)pdg.SectorsPerTrack \n            * (ULONG)pdg.BytesPerSector;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CloseHandle(hDisk);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"\\tByte\/Sec %d, Cylinders: %d, Sector\/Track %d, Track\/Cylinder %d\\r\\n\", \n            pdg.BytesPerSector, pdg.Cylinders, pdg.SectorsPerTrack, pdg.TracksPerCylinder);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"\\tDevice:%d, Media Type:%d Disk Size: %.2f (Gb)\\r\\n\\r\\n\", \n            i, pdg.MediaType, (double)DiskSize \/ (1024.0f * 1024.0f * 1024.0f));\n\u00a0\u00a0\u00a0 }\n\u00a0\u00a0\u00a0 printf(\"Which disk do you want to write?\\r\\n\");\n\u00a0\u00a0\u00a0 printf(\"(Be careful, wrong disk number could corrupt your entire disk!)\\r\\n\");\n\u00a0\u00a0\u00a0 scanf(\"%d\", &amp;selectedDisk);\n\u00a0\u00a0\u00a0 return selectedDisk;\n}\n\nint _tmain(int argc, _TCHAR* argv[])\n{\u00a0 \u00a0\n\u00a0\u00a0\u00a0 if (argc != 2)\n\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PrintHelp();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return 0;\n\u00a0\u00a0\u00a0 }\n\u00a0\u00a0 \u00a0\n\u00a0\u00a0\u00a0 int devID = PrintDisks();\n\u00a0\u00a0\u00a0 if (devID != -1)\n\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 HANDLE hDisk = OpenDisk(devID);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BYTE buffer[65536];\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DWORD byteRead, byteWrite, status;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ULONGLONG totalWrite = 0;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LARGE_INTEGER fileSize;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 HANDLE hImage = CreateFile(argv[1], \n            GENERIC_READ, FILE_SHARE_READ, NULL, \n            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (hImage == INVALID_HANDLE_VALUE)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"error: Open file failed %d\", GetLastError());\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return -1;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 GetFileSizeEx(hImage, &amp;fileSize);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 while (ReadFile(hImage, buffer, 65536, &amp;byteRead, NULL) &amp;&amp; byteRead &gt; 0)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (!WriteFile(hDisk, buffer, byteRead, &amp;byteWrite, NULL))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"error: Write to disk failed %d\", GetLastError());\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 else\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\");\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 totalWrite += byteRead;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"%f%%\", totalWrite * 100.0f \/ fileSize.QuadPart);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CloseHandle(hImage);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CloseHandle(hDisk);\n\u00a0\u00a0\u00a0 }\n\u00a0\u00a0 \u00a0return 0;\n}\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;t work properly. GUI is not Englisht When image size is too big, it doesn&#8217;t show the correct size. Then I decide to make &hellip; <a href=\"https:\/\/nickdu.com\/?p=647\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Windows physical disk image writer in C&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,2],"tags":[],"class_list":["post-647","post","type-post","status-publish","format-standard","hentry","category-cc","category-it"],"_links":{"self":[{"href":"https:\/\/nickdu.com\/index.php?rest_route=\/wp\/v2\/posts\/647","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nickdu.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nickdu.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nickdu.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nickdu.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=647"}],"version-history":[{"count":0,"href":"https:\/\/nickdu.com\/index.php?rest_route=\/wp\/v2\/posts\/647\/revisions"}],"wp:attachment":[{"href":"https:\/\/nickdu.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=647"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nickdu.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=647"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nickdu.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=647"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}