win-pvdrivers

view copyconfig/copyconfig.c @ 424:37ed25854efa

Added 'copyconfig' utility to copy rtl8139 ip configuration to xen driver
author James Harper <james.harper@bendigoit.com.au>
date Thu Sep 04 22:26:18 2008 +1000 (2008-09-04)
parents
children 599061042271
line source
1 #include <basetyps.h>
2 #include <stdlib.h>
3 #include <wtypes.h>
4 #include <initguid.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <winioctl.h>
8 #include <ntddndis.h>
10 /*
11 1. Get an adapter id. You can get it from registry,
12 \\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters
13 - they are specified in this key.
15 2. For each adapter id you have to open it using ZwCreateFile to obtain it's
16 handle to make ioctl's on,
18 status = ZwOpenFile(&adapter, GENERIC_READ|GENERIC_WRITE, &oa, &ioStatus,
19 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE);
21 Don't forget to prepend \\??\\ at the begning of the adapter id string.
23 3. Once you obtained valid apadter handle, you can query
24 OID_802_3_PERMANENT_ADDRESS:
26 args = OID_802_3_PERMANENT_ADDRESS;
27 status = ZwDeviceIoControlFile(adapter, 0, 0, 0, &ioStatus,
28 IOCTL_NDIS_QUERY_GLOBAL_STATS, &args, sizeof(ULONG), controlbuff,
29 sizeofcontrolbuf);
31 Make sure, that you can obtain adapter mac address while the device is up.
32 If it is down - imagine wi-fi apadter on notebook when it is switched off -
33 you're out of luck.
34 */
36 #define ADAPTER_TYPE_XEN
37 #define ADAPTER_TYPE_OTHER
39 typedef struct adapter_details
40 {
41 struct adapter_details *next;
42 BYTE mac_address[6];
43 CHAR xen_IpConfig_key_name[1024];
44 CHAR other_IpConfig_key_name[1024];
45 } adapter_details_t;
47 int __cdecl
48 main(
49 // __in ULONG argc,
50 // __in_ecount(argc) PCHAR argv[]
51 )
52 {
53 HKEY key_handle;
54 HKEY adapter_key_handle;
55 LONG status;
56 CHAR adapter_key_name[256];
57 BYTE buf[1024];
58 DWORD buf_len;
59 CHAR *keyptr;
60 HANDLE handle;
61 CHAR filename[256];
62 NDIS_STATISTICS_VALUE oid_req;
63 int i;
64 adapter_details_t *list_head = NULL, *prev;
65 adapter_details_t *adapter;
66 CHAR value_name[256];
67 DWORD value_name_len;
68 DWORD value_type;
69 CHAR value_data[1024];
70 DWORD value_data_len;
71 HKEY src_key_handle;
72 HKEY dst_key_handle;
74 // Enumerate keys in \\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters
75 status = RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters", &key_handle);
76 if (status != ERROR_SUCCESS)
77 {
78 fprintf(stderr, "Cannot read registry - status = %08x\n", status);
79 return 1;
80 }
81 printf("Enumerating adapters\n");
82 buf_len = 39;
83 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++)
84 {
85 if (status == ERROR_MORE_DATA)
86 continue; /* if the key is longer than a GUID then we aren't interested in it anyway */
87 if (status != ERROR_SUCCESS)
88 break;
89 //printf("buf_len = %d, buf = %s\n", buf_len, buf);
90 if (buf_len != 38)
91 continue;
92 /* check that the name looks like a guid */
93 sprintf(filename, "\\\\.\\%s", adapter_key_name);
94 handle = CreateFile(filename, FILE_GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
95 if (!handle)
96 continue;
97 oid_req.Oid = OID_802_3_PERMANENT_ADDRESS;
98 oid_req.DataLength = 10;
99 status = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid_req, sizeof(NDIS_STATISTICS_VALUE), buf, 256, &buf_len, NULL);
100 if (!status || buf_len != 6)
101 continue;
102 if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0 && buf[4] == 0 && buf[5] == 0)
103 continue;
104 printf("Found Adapter:\n MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
105 buf[0], buf[1], buf[2],
106 buf[3], buf[4], buf[5]);
107 for (adapter = list_head, prev = NULL; adapter != NULL; prev = adapter, adapter = adapter->next)
108 {
109 if (memcmp(adapter->mac_address, buf, 6) == 0)
110 break;
111 }
112 if (!adapter)
113 {
114 adapter = malloc(sizeof(adapter_details_t));
115 if (prev == NULL)
116 list_head = adapter;
117 else
118 prev->next = adapter;
119 adapter->next = NULL;
120 memcpy(adapter->mac_address, buf, 6);
121 adapter->xen_IpConfig_key_name[0] = 0;
122 adapter->other_IpConfig_key_name[0] = 0;
123 }
125 oid_req.Oid = OID_GEN_VENDOR_DESCRIPTION;
126 oid_req.DataLength = 256;
127 status = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid_req, sizeof(NDIS_STATISTICS_VALUE), buf, 256, &buf_len, NULL);
128 if (!status)
129 {
130 printf(" Error opening. Ignoring\n");
131 continue;
132 }
133 printf(" Description = %s\n", buf);
134 if (strstr(buf, "Xen"))
135 {
136 printf(" Type = Xen\n");
137 keyptr = adapter->xen_IpConfig_key_name;
138 }
139 else
140 {
141 printf(" Type = Other\n");
142 keyptr = adapter->other_IpConfig_key_name;
143 }
144 if (keyptr[0])
145 {
146 printf(" Multiple Other or multiple Xen adapters exist with the same mac. Ignoring.\n");
147 continue;
148 }
149 buf_len = 1024;
151 status = RegOpenKey(key_handle, adapter_key_name, &adapter_key_handle);
152 if (status != ERROR_SUCCESS)
153 {
154 printf(" Failed to read registry (%08x). Ignoring.\n", status);
155 continue;
156 }
157 status = RegQueryValueEx(adapter_key_handle, "IpConfig", NULL, NULL, keyptr, &buf_len);
158 if (status != ERROR_SUCCESS)
159 {
160 printf(" Failed to read registry (%08x). Ignoring.\n", status);
161 continue;
162 }
163 }
165 printf("\nCloning IP Configurations\n");
166 for (adapter = list_head; adapter != NULL; adapter = adapter->next)
167 {
168 printf("Considering MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
169 adapter->mac_address[0], adapter->mac_address[1], adapter->mac_address[2],
170 adapter->mac_address[3], adapter->mac_address[4], adapter->mac_address[5]);
171 if (adapter->xen_IpConfig_key_name[0])
172 printf(" Xen adapter present\n");
173 else
174 printf(" Xen adapter not present\n");
175 if (adapter->other_IpConfig_key_name[0])
176 printf(" Other adapter present\n");
177 else
178 printf(" Other adapter not present\n");
180 if (adapter->xen_IpConfig_key_name[0] && adapter->other_IpConfig_key_name[0])
181 {
182 // open HKLM\SYSTEM\Services\%s
183 sprintf(buf, "SYSTEM\\CurrentControlSet\\Services\\%s", adapter->xen_IpConfig_key_name);
184 status = RegOpenKey(HKEY_LOCAL_MACHINE, buf, &dst_key_handle);
185 if (status != ERROR_SUCCESS)
186 {
187 printf(" Cannot open Xen adapter config key. Skipping.\n");
188 continue;
189 }
190 sprintf(buf, "SYSTEM\\CurrentControlSet\\Services\\%s", adapter->other_IpConfig_key_name);
191 status = RegOpenKey(HKEY_LOCAL_MACHINE, buf, &src_key_handle);
192 if (status != ERROR_SUCCESS)
193 {
194 printf(" Cannot open Other adapter config key. Skipping.\n");
195 continue;
196 }
197 value_name_len = 256;
198 value_data_len = 1024;
199 while ((status = RegEnumValue(dst_key_handle, 0, value_name, &value_name_len, NULL, &value_type, value_data, &value_data_len)) != ERROR_NO_MORE_ITEMS)
200 {
201 RegDeleteValue(dst_key_handle, value_name);
202 value_name_len = 256;
203 value_data_len = 1024;
204 }
205 i = 0;
206 value_name_len = 256;
207 value_data_len = 1024;
208 while ((status = RegEnumValue(src_key_handle, i, value_name, &value_name_len, NULL, &value_type, value_data, &value_data_len)) != ERROR_NO_MORE_ITEMS)
209 {
210 RegSetValueEx(dst_key_handle, value_name, 0, value_type, value_data, value_data_len);
211 value_name_len = 256;
212 value_data_len = 1024;
213 i++;
214 }
215 printf(" Copied\n", buf);
216 }
217 }
219 // loop through key names that look like GUIDs
220 // get OID_GEN_VENDOR_DESCRIPTION
221 // if description does not contain "RTL8139" then continue to next key name
222 // get OID_802_3_PERMANENT_ADDRESS
223 // get IpConfig path value registry
224 // again loop through key names that look like GUIDs
225 // if description does not contain "xen" then continue to next key name
226 // get IpConfig path value from registry
227 // delete contents of above path
228 // copy contents of RTL8139 IpConfig to Xen IpConfig (use RegCopyTree)
229 }