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.

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