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.

904 lines
29 KiB

  1. /*-----------------------------------------------------------------------------
  2. rnaapi.cpp
  3. Wrapper to softlink to RNAPH and RASAPI32.DLL
  4. Copyright (C) 1996 Microsoft Corporation
  5. All rights reserved.
  6. Authors:
  7. ChrisK ChrisKauffman
  8. History:
  9. 1/29/96 ChrisK Created
  10. 7/22/96 ChrisK Cleaned and formatted
  11. -----------------------------------------------------------------------------*/
  12. #include "pch.hpp"
  13. static const TCHAR cszRASAPI32_DLL[] = TEXT("RASAPI32.DLL");
  14. static const TCHAR cszRNAPH_DLL[] = TEXT("RNAPH.DLL");
  15. static const TCHAR cszRAS16[] = TEXT("RASC16IE.DLL");
  16. #ifdef UNICODE
  17. static const CHAR cszRasEnumDevices[] = "RasEnumDevicesW";
  18. static const CHAR cszRasValidateEntryNamePlain[] = "RasValidateEntryName";
  19. static const CHAR cszRasValidateEntryName[] = "RasValidateEntryNameW";
  20. static const CHAR cszRasSetEntryProperties[] = "RasSetEntryPropertiesW";
  21. static const CHAR cszRasGetEntryProperties[] = "RasGetEntryPropertiesW";
  22. static const CHAR cszRasDeleteEntry[] = "RasDeleteEntryW";
  23. static const CHAR cszRasHangUp[] = "RasHangUpW";
  24. static const CHAR cszRasGetConnectStatus[] = "RasGetConnectStatusW";
  25. static const CHAR cszRasDial[] = "RasDialW";
  26. static const CHAR cszRasEnumConnections[] = "RasEnumConnectionsW";
  27. static const CHAR cszRasGetEntryDialParams[] = "RasGetEntryDialParamsW";
  28. static const CHAR cszRasGetCountryInfo[] = "RasGetCountryInfoW";
  29. #else // UNICODE
  30. static const CHAR cszRasEnumDevices[] = "RasEnumDevicesA";
  31. static const CHAR cszRasValidateEntryNamePlain[] = "RasValidateEntryName";
  32. static const CHAR cszRasValidateEntryName[] = "RasValidateEntryNameA";
  33. static const CHAR cszRasSetEntryProperties[] = "RasSetEntryPropertiesA";
  34. static const CHAR cszRasGetEntryProperties[] = "RasGetEntryPropertiesA";
  35. static const CHAR cszRasDeleteEntry[] = "RasDeleteEntryA";
  36. static const CHAR cszRasHangUp[] = "RasHangUpA";
  37. static const CHAR cszRasGetConnectStatus[] = "RasGetConnectStatusA";
  38. static const CHAR cszRasDial[] = "RasDialA";
  39. static const CHAR cszRasEnumConnections[] = "RasEnumConnectionsA";
  40. static const CHAR cszRasGetEntryDialParams[] = "RasGetEntryDialParamsA";
  41. static const CHAR cszRasGetCountryInfo[] = "RasGetCountryInfoA";
  42. #endif // UNICODE
  43. // on NT we have to call RasGetEntryProperties with a larger buffer than RASENTRY.
  44. // This is a bug in WinNT4.0 RAS, that didn't get fixed.
  45. //
  46. #define RASENTRY_SIZE_PATCH (7 * sizeof(DWORD))
  47. //+----------------------------------------------------------------------------
  48. //
  49. // Function: RNAAPI::RNAAPI
  50. //
  51. // Synopsis: Initialize class members and load DLLs
  52. //
  53. // Arguments: None
  54. //
  55. // Returns: None
  56. //
  57. // History: ChrisK Created 1/15/96
  58. //
  59. //-----------------------------------------------------------------------------
  60. RNAAPI::RNAAPI()
  61. {
  62. #if defined(WIN16)
  63. m_hInst = LoadLibrary(cszRAS16);
  64. m_hInst2 = NULL;
  65. #else
  66. m_hInst = LoadLibrary(cszRASAPI32_DLL);
  67. if (FALSE == IsNT ())
  68. {
  69. //
  70. // we only load RNAPH.DLL if it is not NT
  71. // MKarki (5/4/97) - Fix for Bug #3378
  72. //
  73. m_hInst2 = LoadLibrary(cszRNAPH_DLL);
  74. }
  75. else
  76. {
  77. m_hInst2 = NULL;
  78. }
  79. #endif
  80. m_fnRasEnumDeviecs = NULL;
  81. m_fnRasValidateEntryName = NULL;
  82. m_fnRasSetEntryProperties = NULL;
  83. m_fnRasGetEntryProperties = NULL;
  84. m_fnRasDeleteEntry = NULL;
  85. m_fnRasHangUp = NULL;
  86. m_fnRasGetConnectStatus = NULL;
  87. m_fnRasEnumConnections = NULL;
  88. m_fnRasDial = NULL;
  89. m_fnRasGetEntryDialParams = NULL;
  90. m_fnRasGetCountryInfo = NULL;
  91. }
  92. //+----------------------------------------------------------------------------
  93. //
  94. // Function: RNAAPI::~RNAAPI
  95. //
  96. // Synopsis: release DLLs
  97. //
  98. // Arguments: None
  99. //
  100. // Returns: None
  101. //
  102. // History: ChrisK Created 1/15/96
  103. //
  104. //-----------------------------------------------------------------------------
  105. RNAAPI::~RNAAPI()
  106. {
  107. //
  108. // Clean up
  109. //
  110. if (m_hInst) FreeLibrary(m_hInst);
  111. if (m_hInst2) FreeLibrary(m_hInst2);
  112. }
  113. //+----------------------------------------------------------------------------
  114. //
  115. // Function: RNAAPI::RasEnumDevices
  116. //
  117. // Synopsis: Softlink to RAS function
  118. //
  119. // Arguments: see RAS documentation
  120. //
  121. // Returns: see RAS documentation
  122. //
  123. // History: ChrisK Created 1/15/96
  124. //
  125. //-----------------------------------------------------------------------------
  126. DWORD RNAAPI::RasEnumDevices(LPRASDEVINFO lpRasDevInfo, LPDWORD lpcb,
  127. LPDWORD lpcDevices)
  128. {
  129. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  130. // Look for the API if we haven't already found it
  131. LoadApi(cszRasEnumDevices,(FARPROC*)&m_fnRasEnumDeviecs);
  132. if (m_fnRasEnumDeviecs)
  133. dwRet = (*m_fnRasEnumDeviecs) (lpRasDevInfo, lpcb, lpcDevices);
  134. return dwRet;
  135. }
  136. //+----------------------------------------------------------------------------
  137. //
  138. // Function: RNAAPI::LoadApi
  139. //
  140. // Synopsis: If the given function pointer is NULL, then try to load the API
  141. // from the first DLL, if that fails, try to load from the second
  142. // DLL
  143. //
  144. // Arguments: pszFName - the name of the exported function
  145. // pfnProc - point to where the proc address will be returned
  146. //
  147. // Returns: TRUE - success
  148. //
  149. // History: ChrisK Created 1/15/96
  150. //
  151. //-----------------------------------------------------------------------------
  152. BOOL RNAAPI::LoadApi(LPCSTR pszFName, FARPROC* pfnProc)
  153. {
  154. if (*pfnProc == NULL)
  155. {
  156. // Look for the entry point in the first DLL
  157. if (m_hInst)
  158. *pfnProc = GetProcAddress(m_hInst,pszFName);
  159. // if that fails, look for the entry point in the second DLL
  160. if (m_hInst2 && !(*pfnProc))
  161. *pfnProc = GetProcAddress(m_hInst2,pszFName);
  162. }
  163. return (pfnProc != NULL);
  164. }
  165. //+----------------------------------------------------------------------------
  166. //
  167. // Function: RNAAPI::RasGetConnectStatus
  168. //
  169. // Synopsis: Softlink to RAS function
  170. //
  171. // Arguments: see RAS documentation
  172. //
  173. // Returns: see RAS documentation
  174. //
  175. // History: ChrisK Created 7/16/96
  176. //
  177. //-----------------------------------------------------------------------------
  178. DWORD RNAAPI::RasGetConnectStatus(HRASCONN hrasconn,LPRASCONNSTATUS lprasconnstatus)
  179. {
  180. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  181. // Look for the API if we haven't already found it
  182. LoadApi(cszRasGetConnectStatus,(FARPROC*)&m_fnRasGetConnectStatus);
  183. if (m_fnRasGetConnectStatus)
  184. dwRet = (*m_fnRasGetConnectStatus) (hrasconn,lprasconnstatus);
  185. #if defined(WIN16) && defined(DEBUG)
  186. TraceMsg(TF_GENERAL, ("RasGetConnectStatus returned %lu\r\n", dwRet);
  187. #endif
  188. return dwRet;
  189. }
  190. //+----------------------------------------------------------------------------
  191. //
  192. // Function: RNAAPI::RasValidateEntryName
  193. //
  194. // Synopsis: Softlink to RAS function
  195. //
  196. // Arguments: see RAS documentation
  197. //
  198. // Returns: see RAS documentation
  199. //
  200. // History: ChrisK Created 1/15/96
  201. //
  202. //-----------------------------------------------------------------------------
  203. DWORD RNAAPI::RasValidateEntryName(LPTSTR lpszPhonebook,LPTSTR lpszEntry)
  204. {
  205. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  206. // Look for the API if we haven't already found it
  207. LoadApi(cszRasValidateEntryNamePlain,(FARPROC*)&m_fnRasValidateEntryName);
  208. LoadApi(cszRasValidateEntryName,(FARPROC*)&m_fnRasValidateEntryName);
  209. if (m_fnRasValidateEntryName)
  210. dwRet = (*m_fnRasValidateEntryName) (lpszPhonebook, lpszEntry);
  211. return dwRet;
  212. }
  213. //+----------------------------------------------------------------------------
  214. //
  215. // Function: RNAAPI::RasSetEntryProperties
  216. //
  217. // Synopsis: Softlink to RAS function
  218. //
  219. // Arguments: see RAS documentation
  220. //
  221. // Returns: see RAS documentation
  222. //
  223. // History: ChrisK Created 1/15/96
  224. //
  225. //-----------------------------------------------------------------------------
  226. DWORD RNAAPI::RasSetEntryProperties(LPTSTR lpszPhonebook, LPTSTR lpszEntry,
  227. LPBYTE lpbEntryInfo, DWORD dwEntryInfoSize,
  228. LPBYTE lpbDeviceInfo, DWORD dwDeviceInfoSize)
  229. {
  230. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  231. // Look for the API if we haven't already found it
  232. LoadApi(cszRasSetEntryProperties,(FARPROC*)&m_fnRasSetEntryProperties);
  233. #if !defined(WIN16)
  234. #define RASGETCOUNTRYINFO_BUFFER_SIZE 256
  235. if (0 == ((LPRASENTRY)lpbEntryInfo)->dwCountryCode)
  236. {
  237. if( !( ((LPRASENTRY)lpbEntryInfo)->dwfOptions & RASEO_UseCountryAndAreaCodes) )
  238. {
  239. // jmazner 10/10/96
  240. // if this is a dial as is number, then RasGetEntryProperties will not have
  241. // filled in the fields below. This makes sense.
  242. // However, RasSetEntryProperties fails to ignore these fileds for a dial-as-is number,
  243. // the hack below in the else clause takes care of an empty countryCode, but
  244. // if the CountryID is missing too, it doesn't work.
  245. // So deal with such a case here, filling in the fields that RasSetEntry will validate.
  246. ((LPRASENTRY)lpbEntryInfo)->dwCountryID = 1;
  247. ((LPRASENTRY)lpbEntryInfo)->dwCountryCode = 1;
  248. ((LPRASENTRY)lpbEntryInfo)->szAreaCode[0] = '8';
  249. ((LPRASENTRY)lpbEntryInfo)->szAreaCode[1] = '\0';
  250. }
  251. else
  252. {
  253. BYTE rasCI[RASGETCOUNTRYINFO_BUFFER_SIZE];
  254. LPRASCTRYINFO prasCI;
  255. DWORD dwSize;
  256. DWORD dw;
  257. prasCI = (LPRASCTRYINFO)rasCI;
  258. ZeroMemory(prasCI,sizeof(rasCI));
  259. prasCI->dwSize = sizeof(RASCTRYINFO);
  260. dwSize = sizeof(rasCI);
  261. Assert(((LPRASENTRY)lpbEntryInfo)->dwCountryID);
  262. prasCI->dwCountryID = ((LPRASENTRY)lpbEntryInfo)->dwCountryID;
  263. dw = RNAAPI::RasGetCountryInfo(prasCI,&dwSize);
  264. if (ERROR_SUCCESS == dw)
  265. {
  266. Assert(prasCI->dwCountryCode);
  267. ((LPRASENTRY)lpbEntryInfo)->dwCountryCode = prasCI->dwCountryCode;
  268. }
  269. else
  270. {
  271. AssertMsg(0,"Unexpected error from RasGetCountryInfo.\r\n");
  272. }
  273. }
  274. }
  275. #endif
  276. if (m_fnRasSetEntryProperties)
  277. dwRet = (*m_fnRasSetEntryProperties) (lpszPhonebook, lpszEntry,
  278. lpbEntryInfo, dwEntryInfoSize,
  279. lpbDeviceInfo, dwDeviceInfoSize);
  280. #if !defined(WIN16)
  281. RasSetEntryPropertiesScriptPatch(((RASENTRY*)&(*lpbEntryInfo))->szScript, lpszEntry);
  282. #endif
  283. return dwRet;
  284. }
  285. //+----------------------------------------------------------------------------
  286. //
  287. // Function: RNAAPI::RasGetEntryProperties
  288. //
  289. // Synopsis: Softlink to RAS function
  290. //
  291. // Arguments: see RAS documentation
  292. //
  293. // Returns: see RAS documentation
  294. //
  295. // History: ChrisK Created 1/15/96
  296. // jmazner 9/16/96 Added bUsePatch variable to allow calls with buffers = NULL and InfoSizes = 0.
  297. // See RasGetEntryProperties docs to learn why this is needed.
  298. //
  299. //-----------------------------------------------------------------------------
  300. DWORD RNAAPI::RasGetEntryProperties(LPTSTR lpszPhonebook, LPTSTR lpszEntry,
  301. LPBYTE lpbEntryInfo, LPDWORD lpdwEntryInfoSize,
  302. LPBYTE lpbDeviceInfo, LPDWORD lpdwDeviceInfoSize)
  303. {
  304. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  305. LPBYTE lpbEntryInfoPatch = NULL;
  306. LPDWORD lpdwEntryInfoPatchSize = NULL;
  307. BOOL bUsePatch = TRUE;
  308. #if defined(WIN16)
  309. bUsePatch = FALSE;
  310. #endif
  311. if( (NULL == lpbEntryInfo) && (NULL == lpbDeviceInfo) )
  312. {
  313. Assert( NULL != lpdwEntryInfoSize );
  314. Assert( NULL != lpdwDeviceInfoSize );
  315. Assert( 0 == *lpdwEntryInfoSize );
  316. Assert( 0 == *lpdwDeviceInfoSize );
  317. // we're here to ask RAS what size these buffers need to be, don't use the patch stuff
  318. // (see RasGetEntryProperties docs)
  319. bUsePatch = FALSE;
  320. }
  321. if( bUsePatch )
  322. {
  323. Assert(lpbEntryInfo && lpdwEntryInfoSize);
  324. Assert( (*lpdwEntryInfoSize) >= sizeof(RASENTRY) );
  325. //
  326. // We are going to fake out RasGetEntryProperties by creating a slightly larger
  327. // temporary buffer and copying the data in and out.
  328. //
  329. lpdwEntryInfoPatchSize = (LPDWORD) GlobalAlloc(GPTR, sizeof(DWORD));
  330. if (NULL == lpdwEntryInfoPatchSize)
  331. return ERROR_NOT_ENOUGH_MEMORY;
  332. *lpdwEntryInfoPatchSize = (*lpdwEntryInfoSize) + RASENTRY_SIZE_PATCH;
  333. lpbEntryInfoPatch = (LPBYTE)GlobalAlloc(GPTR,*lpdwEntryInfoPatchSize);
  334. if (NULL == lpbEntryInfoPatch)
  335. return ERROR_NOT_ENOUGH_MEMORY;
  336. // RAS expects the dwSize field to contain the size of the LPRASENTRY struct
  337. // (used to check which version of the struct we're using) rather than the amount
  338. // of memory actually allocated to the pointer.
  339. //((LPRASENTRY)lpbEntryInfoPatch)->dwSize = *lpdwEntryInfoPatchSize;
  340. ((LPRASENTRY)lpbEntryInfoPatch)->dwSize = sizeof(RASENTRY);
  341. }
  342. else
  343. {
  344. lpbEntryInfoPatch = lpbEntryInfo;
  345. lpdwEntryInfoPatchSize = lpdwEntryInfoSize;
  346. }
  347. // Look for the API if we haven't already found it
  348. LoadApi(cszRasGetEntryProperties,(FARPROC*)&m_fnRasGetEntryProperties);
  349. if (m_fnRasGetEntryProperties)
  350. dwRet = (*m_fnRasGetEntryProperties) (lpszPhonebook, lpszEntry,
  351. lpbEntryInfoPatch, lpdwEntryInfoPatchSize,
  352. lpbDeviceInfo, lpdwDeviceInfoSize);
  353. TraceMsg(TF_GENERAL, "ICWDIAL: RasGetEntryProperties returned %lu\r\n", dwRet);
  354. if( bUsePatch )
  355. {
  356. //
  357. // Copy out the contents of the temporary buffer UP TO the size of the original buffer
  358. //
  359. Assert(lpbEntryInfoPatch);
  360. memcpy(lpbEntryInfo,lpbEntryInfoPatch,*lpdwEntryInfoSize);
  361. GlobalFree(lpbEntryInfoPatch);
  362. lpbEntryInfoPatch = NULL;
  363. }
  364. //
  365. // We are again faking Ras functionality here by over writing the size value;
  366. // This is so that RasSetEntryProperties will not choke...
  367. if( NULL != lpbEntryInfo )
  368. {
  369. *lpdwEntryInfoSize = sizeof(RASENTRY);
  370. }
  371. return dwRet;
  372. }
  373. //+----------------------------------------------------------------------------
  374. //
  375. // Function: RNAAPI::RasDeleteEntry
  376. //
  377. // Synopsis: Softlink to RAS function
  378. //
  379. // Arguments: see RAS documentation
  380. //
  381. // Returns: see RAS documentation
  382. //
  383. // History: ChrisK Created 1/15/96
  384. //
  385. //-----------------------------------------------------------------------------
  386. DWORD RNAAPI::RasDeleteEntry(LPTSTR lpszPhonebook, LPTSTR lpszEntry)
  387. {
  388. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  389. // Look for the API if we haven't already found it
  390. LoadApi(cszRasDeleteEntry,(FARPROC*)&m_fnRasDeleteEntry);
  391. if (m_fnRasDeleteEntry)
  392. dwRet = (*m_fnRasDeleteEntry) (lpszPhonebook, lpszEntry);
  393. return dwRet;
  394. }
  395. //+----------------------------------------------------------------------------
  396. //
  397. // Function: RNAAPI::RasHangUp
  398. //
  399. // Synopsis: Softlink to RAS function
  400. //
  401. // Arguments: see RAS documentation
  402. //
  403. // Returns: see RAS documentation
  404. //
  405. // History: ChrisK Created 1/15/96
  406. //
  407. //-----------------------------------------------------------------------------
  408. DWORD RNAAPI::RasHangUp(HRASCONN hrasconn)
  409. {
  410. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  411. // Look for the API if we haven't already found it
  412. LoadApi(cszRasHangUp,(FARPROC*)&m_fnRasHangUp);
  413. if (m_fnRasHangUp)
  414. {
  415. dwRet = (*m_fnRasHangUp) (hrasconn);
  416. #if !defined(WIN16)
  417. Sleep(3000);
  418. #endif
  419. }
  420. return dwRet;
  421. }
  422. // ############################################################################
  423. DWORD RNAAPI::RasDial(LPRASDIALEXTENSIONS lpRasDialExtensions,LPTSTR lpszPhonebook,
  424. LPRASDIALPARAMS lpRasDialParams, DWORD dwNotifierType,
  425. LPVOID lpvNotifier, LPHRASCONN lphRasConn)
  426. {
  427. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  428. // Look for the API if we haven't already found it
  429. LoadApi(cszRasDial,(FARPROC*)&m_fnRasDial);
  430. if (m_fnRasDial)
  431. {
  432. dwRet = (*m_fnRasDial) (lpRasDialExtensions,lpszPhonebook,lpRasDialParams,
  433. dwNotifierType,lpvNotifier,lphRasConn);
  434. }
  435. return dwRet;
  436. }
  437. // ############################################################################
  438. DWORD RNAAPI::RasEnumConnections(LPRASCONN lprasconn,LPDWORD lpcb,LPDWORD lpcConnections)
  439. {
  440. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  441. // Look for the API if we haven't already found it
  442. LoadApi(cszRasEnumConnections,(FARPROC*)&m_fnRasEnumConnections);
  443. if (m_fnRasEnumConnections)
  444. {
  445. dwRet = (*m_fnRasEnumConnections) (lprasconn,lpcb,lpcConnections);
  446. }
  447. return dwRet;
  448. }
  449. // ############################################################################
  450. DWORD RNAAPI::RasGetEntryDialParams(LPTSTR lpszPhonebook,LPRASDIALPARAMS lprasdialparams,
  451. LPBOOL lpfPassword)
  452. {
  453. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  454. // Look for the API if we haven't already found it
  455. LoadApi(cszRasGetEntryDialParams,(FARPROC*)&m_fnRasGetEntryDialParams);
  456. if (m_fnRasGetEntryDialParams)
  457. {
  458. dwRet = (*m_fnRasGetEntryDialParams) (lpszPhonebook,lprasdialparams,lpfPassword);
  459. }
  460. return dwRet;
  461. }
  462. //+----------------------------------------------------------------------------
  463. //
  464. // Function: RNAAPI::RasGetCountryInfo
  465. //
  466. // Synopsis: Softlink to RAS function
  467. //
  468. // Arguments: see RAS documentation
  469. //
  470. // Returns: see RAS documentation
  471. //
  472. // History: ChrisK Created 8/16/96
  473. //
  474. //-----------------------------------------------------------------------------
  475. DWORD RNAAPI::RasGetCountryInfo(LPRASCTRYINFO lprci, LPDWORD lpdwSize)
  476. {
  477. DWORD dwRet = ERROR_DLL_NOT_FOUND;
  478. // Look for the API if we haven't already found it
  479. LoadApi(cszRasGetCountryInfo,(FARPROC*)&m_fnRasGetCountryInfo);
  480. if (m_fnRasGetCountryInfo)
  481. {
  482. dwRet = (*m_fnRasGetCountryInfo) (lprci,lpdwSize);
  483. }
  484. return dwRet;
  485. }
  486. #if !defined(WIN16)
  487. static const TCHAR cszDeviceSwitch[] = TEXT("DEVICE=switch");
  488. static const TCHAR cszRasPBKFilename[] = TEXT("\\ras\\rasphone.pbk");
  489. #define SCRIPT_PATCH_BUFFER_SIZE 2048
  490. #define SIZEOF_NULL 1
  491. static const TCHAR cszType[] = TEXT("Type=");
  492. //+----------------------------------------------------------------------------
  493. //
  494. // Function RemoveOldScriptFilenames
  495. //
  496. // Synopsis Given the data returned from a call to GetPrivateProfileSection
  497. // remove any information about existing script file so that
  498. // we can replace it with the new script information.
  499. //
  500. // Arguments lpszData - pointer to input data
  501. //
  502. // Returns TRUE - success
  503. // lpdwSize - size of resulting data
  504. //
  505. // History 10/2/96 ChrisK Created
  506. //
  507. //-----------------------------------------------------------------------------
  508. static BOOL RemoveOldScriptFilenames(LPTSTR lpszData, LPDWORD lpdwSize)
  509. {
  510. BOOL bRC = FALSE;
  511. LPTSTR lpszTemp = lpszData;
  512. LPTSTR lpszCopyTo = lpszData;
  513. INT iLen = 0;
  514. //
  515. // Walk through list of name value pairs
  516. //
  517. if (!lpszData || '\0' == lpszData[0])
  518. goto RemoveOldScriptFilenamesExit;
  519. while (*lpszTemp) {
  520. if (0 != lstrcmpi(lpszTemp,cszDeviceSwitch))
  521. {
  522. //
  523. // Keep pairs that don't match criteria
  524. //
  525. iLen = lstrlen(lpszTemp);
  526. if (lpszCopyTo != lpszTemp)
  527. {
  528. memmove(lpszCopyTo, lpszTemp, iLen+1);
  529. }
  530. lpszCopyTo += iLen + 1;
  531. lpszTemp += iLen + 1;
  532. }
  533. else
  534. {
  535. //
  536. // Skip the pair that matches and the one after that
  537. //
  538. lpszTemp += lstrlen(lpszTemp) + 1;
  539. if (*lpszTemp)
  540. lpszTemp += lstrlen(lpszTemp) + 1;
  541. }
  542. }
  543. //
  544. // Add second trailing NULL
  545. //
  546. *lpszCopyTo = '\0';
  547. //
  548. // Return new size
  549. // Note the size does not include the final \0
  550. //
  551. *lpdwSize = (DWORD)(lpszCopyTo - lpszData);
  552. bRC = TRUE;
  553. RemoveOldScriptFilenamesExit:
  554. return bRC;
  555. }
  556. //+----------------------------------------------------------------------------
  557. //
  558. // Function GleanRealScriptFileName
  559. //
  560. // Synopsis Given a string figure out the real filename
  561. // Due to another NT4.0 Ras bug, script filenames returned by
  562. // RasGetEntryProperties may contain a leading garbage character
  563. //
  564. // Arguments lppszOut - pointer that will point to real filename
  565. // lpszIn - points to current filename
  566. //
  567. // Returns TRUE - success
  568. // *lppszOut - points to real file name, remember to free the memory
  569. // in this variable when you are done. And don't talk with
  570. // your mouth full - mom.
  571. //
  572. // History 10/2/96 ChrisK Created
  573. //
  574. //-----------------------------------------------------------------------------
  575. static BOOL GleanRealScriptFileName(LPTSTR *lppszOut, LPTSTR lpszIn)
  576. {
  577. BOOL bRC = FALSE;
  578. LPTSTR lpsz = NULL;
  579. DWORD dwRet = 0;
  580. //
  581. // Validate parameters
  582. //
  583. Assert(lppszOut && lpszIn);
  584. if (!(lppszOut && lpszIn))
  585. goto GleanFilenameExit;
  586. //
  587. // first determine if the filename is OK as is
  588. //
  589. dwRet = GetFileAttributes(lpszIn);
  590. if ('\0' != lpszIn[0] && 0xFFFFFFFF == dwRet) // Empty filename is OK
  591. {
  592. //
  593. // Check for the same filename without the first character
  594. //
  595. lpsz = lpszIn+1;
  596. dwRet = GetFileAttributes(lpsz);
  597. if (0xFFFFFFFF == dwRet)
  598. goto GleanFilenameExit;
  599. }
  600. else
  601. {
  602. lpsz = lpszIn;
  603. }
  604. //
  605. // Return filename
  606. //
  607. *lppszOut = (LPTSTR)GlobalAlloc(GPTR,sizeof(TCHAR)*(lstrlen(lpsz)+1));
  608. if (!(*lppszOut))
  609. {
  610. goto GleanFilenameExit;
  611. }
  612. lstrcpy(*lppszOut,lpsz);
  613. bRC = TRUE;
  614. GleanFilenameExit:
  615. return bRC;
  616. }
  617. //+----------------------------------------------------------------------------
  618. //
  619. // Function IsScriptPatchNeeded
  620. //
  621. // Synopsis Check version to see if patch is needed
  622. //
  623. // Arguments lpszData - contents of section in rasphone.pbk
  624. // lpszScript - name of script file
  625. //
  626. // Returns TRUE - patch is needed
  627. //
  628. // Histroy 10/1/96
  629. //
  630. //-----------------------------------------------------------------------------
  631. static BOOL IsScriptPatchNeeded(LPTSTR lpszData, LPTSTR lpszScript)
  632. {
  633. BOOL bRC = FALSE;
  634. LPTSTR lpsz = lpszData;
  635. TCHAR szType[MAX_PATH + sizeof(cszType)/sizeof(TCHAR) + 1];
  636. lstrcpy(szType,cszType);
  637. lstrcat(szType,lpszScript);
  638. Assert(MAX_PATH + sizeof(cszType)/sizeof(TCHAR) +1 > lstrlen(szType));
  639. lpsz = lpszData;
  640. while(*lpsz)
  641. {
  642. if (0 == lstrcmp(lpsz,cszDeviceSwitch))
  643. {
  644. lpsz += lstrlen(lpsz)+1;
  645. // if we find a DEVICE=switch statement and the script is empty
  646. // then we'll have to patch the entry
  647. if (0 == lpszScript[0])
  648. bRC = TRUE;
  649. // if we find a DEVICE=switch statement and the script is different
  650. // then we'll have to patch the entry
  651. else if (0 != lstrcmp(lpsz,szType))
  652. bRC = TRUE;
  653. // if we find a DEVICE=switch statement and the script is the same
  654. // then we DON'T have to patch it
  655. else
  656. bRC = FALSE;
  657. break; // get out of while statement
  658. }
  659. lpsz += lstrlen(lpsz)+1;
  660. }
  661. if ('\0' == *lpsz)
  662. {
  663. // if we didn't find DEVICE=switch statement and the script is empty
  664. // then we DON'T have to patch it
  665. if ('\0' == lpszScript[0])
  666. bRC = FALSE;
  667. // if we didn't find DEVICE=switch statement and the script is not
  668. // empty the we'll have to patch it.
  669. else
  670. bRC = TRUE;
  671. }
  672. return bRC;
  673. }
  674. //+----------------------------------------------------------------------------
  675. //
  676. // Function GetRasPBKFilename
  677. //
  678. // Synopsis Find the Ras phone book and return the fully qualified path
  679. // in the buffer
  680. //
  681. // Arguments lpBuffer - pointer to buffer
  682. // dwSize - size of buffer (must be at least MAX_PATH)
  683. //
  684. // Returns TRUE - success
  685. //
  686. // History 10/1/96 ChrisK Created
  687. //
  688. //-----------------------------------------------------------------------------
  689. static BOOL GetRasPBKFilename(LPTSTR lpBuffer, DWORD dwSize)
  690. {
  691. BOOL bRC = FALSE;
  692. UINT urc = 0;
  693. LPTSTR lpsz = NULL;
  694. //
  695. // Validate parameters
  696. //
  697. Assert(lpBuffer && (dwSize >= MAX_PATH));
  698. //
  699. // Get path to system directory
  700. //
  701. urc = GetSystemDirectory(lpBuffer,dwSize);
  702. if (0 == urc || urc > dwSize)
  703. goto GetRasPBKExit;
  704. //
  705. // Check for trailing '\' and add \ras\rasphone.pbk to path
  706. //
  707. lpsz = &lpBuffer[lstrlen(lpBuffer)-1];
  708. if ('\\' != *lpsz)
  709. lpsz++;
  710. lstrcpy(lpsz,cszRasPBKFilename);
  711. bRC = TRUE;
  712. GetRasPBKExit:
  713. return bRC;
  714. }
  715. //+----------------------------------------------------------------------------
  716. //
  717. // Function RasSetEntryPropertiesScriptPatch
  718. //
  719. // Synopsis Work around bug in NT4.0 that does not save script file names
  720. // to RAS phone book entries
  721. //
  722. // Arguments lpszScript - name of script file
  723. // lpszEntry - name of phone book entry
  724. //
  725. // Returns TRUE - success
  726. //
  727. // Histroy 10/1/96 ChrisK Created
  728. //
  729. //-----------------------------------------------------------------------------
  730. BOOL WINAPI RasSetEntryPropertiesScriptPatch(LPTSTR lpszScript, LPTSTR lpszEntry)
  731. {
  732. BOOL bRC = FALSE;
  733. TCHAR szRasPBK[MAX_PATH+1];
  734. TCHAR szData[SCRIPT_PATCH_BUFFER_SIZE];
  735. DWORD dwrc = 0;
  736. LPTSTR lpszTo;
  737. LPTSTR lpszFixedFilename = NULL;
  738. //
  739. // Validate parameters
  740. //
  741. Assert(lpszScript && lpszEntry);
  742. TraceMsg(TF_GENERAL, "ICWDIAL: ScriptPatch script %s, entry %s.\r\n", lpszScript,lpszEntry);
  743. //
  744. // Verify and fix filename
  745. //
  746. if (!GleanRealScriptFileName(&lpszFixedFilename, lpszScript))
  747. goto ScriptPatchExit;
  748. //
  749. // Get the path to the RAS phone book
  750. //
  751. if (!GetRasPBKFilename(szRasPBK,MAX_PATH+1))
  752. goto ScriptPatchExit;
  753. //
  754. // Get data
  755. //
  756. ZeroMemory(szData,SCRIPT_PATCH_BUFFER_SIZE);
  757. dwrc = GetPrivateProfileSection(lpszEntry,szData,SCRIPT_PATCH_BUFFER_SIZE,szRasPBK);
  758. if (SCRIPT_PATCH_BUFFER_SIZE == (dwrc + 2))
  759. goto ScriptPatchExit;
  760. //
  761. // Verify version
  762. //
  763. if (!IsScriptPatchNeeded(szData,lpszFixedFilename))
  764. {
  765. bRC = TRUE;
  766. goto ScriptPatchExit;
  767. }
  768. //
  769. // Clean up data
  770. //
  771. RemoveOldScriptFilenames(szData, &dwrc);
  772. //
  773. // Make sure there is enough space left to add new data
  774. //
  775. if (SCRIPT_PATCH_BUFFER_SIZE <=
  776. (dwrc + sizeof(cszDeviceSwitch)/sizeof(TCHAR) + SIZEOF_NULL + sizeof(cszType)/sizeof(TCHAR) + MAX_PATH))
  777. goto ScriptPatchExit;
  778. //
  779. // Add data
  780. //
  781. if ('\0' != lpszFixedFilename[0])
  782. {
  783. lpszTo = &szData[dwrc];
  784. lstrcpy(lpszTo,cszDeviceSwitch);
  785. lpszTo += sizeof(cszDeviceSwitch)/sizeof(TCHAR);
  786. lstrcpy(lpszTo,cszType);
  787. lpszTo += sizeof(cszType)/sizeof(TCHAR) - 1;
  788. lstrcpy(lpszTo,lpszFixedFilename);
  789. lpszTo += lstrlen(lpszFixedFilename) + SIZEOF_NULL;
  790. *lpszTo = '\0'; // extra terminating NULL
  791. Assert(&lpszTo[SIZEOF_NULL]<&szData[SCRIPT_PATCH_BUFFER_SIZE]);
  792. }
  793. //
  794. // Write data
  795. //
  796. bRC = WritePrivateProfileSection(lpszEntry,szData,szRasPBK);
  797. ScriptPatchExit:
  798. if (lpszFixedFilename)
  799. GlobalFree(lpszFixedFilename);
  800. lpszFixedFilename = NULL;
  801. if (!bRC)
  802. TraceMsg(TF_GENERAL, "ICWDIAL: ScriptPatch failed.\r\n");
  803. return bRC;
  804. }
  805. #endif //!win16