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.

807 lines
18 KiB

  1. /*
  2. File routerdb.c
  3. Implements a database abstraction for accessing router interfaces.
  4. If any caching/transactioning/commit-noncommit-moding is done, it
  5. should be implemented here with the api's remaining constant.
  6. */
  7. #include "precomp.h"
  8. EXTERN_C
  9. HRESULT APIENTRY HrRenameConnection(const GUID* guidId, PCWSTR pszNewName);
  10. typedef
  11. DWORD
  12. (WINAPI *PRasValidateEntryName)(
  13. LPWSTR lpszPhonebook, // pointer to full path and filename of phone-book file
  14. LPWSTR lpszEntry // pointer to the entry name to validate
  15. );
  16. typedef struct _RTR_IF_LIST
  17. {
  18. WCHAR pszName[MAX_INTERFACE_NAME_LEN + 1];
  19. struct _RTR_IF_LIST* pNext;
  20. } RTR_IF_LIST;
  21. //
  22. // Callback for RtrdbInterfaceEnumerate that adds the interface
  23. // to a list if the interface is type wan.
  24. //
  25. DWORD
  26. RtrdbAddWanIfToList(
  27. IN PWCHAR pwszIfName,
  28. IN DWORD dwLevel,
  29. IN DWORD dwFormat,
  30. IN PVOID pvData,
  31. IN HANDLE hData)
  32. {
  33. MPR_INTERFACE_0* pIf0 = (MPR_INTERFACE_0*)pvData;
  34. RTR_IF_LIST** ppList = (RTR_IF_LIST**)hData;
  35. RTR_IF_LIST* pNode = NULL;
  36. DWORD dwErr = NO_ERROR, dwSize;
  37. do
  38. {
  39. // See if the interface type is right
  40. //
  41. if (pIf0->dwIfType == ROUTER_IF_TYPE_FULL_ROUTER)
  42. {
  43. // Initialize a new node for the list
  44. //
  45. pNode = (RTR_IF_LIST*)
  46. IfutlAlloc(sizeof(RTR_IF_LIST), TRUE);
  47. if (pNode == NULL)
  48. {
  49. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  50. break;
  51. }
  52. dwSize = sizeof(pNode->pszName);
  53. dwErr = GetIfNameFromFriendlyName(
  54. pwszIfName,
  55. pNode->pszName,
  56. &dwSize);
  57. BREAK_ON_DWERR(dwErr);
  58. // Add the interface to the list
  59. //
  60. pNode->pNext = *ppList;
  61. *ppList = pNode;
  62. }
  63. } while (FALSE);
  64. // Cleanup
  65. {
  66. if (dwErr != NO_ERROR)
  67. {
  68. IfutlFree(pNode);
  69. }
  70. }
  71. return dwErr;
  72. }
  73. DWORD
  74. RtrdbValidatePhoneBookEntry(
  75. PWSTR pwszInterfaceName
  76. )
  77. {
  78. HMODULE hRasApi32;
  79. PRasValidateEntryName pfnRasValidateEntryName;
  80. DWORD dwErr;
  81. WCHAR rgwcPath[MAX_PATH+1];
  82. //
  83. // get phone book path + file name
  84. //
  85. if(g_pwszRouter is NULL)
  86. {
  87. dwErr =
  88. ExpandEnvironmentStringsW(LOCAL_ROUTER_PB_PATHW,
  89. rgwcPath,
  90. sizeof(rgwcPath)/sizeof(rgwcPath[0]));
  91. }
  92. else
  93. {
  94. dwErr = wsprintfW(rgwcPath,
  95. REMOTE_ROUTER_PB_PATHW,
  96. g_pwszRouter);
  97. }
  98. ASSERT(dwErr > 0);
  99. //
  100. // Load RASAPI32 DLL and call into it to verify specified
  101. // phone book entry
  102. //
  103. hRasApi32 = LoadLibraryW(L"RASAPI32.DLL");
  104. if(hRasApi32 isnot NULL)
  105. {
  106. pfnRasValidateEntryName =
  107. (PRasValidateEntryName) GetProcAddress(hRasApi32,
  108. "RasValidateEntryNameW");
  109. if(pfnRasValidateEntryName isnot NULL )
  110. {
  111. dwErr = pfnRasValidateEntryName(rgwcPath,
  112. pwszInterfaceName);
  113. if(dwErr is NO_ERROR)
  114. {
  115. dwErr = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
  116. }
  117. else
  118. {
  119. if(dwErr is ERROR_ALREADY_EXISTS)
  120. {
  121. dwErr = NO_ERROR;
  122. }
  123. }
  124. }
  125. else
  126. {
  127. dwErr = GetLastError ();
  128. }
  129. FreeLibrary(hRasApi32);
  130. }
  131. else
  132. {
  133. dwErr = GetLastError();
  134. }
  135. return dwErr;
  136. }
  137. DWORD
  138. RtrInterfaceCreate(
  139. PMPR_INTERFACE_0 pIfInfo
  140. )
  141. {
  142. DWORD dwErr;
  143. HANDLE hIfCfg, hIfAdmin;
  144. dwErr = MprConfigInterfaceCreate(g_hMprConfig,
  145. 0,
  146. (PBYTE)pIfInfo,
  147. &hIfCfg);
  148. if(dwErr isnot NO_ERROR)
  149. {
  150. DisplayError(g_hModule,
  151. dwErr);
  152. return dwErr;
  153. }
  154. //
  155. // if router service is running add the interface
  156. // to it too.
  157. //
  158. if(IfutlIsRouterRunning())
  159. {
  160. dwErr = MprAdminInterfaceCreate(g_hMprAdmin,
  161. 0,
  162. (PBYTE)pIfInfo,
  163. &hIfAdmin);
  164. if(dwErr isnot NO_ERROR)
  165. {
  166. DisplayError(g_hModule,
  167. dwErr);
  168. return dwErr;
  169. }
  170. }
  171. return NO_ERROR;
  172. }
  173. DWORD
  174. RtrdbInterfaceAdd(
  175. IN PWCHAR pszInterface,
  176. IN DWORD dwLevel,
  177. IN PVOID pvInfo
  178. )
  179. /*++
  180. Routine Description:
  181. Adds an interface to the router
  182. Arguments:
  183. pIfInfo - Info for adding the interface
  184. Return Value:
  185. NO_ERROR
  186. --*/
  187. {
  188. DWORD dwErr;
  189. HANDLE hIfAdmin, hIfCfg;
  190. GUID Guid;
  191. MPR_INTERFACE_0* pIfInfo = (MPR_INTERFACE_0*)pvInfo;
  192. //
  193. // If an interface with this name exists, bug out
  194. //
  195. if(pIfInfo->dwIfType is ROUTER_IF_TYPE_FULL_ROUTER)
  196. {
  197. //
  198. // to create an interface we need a phone book entry
  199. // for it.
  200. //
  201. dwErr = RtrdbValidatePhoneBookEntry(pIfInfo->wszInterfaceName);
  202. if(dwErr isnot NO_ERROR)
  203. {
  204. DisplayMessage(g_hModule,
  205. EMSG_NO_PHONEBOOK,
  206. pIfInfo->wszInterfaceName);
  207. return dwErr;
  208. }
  209. }
  210. else
  211. {
  212. DisplayMessage(g_hModule,
  213. EMSG_BAD_IF_TYPE,
  214. pIfInfo->dwIfType);
  215. return ERROR_INVALID_PARAMETER;
  216. }
  217. //
  218. // create interface with defaults
  219. //
  220. pIfInfo->hInterface = INVALID_HANDLE_VALUE;
  221. dwErr = RtrInterfaceCreate(pIfInfo);
  222. if(dwErr isnot NO_ERROR)
  223. {
  224. DisplayMessage(g_hModule,
  225. EMSG_CANT_CREATE_IF,
  226. pIfInfo->wszInterfaceName,
  227. dwErr);
  228. }
  229. return dwErr;
  230. }
  231. DWORD
  232. RtrdbInterfaceDelete(
  233. IN PWCHAR pwszIfName
  234. )
  235. {
  236. DWORD dwErr, dwSize, dwIfType;
  237. HANDLE hIfCfg, hIfAdmin;
  238. GUID Guid;
  239. PMPR_INTERFACE_0 pIfInfo;
  240. do
  241. {
  242. dwErr = MprConfigInterfaceGetHandle(g_hMprConfig,
  243. pwszIfName,
  244. &hIfCfg);
  245. if(dwErr isnot NO_ERROR)
  246. {
  247. break;
  248. }
  249. dwErr = MprConfigInterfaceGetInfo(g_hMprConfig,
  250. hIfCfg,
  251. 0,
  252. (PBYTE *)&pIfInfo,
  253. &dwSize);
  254. if(dwErr isnot NO_ERROR)
  255. {
  256. break;
  257. }
  258. if(pIfInfo->dwIfType isnot ROUTER_IF_TYPE_FULL_ROUTER)
  259. {
  260. MprConfigBufferFree(pIfInfo);
  261. dwErr = ERROR_INVALID_PARAMETER;
  262. break;
  263. }
  264. if(IfutlIsRouterRunning())
  265. {
  266. dwErr = MprAdminInterfaceGetHandle(g_hMprAdmin,
  267. pwszIfName,
  268. &hIfAdmin,
  269. FALSE);
  270. if(dwErr isnot NO_ERROR)
  271. {
  272. break;
  273. }
  274. dwErr = MprAdminInterfaceDelete(g_hMprAdmin,
  275. hIfAdmin);
  276. if(dwErr isnot NO_ERROR)
  277. {
  278. break;
  279. }
  280. }
  281. dwIfType = pIfInfo->dwIfType;
  282. dwErr = MprConfigInterfaceDelete(g_hMprConfig,
  283. hIfCfg);
  284. MprConfigBufferFree(pIfInfo);
  285. if(dwErr isnot NO_ERROR)
  286. {
  287. break;
  288. }
  289. }while(FALSE);
  290. return dwErr;
  291. }
  292. DWORD
  293. RtrdbInterfaceEnumerate(
  294. IN DWORD dwLevel,
  295. IN DWORD dwFormat,
  296. IN RTR_IF_ENUM_FUNC pEnum,
  297. IN HANDLE hData
  298. )
  299. {
  300. DWORD dwErr, i, dwCount, dwTotal, dwResume, dwPrefBufSize;
  301. MPR_INTERFACE_0* pCurIf = NULL;
  302. LPBYTE pbBuffer = NULL;
  303. BOOL bRouter, bContinue;
  304. // Validate / Initiazlize
  305. if (pEnum == NULL)
  306. {
  307. return ERROR_INVALID_PARAMETER;
  308. }
  309. dwPrefBufSize = sizeof(MPR_INTERFACE_0) * 100;
  310. bRouter = IfutlIsRouterRunning();
  311. dwResume = 0;
  312. do
  313. {
  314. // Enumerate the first n interfaces
  315. //
  316. if (bRouter)
  317. {
  318. dwErr = MprAdminInterfaceEnum(
  319. g_hMprAdmin,
  320. 0,
  321. &pbBuffer,
  322. dwPrefBufSize,
  323. &dwCount,
  324. &dwTotal,
  325. &dwResume);
  326. }
  327. else
  328. {
  329. dwErr = MprConfigInterfaceEnum(
  330. g_hMprConfig,
  331. 0,
  332. &pbBuffer,
  333. dwPrefBufSize,
  334. &dwCount,
  335. &dwTotal,
  336. &dwResume);
  337. }
  338. if (dwErr == ERROR_MORE_DATA)
  339. {
  340. dwErr = NO_ERROR;
  341. bContinue = TRUE;
  342. }
  343. else
  344. {
  345. bContinue = FALSE;
  346. }
  347. if (dwErr != NO_ERROR)
  348. {
  349. break;
  350. }
  351. // Call the callback for each interface as long
  352. // as we're instructed to continue
  353. pCurIf = (MPR_INTERFACE_0*)pbBuffer;
  354. for (i = 0; (i < dwCount) && (dwErr == NO_ERROR); i++)
  355. {
  356. dwErr = (*pEnum)(
  357. pCurIf->wszInterfaceName,
  358. dwLevel,
  359. dwFormat,
  360. (PVOID)pCurIf,
  361. hData);
  362. pCurIf++;
  363. }
  364. if (dwErr != NO_ERROR)
  365. {
  366. break;
  367. }
  368. // Free up the interface list buffer
  369. if (pbBuffer)
  370. {
  371. if (bRouter)
  372. {
  373. MprAdminBufferFree(pbBuffer);
  374. }
  375. else
  376. {
  377. MprConfigBufferFree(pbBuffer);
  378. }
  379. pbBuffer = NULL;
  380. }
  381. // Keep this loop going until there are
  382. // no more interfaces
  383. //
  384. } while (bContinue);
  385. // Cleanup
  386. {
  387. }
  388. return dwErr;
  389. }
  390. DWORD
  391. RtrdbInterfaceRead(
  392. IN PWCHAR pwszIfName,
  393. IN DWORD dwLevel,
  394. IN PVOID pvInfo
  395. )
  396. {
  397. DWORD dwErr, dwSize;
  398. HANDLE hIfCfg, hIfAdmin;
  399. PMPR_INTERFACE_0 pInfo = NULL;
  400. do
  401. {
  402. if(IfutlIsRouterRunning())
  403. {
  404. dwErr = MprAdminInterfaceGetHandle(g_hMprAdmin,
  405. pwszIfName,
  406. &hIfAdmin,
  407. FALSE);
  408. if(dwErr isnot NO_ERROR)
  409. {
  410. break;
  411. }
  412. dwErr = MprAdminInterfaceGetInfo(g_hMprAdmin,
  413. hIfAdmin,
  414. 0,
  415. (PBYTE *)&pInfo);
  416. if(dwErr isnot NO_ERROR)
  417. {
  418. break;
  419. }
  420. if (pInfo == NULL)
  421. {
  422. dwErr = ERROR_CAN_NOT_COMPLETE;
  423. break;
  424. }
  425. *((MPR_INTERFACE_0*)pvInfo) = *pInfo;
  426. MprAdminBufferFree(pInfo);
  427. }
  428. else
  429. {
  430. dwErr = MprConfigInterfaceGetHandle(g_hMprConfig,
  431. pwszIfName,
  432. &hIfCfg);
  433. if(dwErr isnot NO_ERROR)
  434. {
  435. break;
  436. }
  437. dwErr = MprConfigInterfaceGetInfo(g_hMprConfig,
  438. hIfCfg,
  439. 0,
  440. (PBYTE *)&pInfo,
  441. &dwSize);
  442. if(dwErr isnot NO_ERROR)
  443. {
  444. break;
  445. }
  446. *((MPR_INTERFACE_0*)pvInfo) = *pInfo;
  447. MprConfigBufferFree(pInfo);
  448. }
  449. } while(FALSE);
  450. return dwErr;
  451. }
  452. DWORD
  453. RtrdbInterfaceWrite(
  454. IN PWCHAR pwszIfName,
  455. IN DWORD dwLevel,
  456. IN PVOID pvInfo
  457. )
  458. {
  459. DWORD dwErr;
  460. HANDLE hIfCfg = NULL;
  461. MPR_INTERFACE_0* pIfInfo = (MPR_INTERFACE_0*)pvInfo;
  462. do
  463. {
  464. if(IfutlIsRouterRunning())
  465. {
  466. dwErr = MprAdminInterfaceSetInfo(g_hMprAdmin,
  467. pIfInfo->hInterface,
  468. 0,
  469. (BYTE*)pIfInfo);
  470. if(dwErr isnot NO_ERROR)
  471. {
  472. break;
  473. }
  474. dwErr = MprConfigInterfaceGetHandle(g_hMprConfig,
  475. pIfInfo->wszInterfaceName,
  476. &hIfCfg);
  477. if(dwErr isnot NO_ERROR)
  478. {
  479. break;
  480. }
  481. dwErr = MprConfigInterfaceSetInfo(g_hMprConfig,
  482. hIfCfg,
  483. 0,
  484. (BYTE*)pIfInfo);
  485. if(dwErr isnot NO_ERROR)
  486. {
  487. break;
  488. }
  489. }
  490. else
  491. {
  492. dwErr = MprConfigInterfaceSetInfo(g_hMprConfig,
  493. pIfInfo->hInterface,
  494. 0,
  495. (BYTE*)pIfInfo);
  496. if(dwErr isnot NO_ERROR)
  497. {
  498. break;
  499. }
  500. }
  501. } while(FALSE);
  502. return dwErr;
  503. }
  504. DWORD
  505. RtrdbInterfaceReadCredentials(
  506. IN PWCHAR pszIfName,
  507. IN PWCHAR pszUser OPTIONAL,
  508. IN PWCHAR pszPassword OPTIONAL,
  509. IN PWCHAR pszDomain OPTIONAL
  510. )
  511. {
  512. MPR_INTERFACE_0 If0;
  513. DWORD dwErr = NO_ERROR;
  514. do
  515. {
  516. ZeroMemory(&If0, sizeof(If0));
  517. dwErr = RtrdbInterfaceRead(
  518. pszIfName,
  519. 0,
  520. (PVOID)&If0);
  521. BREAK_ON_DWERR(dwErr);
  522. if (If0.dwIfType != ROUTER_IF_TYPE_FULL_ROUTER)
  523. {
  524. DisplayError(g_hModule, EMSG_IF_BAD_CREDENTIALS_TYPE);
  525. dwErr = ERROR_CAN_NOT_COMPLETE;
  526. break;
  527. }
  528. // Set the credentials
  529. //
  530. if (pszUser)
  531. {
  532. pszUser[0] = L'\0';
  533. }
  534. if (pszDomain)
  535. {
  536. pszDomain[0] = L'\0';
  537. }
  538. if (pszPassword)
  539. {
  540. pszPassword[0] = L'\0';
  541. }
  542. dwErr = MprAdminInterfaceGetCredentials(
  543. g_pwszRouter,
  544. pszIfName,
  545. pszUser,
  546. NULL,
  547. pszDomain);
  548. BREAK_ON_DWERR(dwErr);
  549. if (pszPassword)
  550. {
  551. wcscpy(pszPassword, L"**********");
  552. }
  553. } while (FALSE);
  554. // Cleanup
  555. {
  556. }
  557. return dwErr;
  558. }
  559. DWORD
  560. RtrdbInterfaceWriteCredentials(
  561. IN PWCHAR pszIfName,
  562. IN PWCHAR pszUser OPTIONAL,
  563. IN PWCHAR pszPassword OPTIONAL,
  564. IN PWCHAR pszDomain OPTIONAL
  565. )
  566. {
  567. MPR_INTERFACE_0 If0;
  568. DWORD dwErr = NO_ERROR;
  569. do
  570. {
  571. ZeroMemory(&If0, sizeof(If0));
  572. dwErr = RtrdbInterfaceRead(
  573. pszIfName,
  574. 0,
  575. (PVOID)&If0);
  576. BREAK_ON_DWERR(dwErr);
  577. if (If0.dwIfType != ROUTER_IF_TYPE_FULL_ROUTER)
  578. {
  579. DisplayError(g_hModule, EMSG_IF_BAD_CREDENTIALS_TYPE);
  580. dwErr = ERROR_CAN_NOT_COMPLETE;
  581. break;
  582. }
  583. // Set the credentials
  584. //
  585. dwErr = MprAdminInterfaceSetCredentials(
  586. g_pwszRouter,
  587. pszIfName,
  588. pszUser,
  589. pszDomain,
  590. pszPassword);
  591. BREAK_ON_DWERR(dwErr);
  592. } while (FALSE);
  593. // Cleanup
  594. {
  595. }
  596. return dwErr;
  597. }
  598. DWORD
  599. RtrdbInterfaceRename(
  600. IN PWCHAR pwszIfName,
  601. IN DWORD dwLevel,
  602. IN PVOID pvInfo,
  603. IN PWCHAR pszNewName)
  604. {
  605. DWORD dwErr = NO_ERROR;
  606. HRESULT hr = S_OK;
  607. NTSTATUS ntStatus = STATUS_SUCCESS;
  608. UNICODE_STRING us;
  609. GUID Guid;
  610. do
  611. {
  612. // Get the guid from the interface name
  613. //
  614. RtlInitUnicodeString(&us, pwszIfName);
  615. ntStatus = RtlGUIDFromString(&us, &Guid);
  616. if (ntStatus != STATUS_SUCCESS)
  617. {
  618. dwErr = ERROR_BAD_FORMAT;
  619. break;
  620. }
  621. // Rename the interface
  622. //
  623. hr = HrRenameConnection(&Guid, pszNewName);
  624. if (FAILED(hr))
  625. {
  626. dwErr = HRESULT_CODE(hr);
  627. break;
  628. }
  629. } while (FALSE);
  630. // Cleanup
  631. //
  632. {
  633. }
  634. return dwErr;
  635. }
  636. DWORD
  637. RtrdbResetAll()
  638. {
  639. RTR_IF_LIST* pList = NULL, *pCur = NULL;
  640. DWORD dwErr = NO_ERROR;
  641. do
  642. {
  643. // Build a list of interfaces that can be
  644. // deleted
  645. //
  646. dwErr = RtrdbInterfaceEnumerate(
  647. 0,
  648. 0,
  649. RtrdbAddWanIfToList,
  650. (HANDLE)&pList);
  651. BREAK_ON_DWERR(dwErr);
  652. // Delete all of the interfaces
  653. //
  654. pCur = pList;
  655. while (pCur)
  656. {
  657. RtrdbInterfaceDelete(pCur->pszName);
  658. pCur = pCur->pNext;
  659. IfutlFree(pList);
  660. pList = pCur;
  661. }
  662. } while (FALSE);
  663. // Cleanup
  664. {
  665. }
  666. return NO_ERROR;
  667. }