rawdisk code added
[instimg] / src / rawdisk.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <windows.h>
5 #include <setupapi.h>
6 #include <devguid.h>
7 #include <winioctl.h>
8 #include "rawdisk.h"
9
10 static GUID guid_iface_disk = {0x53f56307, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}};
11
12 int rawdisk_detect(struct rawdisk_device *disks, int max_disks)
13 {
14         int devidx, ifidx, count;
15         HDEVINFO devset;
16         SP_DEVINFO_DATA devdata;
17         SP_DEVICE_INTERFACE_DATA devif;
18         SP_DEVICE_INTERFACE_DETAIL_DATA_A *devdetail;
19         DWORD size, regtype;
20         char devname[1024];
21
22         if((devset = SetupDiGetClassDevs(&guid_iface_disk, 0, 0,
23                         DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) == INVALID_HANDLE_VALUE) {
24                 fprintf(stderr, "failed to enumerate devices\n");
25                 return -1;
26         }
27
28         count = 0;
29         devidx = 0;
30         for(;;) {
31                 memset(&devdata, 0, sizeof devdata);
32                 devdata.cbSize = sizeof devdata;
33                 if(!SetupDiEnumDeviceInfo(devset, devidx, &devdata)) {
34                         if(GetLastError() == ERROR_NO_MORE_ITEMS) break;
35                         devidx++;
36                         continue;
37                 }
38
39                 regtype = SPDRP_PHYSICAL_DEVICE_OBJECT_NAME;
40                 SetupDiGetDeviceRegistryProperty(devset, &devdata, SPDRP_FRIENDLYNAME,
41                                 &regtype, (unsigned char*)devname, sizeof devname, &size);
42
43                 count = 0;
44                 ifidx = 0;
45                 for(;;) {
46                         memset(&devif, 0, sizeof devif);
47                         devif.cbSize = sizeof devif;
48                         if(!SetupDiEnumDeviceInterfaces(devset, &devdata, &guid_iface_disk, ifidx, &devif)) {
49                                 if(GetLastError() == ERROR_NO_MORE_ITEMS) break;
50                                 ifidx++;
51                                 continue;
52                         }
53
54                         SetupDiGetDeviceInterfaceDetail(devset, &devif, 0, 0, &size, 0);
55                         if(!(devdetail = malloc(size))) {
56                                 fprintf(stderr, "failed to allocate device interface detail buffer (size: %lu)\n", (unsigned long)size);
57                                 return -1;
58                         }
59                         devdetail->cbSize = sizeof *devdetail;
60                         SetupDiGetDeviceInterfaceDetail(devset, &devif, devdetail, size, 0, 0);
61
62
63                         if(count < max_disks) {
64                                 disks[count].path = strdup(devdetail->DevicePath);
65                                 disks[count].name = strdup(devname);
66                                 if(!disks[count].path || !disks[count].name) {
67                                         fprintf(stderr, "failed to allocate device strings\n");
68                                         return -1;
69                                 }
70                                 count++;
71                         }
72
73                         free(devdetail);
74                         ifidx++;
75                 }
76
77                 devidx++;
78         }
79
80         return count;
81 }