Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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