Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

465 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000
  5. //
  6. // File: N E T I P. C P P
  7. //
  8. // Contents: Routines supporting RAS interoperability
  9. //
  10. // Notes:
  11. //
  12. // Author: billi 07 03 2001
  13. //
  14. // History:
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <windows.h>
  18. #include <devguid.h>
  19. #include <objbase.h>
  20. #include <setupapi.h>
  21. #include <stdio.h>
  22. #include "netconn.h"
  23. #include "nconnwrap.h"
  24. #include "debug.h"
  25. #include "NetIp.h"
  26. #include "w9xdhcp.h"
  27. #include "netip.h"
  28. #include "util.h"
  29. #include "registry.h"
  30. #include "theapp.h"
  31. //#define INITGUID
  32. //#include <guiddef.h>
  33. //DEFINE_GUID( GUID_DEVCLASS_NET, 0x4d36e972L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
  34. #define CM_DRP_DRIVER (0x0000000A) // Driver REG_SZ property (RW)
  35. #undef NETADAPTER
  36. // Prototype for iphlpapi routine. For some reason, this isn't defined
  37. // in any header.
  38. #ifdef __cplusplus
  39. extern "C" {
  40. #endif
  41. typedef DWORD (APIENTRY *LPFNSETADAPTERIPADDRESS)(
  42. LPSTR AdapterName,
  43. BOOL EnableDHCP,
  44. ULONG IPAddress,
  45. ULONG SubnetMask,
  46. ULONG DefaultGateway
  47. );
  48. #ifdef __cplusplus
  49. }
  50. #endif
  51. HRESULT HrInternalGetAdapterInfo(
  52. PIP_ADAPTER_INFO* ppAdapter
  53. )
  54. //+---------------------------------------------------------------------------
  55. //
  56. // Function: HrInternalGetAdapterInfo
  57. //
  58. // Purpose:
  59. //
  60. // Arguments: PIP_ADAPTER_INFO* ppAdapter
  61. //
  62. // Returns: HRESULT
  63. //
  64. // Author: billi 12/02/01
  65. //
  66. // Notes:
  67. //
  68. {
  69. HRESULT hr;
  70. PIP_ADAPTER_INFO paAdapterInfo = NULL;
  71. ASSERT( ppAdapter );
  72. if ( NULL == ppAdapter )
  73. {
  74. ppAdapter = &paAdapterInfo;
  75. hr = E_POINTER;
  76. }
  77. else
  78. {
  79. ULONG uLen = 1024;
  80. *ppAdapter = NULL;
  81. hr = E_FAIL;
  82. for ( int i=0; i<2; i++ )
  83. {
  84. PIP_ADAPTER_INFO pInfo = (PIP_ADAPTER_INFO)new BYTE[ uLen ];
  85. ZeroMemory( pInfo, uLen );
  86. if ( NULL != pInfo )
  87. {
  88. DWORD dwErr = GetAdaptersInfo( pInfo, &uLen );
  89. if ( ERROR_SUCCESS == dwErr )
  90. {
  91. hr = S_OK;
  92. *ppAdapter = pInfo;
  93. break;
  94. }
  95. delete [] (BYTE *)pInfo;
  96. }
  97. else
  98. {
  99. hr = E_OUTOFMEMORY;
  100. break;
  101. }
  102. }
  103. }
  104. return hr;
  105. }
  106. /*
  107. HRESULT HrOpenDevRegKey(
  108. const GUID* lpGuid,
  109. DWORD Node,
  110. DWORD Scope,
  111. DWORD HwProfile,
  112. DWORD KeyType,
  113. REGSAM samDesired,
  114. HKEY* phKey
  115. )
  116. //+---------------------------------------------------------------------------
  117. //
  118. // Function: Hr
  119. //
  120. // Purpose:
  121. //
  122. // Arguments:
  123. //
  124. // Returns: HRESULT
  125. //
  126. // Author: billi 12/02/01
  127. //
  128. // Notes:
  129. //
  130. {
  131. HRESULT hr = E_INVALIDARG;
  132. ASSERT( lpGuid );
  133. if ( lpGuid )
  134. {
  135. hr = E_POINTER;
  136. ASSERT( phKey );
  137. if ( phKey )
  138. {
  139. // The only way to open a specific device is to get the list of Class "Net" devices
  140. // and search the list for one with a matching devnode
  141. HDEVINFO hDevInfo;
  142. *phKey = (HKEY)INVALID_HANDLE_VALUE;
  143. hr = E_FAIL;
  144. hDevInfo = SetupDiGetClassDevs( lpGuid, NULL, NULL, DIGCF_DEVICEINTERFACE );
  145. if ( INVALID_HANDLE_VALUE != hDevInfo )
  146. {
  147. SP_DEVINFO_DATA SpData;
  148. DWORD i = 0;
  149. // Here we walk the list of devices and try to match the devnode handles
  150. ZeroMemory( &SpData, sizeof(SP_DEVINFO_DATA) );
  151. SpData.cbSize = sizeof(SP_DEVINFO_DATA);
  152. while ( SetupDiEnumDeviceInfo( hDevInfo, i, &SpData ) )
  153. {
  154. if ( Node == SpData.DevInst )
  155. {
  156. // Got it!
  157. HKEY hKey =
  158. SetupDiOpenDevRegKey( hDevInfo, &SpData, Scope, HwProfile, KeyType, samDesired );
  159. if ( INVALID_HANDLE_VALUE != hKey )
  160. {
  161. *phKey = hKey;
  162. hr = S_OK;
  163. }
  164. }
  165. i++;
  166. ZeroMemory( &SpData, sizeof(SP_DEVINFO_DATA) );
  167. SpData.cbSize = sizeof(SP_DEVINFO_DATA);
  168. }
  169. SetupDiDestroyDeviceInfoList( hDevInfo );
  170. }
  171. }
  172. }
  173. return hr;
  174. }
  175. */
  176. #ifdef __cplusplus
  177. extern "C" {
  178. #endif
  179. char*
  180. HostAddrToIpPsz(
  181. DWORD dwAddress
  182. )
  183. // Converts IP Address from host by order to string
  184. {
  185. char *pszNewStr = new char[16];
  186. if ( pszNewStr )
  187. {
  188. sprintf( pszNewStr,
  189. "%u.%u.%u.%u",
  190. (dwAddress&0xff),
  191. ((dwAddress>>8)&0x0ff),
  192. ((dwAddress>>16)&0x0ff),
  193. ((dwAddress>>24)&0x0ff) );
  194. }
  195. return pszNewStr;
  196. }
  197. BOOLEAN WINAPI IsAdapterDisconnected(
  198. VOID *pContext
  199. )
  200. //+---------------------------------------------------------------------------
  201. //
  202. // Function: IsAdapterDisconnected
  203. //
  204. // Purpose:
  205. //
  206. // Arguments: const NETADAPTER* pNA
  207. //
  208. // Returns: HRESULT
  209. //
  210. // Author: billi 11/04/01
  211. //
  212. // Notes:
  213. //
  214. {
  215. const NETADAPTER* pAdapter = (const NETADAPTER*)pContext;
  216. BOOLEAN bDisconnected = FALSE;
  217. ASSERT( pAdapter );
  218. if ( NULL != pAdapter )
  219. {
  220. HRESULT hr;
  221. PIP_ADAPTER_INFO pInfo;
  222. hr = HrInternalGetAdapterInfo( &pInfo );
  223. if ( SUCCEEDED(hr) )
  224. {
  225. char* pszName;
  226. hr = HrWideCharToMultiByte( pAdapter->szDisplayName, &pszName );
  227. if ( SUCCEEDED(hr) )
  228. {
  229. PIP_ADAPTER_INFO pAdapter = pInfo;
  230. while ( pAdapter )
  231. {
  232. if ( ( strcmp( pAdapter->AdapterName, pszName ) == 0 ) ||
  233. ( strcmp( pAdapter->Description, pszName ) == 0 ) )
  234. {
  235. // If a single matching card returns TRUE then we return TRUE
  236. bDisconnected = bDisconnected || IsMediaDisconnected( pAdapter->Index );
  237. }
  238. pAdapter = pAdapter->Next;
  239. } // while ( pAdapter )
  240. delete [] pszName;
  241. } // if ( SUCCEEDED(hr) )
  242. delete pInfo;
  243. } // if ( SUCCEEDED(hr) )
  244. } // if ( NULL != pNA )
  245. return bDisconnected;
  246. }
  247. HRESULT HrSetAdapterIpAddress(
  248. const NETADAPTER* pNA,
  249. ULONG IPAddress,
  250. ULONG SubnetMask
  251. )
  252. //+---------------------------------------------------------------------------
  253. //
  254. // Function: HrSetAdapterIpAddress
  255. //
  256. // Purpose:
  257. //
  258. // Arguments:
  259. // const NETADAPTER* pNA,
  260. // BOOL EnableDHCP,
  261. // ULONG IPAddress,
  262. // ULONG SubnetMask,
  263. //
  264. // Returns: S_OK on success, otherwise an error code
  265. //
  266. // Notes:
  267. //
  268. {
  269. HRESULT hr = E_INVALIDARG;
  270. ASSERT( pNA );
  271. if ( pNA )
  272. {
  273. TCHAR* pszAddress = HostAddrToIpPsz( IPAddress );
  274. TCHAR* pszSubnet = HostAddrToIpPsz( SubnetMask );
  275. hr = E_OUTOFMEMORY;
  276. if ( pszAddress && pszSubnet )
  277. {
  278. HINSTANCE hLibInstance = NULL;
  279. DWORD dnParent = pNA->devnode;
  280. DWORD dnChild;
  281. DWORD cRet = GetChildDevice( &dnChild, dnParent, &hLibInstance, 0 );
  282. do
  283. {
  284. TCHAR* Buffer = NULL;
  285. ULONG Length = 0L;
  286. if ( STATUS_SUCCESS == cRet )
  287. cRet = GetDeviceIdA( dnChild, &Buffer, &Length, 0);
  288. if ( (STATUS_SUCCESS == cRet) && Buffer && Length && (strstr( Buffer, SZ_PROTOCOL_TCPIPA ) != NULL) )
  289. {
  290. char pszSubkey[ MAX_PATH ];
  291. Length = MAX_PATH;
  292. cRet = GetDevNodeRegistryPropertyA( dnChild, CM_DRP_DRIVER, NULL, pszSubkey, &Length, 0);
  293. if ( STATUS_SUCCESS == cRet )
  294. {
  295. CRegistry reg;
  296. char pszDriverKey[ MAX_PATH ];
  297. lstrcpy( pszDriverKey, "System\\CurrentControlSet\\Services\\Class\\" );
  298. lstrcat( pszDriverKey, pszSubkey );
  299. if ( reg.OpenKey( HKEY_LOCAL_MACHINE, pszDriverKey, KEY_ALL_ACCESS) )
  300. {
  301. if ( reg.SetStringValue( "IPAddress", pszAddress ) &&
  302. reg.SetStringValue( "IPMask", pszSubnet ) )
  303. {
  304. hr = S_OK;
  305. }
  306. reg.CloseKey();
  307. }
  308. } // if ( STATUS_SUCCESS == cRet )
  309. } // if ( Buffer && Length && (strcmp( Buffer, SZ_PROTOCOL_TCPIPA ) == 0) )
  310. if ( Buffer )
  311. delete [] Buffer;
  312. dnParent = dnChild;
  313. cRet = GetSiblingDevice( &dnChild, dnParent, hLibInstance, 0 );
  314. }
  315. while ( STATUS_SUCCESS == cRet );
  316. if ( hLibInstance )
  317. {
  318. FreeLibrary( hLibInstance );
  319. }
  320. } // if ( pszAddress && pszSubnet )
  321. if ( pszAddress )
  322. delete [] pszAddress;
  323. if ( pszSubnet )
  324. delete [] pszSubnet;
  325. } // if ( pNA )
  326. return hr;
  327. }
  328. HRESULT HrEnableDhcp( VOID* pContext, DWORD dwFlags )
  329. //+---------------------------------------------------------------------------
  330. //
  331. // Function: HrEnableDhcpIfLAN
  332. //
  333. // Purpose:
  334. //
  335. // Arguments: NETADAPTER* pNA
  336. // DWORD dwFlags
  337. //
  338. // Returns: HRESULT
  339. //
  340. // Author: billi 29/04/01
  341. //
  342. // Notes:
  343. //
  344. {
  345. HRESULT hr = E_INVALIDARG;
  346. const NETADAPTER* pNA = (const NETADAPTER*)pContext;
  347. ASSERT( pNA );
  348. if ( NULL != pNA )
  349. {
  350. hr = HrSetAdapterIpAddress( pNA, 0, 0 );
  351. if ( SUCCEEDED(hr) )
  352. {
  353. hr = RestartNetAdapter( pNA->devnode );
  354. }
  355. } // if ( NULL != pNA )
  356. return hr;
  357. }
  358. #ifdef __cplusplus
  359. }
  360. #endif