win-pvdrivers

annotate copyconfig/copyconfig.c @ 1086:3d4d85c41fc6

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