win-pvdrivers

view copyconfig/copyconfig.c @ 759:996f1c7d2cb3

Fixed a bug causing a hang in copyconfig when the buffer size is exceeded or the user has insufficient privileges
author James Harper <james.harper@bendigoit.com.au>
date Tue Jan 12 23:17:20 2010 +1100 (2010-01-12)
parents 3b46c7474a82
children
line source
1 #pragma warning(disable: 4201)
2 #include <basetyps.h>
3 #include <stdlib.h>
4 #include <wtypes.h>
5 #include <initguid.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <winioctl.h>
9 #include <ntddndis.h>
10 #include <strsafe.h>
12 #define ADAPTER_TYPE_XEN
13 #define ADAPTER_TYPE_OTHER
15 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
17 typedef struct adapter_details
18 {
19 struct adapter_details *next;
20 BYTE mac_address[6];
21 CHAR xen_IpConfig_key_name[1024];
22 CHAR other_IpConfig_key_name[1024];
23 } adapter_details_t;
25 int __cdecl
26 main(
27 // __in ULONG argc,
28 // __in_ecount(argc) PCHAR argv[]
29 )
30 {
31 HKEY key_handle;
32 HKEY adapter_key_handle;
33 LONG status;
34 CHAR adapter_key_name[256];
35 BYTE buf[1024];
36 DWORD buf_len;
37 CHAR *keyptr;
38 HANDLE handle;
39 CHAR filename[256];
40 NDIS_STATISTICS_VALUE oid_req;
41 int i;
42 adapter_details_t *list_head = NULL, *prev;
43 adapter_details_t *adapter;
44 CHAR value_name[256];
45 DWORD value_name_len;
46 DWORD value_type;
47 PCHAR value_data;
48 DWORD value_data_len;
49 DWORD value_data_max_len;
50 HKEY src_key_handle;
51 HKEY dst_key_handle;
53 // Enumerate keys in \\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters
54 status = RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters", &key_handle);
55 if (status != ERROR_SUCCESS)
56 {
57 fprintf(stderr, "Cannot read registry - status = %08x\n", status);
58 return 1;
59 }
60 printf("Enumerating adapters\n");
61 buf_len = 39;
62 for (i = 0; (status = RegEnumKeyEx(key_handle, i, adapter_key_name, &buf_len, NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS; buf_len = 39, i++)
63 {
64 if (status == ERROR_MORE_DATA)
65 continue; /* if the key is longer than a GUID then we aren't interested in it anyway */
66 if (status != ERROR_SUCCESS)
67 break;
68 //printf("buf_len = %d, buf = %s\n", buf_len, buf);
69 if (buf_len != 38)
70 continue;
71 /* check that the name looks like a guid */
72 StringCbPrintfA(filename, ARRAY_SIZE(filename), "\\\\.\\%s", adapter_key_name);
73 handle = CreateFile(filename, FILE_GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
74 if (!handle)
75 continue;
76 oid_req.Oid = OID_802_3_PERMANENT_ADDRESS;
77 oid_req.DataLength = 10;
78 status = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid_req, sizeof(NDIS_STATISTICS_VALUE), buf, 256, &buf_len, NULL);
79 if (!status || buf_len != 6)
80 continue;
81 if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 && buf[4] == 0 && buf[5] == 0)
82 continue;
83 printf("Found Adapter:\n MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
84 buf[0], buf[1], buf[2],
85 buf[3], buf[4], buf[5]);
86 for (adapter = list_head, prev = NULL; adapter != NULL; prev = adapter, adapter = adapter->next)
87 {
88 if (memcmp(adapter->mac_address, buf, 6) == 0)
89 break;
90 }
91 if (!adapter)
92 {
93 adapter = malloc(sizeof(adapter_details_t));
94 if (prev == NULL)
95 list_head = adapter;
96 else
97 prev->next = adapter;
98 adapter->next = NULL;
99 memcpy(adapter->mac_address, buf, 6);
100 adapter->xen_IpConfig_key_name[0] = 0;
101 adapter->other_IpConfig_key_name[0] = 0;
102 }
104 oid_req.Oid = OID_GEN_VENDOR_DESCRIPTION;
105 oid_req.DataLength = 256;
106 status = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid_req, sizeof(NDIS_STATISTICS_VALUE), buf, 256, &buf_len, NULL);
107 if (!status)
108 {
109 printf(" Error opening. Ignoring\n");
110 continue;
111 }
112 printf(" Description = %s\n", buf);
113 if (strstr((char *)buf, "Xen"))
114 {
115 printf(" Type = Xen\n");
116 keyptr = adapter->xen_IpConfig_key_name;
117 }
118 else
119 {
120 printf(" Type = Other\n");
121 keyptr = adapter->other_IpConfig_key_name;
122 }
123 if (keyptr[0])
124 {
125 printf(" Multiple Other or multiple Xen adapters exist with the same mac. Ignoring.\n");
126 continue;
127 }
128 buf_len = 1024;
130 status = RegOpenKey(key_handle, adapter_key_name, &adapter_key_handle);
131 if (status != ERROR_SUCCESS)
132 {
133 printf(" Failed to read registry (%08x). Ignoring.\n", status);
134 continue;
135 }
136 status = RegQueryValueEx(adapter_key_handle, "IpConfig", NULL, NULL, (LPBYTE)keyptr, &buf_len);
137 if (status != ERROR_SUCCESS)
138 {
139 printf(" Failed to read registry (%08x). Ignoring.\n", status);
140 continue;
141 }
142 }
144 printf("\nCloning IP Configurations\n");
145 for (adapter = list_head; adapter != NULL; adapter = adapter->next)
146 {
147 printf("Considering MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
148 adapter->mac_address[0], adapter->mac_address[1], adapter->mac_address[2],
149 adapter->mac_address[3], adapter->mac_address[4], adapter->mac_address[5]);
150 if (adapter->xen_IpConfig_key_name[0])
151 printf(" Xen adapter present\n");
152 else
153 printf(" Xen adapter not present\n");
154 if (adapter->other_IpConfig_key_name[0])
155 printf(" Other adapter present\n");
156 else
157 printf(" Other adapter not present\n");
159 if (adapter->xen_IpConfig_key_name[0] && adapter->other_IpConfig_key_name[0])
160 {
161 // open HKLM\SYSTEM\Services\%s
162 StringCbPrintfA((char *)buf, ARRAY_SIZE(buf), "SYSTEM\\CurrentControlSet\\Services\\%s", adapter->xen_IpConfig_key_name);
163 status = RegOpenKey(HKEY_LOCAL_MACHINE, (LPCSTR)buf, &dst_key_handle);
164 if (status != ERROR_SUCCESS)
165 {
166 printf(" Cannot open Xen adapter config key. Skipping.\n");
167 continue;
168 }
169 StringCbPrintfA((char *)buf, ARRAY_SIZE(buf), "SYSTEM\\CurrentControlSet\\Services\\%s", adapter->other_IpConfig_key_name);
170 status = RegOpenKey(HKEY_LOCAL_MACHINE, (LPCSTR)buf, &src_key_handle);
171 if (status != ERROR_SUCCESS)
172 {
173 printf(" Cannot open Other adapter config key. Skipping.\n");
174 continue;
175 }
176 value_name_len = 256;
177 value_data_max_len = 0;
178 value_data = NULL;
179 value_data_len = 0;
180 while ((status = RegEnumValue(dst_key_handle, 0, value_name, &value_name_len, NULL, &value_type, (LPBYTE)value_data, &value_data_len)) != ERROR_NO_MORE_ITEMS)
181 {
182 //printf("A status = %08x, value_data_max_len = %d, value_data_len = %d\n", status, value_data_max_len, value_data_len);
183 if (value_data_len > value_data_max_len || status == ERROR_MORE_DATA)
184 {
185 //printf("A Buffer %d too small. Allocating %d bytes\n", value_data_max_len, value_data_len);
186 if (value_data != NULL)
187 free(value_data);
188 value_data_max_len = value_data_len;
189 value_data = malloc(value_data_max_len);
190 }
191 else if (status != ERROR_SUCCESS)
192 {
193 printf("Failed to read registry %08x\n", status);
194 return 1;
195 }
196 else
197 {
198 RegDeleteValue(dst_key_handle, value_name);
199 }
200 value_name_len = 256;
201 value_data_len = value_data_max_len;
202 }
203 i = 0;
204 value_name_len = 256;
205 value_data_len = value_data_max_len;
206 while ((status = RegEnumValue(src_key_handle, i, value_name, &value_name_len, NULL, &value_type, (LPBYTE)value_data, &value_data_len)) != ERROR_NO_MORE_ITEMS)
207 {
208 //printf("B status = %08x, value_data_max_len = %d, value_data_len = %d\n", status, value_data_max_len, value_data_len);
209 if (value_data_len > value_data_max_len || status == ERROR_MORE_DATA)
210 {
211 //printf("B Buffer %d too small. Allocating %d bytes\n", value_data_max_len, value_data_len);
212 if (value_data != NULL)
213 free(value_data);
214 value_data_max_len = value_data_len;
215 value_data = malloc(value_data_max_len);
216 }
217 else if (status != ERROR_SUCCESS)
218 {
219 printf("Failed to read registry %08x\n", status);
220 return 1;
221 }
222 else
223 {
224 RegSetValueEx(dst_key_handle, value_name, 0, value_type, (BYTE *)value_data, value_data_len);
225 i++;
226 }
227 value_name_len = 256;
228 value_data_len = value_data_max_len;
229 }
230 printf(" Copied\n", buf);
231 }
232 }
233 return 0;
235 // loop through key names that look like GUIDs
236 // get OID_GEN_VENDOR_DESCRIPTION
237 // if description does not contain "RTL8139" then continue to next key name
238 // get OID_802_3_PERMANENT_ADDRESS
239 // get IpConfig path value registry
240 // again loop through key names that look like GUIDs
241 // if description does not contain "xen" then continue to next key name
242 // get IpConfig path value from registry
243 // delete contents of above path
244 // copy contents of RTL8139 IpConfig to Xen IpConfig (use RegCopyTree)
245 }