Leaked source code of windows server 2003
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.

794 lines
30 KiB

  1. // inets.cpp: implementation of the CInetSetup class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "inets.h"
  5. #include <ras.h>
  6. #include <tapi.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <appdefs.h>
  10. #define MAXNAME 200
  11. typedef DWORD (WINAPI *LPFNDLL_RASGETENTRYPROPERTIES)(LPCWSTR, LPCWSTR, LPRASENTRY, LPDWORD, LPBYTE, LPDWORD);
  12. typedef DWORD (WINAPI *LPFNDLL_RASSETENTRYPROPERTIES)(LPCWSTR, LPCWSTR, LPRASENTRY, DWORD , LPBYTE, DWORD );
  13. /////////////////////////////////////////////////////////////////////////
  14. // Registry Values //
  15. /////////////////////////////////////////////////////////////////////////
  16. // For CInetSetup::InetSSetLanConnection
  17. //static const WCHAR cszRegEnumPciKey[] = L"Enum\\PCI";
  18. //static const WCHAR cszRegEnumNetworkTcpKey[] = L"Enum\\Network\\MSTCP";
  19. //static const WCHAR cszRegClassKey[] = L"System\\CurrentControlSet\\Services\\Class";
  20. static const WCHAR cszRegBindings[] = L"Bindings";
  21. //static const WCHAR cszRegEnumDriverKey[] = L"Driver";
  22. static const WCHAR cszRegTcpIp[] = L"MSTCP";
  23. // Global TcpIp Reg Location
  24. static const WCHAR cszRegFixedTcpInfoKey[] = L"System\\CurrentControlSet\\Services\\VxD\\MSTCP";
  25. //
  26. // IP Address
  27. //
  28. static const WCHAR cszRegIPAddress[] = L"IPAddress";
  29. static const WCHAR cszRegIPMask[] = L"IPMask";
  30. //
  31. // WINS
  32. //
  33. static const WCHAR cszRegWINS[] = L"NameServer";
  34. //
  35. // Gateway
  36. //
  37. static const WCHAR cszRegDefaultGateway[] = L"DefaultGateway";
  38. //
  39. // DNS
  40. //
  41. static const WCHAR cszRegDomainName[] = L"Domain";
  42. static const WCHAR cszRegNameServer[] = L"NameServer";
  43. static const WCHAR cszRegHostName[] = L"HostName";
  44. static const WCHAR cszRegEnableDNS[] = L"EnableDNS";
  45. static const WCHAR cszRegSuffixSearchList[] = L"SearchList";
  46. static const WCHAR cszNullIP[] = L"0.0.0.0";
  47. static const WCHAR cszAdapterClass[] = L"Net";
  48. static const WCHAR cszProtocolClass[] = L"NetTrans";
  49. static const WCHAR cszNodeType[] = L"NodeType";
  50. static const WCHAR cszScopeID[] = L"ScopeID";
  51. // Not in use by OOBE, but included in case this becomes
  52. // a seperate module. API does *NOT* work with PPPOA.
  53. DWORD WINAPI InetSSetRasConnection ( RASINFO& RasEntry )
  54. {
  55. DWORD nRetVal = ERROR_SUCCESS;
  56. LPFNDLL_RASSETENTRYPROPERTIES rsep = NULL;
  57. LPFNDLL_RASGETENTRYPROPERTIES rgep = NULL;
  58. LPBYTE lpDeviceBuf = NULL;
  59. DWORD dwDeviceBufSize = 0;
  60. HMODULE hRasApi = LoadLibrary (L"RasApi32.dll");
  61. if (!hRasApi) return GetLastError();
  62. if (!(rsep = (LPFNDLL_RASSETENTRYPROPERTIES) GetProcAddress (hRasApi, "RasSetEntryProperties"))) {
  63. nRetVal = GetLastError();
  64. goto end;
  65. }
  66. if (!(rgep = (LPFNDLL_RASGETENTRYPROPERTIES) GetProcAddress (hRasApi, "RasGetEntryProperties"))) {
  67. nRetVal = GetLastError();
  68. goto end;
  69. }
  70. if ( (nRetVal = RasValidateEntryName ( ((!lstrlen(RasEntry.szPhoneBook)) ? NULL : RasEntry.szPhoneBook), RasEntry.szEntryName )) != ERROR_SUCCESS &&
  71. nRetVal != ERROR_ALREADY_EXISTS ) {
  72. nRetVal = ERROR_INVALID_NAME;
  73. goto end;
  74. }
  75. // we place the RASENTRY structure first. the lpDeviceInfo information is only considered for
  76. // ATM.
  77. if ( (nRetVal = rsep (((!lstrlen(RasEntry.szPhoneBook)) ? NULL : RasEntry.szPhoneBook), RasEntry.szEntryName, &RasEntry.RasEntry, sizeof (RasEntry.RasEntry), NULL, 0)) != ERROR_SUCCESS ) {
  78. goto end;
  79. }
  80. // unless the device is ATM, no further action is necessary.
  81. //if ( lstrcmpi (RasEntry.RasEntry.szDeviceType, RASDT_Atm) )
  82. {
  83. nRetVal = ERROR_SUCCESS;
  84. goto end;
  85. }
  86. if ( RasEntry.dwDeviceInfoSize != sizeof (ATMPBCONFIG) ) {
  87. nRetVal = ERROR_INVALID_PARAMETER;
  88. goto end;
  89. }
  90. if ( (nRetVal = rgep (((!lstrlen(RasEntry.szPhoneBook)) ? NULL : RasEntry.szPhoneBook), RasEntry.szEntryName, &(RasEntry.RasEntry), &(RasEntry.RasEntry.dwSize), NULL, &dwDeviceBufSize)) != ERROR_SUCCESS ) {
  91. goto end;
  92. }
  93. if ( !(lpDeviceBuf = (LPBYTE) malloc (dwDeviceBufSize)) ) {
  94. nRetVal = ERROR_NOT_ENOUGH_MEMORY;
  95. goto end;
  96. }
  97. if ( (nRetVal = rgep (((!lstrlen(RasEntry.szPhoneBook)) ? NULL : RasEntry.szPhoneBook), RasEntry.szEntryName, &(RasEntry.RasEntry), &(RasEntry.RasEntry.dwSize), lpDeviceBuf, &dwDeviceBufSize)) != ERROR_SUCCESS ) {
  98. goto end;
  99. }
  100. // ** BUGBUG: WARNING: THIS IS NOT STABLE CODE: THERE IS NO DOCUMENTATION ON THE CORRECT
  101. // ** -------- USE OF THE RASSETENTRYPROPERTIES FOR THE LPDEVICEINFO BUFFER.
  102. memcpy (lpDeviceBuf+66, &RasEntry.lpDeviceInfo, RasEntry.dwDeviceInfoSize); // HACK!
  103. if ( (nRetVal = rsep (NULL, RasEntry.szEntryName,
  104. &RasEntry.RasEntry, sizeof (RasEntry.RasEntry),
  105. lpDeviceBuf, dwDeviceBufSize)) != ERROR_SUCCESS) {
  106. goto end;
  107. }
  108. end:
  109. free (lpDeviceBuf);
  110. FreeLibrary(hRasApi);
  111. return nRetVal;
  112. }
  113. // this function sets a PPPOE connection. Presently, it merely updates
  114. // the device's registry location with the parameters in the INS file.
  115. // in the future, InetSSetPppoeConnection () will have native support.
  116. DWORD WINAPI InetSSetPppoeConnection ( PPPOEINFO& PppoeInfo )
  117. {
  118. // settings:
  119. // ---------------------------------------------------
  120. // Format: "RegKey=RegVal" e.g. "Pvc1=10"
  121. // LPBYTE lpbNdiBuf = PppoeInfo.PppoeModule.lpbRegNdiParamBuf;
  122. LPWSTR pwchSetBuf = (LPWSTR)PppoeInfo.PppoeModule.lpbRegSettingsBuf;
  123. LPWSTR eq = 0;
  124. DWORD cwchValue = 0;
  125. HKEY hkeyAdapterClass = NULL;
  126. // BUGBUG: error checking is ignored. BUG-BUG
  127. DWORD nRetVal = 0;
  128. if ( (nRetVal = InetSGetAdapterKey ( cszAdapterClass, PppoeInfo.TcpIpInfo.szPnPId, INETS_ADAPTER_HARDWAREID, DIREG_DRV, hkeyAdapterClass )) != ERROR_SUCCESS )
  129. {
  130. return nRetVal;
  131. }
  132. while ( *pwchSetBuf )
  133. {
  134. if ( !(eq = wcschr ( pwchSetBuf, L'=' )) )
  135. {
  136. return ERROR_INVALID_PARAMETER;
  137. }
  138. // we also disallow the following: "Vci="
  139. if ( !(*(eq+1)) )
  140. {
  141. return ERROR_INVALID_PARAMETER;
  142. }
  143. // flush out the '=' so that we have two token strings.
  144. // we simply move each string directly into the registry.
  145. *eq = L'\0';
  146. cwchValue = lstrlen(eq + 1) + 1; // account for trailing 0
  147. if ( RegSetValueEx ( hkeyAdapterClass, pwchSetBuf, 0, REG_SZ, (LPBYTE)(eq + 1), cwchValue * sizeof(WCHAR)) != ERROR_SUCCESS )
  148. {
  149. *eq = L'=';
  150. return E_FAIL;
  151. }
  152. // restore the '=' and move to the next pair "name=value"
  153. *eq = L'=';
  154. pwchSetBuf = eq + 1 + cwchValue; // include '='
  155. }
  156. if ( InetSSetLanConnection ( PppoeInfo.TcpIpInfo ) != ERROR_SUCCESS )
  157. {
  158. return E_FAIL;
  159. }
  160. return ERROR_SUCCESS;
  161. }
  162. DWORD WINAPI InetSSetRfc1483Connection ( RFC1483INFO &Rfc1483Info )
  163. {
  164. // settings:
  165. // ---------------------------------------------------
  166. // Format: "RegKey=RegVal" e.g. "Pvc1=10"
  167. // LPBYTE lpbNdiBuf = Rfc1483Info.Rfc1483Module.lpbRegNdiParamBuf;
  168. // BUGBUG: What does lpbSetBuf contain??
  169. LPBYTE lpbSetBuf = Rfc1483Info.Rfc1483Module.lpbRegSettingsBuf;
  170. WCHAR *eq = 0;
  171. DWORD_PTR dwNameSize = 0;
  172. DWORD dwValueSize = 0;
  173. HKEY hkeyAdapterClass = NULL;
  174. // BUGBUG: error checking is ignored. BUG-BUG
  175. DWORD nRetVal = 0;
  176. if ( (nRetVal = InetSGetAdapterKey ( cszAdapterClass, Rfc1483Info.TcpIpInfo.szPnPId, INETS_ADAPTER_HARDWAREID, DIREG_DRV, hkeyAdapterClass )) != ERROR_SUCCESS )
  177. {
  178. return nRetVal;
  179. }
  180. while ( *lpbSetBuf )
  181. {
  182. if ( !(eq = wcschr ( (WCHAR*)lpbSetBuf, L'=' )) )
  183. {
  184. return ERROR_INVALID_PARAMETER;
  185. }
  186. // we also disallow the following: "Vci="
  187. if ( !(*(eq+1)) )
  188. {
  189. return ERROR_INVALID_PARAMETER;
  190. }
  191. // flush out the '=' so that we have two token strings.
  192. // we simply move each string directly into the registry.
  193. *eq = L'\0';
  194. dwNameSize = eq-(WCHAR*)lpbSetBuf;
  195. dwValueSize = BYTES_REQUIRED_BY_SZ(eq+1);
  196. if ( RegSetValueEx ( hkeyAdapterClass, (WCHAR*)lpbSetBuf, 0, REG_SZ, (LPBYTE)eq+1, dwValueSize+1) != ERROR_SUCCESS )
  197. {
  198. *eq = L'=';
  199. return E_FAIL;
  200. }
  201. // restore the '=' and move to the next pair "name=value"
  202. *eq = L'=';
  203. lpbSetBuf += dwNameSize+dwValueSize+2; // for '=' and '\0'
  204. }
  205. if ( InetSSetLanConnection ( Rfc1483Info.TcpIpInfo ) != ERROR_SUCCESS )
  206. {
  207. return E_FAIL;
  208. }
  209. return ERROR_SUCCESS;
  210. }
  211. // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-* InetSGetAdapterKey -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* //
  212. //
  213. // Description:
  214. // This function returns a Driver Registry Key for a Device.
  215. //
  216. // Arguments:
  217. // cszDeviceClass - Any Device Class, e.g. "Net", "NetTrans", etc.
  218. // cszDeviceParam - Value that we're using to identify the Device.
  219. // dwEnumType - Can be either INETS_ADAPTER_HARDWAREID or
  220. // INETS_ADAPTER_INSTANCEID.
  221. // dwRequiredKeyType - This corresponds to KeyType in SetupDiOpenDevRegKey
  222. // in SetupAPI.
  223. //
  224. // hkeyDevKey - Registry Key Handle provided by the caller.
  225. //
  226. // Return Values:
  227. // ERROR_SUCCESS - Function returns successfully.
  228. // Other - use GetLastError(). Note: hkeyDevKey = INVALID_HANDLE_VALUE in this case.
  229. //
  230. // Remarks:
  231. // Use this function to browse the Device Manager for Network Devices and Protocol Drivers.
  232. //
  233. DWORD WINAPI InetSGetAdapterKey ( LPCWSTR cszDeviceClass, LPCWSTR cszDeviceParam, DWORD dwEnumType, DWORD dwRequiredKeyType, HKEY &hkeyDevKey ) {
  234. // initialization of parameter
  235. hkeyDevKey = (HKEY) INVALID_HANDLE_VALUE;
  236. DWORD nRetVal = ERROR_SUCCESS;
  237. // We find out the network adapter's TCP/IP Binding first.
  238. HINSTANCE hSetupLib = LoadLibrary (L"SetupApi.Dll");
  239. if (!hSetupLib)
  240. {
  241. return GetLastError();
  242. }
  243. // Get procedures we need from the DLL.
  244. LPFNDLL_SETUPDICLASSGUIDSFROMNAME lpfndll_SetupDiClassGuidsFromName = NULL;
  245. LPFNDLL_SETUPDIGETCLASSDEVS lpfndll_SetupDiGetClassDevs = NULL;
  246. LPFNDLL_SETUPDIENUMDEVICEINFO lpfndll_SetupDiEnumDeviceInfo = NULL;
  247. LPFNDLL_SETUPDIGETDEVICEREGISTRYPROPERTY lpfndll_SetupDiGetDeviceRegistryProperty = NULL;
  248. LPFNDLL_SETUPDIOPENDEVREGKEY lpfndll_SetupDiOpenDevRegKey = NULL;
  249. LPFNDLL_SETUPDIGETDEVICEINSTANCEID lpfndll_SetupDiGetDeviceInstanceId = NULL;
  250. if ( !(lpfndll_SetupDiClassGuidsFromName = (LPFNDLL_SETUPDICLASSGUIDSFROMNAME) GetProcAddress ( hSetupLib, cszSetupDiClassGuidsFromName )) )
  251. {
  252. nRetVal = GetLastError();
  253. FreeLibrary ( hSetupLib );
  254. return nRetVal;
  255. }
  256. if ( !(lpfndll_SetupDiGetClassDevs = (LPFNDLL_SETUPDIGETCLASSDEVS) GetProcAddress ( hSetupLib, cszSetupDiGetClassDevs )) )
  257. {
  258. nRetVal = GetLastError();
  259. FreeLibrary ( hSetupLib );
  260. return nRetVal;
  261. }
  262. if ( !(lpfndll_SetupDiEnumDeviceInfo = (LPFNDLL_SETUPDIENUMDEVICEINFO) GetProcAddress ( hSetupLib, "SetupDiEnumDeviceInfo" )) )
  263. {
  264. nRetVal = GetLastError();
  265. FreeLibrary ( hSetupLib );
  266. return nRetVal;
  267. }
  268. if ( !(lpfndll_SetupDiGetDeviceRegistryProperty = (LPFNDLL_SETUPDIGETDEVICEREGISTRYPROPERTY) GetProcAddress ( hSetupLib, cszSetupDiGetDeviceRegistryProperty )) )
  269. {
  270. nRetVal = GetLastError();
  271. FreeLibrary ( hSetupLib );
  272. return nRetVal;
  273. }
  274. if ( !(lpfndll_SetupDiOpenDevRegKey = (LPFNDLL_SETUPDIOPENDEVREGKEY) GetProcAddress ( hSetupLib, "SetupDiOpenDevRegKey" )) )
  275. {
  276. nRetVal = GetLastError();
  277. FreeLibrary ( hSetupLib );
  278. return nRetVal;
  279. }
  280. if ( !(lpfndll_SetupDiGetDeviceInstanceId = (LPFNDLL_SETUPDIGETDEVICEINSTANCEID) GetProcAddress ( hSetupLib, cszSetupDiGetDeviceInstanceId ) ) )
  281. {
  282. nRetVal = GetLastError();
  283. FreeLibrary ( hSetupLib );
  284. return nRetVal;
  285. }
  286. // fantastic. we have the functions. now, on to business.
  287. // Get Class Guid.
  288. BOOLEAN bRet = FALSE;
  289. DWORD dwArraySize = 0;
  290. LPGUID lpguidArray = NULL;
  291. bRet = lpfndll_SetupDiClassGuidsFromName ( cszDeviceClass, NULL, NULL, &dwArraySize );
  292. // We depend on SetupDiClassGuidsFromName() to provide us with the Guid, and we need to
  293. // allocate space to accomodate the Guid. If this cannot be done, we are crippled!
  294. if ( !dwArraySize )
  295. {
  296. FreeLibrary ( hSetupLib );
  297. return ERROR_INVALID_DATA;
  298. }
  299. if ( !(lpguidArray = (LPGUID) malloc (dwArraySize*sizeof(GUID))) )
  300. {
  301. FreeLibrary ( hSetupLib );
  302. return ERROR_NOT_ENOUGH_MEMORY;
  303. }
  304. if ( !(bRet = (lpfndll_SetupDiClassGuidsFromName ( cszDeviceClass, lpguidArray, dwArraySize, &dwArraySize )) ) )
  305. {
  306. FreeLibrary ( hSetupLib );
  307. free ( lpguidArray );
  308. return ERROR_INVALID_FUNCTION;
  309. }
  310. // we retrieve the list of devices.
  311. HDEVINFO hdevNetDeviceList = lpfndll_SetupDiGetClassDevs ( lpguidArray, NULL, NULL, DIGCF_PRESENT );
  312. if ( !hdevNetDeviceList )
  313. {
  314. FreeLibrary ( hSetupLib );
  315. free ( lpguidArray );
  316. return ERROR_INVALID_FUNCTION;
  317. }
  318. free ( lpguidArray ); // where shall we do this garbage collection ?
  319. // we will now enumerate through the list of Net devices.
  320. SP_DEVINFO_DATA DevInfoStruct;
  321. memset ( &DevInfoStruct, 0, sizeof (DevInfoStruct) );
  322. DevInfoStruct.cbSize = sizeof (DevInfoStruct);
  323. int i = 0;
  324. LPBYTE lpbHardwareIdBuf = NULL;
  325. DWORD dwHardwareIdBufSize = 0;
  326. DWORD dwRequiredSize = 0;
  327. BOOL bFound = FALSE;
  328. const DWORD cdwIncrement = 500; // BUGBUG: What's magic about 500??
  329. if ( !(lpbHardwareIdBuf = (LPBYTE) malloc (500)) )
  330. {
  331. FreeLibrary ( hSetupLib );
  332. return ERROR_NOT_ENOUGH_MEMORY;
  333. }
  334. dwHardwareIdBufSize = 500;
  335. while ( bRet = ( lpfndll_SetupDiEnumDeviceInfo (hdevNetDeviceList, i, &DevInfoStruct )) )
  336. {
  337. // for each Net device, we will compare its hardware ID to the one
  338. // provided in the parameter.
  339. switch ( dwEnumType )
  340. {
  341. case INETS_ADAPTER_HARDWAREID:
  342. while ( !(bRet = lpfndll_SetupDiGetDeviceRegistryProperty ( hdevNetDeviceList, &DevInfoStruct, SPDRP_HARDWAREID, NULL, lpbHardwareIdBuf, dwHardwareIdBufSize, &dwRequiredSize )) && ((nRetVal = GetLastError()) == ERROR_INSUFFICIENT_BUFFER ))
  343. { // we need to reallocate the buffer size.
  344. if ( !dwRequiredSize ) dwHardwareIdBufSize += cdwIncrement;
  345. else dwHardwareIdBufSize += dwRequiredSize;
  346. LPBYTE lpbHardwareIdBufTemp = (LPBYTE) realloc ( (void*) lpbHardwareIdBuf, dwHardwareIdBufSize );
  347. if ( lpbHardwareIdBufTemp )
  348. {
  349. lpbHardwareIdBuf = lpbHardwareIdBufTemp;
  350. }
  351. else
  352. {
  353. // not enough memory!
  354. free (lpbHardwareIdBuf);
  355. FreeLibrary ( hSetupLib );
  356. return ERROR_NOT_ENOUGH_MEMORY;
  357. }
  358. }
  359. break;
  360. case INETS_ADAPTER_INSTANCEID:
  361. while ( !(bRet = lpfndll_SetupDiGetDeviceInstanceId ( hdevNetDeviceList, &DevInfoStruct, (PCWSTR) lpbHardwareIdBuf, dwHardwareIdBufSize, &dwRequiredSize )) && ((nRetVal = GetLastError()) == ERROR_INSUFFICIENT_BUFFER ))
  362. {
  363. // we need to reallocate the buffer size.
  364. if ( !dwRequiredSize ) dwHardwareIdBufSize += cdwIncrement;
  365. else dwHardwareIdBufSize += dwRequiredSize;
  366. LPBYTE lpbHardwareIdBufTemp = (LPBYTE) realloc ( (void*) lpbHardwareIdBuf, dwHardwareIdBufSize );
  367. if ( lpbHardwareIdBufTemp )
  368. {
  369. lpbHardwareIdBuf = lpbHardwareIdBufTemp;
  370. }
  371. else
  372. {
  373. // not enough memory!
  374. free (lpbHardwareIdBuf);
  375. FreeLibrary ( hSetupLib );
  376. return ERROR_NOT_ENOUGH_MEMORY;
  377. }
  378. }
  379. break;
  380. default:
  381. free (lpbHardwareIdBuf);
  382. FreeLibrary ( hSetupLib );
  383. return ERROR_INVALID_PARAMETER;
  384. }
  385. if ( bRet )
  386. {
  387. // we should have the hardware ID, at this stage. we compare it with
  388. // the device's plug-and-play ID.
  389. // BUGBUG: Is lpbHardwareIdBuf ANSI or Unicode?
  390. if ( wcsstr( (const WCHAR *)lpbHardwareIdBuf, cszDeviceParam) )
  391. {
  392. // found!
  393. bFound = TRUE;
  394. // we get the device's registry key.
  395. if ( (hkeyDevKey = lpfndll_SetupDiOpenDevRegKey ( hdevNetDeviceList, &DevInfoStruct, DICS_FLAG_GLOBAL, 0, dwRequiredKeyType, KEY_ALL_ACCESS )) == INVALID_HANDLE_VALUE )
  396. {
  397. free (lpbHardwareIdBuf);
  398. FreeLibrary ( hSetupLib );
  399. return ERROR_BADKEY;
  400. }
  401. free (lpbHardwareIdBuf);
  402. FreeLibrary ( hSetupLib );
  403. return ERROR_SUCCESS;
  404. }
  405. }
  406. i++;
  407. }
  408. // the while loop enumerated unsuccessfully.
  409. free (lpbHardwareIdBuf);
  410. FreeLibrary ( hSetupLib );
  411. return ERROR_NOT_FOUND;
  412. }
  413. DWORD WINAPI InetSSetLanConnection ( LANINFO& LANINFO )
  414. {
  415. HKEY hkeyAdapter = NULL;
  416. DWORD nRetVal = 0;
  417. HKEY hkeyGlobalTcp = NULL;
  418. LPBYTE lpbBufPtr = NULL;
  419. DWORD dwValueBufSize = 0;
  420. WCHAR *Token = NULL, *PlaceHolder = NULL;
  421. WCHAR *WINSListPtr = NULL;
  422. // TCP/IP InstanceID ==> Class Key
  423. HKEY hkeyClassTcp = NULL;
  424. HKEY hkeyAdapterBinding = NULL;
  425. __try
  426. {
  427. // PnPId ==> Device Configuration Key
  428. if ( (nRetVal = InetSGetAdapterKey ( cszAdapterClass, LANINFO.szPnPId, INETS_ADAPTER_HARDWAREID, DIREG_DEV, hkeyAdapter)) != ERROR_SUCCESS )
  429. {
  430. __leave;
  431. }
  432. // Open the Bindings subkey to look for TCP/IP Binding.
  433. if ( RegOpenKeyEx ( hkeyAdapter, cszRegBindings, 0, KEY_ALL_ACCESS, &hkeyAdapterBinding ) != ERROR_SUCCESS )
  434. {
  435. nRetVal = GetLastError();
  436. __leave;
  437. }
  438. // Find the TCP/IP binding.
  439. WCHAR szBindingValueName [GEN_MAX_STRING_LENGTH];
  440. DWORD dwBindingValueNameSize = sizeof (szBindingValueName) / sizeof(WCHAR);
  441. int index = 0;
  442. while ( RegEnumValue ( hkeyAdapterBinding, index, szBindingValueName, &dwBindingValueNameSize, 0, 0, 0, 0 ) == ERROR_SUCCESS )
  443. {
  444. if ( !wcsncmp ( szBindingValueName, cszRegTcpIp, sizeof (cszRegTcpIp)-1 ) )
  445. {
  446. // we found a binding!
  447. break;
  448. }
  449. index++;
  450. }
  451. if ( (nRetVal = InetSGetAdapterKey ( cszProtocolClass, szBindingValueName, INETS_ADAPTER_INSTANCEID, DIREG_DRV, hkeyClassTcp )) != ERROR_SUCCESS )
  452. {
  453. nRetVal = GetLastError();
  454. __leave;
  455. }
  456. // Got it. we will now start the update.
  457. //
  458. // IP Address
  459. //
  460. lpbBufPtr = 0;
  461. dwValueBufSize = 0;
  462. if ( LANINFO.TcpIpInfo.EnableIP )
  463. {
  464. lpbBufPtr = (LPBYTE) LANINFO.TcpIpInfo.szIPAddress;
  465. dwValueBufSize = BYTES_REQUIRED_BY_SZ(LANINFO.TcpIpInfo.szIPAddress);
  466. if (RegSetValueEx ( hkeyClassTcp, cszRegIPAddress, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  467. {
  468. // close handles also!
  469. nRetVal = E_FAIL;
  470. __leave;
  471. }
  472. lpbBufPtr = (LPBYTE) LANINFO.TcpIpInfo.szIPMask;
  473. dwValueBufSize = BYTES_REQUIRED_BY_SZ(LANINFO.TcpIpInfo.szIPMask);
  474. if (RegSetValueEx ( hkeyClassTcp, cszRegIPMask, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  475. {
  476. // close handles also!
  477. nRetVal = E_FAIL;
  478. __leave;
  479. }
  480. }
  481. else
  482. {
  483. lpbBufPtr = (LPBYTE) cszNullIP;
  484. dwValueBufSize = BYTES_REQUIRED_BY_SZ(cszNullIP);
  485. if (RegSetValueEx ( hkeyClassTcp, cszRegIPAddress, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  486. {
  487. // close handles also!
  488. nRetVal = E_FAIL;
  489. __leave;
  490. }
  491. if (RegSetValueEx ( hkeyClassTcp, cszRegIPMask, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  492. {
  493. // close handles also!
  494. nRetVal = E_FAIL;
  495. __leave;
  496. }
  497. }
  498. //
  499. // WINS
  500. //
  501. lpbBufPtr = 0;
  502. dwValueBufSize = 0;
  503. index = 1;
  504. WCHAR szWINSEntry [GEN_MAX_STRING_LENGTH];
  505. WCHAR szWINSListCopy [GEN_MAX_STRING_LENGTH];
  506. WINSListPtr = szWINSListCopy;
  507. // BUGBUG: Is LANINFO.TcpIpInfo.szWINSList ANSI or Unicode?
  508. lstrcpy (WINSListPtr, LANINFO.TcpIpInfo.szWINSList);
  509. wsprintf (szWINSEntry, L"%s%d", cszRegWINS, index);
  510. PlaceHolder = szWINSEntry+lstrlen(cszRegWINS);
  511. if ( LANINFO.TcpIpInfo.EnableWINS )
  512. {
  513. while ( Token = wcstok ((index > 1) ? NULL : WINSListPtr, L", " )) { // WARNING. wcstok uses static data! Also the whitespace in ", " is necessary!
  514. if (!Token)
  515. {
  516. nRetVal = E_FAIL;
  517. __leave;
  518. }
  519. lpbBufPtr = (LPBYTE) Token;
  520. dwValueBufSize = BYTES_REQUIRED_BY_SZ(Token);
  521. if (RegSetValueEx ( hkeyClassTcp, szWINSEntry, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  522. {
  523. // close handles also!
  524. nRetVal = E_FAIL;
  525. __leave;
  526. }
  527. wsprintf (PlaceHolder, L"%d", ++index);
  528. }
  529. if (RegSetValueEx ( hkeyClassTcp, cszNodeType, 0, REG_SZ, (LPBYTE) L"8", sizeof (L"8") ) != ERROR_SUCCESS)
  530. {
  531. nRetVal = E_FAIL;
  532. __leave;
  533. }
  534. }
  535. else
  536. {
  537. // TODO: Remove all instances of NameServerX <== IMPORTANT
  538. index = 0;
  539. WCHAR szEnumValueBuffer[GEN_MAX_STRING_LENGTH];
  540. DWORD dwEnumValueBufferSize;
  541. while ( RegEnumValue ( hkeyClassTcp, index, szEnumValueBuffer, &(dwEnumValueBufferSize=sizeof(szEnumValueBuffer)/sizeof(WCHAR)), 0, 0, 0, 0 ) != ERROR_NO_MORE_ITEMS )
  542. {
  543. if ( !wcsncmp (szEnumValueBuffer, cszRegWINS, sizeof (cszRegWINS)-1) )
  544. {
  545. if ( RegDeleteValue ( hkeyClassTcp, szEnumValueBuffer ) != ERROR_SUCCESS )
  546. {
  547. nRetVal = E_FAIL;
  548. __leave;
  549. }
  550. continue;
  551. }
  552. index++;
  553. }
  554. if (RegSetValueEx ( hkeyClassTcp, cszNodeType, 0, REG_SZ, (LPBYTE) L"1", sizeof (L"1") ) != ERROR_SUCCESS)
  555. {
  556. nRetVal = E_FAIL;
  557. __leave;
  558. }
  559. }
  560. //
  561. // Default Gateway
  562. //
  563. lpbBufPtr = (LPBYTE) LANINFO.TcpIpInfo.szDefaultGatewayList;
  564. dwValueBufSize = BYTES_REQUIRED_BY_SZ (LANINFO.TcpIpInfo.szDefaultGatewayList);
  565. if (RegSetValueEx ( hkeyClassTcp, cszRegDefaultGateway, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  566. {
  567. // close handles also!
  568. nRetVal = E_FAIL;
  569. __leave;
  570. }
  571. // Step 4: Update global TCPIP entries (DNS)
  572. if ( RegOpenKeyEx ( HKEY_LOCAL_MACHINE, cszRegFixedTcpInfoKey, 0, KEY_ALL_ACCESS, &hkeyGlobalTcp) != ERROR_SUCCESS )
  573. {
  574. // close keys
  575. nRetVal = E_FAIL;
  576. __leave;
  577. }
  578. if ( LANINFO.TcpIpInfo.EnableDNS )
  579. {
  580. lpbBufPtr = (LPBYTE) LANINFO.TcpIpInfo.szHostName;
  581. dwValueBufSize = BYTES_REQUIRED_BY_SZ (LANINFO.TcpIpInfo.szHostName);
  582. if (RegSetValueEx ( hkeyGlobalTcp, cszRegHostName, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  583. {
  584. // close handles also!
  585. nRetVal = E_FAIL;
  586. __leave;
  587. }
  588. lpbBufPtr = (LPBYTE) LANINFO.TcpIpInfo.szDomainName;
  589. dwValueBufSize = BYTES_REQUIRED_BY_SZ (LANINFO.TcpIpInfo.szDomainName);
  590. if (RegSetValueEx ( hkeyGlobalTcp, cszRegDomainName, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  591. {
  592. // close handles also!
  593. nRetVal = E_FAIL;
  594. __leave;
  595. }
  596. lpbBufPtr = (LPBYTE) LANINFO.TcpIpInfo.szDNSList;
  597. dwValueBufSize = BYTES_REQUIRED_BY_SZ (LANINFO.TcpIpInfo.szDNSList);
  598. if (RegSetValueEx ( hkeyGlobalTcp, cszRegNameServer, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  599. {
  600. // close handles also!
  601. nRetVal = E_FAIL;
  602. __leave;
  603. }
  604. lpbBufPtr = (LPBYTE) LANINFO.TcpIpInfo.szSuffixSearchList;
  605. dwValueBufSize = BYTES_REQUIRED_BY_SZ (LANINFO.TcpIpInfo.szSuffixSearchList);
  606. if (RegSetValueEx ( hkeyGlobalTcp, cszRegSuffixSearchList, 0, REG_SZ, lpbBufPtr, dwValueBufSize) != ERROR_SUCCESS)
  607. {
  608. // close handles also!
  609. nRetVal = E_FAIL;
  610. __leave;
  611. }
  612. if (RegSetValueEx ( hkeyGlobalTcp, cszRegEnableDNS, 0, REG_SZ, (LPBYTE)L"1", sizeof(L"1")) != ERROR_SUCCESS)
  613. {
  614. // close handles also!
  615. nRetVal = E_FAIL;
  616. __leave;
  617. }
  618. }
  619. else
  620. {
  621. if (RegSetValueEx ( hkeyGlobalTcp, cszRegEnableDNS, 0, REG_SZ, (LPBYTE)L"0", sizeof(L"0")) != ERROR_SUCCESS)
  622. {
  623. // close handles also!
  624. nRetVal = E_FAIL;
  625. __leave;
  626. }
  627. }
  628. WCHAR szScopeID[GEN_MAX_STRING_LENGTH];
  629. if ( LANINFO.TcpIpInfo.EnableWINS )
  630. {
  631. if (LANINFO.TcpIpInfo.uiScopeID == (UINT)~0x0) // this line implies that no ScopeID is given.
  632. {
  633. if ( RegSetValueEx ( hkeyGlobalTcp, cszScopeID, 0, REG_SZ, (LPBYTE)L"", sizeof(L"") ) )
  634. {
  635. nRetVal = E_FAIL;
  636. __leave;
  637. }
  638. }
  639. else if (RegSetValueEx(hkeyGlobalTcp,
  640. cszScopeID,
  641. 0,
  642. REG_SZ,
  643. (LPBYTE)_itow( LANINFO.TcpIpInfo.uiScopeID, szScopeID, 10 ),
  644. BYTES_REQUIRED_BY_SZ(szScopeID)
  645. ) != ERROR_SUCCESS )
  646. {
  647. nRetVal = E_FAIL;
  648. __leave;
  649. }
  650. }
  651. else
  652. {
  653. if ( RegDeleteValue ( hkeyGlobalTcp, cszScopeID ) != ERROR_SUCCESS )
  654. {
  655. nRetVal = E_FAIL;
  656. __leave;
  657. }
  658. }
  659. }
  660. // end.
  661. __finally
  662. {
  663. if ( hkeyAdapter )
  664. {
  665. RegCloseKey ( hkeyAdapter );
  666. }
  667. if ( hkeyGlobalTcp )
  668. {
  669. RegCloseKey ( hkeyGlobalTcp );
  670. }
  671. if ( hkeyAdapterBinding )
  672. {
  673. RegCloseKey ( hkeyAdapterBinding );
  674. }
  675. if ( hkeyClassTcp )
  676. {
  677. RegCloseKey ( hkeyClassTcp );
  678. }
  679. }
  680. return nRetVal;
  681. }
  682. /*
  683. int main() {
  684. CInetSetup inetSetup;
  685. const WCHAR cszINS[] = L"C:\\test.ins";
  686. LANINFO LanInfo;
  687. RASINFO RasInfo;
  688. memset ( &RasInfo, 0, sizeof(RASINFO) );
  689. memset ( &LanInfo, 0, sizeof(LANINFO) );
  690. RasInfo.dwDeviceInfoSize = sizeof(ATMPBCONFIG);
  691. RasInfo.lpDeviceInfo = (LPBYTE) malloc (sizeof (ATMPBCONFIG));
  692. RasInfo.RasEntry.dwSize = sizeof (RASENTRY);
  693. RasInfo.RasEntry.dwfNetProtocols = RASNP_Ip;
  694. RasInfo.RasEntry.dwFramingProtocol = RASFP_Ppp;
  695. lstrcpy ( RasInfo.RasEntry.szDeviceType, RASDT_Modem );
  696. lstrcpy ( RasInfo.RasEntry.szDeviceName, L"Standard 56000 bps V90 Modem" );
  697. lstrcpy ( RasInfo.RasEntry.szLocalPhoneNumber, L"5551212" );
  698. lstrcpy ( RasInfo.szEntryName, L"Test1" );
  699. lstrcpy ( RasInfo.szPhoneBook, L"" );
  700. inetSetup.InetSImportLanConnection ( LanInfo, cszINS );
  701. inetSetup.InetSSetLanConnection ( LanInfo );
  702. inetSetup.InetSSetRasConnection ( RasInfo );
  703. free ( RasInfo.lpDeviceInfo );
  704. return 0;
  705. }
  706. */