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.

701 lines
20 KiB

  1. //****************************************************************************
  2. //
  3. // Module: ISIGNUP.EXE
  4. // File: client.c
  5. // Content: This file contains all the functions that handle importing
  6. // client information.
  7. // History:
  8. // Sat 10-Mar-1996 23:50:40 -by- Mark MacLin [mmaclin]
  9. //
  10. // Copyright (c) Microsoft Corporation 1991-1996
  11. //
  12. //****************************************************************************
  13. #include "isignup.h"
  14. HRESULT PopulateNTAutodialAddress(LPCTSTR pszFileName, LPCTSTR pszEntryName);
  15. LPTSTR MoveToNextAddress(LPTSTR lpsz);
  16. #define TAPI_CURRENT_VERSION 0x00010004
  17. #include <tapi.h>
  18. #pragma data_seg(".rdata")
  19. // "INI" file constants
  20. static const TCHAR cszEMailSection[] = TEXT("Internet_Mail");
  21. static const TCHAR cszEMailName[] = TEXT("EMail_Name");
  22. static const TCHAR cszEMailAddress[] = TEXT("EMail_Address");
  23. static const TCHAR cszPOPLogonName[] = TEXT("POP_Logon_Name");
  24. static const TCHAR cszPOPLogonPassword[] = TEXT("POP_Logon_Password");
  25. static const TCHAR cszPOPServer[] = TEXT("POP_Server");
  26. static const TCHAR cszSMTPServer[] = TEXT("SMTP_Server");
  27. static const TCHAR cszNewsSection[] = TEXT("Internet_News");
  28. static const TCHAR cszNNTPLogonName[] = TEXT("NNTP_Logon_Name");
  29. static const TCHAR cszNNTPLogonPassword[] = TEXT("NNTP_Logon_Password");
  30. static const TCHAR cszNNTPServer[] = TEXT("NNTP_Server");
  31. static const TCHAR cszUseExchange[] = TEXT("Use_MS_Exchange");
  32. static const TCHAR cszUserSection[] = TEXT("User");
  33. static const TCHAR cszDisplayPassword[] = TEXT("Display_Password");
  34. static const TCHAR cszNull[] = TEXT("");
  35. static const TCHAR cszYes[] = TEXT("yes");
  36. static const TCHAR cszNo[] = TEXT("no");
  37. static const TCHAR cszCMHeader[] = TEXT("Connection Manager CMS 0");
  38. static const TCHAR cszEntrySection[] = TEXT("Entry");
  39. static const TCHAR cszEntryName[] = TEXT("Entry_Name");
  40. TCHAR FAR cszCMCFG_DLL[] = TEXT("CMCFG32.DLL\0");
  41. CHAR FAR cszCMCFG_CONFIGURE[] = "CMConfig\0";
  42. CHAR FAR cszCMCFG_CONFIGUREEX[] = "CMConfigEx\0"; // Proc address
  43. typedef BOOL (WINAPI * CMCONFIGUREEX)(LPCSTR lpszINSFile);
  44. typedef BOOL (WINAPI * CMCONFIGURE)(LPCSTR lpszINSFile, LPCSTR lpszConnectoidNams);
  45. CMCONFIGURE lpfnCMConfigure;
  46. CMCONFIGUREEX lpfnCMConfigureEx;
  47. #define CLIENT_OFFSET(elem) ((DWORD)(DWORD_PTR)&(((LPINETCLIENTINFO)(NULL))->elem))
  48. #define CLIENT_SIZE(elem) sizeof(((LPINETCLIENTINFO)(NULL))->elem)
  49. #define CLIENT_ENTRY(section, value, elem) \
  50. {section, value, CLIENT_OFFSET(elem), CLIENT_SIZE(elem)}
  51. typedef struct
  52. {
  53. LPCTSTR lpszSection;
  54. LPCTSTR lpszValue;
  55. UINT uOffset;
  56. UINT uSize;
  57. } CLIENT_TABLE, FAR *LPCLIENT_TABLE;
  58. CLIENT_TABLE iniTable[] =
  59. {
  60. CLIENT_ENTRY(cszEMailSection, cszEMailName, szEMailName),
  61. CLIENT_ENTRY(cszEMailSection, cszEMailAddress, szEMailAddress),
  62. CLIENT_ENTRY(cszEMailSection, cszPOPLogonName, szPOPLogonName),
  63. CLIENT_ENTRY(cszEMailSection, cszPOPLogonPassword, szPOPLogonPassword),
  64. CLIENT_ENTRY(cszEMailSection, cszPOPServer, szPOPServer),
  65. CLIENT_ENTRY(cszEMailSection, cszSMTPServer, szSMTPServer),
  66. CLIENT_ENTRY(cszNewsSection, cszNNTPLogonName, szNNTPLogonName),
  67. CLIENT_ENTRY(cszNewsSection, cszNNTPLogonPassword, szNNTPLogonPassword),
  68. CLIENT_ENTRY(cszNewsSection, cszNNTPServer, szNNTPServer),
  69. {NULL, NULL, 0, 0}
  70. };
  71. #pragma data_seg()
  72. //
  73. // 5/19/97 jmazner Olympus #3663
  74. // The branding DLL (IEDKCS32.DLL) is responsible for all
  75. // proxy configuration.
  76. //
  77. /****
  78. DWORD ImportProxySettings(LPCTSTR lpszFile)
  79. {
  80. TCHAR szServer[MAX_SERVER_NAME + 1];
  81. TCHAR szOverride[1024];
  82. LPTSTR lpszServer = NULL;
  83. LPTSTR lpszOverride = NULL;
  84. BOOL fEnable = FALSE;
  85. if (GetPrivateProfileString(cszProxySection,
  86. cszProxyServer,
  87. cszNull,
  88. szServer,
  89. sizeof(szServer),
  90. lpszFile) != 0)
  91. {
  92. fEnable = TRUE;
  93. lpszServer = szServer;
  94. GetPrivateProfileString(cszProxySection,
  95. cszProxyOverride,
  96. cszNull,
  97. szOverride,
  98. sizeof(szOverride),
  99. lpszFile);
  100. lpszOverride = szOverride;
  101. }
  102. return lpfnInetSetProxy(fEnable, lpszServer, lpszOverride);
  103. }
  104. ****/
  105. DWORD ReadClientInfo(LPCTSTR lpszFile, LPINETCLIENTINFO lpClientInfo, LPCLIENT_TABLE lpClientTable)
  106. {
  107. LPCLIENT_TABLE lpTable;
  108. for (lpTable = lpClientTable; NULL != lpTable->lpszSection; ++lpTable)
  109. {
  110. GetPrivateProfileString(lpTable->lpszSection,
  111. lpTable->lpszValue,
  112. cszNull,
  113. (LPTSTR)((LPBYTE)lpClientInfo + lpTable->uOffset),
  114. lpTable->uSize / sizeof(TCHAR),
  115. lpszFile);
  116. }
  117. lpClientInfo->dwFlags = 0;
  118. if (*lpClientInfo->szPOPLogonName)
  119. {
  120. lpClientInfo->dwFlags |= INETC_LOGONMAIL;
  121. }
  122. if ((*lpClientInfo->szNNTPLogonName) || (*lpClientInfo->szNNTPServer))
  123. {
  124. lpClientInfo->dwFlags |= INETC_LOGONNEWS;
  125. }
  126. return ERROR_SUCCESS;
  127. }
  128. BOOL WantsExchangeInstalled(LPCTSTR lpszFile)
  129. {
  130. TCHAR szTemp[10];
  131. GetPrivateProfileString(cszEMailSection,
  132. cszUseExchange,
  133. cszNo,
  134. szTemp,
  135. 10,
  136. lpszFile);
  137. return (!lstrcmpi(szTemp, cszYes));
  138. }
  139. //+----------------------------------------------------------------------------
  140. //
  141. // Function: CallCMConfig
  142. //
  143. // Synopsis: Call into the Connection Manager dll's Configure function to allow CM to
  144. // process the .ins file as needed.
  145. //
  146. // Arguements: lpszINSFile -- full path to the .ins file
  147. //
  148. // Returns: TRUE if a CM profile is created, FALSE otherwise
  149. //
  150. // History: 09/02/98 DONALDM
  151. //
  152. //-----------------------------------------------------------------------------
  153. BOOL CallCMConfig(LPCTSTR lpszINSFile)
  154. {
  155. HINSTANCE hCMDLL = NULL;
  156. BOOL bRet = FALSE;
  157. // Load DLL and entry point
  158. hCMDLL = LoadLibrary(cszCMCFG_DLL);
  159. if (NULL != hCMDLL)
  160. {
  161. // To determine whether we should call CMConfig or CMConfigEx
  162. // Loop to find the appropriate buffer size to retieve the ins to memory
  163. ULONG ulBufferSize = 1024*10;
  164. // Parse the ISP section in the INI file to find query pair to append
  165. TCHAR *pszKeys = NULL;
  166. PTSTR pszKey = NULL;
  167. ULONG ulRetVal = 0;
  168. BOOL bEnumerate = TRUE;
  169. BOOL bUseEx = FALSE;
  170. PTSTR pszBuff = NULL;
  171. ulRetVal = 0;
  172. pszKeys = new TCHAR [ulBufferSize];
  173. if (pszKeys)
  174. {
  175. while (ulRetVal < (ulBufferSize - 2))
  176. {
  177. ulRetVal = ::GetPrivateProfileString(NULL, NULL, _T(""), pszKeys, ulBufferSize, lpszINSFile);
  178. if (0 == ulRetVal)
  179. bEnumerate = FALSE;
  180. if (ulRetVal < (ulBufferSize - 2))
  181. {
  182. break;
  183. }
  184. delete [] pszKeys;
  185. ulBufferSize += ulBufferSize;
  186. pszKeys = new TCHAR [ulBufferSize];
  187. if (!pszKeys)
  188. {
  189. bEnumerate = FALSE;
  190. }
  191. }
  192. if (bEnumerate)
  193. {
  194. pszKey = pszKeys;
  195. if (ulRetVal != 0)
  196. {
  197. while (*pszKey)
  198. {
  199. if (!lstrcmpi(pszKey, cszCMHeader))
  200. {
  201. bUseEx = TRUE;
  202. break;
  203. }
  204. pszKey += lstrlen(pszKey) + 1;
  205. }
  206. }
  207. }
  208. if (pszKeys)
  209. delete [] pszKeys;
  210. }
  211. TCHAR szConnectoidName[RAS_MaxEntryName];
  212. // Get the connectoid name from the [Entry] Section
  213. GetPrivateProfileString(cszEntrySection,
  214. cszEntryName,
  215. cszNull,
  216. szConnectoidName,
  217. RAS_MaxEntryName,
  218. lpszINSFile);
  219. if (bUseEx)
  220. {
  221. // Call CMConfigEx
  222. lpfnCMConfigureEx = (CMCONFIGUREEX)GetProcAddress(hCMDLL,cszCMCFG_CONFIGUREEX);
  223. if( lpfnCMConfigureEx )
  224. {
  225. #ifdef UNICODE
  226. CHAR szFile[_MAX_PATH + 1];
  227. wcstombs(szFile, lpszINSFile, _MAX_PATH + 1);
  228. bRet = lpfnCMConfigureEx(szFile);
  229. #else
  230. bRet = lpfnCMConfigureEx(lpszINSFile);
  231. #endif
  232. }
  233. }
  234. else
  235. {
  236. // Call CMConfig
  237. lpfnCMConfigure = (CMCONFIGURE)GetProcAddress(hCMDLL,cszCMCFG_CONFIGURE);
  238. if( lpfnCMConfigure )
  239. {
  240. #ifdef UNICODE
  241. CHAR szEntry[RAS_MaxEntryName];
  242. CHAR szFile[_MAX_PATH + 1];
  243. wcstombs(szEntry, szConnectoidName, RAS_MaxEntryName);
  244. wcstombs(szFile, lpszINSFile, _MAX_PATH + 1);
  245. bRet = lpfnCMConfigure(szFile, szEntry);
  246. #else
  247. bRet = lpfnCMConfigure(lpszINSFile, szConnectoidName);
  248. #endif
  249. }
  250. }
  251. if (bRet)
  252. {
  253. // restore original autodial settings
  254. lpfnInetSetAutodial(TRUE, szConnectoidName);
  255. }
  256. }
  257. // Cleanup
  258. if( hCMDLL )
  259. FreeLibrary(hCMDLL);
  260. if( lpfnCMConfigure )
  261. lpfnCMConfigure = NULL;
  262. return bRet;
  263. }
  264. BOOL DisplayPassword(LPCTSTR lpszFile)
  265. {
  266. TCHAR szTemp[10];
  267. GetPrivateProfileString(cszUserSection,
  268. cszDisplayPassword,
  269. cszNo,
  270. szTemp,
  271. 10,
  272. lpszFile);
  273. return (!lstrcmpi(szTemp, cszYes));
  274. }
  275. DWORD ImportClientInfo(
  276. LPCTSTR lpszFile,
  277. LPINETCLIENTINFO lpClientInfo)
  278. {
  279. DWORD dwRet;
  280. lpClientInfo->dwSize = sizeof(INETCLIENTINFO);
  281. dwRet = ReadClientInfo(lpszFile, lpClientInfo, iniTable);
  282. return dwRet;
  283. }
  284. DWORD ConfigureClient(
  285. HWND hwnd,
  286. LPCTSTR lpszFile,
  287. LPBOOL lpfNeedsRestart,
  288. LPBOOL lpfConnectoidCreated,
  289. BOOL fHookAutodial,
  290. LPTSTR szConnectoidName,
  291. DWORD dwConnectoidNameSize
  292. )
  293. {
  294. LPICONNECTION pConn;
  295. LPINETCLIENTINFO pClientInfo;
  296. DWORD dwRet = ERROR_SUCCESS;
  297. UINT cb = sizeof(ICONNECTION) + sizeof(INETCLIENTINFO);
  298. DWORD dwfOptions = INETCFG_INSTALLTCP | INETCFG_WARNIFSHARINGBOUND;
  299. LPRASENTRY pRasEntry = NULL;
  300. //
  301. // ChrisK Olympus 4756 5/25/97
  302. // Do not display busy animation on Win95
  303. //
  304. if (IsNT())
  305. {
  306. dwfOptions |= INETCFG_SHOWBUSYANIMATION;
  307. }
  308. // Allocate a buffer for connection and clientinfo objects
  309. //
  310. if ((pConn = (LPICONNECTION)LocalAlloc(LPTR, cb)) == NULL)
  311. {
  312. return ERROR_OUTOFMEMORY;
  313. }
  314. if (WantsExchangeInstalled(lpszFile))
  315. {
  316. dwfOptions |= INETCFG_INSTALLMAIL;
  317. }
  318. // Create either a CM profile, or a connectoid
  319. if (CallCMConfig(lpszFile))
  320. {
  321. *lpfConnectoidCreated = TRUE; // A dialup connection was created
  322. }
  323. else
  324. {
  325. dwRet = ImportConnection(lpszFile, pConn);
  326. if (ERROR_SUCCESS == dwRet)
  327. {
  328. pRasEntry = &pConn->RasEntry;
  329. dwfOptions |= INETCFG_SETASAUTODIAL |
  330. INETCFG_INSTALLRNA |
  331. INETCFG_INSTALLMODEM;
  332. }
  333. else if (ERROR_NO_MATCH == dwRet)
  334. {
  335. // 10/07/98 vyung IE bug#32882 hack.
  336. // If we do not detect the [Entry] section in the ins file,
  337. // we will assume it is an OE ins file. Then we will assume
  338. // we have a autodial connection and pass the INS to OE.
  339. return dwRet;
  340. }
  341. else if (ERROR_CANNOT_FIND_PHONEBOOK_ENTRY != dwRet)
  342. {
  343. return dwRet;
  344. }
  345. if (DisplayPassword(lpszFile))
  346. {
  347. if (*pConn->szPassword || *pConn->szUserName)
  348. {
  349. TCHAR szFmt[128];
  350. TCHAR szMsg[384];
  351. LoadString(ghInstance,IDS_PASSWORD,szFmt,SIZEOF_TCHAR_BUFFER(szFmt));
  352. wsprintf(szMsg, szFmt, pConn->szUserName, pConn->szPassword);
  353. MessageBox(hwnd,szMsg,cszAppName,MB_ICONINFORMATION | MB_OK);
  354. }
  355. }
  356. if (fHookAutodial &&
  357. ((0 == *pConn->RasEntry.szAutodialDll) ||
  358. (0 == *pConn->RasEntry.szAutodialFunc)))
  359. {
  360. lstrcpy(pConn->RasEntry.szAutodialDll, TEXT("isign32.dll"));
  361. lstrcpy(pConn->RasEntry.szAutodialFunc, TEXT("AutoDialLogon"));
  362. }
  363. if (ERROR_SUCCESS != dwRet)
  364. {
  365. pClientInfo = NULL;
  366. }
  367. // humongous hack for ISBU
  368. dwRet = lpfnInetConfigClient(hwnd,
  369. NULL,
  370. pConn->szEntryName,
  371. pRasEntry,
  372. pConn->szUserName,
  373. pConn->szPassword,
  374. NULL,
  375. NULL,
  376. dwfOptions & ~INETCFG_INSTALLMAIL,
  377. lpfNeedsRestart);
  378. lstrcpy(szConnectoidName, pConn->szEntryName);
  379. LclSetEntryScriptPatch(pRasEntry->szScript,pConn->szEntryName);
  380. BOOL fEnabled = TRUE;
  381. DWORD dwResult = 0xba;
  382. dwResult = lpfnInetGetAutodial(&fEnabled, pConn->szEntryName, RAS_MaxEntryName+1);
  383. if ((ERROR_SUCCESS == dwRet) && lstrlen(pConn->szEntryName))
  384. {
  385. *lpfConnectoidCreated = (NULL != pRasEntry);
  386. PopulateNTAutodialAddress( lpszFile, pConn->szEntryName );
  387. }
  388. else
  389. {
  390. DebugOut("ISIGNUP: ERROR: InetGetAutodial failed, will not be able to set NT Autodial\n");
  391. }
  392. }
  393. if (ERROR_SUCCESS == dwRet)
  394. {
  395. // Get the mail client info
  396. INETCLIENTINFO pClientInfo;
  397. ImportClientInfo(lpszFile, &pClientInfo);
  398. dwRet = lpfnInetConfigClient(
  399. hwnd,
  400. NULL,
  401. NULL,
  402. NULL,
  403. NULL,
  404. NULL,
  405. NULL,
  406. &pClientInfo,
  407. dwfOptions & INETCFG_INSTALLMAIL,
  408. lpfNeedsRestart);
  409. }
  410. LocalFree(pConn);
  411. return dwRet;
  412. }
  413. //+----------------------------------------------------------------------------
  414. //
  415. // Function: PopulateNTAutodialAddress
  416. //
  417. // Synopsis: Take Internet addresses from INS file and load them into the
  418. // autodial database
  419. //
  420. // Arguments: pszFileName - pointer to INS file name
  421. //
  422. // Returns: Error code (ERROR_SUCCESS == success)
  423. //
  424. // History: 8/29/96 ChrisK Created
  425. //
  426. //-----------------------------------------------------------------------------
  427. #define AUTODIAL_ADDRESS_BUFFER_SIZE 2048
  428. #define AUTODIAL_ADDRESS_SECTION_NAME TEXT("Autodial_Addresses_for_NT")
  429. HRESULT PopulateNTAutodialAddress(LPCTSTR pszFileName, LPCTSTR pszEntryName)
  430. {
  431. HRESULT hr = ERROR_SUCCESS;
  432. LONG lRC = 0;
  433. LPLINETRANSLATECAPS lpcap = NULL;
  434. LPLINETRANSLATECAPS lpTemp = NULL;
  435. LPLINELOCATIONENTRY lpLE = NULL;
  436. LPRASAUTODIALENTRY rADE;
  437. INT idx = 0;
  438. LPTSTR lpszBuffer = NULL;
  439. LPTSTR lpszNextAddress = NULL;
  440. rADE = NULL;
  441. //RNAAPI *pRnaapi = NULL;
  442. // jmazner 10/8/96 this function is NT specific
  443. if( !IsNT() )
  444. {
  445. DebugOut("ISIGNUP: Bypassing PopulateNTAutodialAddress for win95.\r\n");
  446. return( ERROR_SUCCESS );
  447. }
  448. //Assert(pszFileName && pszEntryName);
  449. //dprintf("ISIGNUP: PopulateNTAutodialAddress "%s %s.\r\n",pszFileName, pszEntryName);
  450. DebugOut(pszFileName);
  451. DebugOut(", ");
  452. DebugOut(pszEntryName);
  453. DebugOut(".\r\n");
  454. // allocate this guy for making softlink calls to Ras functions
  455. //pRnaapi = new RNAAPI;
  456. //if( !pRnaapi )
  457. //{
  458. //hr = ERROR_NOT_ENOUGH_MEMORY;
  459. //goto PopulateNTAutodialAddressExit;
  460. //}
  461. //
  462. // Get list of TAPI locations
  463. //
  464. lpcap = (LPLINETRANSLATECAPS)GlobalAlloc(GPTR,sizeof(LINETRANSLATECAPS));
  465. if (!lpcap)
  466. {
  467. hr = ERROR_NOT_ENOUGH_MEMORY;
  468. goto PopulateNTAutodialAddressExit;
  469. }
  470. lpcap->dwTotalSize = sizeof(LINETRANSLATECAPS);
  471. lRC = lineGetTranslateCaps(0,0x10004,lpcap);
  472. if (SUCCESS == lRC)
  473. {
  474. lpTemp = (LPLINETRANSLATECAPS)GlobalAlloc(GPTR,lpcap->dwNeededSize);
  475. if (!lpTemp)
  476. {
  477. hr = ERROR_NOT_ENOUGH_MEMORY;
  478. goto PopulateNTAutodialAddressExit;
  479. }
  480. lpTemp->dwTotalSize = lpcap->dwNeededSize;
  481. GlobalFree(lpcap);
  482. lpcap = (LPLINETRANSLATECAPS)lpTemp;
  483. lpTemp = NULL;
  484. lRC = lineGetTranslateCaps(0,0x10004,lpcap);
  485. }
  486. if (SUCCESS != lRC)
  487. {
  488. hr = (HRESULT)lRC; // REVIEW: not real sure about this.
  489. goto PopulateNTAutodialAddressExit;
  490. }
  491. //
  492. // Create an array of RASAUTODIALENTRY structs
  493. //
  494. rADE = (LPRASAUTODIALENTRY)GlobalAlloc(GPTR,
  495. sizeof(RASAUTODIALENTRY)*lpcap->dwNumLocations);
  496. if (!rADE)
  497. {
  498. hr = ERROR_NOT_ENOUGH_MEMORY;
  499. goto PopulateNTAutodialAddressExit;
  500. }
  501. //
  502. // Enable autodialing for all locations
  503. //
  504. idx = lpcap->dwNumLocations;
  505. lpLE = (LPLINELOCATIONENTRY)((DWORD_PTR)lpcap + (DWORD)lpcap->dwLocationListOffset);
  506. while (idx)
  507. {
  508. idx--;
  509. lpfnRasSetAutodialEnable(lpLE[idx].dwPermanentLocationID,TRUE);
  510. //
  511. // fill in array values
  512. //
  513. rADE[idx].dwSize = sizeof(RASAUTODIALENTRY);
  514. rADE[idx].dwDialingLocation = lpLE[idx].dwPermanentLocationID;
  515. lstrcpyn(rADE[idx].szEntry,pszEntryName,RAS_MaxEntryName);
  516. }
  517. //
  518. // Get list of addresses
  519. //
  520. lpszBuffer = (LPTSTR)GlobalAlloc(GPTR,AUTODIAL_ADDRESS_BUFFER_SIZE);
  521. if (!lpszBuffer)
  522. {
  523. hr = ERROR_NOT_ENOUGH_MEMORY;
  524. goto PopulateNTAutodialAddressExit;
  525. }
  526. if((AUTODIAL_ADDRESS_BUFFER_SIZE-2) == GetPrivateProfileSection(AUTODIAL_ADDRESS_SECTION_NAME,
  527. lpszBuffer, AUTODIAL_ADDRESS_BUFFER_SIZE / sizeof(TCHAR), pszFileName))
  528. {
  529. //AssertSz(0,"Autodial address section bigger than buffer.\r\n");
  530. hr = ERROR_NOT_ENOUGH_MEMORY;
  531. goto PopulateNTAutodialAddressExit;
  532. }
  533. //
  534. // Walk list of addresses and set autodialing for each one
  535. //
  536. lpszNextAddress = lpszBuffer;
  537. do
  538. {
  539. lpszNextAddress = MoveToNextAddress(lpszNextAddress);
  540. if (!(*lpszNextAddress))
  541. break; // do-while
  542. lpfnRasSetAutodialAddress(lpszNextAddress,0,rADE,
  543. sizeof(RASAUTODIALENTRY)*lpcap->dwNumLocations,lpcap->dwNumLocations);
  544. lpszNextAddress = lpszNextAddress + lstrlen(lpszNextAddress);
  545. } while(1);
  546. PopulateNTAutodialAddressExit:
  547. if (lpcap)
  548. GlobalFree(lpcap);
  549. lpcap = NULL;
  550. if (rADE)
  551. GlobalFree(rADE);
  552. rADE = NULL;
  553. if (lpszBuffer)
  554. GlobalFree(lpszBuffer);
  555. lpszBuffer = NULL;
  556. //if( pRnaapi )
  557. // delete pRnaapi;
  558. //pRnaapi = NULL;
  559. return hr;
  560. }
  561. //+----------------------------------------------------------------------------
  562. //
  563. // Function: MoveToNextAddress
  564. //
  565. // Synopsis: Given a pointer into the data bufffer, this function will move
  566. // through the buffer until it points to the begining of the next
  567. // address or it reaches the end of the buffer.
  568. //
  569. // Arguements: lpsz - pointer into buffer
  570. //
  571. // Returns: Pointer to the next address, return value will point to NULL
  572. // if there are no more addresses
  573. //
  574. // History: 8/29/96 ChrisK Created
  575. //
  576. //-----------------------------------------------------------------------------
  577. LPTSTR MoveToNextAddress(LPTSTR lpsz)
  578. {
  579. BOOL fLastCharWasNULL = FALSE;
  580. //AssertSz(lpsz,"MoveToNextAddress: NULL input\r\n");
  581. //
  582. // Look for an = sign
  583. //
  584. do
  585. {
  586. if (fLastCharWasNULL && '\0' == *lpsz)
  587. break; // are we at the end of the data?
  588. if ('\0' == *lpsz)
  589. fLastCharWasNULL = TRUE;
  590. else
  591. fLastCharWasNULL = FALSE;
  592. if ('=' == *lpsz)
  593. break;
  594. if (*lpsz)
  595. lpsz = CharNext(lpsz);
  596. else
  597. lpsz++;
  598. } while (1);
  599. //
  600. // Move to the first character beyond the = sign.
  601. //
  602. if (*lpsz)
  603. lpsz = CharNext(lpsz);
  604. return lpsz;
  605. }