diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2012-12-11 22:35:41 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2012-12-11 22:35:41 +0000 |
commit | 3887b55c642cd602831f21720b62dca8ca6c5bcc (patch) | |
tree | 5a6b158acd5b36e3e3a2a90e0e4e72e9d954304a /src/vpn | |
parent | 57f1e799be9be1ef6aa5c52eb1c9f72cc1c5d59a (diff) | |
download | gnunet-3887b55c642cd602831f21720b62dca8ca6c5bcc.tar.gz gnunet-3887b55c642cd602831f21720b62dca8ca6c5bcc.zip |
grml, friendlyName is not friendly, because it does not help us for
finding anything. Switched over to backup plan:
* lookup the devices's name directly in registry via the PNPInterfaceID. Registry fun, yey!
* added a few fixes here and there
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/gnunet-helper-vpn-windows.c | 166 |
1 files changed, 147 insertions, 19 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c index 8d9d3e08d..03da4ed60 100644 --- a/src/vpn/gnunet-helper-vpn-windows.c +++ b/src/vpn/gnunet-helper-vpn-windows.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <tchar.h> | 35 | #include <tchar.h> |
36 | #include <windows.h> | 36 | #include <windows.h> |
37 | #include <setupapi.h> | 37 | #include <setupapi.h> |
38 | #include <ddk/cfgmgr32.h> | ||
38 | #include "platform.h" | 39 | #include "platform.h" |
39 | 40 | ||
40 | /** | 41 | /** |
@@ -70,6 +71,12 @@ | |||
70 | */ | 71 | */ |
71 | #define HARDWARE_ID _T("TAP0901") | 72 | #define HARDWARE_ID _T("TAP0901") |
72 | 73 | ||
74 | /** | ||
75 | * Location of the network interface list resides in registry. | ||
76 | * TODO: is this fixed on all version of windows? Checked with XP and 7 | ||
77 | */ | ||
78 | #define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" | ||
79 | |||
73 | /* | 80 | /* |
74 | * Our local process' PID. Used for creating a sufficiently unique additional | 81 | * Our local process' PID. Used for creating a sufficiently unique additional |
75 | * hardware ID for our device. | 82 | * hardware ID for our device. |
@@ -77,10 +84,11 @@ | |||
77 | static TCHAR secondary_hwid[LINE_LEN / 2]; | 84 | static TCHAR secondary_hwid[LINE_LEN / 2]; |
78 | 85 | ||
79 | /* | 86 | /* |
80 | * Device's Friendly Name, used to identify a network device in netsh. | 87 | * Device's visible Name, used to identify a network device in netsh. |
81 | * eg: "TAP-Windows Adapter V9 #4" | 88 | * eg: "Local Area Connection 9" |
82 | */ | 89 | */ |
83 | static TCHAR device_friendly_name[LINE_LEN / 2]; | 90 | static TCHAR device_visible_name[256]; |
91 | |||
84 | /** | 92 | /** |
85 | * This is our own local instance of a virtual network interface | 93 | * This is our own local instance of a virtual network interface |
86 | * It is (somewhat) equivalent to using tun/tap in unixoid systems | 94 | * It is (somewhat) equivalent to using tun/tap in unixoid systems |
@@ -212,6 +220,7 @@ setup_interface () | |||
212 | */ | 220 | */ |
213 | TCHAR inf_file_path[MAX_PATH]; | 221 | TCHAR inf_file_path[MAX_PATH]; |
214 | TCHAR hwidlist[LINE_LEN + 4]; | 222 | TCHAR hwidlist[LINE_LEN + 4]; |
223 | |||
215 | int str_lenth = 0; | 224 | int str_lenth = 0; |
216 | 225 | ||
217 | 226 | ||
@@ -222,16 +231,15 @@ setup_interface () | |||
222 | * TODO: Currently we just use TAP0901 as HWID, | 231 | * TODO: Currently we just use TAP0901 as HWID, |
223 | * but we might want to add additional information | 232 | * but we might want to add additional information |
224 | */ | 233 | */ |
225 | strncpy (hwidlist, HARDWARE_ID, LINE_LEN); | 234 | _tcsncpy (hwidlist, HARDWARE_ID, LINE_LEN); |
226 | /** | 235 | /** |
227 | * this is kind of over-complicated, but allows keeps things independent of | 236 | * this is kind of over-complicated, but allows keeps things independent of |
228 | * how the openvpn-hwid is actually stored. | 237 | * how the openvpn-hwid is actually stored. |
229 | * | 238 | * |
230 | * A HWID list is double-\0 terminated and \0 separated | 239 | * A HWID list is double-\0 terminated and \0 separated |
231 | */ | 240 | */ |
232 | str_lenth = strlen (hwidlist) + 1 ; | 241 | str_lenth = _tcslen (hwidlist) + 1 ; |
233 | hwidlist[str_lenth] = _T("\0"); | 242 | _tcsncpy (&hwidlist[str_lenth], secondary_hwid, LINE_LEN - str_lenth); |
234 | strncpy (&hwidlist[str_lenth], secondary_hwid, LINE_LEN - str_lenth); | ||
235 | 243 | ||
236 | /** | 244 | /** |
237 | * Locate the inf-file, we need to store it somewhere where the system can | 245 | * Locate the inf-file, we need to store it somewhere where the system can |
@@ -283,18 +291,6 @@ setup_interface () | |||
283 | &DeviceNode)) | 291 | &DeviceNode)) |
284 | return FALSE; | 292 | return FALSE; |
285 | 293 | ||
286 | /* Now, pull the device device's FriendlyName off the registry. */ | ||
287 | if ( !SetupDiGetDeviceRegistryProperty(DeviceInfo, | ||
288 | (PSP_DEVINFO_DATA) & DeviceNode, | ||
289 | SPDRP_FRIENDLYNAME, | ||
290 | NULL, | ||
291 | (LPBYTE)device_friendly_name, | ||
292 | LINE_LEN / 2, | ||
293 | NULL) || strlen(device_friendly_name) < 1){ | ||
294 | return FALSE; | ||
295 | } | ||
296 | device_friendly_name[LINE_LEN / 2 - 1] = _T("\0"); | ||
297 | |||
298 | return TRUE; | 294 | return TRUE; |
299 | } | 295 | } |
300 | 296 | ||
@@ -340,6 +336,133 @@ remove_interface () | |||
340 | } | 336 | } |
341 | 337 | ||
342 | /** | 338 | /** |
339 | * Do all the lookup necessary to retrieve the inteface's actual name | ||
340 | * off the registry. | ||
341 | * | ||
342 | * @return: TRUE if we were able to lookup the interface's name, else FALSE | ||
343 | */ | ||
344 | static boolean | ||
345 | resolve_interface_name () | ||
346 | { | ||
347 | |||
348 | SP_DEVINFO_LIST_DETAIL_DATA device_details; | ||
349 | TCHAR pnp_instance_id [MAX_DEVICE_ID_LEN]; | ||
350 | HKEY adapter_key_handle; | ||
351 | LONG status; | ||
352 | DWORD len; | ||
353 | int i = 0; | ||
354 | boolean retval=FALSE; | ||
355 | TCHAR adapter[] = _T (INTERFACE_REGISTRY_LOCATION); | ||
356 | |||
357 | /* We can obtain the PNP instance ID from our setupapi handle */ | ||
358 | device_details.cbSize = sizeof (device_details); | ||
359 | if (CR_SUCCESS != CM_Get_Device_ID_Ex (DeviceNode.DevInst, | ||
360 | (PWSTR) pnp_instance_id, | ||
361 | MAX_DEVICE_ID_LEN, | ||
362 | 0, //must be 0 | ||
363 | NULL)) //hMachine, we are local | ||
364 | return FALSE; | ||
365 | |||
366 | /* Now we can use this ID to locate the correct networks interface in registry */ | ||
367 | if (ERROR_SUCCESS != RegOpenKeyEx ( | ||
368 | HKEY_LOCAL_MACHINE, | ||
369 | adapter, | ||
370 | 0, | ||
371 | KEY_READ, | ||
372 | &adapter_key_handle)) | ||
373 | return FALSE; | ||
374 | |||
375 | /* Of course there is a multitude of entries here, with arbitrary names, | ||
376 | * thus we need to iterate through there. | ||
377 | */ | ||
378 | while (FALSE == retval) | ||
379 | { | ||
380 | TCHAR instance_key[256]; | ||
381 | TCHAR query_key [256]; | ||
382 | HKEY instance_key_handle; | ||
383 | TCHAR pnpinstanceid_name[] = _T("PnpInstanceID"); | ||
384 | TCHAR pnpinstanceid_value[256]; | ||
385 | TCHAR adaptername_name[] = _T("Name"); | ||
386 | DWORD data_type; | ||
387 | |||
388 | len = sizeof (adapter_key_handle); | ||
389 | /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */ | ||
390 | status = RegEnumKeyEx ( | ||
391 | adapter_key_handle, | ||
392 | i, | ||
393 | instance_key, | ||
394 | &len, | ||
395 | NULL, | ||
396 | NULL, | ||
397 | NULL, | ||
398 | NULL); | ||
399 | |||
400 | /* this may fail due to one of two reasons: | ||
401 | * we are at the end of the list*/ | ||
402 | if (ERROR_NO_MORE_ITEMS == status) | ||
403 | break; | ||
404 | // * we found a broken registry key, continue with the next key. | ||
405 | if (ERROR_SUCCESS != status) | ||
406 | goto cleanup; | ||
407 | |||
408 | /* prepare our new querty string: */ | ||
409 | _sntprintf (query_key, 256, _T ("%s\\%s\\Connection"), | ||
410 | _T (INTERFACE_REGISTRY_LOCATION), | ||
411 | instance_key); | ||
412 | |||
413 | /* look inside instance_key\\Connection */ | ||
414 | status = RegOpenKeyEx ( | ||
415 | HKEY_LOCAL_MACHINE, | ||
416 | query_key, | ||
417 | 0, | ||
418 | KEY_READ, | ||
419 | &instance_key_handle); | ||
420 | |||
421 | if (status != ERROR_SUCCESS) | ||
422 | continue; | ||
423 | |||
424 | /* now, read our PnpInstanceID */ | ||
425 | len = sizeof (pnpinstanceid_value); | ||
426 | status = RegQueryValueEx (instance_key_handle, | ||
427 | pnpinstanceid_name, | ||
428 | NULL, //reserved, always NULL according to MSDN | ||
429 | &data_type, | ||
430 | (LPBYTE) pnpinstanceid_value, | ||
431 | &len); | ||
432 | |||
433 | if (status != ERROR_SUCCESS || data_type != REG_SZ) | ||
434 | goto cleanup; | ||
435 | |||
436 | /* compare the value we got to our devices PNPInstanceID*/ | ||
437 | if ( 0 != _tcsncmp (pnpinstanceid_value, pnp_instance_id, | ||
438 | sizeof (pnpinstanceid_value)/sizeof(TCHAR))) | ||
439 | goto cleanup; | ||
440 | |||
441 | len = sizeof (device_visible_name); | ||
442 | status = RegQueryValueEx ( | ||
443 | instance_key_handle, | ||
444 | adaptername_name, | ||
445 | NULL, //reserved, always NULL according to MSDN | ||
446 | &data_type, | ||
447 | (LPBYTE) device_visible_name, | ||
448 | &len); | ||
449 | |||
450 | if (status == ERROR_SUCCESS && data_type == REG_SZ) | ||
451 | { | ||
452 | retval = TRUE; | ||
453 | } | ||
454 | cleanup: | ||
455 | RegCloseKey (instance_key_handle); | ||
456 | |||
457 | ++i; | ||
458 | } | ||
459 | |||
460 | RegCloseKey (adapter_key_handle); | ||
461 | |||
462 | return retval; | ||
463 | } | ||
464 | |||
465 | /** | ||
343 | * Creates a tun-interface called dev; | 466 | * Creates a tun-interface called dev; |
344 | * | 467 | * |
345 | * @param hwid is asumed to point to a TCHAR[LINE_LEN] | 468 | * @param hwid is asumed to point to a TCHAR[LINE_LEN] |
@@ -362,6 +485,11 @@ init_tun (TCHAR *hwid) | |||
362 | return -1; | 485 | return -1; |
363 | } | 486 | } |
364 | 487 | ||
488 | if (! resolve_interface_name()){ | ||
489 | errno = ENODEV; | ||
490 | return -1; | ||
491 | } | ||
492 | |||
365 | 493 | ||
366 | return fd; | 494 | return fd; |
367 | } | 495 | } |