rawdisk code added
[instimg] / src / rawdisk.c
diff --git a/src/rawdisk.c b/src/rawdisk.c
new file mode 100644 (file)
index 0000000..b2576ba
--- /dev/null
@@ -0,0 +1,81 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+#include <setupapi.h>
+#include <devguid.h>
+#include <winioctl.h>
+#include "rawdisk.h"
+
+static GUID guid_iface_disk = {0x53f56307, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}};
+
+int rawdisk_detect(struct rawdisk_device *disks, int max_disks)
+{
+       int devidx, ifidx, count;
+       HDEVINFO devset;
+       SP_DEVINFO_DATA devdata;
+       SP_DEVICE_INTERFACE_DATA devif;
+       SP_DEVICE_INTERFACE_DETAIL_DATA_A *devdetail;
+       DWORD size, regtype;
+       char devname[1024];
+
+       if((devset = SetupDiGetClassDevs(&guid_iface_disk, 0, 0,
+                       DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) == INVALID_HANDLE_VALUE) {
+               fprintf(stderr, "failed to enumerate devices\n");
+               return -1;
+       }
+
+       count = 0;
+       devidx = 0;
+       for(;;) {
+               memset(&devdata, 0, sizeof devdata);
+               devdata.cbSize = sizeof devdata;
+               if(!SetupDiEnumDeviceInfo(devset, devidx, &devdata)) {
+                       if(GetLastError() == ERROR_NO_MORE_ITEMS) break;
+                       devidx++;
+                       continue;
+               }
+
+               regtype = SPDRP_PHYSICAL_DEVICE_OBJECT_NAME;
+               SetupDiGetDeviceRegistryProperty(devset, &devdata, SPDRP_FRIENDLYNAME,
+                               &regtype, (unsigned char*)devname, sizeof devname, &size);
+
+               count = 0;
+               ifidx = 0;
+               for(;;) {
+                       memset(&devif, 0, sizeof devif);
+                       devif.cbSize = sizeof devif;
+                       if(!SetupDiEnumDeviceInterfaces(devset, &devdata, &guid_iface_disk, ifidx, &devif)) {
+                               if(GetLastError() == ERROR_NO_MORE_ITEMS) break;
+                               ifidx++;
+                               continue;
+                       }
+
+                       SetupDiGetDeviceInterfaceDetail(devset, &devif, 0, 0, &size, 0);
+                       if(!(devdetail = malloc(size))) {
+                               fprintf(stderr, "failed to allocate device interface detail buffer (size: %lu)\n", (unsigned long)size);
+                               return -1;
+                       }
+                       devdetail->cbSize = sizeof *devdetail;
+                       SetupDiGetDeviceInterfaceDetail(devset, &devif, devdetail, size, 0, 0);
+
+
+                       if(count < max_disks) {
+                               disks[count].path = strdup(devdetail->DevicePath);
+                               disks[count].name = strdup(devname);
+                               if(!disks[count].path || !disks[count].name) {
+                                       fprintf(stderr, "failed to allocate device strings\n");
+                                       return -1;
+                               }
+                               count++;
+                       }
+
+                       free(devdetail);
+                       ifidx++;
+               }
+
+               devidx++;
+       }
+
+       return count;
+}