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.

4413 lines
136 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: ras.cpp
  4. //
  5. // Module: CMDIAL32.DLL
  6. //
  7. // Synopsis: This module contains the functions to allow Connection Manager to
  8. // interact with RAS.
  9. //
  10. // Copyright (c) 1997-1999 Microsoft Corporation
  11. //
  12. // Author: byao created 04/29/97
  13. // quintinb created Header 08/16/99
  14. //
  15. //+----------------------------------------------------------------------------
  16. #include "cmmaster.h"
  17. #include "compchck.h"
  18. #include "dial_str.h"
  19. #include "dun_str.h"
  20. #include "tunl_str.h"
  21. #include "stp_str.h"
  22. #include "ras_str.h"
  23. #include "dialogs.h"
  24. #include <cmdefs.h> // located in net\inc
  25. //
  26. // CMS flags use to specify DUN settings. These entries are specific
  27. // to this code module, shared entries are stored on dun_str.h
  28. //
  29. const TCHAR* const c_pszCmSectionDunPhone = TEXT("Phone");
  30. const TCHAR* const c_pszCmEntryDunPhoneDialAsIs = TEXT("Dial_As_Is");
  31. const TCHAR* const c_pszCmEntryDunPhonePhoneNumber = TEXT("Phone_Number");
  32. const TCHAR* const c_pszCmEntryDunPhoneAreaCode = TEXT("Area_Code");
  33. const TCHAR* const c_pszCmEntryDunPhoneCountryCode = TEXT("Country_Code");
  34. const TCHAR* const c_pszCmEntryDunPhoneCountryId = TEXT("Country_ID");
  35. const TCHAR* const c_pszCmSectionDunDevice = TEXT("Device");
  36. const TCHAR* const c_pszCmEntryDunDeviceType = TEXT("Type");
  37. const TCHAR* const c_pszCmEntryDunDeviceName = TEXT("Name");
  38. const TCHAR* const c_pszCmEntryHideTrayIcon = TEXT("HideTrayIcon");
  39. const TCHAR* const c_pszCmEntryInternetConnection = TEXT("InternetConnection");
  40. //
  41. // the following reg key and value control whether Dial-Up Networking on Win95
  42. // will start the Wizard. Note that these are explicitly chars instead of TCHARs
  43. //
  44. const CHAR* const c_pszRegRemoteAccess = "RemoteAccess";
  45. const CHAR* const c_pszRegWizard = "wizard";
  46. #define ICM_RAS_REG_WIZARD_VALUE 0x00000080
  47. //
  48. // .CMS flags used only by ras.cpp
  49. //
  50. const TCHAR* const c_pszCmEntryDialExtraPercent = TEXT("DialExtraPercent");
  51. const TCHAR* const c_pszCmEntryDialExtraSampleSeconds = TEXT("DialExtraSampleSeconds");
  52. const TCHAR* const c_pszCmEntryHangUpExtraPercent = TEXT("HangUpExtraPercent");
  53. const TCHAR* const c_pszCmEntryHangUpExtraSampleSeconds = TEXT("HangUpExtraSampleSeconds");
  54. //
  55. // This file includes the definitions of c_ArrayOfRasFuncsW and c_ArrayOfRasFuncsUA below
  56. //
  57. #include "raslink.cpp"
  58. //+----------------------------------------------------------------------------
  59. //
  60. // Function: LinkToRas
  61. //
  62. // Synopsis: Establishes the RAS linkage by populating the inputted RAS Linkage structure
  63. // with function pointers from Rasapi32.dll (on NT) or from cmutoa.dll (Unicode
  64. // to ANSI wrapper functions used on win9x). Most of the actual work is done
  65. // in LinkToDll, this function just does setup work to make sure the correct
  66. // entry points are searched for and that Cmutoa.dll is initialized properly (since it
  67. // needs to link to rasapi32.dll itself to get the actual ANSI RAS API's to work with).
  68. //
  69. // Arguments: RasLinkageStruct *prlsRasLink - pointer to a RAS Linkage structure. This
  70. // structure contains storage for pointers to
  71. // the RAS dll and all of the needed RAS
  72. // function pointers.
  73. //
  74. // Returns: BOOL - FALSE if *any* entry point is still not resolved.
  75. //
  76. // History: quintinb Created Header 01/04/2000
  77. //
  78. //+----------------------------------------------------------------------------
  79. BOOL LinkToRas(RasLinkageStruct *prlsRasLink)
  80. {
  81. BOOL bReturn = TRUE;
  82. //
  83. // Check inputs
  84. //
  85. if (NULL == prlsRasLink)
  86. {
  87. return FALSE;
  88. }
  89. if (OS_NT)
  90. {
  91. //
  92. // On NT we get our RAS APIs from rasapi32.dll and we ask for the W version
  93. // of the API.
  94. //
  95. if (OS_NT4)
  96. {
  97. c_ArrayOfRasFuncsW[11] = NULL; //RasDeleteSubEntry
  98. c_ArrayOfRasFuncsW[12] = NULL; //RasSetCustomAuthData
  99. c_ArrayOfRasFuncsW[13] = NULL; //RasGetEapUserIdentity
  100. c_ArrayOfRasFuncsW[14] = NULL; //RasFreeEapUserIdentity
  101. c_ArrayOfRasFuncsW[15] = NULL; //RasInvokeEapUI
  102. c_ArrayOfRasFuncsW[16] = NULL; //pfnGetCredentials
  103. c_ArrayOfRasFuncsW[17] = NULL; //pfnSetCredentials
  104. }
  105. else if (OS_W2K)
  106. {
  107. //
  108. // Special-casing for APIs that changed after Windows2000 shipped
  109. //
  110. c_ArrayOfRasFuncsW[11] = "DwDeleteSubEntry"; //RasDeleteSubEntry is DwDeleteSubEntry on Win2k
  111. }
  112. bReturn = LinkToDll(&prlsRasLink->hInstRas, "RASAPI32.DLL", c_ArrayOfRasFuncsW,
  113. prlsRasLink->apvPfnRas);
  114. }
  115. else
  116. {
  117. //
  118. // On Win9x we still want the W version of the API but since it isn't available we
  119. // call the wrappers in cmutoa.dll instead. Thus we use cmutoa.dll as our RAS API dll
  120. // and call the UA APIs. We also have an extra step because we want to make sure
  121. // that cmutoa.dll can actually initialize the RAS dll's that it uses for the UA
  122. // conversion functions. Thus we call cmutoa's InitCmRasUtoA function to set up
  123. // its internal RAS linkage. If this function fails, we must fail the RAS link.
  124. typedef BOOL (WINAPI *pfnInitCmRasUtoASpec)(void);
  125. pfnInitCmRasUtoASpec InitCmRasUtoA;
  126. HMODULE hCmUtoADll = LoadLibraryExA("cmutoa.DLL", NULL, 0); // REVIEW: this should use getmodulehandle so as not to change the refcount on the dll.
  127. if (!hCmUtoADll)
  128. {
  129. return FALSE;
  130. }
  131. // Get Initialization routine from the DLL
  132. InitCmRasUtoA = (pfnInitCmRasUtoASpec) GetProcAddress(hCmUtoADll, "InitCmRasUtoA") ;
  133. if (InitCmRasUtoA)
  134. {
  135. bReturn = InitCmRasUtoA();
  136. if (bReturn)
  137. {
  138. if (!OS_MIL)
  139. {
  140. c_ArrayOfRasFuncsUA[10] = NULL; //RasSetSubEntryProperties
  141. c_ArrayOfRasFuncsUA[11] = NULL; //RasDeleteSubEntry
  142. }
  143. bReturn = LinkToDll(&prlsRasLink->hInstRas, "CMUTOA.DLL", c_ArrayOfRasFuncsUA,
  144. prlsRasLink->apvPfnRas);
  145. }
  146. }
  147. FreeLibrary(hCmUtoADll); // we want this to stay in memory but the refcount should also be correct
  148. }
  149. return bReturn;
  150. }
  151. BOOL IsRasLoaded(const RasLinkageStruct * const prlsRasLink)
  152. {
  153. UINT uIndex = 0;
  154. //
  155. // Did we get a valid pointer passed in and does that
  156. // struct contain a pointer to a RAS dll?
  157. //
  158. BOOL bReturn = (NULL != prlsRasLink) && (NULL != prlsRasLink->hInstRas);
  159. //
  160. // The list of functions we are checking for is different on NT
  161. // and Win9x. Note that we also assume that LinkToRas has already
  162. // been called so that the list of functions we are expecting will
  163. // have been modified for the exact platform that we are one. If
  164. // LinkToRas hasn't been called then the hInstRas param should be
  165. // NULL.
  166. //
  167. if (OS_NT)
  168. {
  169. while (bReturn && (NULL != c_ArrayOfRasFuncsW[uIndex]))
  170. {
  171. //
  172. // Check for a NULL function pointer when we have
  173. // a valid function name.
  174. //
  175. if (NULL == prlsRasLink->apvPfnRas[uIndex])
  176. {
  177. bReturn = FALSE;
  178. }
  179. uIndex++;
  180. }
  181. }
  182. else
  183. {
  184. while (bReturn && (NULL != c_ArrayOfRasFuncsUA[uIndex]))
  185. {
  186. //
  187. // Check for a NULL function pointer when we have
  188. // a valid function name.
  189. //
  190. if (NULL == prlsRasLink->apvPfnRas[uIndex])
  191. {
  192. bReturn = FALSE;
  193. }
  194. uIndex++;
  195. }
  196. }
  197. return bReturn;
  198. }
  199. //+----------------------------------------------------------------------------
  200. //
  201. // Function: UnlinkFromRas
  202. //
  203. // Synopsis: This function tears down the linkage with RAS by freeing RAS dll's, calling
  204. // the cmutoa unklinkage function (if necessary), and zeroing the RAS Linkage
  205. // structure passed in.
  206. //
  207. // Arguments: RasLinkageStruct *prlsRasLink - pointer to a RAS Linkage structure. This
  208. // structure contains storage for pointers to
  209. // the RAS dll and all of the needed RAS
  210. // function pointers.
  211. //
  212. // Returns: Nothing
  213. //
  214. // History: quintinb Created Header 01/04/2000
  215. //
  216. //+----------------------------------------------------------------------------
  217. void UnlinkFromRas(RasLinkageStruct *prlsRasLink)
  218. {
  219. if (!OS_NT)
  220. {
  221. HMODULE hCmUtoADll = LoadLibraryExA("cmutoa.dll", NULL, 0);
  222. if (!hCmUtoADll)
  223. {
  224. CMASSERTMSG(FALSE, TEXT("UnlinkFromRas -- Unable to load cmutoa."));
  225. return;
  226. }
  227. FARPROC FreeCmRasUtoA = GetProcAddress(hCmUtoADll, "FreeCmRasUtoA");
  228. if (FreeCmRasUtoA)
  229. {
  230. FreeCmRasUtoA();
  231. }
  232. FreeLibrary(hCmUtoADll);
  233. }
  234. if (prlsRasLink->hInstRas)
  235. {
  236. FreeLibrary(prlsRasLink->hInstRas);
  237. }
  238. memset(prlsRasLink,0,sizeof(RasLinkageStruct));
  239. }
  240. //
  241. // GetRasModems: get a list of modem devices from RAS
  242. //
  243. //+----------------------------------------------------------------------------
  244. //
  245. // Function: GetRasModems
  246. //
  247. // Synopsis: Enumerates the available RAS devices. The device list is allocated and passed
  248. // back to the caller through the pprdiRasDevInfo pointer. This allocated memory
  249. // must be freed by the caller. The count of available devices is stored in the
  250. // pdwCnt input parameter.
  251. //
  252. // Arguments: RasLinkageStruct *prlsRasLink - pointer to the RAS Linkage structure
  253. // LPRASDEVINFO *pprdiRasDevInfo - pointer to hold the RAS device list
  254. // LPDWORD pdwCnt - pointer to hold the count of devices
  255. //
  256. // Returns: BOOL - FALSE if unable to return the enumerated device list.
  257. //
  258. // History: quintinb Created Header 01/04/2000
  259. //
  260. //+----------------------------------------------------------------------------
  261. BOOL GetRasModems(const RasLinkageStruct *prlsRasLink,
  262. LPRASDEVINFO *pprdiRasDevInfo,
  263. LPDWORD pdwCnt)
  264. {
  265. DWORD dwLen;
  266. DWORD dwRes;
  267. DWORD dwCnt;
  268. if (pprdiRasDevInfo)
  269. {
  270. *pprdiRasDevInfo = NULL;
  271. }
  272. if (pdwCnt)
  273. {
  274. *pdwCnt = 0;
  275. }
  276. if (!prlsRasLink->pfnEnumDevices)
  277. {
  278. return (FALSE);
  279. }
  280. dwLen = 0;
  281. dwRes = prlsRasLink->pfnEnumDevices(NULL,&dwLen,&dwCnt);
  282. CMTRACE3(TEXT("GetRasModems() RasEnumDevices(NULL,pdwLen,&dwCnt) returns %u, dwLen=%u, dwCnt=%u."),
  283. dwRes, dwLen, dwCnt);
  284. if (((dwRes != ERROR_SUCCESS) && (dwRes != ERROR_BUFFER_TOO_SMALL)) || (dwLen < sizeof(**pprdiRasDevInfo)))
  285. {
  286. return (FALSE);
  287. }
  288. if (!pprdiRasDevInfo)
  289. {
  290. if (pdwCnt)
  291. {
  292. *pdwCnt = dwCnt;
  293. }
  294. return (TRUE);
  295. }
  296. *pprdiRasDevInfo = (LPRASDEVINFO) CmMalloc(__max(dwLen,sizeof(**pprdiRasDevInfo)));
  297. if (*pprdiRasDevInfo)
  298. {
  299. (*pprdiRasDevInfo)->dwSize = sizeof(**pprdiRasDevInfo);
  300. dwRes = prlsRasLink->pfnEnumDevices(*pprdiRasDevInfo,&dwLen,&dwCnt);
  301. CMTRACE3(TEXT("GetRasModems() RasEnumDevices(*pprdiRasDevInfo,&dwLen,&dwCnt) returns %u, dwLen=%u, dwCnt=%u."),
  302. dwRes, dwLen, dwCnt);
  303. if (dwRes != ERROR_SUCCESS)
  304. {
  305. CmFree(*pprdiRasDevInfo);
  306. *pprdiRasDevInfo = NULL;
  307. return (FALSE);
  308. }
  309. }
  310. else
  311. {
  312. CMASSERTMSG(FALSE, TEXT("GetRasModems -- CmMalloc failed to allocate memory for *pprdiRasDevInfo."));
  313. return (FALSE);
  314. }
  315. if (pdwCnt)
  316. {
  317. *pdwCnt = dwCnt;
  318. }
  319. return (TRUE);
  320. }
  321. //+----------------------------------------------------------------------------
  322. //
  323. // Function: PickModem
  324. //
  325. // Synopsis:
  326. //
  327. // Arguments: const pArgs, the pArgs->pIniProfile contains the modem name
  328. // OUT pszDeviceType, the device type if not NULL
  329. // OUT pszDeviceName, the device name if not NULL
  330. // OUT pfSameModem, Whether the modem found is the same as
  331. // the one in profile
  332. //
  333. // Returns: TRUE, is modem is found
  334. //
  335. // History: fengsun Created Header 10/24/97
  336. //
  337. //+----------------------------------------------------------------------------
  338. BOOL PickModem(IN const ArgsStruct *pArgs, OUT LPTSTR pszDeviceType,
  339. OUT LPTSTR pszDeviceName, OUT BOOL* pfSameModem)
  340. {
  341. LPRASDEVINFO prdiModems;
  342. DWORD dwCnt;
  343. LPTSTR pszModem;
  344. DWORD dwIdx;
  345. BOOL bFound = FALSE;
  346. //
  347. // First, get a list of modems from RAS
  348. //
  349. if (!GetRasModems(&pArgs->rlsRasLink,&prdiModems,&dwCnt) || dwCnt == 0)
  350. {
  351. return (FALSE);
  352. }
  353. if (pfSameModem)
  354. {
  355. *pfSameModem = FALSE;
  356. }
  357. //
  358. // Get the name of the current modem from the service profile and
  359. // try to find a match against non-tunnel RAS devices in the list
  360. //
  361. pszModem = pArgs->piniProfile->GPPS(c_pszCmSection, c_pszCmEntryDialDevice);
  362. if (*pszModem)
  363. {
  364. CMTRACE1(TEXT("PickModem() - looking for match with %s"), pszModem);
  365. for (dwIdx=0; dwIdx < dwCnt; dwIdx++)
  366. {
  367. CMTRACE2(TEXT("PickModem() - examining device (%s) of type (%s)"), prdiModems[dwIdx].szDeviceName, prdiModems[dwIdx].szDeviceType);
  368. //
  369. // we'll take only ISDN and modem devices
  370. //
  371. if (lstrcmpiU(prdiModems[dwIdx].szDeviceType, RASDT_Isdn) &&
  372. lstrcmpiU(prdiModems[dwIdx].szDeviceType, RASDT_Modem) &&
  373. lstrcmpiU(prdiModems[dwIdx].szDeviceType, RASDT_Atm))
  374. {
  375. continue;
  376. }
  377. //
  378. // If we have a match, we're done here
  379. //
  380. if (lstrcmpiU(pszModem,prdiModems[dwIdx].szDeviceName) == 0)
  381. {
  382. CMTRACE(TEXT("PickModem() - match found."));
  383. bFound = TRUE;
  384. if (pfSameModem)
  385. {
  386. *pfSameModem = TRUE;
  387. }
  388. break;
  389. }
  390. }
  391. }
  392. if (FALSE == bFound)
  393. {
  394. //
  395. // No match, find the first non-tunnel device and use it by default.
  396. //
  397. CMTRACE(TEXT("PickModem() - enumerating devices for default match against type RASDT_Isdn, RASDT_Modem or RASDT_Atm"));
  398. for (dwIdx=0; dwIdx < dwCnt; dwIdx++)
  399. {
  400. CMTRACE2(TEXT("PickModem() - examining device (%s) of type (%s)"), prdiModems[dwIdx].szDeviceName, prdiModems[dwIdx].szDeviceType);
  401. //
  402. // we'll take only ISDN and modem devices
  403. //
  404. if (!lstrcmpiU(prdiModems[dwIdx].szDeviceType, RASDT_Isdn) ||
  405. !lstrcmpiU(prdiModems[dwIdx].szDeviceType, RASDT_Modem) ||
  406. !lstrcmpiU(prdiModems[dwIdx].szDeviceType, RASDT_Atm))
  407. {
  408. CMTRACE2(TEXT("PickModem() - default device (%s) of type (%s) selected."), prdiModems[dwIdx].szDeviceName, prdiModems[dwIdx].szDeviceType);
  409. bFound = TRUE;
  410. break;
  411. }
  412. }
  413. }
  414. //
  415. // If we have a match, fill device name and device type
  416. //
  417. if (bFound)
  418. {
  419. if (pszDeviceType)
  420. {
  421. lstrcpyU(pszDeviceType,prdiModems[dwIdx].szDeviceType);
  422. }
  423. if (pszDeviceName)
  424. {
  425. lstrcpyU(pszDeviceName,prdiModems[dwIdx].szDeviceName);
  426. }
  427. }
  428. CmFree(pszModem);
  429. CmFree(prdiModems);
  430. return (bFound);
  431. }
  432. //+----------------------------------------------------------------------------
  433. //
  434. // Function: GetDeviceType
  435. //
  436. // Synopsis: Get the deviceType for a chosen device name
  437. //
  438. // Arguments: pArgs - Pointer to ArgsStruct
  439. // pszDeviceType[OUT] - pointer to buffer where device
  440. // type will be returned
  441. // uNumCharsInDeviceType [IN] - number of chars of memory available in pszDeviceType
  442. // pszDeviceName[IN] - device name
  443. //
  444. // Returns: TRUE on success, FALSE otherwise
  445. //
  446. // History: byao Created 03/21/97
  447. //-----------------------------------------------------------------------------
  448. BOOL GetDeviceType(ArgsStruct *pArgs, LPTSTR pszDeviceType, UINT uNumCharsInDeviceType, LPTSTR pszDeviceName)
  449. {
  450. LPRASDEVINFO prdiModems;
  451. DWORD dwCnt, dwIdx;
  452. if (!pszDeviceType)
  453. {
  454. return FALSE;
  455. }
  456. // first, get a list of modems from RAS
  457. if (!GetRasModems(&pArgs->rlsRasLink,&prdiModems,&dwCnt))
  458. {
  459. return (FALSE);
  460. }
  461. // choose the device that has the same name as pszDeviceName
  462. for (dwIdx=0;dwIdx<dwCnt;dwIdx++)
  463. {
  464. if (lstrcmpiU(pszDeviceName,prdiModems[dwIdx].szDeviceName) == 0)
  465. {
  466. lstrcpynU(pszDeviceType, prdiModems[dwIdx].szDeviceType, uNumCharsInDeviceType);
  467. break;
  468. }
  469. }
  470. CmFree(prdiModems);
  471. if (dwIdx == dwCnt) // not found in the modem list -- strange things happened
  472. {
  473. return FALSE;
  474. }
  475. return TRUE;
  476. }
  477. //+----------------------------------------------------------------------------
  478. //
  479. // Function PickTunnelDevice
  480. //
  481. // Synopsis pick a tunnel device used to dial out
  482. //
  483. // Arguments
  484. // pszDeviceType Tunnel device type. -- RASDT_Vpn
  485. // pszDeviceName Tunnel device name
  486. // prdiModems Pointer to a list of modems
  487. // dwCnt Total number of modems available in the system
  488. //
  489. // Returns TRUE succeed
  490. // FALSE otherwise
  491. //
  492. // History 3/1/97 byao Created
  493. //
  494. //-----------------------------------------------------------------------------
  495. BOOL PickTunnelDevice(LPTSTR pszDeviceType,
  496. LPTSTR pszDeviceName,
  497. LPRASDEVINFO prdiModems,
  498. DWORD dwCnt)
  499. {
  500. DWORD dwIdx;
  501. if (dwCnt == 0)
  502. {
  503. return (FALSE);
  504. }
  505. for (dwIdx=0;dwIdx<dwCnt;dwIdx++)
  506. {
  507. if (lstrcmpiU(pszDeviceType,prdiModems[dwIdx].szDeviceType) == 0)
  508. {
  509. break;
  510. }
  511. }
  512. if (dwIdx == dwCnt)
  513. {
  514. return (FALSE);
  515. }
  516. if (pszDeviceType)
  517. {
  518. lstrcpyU(pszDeviceType,prdiModems[dwIdx].szDeviceType);
  519. }
  520. if (pszDeviceName)
  521. {
  522. lstrcpyU(pszDeviceName,prdiModems[dwIdx].szDeviceName);
  523. }
  524. return (TRUE);
  525. }
  526. //+----------------------------------------------------------------------------
  527. //
  528. // Function PickTunnelDevice
  529. //
  530. // Synopsis pick a tunnel device used to dial out
  531. //
  532. // Arguments pArgs Pointer to ArgsStruct
  533. // pszDeviceType Tunnel device type. -- RASDT_Vpn
  534. // pszDeviceName Tunnel device name
  535. //
  536. // Returns TRUE - scripting has been installed
  537. //
  538. // History 3/1/97 byao Created
  539. //
  540. //-----------------------------------------------------------------------------
  541. BOOL PickTunnelDevice(ArgsStruct *pArgs,
  542. LPTSTR pszDeviceType,
  543. LPTSTR pszDeviceName)
  544. {
  545. LPRASDEVINFO prdiModems;
  546. DWORD dwCnt;
  547. BOOL bRes;
  548. // first, get a list of modems from RAS
  549. if (!GetRasModems(&pArgs->rlsRasLink,&prdiModems,&dwCnt))
  550. {
  551. return (FALSE);
  552. }
  553. // then, pick up the one used for tunneling
  554. bRes = PickTunnelDevice(pszDeviceType,pszDeviceName,prdiModems,dwCnt);
  555. CmFree(prdiModems);
  556. return (bRes);
  557. }
  558. //+----------------------------------------------------------------------------
  559. //
  560. // Function: CopyAutoDial
  561. //
  562. // Synopsis: Sets the szAutodialDll and szAutodialFunc members of the
  563. // specified RAS entry structure with our module name and
  564. // InetDialHandler repectively. Not on NT5.
  565. //
  566. // Arguments: LPRASENTRY preEntry - Ptr to the Ras entry structure.
  567. //
  568. // Returns: Nothing
  569. //
  570. // History: nickball Created Header 03/16/98
  571. // nickball Removed from NT5 11/17/98
  572. //
  573. //+----------------------------------------------------------------------------
  574. void CopyAutoDial(LPRASENTRY preEntry)
  575. {
  576. MYDBGASSERT(preEntry);
  577. //
  578. // Don't set these on NT5, they are no longer used by IE and the
  579. // InetDialHandler prototype differs from that used by RAS
  580. //
  581. if (OS_NT5 || NULL == preEntry)
  582. {
  583. return;
  584. }
  585. memset(preEntry->szAutodialDll,0,sizeof(preEntry->szAutodialDll));
  586. //
  587. // Set szAutodialDll with our Module name
  588. //
  589. GetModuleFileNameU(g_hInst, preEntry->szAutodialDll, sizeof(preEntry->szAutodialDll)/sizeof(TCHAR));
  590. //
  591. // Set szAutodialFunc with the mangled form of InetDialHandler
  592. //
  593. memset(preEntry->szAutodialFunc,0,sizeof(preEntry->szAutodialFunc));
  594. lstrcpyU(preEntry->szAutodialFunc, c_pszInetDialHandler);
  595. }
  596. //+----------------------------------------------------------------------------
  597. //
  598. // Function MyRGEP
  599. //
  600. // Synopsis Call RasGetEntryProperties()
  601. //
  602. // Arguments
  603. //
  604. // Returns
  605. //
  606. // Histroy Revised to improve performance 08/7/97 fengsun
  607. //-----------------------------------------------------------------------------
  608. LPRASENTRY MyRGEP(LPCTSTR pszRasPbk, LPCTSTR pszEntryName, RasLinkageStruct *prlsRasLink)
  609. {
  610. LPRASENTRY preRasEntry;
  611. DWORD dwRes;
  612. if (!(preRasEntry = AllocateRasEntry()))
  613. {
  614. MYDBGASSERT(0);
  615. return NULL;
  616. }
  617. DWORD dwRasEntry = preRasEntry->dwSize;
  618. dwRes = prlsRasLink->pfnGetEntryProperties(pszRasPbk,
  619. pszEntryName,
  620. preRasEntry,
  621. &dwRasEntry,
  622. NULL, // lpbDeviceInfo
  623. NULL); // lpdwDeviceInfoSize
  624. CMTRACE2(TEXT("MyRGEP() - dwRasEntry = %u : sizeof(*preRasEntry) = %u"), dwRasEntry, sizeof(*preRasEntry));
  625. if ((dwRes == ERROR_BUFFER_TOO_SMALL) && (dwRasEntry >= sizeof(*preRasEntry)))
  626. {
  627. //
  628. // If the memory if not large enough, realloc one
  629. //
  630. CmFree(preRasEntry);
  631. preRasEntry = (LPRASENTRY) CmMalloc(dwRasEntry);
  632. if (NULL != preRasEntry)
  633. {
  634. //
  635. // dwSize has to be set to sizeof(RASENTRY)
  636. // because dwRasEntry contains the additional
  637. // bytes required for this connectoid (alternative
  638. // phone numbers, etc.
  639. //
  640. preRasEntry->dwSize = sizeof(RASENTRY); // Specifies version
  641. dwRes = prlsRasLink->pfnGetEntryProperties (pszRasPbk,
  642. pszEntryName,
  643. preRasEntry,
  644. &dwRasEntry,
  645. NULL,
  646. NULL);
  647. }
  648. else
  649. {
  650. MYDBGASSERT(0);
  651. return NULL;
  652. }
  653. }
  654. if (dwRes != ERROR_SUCCESS)
  655. {
  656. CMTRACE3(TEXT("MyRGEP(*pszRasPbk=%s, *pszEntryName=%s) RasGetEntryProperties returned %u"), pszRasPbk, pszEntryName, dwRes);
  657. CmFree(preRasEntry);
  658. preRasEntry = NULL;
  659. }
  660. SetLastError(dwRes);
  661. return (preRasEntry);
  662. }
  663. //+----------------------------------------------------------------------------
  664. //
  665. // Function IsConnectErrorFatal
  666. //
  667. // Synopsis Determine if an error is recoverable, (ie. we should re-dial).
  668. //
  669. // Arguments DWORD dwErr - The RAS error code
  670. // ArgsStruct* pArgs - Ptr to global args struct
  671. //
  672. // Returns TRUE if error is fatal
  673. //
  674. // Histroy nickball Created header 05/21/99
  675. //
  676. //-----------------------------------------------------------------------------
  677. BOOL IsConnectErrorFatal(DWORD dwErr, ArgsStruct *pArgs)
  678. {
  679. switch (dwErr)
  680. {
  681. //
  682. // The following cases are W9x ISDN error returns that actually mean
  683. // different things on WinNT. Since we use the NT header files, we don't
  684. // have an include file that contains these errors. We have to special
  685. // case these so that we recognize them as ISDN errors, and reconnect as
  686. // appropriate.
  687. //
  688. // The 9x errors are listed below along with the NT equivalents.
  689. //
  690. case 751: // 9x.ERROR_BAD_DEST_ADDRESS == NT.ERROR_INVALID_CALLBACK_NUMBER
  691. case 752: // 9x.ERROR_UNREACHABLE_DEST == NT.ERROR_SCRIPT_SYNTAX
  692. case 753: // 9x.ERROR_INCOMPATIBLE_DEST == NT.ERROR_HANGUP_FAILED
  693. case 754: // 9x.ERROR_NETWORK_CONGESTION == NT.ERROR_BUNDLE_NOT_FOUND
  694. case 755: // 9x.ERROR_CALL_BLOCKED == NT.ERROR_CANNOT_DO_CUSTOMDIAL
  695. case 756: // 9x.ERROR_NETWORK_TEMPFAILURE == NT.ERROR_DIAL_ALREADY_IN_PROGRESS
  696. if (OS_W9X)
  697. {
  698. //
  699. // On W9x, if you have an invalid ISDN number, the error codes
  700. // returned by Millennium RAS are different from the NT ones.
  701. // We have to special-case these by number so that we reconnect
  702. //
  703. CMTRACE1(TEXT("IsConnectErrorFatal : handled Win9x ISDN error %d"), dwErr);
  704. return FALSE;
  705. }
  706. break;
  707. case ERROR_PPP_TIMEOUT: // Timed out waiting for a valid response from the remote PPP peer.%0
  708. case ERROR_PPP_REMOTE_TERMINATED: // PPP terminated by remote machine.%0
  709. case ERROR_PPP_INVALID_PACKET: // The PPP packet is invalid.%0
  710. case ERROR_PPP_NO_RESPONSE: // Remote PPP peer is not responding
  711. case ERROR_SERVER_NOT_RESPONDING:
  712. case ERROR_LINE_BUSY:
  713. case ERROR_NO_CARRIER:
  714. case ERROR_REMOTE_DISCONNECTION:
  715. case ERROR_BAD_ADDRESS_SPECIFIED:
  716. case ERROR_AUTOMATIC_VPN_FAILED: // New ras error for VPN
  717. return FALSE;
  718. break;
  719. case ERROR_NO_ANSWER:
  720. {
  721. //
  722. // For ISDN (Whistler bug#384223) we want to make sure CM displays the correct ras error (same as TAPI)
  723. // thus we have to treat this error as a fatal error.
  724. // This should return TRUE for the first time we are dialing and only dual-channel mode
  725. //
  726. if (0 == lstrcmpiU(pArgs->szDeviceType, RASDT_Isdn) && (pArgs->nMaxRedials == pArgs->nRedialCnt))
  727. {
  728. if (CM_ISDN_MODE_DUALCHANNEL_ONLY == pArgs->dwIsdnDialMode)
  729. {
  730. return TRUE;
  731. }
  732. }
  733. return FALSE;
  734. break;
  735. }
  736. default:
  737. break;
  738. }
  739. return TRUE;
  740. }
  741. //+----------------------------------------------------------------------------
  742. //
  743. // Function IsRasError
  744. //
  745. // Synopsis Simple function to determine if an error falls in the RAS range
  746. //
  747. // Arguments DWORD dwErr - The error code
  748. //
  749. // Returns TRUE if error is within RAS range
  750. //
  751. // Histroy nickball Created header 05/21/99
  752. //
  753. //-----------------------------------------------------------------------------
  754. inline BOOL IsRasError(DWORD dwErr)
  755. {
  756. return ((dwErr >= RASBASE) && (dwErr <= RASBASEEND));
  757. }
  758. //+----------------------------------------------------------------------------
  759. //
  760. // Function CheckConnectionError
  761. //
  762. // Synopsis Determine if a RAS error is recoverable. If not recoverable,
  763. // retrieves the appropriate error message for display.
  764. //
  765. // Arguments DWORD dwErr - The RAS error code
  766. // ArgsStruct* pArgs - Ptr to global args struct
  767. // BOOL fTunneling - Flag indicating whether we're tunneling
  768. // LPTSTR *ppszRasErrMsg - Pointer to pointer for message string
  769. //
  770. // Returns TRUE if error is fatal
  771. //
  772. // Histroy nickball Created header 05/21/99
  773. //
  774. //-----------------------------------------------------------------------------
  775. BOOL CheckConnectionError(HWND hwndDlg,
  776. DWORD dwErr,
  777. ArgsStruct *pArgs,
  778. BOOL fTunneling,
  779. LPTSTR *ppszRasErrMsg)
  780. {
  781. DWORD dwIdMsg = 0;
  782. LPTSTR pszMsg = NULL;
  783. LPTSTR pszTmp = NULL;
  784. //
  785. // Examine the error more closely. Note: For W2K, we skip RAS
  786. // errors and query RAS for a displayable error string below.
  787. //
  788. if ((!OS_NT5) || (!IsRasError(dwErr)))
  789. {
  790. switch (dwErr)
  791. {
  792. case ERROR_PPP_TIMEOUT: // Timed out waiting for a valid response from the remote PPP peer.%0
  793. case ERROR_PPP_REMOTE_TERMINATED: // PPP terminated by remote machine.%0
  794. case ERROR_PPP_INVALID_PACKET: // The PPP packet is invalid.%0
  795. case ERROR_PPP_NO_RESPONSE: // Remote PPP peer is not responding
  796. case ERROR_SERVER_NOT_RESPONDING:
  797. dwIdMsg = IDMSG_PPPPROBLEM;
  798. break;
  799. case ERROR_LINE_BUSY:
  800. if ((pArgs->nDialIdx+1 == MAX_PHONE_NUMBERS ||
  801. !pArgs->aDialInfo[pArgs->nDialIdx+1].szDialablePhoneNumber[0]) &&
  802. !pArgs->nRedialCnt)
  803. dwIdMsg = IDMSG_LINEBUSY;
  804. else
  805. dwIdMsg = IDMSG_LINEBUSYREDIAL;
  806. break;
  807. case ERROR_NO_ANSWER:
  808. case ERROR_NO_CARRIER:
  809. if ((pArgs->nDialIdx+1 == MAX_PHONE_NUMBERS ||
  810. !pArgs->aDialInfo[pArgs->nDialIdx+1].szDialablePhoneNumber[0]) &&
  811. !pArgs->nRedialCnt)
  812. dwIdMsg = fTunneling ? IDMSG_TUNNEL_NOANSWER : IDMSG_NOANSWER ;
  813. else
  814. dwIdMsg = fTunneling ? IDMSG_TUNNEL_NOANSWERREDIAL : IDMSG_NOANSWERREDIAL;
  815. break;
  816. case ERROR_REMOTE_DISCONNECTION:
  817. dwIdMsg = IDMSG_REMOTEDISCONNECTED;
  818. break;
  819. case ERROR_BAD_ADDRESS_SPECIFIED:
  820. dwIdMsg = IDMSG_TUNNEL_NOANSWERREDIAL;
  821. break;
  822. case ERROR_PPP_NO_PROTOCOLS_CONFIGURED: // No PPP control protocols configured.%0
  823. dwIdMsg = IDMSG_TCPIPPROBLEM;
  824. break;
  825. case ERROR_PORT_ALREADY_OPEN:
  826. dwIdMsg = fTunneling ? IDMSG_TUNNELINUSE : IDMSG_PORTINUSE ;
  827. break;
  828. case ERROR_FROM_DEVICE:
  829. dwIdMsg = IDMSG_DEVICEERROR;
  830. break;
  831. case ERROR_HARDWARE_FAILURE:
  832. case ERROR_PORT_OR_DEVICE: //11694
  833. case ERROR_DEVICE_NOT_READY:
  834. dwIdMsg = IDMSG_NOTRESPONDING;
  835. break;
  836. case ERROR_NO_DIALTONE:
  837. dwIdMsg = IDMSG_NODIALTONE;
  838. break;
  839. case ERROR_CANCELLED:
  840. case ERROR_USER_DISCONNECTION:
  841. dwIdMsg = IDMSG_CANCELED;
  842. break;
  843. case ERROR_AUTHENTICATION_FAILURE:
  844. case ERROR_ACCESS_DENIED: // 13795 // WINDOWS ERROR
  845. dwIdMsg = IDMSG_BADPASSWORD;
  846. break;
  847. case ERROR_VOICE_ANSWER:
  848. dwIdMsg = IDMSG_VOICEANSWER;
  849. break;
  850. case ERROR_PORT_NOT_AVAILABLE:
  851. if (IsDialingTunnel(pArgs))
  852. {
  853. dwIdMsg = IDMSG_TUNNELNOTAVAILABLE;
  854. }
  855. else
  856. {
  857. dwIdMsg = IDMSG_PORTNOTAVAILABLE;
  858. }
  859. break;
  860. case ERROR_PORT_NOT_CONFIGURED:
  861. dwIdMsg = IDMSG_PORTNOTCONFIGURED;
  862. break;
  863. case ERROR_RESTRICTED_LOGON_HOURS:
  864. dwIdMsg = IDMSG_RESTRICTEDLOGONHOURS;
  865. break;
  866. case ERROR_ACCT_DISABLED:
  867. case ERROR_ACCT_EXPIRED:
  868. dwIdMsg = IDMSG_ACCTDISABLED;
  869. break;
  870. case ERROR_PASSWD_EXPIRED:
  871. dwIdMsg = IDMSG_PASSWDEXPIRED;
  872. break;
  873. case ERROR_NO_DIALIN_PERMISSION:
  874. dwIdMsg = IDMSG_NODIALINPERMISSION;
  875. break;
  876. case ERROR_PROTOCOL_NOT_CONFIGURED:
  877. dwIdMsg = IDMSG_PROTOCOL_NOT_CONFIGURED;
  878. break;
  879. case ERROR_INVALID_DATA: // WINDOWS ERROR
  880. //
  881. // The specific case in which we encountered DUN settings
  882. // that aren't supported on the current platform
  883. //
  884. CMTRACE(TEXT("CheckConnectionError - Unsupported DUN setting detected"));
  885. dwIdMsg = IDMSG_UNSUPPORTED_SETTING;
  886. break;
  887. case ERROR_BAD_PHONE_NUMBER: // TBD - drop through to default
  888. default:
  889. break;
  890. }
  891. }
  892. if (0 == dwIdMsg)
  893. {
  894. //
  895. // If no message ID was picked up, then try to get one from RAS
  896. //
  897. if (pArgs->rlsRasLink.pfnGetErrorString)
  898. {
  899. DWORD dwRes;
  900. DWORD dwFmtMsgId;
  901. pszTmp = (LPTSTR) CmMalloc(256 * sizeof(TCHAR)); // Docs say 256 chars is always enough.
  902. if (pszTmp)
  903. {
  904. dwRes = pArgs->rlsRasLink.pfnGetErrorString((UINT) dwErr, pszTmp, (DWORD) 256);
  905. if (ERROR_SUCCESS == dwRes)
  906. {
  907. pszMsg = CmFmtMsg(g_hInst, IDMSG_RAS_ERROR, pszTmp, dwErr);
  908. }
  909. }
  910. CmFree(pszTmp);
  911. }
  912. if (NULL == pszMsg)
  913. {
  914. //
  915. // Still no message, try to get description from system (on NT)
  916. // Note: HRESULTS are displayed in Hex, Win errors are decimal.
  917. if (OS_NT)
  918. {
  919. if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER + FORMAT_MESSAGE_IGNORE_INSERTS + FORMAT_MESSAGE_FROM_SYSTEM,
  920. NULL, dwErr, 0, (LPTSTR) &pszTmp, 1, NULL))
  921. {
  922. if (pszTmp)
  923. {
  924. pszMsg = CmFmtMsg(g_hInst, (dwErr > 0x7FFFFFFF) ? IDMSG_SYS_ERROR_HEX : IDMSG_SYS_ERROR_DEC, pszTmp, dwErr);
  925. LocalFree(pszTmp);
  926. }
  927. else
  928. {
  929. CMASSERTMSG(FALSE, TEXT("CheckConnectionError -- FormatMessage failed to allocate pszTmp."));
  930. }
  931. }
  932. }
  933. if (NULL == pszMsg)
  934. {
  935. //
  936. // Still no message, go with default
  937. //
  938. pszMsg = CmFmtMsg(g_hInst, (dwErr > 0x7FFFFFFF) ? IDMSG_CM_ERROR_HEX : IDMSG_CM_ERROR_DEC, dwErr);
  939. }
  940. }
  941. }
  942. //
  943. // Special check for tunneling to verify that we have a device name
  944. //
  945. if (IsDialingTunnel(pArgs))
  946. {
  947. //
  948. // Check whether the tunnel device name is valid
  949. //
  950. if (!PickTunnelDevice(pArgs,pArgs->szTunnelDeviceType,pArgs->szTunnelDeviceName))
  951. {
  952. pArgs->szTunnelDeviceName[0]= TEXT('\0');
  953. pArgs->piniProfile->WPPS(c_pszCmSection, c_pszCmEntryTunnelDevice, TEXT(""));
  954. pszMsg = CmLoadString(g_hInst, GetPPTPMsgId());
  955. dwIdMsg = 0;
  956. }
  957. pArgs->piniProfile->WPPS(c_pszCmSection, c_pszCmEntryTunnelDevice, pArgs->szTunnelDeviceName);
  958. }
  959. //
  960. // If we have a message ID format it for display
  961. //
  962. if (dwIdMsg)
  963. {
  964. MYDBGASSERT(!pszMsg);
  965. pszMsg = CmFmtMsg(g_hInst,dwIdMsg);
  966. }
  967. if (pszMsg)
  968. {
  969. if (!ppszRasErrMsg)
  970. {
  971. AppendStatusPane(hwndDlg,pszMsg);
  972. CmFree(pszMsg);
  973. }
  974. else
  975. {
  976. //
  977. // pass the msg to the caller. the caller needs to free it.
  978. //
  979. *ppszRasErrMsg = pszMsg;
  980. }
  981. }
  982. BOOL bCancel = IsConnectErrorFatal(dwErr, pArgs);
  983. if (bCancel && dwErr != ERROR_CANCELLED &&
  984. dwErr != ERROR_AUTHENTICATION_FAILURE &&
  985. dwErr != ERROR_ACCESS_DENIED)
  986. {
  987. //
  988. // if we're canceling redial, then there might be something
  989. // seriously wrong. We want to recheck our configs the next
  990. // time CM is run.
  991. //
  992. ClearComponentsChecked();
  993. }
  994. return (bCancel);
  995. }
  996. //+----------------------------------------------------------------------------
  997. //
  998. // Function GetRasConnectoidName
  999. //
  1000. // Synopsis Construct a RAS connectoid name.
  1001. //
  1002. // The connectoid name is "<long service name>-[Primary|Backup]".
  1003. // or "<long service name>&Tunnel" for the case of tunnel entry.
  1004. //
  1005. // Arguments pArgs Pointer to ArgsStruct
  1006. // piniService[IN] the service obj
  1007. // fTunnelEntry[IN] TRUE: This connectoid is for tunneling
  1008. // FALSE: otherwise
  1009. //
  1010. // Returns LPTSTR The connectoid name.
  1011. //
  1012. //-----------------------------------------------------------------------------
  1013. LPTSTR GetRasConnectoidName(
  1014. ArgsStruct *pArgs,
  1015. CIni* piniService,
  1016. BOOL fTunnelEntry
  1017. )
  1018. {
  1019. LPTSTR pszConnectoid = GetServiceName(piniService);
  1020. if (pszConnectoid)
  1021. {
  1022. //
  1023. // If tunneling 9X connectoid, append the Tunnel
  1024. // Suffix - e.g. "Tunnel (for advanced use only)"
  1025. //
  1026. if (OS_W9X && fTunnelEntry)
  1027. {
  1028. LPTSTR pszSuffix = GetTunnelSuffix();
  1029. if (pszSuffix)
  1030. {
  1031. pszConnectoid = CmStrCatAlloc(&pszConnectoid, pszSuffix);
  1032. }
  1033. CmFree(pszSuffix);
  1034. }
  1035. }
  1036. return pszConnectoid;
  1037. }
  1038. //+----------------------------------------------------------------------------
  1039. //
  1040. // Function CreateRASEntryStruct
  1041. //
  1042. // Synopsis Create a connectoid with the settings specified in the cms.
  1043. // If a parameter does NOT exist in the cms file, the corresponding
  1044. // value is used.
  1045. //
  1046. // The connectoid name is "<long service name>-[Primary|Backup]".
  1047. // or "<long service name>&Tunnel" for the case of tunnel entry.
  1048. //
  1049. // Arguments pArgs Pointer to ArgsStruct
  1050. // pszDUN DUN name
  1051. // piniService[IN] the service file obj
  1052. // fTunnelEntry[IN] TRUE: This connectoid is for tunneling
  1053. // FALSE: otherwise
  1054. // pszRasPbk the RAS phonebook in which the connectoid is located
  1055. // ppbEapData[OUT] Address of pointer to store EapData, allocated here.
  1056. // pdwEapSize[OUT] Ptr to a DWORD to record the size of the data blob.
  1057. //
  1058. // Returns LPRASENTRY The new RAS connectoid
  1059. //
  1060. // History 5/12/97 henryt created
  1061. // 5/23/97 byao Modified: added fSkipProfile flag
  1062. // 6/9/97 byao Modified: use DUN= field when the
  1063. // phone number has no DUN name associated
  1064. // 7/28/97 byao Added change for #10459
  1065. // 4/13/97 nickball Renamed, return LPRASENTRY
  1066. //-----------------------------------------------------------------------------
  1067. LPRASENTRY CreateRASEntryStruct(
  1068. ArgsStruct *pArgs,
  1069. LPCTSTR pszDUN,
  1070. CIni* piniService,
  1071. BOOL fTunnelEntry,
  1072. LPTSTR pszRasPbk,
  1073. LPBYTE *ppbEapData,
  1074. LPDWORD pdwEapSize
  1075. )
  1076. {
  1077. LPTSTR pszDunEntry = NULL;
  1078. DWORD dwErr;
  1079. BOOL bTmp;
  1080. //
  1081. // first we need to create a RAS entry in memory with default values
  1082. //
  1083. LPRASENTRY preBuffer = AllocateRasEntry();
  1084. if (!preBuffer)
  1085. {
  1086. return NULL;
  1087. }
  1088. MYDBGASSERT(preBuffer->dwSize >= sizeof(*preBuffer));
  1089. //
  1090. // Set up the preBuffer to defaults value
  1091. //
  1092. preBuffer->dwFramingProtocol = RASFP_Ppp;
  1093. //
  1094. // Allow only TCP/IP by default
  1095. //
  1096. preBuffer->dwfNetProtocols |= RASNP_Ip;
  1097. //
  1098. // Set default RASEO settings.
  1099. //
  1100. if (!fTunnelEntry)
  1101. {
  1102. preBuffer->dwfOptions |= RASEO_UseCountryAndAreaCodes |
  1103. RASEO_IpHeaderCompression |
  1104. RASEO_RemoteDefaultGateway |
  1105. RASEO_SwCompression;
  1106. //RASEO_SecureLocalFiles; // NT 427042
  1107. //RASEO_DisableLcpExtensions; //13059 Olympus + 289461 NT
  1108. //
  1109. // We want to honor the HideTrayIcon flag. If it is not NT5, then
  1110. // we always set this flag. If it is NT5, then we should only set
  1111. // this flag if HideTrayIcon is false.
  1112. //
  1113. if (!OS_NT5 || !(pArgs->piniService->GPPI(c_pszCmSection, c_pszCmEntryHideTrayIcon)))
  1114. {
  1115. preBuffer->dwfOptions |= RASEO_ModemLights;
  1116. }
  1117. //
  1118. // In order for users to be able to specify device settings on Whistler,
  1119. // they have to do it from the control panel and we have to set the
  1120. // RASEO2_UseGlobalDeviceSettings flag in dwfOptions2.
  1121. //
  1122. if (OS_NT51)
  1123. {
  1124. ((LPRASENTRY_V501)preBuffer)->dwfOptions2 |= RASEO2_UseGlobalDeviceSettings;
  1125. }
  1126. //
  1127. // We should have the devicename/devicetype by now.
  1128. // (PickModem should be called)
  1129. //
  1130. MYDBGASSERT(pArgs->szDeviceType[0]);
  1131. MYDBGASSERT(pArgs->szDeviceName[0]);
  1132. lstrcpynU(preBuffer->szDeviceType, pArgs->szDeviceType,
  1133. sizeof(preBuffer->szDeviceType)/sizeof(TCHAR));
  1134. lstrcpynU(preBuffer->szDeviceName, pArgs->szDeviceName,
  1135. sizeof(preBuffer->szDeviceName)/sizeof(TCHAR));
  1136. }
  1137. else
  1138. {
  1139. preBuffer->dwfOptions = RASEO_IpHeaderCompression |
  1140. RASEO_RemoteDefaultGateway |
  1141. RASEO_NetworkLogon |
  1142. RASEO_SwCompression;
  1143. //RASEO_SecureLocalFiles // NT 427042
  1144. //RASEO_DisableLcpExtensions
  1145. //
  1146. // Always set Modem lights on direct connection, unless HideTrayIcon
  1147. // flag is explicitly set in the .CMS. #262825, #262988
  1148. //
  1149. if (!(pArgs->piniService->GPPI(c_pszCmSection, c_pszCmEntryHideTrayIcon)))
  1150. {
  1151. preBuffer->dwfOptions |= RASEO_ModemLights;
  1152. }
  1153. MYDBGASSERT(pArgs->szTunnelDeviceType[0]);
  1154. MYDBGASSERT(pArgs->szTunnelDeviceName[0]);
  1155. lstrcpynU(preBuffer->szDeviceType, pArgs->szTunnelDeviceType,
  1156. sizeof(preBuffer->szDeviceType)/sizeof(TCHAR));
  1157. lstrcpynU(preBuffer->szDeviceName, pArgs->szTunnelDeviceName,
  1158. sizeof(preBuffer->szDeviceName)/sizeof(TCHAR));
  1159. lstrcpyU(preBuffer->szLocalPhoneNumber, pArgs->GetTunnelAddress());
  1160. }
  1161. //
  1162. // Check to see if we need to tell RAS that this connection has Internet Connectivity or not
  1163. //
  1164. if (OS_NT51)
  1165. {
  1166. //
  1167. // Note that we use the top level service profile on purpose here (pArgs->pIniService directly)
  1168. // as this is a profile global setting.
  1169. //
  1170. if (pArgs->piniService->GPPB(c_pszCmSection, c_pszCmEntryInternetConnection,
  1171. (BOOL) ((LPRASENTRY_V501)preBuffer)->dwfOptions2 & RASEO2_Internet))
  1172. {
  1173. ((LPRASENTRY_V501)preBuffer)->dwfOptions2 |= RASEO2_Internet;
  1174. }
  1175. else
  1176. {
  1177. ((LPRASENTRY_V501)preBuffer)->dwfOptions2 &= ~RASEO2_Internet;
  1178. }
  1179. }
  1180. //
  1181. // If we have a specific DUN name to use, then
  1182. // use it instead of the default DUN setting in the .CMS.
  1183. //
  1184. if (pszDUN && *pszDUN)
  1185. {
  1186. pszDunEntry = CmStrCpyAlloc(pszDUN);
  1187. }
  1188. else
  1189. {
  1190. pszDunEntry = GetDefaultDunSettingName(piniService, fTunnelEntry);
  1191. }
  1192. //
  1193. // If we have a DUN setting name, read the settings from cms
  1194. //
  1195. if (pszDunEntry && *pszDunEntry)
  1196. {
  1197. dwErr = (DWORD)ReadDUNSettings(pArgs, piniService->GetFile(), pszDunEntry, preBuffer, ppbEapData ,pdwEapSize, fTunnelEntry);
  1198. if (ERROR_SUCCESS != dwErr)
  1199. {
  1200. CMTRACE(TEXT("UpdateRASConnectoid: ReadDUNSettings failed"));
  1201. CmFree(preBuffer);
  1202. preBuffer = NULL;
  1203. goto exit;
  1204. }
  1205. }
  1206. //
  1207. // Get autodial information, store in preBuffer
  1208. //
  1209. CopyAutoDial(preBuffer);
  1210. //
  1211. // disable the RAS wizard on Win95
  1212. //
  1213. if (OS_W9X)
  1214. {
  1215. DisableWin95RasWizard();
  1216. }
  1217. exit:
  1218. if (pszDunEntry)
  1219. {
  1220. CmFree(pszDunEntry);
  1221. }
  1222. SetLastError(dwErr);
  1223. return preBuffer;
  1224. }
  1225. //+----------------------------------------------------------------------------
  1226. //
  1227. // Function CreateRasPrivatePbk
  1228. //
  1229. // Synopsis Create the private RAS phone book and returns the full path.
  1230. //
  1231. // Arguments pArgs Pointer to global Args struct
  1232. //
  1233. // Returns LPTSTR The full path name of the newly created private pbk
  1234. //
  1235. // History ??/??/97 henryt created
  1236. //
  1237. // 01/15/99 Jeffspr Changed the GetTempFileName pattern,
  1238. // as it was using more than the allowed/
  1239. // used 3 chars, plus made the failure
  1240. // case use the same pattern (we will
  1241. // filter on this in the connection
  1242. // enumerator to ignore these entries).
  1243. //
  1244. // 05/21/99 nickball Added allocation, removed input buf
  1245. // 04/10/00 quintinb Removed GetTempFileName as we no longer
  1246. // want this file to be temporary. Changed
  1247. // the function to create a file named _cmphone.pbk
  1248. // in the profile directory.
  1249. // Please see Whistler bug 15812 for details.
  1250. // 07/05/00 t-urama Changed the path to the hidden pbk to point
  1251. // to the RAS pbk.
  1252. //
  1253. //-----------------------------------------------------------------------------
  1254. LPTSTR CreateRasPrivatePbk(ArgsStruct *pArgs)
  1255. {
  1256. //
  1257. // No private PBK on win9x, everything is in the registry.
  1258. //
  1259. if (OS_W9X)
  1260. {
  1261. return NULL;
  1262. }
  1263. if (NULL == pArgs)
  1264. {
  1265. MYDBGASSERT(pArgs);
  1266. return NULL;
  1267. }
  1268. LPTSTR pszHiddenPbkPath = NULL;
  1269. LPCTSTR pszCmp = pArgs->piniProfile->GetFile();
  1270. //
  1271. // This version of the function uses the function GetPathToPbk in connect.cpp to find the path
  1272. // to the phone book. The hidden phone book also has to be created in the same directory.
  1273. //
  1274. if (pszCmp)
  1275. {
  1276. LPTSTR pszRasPbkDir = GetPathToPbk(pszCmp, pArgs);
  1277. MYDBGASSERT(pszRasPbkDir);
  1278. if (pszRasPbkDir)
  1279. {
  1280. pszHiddenPbkPath = (LPTSTR) CmMalloc((lstrlen(pszRasPbkDir) + lstrlen(CM_PBK_FILTER_PREFIX) + 7) * sizeof(TCHAR));
  1281. if (pszHiddenPbkPath)
  1282. {
  1283. wsprintfU(pszHiddenPbkPath, TEXT("%s\\%sphone"), pszRasPbkDir, CM_PBK_FILTER_PREFIX);
  1284. MYDBGASSERT(pszHiddenPbkPath);
  1285. HANDLE hFile = INVALID_HANDLE_VALUE;
  1286. SECURITY_ATTRIBUTES sa = {0};
  1287. PSECURITY_ATTRIBUTES pSA = NULL;
  1288. PSECURITY_DESCRIPTOR pSd = NULL;
  1289. if (OS_NT5 && pArgs->fAllUser)
  1290. {
  1291. //
  1292. // Be sure to create it with a security descriptor that
  1293. // allows it to be read by any authenticated user. If we don't it may
  1294. // prevent other users from being able to read it. We didn't want to
  1295. // change the old behavior downlevel so this fix is just for Whistler+.
  1296. //
  1297. DWORD dwErr = AllocateSecurityDescriptorAllowAccessToWorld(&pSd);
  1298. if ((ERROR_SUCCESS == dwErr) && pSd)
  1299. {
  1300. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  1301. sa.lpSecurityDescriptor = pSd;
  1302. sa.bInheritHandle = TRUE;
  1303. pSA = &sa;
  1304. }
  1305. }
  1306. hFile = CreateFileU(pszHiddenPbkPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
  1307. pSA, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1308. CmFree(pSd);
  1309. if (hFile == INVALID_HANDLE_VALUE)
  1310. {
  1311. DWORD dwLastError = GetLastError();
  1312. MYDBGASSERT(hFile != INVALID_HANDLE_VALUE);
  1313. CMTRACE1(TEXT("CreateRasPrivatePbk - CreateFileU failed. GetLastError = %d"), dwLastError);
  1314. }
  1315. CloseHandle(hFile);
  1316. }
  1317. else
  1318. {
  1319. CMASSERTMSG(FALSE, TEXT("CreateRasPrivatePbk -- CmMalloc returned NULL for pszHiddenPbkPath"));
  1320. }
  1321. CmFree(pszRasPbkDir);
  1322. }
  1323. }
  1324. return pszHiddenPbkPath;
  1325. }
  1326. //+----------------------------------------------------------------------------
  1327. //
  1328. // Function GetPathToPbk
  1329. //
  1330. // Synopsis This function is a helper function called by
  1331. // CheckAccessToCmpAndPbk in connect.cpp and by
  1332. // CreateRasPrivatePbk. It returns the path to the RAS
  1333. // phonebook.
  1334. //
  1335. // Arguments LPTSTR pszCmp - The path to the cmp file
  1336. // LPTSTR pszRasPbk - The string to store the result
  1337. // ArgsStruct *pArgs - pArgs
  1338. //
  1339. // Returns NONE
  1340. //
  1341. // History 07/05/00 t-urama created
  1342. //-----------------------------------------------------------------------------
  1343. LPTSTR GetPathToPbk(LPCTSTR pszCmp, ArgsStruct *pArgs)
  1344. {
  1345. MYDBGASSERT(pArgs);
  1346. if (NULL == pArgs)
  1347. {
  1348. return NULL;
  1349. }
  1350. MYDBGASSERT(pszCmp);
  1351. if (NULL == pszCmp)
  1352. {
  1353. return NULL;
  1354. }
  1355. LPTSTR pszRasPbk = NULL;
  1356. //
  1357. // pszRasPbk could be NULL if we are on NT4 or we are using the
  1358. // all user default phonebook.
  1359. //
  1360. if (NULL == pArgs->pszRasPbk)
  1361. {
  1362. if (OS_NT4)
  1363. {
  1364. DWORD dwSize = (MAX_PATH + 1);
  1365. DWORD dwRet;
  1366. BOOL bExitLoop = TRUE;
  1367. do
  1368. {
  1369. pszRasPbk = (LPTSTR)CmMalloc(dwSize*sizeof(TCHAR));
  1370. if (pszRasPbk)
  1371. {
  1372. dwRet = GetSystemDirectoryU(pszRasPbk, dwSize);
  1373. if (dwRet)
  1374. {
  1375. if (dwRet > dwSize)
  1376. {
  1377. dwSize = dwRet + 1;
  1378. bExitLoop = FALSE; // we didn't get all of the string, try again
  1379. CmFree(pszRasPbk);
  1380. }
  1381. else
  1382. {
  1383. bExitLoop = TRUE;
  1384. CmStrCatAlloc(&pszRasPbk, c_pszRasDirRas);
  1385. }
  1386. }
  1387. else
  1388. {
  1389. CmFree(pszRasPbk);
  1390. pszRasPbk = NULL;
  1391. }
  1392. }
  1393. else
  1394. {
  1395. CMASSERTMSG(FALSE, TEXT("GetPathToPbk -- CmMalloc failed!"));
  1396. return NULL;
  1397. }
  1398. } while (!bExitLoop);
  1399. }
  1400. else
  1401. {
  1402. pszRasPbk = CmStrCpyAlloc(pszCmp);
  1403. if (pszRasPbk)
  1404. {
  1405. LPTSTR pszSlash = CmStrrchr(pszRasPbk, TEXT('\\'));
  1406. if (pszSlash)
  1407. {
  1408. *pszSlash = TEXT('\0'); // remove <shortservicename>.cmp
  1409. pszSlash = CmStrrchr(pszRasPbk, TEXT('\\'));
  1410. if (pszSlash)
  1411. {
  1412. *pszSlash = TEXT('\0');
  1413. CmStrCatAlloc(&pszRasPbk, TEXT("\\"));
  1414. CmStrCatAlloc(&pszRasPbk, c_pszPbk);
  1415. }
  1416. else
  1417. {
  1418. CMASSERTMSG(FALSE, TEXT("GetPathToPbk -- unable to convert cmp path to pbk path."));
  1419. CmFree(pszRasPbk);
  1420. pszRasPbk = NULL;
  1421. }
  1422. }
  1423. else
  1424. {
  1425. CMASSERTMSG(FALSE, TEXT("GetPathToPbk -- unable to convert cmp path to pbk path!"));
  1426. CmFree(pszRasPbk);
  1427. pszRasPbk = NULL;
  1428. }
  1429. }
  1430. }
  1431. }
  1432. else
  1433. {
  1434. pszRasPbk = CmStrCpyAlloc(pArgs->pszRasPbk);
  1435. LPTSTR pszSlash = CmStrrchr(pszRasPbk, TEXT('\\'));
  1436. if (pszSlash)
  1437. {
  1438. *pszSlash = TEXT('\0'); // remove the RAS phonebook name
  1439. }
  1440. else
  1441. {
  1442. CMASSERTMSG(FALSE, TEXT("GetPathToPbk -- unable to convert RAS pbk name to pbk path!"));
  1443. CmFree(pszRasPbk);
  1444. pszRasPbk = NULL;
  1445. }
  1446. }
  1447. return pszRasPbk;
  1448. }
  1449. //+----------------------------------------------------------------------------
  1450. //
  1451. // Function DisableWin95RasWizard
  1452. //
  1453. // Synopsis This function disable the Win95 Dial-up Networking wizard
  1454. // by writing a dword reg value 0x00000080 in the registry.
  1455. //
  1456. // Arguments NONE
  1457. //
  1458. // Returns NONE
  1459. //
  1460. // History 7/1/97 henryt created
  1461. //-----------------------------------------------------------------------------
  1462. void DisableWin95RasWizard(
  1463. void)
  1464. {
  1465. HKEY hkReg = NULL;
  1466. LONG lRes;
  1467. DWORD dwSize;
  1468. DWORD dwType;
  1469. DWORD dwValue;
  1470. lRes = RegOpenKeyExA(HKEY_CURRENT_USER, c_pszRegRemoteAccess, 0,
  1471. KEY_QUERY_VALUE|KEY_SET_VALUE, &hkReg);
  1472. if (ERROR_SUCCESS != lRes)
  1473. {
  1474. CMTRACE1(TEXT("DisableWin95RasWizard() RegOpenKeyEx() failed, GLE=%u."), lRes);
  1475. goto exit;
  1476. }
  1477. //
  1478. // see if we already have a value there.
  1479. //
  1480. dwSize = sizeof(DWORD);
  1481. lRes = RegQueryValueExA(hkReg,
  1482. c_pszRegWizard,
  1483. NULL,
  1484. &dwType,
  1485. (LPBYTE)&dwValue,
  1486. &dwSize);
  1487. if (lRes == ERROR_SUCCESS &&
  1488. dwSize == sizeof(DWORD) &&
  1489. dwType == REG_BINARY &&
  1490. dwValue == ICM_RAS_REG_WIZARD_VALUE)
  1491. {
  1492. CMTRACE(TEXT("DisableWin95RasWizard() RegQueryValueEx() - found correct value."));
  1493. goto exit;
  1494. }
  1495. //
  1496. // well, the value is not in reg yet. we need to create the value.
  1497. //
  1498. dwValue = ICM_RAS_REG_WIZARD_VALUE;
  1499. lRes = RegSetValueExA(hkReg,
  1500. c_pszRegWizard,
  1501. 0,
  1502. REG_BINARY,
  1503. (LPBYTE)&dwValue,
  1504. sizeof(dwValue));
  1505. #ifdef DEBUG
  1506. if (ERROR_SUCCESS != lRes)
  1507. {
  1508. CMTRACE1(TEXT("DisableWin95RasWizard() RegSetValueEx() failed, GLE=%u."), lRes);
  1509. }
  1510. #endif
  1511. exit:
  1512. if (hkReg)
  1513. {
  1514. lRes = RegCloseKey(hkReg);
  1515. #ifdef DEBUG
  1516. if (ERROR_SUCCESS != lRes)
  1517. {
  1518. CMTRACE1(TEXT("DisableWin95RasWizard() RegCloseKey() failed, GLE=%u."), lRes);
  1519. }
  1520. #endif
  1521. }
  1522. return;
  1523. }
  1524. //+----------------------------------------------------------------------------
  1525. //
  1526. // Function SetIsdnDualChannelEntries
  1527. //
  1528. // Synopsis As what the func name says. We prepare the RASENTRY and
  1529. // RASSUBENTRY properly. We don't actually make RAS calls to
  1530. // save the entries. We'll leave it to the caller(so that the
  1531. // can make other changes to the structs for other reasons and
  1532. // commit the changes in 1 or 2 RAS calls).
  1533. //
  1534. // Arguments pArgs [IN] Pointer to ArgsStruct
  1535. // pRasEntry [IN/OUT] rasentry to be filled
  1536. // ppRasSubEntry [OUT] pointer to be filled with the subentry array
  1537. // The buffer is allocated in this function.
  1538. // pdwSubEntryCount Number of subentries allocated.
  1539. //
  1540. // Returns BOOL TRUE = success, FALSE = failure.
  1541. //
  1542. //-----------------------------------------------------------------------------
  1543. BOOL SetIsdnDualChannelEntries(ArgsStruct *pArgs, LPRASENTRY pRasEntry,
  1544. LPRASSUBENTRY *ppRasSubEntry, PDWORD pdwSubEntryCount)
  1545. {
  1546. //
  1547. // Lets check the input parameters
  1548. //
  1549. MYDBGASSERT(pArgs);
  1550. MYDBGASSERT(pRasEntry);
  1551. MYDBGASSERT(ppRasSubEntry);
  1552. MYDBGASSERT(pdwSubEntryCount);
  1553. if ((NULL == pArgs) || (NULL == pRasEntry) || (NULL == ppRasSubEntry) ||
  1554. (NULL == pdwSubEntryCount))
  1555. {
  1556. return FALSE;
  1557. }
  1558. //
  1559. // Since we don't support BAP if they called this function they must have wanted
  1560. // to do DualChannel ISDN. If the dial mode isn't set for dual channel, we will
  1561. // assert an continue. Better to connect the user in dual channel mode then not
  1562. // at all if they have a misconfigured profile.
  1563. //
  1564. MYDBGASSERT(pArgs->dwIsdnDialMode != CM_ISDN_MODE_SINGLECHANNEL);
  1565. //
  1566. // Check the size of the passed in RasEntry struct. If it isn't at least
  1567. // a 4.01 size struct, then return.
  1568. //
  1569. MYDBGASSERT(pRasEntry->dwSize >= sizeof(LPRASENTRY_V401));
  1570. if (sizeof(LPRASENTRY_V401) > pRasEntry->dwSize)
  1571. {
  1572. return FALSE;
  1573. }
  1574. LPRASENTRY_V401 pRasEntry401 = (LPRASENTRY_V401)pRasEntry;
  1575. //
  1576. // set isdn dial mode to dial both channels
  1577. //
  1578. pRasEntry401->dwDialMode = RASEDM_DialAll;
  1579. CMTRACE(TEXT("ISDN Dual Channel Mode On"));
  1580. if (OS_NT)
  1581. {
  1582. *pdwSubEntryCount = 2;
  1583. }
  1584. else if (OS_MIL)
  1585. {
  1586. // 112351: 9x only requires one sub entry. We'll keep the device name the same.
  1587. // In this case, Win9x will work as follows:
  1588. // for the 1st channel, the device name provided works fine.
  1589. // for the 2nd channel, 9x sees the device is in use and looks for the
  1590. // the closest match (which is the 2nd channel).
  1591. //
  1592. *pdwSubEntryCount = 1;
  1593. }
  1594. else
  1595. {
  1596. CMASSERTMSG(FALSE, TEXT("SetIsdnDualChannelEntries -- Function called on a platform other than NT or Millennium."));
  1597. return FALSE;
  1598. }
  1599. //
  1600. // Allocate the sub entries
  1601. //
  1602. *ppRasSubEntry = (LPRASSUBENTRY)CmMalloc((*pdwSubEntryCount)*(sizeof(RASSUBENTRY)));
  1603. if (NULL == *ppRasSubEntry)
  1604. {
  1605. CMASSERTMSG(FALSE, TEXT("SetIsdnDualChannelEntries -- CmMalloc failed to alloc ppRasSubEntry."));
  1606. return FALSE;
  1607. }
  1608. //
  1609. // Fill in the sub entries with the device and phonenumber information
  1610. //
  1611. for (DWORD dwIndex=0; dwIndex < (*pdwSubEntryCount); dwIndex++)
  1612. {
  1613. (*ppRasSubEntry)[dwIndex].dwSize = sizeof(RASSUBENTRY);
  1614. lstrcpyU((*ppRasSubEntry)[dwIndex].szDeviceType, pArgs->szDeviceType);
  1615. lstrcpyU((*ppRasSubEntry)[dwIndex].szDeviceName, pArgs->szDeviceName);
  1616. lstrcpyU((*ppRasSubEntry)[dwIndex].szLocalPhoneNumber, pRasEntry401->szLocalPhoneNumber);
  1617. }
  1618. return TRUE;
  1619. }
  1620. //
  1621. // Keep in case we ever want to support BAP
  1622. //
  1623. /*
  1624. BOOL SetIsdnDualChannelEntries(
  1625. ArgsStruct *pArgs,
  1626. LPRASENTRY pre,
  1627. LPRASSUBENTRY *prgrse,
  1628. PDWORD pdwSubEntryCount
  1629. )
  1630. {
  1631. LPRASENTRY_V401 pre401;
  1632. MYDBGASSERT(pArgs->dwIsdnDialMode != CM_ISDN_MODE_SINGLECHANNEL);
  1633. MYDBGASSERT(pre->dwSize >= sizeof(LPRASENTRY_V401));
  1634. pre401 = (LPRASENTRY_V401)pre;
  1635. //
  1636. // set isdn dial mode
  1637. //
  1638. if (pArgs->dwIsdnDialMode == CM_ISDN_MODE_DIALALL)
  1639. {
  1640. //
  1641. // dial both channels
  1642. //
  1643. pre401->dwDialMode = RASEDM_DialAll;
  1644. CMTRACE(TEXT("ISDN Dual Channel Mode On"));
  1645. }
  1646. else
  1647. {
  1648. //
  1649. // dial 2nd channel on demand
  1650. //
  1651. //
  1652. // First get the 4 thresholds
  1653. //
  1654. if (!pArgs->dwDialExtraPercent)
  1655. {
  1656. pArgs->dwDialExtraPercent = pArgs->piniService->GPPI(c_pszCmSection,
  1657. c_pszCmEntryDialExtraPercent,
  1658. DEFAULT_DIALEXTRAPERCENT);
  1659. if (pArgs->dwDialExtraPercent < 0 ||
  1660. pArgs->dwDialExtraPercent > 100)
  1661. {
  1662. pArgs->dwDialExtraPercent = DEFAULT_DIALEXTRAPERCENT;
  1663. }
  1664. }
  1665. if (!pArgs->dwDialExtraSampleSeconds)
  1666. {
  1667. pArgs->dwDialExtraSampleSeconds = pArgs->piniService->GPPI(c_pszCmSection,
  1668. c_pszCmEntryDialExtraSampleSeconds,
  1669. DEFAULT_DIALEXTRASAMPLESECONDS);
  1670. if (pArgs->dwDialExtraSampleSeconds < 0)
  1671. {
  1672. pArgs->dwDialExtraSampleSeconds = DEFAULT_DIALEXTRASAMPLESECONDS;
  1673. }
  1674. }
  1675. if (!pArgs->dwHangUpExtraPercent)
  1676. {
  1677. pArgs->dwHangUpExtraPercent = pArgs->piniService->GPPI(c_pszCmSection,
  1678. c_pszCmEntryHangUpExtraPercent,
  1679. DEFAULT_HANGUPEXTRAPERCENT);
  1680. if (pArgs->dwHangUpExtraPercent < 0 ||
  1681. pArgs->dwHangUpExtraPercent > 100)
  1682. {
  1683. pArgs->dwHangUpExtraPercent = DEFAULT_HANGUPEXTRAPERCENT;
  1684. }
  1685. }
  1686. if (!pArgs->dwHangUpExtraSampleSeconds)
  1687. {
  1688. pArgs->dwHangUpExtraSampleSeconds = pArgs->piniService->GPPI(c_pszCmSection,
  1689. c_pszCmEntryHangUpExtraSampleSeconds,
  1690. DEFAULT_HANGUPEXTRASAMPLESECONDS);
  1691. if (pArgs->dwHangUpExtraSampleSeconds < 0)
  1692. {
  1693. pArgs->dwHangUpExtraSampleSeconds = DEFAULT_HANGUPEXTRASAMPLESECONDS;
  1694. }
  1695. }
  1696. //
  1697. // set multilink info
  1698. //
  1699. pre401->dwDialMode = RASEDM_DialAsNeeded;
  1700. pre401->dwDialExtraPercent = pArgs->dwDialExtraPercent;
  1701. pre401->dwDialExtraSampleSeconds = pArgs->dwDialExtraSampleSeconds;
  1702. pre401->dwHangUpExtraPercent = pArgs->dwHangUpExtraPercent;
  1703. pre401->dwHangUpExtraSampleSeconds = pArgs->dwHangUpExtraSampleSeconds;
  1704. CMTRACE2(TEXT("ISDN 2nd Channel Dial On Demand: dial extra %u%%, dial extra %u sample secs"),
  1705. pre401->dwDialExtraPercent, pre401->dwDialExtraSampleSeconds);
  1706. CMTRACE2(TEXT("\t\thangup extra %u%%, hangup extra %u sample secs"),
  1707. pre401->dwHangUpExtraPercent, pre401->dwHangUpExtraSampleSeconds);
  1708. }
  1709. if (OS_NT)
  1710. {
  1711. if (!(*prgrse = (LPRASSUBENTRY)CmMalloc(2*sizeof(RASSUBENTRY))))
  1712. {
  1713. CMTRACE(TEXT("SetIsdnDualChannelEntries failed to alloc a ras sub entry"));
  1714. return FALSE;
  1715. }
  1716. ZeroMemory((PVOID)*prgrse, 2*sizeof(RASSUBENTRY));
  1717. //
  1718. // first channel
  1719. //
  1720. (*prgrse)[0].dwSize = sizeof(RASSUBENTRY);
  1721. lstrcpyU((*prgrse)[0].szDeviceType, pArgs->szDeviceType);
  1722. lstrcpyU((*prgrse)[0].szDeviceName, pArgs->szDeviceName);
  1723. lstrcpyU((*prgrse)[0].szLocalPhoneNumber, pre401->szLocalPhoneNumber);
  1724. //
  1725. // the 2nd channel is identical
  1726. //
  1727. CopyMemory((PVOID)(*prgrse + 1), (PVOID)*prgrse, sizeof(RASSUBENTRY));
  1728. *pdwSubEntryCount = 2;
  1729. }
  1730. else
  1731. {
  1732. MYDBGASSERT(OS_MIL);
  1733. CMTRACE(TEXT("doing the Millennium subentry stuff"));
  1734. // 112351: 9x only requires one sub entry. We'll keep the device name the same.
  1735. // In this case, Win9x will work as follows:
  1736. // for the 1st channel, the device name provided works fine.
  1737. // for the 2nd channel, 9x sees the device is in use and looks for the
  1738. // the closest match (which is the 2nd channel).
  1739. //
  1740. if (!(*prgrse = (LPRASSUBENTRY)CmMalloc(1*sizeof(RASSUBENTRY))))
  1741. {
  1742. CMTRACE(TEXT("SetIsdnDualChannelEntries failed to alloc a ras sub entry"));
  1743. return FALSE;
  1744. }
  1745. ZeroMemory((PVOID)*prgrse, 1*sizeof(RASSUBENTRY));
  1746. //
  1747. // 2nd channel
  1748. //
  1749. (*prgrse)[0].dwSize = sizeof(RASSUBENTRY);
  1750. lstrcpyU((*prgrse)[0].szDeviceType, pArgs->szDeviceType);
  1751. lstrcpyU((*prgrse)[0].szDeviceName, pArgs->szDeviceName);
  1752. lstrcpyU((*prgrse)[0].szLocalPhoneNumber, pre401->szLocalPhoneNumber);
  1753. *pdwSubEntryCount = 1;
  1754. }
  1755. return TRUE;
  1756. }
  1757. */
  1758. //+----------------------------------------------------------------------------
  1759. //
  1760. // Function SetNtIdleDisconnectInRasEntry
  1761. //
  1762. // Synopsis As what the func name says. We prepare the RASENTRY and
  1763. // RASSUBENTRY properly. We don't actually make RAS calls to
  1764. // save the entries. We'll leave it to the caller(so that the
  1765. // can make other changes to the structs for other reasons and
  1766. // commit the changes in 1 or 2 RAS calls).
  1767. //
  1768. // Arguments pArgs [IN] Pointer to ArgsStruct
  1769. // pre [OUT] Pointer to RASENTRY with the correct size
  1770. //
  1771. // Returns BOOL TRUE = success, FALSE = failure.
  1772. //
  1773. //-----------------------------------------------------------------------------
  1774. BOOL SetNtIdleDisconnectInRasEntry(
  1775. ArgsStruct *pArgs,
  1776. LPRASENTRY pre
  1777. )
  1778. {
  1779. if (!OS_NT4)
  1780. {
  1781. return FALSE;
  1782. }
  1783. if ((NULL == pArgs) || (NULL == pre) || (pre->dwSize < sizeof(LPRASENTRY_V401)))
  1784. {
  1785. CMASSERTMSG(FALSE, TEXT("SetNtIdleDisconnectInRasEntry -- Invalid parameter"));
  1786. return FALSE;
  1787. }
  1788. //
  1789. // If idle-disconnect is enabled, use the options value otherwise
  1790. // pArgs->dwIdleTimeout is in minutes. Note that 0xFFFFFFFF means
  1791. // no idle disconnect to RAS but 0 is the value we use to mean never
  1792. // idle disconnect in the CMS.
  1793. //
  1794. DWORD dwIdle = (pArgs->dwIdleTimeout * 60);
  1795. if (0 == dwIdle)
  1796. {
  1797. dwIdle = (DWORD)-1;
  1798. }
  1799. ((LPRASENTRY_V401 )pre)->dwIdleDisconnectSeconds = dwIdle;
  1800. CMTRACE1(TEXT("SetNtIdleDisconnect: current idle Timeout is %u seconds."), dwIdle);
  1801. return TRUE;
  1802. }
  1803. //+----------------------------------------------------------------------------
  1804. //
  1805. // Function: DisableSystemIdleDisconnect
  1806. //
  1807. // Synopsis: This function sets the idle timeout value of a RAS connection to
  1808. // be disabled.
  1809. //
  1810. // Arguments: LPRASENTRY pre - pointer to a RASENTRY to disable idle disconnect for
  1811. //
  1812. // Returns: BOOL TRUE = success, FALSE = failure.
  1813. //
  1814. //-----------------------------------------------------------------------------
  1815. BOOL DisableSystemIdleDisconnect(LPRASENTRY pre)
  1816. {
  1817. if ((NULL == pre) || (pre->dwSize < sizeof(LPRASENTRY_V401)))
  1818. {
  1819. CMASSERTMSG(FALSE, TEXT("DisableSystemIdleDisconnect -- Invalid parameter"));
  1820. return FALSE;
  1821. }
  1822. //
  1823. // Set the idle time to 0xFFFFFFFF which means no idle disconnect to RAS
  1824. //
  1825. ((LPRASENTRY_V401 )pre)->dwIdleDisconnectSeconds = (DWORD)-1;
  1826. CMTRACE(TEXT("DisableSystemIdleDisconnect -- System Idle disconnect disabled"));
  1827. return TRUE;
  1828. }
  1829. //+----------------------------------------------------------------------------
  1830. //
  1831. // Function RasDialFunc2
  1832. //
  1833. // Synopsis A RAS callback type 2 for RasDial.
  1834. //
  1835. // Arguments
  1836. // ULONG_PTR dwCallbackId,// user-defined value specified in RasDial
  1837. // DWORD dwSubEntry, // subentry index in multilink connection
  1838. // HRASCONN hrasconn, // handle to RAS connection
  1839. // UINT unMsg, // type of event that has occurred
  1840. // RASCONNSTATE rascs, // connection state about to be entered
  1841. // DWORD dwError, // error that may have occurred
  1842. // DWORD dwExtendedError // extended error information for some errors
  1843. //
  1844. // Returns LPRASENTRY - pointer to the RASENTRY structure allocated
  1845. //
  1846. //-----------------------------------------------------------------------------
  1847. DWORD WINAPI RasDialFunc2(
  1848. ULONG_PTR dwCallbackId, // user-defined value specified in RasDial
  1849. DWORD dwSubEntry, // subentry index in multilink connection
  1850. HRASCONN hrasconn, // handle to RAS connection
  1851. UINT unMsg, // type of event that has occurred
  1852. RASCONNSTATE rascs, // connection state about to be entered
  1853. DWORD dwError, // error that may have occurred
  1854. DWORD dwExtendedError // extended error information for some errors
  1855. )
  1856. {
  1857. CMTRACE2(TEXT("RasDialFunc2(): dwSubentry=%u. dwErr=0x%x"), dwSubEntry, dwError);
  1858. CMTRACE2(TEXT("RasDialFunc2(): dwExtendedErr=0x%x, rascs=%u"), dwExtendedError, rascs);
  1859. MYDBGASSERT(dwCallbackId);
  1860. if (dwCallbackId)
  1861. {
  1862. ArgsStruct *pArgs = (ArgsStruct *) dwCallbackId;
  1863. pArgs->dwRasSubEntry = dwSubEntry;
  1864. //CMTRACE1(TEXT("RasDialFunc2(): pArgs->lInConnectOrCancel=%d"),pArgs->lInConnectOrCancel);
  1865. //CMASSERTMSG((NOT_IN_CONNECT_OR_CANCEL == pArgs->lInConnectOrCancel),
  1866. // TEXT("RasDialFunc2 - RasDial mutex is NOT NULL..."));
  1867. SendMessage(pArgs->hwndMainDlg, pArgs->uMsgId, rascs, dwError);
  1868. }
  1869. return 1;
  1870. }
  1871. //+----------------------------------------------------------------------------
  1872. //
  1873. // Function: SetRasDialExtensions
  1874. //
  1875. // Synopsis: Encapsulates initialization and configuration of the
  1876. // RasDialExtensions that we use on NT.
  1877. //
  1878. // Arguments: pArgs - Ptr to global args struct
  1879. // fEnablePausedStates - Use Paused states or not
  1880. // fEnableCustomScripting - whether to use custom scripting or not
  1881. //
  1882. // Returns: DWORD - Error code
  1883. //
  1884. // History: nickball Created 7/22/99
  1885. //
  1886. //+----------------------------------------------------------------------------
  1887. DWORD SetRasDialExtensions(ArgsStruct* pArgs, BOOL fEnablePausedStates, BOOL fEnableCustomScripting)
  1888. {
  1889. DWORD dwRes = ERROR_SUCCESS;
  1890. MYDBGASSERT(pArgs);
  1891. if (NULL == pArgs)
  1892. {
  1893. return ERROR_INVALID_PARAMETER;
  1894. }
  1895. //
  1896. // If not already allocated, we need a RasDialExtensions struct
  1897. //
  1898. if (!pArgs->pRasDialExtensions)
  1899. {
  1900. pArgs->pRasDialExtensions = AllocateAndInitRasDialExtensions();
  1901. if (!pArgs->pRasDialExtensions)
  1902. {
  1903. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  1904. }
  1905. }
  1906. else
  1907. {
  1908. dwRes = InitRasDialExtensions(pArgs->pRasDialExtensions);
  1909. }
  1910. if (ERROR_SUCCESS != dwRes)
  1911. {
  1912. goto SetRasDialExtensionsExit;
  1913. }
  1914. //
  1915. // Turn on PauseStates for NT
  1916. //
  1917. if (fEnablePausedStates)
  1918. {
  1919. pArgs->pRasDialExtensions->dwfOptions |= RDEOPT_PausedStates;
  1920. }
  1921. //
  1922. // Turn on custom scripting if we are running on Whistler+ and the caller
  1923. // asked for it.
  1924. //
  1925. if (fEnableCustomScripting && OS_NT51)
  1926. {
  1927. pArgs->pRasDialExtensions->dwfOptions |= RDEOPT_UseCustomScripting;
  1928. }
  1929. //
  1930. // RDEOPT_NoUser is required for the WinLogon credential case,
  1931. // which we identify by the presence of either lpEapLogonInfo
  1932. // or lpRasNoUser. Note that the if statement below is somewhat redundant
  1933. // since we should have CM_LOGON_TYPE_WINLOGON set if we get either a NoUser
  1934. // struct or an EapLogonInfo struct. However, wanted to point out that on Win2k
  1935. // one of the first two will always be true and on Whistler the first two may be
  1936. // false but the third true (RAS now sends a flag to tell us when we are at WinLogon on
  1937. // whistler as there are Ctrl-Alt-Del with SmartCard cases where it sends neither struct).
  1938. //
  1939. if (pArgs->lpEapLogonInfo || pArgs->lpRasNoUser || (CM_LOGON_TYPE_WINLOGON == pArgs->dwWinLogonType))
  1940. {
  1941. pArgs->pRasDialExtensions->dwfOptions |= RDEOPT_NoUser;
  1942. }
  1943. //
  1944. // If the modem speaker is turned off, makes sure that we
  1945. // disable it explicitly in RAS, otherwise it will use
  1946. // its default and turn the speaker on. These settings
  1947. // should be ignored by RAS in the tunnel case.
  1948. //
  1949. if (pArgs->tlsTapiLink.bModemSpeakerOff)
  1950. {
  1951. pArgs->pRasDialExtensions->dwfOptions |= RDEOPT_IgnoreModemSpeaker;
  1952. pArgs->pRasDialExtensions->dwfOptions &= ~RDEOPT_SetModemSpeaker;
  1953. }
  1954. SetRasDialExtensionsExit:
  1955. return dwRes;
  1956. }
  1957. //+----------------------------------------------------------------------------
  1958. //
  1959. // Function: InitRasDialExtensions
  1960. //
  1961. // Synopsis: Flushes a previously allocated RasDialExtensions buffer and sets
  1962. // size, options for re-use.
  1963. //
  1964. // Arguments: LPRASDIALEXTENSIONS - Ptr to allocated struct with size set.
  1965. //
  1966. // Returns: DWORD - Error code
  1967. //
  1968. // History: nickball Created 5/22/99
  1969. //
  1970. //+----------------------------------------------------------------------------
  1971. DWORD InitRasDialExtensions(LPRASDIALEXTENSIONS lpRasDialExtensions)
  1972. {
  1973. MYDBGASSERT(lpRasDialExtensions);
  1974. if (NULL == lpRasDialExtensions)
  1975. {
  1976. return ERROR_INVALID_PARAMETER;
  1977. }
  1978. //
  1979. // First, we determine the size
  1980. //
  1981. DWORD dwSize = OS_NT5 ? sizeof(RASDIALEXTENSIONS_V500) : sizeof(RASDIALEXTENSIONS);
  1982. //
  1983. // Flush buffer and reset size.
  1984. //
  1985. ZeroMemory(lpRasDialExtensions, dwSize);
  1986. lpRasDialExtensions->dwSize = dwSize;
  1987. //
  1988. // Set customdial if needed
  1989. //
  1990. if (dwSize == sizeof(RASDIALEXTENSIONS_V500))
  1991. {
  1992. //
  1993. // Set the CustomDial flag for NT5. We don't set this on NT4
  1994. // and 9X as a precaution because the falg isn't defined.
  1995. //
  1996. lpRasDialExtensions->dwfOptions |= RDEOPT_CustomDial;
  1997. }
  1998. CMTRACE1(TEXT("InitRasDialExtensions() - dwSize is %u"), dwSize);
  1999. return ERROR_SUCCESS;
  2000. }
  2001. //+----------------------------------------------------------------------------
  2002. //
  2003. // Function: AllocateAndInitRasDialExtensions
  2004. //
  2005. // Synopsis: Encapsulates the allocation of a RASEXTENSION based upon the OS
  2006. //
  2007. // Arguments: None
  2008. //
  2009. // Returns: LPRASDIALEXTENSIONS - Ptr to allocated struct with size set.
  2010. //
  2011. // History: nickball Created 5/13/99
  2012. //
  2013. //+----------------------------------------------------------------------------
  2014. LPRASDIALEXTENSIONS AllocateAndInitRasDialExtensions()
  2015. {
  2016. //
  2017. // Allocate struct and pre-fill as appropriate
  2018. //
  2019. LPRASDIALEXTENSIONS prdeNew = (LPRASDIALEXTENSIONS)CmMalloc(OS_NT5 ?
  2020. sizeof(RASDIALEXTENSIONS_V500) : sizeof(RASDIALEXTENSIONS));
  2021. if (!prdeNew)
  2022. {
  2023. CMTRACE(TEXT("AllocateAndInitRasDialExtensions: failed to alloc RasDialExtension buffer"));
  2024. return NULL;
  2025. }
  2026. InitRasDialExtensions(prdeNew);
  2027. return prdeNew;
  2028. }
  2029. //+----------------------------------------------------------------------------
  2030. //
  2031. // Function: InitRasDialParams
  2032. //
  2033. // Synopsis: Flushes a previously allocated RasDialParams buffer and sets
  2034. // size, options for re-use.
  2035. //
  2036. // Arguments: LPRASDIALPARAMS - Ptr to allocated struct with size set.
  2037. //
  2038. // Returns: DWORD - Error code
  2039. //
  2040. // History: nickball Created 5/22/99
  2041. //
  2042. //+----------------------------------------------------------------------------
  2043. DWORD InitRasDialParams(LPRASDIALPARAMS lpRasDialParams)
  2044. {
  2045. MYDBGASSERT(lpRasDialParams);
  2046. if (NULL == lpRasDialParams)
  2047. {
  2048. return ERROR_INVALID_PARAMETER;
  2049. }
  2050. //
  2051. // First, we determine the size
  2052. //
  2053. DWORD dwSize = OS_NT ? sizeof(RASDIALPARAMS_V401) : sizeof(RASDIALPARAMS);
  2054. //
  2055. // Flush buffer and reset size.
  2056. //
  2057. ZeroMemory(lpRasDialParams, dwSize);
  2058. lpRasDialParams->dwSize = dwSize;
  2059. CMTRACE1(TEXT("InitRasDialParams() - dwSize is %u"), dwSize);
  2060. return ERROR_SUCCESS;
  2061. }
  2062. //+----------------------------------------------------------------------------
  2063. //
  2064. // Function: AllocateAndInitRasDialParams
  2065. //
  2066. // Synopsis: Encapsulates the allocation of a RASDIALPARAMS based upon the OS
  2067. //
  2068. // Arguments: None
  2069. //
  2070. // Returns: LPRASDIALPARAMS - Ptr to allocated struct with size set.
  2071. //
  2072. // History: nickball Created 5/22/99
  2073. //
  2074. //+----------------------------------------------------------------------------
  2075. LPRASDIALPARAMS AllocateAndInitRasDialParams()
  2076. {
  2077. //
  2078. // Allocate struct and pre-fill as appropriate
  2079. //
  2080. LPRASDIALPARAMS prdpNew = (LPRASDIALPARAMS)CmMalloc(OS_NT ?
  2081. sizeof(RASDIALPARAMS_V401) : sizeof(RASDIALPARAMS));
  2082. if (!prdpNew)
  2083. {
  2084. CMTRACE(TEXT("AllocateRasDialParams: failed to alloc RasDialParams buffer"));
  2085. return NULL;
  2086. }
  2087. InitRasDialParams(prdpNew);
  2088. return prdpNew;
  2089. }
  2090. //+----------------------------------------------------------------------------
  2091. //
  2092. // Function: AllocateRasEntry
  2093. //
  2094. // Synopsis: Encapsulates the allocation of a RASENTRY struct based upon the OS
  2095. //
  2096. // Arguments: None
  2097. //
  2098. // Returns: LPRASENTRY - Ptr to allocated struct with size set.
  2099. //
  2100. // History: nickball Created Header 5/13/99
  2101. //
  2102. //+----------------------------------------------------------------------------
  2103. LPRASENTRY AllocateRasEntry()
  2104. {
  2105. static DWORD s_dwRasEntrySize = -1;
  2106. //
  2107. // first, we determine the size
  2108. //
  2109. if (s_dwRasEntrySize == -1)
  2110. {
  2111. if (OS_NT51)
  2112. {
  2113. //
  2114. // Whistler
  2115. //
  2116. s_dwRasEntrySize = sizeof(RASENTRY_V501);
  2117. }
  2118. else if (OS_W2K)
  2119. {
  2120. //
  2121. // nt5
  2122. //
  2123. s_dwRasEntrySize = sizeof(RASENTRY_V500);
  2124. }
  2125. else if (OS_MIL || OS_NT4)
  2126. {
  2127. //
  2128. // Millennium uses the NT4 structure
  2129. //
  2130. s_dwRasEntrySize = sizeof(RASENTRY_V401);
  2131. }
  2132. else
  2133. {
  2134. //
  2135. // win9x
  2136. //
  2137. s_dwRasEntrySize = sizeof(RASENTRY);
  2138. }
  2139. }
  2140. //
  2141. // add 512 bytes since a rasentry can contain alternate phone #'s
  2142. // See RASENTRY.dwAlternateOffset
  2143. //
  2144. LPRASENTRY preNew = (LPRASENTRY)CmMalloc(s_dwRasEntrySize+512);
  2145. if (!preNew)
  2146. {
  2147. CMTRACE(TEXT("AllocateRasEntry: failed to alloc rasentry buffer"));
  2148. return NULL;
  2149. }
  2150. preNew->dwSize = s_dwRasEntrySize;
  2151. if (s_dwRasEntrySize >= sizeof(RASENTRY_V500))
  2152. {
  2153. ((LPRASENTRY_V500)preNew)->dwType = RASET_Internet;
  2154. //
  2155. // For NT5, set szCustomDialDll with our Module name. This ensures that our
  2156. // custom DialDlg, DialEntry, and Hangup routines will be called by RAS for
  2157. // operations on our connectoid. We don't want to tie our path to anything
  2158. // machine specific, so we'll use the %windir% environment string.
  2159. //
  2160. lstrcpyU(((LPRASENTRY_V500)preNew)->szCustomDialDll, c_pszCmDialPath);
  2161. }
  2162. CMTRACE1(TEXT("AllocateRasEntry() - s_dwRasEntrySize is %u"), s_dwRasEntrySize);
  2163. return preNew;
  2164. }
  2165. #if 0
  2166. /*
  2167. //+----------------------------------------------------------------------------
  2168. //
  2169. // Function: GetRasSystemPhoneBookPath
  2170. //
  2171. // Synopsis: Builds the conventional path to the RAS system phonebook
  2172. //
  2173. // Arguments: None
  2174. //
  2175. // Returns: LPTSTR - The phonebook path
  2176. //
  2177. // History: nickball Created 8/14/98
  2178. //
  2179. //+----------------------------------------------------------------------------
  2180. LPTSTR GetRasSystemPhoneBookPath()
  2181. {
  2182. MYDBGASSERT(OS_NT);
  2183. TCHAR szTemp[MAX_PATH+1];
  2184. GetSystemDirectoryU(szTemp,sizeof(szTemp));
  2185. lstrcatU(szTemp, c_pszRasDirRas);
  2186. lstrcatU(szTemp, c_pszRasPhonePbk);
  2187. return CmStrCpyAlloc(szTemp);
  2188. }
  2189. //+---------------------------------------------------------------------------
  2190. //
  2191. // Function: InitDefaultRasPhoneBook
  2192. //
  2193. // Synopsis: Special case Helper function ensures that there is a default
  2194. // ras phonebook when running on NT. We simply attempt to create
  2195. // the file which fails if the file already exists, or creates
  2196. // an empty file if it does not.
  2197. //
  2198. // Arguments: None
  2199. //
  2200. // Returns: Nothing
  2201. //
  2202. // History: a-nichb - 4/30/97 Created
  2203. // VetriV 5/21/97 Changed code to call GetOSVersion()
  2204. // instead of using pArgs->dwPlatformID
  2205. // for bug #4700
  2206. // nickball ??/??/98 Removed as we no longer call RasValidateEntry
  2207. // which introduced the requirement of having at
  2208. // least an empty phonebook for the API to work.
  2209. //
  2210. //----------------------------------------------------------------------------
  2211. void InitDefaultRasPhoneBook()
  2212. {
  2213. //
  2214. // NT only. Create empty system phonebook if none exists
  2215. //
  2216. if (OS_NT)
  2217. {
  2218. LPTSTR pszSystemPbk = GetRasSystemPhoneBookPath();
  2219. if (pszSystemPbk)
  2220. {
  2221. //
  2222. // Try to create the phonebook, fails if file already exists
  2223. //
  2224. HANDLE hInf = CreateFileU(pszSystemPbk,
  2225. GENERIC_WRITE|GENERIC_READ,
  2226. 0,
  2227. NULL,
  2228. CREATE_NEW,
  2229. FILE_ATTRIBUTE_NORMAL,
  2230. NULL);
  2231. if (hInf != INVALID_HANDLE_VALUE)
  2232. {
  2233. CloseHandle(hInf);
  2234. }
  2235. }
  2236. CmFree(pszSystemPbk);
  2237. }
  2238. }
  2239. */
  2240. #endif
  2241. //+----------------------------------------------------------------------------
  2242. //
  2243. // Function: GetRasPbkFromNT5ProfilePath
  2244. //
  2245. // Synopsis: Helper function to manufacture a RAS phonebook path from
  2246. // a .CMP file path on NT5
  2247. //
  2248. // Arguments: LPCTSTR pszProfile - The full path to a profile .CMP file.
  2249. //
  2250. // Returns: LPTSTR - The new phonebook path. NULL on failure
  2251. //
  2252. // History: nickball Created 8/13/98
  2253. //
  2254. //+----------------------------------------------------------------------------
  2255. LPTSTR GetRasPbkFromNT5ProfilePath(LPCTSTR pszProfile)
  2256. {
  2257. MYDBGASSERT(OS_NT5);
  2258. MYDBGASSERT(pszProfile);
  2259. if (NULL == pszProfile)
  2260. {
  2261. return NULL;
  2262. }
  2263. //
  2264. // We will deduce the phonebook path from our current profile location.
  2265. //
  2266. LPTSTR pszRasPhonePath = (LPTSTR) CmMalloc(MAX_PATH + 1);
  2267. MYDBGASSERT(pszRasPhonePath);
  2268. if (pszRasPhonePath)
  2269. {
  2270. //
  2271. // Strip .CMP file name and parent directory
  2272. //
  2273. LPTSTR pszDir = CmStripFileName(pszProfile, FALSE);
  2274. MYDBGASSERT(pszDir);
  2275. if (pszDir)
  2276. {
  2277. LPTSTR pszTmp = CmStrrchr(pszDir, TEXT('\\'));
  2278. MYDBGASSERT(pszTmp);
  2279. if (pszTmp)
  2280. {
  2281. *pszTmp = 0;
  2282. //
  2283. // Append \\pbk\\rasphone.pbk
  2284. //
  2285. lstrcpyU(pszRasPhonePath, pszDir);
  2286. lstrcatU(pszRasPhonePath, TEXT("\\"));
  2287. lstrcatU(pszRasPhonePath, c_pszPbk);
  2288. lstrcatU(pszRasPhonePath, c_pszRasPhonePbk);
  2289. }
  2290. CmFree(pszDir);
  2291. }
  2292. else
  2293. {
  2294. CmFree(pszRasPhonePath);
  2295. }
  2296. }
  2297. return pszRasPhonePath;
  2298. }
  2299. #define MAX_BLOB_CHARS_PER_LINE 128
  2300. //+----------------------------------------------------------------------------
  2301. //
  2302. // Function: ReadDunSettingsEapData
  2303. //
  2304. // Synopsis: Retrieves DUN setting for EAP config (opaque blob) data. The
  2305. // entry may span several lines and contain several EAP data blocks.
  2306. //
  2307. // Arguments: CIni *pIni - Ptr to ini object to be used.
  2308. // LPBYTE* ppbEapData - Address of pointer to store EapData, allocated here.
  2309. // LPDWORD pdwEapSize - Ptr to a DWORD to record the size of the data blob.
  2310. // DWORD dwCustomAuthKey - The EAP type that we are interested in.
  2311. //
  2312. // Returns: TRUE on success
  2313. //
  2314. // Note: CM expects blob data to be provided in numbered entries such as:
  2315. // CustomAuthData0=, CustomAuthData1=, CustomAuthData2=, etc.
  2316. //
  2317. // History: nickball Created 08/24/98
  2318. // nickball Handle multiple EAP data blocks in blob. 09/11/99
  2319. //
  2320. //+----------------------------------------------------------------------------
  2321. BOOL ReadDunSettingsEapData(CIni *pIni,
  2322. LPBYTE* ppbEapData,
  2323. LPDWORD pdwEapSize,
  2324. const DWORD dwCustomAuthKey)
  2325. {
  2326. CHAR *pchBuf = NULL;
  2327. CHAR szTmp[MAX_BLOB_CHARS_PER_LINE + 2];
  2328. CHAR szEntry[128];
  2329. int nLine = -1;
  2330. int nRead = -1;
  2331. int nTotal = 0;
  2332. LPBYTE pbEapBytes = NULL;
  2333. MYDBGASSERT(pIni);
  2334. MYDBGASSERT(ppbEapData);
  2335. MYDBGASSERT(pdwEapSize);
  2336. if (NULL == pIni || NULL == ppbEapData || NULL == pdwEapSize)
  2337. {
  2338. return FALSE;
  2339. }
  2340. //
  2341. // First get the section (it should include &) then the entry.
  2342. //
  2343. BOOL bRet = FALSE;
  2344. LPWSTR pszLoadSection = pIni->LoadSection(c_pszCmSectionDunServer);
  2345. LPSTR pszSection = WzToSzWithAlloc(pszLoadSection);
  2346. LPSTR pszFile = WzToSzWithAlloc(pIni->GetFile());
  2347. if (!pszLoadSection || !pszSection || !pszFile)
  2348. {
  2349. bRet = FALSE;
  2350. goto exit;
  2351. }
  2352. //
  2353. // Read numbered entries until there are no more.
  2354. // Note: RAS blob doesn't exceed 64 chars, but can wrap over multiple lines
  2355. //
  2356. while (nRead)
  2357. {
  2358. //
  2359. // Read CustomAuthDataX where X is the number of entries
  2360. //
  2361. nLine++;
  2362. wsprintfA(szEntry, "%s%d", c_pszCmEntryDunServerCustomAuthData, nLine);
  2363. nRead = GetPrivateProfileStringA(pszSection, szEntry, "", szTmp, sizeof(szTmp), pszFile);
  2364. if (nRead)
  2365. {
  2366. //
  2367. // If line exceeded 64 chars, it is considered corrupt
  2368. //
  2369. if (MAX_BLOB_CHARS_PER_LINE < nRead)
  2370. {
  2371. nTotal = 0;
  2372. break;
  2373. }
  2374. //
  2375. // Update our local master buffer with the latest fragment
  2376. //
  2377. if (nLine)
  2378. {
  2379. pchBuf = CmStrCatAllocA(&pchBuf, szTmp);
  2380. }
  2381. else
  2382. {
  2383. pchBuf = CmStrCpyAllocA(szTmp);
  2384. }
  2385. if (!pchBuf)
  2386. {
  2387. bRet = FALSE;
  2388. goto exit;
  2389. }
  2390. nTotal += nRead;
  2391. }
  2392. }
  2393. //
  2394. // At this point we should have the entire entry in pchBuf in HEX format
  2395. // Convert the buffer to byte format and store in supplied EAP buffer.
  2396. //
  2397. if (nTotal && !(nTotal & 1))
  2398. {
  2399. nTotal /= 2; // Only need half the hex char size
  2400. pbEapBytes = (BYTE *) CmMalloc(nTotal + 1);
  2401. if (!pbEapBytes)
  2402. {
  2403. goto exit;
  2404. }
  2405. CHAR *pch = pchBuf;
  2406. BYTE *pb = pbEapBytes;
  2407. while (*pch != '\0')
  2408. {
  2409. *pb = HexValue( *pch++ ) * 16;
  2410. *pb += HexValue( *pch++ );
  2411. ++pb;
  2412. }
  2413. //
  2414. // Now we have the bytes, locate and extract the data block that we
  2415. // are after. Note: Multiple blocks are arrayed using the following
  2416. // header:
  2417. //
  2418. // typedef struct _EAP_CUSTOM_DATA
  2419. // {
  2420. // DWORD dwSignature;
  2421. // DWORD dwCustomAuthKey;
  2422. // DWORD dwSize;
  2423. // BYTE abdata[1];
  2424. // } EAP_CUSTOM_DATA;
  2425. //
  2426. EAP_CUSTOM_DATA *pCustomData = (EAP_CUSTOM_DATA *) pbEapBytes;
  2427. while (((LPBYTE) pCustomData - pbEapBytes) < nTotal)
  2428. {
  2429. if (pCustomData->dwCustomAuthKey == dwCustomAuthKey)
  2430. {
  2431. //
  2432. // Bingo! We have a match, first make sure that the indicated
  2433. // size isn't pointing out into space, then make a copy and
  2434. // run for the hills.
  2435. //
  2436. if (((LPBYTE) pCustomData - pbEapBytes) + sizeof(EAP_CUSTOM_DATA) + pCustomData->dwSize > (DWORD) nTotal)
  2437. {
  2438. MYDBGASSERT(FALSE);
  2439. goto exit;
  2440. }
  2441. *ppbEapData = (BYTE *) CmMalloc(pCustomData->dwSize);
  2442. if (*ppbEapData)
  2443. {
  2444. CopyMemory(*ppbEapData, pCustomData->abdata, pCustomData->dwSize);
  2445. *pdwEapSize = pCustomData->dwSize;
  2446. bRet = TRUE;
  2447. goto exit;
  2448. }
  2449. }
  2450. //
  2451. // Locate the next data block
  2452. //
  2453. pCustomData = (EAP_CUSTOM_DATA *) ((LPBYTE) pCustomData + sizeof(EAP_CUSTOM_DATA) + pCustomData->dwSize);
  2454. }
  2455. }
  2456. exit:
  2457. CmFree(pchBuf);
  2458. CmFree(pszLoadSection);
  2459. CmFree(pszSection);
  2460. CmFree(pszFile);
  2461. CmFree(pbEapBytes);
  2462. return bRet;
  2463. }
  2464. //+----------------------------------------------------------------------------
  2465. //
  2466. // Function: ReadDUNSettings
  2467. //
  2468. // Synopsis: Reads the DUN settings for the specified DUN name and .CMS file
  2469. // into a RASENTRY structure. Because some settings are not supported
  2470. // on downlevel platforms, this function will potentially display an
  2471. // error message to the user.
  2472. //
  2473. // Arguments: ArgsStruct *pArgs - Ptr to global args struct.
  2474. // LPCSTR pszFile - Full path to the .CMS file.
  2475. // LPCTSTR pszDunName - The DUN name for the settings.
  2476. // LPVOID pvBuffer - Ptr to RASENTRY buffer.
  2477. // LPBYTE* ppbEapData - Address of pointer to store EapData
  2478. // LPDWORD pdwEapSize - Ptr to a DWORD to record the size of the data blob.
  2479. // BOOL fTunnel - are we reading tunnel settings?
  2480. //
  2481. // Returns: ERROR_SUCCESS on success. Use GetLastError for failure details.
  2482. //
  2483. // Note: This was formerly the PhoneBookReadDun API in CMPBK.DLL
  2484. //
  2485. // History: nickball 8/22/98 Created Header
  2486. // nickball 02/03/99 Added pArgs :( in order to have access to the
  2487. // the top-level service for path conversion.
  2488. //
  2489. //+----------------------------------------------------------------------------
  2490. LRESULT ReadDUNSettings(ArgsStruct *pArgs,
  2491. LPCTSTR pszFile,
  2492. LPCTSTR pszDunName,
  2493. LPVOID pvBuffer,
  2494. LPBYTE* ppbEapData,
  2495. LPDWORD pdwEapSize,
  2496. BOOL fTunnel)
  2497. {
  2498. MYDBGASSERT(pszFile);
  2499. MYDBGASSERT(pszDunName);
  2500. MYDBGASSERT(pvBuffer);
  2501. if (NULL == pszFile || NULL == pszDunName || NULL == pvBuffer)
  2502. {
  2503. return (ERROR_INVALID_PARAMETER);
  2504. }
  2505. CMTRACE1(TEXT("ReadDUNSettings -- using DUN setting: %s"), pszDunName);
  2506. RASENTRYW *preRas = (RASENTRYW *) pvBuffer;
  2507. //
  2508. // Setup INI object. Prepend pszDunName with "&" for section.
  2509. //
  2510. CIni iniFile(g_hInst, pszFile);
  2511. LPTSTR pszSection = CmStrCpyAlloc(TEXT("&"));
  2512. pszSection = CmStrCatAlloc(&pszSection, pszDunName);
  2513. iniFile.SetSection(pszSection);
  2514. CmFree(pszSection);
  2515. //
  2516. // Get and apply the Phone section entries
  2517. //
  2518. if (iniFile.GPPB(c_pszCmSectionDunPhone, c_pszCmEntryDunPhoneDialAsIs))
  2519. {
  2520. preRas->dwfOptions &= ~RASEO_UseCountryAndAreaCodes;;
  2521. }
  2522. CopyGPPS(&iniFile, c_pszCmSectionDunPhone, c_pszCmEntryDunPhonePhoneNumber, preRas->szLocalPhoneNumber, sizeof(preRas->szLocalPhoneNumber)/sizeof(TCHAR));
  2523. CopyGPPS(&iniFile,c_pszCmSectionDunPhone, c_pszCmEntryDunPhoneAreaCode, preRas->szAreaCode, sizeof(preRas->szAreaCode)/sizeof(TCHAR));
  2524. preRas->dwCountryCode = iniFile.GPPI(c_pszCmSectionDunPhone, c_pszCmEntryDunPhoneCountryCode, preRas->dwCountryCode);
  2525. preRas->dwCountryID = iniFile.GPPI(c_pszCmSectionDunPhone, c_pszCmEntryDunPhoneCountryId, preRas->dwCountryID);
  2526. //
  2527. // Get and apply the Device section entries
  2528. //
  2529. CopyGPPS(&iniFile,c_pszCmSectionDunDevice, c_pszCmEntryDunDeviceType, preRas->szDeviceType, sizeof(preRas->szDeviceType)/sizeof(TCHAR));
  2530. CopyGPPS(&iniFile,c_pszCmSectionDunDevice, c_pszCmEntryDunDeviceName, preRas->szDeviceName, sizeof(preRas->szDeviceName)/sizeof(TCHAR));
  2531. //
  2532. // Get and apply the Server section entries
  2533. //
  2534. LPTSTR pszTmp = iniFile.GPPS(c_pszCmSectionDunServer, c_pszCmEntryDunServerType);
  2535. if (*pszTmp)
  2536. {
  2537. if (0 == lstrcmpiU(pszTmp, c_pszDunPpp))
  2538. {
  2539. preRas->dwFramingProtocol = RASFP_Ppp;
  2540. }
  2541. else if (0 == lstrcmpiU(pszTmp, c_pszDunCslip))
  2542. {
  2543. preRas->dwFramingProtocol = RASFP_Slip;
  2544. preRas->dwfOptions |= RASEO_IpHeaderCompression;
  2545. }
  2546. else if (0 == lstrcmpiU(pszTmp, c_pszDunSlip))
  2547. {
  2548. preRas->dwFramingProtocol = RASFP_Slip;
  2549. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunTcpIpIpHeaderCompress,
  2550. (BOOL) preRas->dwfOptions & RASEO_IpHeaderCompression))
  2551. {
  2552. preRas->dwfOptions |= RASEO_IpHeaderCompression;
  2553. }
  2554. else
  2555. {
  2556. preRas->dwfOptions &= ~RASEO_IpHeaderCompression;
  2557. }
  2558. }
  2559. }
  2560. CmFree(pszTmp);
  2561. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerSwCompress,
  2562. (BOOL) preRas->dwfOptions & RASEO_SwCompression))
  2563. {
  2564. preRas->dwfOptions |= RASEO_SwCompression;
  2565. }
  2566. else
  2567. {
  2568. preRas->dwfOptions &= ~RASEO_SwCompression;
  2569. }
  2570. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerDisableLcp,
  2571. (BOOL) preRas->dwfOptions & RASEO_DisableLcpExtensions))
  2572. {
  2573. preRas->dwfOptions |= RASEO_DisableLcpExtensions;
  2574. }
  2575. else
  2576. {
  2577. preRas->dwfOptions &= ~RASEO_DisableLcpExtensions;
  2578. }
  2579. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerNetworkLogon,
  2580. (BOOL) preRas->dwfOptions & RASEO_NetworkLogon))
  2581. {
  2582. preRas->dwfOptions |= RASEO_NetworkLogon;
  2583. }
  2584. else
  2585. {
  2586. preRas->dwfOptions &= ~RASEO_NetworkLogon;
  2587. }
  2588. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerNegotiateTcpIp,
  2589. (BOOL) preRas->dwfNetProtocols & RASNP_Ip))
  2590. {
  2591. preRas->dwfNetProtocols |= RASNP_Ip;
  2592. }
  2593. else
  2594. {
  2595. preRas->dwfNetProtocols &= ~RASNP_Ip;
  2596. }
  2597. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerNegotiateIpx,
  2598. (BOOL) preRas->dwfNetProtocols & RASNP_Ipx))
  2599. {
  2600. preRas->dwfNetProtocols |= RASNP_Ipx;
  2601. }
  2602. else
  2603. {
  2604. preRas->dwfNetProtocols &= ~RASNP_Ipx;
  2605. }
  2606. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerNegotiateNetBeui, preRas->dwfNetProtocols&RASNP_NetBEUI))
  2607. {
  2608. preRas->dwfNetProtocols |= RASNP_NetBEUI;
  2609. }
  2610. else
  2611. {
  2612. preRas->dwfNetProtocols &= ~RASNP_NetBEUI;
  2613. }
  2614. //
  2615. // Get the NT5 specific DUN settings. We will error out if we're running
  2616. // downlevel when these settings are configured and the EnforceCustomSecurity
  2617. // flag has been set.
  2618. //
  2619. // Note: c_pszCmEntryDunServerEnforceCustomSecurity is a DUN setting and is FALSE by default
  2620. //
  2621. BOOL bEnforceCustomSecurity = iniFile.GPPI(c_pszCmSectionDunServer, c_pszCmEntryDunServerEnforceCustomSecurity, FALSE);
  2622. //
  2623. // Is EAP required
  2624. //
  2625. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireEap,
  2626. (BOOL) preRas->dwfOptions & RASEO_RequireEAP))
  2627. {
  2628. if (!(OS_NT5) && bEnforceCustomSecurity)
  2629. {
  2630. return (ERROR_INVALID_DATA);
  2631. }
  2632. preRas->dwfOptions |= RASEO_RequireEAP;
  2633. }
  2634. else
  2635. {
  2636. preRas->dwfOptions &= ~RASEO_RequireEAP;
  2637. }
  2638. //
  2639. // PAP required
  2640. //
  2641. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequirePap,
  2642. (BOOL) preRas->dwfOptions & RASEO_RequirePAP))
  2643. {
  2644. if (!(OS_NT5) && bEnforceCustomSecurity)
  2645. {
  2646. return (ERROR_INVALID_DATA);
  2647. }
  2648. preRas->dwfOptions |= RASEO_RequirePAP;
  2649. }
  2650. else
  2651. {
  2652. preRas->dwfOptions &= ~RASEO_RequirePAP;
  2653. }
  2654. //
  2655. // SPAP required
  2656. //
  2657. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireSpap,
  2658. (BOOL) preRas->dwfOptions & RASEO_RequireSPAP))
  2659. {
  2660. if (!(OS_NT5) && bEnforceCustomSecurity)
  2661. {
  2662. return (ERROR_INVALID_DATA);
  2663. }
  2664. preRas->dwfOptions |= RASEO_RequireSPAP;
  2665. }
  2666. else
  2667. {
  2668. preRas->dwfOptions &= ~RASEO_RequireSPAP;
  2669. }
  2670. //
  2671. // CHAP required
  2672. //
  2673. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireChap,
  2674. (BOOL) preRas->dwfOptions & RASEO_RequireCHAP))
  2675. {
  2676. if (!(OS_NT5) && bEnforceCustomSecurity)
  2677. {
  2678. return (ERROR_INVALID_DATA);
  2679. }
  2680. preRas->dwfOptions |= RASEO_RequireCHAP;
  2681. }
  2682. else
  2683. {
  2684. preRas->dwfOptions &= ~RASEO_RequireCHAP;
  2685. }
  2686. //
  2687. // MSCHAP required
  2688. //
  2689. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireMsChap,
  2690. (BOOL) preRas->dwfOptions & RASEO_RequireMsCHAP))
  2691. {
  2692. if (!(OS_NT5) && bEnforceCustomSecurity)
  2693. {
  2694. return (ERROR_INVALID_DATA);
  2695. }
  2696. preRas->dwfOptions |= RASEO_RequireMsCHAP;
  2697. }
  2698. else
  2699. {
  2700. preRas->dwfOptions &= ~RASEO_RequireMsCHAP;
  2701. }
  2702. //
  2703. // MSCHAP2 required
  2704. //
  2705. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireMsChap2,
  2706. (BOOL) preRas->dwfOptions & RASEO_RequireMsCHAP2))
  2707. {
  2708. if (!(OS_NT5) && bEnforceCustomSecurity)
  2709. {
  2710. return (ERROR_INVALID_DATA);
  2711. }
  2712. preRas->dwfOptions |= RASEO_RequireMsCHAP2;
  2713. }
  2714. else
  2715. {
  2716. preRas->dwfOptions &= ~RASEO_RequireMsCHAP2;
  2717. }
  2718. //
  2719. // W95 MSCHAP required
  2720. //
  2721. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireW95MsChap,
  2722. (BOOL) preRas->dwfOptions & RASEO_RequireW95MSCHAP))
  2723. {
  2724. if (!(OS_NT5) && bEnforceCustomSecurity)
  2725. {
  2726. return (ERROR_INVALID_DATA);
  2727. }
  2728. preRas->dwfOptions |= RASEO_RequireW95MSCHAP;
  2729. }
  2730. else
  2731. {
  2732. preRas->dwfOptions &= ~RASEO_RequireW95MSCHAP;
  2733. }
  2734. //
  2735. // Custom Security configuration
  2736. //
  2737. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerCustomSecurity,
  2738. (BOOL) preRas->dwfOptions & RASEO_Custom))
  2739. {
  2740. if (!(OS_NT5) && bEnforceCustomSecurity)
  2741. {
  2742. return (ERROR_INVALID_DATA);
  2743. }
  2744. preRas->dwfOptions |= RASEO_Custom;
  2745. }
  2746. else
  2747. {
  2748. preRas->dwfOptions &= ~RASEO_Custom;
  2749. }
  2750. //
  2751. // Now get the legacy security settings if we don't already have
  2752. // settings specificed from above. By checking for the Win2k specific
  2753. // settings first we allow Admins to specify both so that legacy platforms
  2754. // can have settings but Win2k can use the more granular settings.
  2755. // If we didn't do this the legacy flags could water down the security on Win2k ...
  2756. //
  2757. const DWORD dwWin2kSecuritySettings = RASEO_RequireEAP | RASEO_RequirePAP | RASEO_RequireSPAP |
  2758. RASEO_RequireCHAP | RASEO_RequireMsCHAP | RASEO_RequireMsCHAP2 | RASEO_RequireW95MSCHAP;
  2759. if (0 == (preRas->dwfOptions & dwWin2kSecuritySettings) || !OS_NT5)
  2760. {
  2761. //
  2762. // Security settings
  2763. //
  2764. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerPwEncrypt,
  2765. (BOOL) preRas->dwfOptions & RASEO_RequireEncryptedPw))
  2766. {
  2767. preRas->dwfOptions |= RASEO_RequireEncryptedPw;
  2768. }
  2769. else
  2770. {
  2771. preRas->dwfOptions &= ~RASEO_RequireEncryptedPw;
  2772. }
  2773. //
  2774. // MS-CHAP
  2775. //
  2776. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerPwEncryptMs,
  2777. (BOOL) preRas->dwfOptions & RASEO_RequireMsEncryptedPw))
  2778. {
  2779. preRas->dwfOptions |= RASEO_RequireMsEncryptedPw;
  2780. }
  2781. else
  2782. {
  2783. preRas->dwfOptions &= ~RASEO_RequireMsEncryptedPw;
  2784. }
  2785. }
  2786. else
  2787. {
  2788. CMASSERTMSG((preRas->dwfOptions & RASEO_Custom), TEXT("ReadDUNSettings -- Win2k+ security setting configured but RASEO_Custom not specified."));
  2789. }
  2790. //
  2791. // Encrypt Data (legacy setting, same as ET_Require from above)
  2792. //
  2793. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerDataEncrypt,
  2794. (BOOL) preRas->dwfOptions & RASEO_RequireDataEncryption))
  2795. {
  2796. preRas->dwfOptions |= RASEO_RequireDataEncryption;
  2797. }
  2798. else
  2799. {
  2800. preRas->dwfOptions &= ~RASEO_RequireDataEncryption;
  2801. }
  2802. //
  2803. // Encryption type, just a straight int read. (win2k+ setting)
  2804. //
  2805. int nTmp = iniFile.GPPI(c_pszCmSectionDunServer, c_pszCmEntryDunServerEncryptionType, -1);
  2806. if (OS_NT5)
  2807. {
  2808. //
  2809. // We need to set Tunnel encryption type to ET_Require because that's what the ConnFolder does.
  2810. // We also set it ET_Require if the user specified RASEO_RequireDataEncryption as a legacy setting
  2811. // but didn't specify a specific win2k setting.
  2812. //
  2813. if (-1 == nTmp)
  2814. {
  2815. if (fTunnel || (preRas->dwfOptions & RASEO_RequireDataEncryption))
  2816. {
  2817. nTmp = ET_Require;
  2818. }
  2819. else
  2820. {
  2821. nTmp = ET_Optional;
  2822. }
  2823. }
  2824. ((LPRASENTRY_V500)preRas)->dwEncryptionType = (DWORD) nTmp;
  2825. }
  2826. else
  2827. {
  2828. if (-1 != nTmp && bEnforceCustomSecurity)
  2829. {
  2830. return (ERROR_INVALID_DATA);
  2831. }
  2832. }
  2833. //
  2834. // Get the EAP type ID (CustomAuthKey) - The data is stored in the RAS
  2835. // pbk via a specific API, just before dialing - SetCustomAuthData().
  2836. //
  2837. nTmp = iniFile.GPPI(c_pszCmSectionDunServer, c_pszCmEntryDunServerCustomAuthKey, -1);
  2838. //
  2839. // If a type ID for EAP is specified, see if there is any config data
  2840. //
  2841. if (-1 != nTmp)
  2842. {
  2843. if (!(OS_NT5) && bEnforceCustomSecurity)
  2844. {
  2845. return (ERROR_INVALID_DATA);
  2846. }
  2847. //
  2848. // We have an ID and its NT5, read the EAP config data
  2849. //
  2850. ((LPRASENTRY_V500)preRas)->dwCustomAuthKey = nTmp;
  2851. ReadDunSettingsEapData(&iniFile, ppbEapData, pdwEapSize, nTmp);
  2852. }
  2853. //
  2854. // Get and apply the Networking section entries.
  2855. //
  2856. nTmp = iniFile.GPPI(c_pszCmSectionDunNetworking, c_pszCmEntryDunNetworkingVpnStrategy, -1);
  2857. if (-1 != nTmp)
  2858. {
  2859. if (!(OS_NT5) && bEnforceCustomSecurity)
  2860. {
  2861. return (ERROR_INVALID_DATA);
  2862. }
  2863. ((LPRASENTRY_V500)preRas)->dwVpnStrategy = nTmp;
  2864. }
  2865. //
  2866. // See if the profile calls for using a Pre-Shared Key for L2TP. Note that we currently don't
  2867. // provide a mechanism to set the Pre-Shared Key through RasSetCredentials but that could easily
  2868. // be done through a custom action or a post install action.
  2869. //
  2870. if (OS_NT51)
  2871. {
  2872. if (iniFile.GPPB(c_pszCmSectionDunNetworking, c_pszCmEntryDunNetworkingUsePreSharedKey,
  2873. (BOOL) ((LPRASENTRY_V501)preRas)->dwfOptions2 & RASEO2_UsePreSharedKey))
  2874. {
  2875. ((LPRASENTRY_V501)preRas)->dwfOptions2 |= RASEO2_UsePreSharedKey;
  2876. }
  2877. else
  2878. {
  2879. ((LPRASENTRY_V501)preRas)->dwfOptions2 &= ~RASEO2_UsePreSharedKey;
  2880. }
  2881. }
  2882. //
  2883. // File and Print sharing. Note that on systems up to Win2k we only have the traditional RASEO_SecureLocalFiles.
  2884. // However, Win2k gave this flag two purposes (enable/disable NetBt and enable/disable file and print sharing).
  2885. // In Whistler two separate flags were developed to allow greater granularity. To give legacy profiles the behavior
  2886. // they expect while disabling file and print sharing as the default the logic gets a little complicated. Basically
  2887. // the new flag overrides the legacy flag and defaults to 1. If the new flag isn't specified then we use the value
  2888. // of the legacy flag if it is specified. If neither is specified we set it to 1. On platforms previous to Whistler
  2889. // the old flag is the only thing we have and it defaults to 0.
  2890. //
  2891. int nLegacySecureLocalFiles = iniFile.GPPI(c_pszCmSectionDunServer, c_pszCmEntryDunServerSecureLocalFiles, -1);
  2892. int nSecureFileAndPrint = iniFile.GPPI(c_pszCmSectionDunServer, c_pszCmEntryDunNetworkingSecureFileAndPrint, -1);
  2893. if (-1 == nSecureFileAndPrint)
  2894. {
  2895. nSecureFileAndPrint = nLegacySecureLocalFiles ? 1 : 0;
  2896. }
  2897. if (-1 == nLegacySecureLocalFiles)
  2898. {
  2899. nLegacySecureLocalFiles = 0;
  2900. }
  2901. if (OS_NT51)
  2902. {
  2903. //
  2904. // Set the 501/Options2 style File and Print sharing flag
  2905. //
  2906. if (nSecureFileAndPrint)
  2907. {
  2908. if (!(OS_NT5) && bEnforceCustomSecurity)
  2909. {
  2910. return (ERROR_INVALID_DATA);
  2911. }
  2912. ((LPRASENTRY_V501)preRas)->dwfOptions2 |= RASEO2_SecureFileAndPrint;
  2913. }
  2914. else
  2915. {
  2916. ((LPRASENTRY_V501)preRas)->dwfOptions2 &= ~RASEO2_SecureFileAndPrint;
  2917. }
  2918. }
  2919. else
  2920. {
  2921. if (nLegacySecureLocalFiles)
  2922. {
  2923. preRas->dwfOptions |= RASEO_SecureLocalFiles;
  2924. }
  2925. else
  2926. {
  2927. preRas->dwfOptions &= ~RASEO_SecureLocalFiles;
  2928. }
  2929. }
  2930. //
  2931. // Pick up Whistler specific DUN settings
  2932. //
  2933. if (OS_NT51)
  2934. {
  2935. //
  2936. // Get the 501/Options2 style MSNet binding flag
  2937. //
  2938. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunNetworkingSecureClientForMSNet,
  2939. (BOOL) ((LPRASENTRY_V501)preRas)->dwfOptions2 & RASEO2_SecureClientForMSNet))
  2940. {
  2941. ((LPRASENTRY_V501)preRas)->dwfOptions2 |= RASEO2_SecureClientForMSNet;
  2942. }
  2943. else
  2944. {
  2945. ((LPRASENTRY_V501)preRas)->dwfOptions2 &= ~RASEO2_SecureClientForMSNet;
  2946. }
  2947. //
  2948. // Get the 501/Options2 style Multilink Negotiation flag
  2949. //
  2950. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunNetworkingDontNegotiateMultilink,
  2951. (BOOL) ((LPRASENTRY_V501)preRas)->dwfOptions2 & RASEO2_DontNegotiateMultilink))
  2952. {
  2953. ((LPRASENTRY_V501)preRas)->dwfOptions2 |= RASEO2_DontNegotiateMultilink;
  2954. }
  2955. else
  2956. {
  2957. ((LPRASENTRY_V501)preRas)->dwfOptions2 &= ~RASEO2_DontNegotiateMultilink;
  2958. }
  2959. //
  2960. // Get the 501/Options2 style DontUseRasCredentials flag
  2961. //
  2962. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunNetworkingDontUseRasCredentials,
  2963. (BOOL) ((LPRASENTRY_V501)preRas)->dwfOptions2 & RASEO2_DontUseRasCredentials))
  2964. {
  2965. ((LPRASENTRY_V501)preRas)->dwfOptions2 |= RASEO2_DontUseRasCredentials;
  2966. }
  2967. else
  2968. {
  2969. ((LPRASENTRY_V501)preRas)->dwfOptions2 &= ~RASEO2_DontUseRasCredentials;
  2970. }
  2971. //
  2972. // Get the RASEO_CustomScript flag value. Note that this flag existed on Win2k but wasn't
  2973. // available for RasDial only RasDialDlg. On Whistler+ it is available to RasDial as well.
  2974. // Note that we also have to set the RDEOPT_UseCustomScripting flag in the RASDIALEXTENSIONS
  2975. // for this to work.
  2976. //
  2977. if (iniFile.GPPB(c_pszCmSectionDunScripting, c_pszCmEntryDunScriptingUseRasCustomScriptDll,
  2978. (BOOL) (preRas->dwfOptions & RASEO_CustomScript)))
  2979. {
  2980. preRas->dwfOptions |= RASEO_CustomScript;
  2981. }
  2982. else
  2983. {
  2984. preRas->dwfOptions &= ~RASEO_CustomScript;
  2985. }
  2986. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerDisableNbtOverIP,
  2987. (BOOL) (((LPRASENTRY_V501)preRas)->dwfOptions2 & RASEO2_DisableNbtOverIP)))
  2988. {
  2989. ((LPRASENTRY_V501)preRas)->dwfOptions2 |= RASEO2_DisableNbtOverIP;
  2990. }
  2991. else
  2992. {
  2993. ((LPRASENTRY_V501)preRas)->dwfOptions2 &= ~RASEO2_DisableNbtOverIP;
  2994. }
  2995. }
  2996. //
  2997. // Get and apply the TCP/IP section entries
  2998. //
  2999. if (iniFile.GPPB(c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpSpecifyIpAddress,
  3000. (BOOL) preRas->dwfOptions & RASEO_SpecificIpAddr))
  3001. {
  3002. preRas->dwfOptions |= RASEO_SpecificIpAddr;
  3003. }
  3004. else
  3005. {
  3006. preRas->dwfOptions &= ~RASEO_SpecificIpAddr;
  3007. }
  3008. Ip_GPPS(&iniFile, c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpIpAddress, &preRas->ipaddr);
  3009. if (iniFile.GPPB(c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpSpecifyServerAddress,
  3010. (BOOL) preRas->dwfOptions & RASEO_SpecificNameServers))
  3011. {
  3012. preRas->dwfOptions |= RASEO_SpecificNameServers;
  3013. }
  3014. else
  3015. {
  3016. preRas->dwfOptions &= ~RASEO_SpecificNameServers;
  3017. }
  3018. if (iniFile.GPPB(c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpIpHeaderCompress,
  3019. (BOOL) preRas->dwfOptions & RASEO_IpHeaderCompression))
  3020. {
  3021. preRas->dwfOptions |= RASEO_IpHeaderCompression;
  3022. }
  3023. else
  3024. {
  3025. preRas->dwfOptions &= ~RASEO_IpHeaderCompression;
  3026. }
  3027. Ip_GPPS(&iniFile, c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpDnsAddress, &preRas->ipaddrDns);
  3028. Ip_GPPS(&iniFile, c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpDnsAltAddress, &preRas->ipaddrDnsAlt);
  3029. Ip_GPPS(&iniFile, c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpWinsAddress, &preRas->ipaddrWins);
  3030. Ip_GPPS(&iniFile, c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpWinsAltAddress, &preRas->ipaddrWinsAlt);
  3031. if (iniFile.GPPB(c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpGatewayOnRemote,
  3032. (BOOL) preRas->dwfOptions & RASEO_RemoteDefaultGateway))
  3033. {
  3034. preRas->dwfOptions |= RASEO_RemoteDefaultGateway;
  3035. }
  3036. else
  3037. {
  3038. preRas->dwfOptions &= ~RASEO_RemoteDefaultGateway;
  3039. }
  3040. if (OS_NT51)
  3041. {
  3042. //
  3043. // If the caller specified a DNS suffix then lets read it and add it to the RAS entry
  3044. //
  3045. CopyGPPS(&iniFile, c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpDnsSuffix, ((LPRASENTRY_V501)preRas)->szDnsSuffix, sizeof(((LPRASENTRY_V501)preRas)->szDnsSuffix)/sizeof(TCHAR));
  3046. }
  3047. //
  3048. // Set the TCP Window size -- the NTT DoCoMo fix for Whistler. The Win2k version of this fix
  3049. // must be written through a private RAS API that must be called after the phonebook entry
  3050. // exists ie. after we call RasSetEntryProperties ... otherwise it won't work on the first
  3051. // dial.
  3052. //
  3053. if (OS_NT51)
  3054. {
  3055. ((LPRASENTRY_V501)preRas)->dwTcpWindowSize = iniFile.GPPI(c_pszCmSectionDunTcpIp, c_pszCmEntryDunTcpIpTcpWindowSize, 0);
  3056. }
  3057. //
  3058. // Get and apply the Scripting section entries
  3059. //
  3060. TCHAR szScript[MAX_PATH + 1] = TEXT("");
  3061. CopyGPPS(&iniFile,c_pszCmSectionDunScripting, c_pszCmEntryDunScriptingName, szScript, sizeof(szScript)/sizeof(TCHAR));
  3062. //
  3063. // The script path from our cms file is a relative path. We need to convert
  3064. // it to a full path, but make sure that we use the top-level service for
  3065. // the conversion because it is used to derive the short-service name for
  3066. // the directory. Note that tunnel dun settings cannot have a script.
  3067. //
  3068. if (szScript[0] && !fTunnel)
  3069. {
  3070. CMTRACE1(TEXT("ReadDunSettings() - Converting script path %s to full path"), szScript);
  3071. pszTmp = CmConvertRelativePath(pArgs->piniService->GetFile(), szScript);
  3072. MYDBGASSERT(pszTmp);
  3073. if (pszTmp && *pszTmp)
  3074. {
  3075. lstrcpyU(preRas->szScript, pszTmp);
  3076. CMTRACE1(TEXT("ReadDunSettings() - Script file is %s"), preRas->szScript);
  3077. }
  3078. CmFree(pszTmp);
  3079. }
  3080. else
  3081. {
  3082. //
  3083. // The cms didn't specify a script ==> no script
  3084. //
  3085. preRas->szScript[0] = TEXT('\0');
  3086. }
  3087. //
  3088. // If this is Whistler+ then we may need to invoke a terminal window
  3089. //
  3090. if (OS_NT51 && !fTunnel && iniFile.GPPB(c_pszCmSectionDunScripting, c_pszCmEntryDunScriptingUseTerminalWindow,
  3091. (BOOL) preRas->dwfOptions & RASEO_TerminalAfterDial))
  3092. {
  3093. preRas->dwfOptions |= RASEO_TerminalAfterDial;
  3094. }
  3095. else
  3096. {
  3097. preRas->dwfOptions &= ~RASEO_TerminalAfterDial;
  3098. }
  3099. return (ERROR_SUCCESS);
  3100. }
  3101. //+----------------------------------------------------------------------------
  3102. //
  3103. // Function: ValidateDialupDunSettings
  3104. //
  3105. // Synopsis: Verifies the DUN settings that the specified .CMS and DUN name are
  3106. // supported on the current platform. If we are running on a downlevel
  3107. // OS and we encounter any NT specific security settings we error out.
  3108. //
  3109. // Arguments: LPCTSTR pszCmsFile - The phone # specific .CMS file name.
  3110. // LPCTSTR pszDunName - The DUN name, if any for the settings.
  3111. // LPCTSTR pszTopLevelCms - The top-level CMS file name.
  3112. //
  3113. // Returns: BOOL - TRUE on success.
  3114. //
  3115. // History: nickball Created 8/26/98
  3116. //
  3117. //+----------------------------------------------------------------------------
  3118. BOOL ValidateDialupDunSettings(LPCTSTR pszCmsFile, LPCTSTR pszDunName, LPCTSTR pszTopLevelCms)
  3119. {
  3120. MYDBGASSERT(pszCmsFile);
  3121. MYDBGASSERT(*pszCmsFile);
  3122. MYDBGASSERT(pszDunName);
  3123. if (NULL == pszCmsFile || (!*pszCmsFile) || NULL == pszDunName)
  3124. {
  3125. return FALSE;
  3126. }
  3127. //
  3128. // On NT5 we currently support all settings, so succeed automatically
  3129. //
  3130. if (OS_NT5)
  3131. {
  3132. return TRUE;
  3133. }
  3134. //
  3135. // Determine the DUN name that we are looking for. In the tunnel case we
  3136. // always read it from the .CMS. For dial-up, we'll use the specified DUN
  3137. // name, and revert to the .CMS if blank.
  3138. //
  3139. CIni iniFile(g_hInst, pszCmsFile);
  3140. //
  3141. // Now determine the DUN name to be used when looking up settings.
  3142. //
  3143. LPTSTR pszEntryName;
  3144. //
  3145. // If we have a specific DUN name to use, and we're not tunneling
  3146. // use it instead of the default DUN setting in the .CMS.
  3147. //
  3148. if (pszDunName && *pszDunName)
  3149. {
  3150. pszEntryName = CmStrCpyAlloc(pszDunName);
  3151. }
  3152. else
  3153. {
  3154. pszEntryName = GetDefaultDunSettingName(&iniFile, FALSE); // FALSE == not tunnel
  3155. }
  3156. //
  3157. // If no DUN name is specified, then pass validation automatically
  3158. //
  3159. if (!pszEntryName || (!*pszEntryName))
  3160. {
  3161. CmFree(pszEntryName);
  3162. CMTRACE1(TEXT("ValidateDunSettings() - No DUN name found in %s"), pszCmsFile);
  3163. return TRUE;
  3164. }
  3165. //
  3166. // Include the entryname in the section headers
  3167. //
  3168. LPTSTR pszSection = CmStrCpyAlloc(TEXT("&"));
  3169. pszSection = CmStrCatAlloc(&pszSection, pszEntryName);
  3170. iniFile.SetSection(pszSection);
  3171. CmFree(pszSection);
  3172. CmFree(pszEntryName);
  3173. //
  3174. // Check to see if the admin wants us to check the custom security settings
  3175. // against the platform. By default, we do not enforce this check.
  3176. //
  3177. //
  3178. if (FALSE == iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerEnforceCustomSecurity))
  3179. {
  3180. return TRUE;
  3181. }
  3182. //
  3183. // Now check the actual settings if we're still here.
  3184. //
  3185. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireEap))
  3186. {
  3187. goto ValidateDunSettingsExit;
  3188. }
  3189. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequirePap))
  3190. {
  3191. goto ValidateDunSettingsExit;
  3192. }
  3193. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireSpap))
  3194. {
  3195. goto ValidateDunSettingsExit;
  3196. }
  3197. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireChap))
  3198. {
  3199. goto ValidateDunSettingsExit;
  3200. }
  3201. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireMsChap))
  3202. {
  3203. goto ValidateDunSettingsExit;
  3204. }
  3205. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireMsChap2))
  3206. {
  3207. goto ValidateDunSettingsExit;
  3208. }
  3209. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerRequireW95MsChap))
  3210. {
  3211. goto ValidateDunSettingsExit;
  3212. }
  3213. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerCustomSecurity))
  3214. {
  3215. goto ValidateDunSettingsExit;
  3216. }
  3217. if (iniFile.GPPB(c_pszCmSectionDunServer, c_pszCmEntryDunServerEncryptionType))
  3218. {
  3219. goto ValidateDunSettingsExit;
  3220. }
  3221. if (-1 != iniFile.GPPI(c_pszCmSectionDunServer, c_pszCmEntryDunServerCustomAuthKey, -1))
  3222. {
  3223. goto ValidateDunSettingsExit;
  3224. }
  3225. if (-1 != iniFile.GPPI(c_pszCmSectionDunNetworking, c_pszCmEntryDunNetworkingVpnStrategy, -1))
  3226. {
  3227. goto ValidateDunSettingsExit;
  3228. }
  3229. return TRUE;
  3230. ValidateDunSettingsExit:
  3231. //
  3232. // Get the top-level service name
  3233. //
  3234. CIni iniTopLevelCms(g_hInst, pszTopLevelCms);
  3235. LPTSTR pszTitle = GetServiceName(&iniTopLevelCms);
  3236. LPTSTR pszTmp = CmFmtMsg(g_hInst,IDMSG_UNSUPPORTED_SETTING_NUM);
  3237. MessageBoxEx(NULL, pszTmp, pszTitle, MB_OK|MB_ICONSTOP, LANG_USER_DEFAULT);//13309
  3238. CmFree(pszTmp);
  3239. CmFree(pszTitle);
  3240. CMTRACE1(TEXT("ValidateDunSettings() - Unsupported setting detected in %s"), pszCmsFile);
  3241. return FALSE;
  3242. }
  3243. //+----------------------------------------------------------------------------
  3244. //
  3245. // Function: InvokeTerminalWindow
  3246. //
  3247. // Synopsis: Allows CM to invoke a terminal window on Whistler or later versions
  3248. // of Win2k but calling a private RAS API in RasDlg.dll.
  3249. //
  3250. // Arguments: LPCWSTR pszPhoneBook - full path to the phonebook file
  3251. // LPCWSTR pszEntry - entry name to invoke the terminal window for
  3252. // RASDIALPARAMS *pRasDialParams - RasDialParams for the connection
  3253. // to invoke the terminal window for
  3254. // HWND hWnd - window handle of the parent dialog
  3255. // HRASCONN hRasconn - handle to the ras connection
  3256. //
  3257. // Returns: Windows error message
  3258. //
  3259. // History: quintinb Created 07/11/00
  3260. //
  3261. //+----------------------------------------------------------------------------
  3262. DWORD InvokeTerminalWindow(LPCWSTR pszPhoneBook, LPCWSTR pszEntry, RASDIALPARAMS *pRasDialParams, HWND hWnd, HRASCONN hRasconn)
  3263. {
  3264. //
  3265. // Validate the input parameters. Note that pszPhoneBook can be NULL but if it is non-NULL then we cannot have
  3266. // an empty string.
  3267. //
  3268. MYDBGASSERT(OS_NT51);
  3269. if (((NULL != pszPhoneBook) && (L'\0' == pszPhoneBook[0])) ||
  3270. (NULL == pszEntry) || (L'\0' == pszEntry[0]) || (NULL == pRasDialParams) ||
  3271. (NULL == hWnd) || (NULL == hRasconn))
  3272. {
  3273. CMASSERTMSG(FALSE, TEXT("InvokeTerminalWindow - Invalid parameter passed."));
  3274. return ERROR_INVALID_PARAMETER;
  3275. }
  3276. DWORD dwReturn;
  3277. typedef DWORD (WINAPI *pfnDwTerminalDlgSpec)(LPCWSTR, LPCWSTR, RASDIALPARAMS *, HWND, HRASCONN);
  3278. //
  3279. // First call loadlibrary on rasdlg.dll
  3280. //
  3281. HMODULE hRasDlg = LoadLibraryExU(TEXT("rasdlg.dll"), NULL, 0);
  3282. if (hRasDlg)
  3283. {
  3284. pfnDwTerminalDlgSpec pfnDwTerminalDlg = (pfnDwTerminalDlgSpec)GetProcAddress(hRasDlg, "DwTerminalDlg");
  3285. if (pfnDwTerminalDlg)
  3286. {
  3287. dwReturn = pfnDwTerminalDlg(pszPhoneBook, pszEntry, pRasDialParams, hWnd, hRasconn);
  3288. }
  3289. else
  3290. {
  3291. dwReturn = ERROR_PROC_NOT_FOUND;
  3292. }
  3293. FreeLibrary(hRasDlg);
  3294. }
  3295. else
  3296. {
  3297. dwReturn = ERROR_MOD_NOT_FOUND;
  3298. }
  3299. return dwReturn;
  3300. }
  3301. //+----------------------------------------------------------------------------
  3302. //
  3303. // Function: OnPauseRasDial
  3304. //
  3305. // Synopsis: Message handler for RasDial pause states. In the pause state, RAS
  3306. // is suspended, waiting for us to restart it by calling RasDial after
  3307. // performing the appropriate interface with the user.
  3308. //
  3309. // Arguments: HWND hwndDlg - Window handle of main dialog
  3310. // ArgsStruct *pArgs - Ptr to global args struct
  3311. // WPARAM wParam - wParam being handled
  3312. // LPARAM lParam - lParam being handled
  3313. //
  3314. // Returns: Windows error message
  3315. //
  3316. // History: nickball Created 05/19/99
  3317. //
  3318. //+----------------------------------------------------------------------------
  3319. DWORD OnPauseRasDial(HWND hwndDlg, ArgsStruct *pArgs, WPARAM wParam, LPARAM lParam)
  3320. {
  3321. CMTRACE2(TEXT("OnPauseRasDial - wParam is %u and lParam is %u."), wParam, lParam);
  3322. MYDBGASSERT(pArgs);
  3323. if (NULL == pArgs)
  3324. {
  3325. return ERROR_INVALID_PARAMETER;
  3326. }
  3327. //
  3328. // Get connection handle and re-dial
  3329. //
  3330. HRASCONN hRasConn;
  3331. DWORD dwRes = ERROR_SUCCESS;
  3332. LPTSTR pszRasPbk = pArgs->pszRasPbk;
  3333. //
  3334. // Determine the appropriate connection handle and phonebook
  3335. // Note: Make an explicit copy or we'll wind up re-dialing
  3336. // if the connection drops while the pause UI is invoked.
  3337. //
  3338. if (IsDialingTunnel(pArgs))
  3339. {
  3340. hRasConn = pArgs->hrcTunnelConn;
  3341. }
  3342. else
  3343. {
  3344. hRasConn = pArgs->hrcRasConn;
  3345. if (pArgs->pszRasHiddenPbk)
  3346. {
  3347. pszRasPbk = pArgs->pszRasHiddenPbk;
  3348. }
  3349. }
  3350. //
  3351. // Handle the pause
  3352. //
  3353. switch (wParam)
  3354. {
  3355. case (RASCS_PAUSED + 4): // 4100 - RASCS_InvokeEapUI )
  3356. //
  3357. // If UNATTENDED, just bail out immediately.
  3358. //
  3359. if (pArgs->dwFlags & FL_UNATTENDED)
  3360. {
  3361. dwRes = ERROR_INTERACTIVE_MODE;
  3362. goto OnPauseRasDialExit;
  3363. }
  3364. //
  3365. // If EAP triggered the pause, invoke the EAP UI
  3366. //
  3367. dwRes = pArgs->rlsRasLink.pfnInvokeEapUI(hRasConn, pArgs->dwRasSubEntry, pArgs->pRasDialExtensions, hwndDlg);
  3368. CMTRACE1(TEXT("OnPauseRasDial() - InvokeEapUI() returns %u."), dwRes);
  3369. break;
  3370. case RASCS_PasswordExpired: // Domain password has expired
  3371. {
  3372. //
  3373. // If UNATTENDED, just bail out immediately.
  3374. //
  3375. if (pArgs->dwFlags & FL_UNATTENDED)
  3376. {
  3377. dwRes = ERROR_INTERACTIVE_MODE;
  3378. goto OnPauseRasDialExit;
  3379. }
  3380. CChangePasswordDlg NewPasswordDlg(pArgs);
  3381. if (IDOK != NewPasswordDlg.DoDialogBox(g_hInst, IDD_CHANGEPASSWORD, pArgs->hwndMainDlg))
  3382. {
  3383. if (pArgs->dwExitCode)
  3384. {
  3385. dwRes = pArgs->dwExitCode;
  3386. }
  3387. else
  3388. {
  3389. dwRes = ERROR_CANCELLED;
  3390. }
  3391. }
  3392. CMTRACE1(TEXT("OnPauseRasDial() - Password Expired"), dwRes);
  3393. break;
  3394. }
  3395. case RASCS_CallbackSetByCaller: // Server wants to call us back
  3396. {
  3397. //
  3398. // Preset dial params and call dialog to retrieve number from user
  3399. //
  3400. LPTSTR pszTmp = pArgs->piniProfile->GPPS(c_pszCmSection, c_pszCmEntryCallbackNumber);
  3401. lstrcpyU(pArgs->pRasDialParams->szCallbackNumber, pszTmp);
  3402. CmFree(pszTmp);
  3403. //
  3404. // If we're running unattended, skip the dialog phase. The
  3405. // presumption is that there is no user there to receive it.
  3406. //
  3407. BOOL bPromptUser = !(pArgs->dwFlags & FL_UNATTENDED);
  3408. if (bPromptUser)
  3409. {
  3410. //
  3411. // The above also applies in the case of DialAutomatically
  3412. // if we have a phone number, then there is no need to prompt.
  3413. //
  3414. if (pArgs->fDialAutomatically && TEXT('\0') != pArgs->pRasDialParams->szCallbackNumber[0])
  3415. {
  3416. bPromptUser = FALSE;
  3417. }
  3418. }
  3419. if (bPromptUser)
  3420. {
  3421. CCallbackNumberDlg CallbackNumberDialog(pArgs);
  3422. if (IDOK != CallbackNumberDialog.DoDialogBox(g_hInst, IDD_CALLBACK_NUMBER, pArgs->hwndMainDlg))
  3423. {
  3424. //
  3425. // If the user canceled, clear the number so that RAS wont attempt callback
  3426. //
  3427. lstrcpyU(pArgs->pRasDialParams->szCallbackNumber, TEXT(""));
  3428. }
  3429. }
  3430. dwRes = ERROR_SUCCESS;
  3431. CMTRACE1(TEXT("OnPauseRasDial() - CallbackSetByCaller returns %u"), dwRes);
  3432. break;
  3433. }
  3434. case RASCS_RetryAuthentication: // Credentials aren't correct
  3435. {
  3436. //
  3437. // If UNATTENDED, just bail out immediately.
  3438. //
  3439. if (pArgs->dwFlags & FL_UNATTENDED)
  3440. {
  3441. dwRes = ERROR_INTERACTIVE_MODE;
  3442. goto OnPauseRasDialExit;
  3443. }
  3444. //
  3445. // Creds didn't work, prompt user for new ones.
  3446. //
  3447. CRetryAuthenticationDlg RetryAuthenticationDialog(pArgs);
  3448. if (IDOK != RetryAuthenticationDialog.DoDialogBox(g_hInst,
  3449. RetryAuthenticationDialog.GetDlgTemplate(),
  3450. pArgs->hwndMainDlg))
  3451. {
  3452. //
  3453. // User canceled, or the call was dropped elsewhere. Use
  3454. // existing error code or designate authentication failure.
  3455. //
  3456. if (pArgs->dwExitCode)
  3457. {
  3458. dwRes = pArgs->dwExitCode;
  3459. }
  3460. else
  3461. {
  3462. dwRes = ERROR_AUTHENTICATION_FAILURE;
  3463. }
  3464. }
  3465. CMTRACE1(TEXT("OnPauseRasDial() - RetryAuthentication"), dwRes);
  3466. break;
  3467. }
  3468. case RASCS_Interactive: // Terminal/script pause state
  3469. if (OS_NT51)
  3470. {
  3471. if (pArgs->dwFlags & FL_UNATTENDED)
  3472. {
  3473. dwRes = ERROR_INTERACTIVE_MODE;
  3474. goto OnPauseRasDialExit;
  3475. }
  3476. dwRes = InvokeTerminalWindow(pszRasPbk, pArgs->szServiceName, pArgs->pRasDialParams, pArgs->hwndMainDlg, hRasConn);
  3477. break;
  3478. } // else fail through to default and error out.
  3479. //
  3480. // We got a pause state that we don't handle, error out.
  3481. //
  3482. default:
  3483. dwRes = ERROR_INTERACTIVE_MODE;
  3484. CMASSERTMSG(FALSE, TEXT("OnPauseRasDial() - Error, unsupported RAS pause state encountered."));
  3485. break;
  3486. }
  3487. //
  3488. // On success, call RasDial to resume connection
  3489. //
  3490. if (ERROR_SUCCESS == dwRes)
  3491. {
  3492. //
  3493. // Decode active password, re-call RasDial, then re-encode
  3494. //
  3495. CmDecodePassword(pArgs->pRasDialParams->szPassword);
  3496. CMASSERTMSG((NOT_IN_CONNECT_OR_CANCEL == pArgs->lInConnectOrCancel),
  3497. TEXT("OnPauseRasDial - RasDial mutex is NOT NULL..."));
  3498. dwRes = pArgs->rlsRasLink.pfnDial(pArgs->pRasDialExtensions,
  3499. pszRasPbk,
  3500. pArgs->pRasDialParams,
  3501. GetRasCallBackType(),
  3502. GetRasCallBack(pArgs),
  3503. &hRasConn);
  3504. CmEncodePassword(pArgs->pRasDialParams->szPassword);
  3505. CMTRACE1(TEXT("OnPauseRasDial() - RasDial() returns %u."), dwRes);
  3506. //
  3507. // Reset timers, the current action starts now.
  3508. //
  3509. pArgs->dwStateStartTime = GetTickCount();
  3510. pArgs->nLastSecondsDisplay = (UINT) -1;
  3511. }
  3512. OnPauseRasDialExit:
  3513. if (ERROR_SUCCESS != dwRes)
  3514. {
  3515. OnRasErrorMessage(hwndDlg, pArgs, dwRes);
  3516. }
  3517. return dwRes;
  3518. }
  3519. //+----------------------------------------------------------------------------
  3520. //
  3521. // Function: GetRasCallBackType
  3522. //
  3523. // Synopsis: Simple function to return the Callback type that we use for RasDial
  3524. // depending upon the OS.
  3525. //
  3526. // Arguments: None
  3527. //
  3528. // Returns: DWORD - The callback type
  3529. //
  3530. // History: nickball Created 05/22/99
  3531. //
  3532. //+----------------------------------------------------------------------------
  3533. DWORD GetRasCallBackType()
  3534. {
  3535. if (OS_NT5)
  3536. {
  3537. return 2;
  3538. }
  3539. else
  3540. {
  3541. return -1;
  3542. }
  3543. }
  3544. //+----------------------------------------------------------------------------
  3545. //
  3546. // Function: GetRasCallBack
  3547. //
  3548. // Synopsis: Simple function to return the Callback that we use for RasDial
  3549. // depending upon the OS.
  3550. //
  3551. // Arguments: ArgsStruct *pArgs - Ptr to global args struct
  3552. //
  3553. // Returns: LPVOID - The callback
  3554. //
  3555. // History: nickball Created 05/22/99
  3556. //
  3557. //+----------------------------------------------------------------------------
  3558. LPVOID GetRasCallBack(ArgsStruct* pArgs)
  3559. {
  3560. MYDBGASSERT(pArgs);
  3561. if (NULL == pArgs)
  3562. {
  3563. return NULL;
  3564. }
  3565. //
  3566. // Now set return the callback func or hwnd according to OS.
  3567. //
  3568. if (OS_NT5)
  3569. {
  3570. //
  3571. // Set Callback data in RasDialParams
  3572. //
  3573. if (pArgs->pRasDialParams->dwSize == sizeof(RASDIALPARAMS_V401))
  3574. {
  3575. ((LPRASDIALPARAMS_V401)pArgs->pRasDialParams)->dwCallbackId = (ULONG_PTR) pArgs;
  3576. }
  3577. return (LPVOID) RasDialFunc2;
  3578. }
  3579. else
  3580. {
  3581. MYDBGASSERT(pArgs->hwndMainDlg);
  3582. return (LPVOID) pArgs->hwndMainDlg;
  3583. }
  3584. }
  3585. //+----------------------------------------------------------------------------
  3586. //
  3587. // Function: AllocateSecurityDescriptorAllowAccessToWorld
  3588. //
  3589. // Synopsis: This function allocates a security descriptor for all users.
  3590. // This function was taken directly from RAS when they create their
  3591. // phonebook. This has to be before GetPhoneBookPath otherwise it
  3592. // causes compile errors in other components since we don't have a
  3593. // function prototype anywhere and cmcfg just includes this (getpbk.cpp)
  3594. // file. This function is also in common\source\getpbk.cpp
  3595. //
  3596. // Arguments: PSECURITY_DESCRIPTOR *ppSd - Pointer to a pointer to the SD struct
  3597. //
  3598. // Returns: DWORD - returns ERROR_SUCCESS if successfull
  3599. //
  3600. // History: 06/27/2001 tomkel Taken from RAS ui\common\pbk\file.c
  3601. //
  3602. //+----------------------------------------------------------------------------
  3603. #define SIZE_ALIGNED_FOR_TYPE(_size, _type) \
  3604. (((_size) + sizeof(_type)-1) & ~(sizeof(_type)-1))
  3605. DWORD AllocateSecurityDescriptorAllowAccessToWorld(PSECURITY_DESCRIPTOR *ppSd)
  3606. {
  3607. PSECURITY_DESCRIPTOR pSd;
  3608. PSID pSid;
  3609. PACL pDacl;
  3610. DWORD dwErr = ERROR_SUCCESS;
  3611. DWORD dwAlignSdSize;
  3612. DWORD dwAlignDaclSize;
  3613. DWORD dwSidSize;
  3614. PVOID pvBuffer;
  3615. DWORD dwAcls = 0;
  3616. // Here is the buffer we are building.
  3617. //
  3618. // |<- a ->|<- b ->|<- c ->|
  3619. // +-------+--------+------+
  3620. // | p| p| |
  3621. // | SD a| DACL a| SID |
  3622. // | d| d| |
  3623. // +-------+-------+-------+
  3624. // ^ ^ ^
  3625. // | | |
  3626. // | | +--pSid
  3627. // | |
  3628. // | +--pDacl
  3629. // |
  3630. // +--pSd (this is returned via *ppSd)
  3631. //
  3632. // pad is so that pDacl and pSid are aligned properly.
  3633. //
  3634. // a = dwAlignSdSize
  3635. // b = dwAlignDaclSize
  3636. // c = dwSidSize
  3637. //
  3638. if (NULL == ppSd)
  3639. {
  3640. return ERROR_INVALID_PARAMETER;
  3641. }
  3642. // Initialize output parameter.
  3643. //
  3644. *ppSd = NULL;
  3645. // Compute the size of the SID. The SID is the well-known SID for World
  3646. // (S-1-1-0).
  3647. //
  3648. dwSidSize = GetSidLengthRequired(1);
  3649. // Compute the size of the DACL. It has an inherent copy of SID within
  3650. // it so add enough room for it. It also must sized properly so that
  3651. // a pointer to a SID structure can come after it. Hence, we use
  3652. // SIZE_ALIGNED_FOR_TYPE.
  3653. //
  3654. dwAlignDaclSize = SIZE_ALIGNED_FOR_TYPE(
  3655. sizeof(ACCESS_ALLOWED_ACE) + sizeof(ACL) + dwSidSize,
  3656. PSID);
  3657. // Compute the size of the SD. It must be sized propertly so that a
  3658. // pointer to a DACL structure can come after it. Hence, we use
  3659. // SIZE_ALIGNED_FOR_TYPE.
  3660. //
  3661. dwAlignSdSize = SIZE_ALIGNED_FOR_TYPE(
  3662. sizeof(SECURITY_DESCRIPTOR),
  3663. PACL);
  3664. // Allocate the buffer big enough for all.
  3665. //
  3666. dwErr = ERROR_OUTOFMEMORY;
  3667. pvBuffer = CmMalloc(dwSidSize + dwAlignDaclSize + dwAlignSdSize);
  3668. if (pvBuffer)
  3669. {
  3670. SID_IDENTIFIER_AUTHORITY SidIdentifierWorldAuth
  3671. = SECURITY_WORLD_SID_AUTHORITY;
  3672. PULONG pSubAuthority;
  3673. dwErr = NOERROR;
  3674. // Setup the pointers into the buffer.
  3675. //
  3676. pSd = pvBuffer;
  3677. pDacl = (PACL)((PBYTE)pvBuffer + dwAlignSdSize);
  3678. pSid = (PSID)((PBYTE)pDacl + dwAlignDaclSize);
  3679. // Initialize pSid as S-1-1-0.
  3680. //
  3681. if (!InitializeSid(
  3682. pSid,
  3683. &SidIdentifierWorldAuth,
  3684. 1)) // 1 sub-authority
  3685. {
  3686. dwErr = GetLastError();
  3687. goto finish;
  3688. }
  3689. pSubAuthority = GetSidSubAuthority(pSid, 0);
  3690. *pSubAuthority = SECURITY_WORLD_RID;
  3691. // Initialize pDacl.
  3692. //
  3693. if (!InitializeAcl(
  3694. pDacl,
  3695. dwAlignDaclSize,
  3696. ACL_REVISION))
  3697. {
  3698. dwErr = GetLastError();
  3699. goto finish;
  3700. }
  3701. dwAcls = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
  3702. dwAcls &= ~(WRITE_DAC | WRITE_OWNER);
  3703. if(!AddAccessAllowedAce(
  3704. pDacl,
  3705. ACL_REVISION,
  3706. dwAcls,
  3707. pSid))
  3708. {
  3709. dwErr = GetLastError();
  3710. goto finish;
  3711. }
  3712. // Initialize pSd.
  3713. //
  3714. if (!InitializeSecurityDescriptor(
  3715. pSd,
  3716. SECURITY_DESCRIPTOR_REVISION))
  3717. {
  3718. dwErr = GetLastError();
  3719. goto finish;
  3720. }
  3721. // Set pSd to use pDacl.
  3722. //
  3723. if (!SetSecurityDescriptorDacl(
  3724. pSd,
  3725. TRUE,
  3726. pDacl,
  3727. FALSE))
  3728. {
  3729. dwErr = GetLastError();
  3730. goto finish;
  3731. }
  3732. // Set the owner for pSd.
  3733. //
  3734. if (!SetSecurityDescriptorOwner(
  3735. pSd,
  3736. NULL,
  3737. TRUE))
  3738. {
  3739. dwErr = GetLastError();
  3740. goto finish;
  3741. }
  3742. // Set the group for pSd.
  3743. //
  3744. if (!SetSecurityDescriptorGroup(
  3745. pSd,
  3746. NULL,
  3747. FALSE))
  3748. {
  3749. dwErr = GetLastError();
  3750. goto finish;
  3751. }
  3752. finish:
  3753. if (!dwErr)
  3754. {
  3755. *ppSd = pSd;
  3756. }
  3757. else
  3758. {
  3759. CmFree(pvBuffer);
  3760. }
  3761. }
  3762. return dwErr;
  3763. }