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.

1579 lines
38 KiB

  1. //--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999 - 2000.
  5. //
  6. //
  7. // File: loadras
  8. //
  9. // Contents: Load system settings.
  10. //
  11. // chrisab 24-Mar-00 Created
  12. //
  13. //---------------------------------------------------------------
  14. #include "loadhead.cxx"
  15. #pragma hdrstop
  16. #undef WINVER
  17. #define WINVER 0x0500
  18. #include <common.hxx>
  19. #include <stdlib.h>
  20. #include <winsock.h>
  21. #include <objerror.h>
  22. #include <loadstate.hxx>
  23. #include <bothchar.hxx>
  24. #include <winnetwk.h>
  25. #include <ras.h>
  26. #include <raserror.h>
  27. #include <loadras.hxx>
  28. extern "C" {
  29. #include "tstr.h"
  30. #include <pbk.h> // Ras phone book include
  31. }
  32. #define PRIVATE_RAS // Access the RAS phone book directly instead of using
  33. // the public RAS APIs.
  34. #define SIZEOF_STRUCT(structname, uptomember) ((int)((LPBYTE)(&((structname*)0)->uptomember) - ((LPBYTE)((structname*)0))))
  35. //
  36. // TRUE when rasman.dll has been
  37. // successfully loaded and initailized.
  38. // See LoadRasmanDllAndInit().
  39. //
  40. DWORD FRasInitialized = FALSE;
  41. BOOL g_FRunningInAppCompatMode = FALSE;
  42. DWORD DwRasInitializeError;
  43. CRITICAL_SECTION PhonebookLock;
  44. // Debugging only
  45. #ifdef NEVER
  46. DWORD RasDumpEntry(TCHAR *strEntryName, RASENTRY *pInRasEntry)
  47. {
  48. DWORD dwErr = ERROR_SUCCESS;
  49. DWORD dwSize = sizeof(RASENTRY);
  50. RASENTRY RasEntry, *pRasEntry;
  51. RASDIALPARAMS RasDialParams;
  52. // If no name passed in, print what pInRasEntry pts to
  53. if( strEntryName == NULL )
  54. {
  55. if( pInRasEntry == NULL )
  56. {
  57. return ERROR_INVALID_HANDLE;
  58. }
  59. pRasEntry = pInRasEntry;
  60. }
  61. // Otherwise, if there's a buffer passed in, use that.
  62. else
  63. {
  64. if( pInRasEntry == NULL )
  65. {
  66. pRasEntry = &RasEntry;
  67. }
  68. else
  69. {
  70. pRasEntry = pInRasEntry;
  71. }
  72. ZeroMemory( pRasEntry, sizeof(RASENTRY) );
  73. pRasEntry->dwSize = sizeof(RASENTRY);
  74. dwErr = RasGetEntryPropertiesW(NULL,
  75. strEntryName,
  76. pRasEntry,
  77. &dwSize,
  78. NULL,
  79. NULL);
  80. if( dwErr )
  81. return dwErr;
  82. }
  83. if( strEntryName )
  84. {
  85. printf( "--- Dumping Ras entry %ls ---\n", strEntryName);
  86. }
  87. else
  88. {
  89. printf( "--- Dumping Ras entry at %p ---\n", pRasEntry);
  90. }
  91. printf( "dwfOptions = %x\n", pRasEntry->dwfOptions);
  92. printf( "dwFramingProtocol = %d\n", pRasEntry->dwFramingProtocol);
  93. printf( " Win2k Extended Info\n");
  94. printf( "dwType = %d\n", pRasEntry->dwType);
  95. printf( "dwEncryptionType = %d\n", pRasEntry->dwEncryptionType);
  96. printf( "dwCustomAuthKey = %d\n", pRasEntry->dwCustomAuthKey);
  97. printf( "szCustomDialDll = [%ls]\n", pRasEntry->szCustomDialDll);
  98. printf( "dwVpnStrategy = %d\n", pRasEntry->dwVpnStrategy);
  99. printf( "\n\n");
  100. return dwErr;
  101. }
  102. DWORD RasDumpPhoneBookEntry(TCHAR *tszEntryName, PBENTRY *pEntry)
  103. {
  104. DWORD dwErr;
  105. PBFILE pbfile;
  106. DTLNODE *pdtlnode;
  107. BOOL fCreated;
  108. if( !pEntry && !tszEntryName )
  109. return ERROR_INVALID_PARAMETER;
  110. if( tszEntryName )
  111. {
  112. // Check and see if the entry name already exists in the phone book
  113. dwErr = GetPbkAndEntryName(NULL,
  114. tszEntryName,
  115. 0,
  116. &pbfile,
  117. &pdtlnode);
  118. // if failed for some other reason than the entry doesn't exist, bail.
  119. if( (dwErr != SUCCESS) && (dwErr != ERROR_CANNOT_FIND_PHONEBOOK_ENTRY) )
  120. {
  121. return dwErr;
  122. }
  123. if( pdtlnode == NULL )
  124. {
  125. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  126. return dwErr;
  127. }
  128. pEntry = (PBENTRY *) DtlGetData(pdtlnode);
  129. printf( "--- Dumping Phonebook Entry %ls ---\n", tszEntryName);
  130. }
  131. else
  132. {
  133. printf( "--- Dumping Phonebook Entry at %p ---\n", pEntry);
  134. }
  135. printf( " pszEntryName = %ls\n", pEntry->pszEntryName);
  136. printf( " dwType = %d\n", pEntry->dwType);
  137. printf( " fSharedPhoneNum = %d\n", pEntry->fSharedPhoneNumbers);
  138. printf( " dwDataEncryption = 0x%x\n", pEntry->dwDataEncryption);
  139. printf( " dwAuthRestrictions = 0x%x\n", pEntry->dwAuthRestrictions);
  140. printf( " dwTypicalAuth = 0x%x\n", pEntry->dwTypicalAuth);
  141. printf( " dwCustomAuthKey = 0x%x\n", pEntry->dwCustomAuthKey);
  142. printf( " fAutoLogon = %d\n", pEntry->fAutoLogon);
  143. printf( " fPreviewUserPw = %d\n", pEntry->fPreviewUserPw);
  144. printf( " fPreviewDomain = %d\n", pEntry->fPreviewDomain);
  145. printf( "\n\n");
  146. return 0;
  147. }
  148. #endif // NEVER - Debugging only
  149. DWORD InitializeLoadRAS(DWORD dwReason)
  150. {
  151. DWORD dwErr = ERROR_SUCCESS;
  152. if( dwReason == DLL_PROCESS_ATTACH )
  153. {
  154. InitializeCriticalSection(&PhonebookLock);
  155. if( InitializePbk() != 0 )
  156. return FALSE;
  157. }
  158. else if( dwReason == DLL_PROCESS_DETACH )
  159. {
  160. TerminatePbk();
  161. }
  162. return dwErr;
  163. }
  164. BOOL
  165. FRunningInAppCompatMode()
  166. {
  167. BOOL fResult = FALSE;
  168. TCHAR *pszCommandLine = NULL;
  169. TCHAR *psz;
  170. pszCommandLine = StrDup(GetCommandLine());
  171. if(NULL == pszCommandLine)
  172. {
  173. goto done;
  174. }
  175. psz = pszCommandLine + lstrlen(pszCommandLine);
  176. while( (TEXT('\\') != *psz)
  177. && (psz != pszCommandLine))
  178. {
  179. psz--;
  180. }
  181. if(TEXT('\\') == *psz)
  182. {
  183. psz++;
  184. }
  185. if( (0 == lstrcmpi(psz, TEXT("INETINFO.EXE")))
  186. || (0 == lstrcmpi(psz, TEXT("WSPSRV.EXE"))))
  187. {
  188. fResult = TRUE;
  189. }
  190. done:
  191. if(NULL != pszCommandLine)
  192. {
  193. Free(pszCommandLine);
  194. }
  195. return fResult;
  196. }
  197. DWORD
  198. LoadRasmanDllAndInit()
  199. {
  200. if (FRasInitialized)
  201. {
  202. return 0;
  203. }
  204. if (LoadRasmanDll())
  205. {
  206. return GetLastError();
  207. }
  208. //
  209. // Success is returned if RasInitialize fails, in which
  210. // case none of the APIs will ever do anything but report
  211. // that RasInitialize failed. All this is to avoid the
  212. // ugly system popup if RasMan service can't start.
  213. //
  214. if ((DwRasInitializeError = g_pRasInitialize()) != 0)
  215. {
  216. return DwRasInitializeError;
  217. }
  218. FRasInitialized = TRUE;
  219. g_FRunningInAppCompatMode = FRunningInAppCompatMode();
  220. // pmay: 300166
  221. //
  222. // We don't start rasauto automatically anymore.
  223. //
  224. // g_pRasStartRasAutoIfRequired();
  225. return 0;
  226. }
  227. DWORD
  228. IpAddrToString(
  229. IN RASIPADDR* pipaddr,
  230. OUT LPTSTR* ppszIpAddr
  231. )
  232. {
  233. DWORD dwErr;
  234. PCHAR psz;
  235. LPTSTR pszIpAddr;
  236. PULONG pul = (PULONG)pipaddr;
  237. struct in_addr in_addr;
  238. pszIpAddr = (TCHAR *) Malloc(17 * sizeof(TCHAR));
  239. if (pszIpAddr == NULL)
  240. {
  241. return ERROR_NOT_ENOUGH_MEMORY;
  242. }
  243. in_addr.s_addr = *pul;
  244. psz = inet_ntoa(in_addr);
  245. if (psz == NULL)
  246. {
  247. DbgPrint("IpAddrToString: inet_ntoa failed!\n");
  248. Free(pszIpAddr);
  249. return WSAGetLastError();
  250. }
  251. strcpyAtoT(pszIpAddr, psz);
  252. *ppszIpAddr = pszIpAddr;
  253. return 0;
  254. }
  255. VOID
  256. GetDevicePortName(
  257. IN TCHAR *pszDevicePortName,
  258. OUT TCHAR *pszDeviceName,
  259. OUT TCHAR *pszPortName
  260. )
  261. {
  262. DWORD i, dwStart;
  263. //
  264. // Copy the device name.
  265. //
  266. lstrcpy(pszDeviceName, pszDevicePortName);
  267. //
  268. // Check to see if there is a NULL
  269. // within MAX_PORT_NAME characters
  270. // after the device name's NULL.If
  271. // there is, the copy the characters
  272. // between the NULLs as the port name.
  273. //
  274. *pszPortName = TEXT('\0');
  275. dwStart = lstrlen(pszDeviceName) + 1;
  276. for (i = 0; i < MAX_PORT_NAME; i++)
  277. {
  278. if (pszDevicePortName[dwStart + i] == TEXT('\0'))
  279. {
  280. lstrcpy(
  281. pszPortName,
  282. &pszDevicePortName[dwStart]);
  283. break;
  284. }
  285. }
  286. }
  287. DWORD
  288. CreateAndInitializePhone(
  289. LPTSTR lpszAreaCode,
  290. DWORD dwCountryCode,
  291. DWORD dwCountryID,
  292. LPTSTR lpszPhoneNumber,
  293. BOOL fUseDialingRules,
  294. LPTSTR lpszComment,
  295. DTLNODE** ppdtlnode)
  296. {
  297. DWORD dwRetCode = ERROR_SUCCESS;
  298. PBPHONE* pPhone;
  299. DTLNODE* pdtlnode;
  300. pdtlnode = CreatePhoneNode();
  301. if (pdtlnode == NULL)
  302. {
  303. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  304. goto done;
  305. }
  306. pPhone = (PBPHONE *) DtlGetData(pdtlnode);
  307. if(lpszAreaCode)
  308. {
  309. pPhone->pszAreaCode = StrDup(lpszAreaCode);
  310. if(NULL == pPhone->pszAreaCode)
  311. {
  312. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  313. goto done;
  314. }
  315. }
  316. else
  317. {
  318. pPhone->pszAreaCode = NULL;
  319. }
  320. pPhone->dwCountryCode = dwCountryCode;
  321. pPhone->dwCountryID = dwCountryID;
  322. pPhone->fUseDialingRules = fUseDialingRules;
  323. if(lpszPhoneNumber)
  324. {
  325. pPhone->pszPhoneNumber = StrDup(lpszPhoneNumber);
  326. if(NULL == pPhone->pszPhoneNumber)
  327. {
  328. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  329. goto done;
  330. }
  331. }
  332. else
  333. {
  334. pPhone->pszPhoneNumber = NULL;
  335. }
  336. if(pPhone->pszComment)
  337. {
  338. pPhone->pszComment = StrDup(lpszComment);
  339. if(NULL == pPhone->pszComment)
  340. {
  341. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  342. goto done;
  343. }
  344. }
  345. else
  346. {
  347. pPhone->pszComment = NULL;
  348. }
  349. *ppdtlnode = pdtlnode;
  350. done:
  351. return dwRetCode;
  352. }
  353. void
  354. SetBogusPortInformation(PBLINK *pLink, DWORD dwType)
  355. {
  356. PBPORT *pPort = &pLink->pbport;
  357. if (dwType == RASET_Phone)
  358. {
  359. pPort->pszMedia = StrDup( TEXT(SERIAL_TXT) );
  360. pPort->pbdevicetype = PBDT_Modem;
  361. pPort->dwFlags |= PBP_F_BogusDevice;
  362. }
  363. else if (dwType == RASET_Vpn)
  364. {
  365. pPort->pszMedia = StrDup( TEXT("rastapi") );
  366. pPort->pbdevicetype = PBDT_Vpn;
  367. }
  368. else
  369. {
  370. pPort->pszMedia = StrDup( TEXT(SERIAL_TXT) );
  371. pPort->pbdevicetype = PBDT_Null;
  372. pPort->dwFlags |= PBP_F_BogusDevice;
  373. }
  374. }
  375. DWORD
  376. WinState_RasEntryToPhonebookEntry(
  377. IN LPCTSTR lpszEntry,
  378. IN LPRASENTRY lpRasEntry,
  379. IN DWORD dwcb,
  380. IN LPBYTE lpbDeviceConfig,
  381. IN DWORD dwcbDeviceConfig,
  382. OUT PBENTRY *pEntry
  383. )
  384. {
  385. DWORD dwErr, dwcbStr;
  386. DTLNODE *pdtlnode;
  387. PBDEVICETYPE pbdevicetype;
  388. PBLINK *pLink;
  389. DTLLIST *pdtllistPorts;
  390. PBPORT *pPort;
  391. DWORD i, cwDevices;
  392. RASMAN_DEVICE *pDevices;
  393. TCHAR szDeviceName[RAS_MaxDeviceName + 1];
  394. TCHAR szPortName[MAX_PORT_NAME];
  395. DTLNODE *pNodePhone;
  396. LPTSTR pszAreaCode;
  397. PBPHONE *pPhone;
  398. BOOL fScriptBefore;
  399. BOOL fScriptBeforeTerminal = FALSE;
  400. LPTSTR pszScriptBefore;
  401. BOOL fNewEntry = FALSE;
  402. //
  403. // Set up to access information for the first link.
  404. //
  405. pdtlnode = DtlGetFirstNode(pEntry->pdtllistLinks);
  406. pLink = (PBLINK *)DtlGetData(pdtlnode);
  407. ASSERT(NULL != pLink);
  408. fScriptBefore = pLink->pbport.fScriptBeforeTerminal;
  409. pszScriptBefore = pLink->pbport.pszScriptBefore;
  410. if(NULL == pEntry->pszEntryName)
  411. {
  412. fNewEntry = TRUE;
  413. }
  414. //
  415. // Get entry name.
  416. //
  417. Free0( pEntry->pszEntryName );
  418. pEntry->pszEntryName = StrDup(lpszEntry);
  419. //
  420. // Get dwfOptions.
  421. //
  422. pEntry->dwIpAddressSource =
  423. lpRasEntry->dwfOptions & RASEO_SpecificIpAddr ?
  424. ASRC_RequireSpecific : ASRC_ServerAssigned;
  425. pEntry->dwIpNameSource =
  426. lpRasEntry->dwfOptions & RASEO_SpecificNameServers ?
  427. ASRC_RequireSpecific : ASRC_ServerAssigned;
  428. switch (lpRasEntry->dwFramingProtocol)
  429. {
  430. case RASFP_Ppp:
  431. //
  432. // Get PPP-based information.
  433. //
  434. pEntry->dwBaseProtocol = BP_Ppp;
  435. #if AMB
  436. pEntry->dwAuthentication = AS_PppThenAmb;
  437. #endif
  438. pEntry->fIpHeaderCompression =
  439. (BOOL)lpRasEntry->dwfOptions & RASEO_IpHeaderCompression;
  440. pEntry->fIpPrioritizeRemote =
  441. (BOOL)lpRasEntry->dwfOptions & RASEO_RemoteDefaultGateway;
  442. //
  443. // Get specified IP addresses.
  444. //
  445. if (pEntry->dwIpAddressSource == ASRC_RequireSpecific)
  446. {
  447. dwErr = IpAddrToString(
  448. &lpRasEntry->ipaddr,
  449. &pEntry->pszIpAddress);
  450. if (dwErr)
  451. return dwErr;
  452. }
  453. else
  454. {
  455. pEntry->pszIpAddress = NULL;
  456. }
  457. if (pEntry->dwIpNameSource == ASRC_RequireSpecific)
  458. {
  459. dwErr = IpAddrToString(
  460. &lpRasEntry->ipaddrDns,
  461. &pEntry->pszIpDnsAddress);
  462. if (dwErr)
  463. {
  464. return dwErr;
  465. }
  466. dwErr = IpAddrToString(
  467. &lpRasEntry->ipaddrDnsAlt,
  468. &pEntry->pszIpDns2Address);
  469. if (dwErr)
  470. {
  471. return dwErr;
  472. }
  473. dwErr = IpAddrToString(
  474. &lpRasEntry->ipaddrWins,
  475. &pEntry->pszIpWinsAddress);
  476. if (dwErr)
  477. {
  478. return dwErr;
  479. }
  480. dwErr = IpAddrToString(
  481. &lpRasEntry->ipaddrWinsAlt,
  482. &pEntry->pszIpWins2Address);
  483. if (dwErr)
  484. {
  485. return dwErr;
  486. }
  487. }
  488. else
  489. {
  490. pEntry->pszIpDnsAddress = NULL;
  491. pEntry->pszIpDns2Address = NULL;
  492. pEntry->pszIpWinsAddress = NULL;
  493. pEntry->pszIpWins2Address = NULL;
  494. }
  495. //
  496. // Get protocol information.
  497. //
  498. pEntry->dwfExcludedProtocols = 0;
  499. if (!(lpRasEntry->dwfNetProtocols & RASNP_NetBEUI))
  500. {
  501. pEntry->dwfExcludedProtocols |= NP_Nbf;
  502. }
  503. if (!(lpRasEntry->dwfNetProtocols & RASNP_Ipx))
  504. {
  505. pEntry->dwfExcludedProtocols |= NP_Ipx;
  506. }
  507. if (!(lpRasEntry->dwfNetProtocols & RASNP_Ip))
  508. {
  509. pEntry->dwfExcludedProtocols |= NP_Ip;
  510. }
  511. break;
  512. case RASFP_Slip:
  513. //
  514. // Get SLIP-based information.
  515. //
  516. pEntry->dwBaseProtocol = BP_Slip;
  517. #if AMB
  518. pEntry->dwAuthentication = AS_PppThenAmb;
  519. #endif
  520. pEntry->dwFrameSize = lpRasEntry->dwFrameSize;
  521. pEntry->fIpHeaderCompression =
  522. (BOOL)lpRasEntry->dwfOptions & RASEO_IpHeaderCompression;
  523. pEntry->fIpPrioritizeRemote =
  524. (BOOL)lpRasEntry->dwfOptions & RASEO_RemoteDefaultGateway;
  525. //
  526. // Get protocol information.
  527. //
  528. pEntry->dwfExcludedProtocols = (NP_Nbf|NP_Ipx);
  529. if (pEntry->dwIpAddressSource == ASRC_RequireSpecific)
  530. {
  531. dwErr = IpAddrToString(
  532. &lpRasEntry->ipaddr,
  533. &pEntry->pszIpAddress);
  534. if (dwErr)
  535. {
  536. return dwErr;
  537. }
  538. }
  539. else
  540. {
  541. pEntry->pszIpAddress = NULL;
  542. }
  543. if (pEntry->dwIpNameSource == ASRC_RequireSpecific)
  544. {
  545. dwErr = IpAddrToString(
  546. &lpRasEntry->ipaddrDns,
  547. &pEntry->pszIpDnsAddress);
  548. if (dwErr)
  549. {
  550. return dwErr;
  551. }
  552. dwErr = IpAddrToString(
  553. &lpRasEntry->ipaddrDnsAlt,
  554. &pEntry->pszIpDns2Address);
  555. if (dwErr)
  556. {
  557. return dwErr;
  558. }
  559. dwErr = IpAddrToString(
  560. &lpRasEntry->ipaddrWins,
  561. &pEntry->pszIpWinsAddress);
  562. if (dwErr)
  563. {
  564. return dwErr;
  565. }
  566. dwErr = IpAddrToString(
  567. &lpRasEntry->ipaddrWinsAlt,
  568. &pEntry->pszIpWins2Address);
  569. if (dwErr)
  570. {
  571. return dwErr;
  572. }
  573. }
  574. else
  575. {
  576. pEntry->pszIpDnsAddress = NULL;
  577. pEntry->pszIpDns2Address = NULL;
  578. pEntry->pszIpWinsAddress = NULL;
  579. pEntry->pszIpWins2Address = NULL;
  580. }
  581. break;
  582. case RASFP_Ras:
  583. //
  584. // Get AMB-based information.
  585. //
  586. pEntry->dwBaseProtocol = BP_Ras;
  587. #if AMB
  588. pEntry->dwAuthentication = AS_AmbOnly;
  589. #endif
  590. break;
  591. }
  592. pEntry->fLcpExtensions =
  593. (BOOL)!(lpRasEntry->dwfOptions & RASEO_DisableLcpExtensions);
  594. //
  595. // If terminal before/after dial options are set,
  596. // then update the entry. Otherwise, leave it as it
  597. // is.
  598. //
  599. if(lpRasEntry->dwfOptions & RASEO_TerminalBeforeDial)
  600. {
  601. fScriptBeforeTerminal = TRUE;
  602. }
  603. if(lpRasEntry->dwfOptions & RASEO_TerminalAfterDial)
  604. {
  605. pEntry->fScriptAfterTerminal = TRUE;
  606. }
  607. else
  608. {
  609. pEntry->fScriptAfterTerminal = FALSE;
  610. }
  611. pEntry->fShowMonitorIconInTaskBar =
  612. (BOOL) (lpRasEntry->dwfOptions & RASEO_ModemLights);
  613. pEntry->fSwCompression =
  614. (BOOL)(lpRasEntry->dwfOptions & RASEO_SwCompression);
  615. if (lpRasEntry->dwfOptions & RASEO_RequireMsEncryptedPw)
  616. {
  617. pEntry->dwAuthRestrictions = AR_F_AuthMSCHAP;
  618. }
  619. else if (lpRasEntry->dwfOptions & RASEO_RequireEncryptedPw)
  620. {
  621. pEntry->dwAuthRestrictions = AR_F_AuthSPAP
  622. | AR_F_AuthMD5CHAP
  623. | AR_F_AuthMSCHAP;
  624. }
  625. else
  626. {
  627. pEntry->dwAuthRestrictions = AR_F_TypicalUnsecure;
  628. }
  629. pEntry->dwDataEncryption =
  630. (lpRasEntry->dwfOptions & RASEO_RequireDataEncryption)
  631. ? DE_Mppe40bit
  632. : DE_None;
  633. pEntry->fAutoLogon =
  634. (BOOL)(lpRasEntry->dwfOptions & RASEO_UseLogonCredentials);
  635. pLink->fPromoteAlternates =
  636. (BOOL)(lpRasEntry->dwfOptions & RASEO_PromoteAlternates);
  637. pEntry->fShareMsFilePrint = pEntry->fBindMsNetClient =
  638. (BOOL) !(lpRasEntry->dwfOptions & RASEO_SecureLocalFiles);
  639. //
  640. // Make sure that the network components section in the
  641. // phonebook correspond to the values user is setting.
  642. //
  643. EnableOrDisableNetComponent(
  644. pEntry,
  645. TEXT("ms_msclient"),
  646. pEntry->fBindMsNetClient);
  647. EnableOrDisableNetComponent(
  648. pEntry,
  649. TEXT("ms_server"),
  650. pEntry->fShareMsFilePrint);
  651. if (*lpRasEntry->szAreaCode != TEXT('\0'))
  652. {
  653. //
  654. // Make sure the area code does not contain
  655. // non-numeric characters.
  656. //
  657. if (!ValidateAreaCode(lpRasEntry->szAreaCode))
  658. {
  659. return ERROR_INVALID_PARAMETER;
  660. }
  661. pszAreaCode = StrDup(lpRasEntry->szAreaCode);
  662. }
  663. else
  664. {
  665. pszAreaCode = NULL;
  666. }
  667. //
  668. // Get script information.
  669. //
  670. if (lpRasEntry->szScript[0] == TEXT('['))
  671. {
  672. //
  673. // Verify the switch is valid.
  674. //
  675. dwErr = GetRasSwitches(NULL, &pDevices, &cwDevices);
  676. if (!dwErr)
  677. {
  678. CHAR szScriptA[MAX_PATH];
  679. strcpyTtoA(szScriptA, lpRasEntry->szScript);
  680. for (i = 0; i < cwDevices; i++)
  681. {
  682. if (!_stricmp(pDevices[i].D_Name, &szScriptA[1]))
  683. {
  684. pEntry->fScriptAfter = TRUE;
  685. pEntry->pszScriptAfter =
  686. StrDup(&lpRasEntry->szScript[1]);
  687. if (pEntry->pszScriptAfter == NULL)
  688. {
  689. dwErr = GetLastError();
  690. }
  691. break;
  692. }
  693. }
  694. Free(pDevices);
  695. if (dwErr)
  696. {
  697. return dwErr;
  698. }
  699. }
  700. }
  701. else if (lpRasEntry->szScript[0] != TEXT('\0'))
  702. {
  703. pEntry->fScriptAfter = TRUE;
  704. pEntry->pszScriptAfter = StrDup(lpRasEntry->szScript);
  705. if (pEntry->pszScriptAfter == NULL)
  706. {
  707. return GetLastError();
  708. }
  709. }
  710. else
  711. {
  712. if(pEntry->pszScriptAfter)
  713. {
  714. Free(pEntry->pszScriptAfter);
  715. pEntry->pszScriptAfter = NULL;
  716. }
  717. pEntry->fScriptAfter = FALSE;
  718. if(pLink->pbport.pszScriptBefore)
  719. {
  720. Free(pLink->pbport.pszScriptBefore);
  721. pLink->pbport.pszScriptBefore = NULL;
  722. pszScriptBefore = NULL;
  723. }
  724. pLink->pbport.fScriptBefore = FALSE;
  725. fScriptBefore = FALSE;
  726. }
  727. //
  728. // Get X.25 information.
  729. //
  730. pEntry->pszX25Network = NULL;
  731. if (*lpRasEntry->szX25PadType != TEXT('\0'))
  732. {
  733. //
  734. // Verify the X25 network is valid.
  735. //
  736. dwErr = GetRasPads(&pDevices, &cwDevices);
  737. if (!dwErr)
  738. {
  739. CHAR szX25PadTypeA[RAS_MaxPadType + 1];
  740. strcpyTtoA(szX25PadTypeA, lpRasEntry->szX25PadType);
  741. for (i = 0; i < cwDevices; i++)
  742. {
  743. if (!_stricmp(pDevices[i].D_Name, szX25PadTypeA))
  744. {
  745. pEntry->pszX25Network = StrDup(lpRasEntry->szX25PadType);
  746. break;
  747. }
  748. }
  749. Free(pDevices);
  750. }
  751. }
  752. pEntry->pszX25Address =
  753. lstrlen(lpRasEntry->szX25Address)
  754. ? StrDup(lpRasEntry->szX25Address)
  755. : NULL;
  756. pEntry->pszX25Facilities =
  757. lstrlen(lpRasEntry->szX25Facilities)
  758. ? StrDup(lpRasEntry->szX25Facilities)
  759. : NULL;
  760. pEntry->pszX25UserData =
  761. lstrlen(lpRasEntry->szX25UserData)
  762. ? StrDup(lpRasEntry->szX25UserData)
  763. : NULL;
  764. //
  765. // Get custom dial UI information.
  766. //
  767. pEntry->pszCustomDialDll =
  768. lstrlen(lpRasEntry->szAutodialDll)
  769. ? StrDup(lpRasEntry->szAutodialDll)
  770. : NULL;
  771. pEntry->pszCustomDialFunc =
  772. lstrlen(lpRasEntry->szAutodialFunc)
  773. ? StrDup(lpRasEntry->szAutodialFunc)
  774. : NULL;
  775. //
  776. // Get primary phone number. Clear out any existing
  777. // numbers.
  778. //
  779. DtlDestroyList(pLink->pdtllistPhones, DestroyPhoneNode);
  780. pLink->pdtllistPhones = DtlCreateList(0);
  781. if(NULL == pLink->pdtllistPhones)
  782. {
  783. return ERROR_NOT_ENOUGH_MEMORY;
  784. }
  785. if (*lpRasEntry->szLocalPhoneNumber != '\0')
  786. {
  787. if(CreateAndInitializePhone(
  788. pszAreaCode,
  789. lpRasEntry->dwCountryCode,
  790. lpRasEntry->dwCountryID,
  791. lpRasEntry->szLocalPhoneNumber,
  792. !!(lpRasEntry->dwfOptions
  793. & RASEO_UseCountryAndAreaCodes),
  794. lpRasEntry->szDeviceName,
  795. &pdtlnode))
  796. {
  797. return ERROR_NOT_ENOUGH_MEMORY;
  798. }
  799. DtlAddNodeFirst(pLink->pdtllistPhones, pdtlnode);
  800. }
  801. //
  802. // Get the alternate phone numbers.
  803. //
  804. if (lpRasEntry->dwAlternateOffset)
  805. {
  806. PTCHAR UNALIGNED pszPhoneNumber =
  807. (PTCHAR)((ULONG_PTR)lpRasEntry
  808. + lpRasEntry->dwAlternateOffset);
  809. while (*pszPhoneNumber != TEXT('\0'))
  810. {
  811. if(CreateAndInitializePhone(
  812. pszAreaCode,
  813. lpRasEntry->dwCountryCode,
  814. lpRasEntry->dwCountryID,
  815. pszPhoneNumber,
  816. !!(lpRasEntry->dwfOptions
  817. & RASEO_UseCountryAndAreaCodes),
  818. lpRasEntry->szDeviceName,
  819. &pdtlnode))
  820. {
  821. return ERROR_NOT_ENOUGH_MEMORY;
  822. }
  823. DtlAddNodeLast(pLink->pdtllistPhones, pdtlnode);
  824. pszPhoneNumber += lstrlen(pszPhoneNumber) + 1;
  825. }
  826. }
  827. //
  828. // Get device information.
  829. //
  830. dwErr = LoadPortsList(&pdtllistPorts);
  831. if (dwErr)
  832. {
  833. return ERROR_INVALID_PARAMETER;
  834. }
  835. //
  836. // Get the encoded device name/port
  837. // and check for a match.
  838. //
  839. GetDevicePortName(
  840. lpRasEntry->szDeviceName,
  841. szDeviceName, szPortName);
  842. pPort = PpbportFromPortAndDeviceName(
  843. pdtllistPorts,
  844. szPortName,
  845. ((szDeviceName[ 0 ]) ? szDeviceName : NULL) );
  846. if (pPort != NULL)
  847. {
  848. if (CopyToPbport(&pLink->pbport, pPort))
  849. {
  850. pPort = NULL;
  851. }
  852. }
  853. //
  854. // Search for a device name match.
  855. //
  856. if (pPort == NULL)
  857. {
  858. for (pdtlnode = DtlGetFirstNode(pdtllistPorts);
  859. pdtlnode != NULL;
  860. pdtlnode = DtlGetNextNode(pdtlnode))
  861. {
  862. PBPORT *pPortTmp = (PBPORT *)DtlGetData(pdtlnode);
  863. if ( (pPortTmp->pszDevice != NULL)
  864. && (!lstrcmpi(pPortTmp->pszDevice, szDeviceName))
  865. && (!CopyToPbport(&pLink->pbport, pPortTmp)))
  866. {
  867. pPort = pPortTmp;
  868. break;
  869. }
  870. }
  871. }
  872. //
  873. // If we don't have a match, then
  874. // pick the first device of the
  875. // same type.
  876. //
  877. if (pPort == NULL)
  878. {
  879. pbdevicetype = PbdevicetypeFromPszType(
  880. lpRasEntry->szDeviceType
  881. );
  882. //
  883. // Initialize dwErr in case
  884. // we fall through the loop
  885. // without finding a match.
  886. //
  887. // dwErr = ERROR_INVALID_PARAMETER;
  888. //
  889. // Look for a port with the same
  890. // device type.
  891. //
  892. for (pdtlnode = DtlGetFirstNode(pdtllistPorts);
  893. pdtlnode != NULL;
  894. pdtlnode = DtlGetNextNode(pdtlnode))
  895. {
  896. pPort = (PBPORT *)DtlGetData(pdtlnode);
  897. if (pPort->pbdevicetype == pbdevicetype)
  898. {
  899. dwErr = CopyToPbport(&pLink->pbport, pPort);
  900. break;
  901. }
  902. }
  903. if( (NULL == pdtlnode)
  904. && (fNewEntry))
  905. {
  906. //
  907. // Hack to make CM connections work.
  908. // Remove this code after beta
  909. // and just return an error in this case. The api
  910. // should not be setting bogus information.
  911. //
  912. SetBogusPortInformation(pLink, pEntry->dwType);
  913. }
  914. //
  915. // If the device is a modem,
  916. // then set the default modem settings.
  917. //
  918. if (pbdevicetype == PBDT_Modem)
  919. {
  920. SetDefaultModemSettings(pLink);
  921. }
  922. }
  923. // pmay: 401682
  924. //
  925. // Update the preferred device. Whenever this api is called,
  926. // we can assume that the user wants the given device to
  927. // be sticky.
  928. //
  929. if (pPort)
  930. {
  931. Free0(pEntry->pszPreferredDevice);
  932. pEntry->pszPreferredDevice = StrDup(pPort->pszDevice);
  933. Free0(pEntry->pszPreferredPort);
  934. pEntry->pszPreferredPort = StrDup(pPort->pszPort);;
  935. }
  936. //
  937. // Copy the remembered values
  938. //
  939. pLink->pbport.fScriptBefore = fScriptBefore;
  940. pLink->pbport.fScriptBeforeTerminal = fScriptBeforeTerminal;
  941. pLink->pbport.pszScriptBefore = pszScriptBefore;
  942. DtlDestroyList(pdtllistPorts, DestroyPortNode);
  943. if (dwErr)
  944. {
  945. return dwErr;
  946. }
  947. //
  948. // Copy the TAPI configuration blob.
  949. //
  950. if (lpbDeviceConfig != NULL && dwcbDeviceConfig)
  951. {
  952. Free0(pLink->pTapiBlob);
  953. pLink->pTapiBlob = (unsigned char *) Malloc(dwcbDeviceConfig);
  954. if (pLink->pTapiBlob == NULL)
  955. {
  956. return ERROR_NOT_ENOUGH_MEMORY;
  957. }
  958. memcpy(pLink->pTapiBlob,
  959. lpbDeviceConfig,
  960. dwcbDeviceConfig);
  961. pLink->cbTapiBlob = dwcbDeviceConfig;
  962. }
  963. //
  964. // Copy the following fields over only for
  965. // a V401 structure or above.
  966. //
  967. // Winstate only supporting NT5 and above.
  968. //
  969. if ( lpRasEntry->dwSize == sizeof (RASENTRY) )
  970. {
  971. //
  972. // Get multilink and idle timeout information.
  973. //
  974. pEntry->dwDialMode = lpRasEntry->dwDialMode
  975. == RASEDM_DialAsNeeded
  976. ? RASEDM_DialAsNeeded
  977. : RASEDM_DialAll;
  978. pEntry->dwDialPercent =
  979. lpRasEntry->dwDialExtraPercent;
  980. pEntry->dwDialSeconds =
  981. lpRasEntry->dwDialExtraSampleSeconds;
  982. pEntry->dwHangUpPercent =
  983. lpRasEntry->dwHangUpExtraPercent;
  984. pEntry->dwHangUpSeconds =
  985. lpRasEntry->dwHangUpExtraSampleSeconds;
  986. //
  987. // Get idle disconnect information.
  988. //
  989. pEntry->lIdleDisconnectSeconds =
  990. lpRasEntry->dwIdleDisconnectSeconds;
  991. //
  992. // if the user is setting the dwIdleDisconnect
  993. // Seconds through apis then override the user
  994. // preferences.
  995. //
  996. if (pEntry->lIdleDisconnectSeconds)
  997. {
  998. pEntry->dwfOverridePref |= RASOR_IdleDisconnectSeconds;
  999. }
  1000. //
  1001. // CustomScript
  1002. //
  1003. pEntry->dwCustomScript = !!( RASEO_CustomScript
  1004. & lpRasEntry->dwfOptions);
  1005. }
  1006. if(RASET_Phone != lpRasEntry->dwType)
  1007. {
  1008. pEntry->fPreviewPhoneNumber = FALSE;
  1009. pEntry->fSharedPhoneNumbers = FALSE;
  1010. }
  1011. //
  1012. // Copy the following information only if its nt5
  1013. //
  1014. if(lpRasEntry->dwSize == sizeof(RASENTRY))
  1015. {
  1016. //
  1017. // Connection type
  1018. //
  1019. pEntry->dwType = lpRasEntry->dwType;
  1020. //
  1021. // Clear the Encryption type. We set it below
  1022. // for nt5 - default to Mppe40Bit.
  1023. //
  1024. pEntry->dwDataEncryption = 0;
  1025. /*
  1026. if( (ET_40Bit & lpRasEntry->dwEncryptionType)
  1027. || ( (0 == lpRasEntry->dwEncryptionType)
  1028. && ( RASEO_RequireDataEncryption
  1029. & lpRasEntry->dwfOptions)))
  1030. {
  1031. pEntry->dwDataEncryption |= DE_Mppe40bit;
  1032. }
  1033. if(ET_128Bit & lpRasEntry->dwEncryptionType)
  1034. {
  1035. pEntry->dwDataEncryption |= DE_Mppe128bit;
  1036. }
  1037. */
  1038. if( (ET_Require == lpRasEntry->dwEncryptionType)
  1039. || ( (0 == lpRasEntry->dwEncryptionType)
  1040. && ( RASEO_RequireDataEncryption
  1041. & lpRasEntry->dwfOptions)))
  1042. {
  1043. pEntry->dwDataEncryption = DE_Require;
  1044. }
  1045. else if (ET_RequireMax == lpRasEntry->dwEncryptionType)
  1046. {
  1047. pEntry->dwDataEncryption = DE_RequireMax;
  1048. }
  1049. else if (ET_Optional == lpRasEntry->dwEncryptionType)
  1050. {
  1051. pEntry->dwDataEncryption = DE_IfPossible;
  1052. }
  1053. //
  1054. // Clear the authrestrictions for nt5 if the user didn't
  1055. // specify any authentication protocol.
  1056. //
  1057. if( (!(lpRasEntry->dwfOptions & RASEO_RequireMsEncryptedPw))
  1058. && (!(lpRasEntry->dwfOptions & RASEO_RequireEncryptedPw)))
  1059. {
  1060. pEntry->dwAuthRestrictions = 0;
  1061. }
  1062. //
  1063. // Set the new authentication bits based on options defined
  1064. // in NT5.
  1065. //
  1066. if(RASEO_RequireCHAP & lpRasEntry->dwfOptions)
  1067. {
  1068. pEntry->dwAuthRestrictions |= AR_F_AuthMD5CHAP;
  1069. }
  1070. if(RASEO_RequireMsCHAP & lpRasEntry->dwfOptions)
  1071. {
  1072. pEntry->dwAuthRestrictions |= AR_F_AuthMSCHAP;
  1073. }
  1074. if(RASEO_RequireMsCHAP2 & lpRasEntry->dwfOptions)
  1075. {
  1076. pEntry->dwAuthRestrictions |= AR_F_AuthMSCHAP2;
  1077. }
  1078. if(RASEO_RequireW95MSCHAP & lpRasEntry->dwfOptions)
  1079. {
  1080. pEntry->dwAuthRestrictions |= (AR_F_AuthW95MSCHAP | AR_F_AuthCustom);
  1081. }
  1082. if(RASEO_RequirePAP & lpRasEntry->dwfOptions)
  1083. {
  1084. pEntry->dwAuthRestrictions |= AR_F_AuthPAP;
  1085. }
  1086. if(RASEO_RequireSPAP & lpRasEntry->dwfOptions)
  1087. {
  1088. pEntry->dwAuthRestrictions |= AR_F_AuthSPAP;
  1089. }
  1090. if(RASEO_RequireEAP & lpRasEntry->dwfOptions)
  1091. {
  1092. pEntry->dwAuthRestrictions |= AR_F_AuthEAP;
  1093. if( (0 != lpRasEntry->dwCustomAuthKey)
  1094. && (-1 != lpRasEntry->dwCustomAuthKey))
  1095. {
  1096. pEntry->dwCustomAuthKey =
  1097. lpRasEntry->dwCustomAuthKey;
  1098. }
  1099. }
  1100. if(RASEO_Custom & lpRasEntry->dwfOptions)
  1101. {
  1102. pEntry->dwAuthRestrictions |= AR_F_AuthCustom;
  1103. }
  1104. if(0 == pEntry->dwAuthRestrictions)
  1105. {
  1106. pEntry->dwAuthRestrictions = AR_F_TypicalUnsecure;
  1107. }
  1108. //
  1109. // Get custom dial UI information.
  1110. //
  1111. pEntry->pszCustomDialerName =
  1112. lstrlen(lpRasEntry->szCustomDialDll)
  1113. ? StrDup(lpRasEntry->szCustomDialDll)
  1114. : NULL;
  1115. //
  1116. // Set fSharedPhoneNumbers/fPreviewPhoneNumbers
  1117. //
  1118. pEntry->fSharedPhoneNumbers = !!( RASEO_SharedPhoneNumbers
  1119. & lpRasEntry->dwfOptions);
  1120. pEntry->fPreviewPhoneNumber = !!( RASEO_PreviewPhoneNumber
  1121. & lpRasEntry->dwfOptions);
  1122. pEntry->fPreviewUserPw = !!( RASEO_PreviewUserPw
  1123. & lpRasEntry->dwfOptions);
  1124. pEntry->fPreviewDomain = !!( RASEO_PreviewDomain
  1125. & lpRasEntry->dwfOptions);
  1126. pEntry->fShowDialingProgress = !!( RASEO_ShowDialingProgress
  1127. & lpRasEntry->dwfOptions);
  1128. //
  1129. // Vpn strategy
  1130. //
  1131. pEntry->dwVpnStrategy = lpRasEntry->dwVpnStrategy;
  1132. }
  1133. //
  1134. // The following are "adjustments" made for State Migration.
  1135. // chrisab 2-Apr-00
  1136. //
  1137. // Bug 90555 and 90561
  1138. //
  1139. if( (lpRasEntry->dwfOptions & RASEO_RequireEncryptedPw) ||
  1140. (lpRasEntry->dwfOptions & RASEO_RequireMsEncryptedPw) )
  1141. {
  1142. pEntry->dwTypicalAuth = TA_Secure;
  1143. }
  1144. else
  1145. {
  1146. pEntry->dwTypicalAuth = TA_Unsecure;
  1147. }
  1148. //
  1149. // Bug #90554
  1150. // Set log on to network option
  1151. //
  1152. if( lpRasEntry->dwfOptions & RASEO_NetworkLogon )
  1153. {
  1154. pEntry->fPreviewDomain = TRUE;
  1155. }
  1156. //
  1157. // Set dirty bit so this entry will get written out.
  1158. //
  1159. pEntry->fDirty = TRUE;
  1160. return 0;
  1161. }
  1162. //
  1163. // WinState_RasSetEntryProperties()
  1164. //
  1165. // This function replaces the Win32 RAS API RasSetEntryProperties().
  1166. // If the define PRIvATE_RAS
  1167. //
  1168. DWORD WinState_RasSetEntryPropertiesW(
  1169. IN LPCWSTR lpszPhonebook,
  1170. IN LPCWSTR lpszEntry,
  1171. IN LPRASENTRYW lpRasEntry,
  1172. IN DWORD dwcbRasEntry,
  1173. IN LPBYTE lpbDeviceConfig,
  1174. IN DWORD dwcbDeviceConfig
  1175. )
  1176. {
  1177. #ifndef PRIVATE_RAS
  1178. return RasSetEntryProperties(lpszPhonebook,
  1179. lpszEntry,
  1180. lpRasEntry,
  1181. dwcbRasEntry,
  1182. lpbDeviceConfig,
  1183. dwcbDeviceConfig);
  1184. #else
  1185. DWORD dwErr;
  1186. PBFILE pbfile;
  1187. DTLNODE *pdtlnode;
  1188. PBENTRY *pEntry;
  1189. BOOL fCreated;
  1190. // Initialize RASMAN.DLL for stuff needed by phonebook APIs.
  1191. dwErr = LoadRasmanDllAndInit();
  1192. if( dwErr )
  1193. {
  1194. return dwErr;
  1195. }
  1196. if( DwRasInitializeError )
  1197. {
  1198. return DwRasInitializeError;
  1199. }
  1200. // Parameter validation.
  1201. if( lpRasEntry == NULL )
  1202. {
  1203. return ERROR_INVALID_PARAMETER;
  1204. }
  1205. // WinState only supporting NT5 and above.
  1206. if ( (lpRasEntry->dwSize != sizeof (RASENTRYW))
  1207. && (lpRasEntry->dwSize != SIZEOF_STRUCT (RASENTRYW, dwType))
  1208. && (lpRasEntry->dwSize != SIZEOF_STRUCT (RASENTRYW, dwSubEntries)))
  1209. {
  1210. return ERROR_INVALID_SIZE;
  1211. }
  1212. if (dwcbRasEntry < lpRasEntry->dwSize)
  1213. {
  1214. return ERROR_BUFFER_TOO_SMALL;
  1215. }
  1216. //
  1217. // Load the phonebook file.
  1218. //
  1219. EnterCriticalSection(&PhonebookLock);
  1220. // Check and see if the entry name already exists in the phone book
  1221. dwErr = GetPbkAndEntryName(lpszPhonebook,
  1222. lpszEntry,
  1223. 0,
  1224. &pbfile,
  1225. &pdtlnode);
  1226. // if failed for some other reason than the entry doesn't exist, bail.
  1227. if( (dwErr != SUCCESS) && (dwErr != ERROR_CANNOT_FIND_PHONEBOOK_ENTRY) )
  1228. {
  1229. return dwErr;
  1230. }
  1231. // If the entry already exists...
  1232. if( pdtlnode != NULL )
  1233. {
  1234. DTLNODE *pdtlnodeNew = DuplicateEntryNode(pdtlnode);
  1235. DtlRemoveNode(pbfile.pdtllistEntries, pdtlnode);
  1236. DestroyEntryNode(pdtlnode);
  1237. pdtlnode = pdtlnodeNew;
  1238. }
  1239. // New Entry
  1240. else
  1241. {
  1242. dwErr = ReadPhonebookFile(lpszPhonebook,
  1243. NULL,
  1244. NULL,
  1245. 0,
  1246. &pbfile);
  1247. if( dwErr )
  1248. {
  1249. return ERROR_CANNOT_OPEN_PHONEBOOK;
  1250. }
  1251. pdtlnode = CreateEntryNode(TRUE);
  1252. fCreated = TRUE;
  1253. }
  1254. if( pdtlnode == NULL )
  1255. {
  1256. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1257. goto cleanup;
  1258. }
  1259. //
  1260. // Add the node to the list of entries
  1261. //
  1262. DtlAddNodeLast(pbfile.pdtllistEntries, pdtlnode);
  1263. pEntry = (PBENTRY *) DtlGetData(pdtlnode);
  1264. //
  1265. // Convert the RASENTRY to a PBENTRY
  1266. // (Call our private version of this)
  1267. //
  1268. dwErr = WinState_RasEntryToPhonebookEntry(
  1269. lpszEntry,
  1270. lpRasEntry,
  1271. dwcbRasEntry,
  1272. lpbDeviceConfig,
  1273. dwcbDeviceConfig,
  1274. pEntry);
  1275. if( dwErr )
  1276. {
  1277. goto cleanup;
  1278. }
  1279. //
  1280. // Write out the phonebook file
  1281. //
  1282. dwErr = WritePhonebookFile(&pbfile, NULL);
  1283. if( dwErr == ERROR_SUCCESS )
  1284. {
  1285. dwErr = DwSendRasNotification(
  1286. (fCreated) ?
  1287. ENTRY_ADDED :
  1288. ENTRY_MODIFIED,
  1289. pEntry,
  1290. pbfile.pszPath);
  1291. dwErr = ERROR_SUCCESS;
  1292. }
  1293. cleanup:
  1294. ClosePhonebookFile(&pbfile);
  1295. LeaveCriticalSection(&PhonebookLock);
  1296. return dwErr;
  1297. #endif
  1298. }
  1299. //
  1300. // DllMain()
  1301. //
  1302. BOOL
  1303. DllMain(
  1304. HANDLE hinstDll,
  1305. DWORD fdwReason,
  1306. LPVOID lpReserved )
  1307. {
  1308. if( InitializeLoadRAS(fdwReason) == ERROR_SUCCESS )
  1309. return TRUE;
  1310. return FALSE;
  1311. }