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.

1222 lines
30 KiB

  1. /*
  2. File: rpbk.c
  3. Implementation of api's that populate the router phonebook
  4. portions of MPR intformation structures.
  5. Paul Mayfield, 11/2/98
  6. The following describes the mapping from ras entry to
  7. router entry.
  8. // The following RAS options are not supported. They will always
  9. // be cleared if set.
  10. //
  11. RASEO_UseCountryAndAreaCodes
  12. RASEO_TerminalBeforeDial
  13. RASEO_TerminalAfterDial
  14. RASEO_ModemLights
  15. RASEO_UseLogonCredentials
  16. RASEO_Custom
  17. RASEO_PreviewPhoneNumber
  18. RASEO_PreviewUserPw
  19. RASEO_PreviewDomain
  20. RASEO_ShowDialingProgress
  21. // The following ras types are not supported.
  22. //
  23. RASET_Internet // Reset to MPRET_Phone if set
  24. // The following protocol setting is not supported
  25. //
  26. RASNP_NetBEUI // Always exclude
  27. //
  28. // RASENTRY Conversion
  29. //
  30. Items deleted:
  31. DWORD dwSize; // version is MPR_INTERFACE_2
  32. WCHAR szScript[ MAX_PATH ]; // Set to ""
  33. DWORD dwReserved1; // Set to 0
  34. DWORD dwReserved2; // Set to 0
  35. WCHAR szAutodialDll[...]; // Set to ""
  36. WCHAR szAutodialFunc[...]; // Set to ""
  37. WCHAR szCustomDialDll[MAX_PATH]; // Set to ""
  38. DWORD dwFramingProtocol; // Set to PPP
  39. DWORD dwCountryID; // Set to 0
  40. DWORD dwCountryCode; // Set to 0
  41. WCHAR szAreaCode[ RAS_MaxAreaCode + 1 ]; // Set to ""
  42. DWORD dwFrameSize
  43. Items modified:
  44. DWORD dwAlternateOffset to PWCHAR pszAlternates
  45. RASIPADDR ipaddr to DWORD
  46. RASIPADDR ipaddrDns to DWORD
  47. RASIPADDR ipaddrDnsAlt to DWORD
  48. RASIPADDR ipaddrWins to DWORD
  49. RASIPADDR ipaddrWinsAlt to DWORD
  50. //
  51. // RASSUBENTRY Conversion
  52. //
  53. Items deleted:
  54. DWORD dwSize; // version is MPR_INTERFACE_DEVICE_0
  55. DWORD dwfFlags; // unused anyway
  56. Items modified:
  57. DWORD dwAlternateOffset to PWCHAR pszAlternates
  58. */
  59. #include "dimsvcp.h"
  60. #include <ras.h>
  61. #include <dimsvc.h> // Generated by MIDL
  62. #include <mprapi.h>
  63. #include <mprapip.h>
  64. #include "rpbk.h"
  65. //
  66. // Definitions
  67. //
  68. #define MPRIO_UnsupportedOptions \
  69. ( \
  70. RASEO_UseCountryAndAreaCodes | \
  71. RASEO_TerminalBeforeDial | \
  72. RASEO_TerminalAfterDial | \
  73. RASEO_ModemLights | \
  74. RASEO_UseLogonCredentials | \
  75. RASEO_Custom | \
  76. RASEO_PreviewPhoneNumber | \
  77. RASEO_PreviewUserPw | \
  78. RASEO_PreviewDomain | \
  79. RASEO_ShowDialingProgress \
  80. )
  81. //
  82. // Strings
  83. //
  84. static const WCHAR pszRouterPbkFmt[] = L"\\ras\\Router.pbk";
  85. //
  86. // Structure tracks router entry information
  87. //
  88. typedef struct _RPBK_ENTRY_INFO
  89. {
  90. PWCHAR pszPhonebookPath;
  91. DWORD dwEntrySize;
  92. LPRASENTRY pRasEntry;
  93. DWORD dwCustAuthDataSize;
  94. LPBYTE lpbCustAuthData;
  95. } RPBK_ENTRY_INFO;
  96. //
  97. // Structure tracks sub entry information
  98. //
  99. typedef struct _RPBK_SUBENTRY_INFO
  100. {
  101. PWCHAR pszPhonebookPath;
  102. LPRASSUBENTRY pRasSubEntry;
  103. DWORD dwSize;
  104. } RPBK_SUBENTRY_INFO;
  105. //
  106. // Common allocation
  107. //
  108. PVOID
  109. RpbkAlloc(
  110. IN DWORD dwBytes,
  111. IN BOOL bZero)
  112. {
  113. return LOCAL_ALLOC( (bZero) ? HEAP_ZERO_MEMORY : 0, dwBytes );
  114. }
  115. //
  116. // Common free
  117. //
  118. VOID
  119. RpbkFree(
  120. IN PVOID pvData)
  121. {
  122. LOCAL_FREE( pvData );
  123. }
  124. //
  125. // Cleans up the entry info blob
  126. //
  127. VOID
  128. RpbkFreeEntryInfo(
  129. IN RPBK_ENTRY_INFO * pInfo)
  130. {
  131. if (pInfo)
  132. {
  133. if (pInfo->pszPhonebookPath)
  134. {
  135. RpbkFreePhonebookPath(pInfo->pszPhonebookPath);
  136. }
  137. if (pInfo->pRasEntry)
  138. {
  139. RpbkFree(pInfo->pRasEntry);
  140. }
  141. if (pInfo->lpbCustAuthData)
  142. {
  143. RpbkFree(pInfo->lpbCustAuthData);
  144. }
  145. RpbkFree(pInfo);
  146. }
  147. }
  148. //
  149. // Cleans up the sub entry info blob
  150. //
  151. VOID
  152. RpbkFreeSubEntryInfo(
  153. IN RPBK_SUBENTRY_INFO * pInfo)
  154. {
  155. if (pInfo)
  156. {
  157. if (pInfo->pszPhonebookPath)
  158. {
  159. RpbkFree(pInfo->pszPhonebookPath);
  160. }
  161. if (pInfo->pRasSubEntry)
  162. {
  163. RpbkFree(pInfo->pRasSubEntry);
  164. }
  165. RpbkFree(pInfo);
  166. }
  167. }
  168. //
  169. // Returns a heap-allocated copy of the path to the router
  170. // phonebook
  171. //
  172. DWORD
  173. RpbkGetPhonebookPath(
  174. OUT PWCHAR* ppszPath)
  175. {
  176. WCHAR pszSystemPath[MAX_PATH];
  177. UINT uiLength = sizeof(pszSystemPath) / sizeof(WCHAR);
  178. DWORD dwRetSize = 0;
  179. PWCHAR pszRet = NULL;
  180. // Find the system directory
  181. //
  182. uiLength = GetSystemDirectoryW(pszSystemPath, uiLength);
  183. if (uiLength == 0)
  184. {
  185. return ERROR_NOT_ENOUGH_MEMORY;
  186. }
  187. // Allocate the return buffer
  188. //
  189. dwRetSize = ((uiLength + 1) * sizeof(WCHAR)) + sizeof(pszRouterPbkFmt);
  190. pszRet = (PWCHAR) RpbkAlloc(dwRetSize, FALSE);
  191. if (pszRet == NULL)
  192. {
  193. return ERROR_NOT_ENOUGH_MEMORY;
  194. }
  195. // Format the string
  196. //
  197. wcscpy(pszRet, pszSystemPath);
  198. wcscpy(pszRet + uiLength, pszRouterPbkFmt);
  199. *ppszPath = pszRet;
  200. return NO_ERROR;
  201. }
  202. //
  203. // Cleans up after RpbkGetPhonebookPath
  204. //
  205. DWORD
  206. RpbkFreePhonebookPath(
  207. IN PWCHAR pszPath)
  208. {
  209. if ( pszPath )
  210. {
  211. RpbkFree(pszPath);
  212. }
  213. return NO_ERROR;
  214. }
  215. //
  216. // Returns size in bytes of a multisz.
  217. //
  218. DWORD
  219. RpbkGetMultiSzSize(
  220. IN LPWSTR lpwsMultSz
  221. )
  222. {
  223. LPWSTR lpwsPtr = lpwsMultSz;
  224. DWORD dwcbAlternates = 0;
  225. DWORD dwCurCount;
  226. if ( lpwsMultSz == NULL )
  227. {
  228. return( 0 );
  229. }
  230. while( *lpwsPtr != L'\0' )
  231. {
  232. dwCurCount = ( wcslen( lpwsPtr ) + 1 );
  233. dwcbAlternates += dwCurCount;
  234. lpwsPtr += dwCurCount;
  235. }
  236. //
  237. // One more for the last NULL terminator
  238. //
  239. dwcbAlternates++;
  240. dwcbAlternates *= sizeof( WCHAR );
  241. return( dwcbAlternates );
  242. }
  243. //
  244. // Copies a multi sz
  245. //
  246. DWORD
  247. RpbkCopyMultiSz(
  248. IN LPWSTR lpwsDst,
  249. IN LPWSTR lpwsSrc)
  250. {
  251. if (!lpwsDst || !lpwsSrc)
  252. {
  253. return ERROR_INVALID_PARAMETER;
  254. }
  255. while (lpwsSrc[0] || lpwsSrc[1])
  256. {
  257. *lpwsDst = *lpwsSrc;
  258. lpwsDst++;
  259. lpwsSrc++;
  260. }
  261. lpwsDst[0] = (WCHAR)0;
  262. lpwsDst[1] = (WCHAR)0;
  263. return NO_ERROR;
  264. }
  265. //
  266. // Removes any unsupported options from the interface data
  267. // provided.
  268. //
  269. DWORD
  270. RpbkConformIfData(
  271. IN DWORD dwLevel,
  272. IN LPBYTE pInterfaceData)
  273. {
  274. MPR_INTERFACE_2* pIf2 = (MPR_INTERFACE_2*)pInterfaceData;
  275. // Clear the unsupported options
  276. //
  277. pIf2->dwfOptions &= ~MPRIO_UnsupportedOptions;
  278. // Make sure that netbios doesn't get reported
  279. //
  280. pIf2->dwfNetProtocols &= ~RASNP_NetBEUI;
  281. // Make sure that the type is not internet
  282. //
  283. if (pIf2->dwType == RASET_Internet)
  284. {
  285. pIf2->dwType = RASET_Phone;
  286. }
  287. return NO_ERROR;
  288. }
  289. //
  290. // Removes any unsupported options from the router entry
  291. // provided.
  292. //
  293. DWORD
  294. RpbkConformEntry(
  295. IN LPRASENTRY pEntry)
  296. {
  297. // Clear the unsupported options
  298. //
  299. pEntry->dwfOptions &= ~MPRIO_UnsupportedOptions;
  300. // Make sure that netbios is not enabled
  301. //
  302. pEntry->dwfNetProtocols &= ~RASNP_NetBEUI;
  303. // Make sure that the type is not internet
  304. //
  305. if (pEntry->dwType == RASET_Internet)
  306. {
  307. pEntry->dwType = RASET_Phone;
  308. }
  309. // Default all other values of the entry that
  310. // can't be supplied through MPR_INTERFACE_*
  311. // structures.
  312. pEntry->dwSize = sizeof(RASENTRY);
  313. pEntry->dwReserved1 = 0;
  314. pEntry->dwReserved2 = 0;
  315. pEntry->dwFramingProtocol = RASFP_Ppp;
  316. pEntry->dwFrameSize = 0;
  317. pEntry->dwCountryID = 0;
  318. pEntry->dwCountryCode = 0;
  319. pEntry->szScript[0] = L'\0';
  320. pEntry->szAutodialDll[0] = L'\0';
  321. pEntry->szAutodialFunc[0] = L'\0';
  322. pEntry->szCustomDialDll[0] = L'\0';
  323. pEntry->szAreaCode[0] = L'\0';
  324. return NO_ERROR;
  325. }
  326. //
  327. // Reads in the router phonebook entry associated with
  328. // the given interface
  329. //
  330. DWORD
  331. RpbkOpenEntry(
  332. IN ROUTER_INTERFACE_OBJECT* pIfObject,
  333. OUT PHANDLE phEntry )
  334. {
  335. RPBK_ENTRY_INFO * pInfo = NULL;
  336. DWORD dwErr = NO_ERROR, dwSize;
  337. do {
  338. // Initialize
  339. *phEntry = NULL;
  340. // Allocate the control structure
  341. //
  342. pInfo = (RPBK_ENTRY_INFO*) RpbkAlloc(sizeof(RPBK_ENTRY_INFO), TRUE);
  343. if (pInfo == NULL)
  344. {
  345. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  346. break;
  347. }
  348. // Get the phonebook path
  349. //
  350. dwErr = RpbkGetPhonebookPath(&(pInfo->pszPhonebookPath));
  351. if (dwErr != NO_ERROR)
  352. {
  353. break;
  354. }
  355. // Find out how big the ras entry needs to be
  356. //
  357. dwErr = RasGetEntryProperties(
  358. pInfo->pszPhonebookPath,
  359. pIfObject->lpwsInterfaceName,
  360. NULL,
  361. &(pInfo->dwEntrySize),
  362. NULL,
  363. NULL);
  364. if (dwErr != ERROR_BUFFER_TOO_SMALL)
  365. {
  366. break;
  367. }
  368. // Allocate the ras entry structure
  369. //
  370. pInfo->pRasEntry = (LPRASENTRY) RpbkAlloc(pInfo->dwEntrySize, TRUE);
  371. if (pInfo->pRasEntry == NULL)
  372. {
  373. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  374. break;
  375. }
  376. // Read in the ras entry
  377. //
  378. pInfo->pRasEntry->dwSize = sizeof(RASENTRY);
  379. dwErr = RasGetEntryProperties(
  380. pInfo->pszPhonebookPath,
  381. pIfObject->lpwsInterfaceName,
  382. pInfo->pRasEntry,
  383. &(pInfo->dwEntrySize),
  384. NULL,
  385. NULL);
  386. if (dwErr != NO_ERROR)
  387. {
  388. break;
  389. }
  390. // Find out how big the custom auth data needs
  391. // to be
  392. dwErr = RasGetCustomAuthDataW (
  393. pInfo->pszPhonebookPath,
  394. pIfObject->lpwsInterfaceName,
  395. NULL,
  396. &(pInfo->dwCustAuthDataSize));
  397. if ( (dwErr != NO_ERROR) &&
  398. (dwErr != ERROR_BUFFER_TOO_SMALL)
  399. )
  400. {
  401. break;
  402. }
  403. dwErr = NO_ERROR;
  404. if ( pInfo->dwCustAuthDataSize )
  405. {
  406. // Allocate the custom auth data
  407. //
  408. pInfo->lpbCustAuthData =
  409. RpbkAlloc(pInfo->dwCustAuthDataSize, TRUE);
  410. if (pInfo->lpbCustAuthData == NULL)
  411. {
  412. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  413. break;
  414. }
  415. // Read in the ras entry
  416. //
  417. dwErr = RasGetCustomAuthDataW(
  418. pInfo->pszPhonebookPath,
  419. pIfObject->lpwsInterfaceName,
  420. pInfo->lpbCustAuthData,
  421. &(pInfo->dwCustAuthDataSize));
  422. if (dwErr != NO_ERROR)
  423. {
  424. break;
  425. }
  426. }
  427. // Assign the return value
  428. *phEntry = (HANDLE)pInfo;
  429. } while (FALSE);
  430. // Cleanup
  431. {
  432. if (dwErr != NO_ERROR)
  433. {
  434. RpbkFreeEntryInfo(pInfo);
  435. }
  436. }
  437. return dwErr;
  438. }
  439. //
  440. // Cleans up the data returned by RpbkOpen* functions
  441. //
  442. DWORD
  443. RpbkCloseEntry(
  444. IN HANDLE hEntry )
  445. {
  446. RpbkFreeEntryInfo((RPBK_ENTRY_INFO*)hEntry);
  447. return NO_ERROR;
  448. }
  449. //
  450. // Writes out the router phonebook entry based on the
  451. // the given interface
  452. //
  453. DWORD
  454. RpbkSetEntry(
  455. IN DWORD dwLevel,
  456. IN LPBYTE pInterfaceData )
  457. {
  458. MPRI_INTERFACE_2* pIf2 = (MPRI_INTERFACE_2*)pInterfaceData;
  459. LPRASENTRY pEntry = NULL;
  460. PWCHAR pszAlternates = NULL, pszPath = NULL;
  461. DWORD dwErr = NO_ERROR, dwSize;
  462. LPWSTR pszAltSrc = NULL;
  463. // Validate parameters
  464. if (!pIf2)
  465. {
  466. return ERROR_INVALID_PARAMETER;
  467. }
  468. // Allocate the ras entry structure
  469. //
  470. dwSize = sizeof(RASENTRY);
  471. if (pIf2->dwAlternatesOffset)
  472. {
  473. pszAltSrc = (LPWSTR)
  474. ((ULONG_PTR)(pIf2) + (ULONG_PTR)(pIf2->dwAlternatesOffset));
  475. dwSize += RpbkGetMultiSzSize(pszAltSrc);
  476. }
  477. pEntry = RpbkAlloc(dwSize, TRUE);
  478. if (pEntry == NULL)
  479. {
  480. return ERROR_NOT_ENOUGH_MEMORY;
  481. }
  482. // Assign all assignable fields
  483. //
  484. pEntry->dwfOptions = pIf2->dwfOptions;
  485. *((DWORD*)&(pEntry->ipaddr)) = pIf2->ipaddr;
  486. *((DWORD*)&(pEntry->ipaddrDns)) = pIf2->ipaddrDns;
  487. *((DWORD*)&(pEntry->ipaddrDnsAlt)) = pIf2->ipaddrDnsAlt;
  488. *((DWORD*)&(pEntry->ipaddrWins)) = pIf2->ipaddrWins;
  489. *((DWORD*)&(pEntry->ipaddrWinsAlt)) = pIf2->ipaddrWinsAlt;
  490. pEntry->dwfNetProtocols = pIf2->dwfNetProtocols;
  491. pEntry->dwChannels = pIf2->dwChannels;
  492. pEntry->dwSubEntries = pIf2->dwSubEntries;
  493. pEntry->dwDialMode = pIf2->dwDialMode;
  494. pEntry->dwDialExtraPercent = pIf2->dwDialExtraPercent;
  495. pEntry->dwDialExtraSampleSeconds = pIf2->dwDialExtraSampleSeconds;
  496. pEntry->dwHangUpExtraPercent = pIf2->dwHangUpExtraPercent;
  497. pEntry->dwHangUpExtraSampleSeconds = pIf2->dwHangUpExtraSampleSeconds;
  498. pEntry->dwIdleDisconnectSeconds = pIf2->dwIdleDisconnectSeconds;
  499. pEntry->dwType = pIf2->dwType;
  500. pEntry->dwEncryptionType = pIf2->dwEncryptionType;
  501. pEntry->dwCustomAuthKey = pIf2->dwCustomAuthKey;
  502. pEntry->dwVpnStrategy = pIf2->dwVpnStrategy;
  503. pEntry->guidId = pIf2->guidId;
  504. // Copy all copyable fields
  505. //
  506. wcscpy(pEntry->szLocalPhoneNumber, pIf2->szLocalPhoneNumber);
  507. wcscpy(pEntry->szDeviceType, pIf2->szDeviceType);
  508. wcscpy(pEntry->szDeviceName, pIf2->szDeviceName);
  509. wcscpy(pEntry->szX25PadType, pIf2->szX25PadType);
  510. wcscpy(pEntry->szX25Address, pIf2->szX25Address);
  511. wcscpy(pEntry->szX25Facilities, pIf2->szX25Facilities);
  512. wcscpy(pEntry->szX25UserData, pIf2->szX25UserData);
  513. do
  514. {
  515. // Copy the alternates list
  516. //
  517. if (pIf2->dwAlternatesOffset)
  518. {
  519. pEntry->dwAlternateOffset = sizeof(RASENTRY);
  520. pszAlternates = (PWCHAR)
  521. ((ULONG_PTR)(pEntry) +
  522. (ULONG_PTR)(pEntry->dwAlternateOffset));
  523. dwErr = RpbkCopyMultiSz(pszAlternates, pszAltSrc);
  524. if (dwErr != NO_ERROR)
  525. {
  526. break;
  527. }
  528. }
  529. else
  530. {
  531. pEntry->dwAlternateOffset = 0;
  532. }
  533. // Remove any unsupported options that may have made
  534. // it in. (shouldn't be any)
  535. //
  536. dwErr = RpbkConformEntry(pEntry);
  537. if (dwErr != NO_ERROR)
  538. {
  539. break;
  540. }
  541. // Map MPRIO_IpSecPreSharedKey to RASEO_PreSharedKey
  542. //
  543. //
  544. if(pIf2->dwfOptions & MPRIO_IpSecPreSharedKey)
  545. {
  546. pEntry->dwfOptions &= ~(MPRIO_IpSecPreSharedKey);
  547. pEntry->dwfOptions2 |= RASEO2_UsePreSharedKey;
  548. }
  549. // Discover the phonebook path
  550. dwErr = RpbkGetPhonebookPath(&pszPath);
  551. if (dwErr != NO_ERROR)
  552. {
  553. break;
  554. }
  555. // Save the entry
  556. dwErr = RasSetEntryPropertiesW(
  557. pszPath,
  558. pIf2->wszInterfaceName,
  559. pEntry,
  560. dwSize,
  561. NULL,
  562. 0);
  563. if (dwErr != NO_ERROR)
  564. {
  565. break;
  566. }
  567. // Save the custom auth options
  568. //
  569. dwErr = RasSetCustomAuthDataW(
  570. pszPath,
  571. pIf2->wszInterfaceName,
  572. (LPBYTE)(pIf2 + 1),
  573. pIf2->dwCustomAuthDataSize);
  574. if ( dwErr != NO_ERROR )
  575. {
  576. break;
  577. }
  578. } while (FALSE);
  579. // Cleanup
  580. {
  581. if (pEntry)
  582. {
  583. RpbkFree(pEntry);
  584. }
  585. if (pszPath)
  586. {
  587. RpbkFree(pszPath);
  588. }
  589. }
  590. return dwErr;
  591. }
  592. //
  593. // Deletes the given entry from the phonebook
  594. //
  595. DWORD
  596. RpbkDeleteEntry(
  597. IN PWCHAR pszInterfaceName )
  598. {
  599. PWCHAR pszPath = NULL;
  600. DWORD dwErr = NO_ERROR;
  601. do
  602. {
  603. // Get the phonebook path
  604. //
  605. dwErr = RpbkGetPhonebookPath(&pszPath);
  606. if (dwErr != NO_ERROR)
  607. {
  608. break;
  609. }
  610. // Delete the entry
  611. //
  612. dwErr = RasDeleteEntry(pszPath, pszInterfaceName);
  613. if (dwErr != NO_ERROR)
  614. {
  615. break;
  616. }
  617. } while (FALSE);
  618. // Cleanup
  619. {
  620. if ( pszPath )
  621. {
  622. RpbkFree(pszPath);
  623. }
  624. }
  625. return dwErr;
  626. }
  627. //
  628. // Calculates the required size of a buffer to hold interface information
  629. // at the given level based on the given entry or sub entry.
  630. //
  631. DWORD
  632. RpbkEntryToIfDataSize(
  633. IN HANDLE hEntry,
  634. IN DWORD dwLevel,
  635. OUT LPDWORD lpdwcbSizeOfData )
  636. {
  637. RPBK_ENTRY_INFO* pInfo = (RPBK_ENTRY_INFO*)hEntry;
  638. DWORD dwSize;
  639. PWCHAR pszAlternates = NULL;
  640. // Validate parameters
  641. if (!pInfo)
  642. {
  643. return ERROR_INVALID_PARAMETER;
  644. }
  645. // Initialize
  646. *lpdwcbSizeOfData = 0;
  647. // For level 2, the size is the size of the level 2
  648. // structure plus the size of the alternate phone list
  649. if (dwLevel != 2)
  650. {
  651. return ERROR_INVALID_LEVEL;
  652. }
  653. // Initailize the size to the base size
  654. //
  655. dwSize = sizeof(MPR_INTERFACE_2);
  656. // Add on the size of the custom auth data
  657. //
  658. dwSize += pInfo->dwCustAuthDataSize;
  659. // Add on the size of the alternates list
  660. //
  661. if (pInfo->pRasEntry->dwAlternateOffset)
  662. {
  663. pszAlternates = (PWCHAR)
  664. ((ULONG_PTR)(pInfo->pRasEntry) +
  665. (ULONG_PTR)(pInfo->pRasEntry->dwAlternateOffset));
  666. dwSize += RpbkGetMultiSzSize(pszAlternates);
  667. }
  668. // Assign the return value
  669. //
  670. *lpdwcbSizeOfData = dwSize;
  671. return NO_ERROR;
  672. }
  673. //
  674. // Populates the ras portion of the given interface info blob based on the
  675. // level and entry or subentry.
  676. //
  677. DWORD
  678. RpbkEntryToIfData(
  679. IN HANDLE hEntry,
  680. IN DWORD dwLevel,
  681. OUT LPBYTE pInterfaceData )
  682. {
  683. RPBK_ENTRY_INFO* pInfo = (RPBK_ENTRY_INFO*)hEntry;
  684. MPRI_INTERFACE_2* pIf2 = (MPRI_INTERFACE_2*)pInterfaceData;
  685. LPRASENTRY pEntry = NULL;
  686. PWCHAR pszSrc, pszDst;
  687. DWORD dwErr = NO_ERROR, dwOffset = 0;
  688. // Validate parameters
  689. if (!pInfo || !pIf2)
  690. {
  691. return ERROR_INVALID_PARAMETER;
  692. }
  693. // Alias the ras entry
  694. //
  695. pEntry = pInfo->pRasEntry;
  696. // Assign all assignable fields
  697. //
  698. pIf2->dwfOptions = pEntry->dwfOptions;
  699. pIf2->ipaddr = *((DWORD*)&(pEntry->ipaddr));
  700. pIf2->ipaddrDns = *((DWORD*)&(pEntry->ipaddrDns));
  701. pIf2->ipaddrDnsAlt = *((DWORD*)&(pEntry->ipaddrDnsAlt));
  702. pIf2->ipaddrWins = *((DWORD*)&(pEntry->ipaddrWins));
  703. pIf2->ipaddrWinsAlt = *((DWORD*)&(pEntry->ipaddrWinsAlt));
  704. pIf2->dwfNetProtocols = pEntry->dwfNetProtocols;
  705. pIf2->dwChannels = pEntry->dwChannels;
  706. pIf2->dwSubEntries = pEntry->dwSubEntries;
  707. pIf2->dwDialMode = pEntry->dwDialMode;
  708. pIf2->dwDialExtraPercent = pEntry->dwDialExtraPercent;
  709. pIf2->dwDialExtraSampleSeconds = pEntry->dwDialExtraSampleSeconds;
  710. pIf2->dwHangUpExtraPercent = pEntry->dwHangUpExtraPercent;
  711. pIf2->dwHangUpExtraSampleSeconds= pEntry->dwHangUpExtraSampleSeconds;
  712. pIf2->dwIdleDisconnectSeconds = pEntry->dwIdleDisconnectSeconds;
  713. pIf2->dwType = pEntry->dwType;
  714. pIf2->dwEncryptionType = pEntry->dwEncryptionType;
  715. pIf2->dwCustomAuthKey = pEntry->dwCustomAuthKey;
  716. pIf2->dwVpnStrategy = pEntry->dwVpnStrategy;
  717. pIf2->guidId = pEntry->guidId;
  718. // Copy all copyable fields
  719. //
  720. wcscpy(pIf2->szLocalPhoneNumber, pEntry->szLocalPhoneNumber);
  721. wcscpy(pIf2->szDeviceType, pEntry->szDeviceType);
  722. wcscpy(pIf2->szDeviceName, pEntry->szDeviceName);
  723. wcscpy(pIf2->szX25PadType, pEntry->szX25PadType);
  724. wcscpy(pIf2->szX25Address, pEntry->szX25Address);
  725. wcscpy(pIf2->szX25Facilities, pEntry->szX25Facilities);
  726. wcscpy(pIf2->szX25UserData, pEntry->szX25UserData);
  727. // Append the custom auth data to the end of the
  728. // structure.
  729. //
  730. dwOffset = sizeof(MPRI_INTERFACE_2);
  731. if ( pInfo->dwCustAuthDataSize )
  732. {
  733. pIf2->dwCustomAuthDataSize =
  734. pInfo->dwCustAuthDataSize;
  735. pIf2->dwCustomAuthDataOffset = TRUE;
  736. CopyMemory(
  737. pIf2 + 1,
  738. pInfo->lpbCustAuthData,
  739. pInfo->dwCustAuthDataSize);
  740. }
  741. // Append the alternates list
  742. //
  743. dwOffset += pInfo->dwCustAuthDataSize;
  744. if (pEntry->dwAlternateOffset)
  745. {
  746. pIf2->dwAlternatesOffset = TRUE;
  747. pszSrc = (PWCHAR)((ULONG_PTR)(pEntry) +
  748. (ULONG_PTR)(pEntry->dwAlternateOffset));
  749. pszDst = (PWCHAR)((ULONG_PTR)(pIf2) + (ULONG_PTR)dwOffset);
  750. dwErr = RpbkCopyMultiSz(pszDst, pszSrc);
  751. if (dwErr != NO_ERROR)
  752. {
  753. return dwErr;
  754. }
  755. }
  756. else
  757. {
  758. pIf2->dwAlternatesOffset = 0;
  759. }
  760. // Remove any unsupported options that may have made
  761. // it in. (shouldn't be any)
  762. //
  763. dwErr = RpbkConformIfData(dwLevel, pInterfaceData);
  764. if (dwErr != NO_ERROR)
  765. {
  766. return dwErr;
  767. }
  768. if(pEntry->dwfOptions2 & RASEO2_UsePreSharedKey)
  769. {
  770. pIf2->dwfOptions |= MPRIO_IpSecPreSharedKey;
  771. }
  772. return NO_ERROR;
  773. }
  774. //
  775. // Reads in the router phonebook sub entry associated with
  776. // the given interface
  777. //
  778. DWORD
  779. RpbkOpenSubEntry(
  780. IN ROUTER_INTERFACE_OBJECT* pIfObject,
  781. IN DWORD dwIndex,
  782. OUT PHANDLE phSubEntry )
  783. {
  784. RPBK_SUBENTRY_INFO * pInfo = NULL;
  785. DWORD dwErr = NO_ERROR, dwSize;
  786. do {
  787. // Initialize
  788. *phSubEntry = NULL;
  789. // Allocate the control structure
  790. //
  791. pInfo = (RPBK_SUBENTRY_INFO*)
  792. RpbkAlloc(sizeof(RPBK_SUBENTRY_INFO), TRUE);
  793. if (pInfo == NULL)
  794. {
  795. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  796. break;
  797. }
  798. // Get the phonebook path
  799. //
  800. dwErr = RpbkGetPhonebookPath(&(pInfo->pszPhonebookPath));
  801. if (dwErr != NO_ERROR)
  802. {
  803. break;
  804. }
  805. // Find out how big the ras entry needs to be
  806. //
  807. dwErr = RasGetSubEntryPropertiesW(
  808. pInfo->pszPhonebookPath,
  809. pIfObject->lpwsInterfaceName,
  810. dwIndex,
  811. NULL,
  812. &(pInfo->dwSize),
  813. NULL,
  814. NULL);
  815. if (dwErr != ERROR_BUFFER_TOO_SMALL)
  816. {
  817. break;
  818. }
  819. // Allocate the ras entry structure
  820. //
  821. pInfo->pRasSubEntry =
  822. (LPRASSUBENTRY) RpbkAlloc(pInfo->dwSize, TRUE);
  823. if (pInfo->pRasSubEntry == NULL)
  824. {
  825. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  826. break;
  827. }
  828. // Read in the ras entry
  829. //
  830. pInfo->pRasSubEntry->dwSize = sizeof(RASSUBENTRY);
  831. dwErr = RasGetSubEntryProperties(
  832. pInfo->pszPhonebookPath,
  833. pIfObject->lpwsInterfaceName,
  834. dwIndex,
  835. pInfo->pRasSubEntry,
  836. &(pInfo->dwSize),
  837. NULL,
  838. NULL);
  839. if (dwErr != NO_ERROR)
  840. {
  841. break;
  842. }
  843. // Assign the return value
  844. *phSubEntry = (HANDLE)pInfo;
  845. } while (FALSE);
  846. // Cleanup
  847. {
  848. if (dwErr != NO_ERROR)
  849. {
  850. RpbkFreeSubEntryInfo(pInfo);
  851. }
  852. }
  853. return dwErr;
  854. }
  855. //
  856. // Cleans up the data returned by RpbkOpen* functions
  857. //
  858. DWORD
  859. RpbkCloseSubEntry(
  860. IN HANDLE hSubEntry )
  861. {
  862. RpbkFreeSubEntryInfo((RPBK_SUBENTRY_INFO*)hSubEntry);
  863. return NO_ERROR;
  864. }
  865. DWORD
  866. RpbkSetSubEntry(
  867. IN PWCHAR pszInterface,
  868. IN DWORD dwIndex,
  869. IN DWORD dwLevel,
  870. OUT LPBYTE pDevData )
  871. {
  872. MPR_DEVICE_0* pDev0 = (MPR_DEVICE_0*)pDevData;
  873. MPR_DEVICE_1* pDev1 = (MPR_DEVICE_1*)pDevData;
  874. LPRASSUBENTRY pSubEntry = NULL;
  875. PWCHAR pszAlternates = NULL, pszPath = NULL;
  876. DWORD dwErr = NO_ERROR, dwSize;
  877. // Validate parameters
  878. if (! pDev0)
  879. {
  880. return ERROR_INVALID_PARAMETER;
  881. }
  882. // Allocate the ras entry structure
  883. //
  884. dwSize = sizeof(RASSUBENTRY);
  885. if ((dwLevel == 1) && (pDev1->szAlternates))
  886. {
  887. dwSize += RpbkGetMultiSzSize(pDev1->szAlternates);
  888. }
  889. pSubEntry = RpbkAlloc(dwSize, TRUE);
  890. if (pSubEntry == NULL)
  891. {
  892. return ERROR_NOT_ENOUGH_MEMORY;
  893. }
  894. pSubEntry->dwSize = sizeof(RASSUBENTRY);
  895. do
  896. {
  897. // Copy all copyable fields
  898. //
  899. if ( dwLevel == 0 )
  900. {
  901. wcscpy(pSubEntry->szDeviceType, pDev0->szDeviceType);
  902. wcscpy(pSubEntry->szDeviceName, pDev0->szDeviceName);
  903. }
  904. if ( dwLevel == 1 )
  905. {
  906. wcscpy(pSubEntry->szDeviceType, pDev1->szDeviceType);
  907. wcscpy(pSubEntry->szDeviceName, pDev1->szDeviceName);
  908. wcscpy(pSubEntry->szLocalPhoneNumber, pDev1->szLocalPhoneNumber);
  909. if (pDev1->szAlternates)
  910. {
  911. pSubEntry->dwAlternateOffset = sizeof(RASSUBENTRY);
  912. pszAlternates = (PWCHAR)
  913. ((ULONG_PTR)(pSubEntry) +
  914. (ULONG_PTR)(pSubEntry->dwAlternateOffset));
  915. dwErr = RpbkCopyMultiSz(pszAlternates, pDev1->szAlternates);
  916. if (dwErr != NO_ERROR)
  917. {
  918. break;
  919. }
  920. }
  921. else
  922. {
  923. pSubEntry->dwAlternateOffset = 0;
  924. }
  925. }
  926. // Discover the phonebook path
  927. dwErr = RpbkGetPhonebookPath(&pszPath);
  928. if (dwErr != NO_ERROR)
  929. {
  930. break;
  931. }
  932. // Save the entry
  933. dwErr = RasSetSubEntryPropertiesW(
  934. pszPath,
  935. pszInterface,
  936. dwIndex,
  937. pSubEntry,
  938. dwSize,
  939. NULL,
  940. 0);
  941. if (dwErr != NO_ERROR)
  942. {
  943. break;
  944. }
  945. } while (FALSE);
  946. // Cleanup
  947. {
  948. if (pSubEntry)
  949. {
  950. RpbkFree(pSubEntry);
  951. }
  952. if (pszPath)
  953. {
  954. RpbkFree(pszPath);
  955. }
  956. }
  957. return dwErr;
  958. }
  959. DWORD
  960. RpbkSubEntryToDevDataSize(
  961. IN HANDLE hSubEntry,
  962. IN DWORD dwLevel,
  963. OUT LPDWORD lpdwcbSizeOfData )
  964. {
  965. RPBK_SUBENTRY_INFO* pInfo = (RPBK_SUBENTRY_INFO*)hSubEntry;
  966. DWORD dwSize = 0;
  967. PWCHAR pszAlternates = NULL;
  968. // Validate parameters
  969. if (pInfo == NULL)
  970. {
  971. return ERROR_INVALID_PARAMETER;
  972. }
  973. // Initialize
  974. *lpdwcbSizeOfData = 0;
  975. // Initailize the size
  976. //
  977. if ( dwLevel == 0 )
  978. {
  979. dwSize = sizeof(MPR_DEVICE_0);
  980. }
  981. else
  982. {
  983. dwSize = sizeof(MPR_DEVICE_1);
  984. // Add on the size of the alternates list
  985. //
  986. if (pInfo->pRasSubEntry->dwAlternateOffset)
  987. {
  988. pszAlternates = (PWCHAR)
  989. ((ULONG_PTR)(pInfo->pRasSubEntry) +
  990. (ULONG_PTR)(pInfo->pRasSubEntry->dwAlternateOffset));
  991. dwSize += RpbkGetMultiSzSize(pszAlternates);
  992. }
  993. }
  994. // Assign the return value
  995. //
  996. *lpdwcbSizeOfData = dwSize;
  997. return NO_ERROR;
  998. }
  999. DWORD
  1000. RpbkSubEntryToDevData(
  1001. IN HANDLE hSubEntry,
  1002. IN DWORD dwLevel,
  1003. OUT LPBYTE pDeviceData )
  1004. {
  1005. RPBK_SUBENTRY_INFO* pInfo = (RPBK_SUBENTRY_INFO*)hSubEntry;
  1006. MPR_DEVICE_0* pDev0 = (MPR_DEVICE_0*)pDeviceData;
  1007. MPR_DEVICE_1* pDev1 = (MPR_DEVICE_1*)pDeviceData;
  1008. LPRASSUBENTRY pSubEntry = NULL;
  1009. PWCHAR pszAlternates = NULL;
  1010. DWORD dwErr = NO_ERROR, dwOffset = 0;
  1011. // Validate parameters
  1012. if (!pInfo || !pDev0)
  1013. {
  1014. return ERROR_INVALID_PARAMETER;
  1015. }
  1016. // Alias the ras entry
  1017. //
  1018. pSubEntry = pInfo->pRasSubEntry;
  1019. // Copy all copyable fields
  1020. //
  1021. if ( dwLevel == 0 )
  1022. {
  1023. wcscpy(pDev0->szDeviceType, pSubEntry->szDeviceType);
  1024. wcscpy(pDev0->szDeviceName, pSubEntry->szDeviceName);
  1025. }
  1026. else if ( dwLevel == 1 )
  1027. {
  1028. wcscpy(pDev1->szDeviceType, pSubEntry->szDeviceType);
  1029. wcscpy(pDev1->szDeviceName, pSubEntry->szDeviceName);
  1030. wcscpy(pDev1->szLocalPhoneNumber, pSubEntry->szLocalPhoneNumber);
  1031. // Append the custom auth data to the end of the
  1032. // structure.
  1033. //
  1034. dwOffset += sizeof(MPR_DEVICE_1);
  1035. if (pSubEntry->dwAlternateOffset)
  1036. {
  1037. pDev1->szAlternates = (PWCHAR)
  1038. ((ULONG_PTR)(pDev1) + dwOffset);
  1039. pszAlternates = (PWCHAR)
  1040. ((ULONG_PTR)(pSubEntry) +
  1041. (ULONG_PTR)(pSubEntry->dwAlternateOffset));
  1042. dwErr = RpbkCopyMultiSz(pDev1->szAlternates, pszAlternates);
  1043. if (dwErr != NO_ERROR)
  1044. {
  1045. return dwErr;
  1046. }
  1047. }
  1048. else
  1049. {
  1050. pDev1->szAlternates = NULL;
  1051. }
  1052. }
  1053. return NO_ERROR;
  1054. }