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.

2490 lines
66 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1995 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: registry.c
  7. //
  8. // Description: This module contains the code for DIM parameters
  9. // initialization and loading from the registry.
  10. //
  11. // History: May 11,1995 NarenG Created original version.
  12. //
  13. #include "dimsvcp.h"
  14. #define DIM_KEYPATH_ROUTER_PARMS TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\Parameters")
  15. #define DIM_KEYPATH_ROUTERMANAGERS TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\RouterManagers")
  16. #define DIM_KEYPATH_INTERFACES TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\Interfaces")
  17. #define DIM_KEYPATH_DDM TEXT("System\\CurrentControlSet\\Services\\RemoteAccess\\DemandDialManager")
  18. #define DIM_VALNAME_GLOBALINFO TEXT("GlobalInfo")
  19. #define DIM_VALNAME_GLOBALINTERFACE TEXT("GlobalInterfaceInfo")
  20. #define DIM_VALNAME_ROUTERROLE TEXT("RouterType")
  21. #define DIM_VALNAME_LOGGINGLEVEL TEXT("LoggingFlags")
  22. #define DIM_VALNAME_DLLPATH TEXT("DLLPath")
  23. #define DIM_VALNAME_TYPE TEXT("Type")
  24. #define DIM_VALNAME_PROTOCOLID TEXT("ProtocolId")
  25. #define DIM_VALNAME_INTERFACE TEXT("InterfaceInfo")
  26. #define DIM_VALNAME_INTERFACE_NAME TEXT("InterfaceName")
  27. #define DIM_VALNAME_ENABLED TEXT("Enabled")
  28. #define DIM_VALNAME_DIALOUT_HOURS TEXT("DialOutHours")
  29. #define DIM_VALNAME_MIN_UNREACHABILITY_INTERVAL \
  30. TEXT("MinUnreachabilityInterval")
  31. #define DIM_VALNAME_MAX_UNREACHABILITY_INTERVAL \
  32. TEXT("MaxUnreachabilityInterval")
  33. static DWORD gbldwInterfaceType;
  34. static DWORD gbldwProtocolId;
  35. static BOOL gblfEnabled;
  36. static BOOL gblInterfaceReachableAfterSecondsMin;
  37. static BOOL gblInterfaceReachableAfterSecondsMax;
  38. typedef struct _DIM_REGISTRY_PARAMS
  39. {
  40. LPWSTR lpwsValueName;
  41. DWORD * pValue;
  42. DWORD dwDefValue;
  43. DWORD dwMinValue;
  44. DWORD dwMaxValue;
  45. } DIM_REGISTRY_PARAMS, *PDIM_REGISTRY_PARAMS;
  46. //
  47. // DIM parameter descriptor table
  48. //
  49. DIM_REGISTRY_PARAMS DIMRegParams[] =
  50. {
  51. DIM_VALNAME_ROUTERROLE,
  52. &(gblDIMConfigInfo.dwRouterRole),
  53. ROUTER_ROLE_RAS | ROUTER_ROLE_LAN | ROUTER_ROLE_WAN,
  54. 0,
  55. ROUTER_ROLE_RAS | ROUTER_ROLE_LAN | ROUTER_ROLE_WAN,
  56. DIM_VALNAME_LOGGINGLEVEL,
  57. &(gblDIMConfigInfo.dwLoggingLevel),
  58. DEF_LOGGINGLEVEL,
  59. MIN_LOGGINGLEVEL,
  60. MAX_LOGGINGLEVEL,
  61. NULL, NULL, 0, 0, 0
  62. };
  63. //
  64. // Interface parameters descriptor table
  65. //
  66. typedef struct _IF_REGISTRY_PARAMS
  67. {
  68. LPWSTR lpwsValueName;
  69. DWORD * pValue;
  70. DWORD dwDefValue;
  71. DWORD dwMinValue;
  72. DWORD dwMaxValue;
  73. } IF_REGISTRY_PARAMS, *PIF_REGISTRY_PARAMS;
  74. IF_REGISTRY_PARAMS IFRegParams[] =
  75. {
  76. DIM_VALNAME_TYPE,
  77. &gbldwInterfaceType,
  78. 0,
  79. 1,
  80. 6,
  81. DIM_VALNAME_ENABLED,
  82. &gblfEnabled,
  83. 1,
  84. 0,
  85. 1,
  86. DIM_VALNAME_MIN_UNREACHABILITY_INTERVAL,
  87. &gblInterfaceReachableAfterSecondsMin,
  88. 300, // 5 minutes
  89. 0,
  90. 0xFFFFFFFF,
  91. DIM_VALNAME_MAX_UNREACHABILITY_INTERVAL,
  92. &gblInterfaceReachableAfterSecondsMax,
  93. 21600, // 6 hours
  94. 0,
  95. 0xFFFFFFFF,
  96. NULL, NULL, 0, 0, 0
  97. };
  98. //
  99. // Router Manager Globals descriptor table
  100. //
  101. typedef struct _GLOBALRM_REGISTRY_PARAMS
  102. {
  103. LPWSTR lpwsValueName;
  104. LPVOID pValue;
  105. LPBYTE * ppValue;
  106. DWORD dwType;
  107. } GLOBALRM_REGISTRY_PARAMS, *PGLOBALRM_REGISTRY_PARAMS;
  108. GLOBALRM_REGISTRY_PARAMS GlobalRMRegParams[] =
  109. {
  110. DIM_VALNAME_PROTOCOLID,
  111. &gbldwProtocolId,
  112. NULL,
  113. REG_DWORD,
  114. DIM_VALNAME_GLOBALINFO,
  115. NULL,
  116. NULL,
  117. REG_BINARY,
  118. DIM_VALNAME_DLLPATH,
  119. NULL,
  120. NULL,
  121. REG_BINARY,
  122. DIM_VALNAME_GLOBALINTERFACE,
  123. NULL,
  124. NULL,
  125. REG_BINARY,
  126. NULL, NULL, NULL, 0
  127. };
  128. //
  129. // Router Manager descriptor table
  130. //
  131. typedef struct _RM_REGISTRY_PARAMS
  132. {
  133. LPWSTR lpwsValueName;
  134. LPVOID pValue;
  135. LPBYTE * ppValue;
  136. DWORD dwType;
  137. } RM_REGISTRY_PARAMS, *PRM_REGISTRY_PARAMS;
  138. RM_REGISTRY_PARAMS RMRegParams[] =
  139. {
  140. DIM_VALNAME_PROTOCOLID,
  141. &gbldwProtocolId,
  142. NULL,
  143. REG_DWORD,
  144. DIM_VALNAME_INTERFACE,
  145. NULL,
  146. NULL,
  147. REG_BINARY,
  148. NULL, NULL, NULL, 0
  149. };
  150. //**
  151. //
  152. // Call: GetKeyMax
  153. //
  154. // Returns: NO_ERROR - success
  155. // non-zero return code - Failure
  156. //
  157. // Description: Returns the nr of values in this key and the maximum
  158. // size of the value data.
  159. //
  160. DWORD
  161. GetKeyMax(
  162. IN HKEY hKey,
  163. OUT LPDWORD lpcbMaxValNameSize, // longest valuename
  164. OUT LPDWORD lpcNumValues, // nr of values
  165. OUT LPDWORD lpcbMaxValueDataSize, // max size of data
  166. OUT LPDWORD lpcNumSubKeys
  167. )
  168. {
  169. DWORD dwRetCode = RegQueryInfoKey(
  170. hKey,
  171. NULL,
  172. NULL,
  173. NULL,
  174. lpcNumSubKeys,
  175. NULL,
  176. NULL,
  177. lpcNumValues,
  178. lpcbMaxValNameSize,
  179. lpcbMaxValueDataSize,
  180. NULL,
  181. NULL );
  182. (*lpcbMaxValNameSize)++;
  183. return( dwRetCode );
  184. }
  185. //**
  186. //
  187. // Call: RegLoadDimParameters
  188. //
  189. // Returns: NO_ERROR - success
  190. // non-zero return code - Failure
  191. //
  192. // Description: Opens the registry, reads and sets specified router
  193. // parameters. If fatal error reading parameters writes the
  194. // error log.
  195. //***
  196. DWORD
  197. RegLoadDimParameters(
  198. VOID
  199. )
  200. {
  201. HKEY hKey;
  202. DWORD dwIndex;
  203. DWORD dwRetCode;
  204. DWORD cbValueBuf;
  205. DWORD dwType;
  206. WCHAR * pChar;
  207. //
  208. // get handle to the DIM parameters key
  209. //
  210. if ( dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  211. DIM_KEYPATH_ROUTER_PARMS,
  212. 0,
  213. KEY_READ,
  214. &hKey ) )
  215. {
  216. pChar = DIM_KEYPATH_ROUTER_PARMS;
  217. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  218. return( dwRetCode );
  219. }
  220. //
  221. // Run through and get all the DIM values
  222. //
  223. for ( dwIndex = 0; DIMRegParams[dwIndex].lpwsValueName != NULL; dwIndex++ )
  224. {
  225. cbValueBuf = sizeof( DWORD );
  226. dwRetCode = RegQueryValueEx(
  227. hKey,
  228. DIMRegParams[dwIndex].lpwsValueName,
  229. NULL,
  230. &dwType,
  231. (LPBYTE)(DIMRegParams[dwIndex].pValue),
  232. &cbValueBuf
  233. );
  234. if ((dwRetCode != NO_ERROR) && (dwRetCode != ERROR_FILE_NOT_FOUND))
  235. {
  236. pChar = DIMRegParams[dwIndex].lpwsValueName;
  237. DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  238. break;
  239. }
  240. if ( dwRetCode == ERROR_FILE_NOT_FOUND )
  241. {
  242. *(DIMRegParams[dwIndex].pValue) = DIMRegParams[dwIndex].dwDefValue;
  243. dwRetCode = NO_ERROR;
  244. }
  245. else
  246. {
  247. if ( ( dwType != REG_DWORD )
  248. ||(*(DIMRegParams[dwIndex].pValue) >
  249. DIMRegParams[dwIndex].dwMaxValue)
  250. ||( *(DIMRegParams[dwIndex].pValue) <
  251. DIMRegParams[dwIndex].dwMinValue))
  252. {
  253. pChar = DIMRegParams[dwIndex].lpwsValueName;
  254. DIMLogWarning( ROUTERLOG_REGVALUE_OVERIDDEN, 1, &pChar );
  255. *(DIMRegParams[dwIndex].pValue) =
  256. DIMRegParams[dwIndex].dwDefValue;
  257. }
  258. }
  259. }
  260. RegCloseKey(hKey);
  261. return( dwRetCode );
  262. }
  263. //**
  264. //
  265. // Call: RegLoadRouterManagers
  266. //
  267. // Returns: NO_ERROR - Success
  268. // non-zero erroc code - Failure
  269. //
  270. // Description: Will load the various router managers and exchange entry points
  271. // with them
  272. //
  273. //***
  274. DWORD
  275. RegLoadRouterManagers(
  276. VOID
  277. )
  278. {
  279. HKEY hKey = NULL;
  280. HKEY hKeyRouterManager = NULL;
  281. WCHAR * pChar;
  282. DWORD dwRetCode = NO_ERROR;
  283. DWORD cbMaxValueDataSize;
  284. DWORD cbMaxValNameSize;
  285. DWORD cNumValues;
  286. WCHAR wchSubKeyName[100];
  287. DWORD cbSubKeyName;
  288. DWORD cNumSubKeys;
  289. DWORD dwKeyIndex;
  290. DWORD cbValueBuf;
  291. LPBYTE pInterfaceInfo = NULL;
  292. LPBYTE pGlobalInfo = NULL;
  293. LPBYTE pDLLPath = NULL;
  294. WCHAR * pDllExpandedPath= NULL;
  295. DWORD dwType;
  296. DWORD cbSize;
  297. DWORD dwIndex;
  298. FILETIME LastWrite;
  299. DWORD dwMaxFilterSize;
  300. DWORD (*StartRouter)(
  301. IN OUT DIM_ROUTER_INTERFACE * pDimRouterIf,
  302. IN BOOL fLANModeOnly,
  303. IN LPVOID pGlobalInfo );
  304. //
  305. // get handle to the Router Managers key
  306. //
  307. dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  308. DIM_KEYPATH_ROUTERMANAGERS,
  309. 0,
  310. KEY_READ,
  311. &hKey );
  312. if ( dwRetCode != NO_ERROR )
  313. {
  314. pChar = DIM_KEYPATH_ROUTERMANAGERS;
  315. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  316. return ( dwRetCode );
  317. }
  318. //
  319. // Find out the number of subkeys
  320. //
  321. dwRetCode = GetKeyMax( hKey,
  322. &cbMaxValNameSize,
  323. &cNumValues,
  324. &cbMaxValueDataSize,
  325. &cNumSubKeys );
  326. if ( dwRetCode != NO_ERROR )
  327. {
  328. RegCloseKey( hKey );
  329. pChar = DIM_KEYPATH_ROUTERMANAGERS;
  330. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  331. return( dwRetCode );
  332. }
  333. gblDIMConfigInfo.dwNumRouterManagers = cNumSubKeys;
  334. gblRouterManagers = (ROUTER_MANAGER_OBJECT *)LOCAL_ALLOC( LPTR,
  335. sizeof(ROUTER_MANAGER_OBJECT) * MAX_NUM_ROUTERMANAGERS);
  336. if ( gblRouterManagers == (ROUTER_MANAGER_OBJECT *)NULL )
  337. {
  338. RegCloseKey( hKey );
  339. dwRetCode = GetLastError();
  340. pChar = DIM_KEYPATH_ROUTERMANAGERS;
  341. DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
  342. return( dwRetCode );
  343. }
  344. for ( dwKeyIndex = 0; dwKeyIndex < cNumSubKeys; dwKeyIndex++ )
  345. {
  346. DWORD cNumSubSubKeys;
  347. cbSubKeyName = sizeof( wchSubKeyName )/sizeof(WCHAR);
  348. dwRetCode = RegEnumKeyEx(
  349. hKey,
  350. dwKeyIndex,
  351. wchSubKeyName,
  352. &cbSubKeyName,
  353. NULL,
  354. NULL,
  355. NULL,
  356. &LastWrite
  357. );
  358. if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
  359. {
  360. pChar = DIM_KEYPATH_ROUTERMANAGERS;
  361. DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
  362. break;
  363. }
  364. dwRetCode = RegOpenKeyEx( hKey,
  365. wchSubKeyName,
  366. 0,
  367. KEY_READ,
  368. &hKeyRouterManager );
  369. if ( dwRetCode != NO_ERROR )
  370. {
  371. pChar = wchSubKeyName;
  372. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  373. break;
  374. }
  375. //
  376. // Find out the size of the path value.
  377. //
  378. dwRetCode = GetKeyMax( hKeyRouterManager,
  379. &cbMaxValNameSize,
  380. &cNumValues,
  381. &cbMaxValueDataSize,
  382. &cNumSubSubKeys);
  383. if ( dwRetCode != NO_ERROR )
  384. {
  385. pChar = wchSubKeyName;
  386. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  387. break;
  388. }
  389. //
  390. // Allocate space to hold data
  391. //
  392. pDLLPath = (LPBYTE)LOCAL_ALLOC( LPTR,
  393. cbMaxValueDataSize+sizeof(WCHAR));
  394. pInterfaceInfo = (LPBYTE)LOCAL_ALLOC( LPTR, cbMaxValueDataSize );
  395. pGlobalInfo = (LPBYTE)LOCAL_ALLOC( LPTR, cbMaxValueDataSize );
  396. if ( ( pInterfaceInfo == NULL ) ||
  397. ( pGlobalInfo == NULL ) ||
  398. ( pDLLPath == NULL ) )
  399. {
  400. dwRetCode = GetLastError();
  401. pChar = wchSubKeyName;
  402. DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  403. break;
  404. }
  405. GlobalRMRegParams[1].pValue = pGlobalInfo;
  406. GlobalRMRegParams[2].pValue = pDLLPath;
  407. GlobalRMRegParams[3].pValue = pInterfaceInfo;
  408. GlobalRMRegParams[1].ppValue = &pGlobalInfo;
  409. GlobalRMRegParams[2].ppValue = &pDLLPath;
  410. GlobalRMRegParams[3].ppValue = &pInterfaceInfo;
  411. //
  412. // Run through and get all the RM values
  413. //
  414. for ( dwIndex = 0;
  415. GlobalRMRegParams[dwIndex].lpwsValueName != NULL;
  416. dwIndex++ )
  417. {
  418. if ( GlobalRMRegParams[dwIndex].dwType == REG_DWORD )
  419. {
  420. cbValueBuf = sizeof( DWORD );
  421. }
  422. else if ( GlobalRMRegParams[dwIndex].dwType == REG_SZ )
  423. {
  424. cbValueBuf = cbMaxValueDataSize + sizeof( WCHAR );
  425. }
  426. else
  427. {
  428. cbValueBuf = cbMaxValueDataSize;
  429. }
  430. dwRetCode = RegQueryValueEx(
  431. hKeyRouterManager,
  432. GlobalRMRegParams[dwIndex].lpwsValueName,
  433. NULL,
  434. &dwType,
  435. (LPBYTE)(GlobalRMRegParams[dwIndex].pValue),
  436. &cbValueBuf
  437. );
  438. if ( ( dwRetCode != NO_ERROR ) &&
  439. ( dwRetCode != ERROR_FILE_NOT_FOUND ) )
  440. {
  441. pChar = GlobalRMRegParams[dwIndex].lpwsValueName;
  442. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  443. break;
  444. }
  445. if ( ( dwRetCode == ERROR_FILE_NOT_FOUND ) || ( cbValueBuf == 0 ) )
  446. {
  447. if ( GlobalRMRegParams[dwIndex].dwType == REG_DWORD )
  448. {
  449. pChar = GlobalRMRegParams[dwIndex].lpwsValueName;
  450. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar,
  451. dwRetCode);
  452. break;
  453. }
  454. else
  455. {
  456. LOCAL_FREE( GlobalRMRegParams[dwIndex].pValue );
  457. *(GlobalRMRegParams[dwIndex].ppValue) = NULL;
  458. GlobalRMRegParams[dwIndex].pValue = NULL;
  459. }
  460. dwRetCode = NO_ERROR;
  461. }
  462. }
  463. if ( dwRetCode != NO_ERROR )
  464. {
  465. break;
  466. }
  467. if ( pDLLPath == NULL )
  468. {
  469. pChar = DIM_VALNAME_DLLPATH;
  470. dwRetCode = ERROR_FILE_NOT_FOUND;
  471. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  472. break;
  473. }
  474. //
  475. // Replace the %SystemRoot% with the actual path.
  476. //
  477. cbSize = ExpandEnvironmentStrings( (LPWSTR)pDLLPath, NULL, 0 );
  478. if ( cbSize == 0 )
  479. {
  480. dwRetCode = GetLastError();
  481. pChar = (LPWSTR)pDLLPath;
  482. DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  483. break;
  484. }
  485. else
  486. {
  487. cbSize *= sizeof( WCHAR );
  488. }
  489. pDllExpandedPath = (LPWSTR)LOCAL_ALLOC( LPTR, cbSize*sizeof(WCHAR) );
  490. if ( pDllExpandedPath == (LPWSTR)NULL )
  491. {
  492. dwRetCode = GetLastError();
  493. pChar = (LPWSTR)pDLLPath;
  494. DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  495. break;
  496. }
  497. cbSize = ExpandEnvironmentStrings( (LPWSTR)pDLLPath,
  498. pDllExpandedPath,
  499. cbSize );
  500. if ( cbSize == 0 )
  501. {
  502. dwRetCode = GetLastError();
  503. pChar = (LPWSTR)pDLLPath;
  504. DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  505. break;
  506. }
  507. //
  508. // Load the DLL
  509. //
  510. gblRouterManagers[dwKeyIndex].hModule = LoadLibrary( pDllExpandedPath );
  511. if ( gblRouterManagers[dwKeyIndex].hModule == NULL )
  512. {
  513. dwRetCode = GetLastError();
  514. DIMLogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
  515. break;
  516. }
  517. //
  518. // Load the StartRouter
  519. //
  520. StartRouter = (PVOID)GetProcAddress(
  521. gblRouterManagers[dwKeyIndex].hModule,
  522. "StartRouter" );
  523. if ( StartRouter == NULL )
  524. {
  525. dwRetCode = GetLastError();
  526. LogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
  527. break;
  528. }
  529. gblRouterManagers[dwKeyIndex].DdmRouterIf.ConnectInterface
  530. = DIMConnectInterface;
  531. gblRouterManagers[dwKeyIndex].DdmRouterIf.DisconnectInterface
  532. = DIMDisconnectInterface;
  533. gblRouterManagers[dwKeyIndex].DdmRouterIf.SaveInterfaceInfo
  534. = DIMSaveInterfaceInfo;
  535. gblRouterManagers[dwKeyIndex].DdmRouterIf.RestoreInterfaceInfo
  536. = DIMRestoreInterfaceInfo;
  537. gblRouterManagers[dwKeyIndex].DdmRouterIf.SaveGlobalInfo
  538. = DIMSaveGlobalInfo;
  539. gblRouterManagers[dwKeyIndex].DdmRouterIf.RouterStopped
  540. = DIMRouterStopped;
  541. gblRouterManagers[dwKeyIndex].DdmRouterIf.InterfaceEnabled
  542. = DIMInterfaceEnabled;
  543. dwRetCode = (*StartRouter)(
  544. &(gblRouterManagers[dwKeyIndex].DdmRouterIf),
  545. gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN,
  546. pGlobalInfo );
  547. if ( dwRetCode != NO_ERROR )
  548. {
  549. LogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
  550. break;
  551. }
  552. //
  553. // Save the global client info
  554. //
  555. if ( pInterfaceInfo == NULL )
  556. {
  557. gblRouterManagers[dwKeyIndex].pDefaultClientInterface = NULL;
  558. gblRouterManagers[dwKeyIndex].dwDefaultClientInterfaceSize = 0;
  559. }
  560. else
  561. {
  562. gblRouterManagers[dwKeyIndex].pDefaultClientInterface =
  563. pInterfaceInfo;
  564. gblRouterManagers[dwKeyIndex].dwDefaultClientInterfaceSize =
  565. cbMaxValueDataSize;
  566. }
  567. gblRouterManagers[dwKeyIndex].fIsRunning = TRUE;
  568. RegCloseKey( hKeyRouterManager );
  569. hKeyRouterManager = (HKEY)NULL;
  570. //
  571. // Only free up 1 thru 2 since 3 is the global interface info that we
  572. // keep around for the life of DDM.
  573. //
  574. for ( dwIndex = 1; dwIndex < 3; dwIndex ++ )
  575. {
  576. if ( GlobalRMRegParams[dwIndex].pValue != NULL )
  577. {
  578. LOCAL_FREE( GlobalRMRegParams[dwIndex].pValue );
  579. *(GlobalRMRegParams[dwIndex].ppValue) = NULL;
  580. GlobalRMRegParams[dwIndex].pValue = NULL;
  581. }
  582. }
  583. if ( pDllExpandedPath != NULL )
  584. {
  585. LOCAL_FREE( pDllExpandedPath );
  586. pDllExpandedPath = NULL;
  587. }
  588. }
  589. if ( dwRetCode != NO_ERROR )
  590. {
  591. for ( dwIndex = 1; dwIndex < 4; dwIndex ++ )
  592. {
  593. if ( GlobalRMRegParams[dwIndex].pValue != NULL )
  594. {
  595. LOCAL_FREE( GlobalRMRegParams[dwIndex].pValue );
  596. *(GlobalRMRegParams[dwIndex].ppValue) = NULL;
  597. GlobalRMRegParams[dwIndex].pValue = NULL;
  598. }
  599. }
  600. }
  601. if ( pDllExpandedPath != NULL )
  602. {
  603. LOCAL_FREE( pDllExpandedPath );
  604. }
  605. if ( hKeyRouterManager != (HKEY)NULL )
  606. {
  607. RegCloseKey( hKeyRouterManager );
  608. }
  609. RegCloseKey( hKey );
  610. return( dwRetCode );
  611. }
  612. //**
  613. //
  614. // Call: RegLoadDDM
  615. //
  616. // Returns: NO_ERROR - Success
  617. // Non-zero return codes - Failure
  618. //
  619. // Description: Will load the Demand Dial Manager DLL and obtains entry points
  620. // into it.
  621. //
  622. DWORD
  623. RegLoadDDM(
  624. VOID
  625. )
  626. {
  627. HKEY hKey;
  628. WCHAR * pChar;
  629. DWORD cbMaxValueDataSize;
  630. DWORD cbMaxValNameSize;
  631. DWORD cNumValues;
  632. DWORD cNumSubKeys;
  633. LPBYTE pData = NULL;
  634. WCHAR * pDllExpandedPath = NULL;
  635. DWORD dwRetCode = NO_ERROR;
  636. DWORD cbSize;
  637. DWORD dwType;
  638. DWORD dwIndex;
  639. //
  640. // get handle to the DIM parameters key
  641. //
  642. if (dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  643. DIM_KEYPATH_DDM,
  644. 0,
  645. KEY_READ,
  646. &hKey))
  647. {
  648. pChar = DIM_KEYPATH_ROUTER_PARMS;
  649. LogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  650. return ( dwRetCode );
  651. }
  652. //
  653. // Find out the size of the path value.
  654. //
  655. dwRetCode = GetKeyMax( hKey,
  656. &cbMaxValNameSize,
  657. &cNumValues,
  658. &cbMaxValueDataSize,
  659. &cNumSubKeys);
  660. if ( dwRetCode != NO_ERROR )
  661. {
  662. RegCloseKey( hKey );
  663. pChar = DIM_KEYPATH_ROUTER_PARMS;
  664. LogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  665. return( dwRetCode );
  666. }
  667. do
  668. {
  669. //
  670. // Allocate space for path and add one for NULL terminator
  671. //
  672. pData = (LPBYTE)LOCAL_ALLOC( LPTR, cbMaxValueDataSize+sizeof(WCHAR) );
  673. if ( pData == (LPBYTE)NULL )
  674. {
  675. dwRetCode = GetLastError();
  676. pChar = DIM_VALNAME_DLLPATH;
  677. LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  678. break;
  679. }
  680. //
  681. // Read in the path
  682. //
  683. dwRetCode = RegQueryValueEx(
  684. hKey,
  685. DIM_VALNAME_DLLPATH,
  686. NULL,
  687. &dwType,
  688. pData,
  689. &cbMaxValueDataSize
  690. );
  691. if ( dwRetCode != NO_ERROR )
  692. {
  693. pChar = DIM_VALNAME_DLLPATH;
  694. LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  695. break;
  696. }
  697. if ( ( dwType != REG_EXPAND_SZ ) && ( dwType != REG_SZ ) )
  698. {
  699. dwRetCode = ERROR_REGISTRY_CORRUPT;
  700. pChar = DIM_VALNAME_DLLPATH;
  701. LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  702. break;
  703. }
  704. //
  705. // Replace the %SystemRoot% with the actual path.
  706. //
  707. cbSize = ExpandEnvironmentStrings( (LPWSTR)pData, NULL, 0 );
  708. if ( cbSize == 0 )
  709. {
  710. dwRetCode = GetLastError();
  711. pChar = (LPWSTR)pData;
  712. LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  713. break;
  714. }
  715. else
  716. {
  717. cbSize *= sizeof( WCHAR );
  718. }
  719. pDllExpandedPath = (LPWSTR)LOCAL_ALLOC( LPTR, cbSize*sizeof(WCHAR) );
  720. if ( pDllExpandedPath == (LPWSTR)NULL )
  721. {
  722. dwRetCode = GetLastError();
  723. pChar = (LPWSTR)pData;
  724. LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  725. break;
  726. }
  727. cbSize = ExpandEnvironmentStrings(
  728. (LPWSTR)pData,
  729. pDllExpandedPath,
  730. cbSize );
  731. if ( cbSize == 0 )
  732. {
  733. dwRetCode = GetLastError();
  734. pChar = (LPWSTR)pData;
  735. LogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  736. break;
  737. }
  738. //
  739. // Load the DLL
  740. //
  741. gblhModuleDDM = LoadLibrary( pDllExpandedPath );
  742. if ( gblhModuleDDM == (HINSTANCE)NULL )
  743. {
  744. dwRetCode = GetLastError();
  745. DIMLogError(ROUTERLOG_LOAD_DLL_ERROR,1,&pDllExpandedPath,dwRetCode);
  746. break;
  747. }
  748. //
  749. // Load the DDM entrypoints.
  750. //
  751. for ( dwIndex = 0;
  752. gblDDMFunctionTable[dwIndex].lpEntryPointName != NULL;
  753. dwIndex ++ )
  754. {
  755. gblDDMFunctionTable[dwIndex].pEntryPoint =
  756. (PVOID)GetProcAddress(
  757. gblhModuleDDM,
  758. gblDDMFunctionTable[dwIndex].lpEntryPointName );
  759. if ( gblDDMFunctionTable[dwIndex].pEntryPoint == NULL )
  760. {
  761. dwRetCode = GetLastError();
  762. DIMLogError( ROUTERLOG_LOAD_DLL_ERROR,
  763. 1,
  764. &pDllExpandedPath,
  765. dwRetCode);
  766. break;
  767. }
  768. }
  769. if ( dwRetCode != NO_ERROR )
  770. {
  771. break;
  772. }
  773. } while(FALSE);
  774. if ( pData != NULL )
  775. {
  776. LOCAL_FREE( pData );
  777. }
  778. if ( pDllExpandedPath != NULL )
  779. {
  780. LOCAL_FREE( pDllExpandedPath );
  781. }
  782. RegCloseKey( hKey );
  783. return( dwRetCode );
  784. }
  785. //**
  786. //
  787. // Call: AddInterfaceToRouterManagers
  788. //
  789. // Returns: NO_ERROR - Success
  790. // Non-zero returns - Failure
  791. //
  792. // Description: Will add the interface to each of the Router Managers.
  793. //
  794. DWORD
  795. AddInterfaceToRouterManagers(
  796. IN HKEY hKeyInterface,
  797. IN LPWSTR lpwsInterfaceName,
  798. IN ROUTER_INTERFACE_OBJECT * pIfObject,
  799. IN DWORD dwTransportId
  800. )
  801. {
  802. DIM_ROUTER_INTERFACE * pDdmRouterIf;
  803. HANDLE hInterface;
  804. FILETIME LastWrite;
  805. HKEY hKeyRM = NULL;
  806. DWORD dwKeyIndex;
  807. DWORD dwIndex;
  808. DWORD dwType;
  809. DWORD dwTransportIndex;
  810. WCHAR * pChar;
  811. DWORD cbMaxValueDataSize;
  812. DWORD cbMaxValNameSize;
  813. DWORD cNumValues;
  814. DWORD cNumSubKeys;
  815. DWORD dwRetCode;
  816. WCHAR wchSubKeyName[100];
  817. DWORD cbSubKeyName;
  818. DWORD cbValueBuf;
  819. DWORD dwMaxFilterSize;
  820. LPBYTE pInterfaceInfo = NULL;
  821. BOOL fAddedToRouterManger = FALSE;
  822. //
  823. // For each of the Router Managers load the static routes and
  824. // filter information
  825. //
  826. for( dwKeyIndex = 0;
  827. dwKeyIndex < gblDIMConfigInfo.dwNumRouterManagers;
  828. dwKeyIndex++ )
  829. {
  830. cbSubKeyName = sizeof( wchSubKeyName )/sizeof(WCHAR);
  831. dwRetCode = RegEnumKeyEx(
  832. hKeyInterface,
  833. dwKeyIndex,
  834. wchSubKeyName,
  835. &cbSubKeyName,
  836. NULL,
  837. NULL,
  838. NULL,
  839. &LastWrite
  840. );
  841. if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
  842. {
  843. if ( dwRetCode == ERROR_NO_MORE_ITEMS )
  844. {
  845. dwRetCode = NO_ERROR;
  846. break;
  847. }
  848. else
  849. {
  850. pChar = lpwsInterfaceName;
  851. DIMLogError(ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode);
  852. }
  853. break;
  854. }
  855. dwRetCode = RegOpenKeyEx( hKeyInterface,
  856. wchSubKeyName,
  857. 0,
  858. KEY_READ,
  859. &hKeyRM );
  860. if ( dwRetCode != NO_ERROR )
  861. {
  862. pChar = wchSubKeyName;
  863. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  864. break;
  865. }
  866. //
  867. // Find out the maximum size of the data for this RM
  868. //
  869. dwRetCode = GetKeyMax( hKeyRM,
  870. &cbMaxValNameSize,
  871. &cNumValues,
  872. &cbMaxValueDataSize,
  873. &cNumSubKeys );
  874. if ( dwRetCode != NO_ERROR )
  875. {
  876. pChar = wchSubKeyName;
  877. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  878. break;
  879. }
  880. //
  881. // Allocate space to hold data
  882. //
  883. pInterfaceInfo = (LPBYTE)LOCAL_ALLOC( LPTR, cbMaxValueDataSize );
  884. if ( ( pInterfaceInfo == NULL ) )
  885. {
  886. dwRetCode = GetLastError();
  887. pChar = wchSubKeyName;
  888. DIMLogError( ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode );
  889. break;
  890. }
  891. RMRegParams[1].pValue = pInterfaceInfo;
  892. RMRegParams[1].ppValue = &pInterfaceInfo;
  893. //
  894. // Run through and get all the RM values
  895. //
  896. for ( dwIndex = 0;
  897. RMRegParams[dwIndex].lpwsValueName != NULL;
  898. dwIndex++ )
  899. {
  900. if ( RMRegParams[dwIndex].dwType == REG_DWORD )
  901. {
  902. cbValueBuf = sizeof( DWORD );
  903. }
  904. else if ( RMRegParams[dwIndex].dwType == REG_SZ )
  905. {
  906. cbValueBuf = cbMaxValueDataSize + sizeof( WCHAR );
  907. }
  908. else
  909. {
  910. cbValueBuf = cbMaxValueDataSize;
  911. }
  912. dwRetCode = RegQueryValueEx(
  913. hKeyRM,
  914. RMRegParams[dwIndex].lpwsValueName,
  915. NULL,
  916. &dwType,
  917. (LPBYTE)(RMRegParams[dwIndex].pValue),
  918. &cbValueBuf
  919. );
  920. if ( ( dwRetCode != NO_ERROR ) &&
  921. ( dwRetCode != ERROR_FILE_NOT_FOUND ) )
  922. {
  923. pChar = RMRegParams[dwIndex].lpwsValueName;
  924. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  925. break;
  926. }
  927. if ( ( dwRetCode == ERROR_FILE_NOT_FOUND ) || ( cbValueBuf == 0 ) )
  928. {
  929. if ( RMRegParams[dwIndex].dwType == REG_DWORD )
  930. {
  931. pChar = RMRegParams[dwIndex].lpwsValueName;
  932. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE,1,&pChar,dwRetCode);
  933. break;
  934. }
  935. else
  936. {
  937. LOCAL_FREE( RMRegParams[dwIndex].pValue );
  938. *(RMRegParams[dwIndex].ppValue) = NULL;
  939. RMRegParams[dwIndex].pValue = NULL;
  940. }
  941. dwRetCode = NO_ERROR;
  942. }
  943. }
  944. if ( ( dwRetCode == NO_ERROR ) &&
  945. (( dwTransportId == 0 ) || ( dwTransportId == gbldwProtocolId )) )
  946. {
  947. //
  948. // If the router manager for this protocol exists then add this interface
  949. // with it otherwise skip it
  950. //
  951. if ( (dwTransportIndex = GetTransportIndex(gbldwProtocolId)) != -1)
  952. {
  953. pDdmRouterIf=&(gblRouterManagers[dwTransportIndex].DdmRouterIf);
  954. if (IsInterfaceRoleAcceptable(pIfObject, gbldwProtocolId))
  955. {
  956. dwRetCode = pDdmRouterIf->AddInterface(
  957. lpwsInterfaceName,
  958. pInterfaceInfo,
  959. pIfObject->IfType,
  960. pIfObject->hDIMInterface,
  961. &hInterface );
  962. if ( dwRetCode == NO_ERROR )
  963. {
  964. if ( !( pIfObject->fFlags & IFFLAG_ENABLED ) )
  965. {
  966. WCHAR wchFriendlyName[MAX_INTERFACE_NAME_LEN+1];
  967. LPWSTR lpszFriendlyName = wchFriendlyName;
  968. if ( MprConfigGetFriendlyName(
  969. gblDIMConfigInfo.hMprConfig,
  970. lpwsInterfaceName,
  971. wchFriendlyName,
  972. sizeof( wchFriendlyName ) ) != NO_ERROR )
  973. {
  974. wcscpy( wchFriendlyName, lpwsInterfaceName );
  975. }
  976. //
  977. // Disable the interface
  978. //
  979. pDdmRouterIf->InterfaceNotReachable(
  980. hInterface,
  981. INTERFACE_DISABLED );
  982. DIMLogInformation( ROUTERLOG_IF_UNREACHABLE_REASON3, 1,
  983. &lpszFriendlyName );
  984. }
  985. pIfObject->Transport[dwTransportIndex].hInterface = hInterface;
  986. fAddedToRouterManger = TRUE;
  987. }
  988. else
  989. {
  990. LPWSTR lpwsString[2];
  991. WCHAR wchProtocolId[10];
  992. lpwsString[0] = lpwsInterfaceName;
  993. lpwsString[1] = ( gbldwProtocolId == PID_IP ) ? L"IP" : L"IPX";
  994. DIMLogErrorString( ROUTERLOG_COULDNT_ADD_INTERFACE,
  995. 2, lpwsString, dwRetCode, 2 );
  996. dwRetCode = NO_ERROR;
  997. }
  998. }
  999. }
  1000. }
  1001. RegCloseKey( hKeyRM );
  1002. hKeyRM = NULL;
  1003. for ( dwIndex = 1; dwIndex < 3; dwIndex ++ )
  1004. {
  1005. if ( RMRegParams[dwIndex].pValue != NULL )
  1006. {
  1007. LOCAL_FREE( RMRegParams[dwIndex].pValue );
  1008. *(RMRegParams[dwIndex].ppValue) = NULL;
  1009. RMRegParams[dwIndex].pValue = NULL;
  1010. }
  1011. }
  1012. if ( dwRetCode != NO_ERROR )
  1013. {
  1014. break;
  1015. }
  1016. }
  1017. for ( dwIndex = 1; dwIndex < 2; dwIndex ++ )
  1018. {
  1019. if ( RMRegParams[dwIndex].pValue != NULL )
  1020. {
  1021. LOCAL_FREE( RMRegParams[dwIndex].pValue );
  1022. }
  1023. }
  1024. if ( hKeyRM != NULL )
  1025. {
  1026. RegCloseKey( hKeyRM );
  1027. }
  1028. //
  1029. // Remove the check below. We want to allow users to add an interface
  1030. // which doesnt have any transports over it.
  1031. // AmritanR
  1032. //
  1033. #if 0
  1034. //
  1035. // If this interface was not successfully added to any router managers
  1036. // then fail
  1037. //
  1038. if ( !fAddedToRouterManger )
  1039. {
  1040. return( ERROR_NO_SUCH_INTERFACE );
  1041. }
  1042. #endif
  1043. return( dwRetCode );
  1044. }
  1045. //**
  1046. //
  1047. // Call: RegLoadInterfaces
  1048. //
  1049. // Returns: NO_ERROR - Success
  1050. // Non-zero return code is a FATAL error
  1051. //
  1052. // Description: Will try to load the various interfaces in the registry. On
  1053. // failure in trying to add any interface an error will be logged
  1054. // but will return NO_ERROR. If the input parameter is not NULL,
  1055. // it will load a specific interface.
  1056. //
  1057. DWORD
  1058. RegLoadInterfaces(
  1059. IN LPWSTR lpwsInterfaceName,
  1060. IN BOOL fAllTransports
  1061. )
  1062. {
  1063. HKEY hKey = NULL;
  1064. HKEY hKeyInterface = NULL;
  1065. WCHAR * pChar;
  1066. DWORD cbMaxValueDataSize;
  1067. DWORD cbMaxValNameSize;
  1068. DWORD cNumValues;
  1069. DWORD cNumSubKeys;
  1070. WCHAR wchInterfaceKeyName[50];
  1071. DWORD cbSubKeyName;
  1072. DWORD dwKeyIndex;
  1073. FILETIME LastWrite;
  1074. DWORD dwRetCode;
  1075. DWORD dwSubKeyIndex;
  1076. WCHAR wchInterfaceName[MAX_INTERFACE_NAME_LEN+1];
  1077. DWORD dwType;
  1078. DWORD cbValueBuf;
  1079. //
  1080. // Get handle to the INTERFACES parameters key
  1081. //
  1082. if ( dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1083. DIM_KEYPATH_INTERFACES,
  1084. 0,
  1085. KEY_READ,
  1086. &hKey ))
  1087. {
  1088. pChar = DIM_KEYPATH_INTERFACES;
  1089. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  1090. return ( dwRetCode );
  1091. }
  1092. //
  1093. // Find out the number of Interfaces
  1094. //
  1095. dwRetCode = GetKeyMax( hKey,
  1096. &cbMaxValNameSize,
  1097. &cNumValues,
  1098. &cbMaxValueDataSize,
  1099. &cNumSubKeys );
  1100. if ( dwRetCode != NO_ERROR )
  1101. {
  1102. RegCloseKey( hKey );
  1103. pChar = DIM_KEYPATH_INTERFACES;
  1104. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  1105. return( dwRetCode );
  1106. }
  1107. dwRetCode = ERROR_NO_SUCH_INTERFACE;
  1108. //
  1109. // For each interface
  1110. //
  1111. for ( dwKeyIndex = 0; dwKeyIndex < cNumSubKeys; dwKeyIndex++ )
  1112. {
  1113. cbSubKeyName = sizeof( wchInterfaceKeyName )/sizeof(WCHAR);
  1114. dwRetCode = RegEnumKeyEx(
  1115. hKey,
  1116. dwKeyIndex,
  1117. wchInterfaceKeyName,
  1118. &cbSubKeyName,
  1119. NULL,
  1120. NULL,
  1121. NULL,
  1122. &LastWrite
  1123. );
  1124. if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
  1125. {
  1126. pChar = DIM_KEYPATH_INTERFACES;
  1127. DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
  1128. break;
  1129. }
  1130. dwRetCode = RegOpenKeyEx( hKey,
  1131. wchInterfaceKeyName,
  1132. 0,
  1133. KEY_READ,
  1134. &hKeyInterface );
  1135. if ( dwRetCode != NO_ERROR )
  1136. {
  1137. pChar = wchInterfaceKeyName;
  1138. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  1139. break;
  1140. }
  1141. //
  1142. // Get the interface name value
  1143. //
  1144. cbValueBuf = sizeof( wchInterfaceName );
  1145. dwRetCode = RegQueryValueEx(
  1146. hKeyInterface,
  1147. DIM_VALNAME_INTERFACE_NAME,
  1148. NULL,
  1149. &dwType,
  1150. (LPBYTE)wchInterfaceName,
  1151. &cbValueBuf
  1152. );
  1153. if ( ( dwRetCode != NO_ERROR ) || ( dwType != REG_SZ ) )
  1154. {
  1155. pChar = DIM_VALNAME_INTERFACE_NAME;
  1156. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  1157. return( dwRetCode );
  1158. }
  1159. if ( lpwsInterfaceName != NULL )
  1160. {
  1161. //
  1162. // We need to load a specific interface
  1163. //
  1164. if ( _wcsicmp( lpwsInterfaceName, wchInterfaceName ) != 0 )
  1165. {
  1166. RegCloseKey( hKeyInterface );
  1167. hKeyInterface = NULL;
  1168. continue;
  1169. }
  1170. }
  1171. dwRetCode = RegLoadInterface( wchInterfaceName, hKeyInterface, fAllTransports );
  1172. if ( dwRetCode != NO_ERROR )
  1173. {
  1174. pChar = wchInterfaceName;
  1175. DIMLogErrorString(ROUTERLOG_COULDNT_LOAD_IF, 1, &pChar,dwRetCode,1);
  1176. }
  1177. //
  1178. // ERROR_NOT_SUPPORTED is returned for ipip tunnels which are not
  1179. // supported as of whistler. We reset the error code here because
  1180. // this is not a critical error and in some cases, a failing
  1181. // call to RegLoadInterfaces will cause the service to not start.
  1182. //
  1183. if ( dwRetCode == ERROR_NOT_SUPPORTED )
  1184. {
  1185. dwRetCode = NO_ERROR;
  1186. }
  1187. RegCloseKey( hKeyInterface );
  1188. hKeyInterface = NULL;
  1189. if ( lpwsInterfaceName != NULL )
  1190. {
  1191. //
  1192. // If we need to load a specific interface and this was it, then we are done.
  1193. //
  1194. if ( _wcsicmp( lpwsInterfaceName, wchInterfaceName ) == 0 )
  1195. {
  1196. break;
  1197. }
  1198. }
  1199. }
  1200. RegCloseKey( hKey );
  1201. //
  1202. // If we aren't looking for a specific interface
  1203. //
  1204. if ( lpwsInterfaceName == NULL )
  1205. {
  1206. //
  1207. // If there was no interface found, then we are OK
  1208. //
  1209. if ( dwRetCode == ERROR_NO_SUCH_INTERFACE )
  1210. {
  1211. dwRetCode = NO_ERROR;
  1212. }
  1213. }
  1214. return( dwRetCode );
  1215. }
  1216. //**
  1217. //
  1218. // Call: RegLoadInterface
  1219. //
  1220. // Returns: NO_ERROR - Success
  1221. // Non-zero returns - Failure
  1222. //
  1223. // Description: Will load the specific interface
  1224. //
  1225. DWORD
  1226. RegLoadInterface(
  1227. IN LPWSTR lpwsInterfaceName,
  1228. IN HKEY hKeyInterface,
  1229. IN BOOL fAllTransports
  1230. )
  1231. {
  1232. DWORD dwIndex;
  1233. WCHAR * pChar;
  1234. DWORD cbValueBuf;
  1235. DWORD dwRetCode;
  1236. DWORD dwType;
  1237. ROUTER_INTERFACE_OBJECT * pIfObject;
  1238. DWORD IfState;
  1239. LPWSTR lpwsDialoutHours = NULL;
  1240. DWORD dwInactiveReason = 0;
  1241. //
  1242. // Get Interface parameters
  1243. //
  1244. for ( dwIndex = 0; IFRegParams[dwIndex].lpwsValueName != NULL; dwIndex++ )
  1245. {
  1246. cbValueBuf = sizeof( DWORD );
  1247. dwRetCode = RegQueryValueEx(
  1248. hKeyInterface,
  1249. IFRegParams[dwIndex].lpwsValueName,
  1250. NULL,
  1251. &dwType,
  1252. (LPBYTE)(IFRegParams[dwIndex].pValue),
  1253. &cbValueBuf );
  1254. if ((dwRetCode != NO_ERROR) && (dwRetCode != ERROR_FILE_NOT_FOUND))
  1255. {
  1256. pChar = IFRegParams[dwIndex].lpwsValueName;
  1257. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  1258. break;
  1259. }
  1260. if ( dwRetCode == ERROR_FILE_NOT_FOUND )
  1261. {
  1262. //
  1263. // dwIndex == 0 means there was no type, this is an error
  1264. //
  1265. if ( dwIndex > 0 )
  1266. {
  1267. *(IFRegParams[dwIndex].pValue)=IFRegParams[dwIndex].dwDefValue;
  1268. dwRetCode = NO_ERROR;
  1269. }
  1270. }
  1271. else
  1272. {
  1273. if ( ( dwType != REG_DWORD )
  1274. ||(*((LPDWORD)IFRegParams[dwIndex].pValue) >
  1275. IFRegParams[dwIndex].dwMaxValue)
  1276. ||( *((LPDWORD)IFRegParams[dwIndex].pValue) <
  1277. IFRegParams[dwIndex].dwMinValue))
  1278. {
  1279. //
  1280. // dwIndex == 0 means the type was invalid, this is an error
  1281. //
  1282. if ( dwIndex > 0 )
  1283. {
  1284. pChar = IFRegParams[dwIndex].lpwsValueName;
  1285. DIMLogWarning(ROUTERLOG_REGVALUE_OVERIDDEN, 1, &pChar);
  1286. *(IFRegParams[dwIndex].pValue) =
  1287. IFRegParams[dwIndex].dwDefValue;
  1288. }
  1289. else
  1290. {
  1291. dwRetCode = ERROR_REGISTRY_CORRUPT;
  1292. pChar = IFRegParams[dwIndex].lpwsValueName;
  1293. DIMLogError( ROUTERLOG_CANT_QUERY_VALUE,
  1294. 1, &pChar, dwRetCode);
  1295. break;
  1296. }
  1297. }
  1298. }
  1299. }
  1300. if ( dwRetCode != NO_ERROR )
  1301. {
  1302. return( dwRetCode );
  1303. }
  1304. //
  1305. // IPIP tunnels are no longer accepted
  1306. //
  1307. if ( gbldwInterfaceType == ROUTER_IF_TYPE_TUNNEL1 )
  1308. {
  1309. return ERROR_NOT_SUPPORTED;
  1310. }
  1311. //
  1312. // Check to see if this interface is active. Do not load otherwise.
  1313. //
  1314. if ( gbldwInterfaceType == ROUTER_IF_TYPE_DEDICATED )
  1315. {
  1316. //
  1317. // Need to handle the IPX interface names ie {GUID}\Frame type
  1318. //
  1319. WCHAR wchGUIDSaveLast;
  1320. LPWSTR lpwszGUIDEnd = wcsrchr( lpwsInterfaceName, L'}' );
  1321. if (lpwszGUIDEnd==NULL)
  1322. return ERROR_INVALID_PARAMETER;
  1323. wchGUIDSaveLast = *(lpwszGUIDEnd+1);
  1324. *(lpwszGUIDEnd+1) = (WCHAR)NULL;
  1325. if ( !IfObjectIsLANDeviceActive( lpwsInterfaceName, &dwInactiveReason ))
  1326. {
  1327. if ( dwInactiveReason == INTERFACE_NO_DEVICE )
  1328. {
  1329. *(lpwszGUIDEnd+1) = wchGUIDSaveLast;
  1330. return( dwRetCode );
  1331. }
  1332. }
  1333. *(lpwszGUIDEnd+1) = wchGUIDSaveLast;
  1334. }
  1335. //
  1336. // Get the dialout hours value if there is one
  1337. //
  1338. cbValueBuf = 0;
  1339. dwRetCode = RegQueryValueEx(
  1340. hKeyInterface,
  1341. DIM_VALNAME_DIALOUT_HOURS,
  1342. NULL,
  1343. &dwType,
  1344. NULL,
  1345. &cbValueBuf
  1346. );
  1347. if ( ( dwRetCode != NO_ERROR ) || ( dwType != REG_MULTI_SZ ) )
  1348. {
  1349. if ( dwRetCode != ERROR_FILE_NOT_FOUND )
  1350. {
  1351. return( dwRetCode );
  1352. }
  1353. else
  1354. {
  1355. dwRetCode = NO_ERROR;
  1356. }
  1357. }
  1358. if ( cbValueBuf > 0 )
  1359. {
  1360. if ( (lpwsDialoutHours = LOCAL_ALLOC( LPTR, cbValueBuf)) == NULL )
  1361. {
  1362. pChar = DIM_VALNAME_DIALOUT_HOURS;
  1363. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  1364. return( dwRetCode );
  1365. }
  1366. dwRetCode = RegQueryValueEx(
  1367. hKeyInterface,
  1368. DIM_VALNAME_DIALOUT_HOURS,
  1369. NULL,
  1370. &dwType,
  1371. (LPBYTE)lpwsDialoutHours,
  1372. &cbValueBuf
  1373. );
  1374. if ( dwRetCode != NO_ERROR )
  1375. {
  1376. LOCAL_FREE( lpwsDialoutHours );
  1377. pChar = DIM_VALNAME_DIALOUT_HOURS;
  1378. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  1379. return( dwRetCode );
  1380. }
  1381. }
  1382. //
  1383. // Allocate an interface object for this interface
  1384. //
  1385. if ( ( gbldwInterfaceType == ROUTER_IF_TYPE_DEDICATED ) ||
  1386. ( gbldwInterfaceType == ROUTER_IF_TYPE_LOOPBACK ) ||
  1387. ( gbldwInterfaceType == ROUTER_IF_TYPE_INTERNAL ) )
  1388. {
  1389. IfState = RISTATE_CONNECTED;
  1390. }
  1391. else
  1392. {
  1393. if ( gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN )
  1394. {
  1395. pChar = lpwsInterfaceName;
  1396. LOCAL_FREE( lpwsDialoutHours );
  1397. DIMLogWarning( ROUTERLOG_DID_NOT_LOAD_DDMIF, 1, &pChar );
  1398. dwRetCode = NO_ERROR;
  1399. return( dwRetCode );
  1400. }
  1401. else
  1402. {
  1403. IfState = RISTATE_DISCONNECTED;
  1404. }
  1405. }
  1406. pIfObject = IfObjectAllocateAndInit(
  1407. lpwsInterfaceName,
  1408. IfState,
  1409. gbldwInterfaceType,
  1410. (HCONN)0,
  1411. gblfEnabled,
  1412. gblInterfaceReachableAfterSecondsMin,
  1413. gblInterfaceReachableAfterSecondsMax,
  1414. lpwsDialoutHours );
  1415. if ( pIfObject == NULL )
  1416. {
  1417. if ( lpwsDialoutHours != NULL )
  1418. {
  1419. LOCAL_FREE( lpwsDialoutHours );
  1420. }
  1421. dwRetCode = NO_ERROR;
  1422. return( dwRetCode );
  1423. }
  1424. //
  1425. // Add interface into table now because a table lookup is made within
  1426. // the InterfaceEnabled call that the router managers make in the
  1427. // context of the AddInterface call.
  1428. //
  1429. if ( ( dwRetCode = IfObjectInsertInTable( pIfObject ) ) != NO_ERROR )
  1430. {
  1431. IfObjectFree( pIfObject );
  1432. return( dwRetCode );
  1433. }
  1434. if ( fAllTransports )
  1435. {
  1436. dwRetCode = AddInterfaceToRouterManagers( hKeyInterface,
  1437. lpwsInterfaceName,
  1438. pIfObject,
  1439. 0 );
  1440. if ( dwRetCode != NO_ERROR )
  1441. {
  1442. IfObjectRemove( pIfObject->hDIMInterface );
  1443. }
  1444. else
  1445. {
  1446. //
  1447. // Check to see if the device has media sense
  1448. //
  1449. if ( pIfObject->IfType == ROUTER_IF_TYPE_DEDICATED )
  1450. {
  1451. if ( dwInactiveReason == INTERFACE_NO_MEDIA_SENSE )
  1452. {
  1453. pIfObject->State = RISTATE_DISCONNECTED;
  1454. pIfObject->fFlags |= IFFLAG_NO_MEDIA_SENSE;
  1455. IfObjectNotifyOfReachabilityChange( pIfObject,
  1456. FALSE,
  1457. INTERFACE_NO_MEDIA_SENSE );
  1458. }
  1459. }
  1460. if ( pIfObject->IfType == ROUTER_IF_TYPE_FULL_ROUTER )
  1461. {
  1462. if ( pIfObject->fFlags & IFFLAG_OUT_OF_RESOURCES )
  1463. {
  1464. IfObjectNotifyOfReachabilityChange( pIfObject,
  1465. FALSE,
  1466. MPR_INTERFACE_OUT_OF_RESOURCES );
  1467. }
  1468. }
  1469. }
  1470. }
  1471. return( dwRetCode );
  1472. }
  1473. //**
  1474. //
  1475. // Call: RegOpenAppropriateKey
  1476. //
  1477. // Returns: NO_ERROR - Success
  1478. //
  1479. // Description: Will open the appropriate registry key for the given router
  1480. // manager within the given interface.
  1481. //
  1482. DWORD
  1483. RegOpenAppropriateKey(
  1484. IN LPWSTR wchInterfaceName,
  1485. IN DWORD dwProtocolId,
  1486. IN OUT HKEY * phKeyRM
  1487. )
  1488. {
  1489. HKEY hKey = NULL;
  1490. HKEY hSubKey = NULL;
  1491. WCHAR wchSubKeyName[100];
  1492. DWORD cbSubKeyName;
  1493. DWORD dwType;
  1494. DWORD dwKeyIndex;
  1495. FILETIME LastWrite;
  1496. DWORD dwPId;
  1497. DWORD cbValueBuf;
  1498. WCHAR * pChar;
  1499. DWORD dwRetCode = NO_ERROR;
  1500. DWORD cbMaxValNameSize;
  1501. DWORD cNumValues;
  1502. DWORD cbMaxValueDataSize;
  1503. DWORD cNumSubKeys;
  1504. WCHAR wchIfName[MAX_INTERFACE_NAME_LEN+1];
  1505. //
  1506. // Get handle to the INTERFACES parameters key
  1507. //
  1508. if ( ( dwRetCode = RegOpenKey( HKEY_LOCAL_MACHINE,
  1509. DIM_KEYPATH_INTERFACES,
  1510. &hKey )) != NO_ERROR )
  1511. {
  1512. pChar = DIM_KEYPATH_INTERFACES;
  1513. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  1514. return( dwRetCode );
  1515. }
  1516. //
  1517. // Find out the number of subkeys
  1518. //
  1519. dwRetCode = GetKeyMax( hKey,
  1520. &cbMaxValNameSize,
  1521. &cNumValues,
  1522. &cbMaxValueDataSize,
  1523. &cNumSubKeys );
  1524. if ( dwRetCode != NO_ERROR )
  1525. {
  1526. RegCloseKey( hKey );
  1527. pChar = DIM_KEYPATH_INTERFACES;
  1528. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  1529. return( dwRetCode );
  1530. }
  1531. //
  1532. // Find the interface
  1533. //
  1534. hSubKey = NULL;
  1535. for ( dwKeyIndex = 0; dwKeyIndex < cNumSubKeys; dwKeyIndex++ )
  1536. {
  1537. cbSubKeyName = sizeof( wchSubKeyName )/sizeof(WCHAR);
  1538. dwRetCode = RegEnumKeyEx(
  1539. hKey,
  1540. dwKeyIndex,
  1541. wchSubKeyName,
  1542. &cbSubKeyName,
  1543. NULL,
  1544. NULL,
  1545. NULL,
  1546. &LastWrite
  1547. );
  1548. if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
  1549. {
  1550. pChar = DIM_KEYPATH_INTERFACES;
  1551. DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
  1552. break;
  1553. }
  1554. //
  1555. // Open this key
  1556. //
  1557. if ( ( dwRetCode = RegOpenKey( hKey,
  1558. wchSubKeyName,
  1559. &hSubKey )) != NO_ERROR )
  1560. {
  1561. pChar = wchSubKeyName;
  1562. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  1563. hSubKey = NULL;
  1564. break;
  1565. }
  1566. //
  1567. // Get the interface name value
  1568. //
  1569. cbValueBuf = sizeof( wchIfName );
  1570. dwRetCode = RegQueryValueEx(
  1571. hSubKey,
  1572. DIM_VALNAME_INTERFACE_NAME,
  1573. NULL,
  1574. &dwType,
  1575. (LPBYTE)wchIfName,
  1576. &cbValueBuf
  1577. );
  1578. if ( dwRetCode != NO_ERROR )
  1579. {
  1580. pChar = DIM_VALNAME_INTERFACE_NAME;
  1581. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  1582. break;
  1583. }
  1584. //
  1585. // Is this the interface we want ?
  1586. //
  1587. if ( _wcsicmp( wchIfName, wchInterfaceName ) == 0 )
  1588. {
  1589. dwRetCode = NO_ERROR;
  1590. break;
  1591. }
  1592. else
  1593. {
  1594. dwRetCode = ERROR_NO_SUCH_INTERFACE;
  1595. RegCloseKey(hSubKey);
  1596. hSubKey = NULL;
  1597. }
  1598. }
  1599. RegCloseKey( hKey );
  1600. if ( dwRetCode != NO_ERROR )
  1601. {
  1602. if ( hSubKey != NULL )
  1603. {
  1604. RegCloseKey( hSubKey );
  1605. }
  1606. return( dwRetCode );
  1607. }
  1608. //
  1609. // Find out which router manager to restore information for.
  1610. //
  1611. for( dwKeyIndex = 0;
  1612. dwKeyIndex < gblDIMConfigInfo.dwNumRouterManagers;
  1613. dwKeyIndex++ )
  1614. {
  1615. cbSubKeyName = sizeof( wchSubKeyName );
  1616. dwRetCode = RegEnumKeyEx(
  1617. hSubKey,
  1618. dwKeyIndex,
  1619. wchSubKeyName,
  1620. &cbSubKeyName,
  1621. NULL,
  1622. NULL,
  1623. NULL,
  1624. &LastWrite
  1625. );
  1626. if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
  1627. {
  1628. pChar = wchInterfaceName;
  1629. DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
  1630. break;
  1631. }
  1632. dwRetCode = RegOpenKeyEx(
  1633. hSubKey,
  1634. wchSubKeyName,
  1635. 0,
  1636. KEY_READ | KEY_WRITE,
  1637. phKeyRM );
  1638. if ( dwRetCode != NO_ERROR )
  1639. {
  1640. pChar = wchSubKeyName;
  1641. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  1642. break;
  1643. }
  1644. cbValueBuf = sizeof( DWORD );
  1645. dwRetCode = RegQueryValueEx(
  1646. *phKeyRM,
  1647. DIM_VALNAME_PROTOCOLID,
  1648. NULL,
  1649. &dwType,
  1650. (LPBYTE)&dwPId,
  1651. &cbValueBuf
  1652. );
  1653. if ( dwRetCode != NO_ERROR )
  1654. {
  1655. pChar = DIM_VALNAME_PROTOCOLID;
  1656. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  1657. break;
  1658. }
  1659. if ( dwPId == dwProtocolId )
  1660. {
  1661. break;
  1662. }
  1663. RegCloseKey( *phKeyRM );
  1664. *phKeyRM = NULL;
  1665. }
  1666. RegCloseKey( hSubKey );
  1667. if ( dwRetCode != NO_ERROR )
  1668. {
  1669. if ( *phKeyRM != NULL )
  1670. {
  1671. RegCloseKey( *phKeyRM );
  1672. *phKeyRM = NULL;
  1673. }
  1674. return( dwRetCode );
  1675. }
  1676. if ( *phKeyRM == NULL )
  1677. {
  1678. return( ERROR_NO_SUCH_INTERFACE );
  1679. }
  1680. return( NO_ERROR );
  1681. }
  1682. //**
  1683. //
  1684. // Call: RegOpenAppropriateRMKey
  1685. //
  1686. // Returns: NO_ERROR - Success
  1687. //
  1688. // Description: Will open the appropriate registry key for the given router
  1689. // manager.
  1690. //
  1691. DWORD
  1692. RegOpenAppropriateRMKey(
  1693. IN DWORD dwProtocolId,
  1694. IN OUT HKEY * phKeyRM
  1695. )
  1696. {
  1697. HKEY hKey = NULL;
  1698. DWORD dwRetCode = NO_ERROR;
  1699. WCHAR wchSubKeyName[100];
  1700. DWORD cbSubKeyName;
  1701. DWORD dwPId;
  1702. DWORD dwKeyIndex;
  1703. FILETIME LastWrite;
  1704. DWORD dwType;
  1705. DWORD cbValueBuf;
  1706. WCHAR * pChar;
  1707. //
  1708. // get handle to the Router Managers key
  1709. //
  1710. dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1711. DIM_KEYPATH_ROUTERMANAGERS,
  1712. 0,
  1713. KEY_READ,
  1714. &hKey );
  1715. if ( dwRetCode != NO_ERROR )
  1716. {
  1717. pChar = DIM_KEYPATH_ROUTERMANAGERS;
  1718. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  1719. return ( dwRetCode );
  1720. }
  1721. //
  1722. // Find out which router manager to restore information for.
  1723. //
  1724. for( dwKeyIndex = 0;
  1725. dwKeyIndex < gblDIMConfigInfo.dwNumRouterManagers;
  1726. dwKeyIndex++ )
  1727. {
  1728. cbSubKeyName = sizeof( wchSubKeyName )/sizeof(WCHAR);
  1729. dwRetCode = RegEnumKeyEx(
  1730. hKey,
  1731. dwKeyIndex,
  1732. wchSubKeyName,
  1733. &cbSubKeyName,
  1734. NULL,
  1735. NULL,
  1736. NULL,
  1737. &LastWrite
  1738. );
  1739. if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
  1740. {
  1741. pChar = DIM_KEYPATH_ROUTERMANAGERS;
  1742. DIMLogError( ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode );
  1743. break;
  1744. }
  1745. dwRetCode = RegOpenKeyEx(
  1746. hKey,
  1747. wchSubKeyName,
  1748. 0,
  1749. KEY_READ | KEY_WRITE,
  1750. phKeyRM );
  1751. if ( dwRetCode != NO_ERROR )
  1752. {
  1753. pChar = wchSubKeyName;
  1754. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode);
  1755. break;
  1756. }
  1757. cbValueBuf = sizeof( DWORD );
  1758. dwRetCode = RegQueryValueEx(
  1759. *phKeyRM,
  1760. DIM_VALNAME_PROTOCOLID,
  1761. NULL,
  1762. &dwType,
  1763. (LPBYTE)&dwPId,
  1764. &cbValueBuf
  1765. );
  1766. if ( dwRetCode != NO_ERROR )
  1767. {
  1768. pChar = DIM_VALNAME_PROTOCOLID;
  1769. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  1770. break;
  1771. }
  1772. if ( dwPId == dwProtocolId )
  1773. {
  1774. break;
  1775. }
  1776. RegCloseKey( *phKeyRM );
  1777. *phKeyRM = NULL;
  1778. }
  1779. RegCloseKey( hKey );
  1780. if ( dwRetCode != NO_ERROR )
  1781. {
  1782. if ( *phKeyRM != NULL )
  1783. {
  1784. RegCloseKey( *phKeyRM );
  1785. }
  1786. return( dwRetCode );
  1787. }
  1788. if ( *phKeyRM == NULL )
  1789. {
  1790. return( ERROR_UNKNOWN_PROTOCOL_ID );
  1791. }
  1792. return( NO_ERROR );
  1793. }
  1794. //**
  1795. //
  1796. // Call: AddInterfacesToRouterManager
  1797. //
  1798. // Returns: NO_ERROR - Success
  1799. // Non-zero returns - Failure
  1800. //
  1801. // Description: Register all existing interfaces with this router manager
  1802. //
  1803. DWORD
  1804. AddInterfacesToRouterManager(
  1805. IN LPWSTR lpwsInterfaceName,
  1806. IN DWORD dwTransportId
  1807. )
  1808. {
  1809. ROUTER_INTERFACE_OBJECT * pIfObject;
  1810. HKEY hKey = NULL;
  1811. HKEY hKeyInterface = NULL;
  1812. DWORD dwKeyIndex = 0;
  1813. DWORD cbMaxValueDataSize;
  1814. DWORD cbMaxValNameSize;
  1815. DWORD cNumValues;
  1816. DWORD cNumSubKeys;
  1817. DWORD cbSubKeyName;
  1818. FILETIME LastWrite;
  1819. DWORD dwType;
  1820. DWORD dwRetCode;
  1821. DWORD cbValueBuf;
  1822. WCHAR * pChar;
  1823. WCHAR wchInterfaceKeyName[50];
  1824. WCHAR wchInterfaceName[MAX_INTERFACE_NAME_LEN+1];
  1825. //
  1826. // Get handle to the INTERFACES parameters key
  1827. //
  1828. if ( dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1829. DIM_KEYPATH_INTERFACES,
  1830. 0,
  1831. KEY_READ,
  1832. &hKey ))
  1833. {
  1834. pChar = DIM_KEYPATH_INTERFACES;
  1835. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  1836. return( NO_ERROR );
  1837. }
  1838. //
  1839. // Find out the number of Interfaces
  1840. //
  1841. dwRetCode = GetKeyMax( hKey,
  1842. &cbMaxValNameSize,
  1843. &cNumValues,
  1844. &cbMaxValueDataSize,
  1845. &cNumSubKeys );
  1846. if ( dwRetCode != NO_ERROR )
  1847. {
  1848. RegCloseKey( hKey );
  1849. pChar = DIM_KEYPATH_INTERFACES;
  1850. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  1851. return( dwRetCode );
  1852. }
  1853. //
  1854. // For each interface
  1855. //
  1856. for ( dwKeyIndex = 0; dwKeyIndex < cNumSubKeys; dwKeyIndex++ )
  1857. {
  1858. cbSubKeyName = sizeof( wchInterfaceKeyName )/sizeof(WCHAR);
  1859. dwRetCode = RegEnumKeyEx(
  1860. hKey,
  1861. dwKeyIndex,
  1862. wchInterfaceKeyName,
  1863. &cbSubKeyName,
  1864. NULL,
  1865. NULL,
  1866. NULL,
  1867. &LastWrite
  1868. );
  1869. if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != ERROR_MORE_DATA ) )
  1870. {
  1871. pChar = DIM_KEYPATH_INTERFACES;
  1872. DIMLogError(ROUTERLOG_CANT_ENUM_SUBKEYS, 1, &pChar, dwRetCode);
  1873. break;
  1874. }
  1875. dwRetCode = RegOpenKeyEx( hKey,
  1876. wchInterfaceKeyName,
  1877. 0,
  1878. KEY_READ,
  1879. &hKeyInterface );
  1880. if ( dwRetCode != NO_ERROR )
  1881. {
  1882. pChar = wchInterfaceKeyName;
  1883. DIMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &pChar, dwRetCode );
  1884. break;
  1885. }
  1886. //
  1887. // Get the interface name value
  1888. //
  1889. cbValueBuf = sizeof( wchInterfaceName );
  1890. dwRetCode = RegQueryValueEx(
  1891. hKeyInterface,
  1892. DIM_VALNAME_INTERFACE_NAME,
  1893. NULL,
  1894. &dwType,
  1895. (LPBYTE)wchInterfaceName,
  1896. &cbValueBuf
  1897. );
  1898. if ( ( dwRetCode != NO_ERROR ) || ( dwType != REG_SZ ) )
  1899. {
  1900. pChar = DIM_VALNAME_INTERFACE_NAME;
  1901. DIMLogError(ROUTERLOG_CANT_QUERY_VALUE, 1, &pChar, dwRetCode);
  1902. pChar = wchInterfaceKeyName;
  1903. DIMLogErrorString(ROUTERLOG_COULDNT_LOAD_IF,1,
  1904. &pChar,dwRetCode,1);
  1905. RegCloseKey( hKeyInterface );
  1906. dwRetCode = NO_ERROR;
  1907. continue;
  1908. }
  1909. //
  1910. // If we are looking for a specific interface
  1911. //
  1912. if ( lpwsInterfaceName != NULL )
  1913. {
  1914. //
  1915. // If this is not the one then we continue looking
  1916. //
  1917. if ( _wcsicmp( lpwsInterfaceName, wchInterfaceName ) != 0 )
  1918. {
  1919. RegCloseKey( hKeyInterface );
  1920. continue;
  1921. }
  1922. }
  1923. EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
  1924. pIfObject = IfObjectGetPointerByName( wchInterfaceName, FALSE );
  1925. if ( pIfObject == NULL )
  1926. {
  1927. LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
  1928. pChar = wchInterfaceName;
  1929. DIMLogErrorString( ROUTERLOG_COULDNT_LOAD_IF, 1,
  1930. &pChar, ERROR_NO_SUCH_INTERFACE, 1 );
  1931. RegCloseKey( hKeyInterface );
  1932. continue;
  1933. }
  1934. dwRetCode = AddInterfaceToRouterManagers( hKeyInterface,
  1935. wchInterfaceName,
  1936. pIfObject,
  1937. dwTransportId );
  1938. LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
  1939. if ( dwRetCode != NO_ERROR )
  1940. {
  1941. pChar = wchInterfaceName;
  1942. DIMLogErrorString( ROUTERLOG_COULDNT_LOAD_IF,1, &pChar,dwRetCode,1);
  1943. dwRetCode = NO_ERROR;
  1944. }
  1945. RegCloseKey( hKeyInterface );
  1946. //
  1947. // If we are looking for a specific interface
  1948. //
  1949. if ( lpwsInterfaceName != NULL )
  1950. {
  1951. //
  1952. // If this was the one then we are done
  1953. //
  1954. if ( _wcsicmp( lpwsInterfaceName, wchInterfaceName ) == 0 )
  1955. {
  1956. break;
  1957. }
  1958. }
  1959. }
  1960. RegCloseKey( hKey );
  1961. return( dwRetCode );
  1962. }