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.

618 lines
18 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright (c) 1994-1998 Microsoft Corporation
  4. //*********************************************************************
  5. //
  6. // RNACALL.C - functions to call RNA dll to create connectoid
  7. //
  8. // HISTORY:
  9. //
  10. // 1/18/95 jeremys Cloned from RNA UI code
  11. // 96/01/31 markdu Renamed CONNENTDLG to OLDCONNENTDLG to avoid
  12. // conflicts with RNAP.H.
  13. // 96/02/23 markdu Replaced RNAValidateEntryName with
  14. // RASValidateEntryName
  15. // 96/02/24 markdu Re-wrote the implementation of ENUM_MODEM to
  16. // use RASEnumDevices() instead of RNAEnumDevices().
  17. // Also eliminated IsValidDevice() and RNAGetDeviceInfo().
  18. // 96/02/24 markdu Re-wrote the implementation of ENUM_CONNECTOID to
  19. // use RASEnumEntries() instead of RNAEnumConnEntries().
  20. // 96/02/26 markdu Replaced all remaining internal RNA APIs.
  21. // 96/03/07 markdu Extend ENUM_MODEM class, and use global modem
  22. // enum object.
  23. // 96/03/08 markdu Do complete verification of device name and type
  24. // strings passed in to CreateConnectoid.
  25. // 96/03/09 markdu Moved generic RASENTRY initialization into
  26. // its own function (InitRasEntry). Added a wait cursor
  27. // during loading of RNA.
  28. // 96/03/09 markdu Added LPRASENTRY parameter to CreateConnectoid()
  29. // 96/03/09 markdu Moved all references to 'need terminal window after
  30. // dial' into RASENTRY.dwfOptions.
  31. // Also no longer need GetConnectoidPhoneNumber function.
  32. // 96/03/10 markdu Moved all references to modem name into RASENTRY.
  33. // 96/03/10 markdu Moved all references to phone number into RASENTRY.
  34. // 96/03/11 markdu Moved code to set username and password out of
  35. // CreateConnectoid into SetConnectoidUsername so it can be reused.
  36. // 96/03/11 markdu Added some flags in InitRasEntry.
  37. // 96/03/13 markdu Change ValidateConncectoidName to take LPCSTR.
  38. // 96/03/16 markdu Added ReInit member function to re-enumerate modems.
  39. // 96/03/21 markdu Work around RNA bug in ENUM_MODEM::ReInit().
  40. // 96/03/24 markdu Replaced memset with ZeroMemory for consistency.
  41. // 96/03/24 markdu Replaced lstrcpy with lstrcpyn where appropriate.
  42. // 96/03/25 markdu Removed GetIPInfo and SetIPInfo.
  43. // 96/04/04 markdu Added phonebook name param to CreateConnectoid,
  44. // ValidateConnectoidName, and SetConnectoidUsername.
  45. // 96/04/07 markdu NASH BUG 15645 Work around RNA bug where area code
  46. // string is required even though it is not being used.
  47. // 96/04/26 markdu NASH BUG 18605 Handle ERROR_FILE_NOT_FOUND return
  48. // from ValidateConnectoidName.
  49. // 96/05/14 markdu NASH BUG 22730 Work around RNA bug. Flags for terminal
  50. // settings are swapped by RasSetEntryproperties.
  51. // 96/05/16 markdu NASH BUG 21810 Added function for IP address validation.
  52. // 96/06/04 markdu OSR BUG 7246 Add RASEO_SwCompression and
  53. // RASEO_ModemLights to default RASENTRY.
  54. //
  55. #include "wizard.h"
  56. #include "tapi.h"
  57. #include "CompareString.cpp"
  58. // instance handle must be in per-instance data segment
  59. #pragma data_seg(DATASEG_PERINSTANCE)
  60. // Global variables
  61. HINSTANCE ghInstRNADll=NULL; // handle to RNA dll we load explicitly
  62. HINSTANCE ghInstRNAPHDll=NULL; // handle to RNAPH dll we load explicitly
  63. DWORD dwRefCount=0;
  64. BOOL fRNALoaded=FALSE; // TRUE if RNA function addresses have been loaded
  65. // global function pointers for RNA apis
  66. RASENUMDEVICES lpRasEnumDevices=NULL;
  67. RASENUMENTRIES lpRasEnumEntries=NULL;
  68. // API table for function addresses to fetch
  69. #define NUM_RNAAPI_PROCS 2
  70. APIFCN RnaApiList[NUM_RNAAPI_PROCS] =
  71. {
  72. { (PVOID *) &lpRasEnumDevices,"RasEnumDevicesA"},
  73. { (PVOID *) &lpRasEnumEntries,"RasEnumEntriesA"}
  74. };
  75. #pragma data_seg(DATASEG_DEFAULT)
  76. ENUM_MODEM * gpEnumModem=NULL; // pointer modem enumeration object
  77. BOOL GetApiProcAddresses(HMODULE hModDLL,APIFCN * pApiProcList,UINT nApiProcs);
  78. static const CHAR szRegValRNAWizard[] = "wizard";
  79. static const CHAR szRegPathRNAWizard[] = REGSTR_PATH_REMOTEACCESS;
  80. /*******************************************************************
  81. NAME: InitRNA
  82. SYNOPSIS: Loads the RNA dll (RASAPI32), gets proc addresses,
  83. and loads RNA engine
  84. EXIT: TRUE if successful, or FALSE if fails. Displays its
  85. own error message upon failure.
  86. NOTES: We load the RNA dll explicitly and get proc addresses
  87. because these are private APIs and not guaranteed to
  88. be supported beyond Windows 95. This way, if the DLL
  89. isn't there or the entry points we expect aren't there,
  90. we can display a coherent message instead of the weird
  91. Windows dialog you get if implicit function addresses
  92. can't be resolved.
  93. ********************************************************************/
  94. BOOL InitRNA(HWND hWnd)
  95. {
  96. DEBUGMSG("rnacall.c::InitRNA()");
  97. // only actually do init stuff on first call to this function
  98. // (when reference count is 0), just increase reference count
  99. // for subsequent calls
  100. if (dwRefCount == 0) {
  101. CHAR szRNADll[SMALL_BUF_LEN];
  102. DEBUGMSG("Loading RNA DLL");
  103. // set an hourglass cursor
  104. WAITCURSOR WaitCursor;
  105. // get the filename (RASAPI32.DLL) out of resource
  106. LoadSz(IDS_RNADLL_FILENAME,szRNADll,sizeof(szRNADll));
  107. // load the RNA api dll
  108. ghInstRNADll = LoadLibrary(szRNADll);
  109. if (!ghInstRNADll) {
  110. UINT uErr = GetLastError();
  111. DisplayErrorMessage(hWnd,IDS_ERRLoadRNADll1,uErr,ERRCLS_STANDARD,
  112. MB_ICONSTOP);
  113. return FALSE;
  114. }
  115. // cycle through the API table and get proc addresses for all the APIs we
  116. // need
  117. if (!GetApiProcAddresses(ghInstRNADll,RnaApiList,NUM_RNAAPI_PROCS)) {
  118. MsgBox(hWnd,IDS_ERRLoadRNADll2,MB_ICONSTOP,MB_OK);
  119. DeInitRNA();
  120. return FALSE;
  121. }
  122. }
  123. fRNALoaded = TRUE;
  124. dwRefCount ++;
  125. return TRUE;
  126. }
  127. /*******************************************************************
  128. NAME: DeInitRNA
  129. SYNOPSIS: Unloads RNA dll.
  130. ********************************************************************/
  131. VOID DeInitRNA()
  132. {
  133. DEBUGMSG("rnacall.c::DeInitRNA()");
  134. UINT nIndex;
  135. // decrement reference count
  136. if (dwRefCount)
  137. dwRefCount --;
  138. // when the reference count hits zero, do real deinitialization stuff
  139. if (dwRefCount == 0)
  140. {
  141. if (fRNALoaded)
  142. {
  143. // set function pointers to NULL
  144. for (nIndex = 0;nIndex<NUM_RNAAPI_PROCS;nIndex++)
  145. *RnaApiList[nIndex].ppFcnPtr = NULL;
  146. fRNALoaded = FALSE;
  147. }
  148. // free the RNA dll
  149. if (ghInstRNADll)
  150. {
  151. DEBUGMSG("Unloading RNA DLL");
  152. FreeLibrary(ghInstRNADll);
  153. ghInstRNADll = NULL;
  154. }
  155. // free the RNAPH dll
  156. if (ghInstRNAPHDll)
  157. {
  158. DEBUGMSG("Unloading RNAPH DLL");
  159. FreeLibrary(ghInstRNAPHDll);
  160. ghInstRNAPHDll = NULL;
  161. }
  162. }
  163. }
  164. VOID FAR PASCAL LineCallback(DWORD hDevice, DWORD dwMsg,
  165. DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2,
  166. DWORD dwParam3)
  167. {
  168. return;
  169. }
  170. /*******************************************************************
  171. NAME: EnsureRNALoaded
  172. SYNOPSIS: Loads RNA if not already loaded
  173. ********************************************************************/
  174. DWORD EnsureRNALoaded(VOID)
  175. {
  176. DEBUGMSG("rnacall.c::EnsureRNALoaded()");
  177. DWORD dwRet = ERROR_SUCCESS;
  178. // load RNA if necessary
  179. if (!fRNALoaded) {
  180. if (InitRNA(NULL))
  181. fRNALoaded = TRUE;
  182. else return ERROR_FILE_NOT_FOUND;
  183. }
  184. return dwRet;
  185. }
  186. /*******************************************************************
  187. NAME: ENUM_MODEM::ENUM_MODEM
  188. SYNOPSIS: Constructor for class to enumerate modems
  189. NOTES: Useful to have a class rather than C functions for
  190. this, due to how the enumerators function
  191. ********************************************************************/
  192. ENUM_MODEM::ENUM_MODEM() :
  193. m_dwError(ERROR_SUCCESS),m_lpData(NULL),m_dwIndex(0)
  194. {
  195. DWORD cbSize = 0;
  196. // Use the reinit member function to do the work.
  197. this->ReInit();
  198. }
  199. /*******************************************************************
  200. NAME: ENUM_MODEM::ReInit
  201. SYNOPSIS: Re-enumerate the modems, freeing the old memory.
  202. ********************************************************************/
  203. DWORD ENUM_MODEM::ReInit()
  204. {
  205. DWORD cbSize = 0;
  206. // Clean up the old list
  207. if (m_lpData)
  208. {
  209. delete m_lpData;
  210. m_lpData = NULL;
  211. }
  212. m_dwNumEntries = 0;
  213. m_dwIndex = 0;
  214. // call RasEnumDevices with no buffer to find out required buffer size
  215. ASSERT(lpRasEnumDevices);
  216. m_dwError = lpRasEnumDevices(NULL, &cbSize, &m_dwNumEntries);
  217. // Special case check to work around RNA bug where ERROR_BUFFER_TOO_SMALL
  218. // is returned even if there are no devices.
  219. // If there are no devices, we are finished.
  220. if (0 == m_dwNumEntries)
  221. {
  222. m_dwError = ERROR_SUCCESS;
  223. return m_dwError;
  224. }
  225. // Since we were just checking how much mem we needed, we expect
  226. // a return value of ERROR_BUFFER_TOO_SMALL, or it may just return
  227. // ERROR_SUCCESS (ChrisK 7/9/96).
  228. if (ERROR_BUFFER_TOO_SMALL != m_dwError && ERROR_SUCCESS != m_dwError)
  229. {
  230. return m_dwError;
  231. }
  232. // Allocate the space for the data
  233. m_lpData = (LPRASDEVINFO) new CHAR[cbSize];
  234. if (NULL == m_lpData)
  235. {
  236. DEBUGTRAP("ENUM_MODEM: Failed to allocate device list buffer");
  237. m_dwError = ERROR_NOT_ENOUGH_MEMORY;
  238. return m_dwError;
  239. }
  240. m_lpData->dwSize = sizeof(RASDEVINFO);
  241. m_dwNumEntries = 0;
  242. // enumerate the modems into buffer
  243. m_dwError = lpRasEnumDevices(m_lpData, &cbSize,
  244. &m_dwNumEntries);
  245. if (ERROR_SUCCESS != m_dwError)
  246. return m_dwError;
  247. //
  248. // ChrisK Olympus 4560 do not include VPN's in the list
  249. //
  250. DWORD dwTempNumEntries;
  251. DWORD idx;
  252. LPRASDEVINFO lpNextValidDevice;
  253. dwTempNumEntries = m_dwNumEntries;
  254. lpNextValidDevice = m_lpData;
  255. //
  256. // Walk through the list of devices and copy non-VPN device to the first
  257. // available element of the array.
  258. //
  259. for (idx = 0;idx < dwTempNumEntries; idx++)
  260. {
  261. if (0 != SafeCompareStringA("VPN",m_lpData[idx].szDeviceType))
  262. {
  263. if (lpNextValidDevice != &m_lpData[idx])
  264. {
  265. MoveMemory(lpNextValidDevice ,&m_lpData[idx],sizeof(RASDEVINFO));
  266. }
  267. lpNextValidDevice++;
  268. }
  269. else
  270. {
  271. m_dwNumEntries--;
  272. }
  273. }
  274. return m_dwError;
  275. }
  276. /*******************************************************************
  277. NAME: ENUM_MODEM::~ENUM_MODEM
  278. SYNOPSIS: Destructor for class
  279. ********************************************************************/
  280. ENUM_MODEM::~ENUM_MODEM()
  281. {
  282. if (m_lpData)
  283. {
  284. delete m_lpData;
  285. m_lpData = NULL;
  286. }
  287. }
  288. /*******************************************************************
  289. NAME: ENUM_MODEM::Next
  290. SYNOPSIS: Enumerates next modem
  291. EXIT: Returns a pointer to device info structure. Returns
  292. NULL if no more modems or error occurred. Call GetError
  293. to determine if error occurred.
  294. ********************************************************************/
  295. CHAR * ENUM_MODEM::Next()
  296. {
  297. if (m_dwIndex < m_dwNumEntries)
  298. {
  299. return m_lpData[m_dwIndex++].szDeviceName;
  300. }
  301. return NULL;
  302. }
  303. /*******************************************************************
  304. NAME: ENUM_MODEM::GetDeviceTypeFromName
  305. SYNOPSIS: Returns type string for specified device.
  306. EXIT: Returns a pointer to device type string for first
  307. device name that matches. Returns
  308. NULL if no device with specified name is found
  309. ********************************************************************/
  310. CHAR * ENUM_MODEM::GetDeviceTypeFromName(LPSTR szDeviceName)
  311. {
  312. DWORD dwIndex = 0;
  313. while (dwIndex < m_dwNumEntries)
  314. {
  315. if (!lstrcmp(m_lpData[dwIndex].szDeviceName, szDeviceName))
  316. {
  317. return m_lpData[dwIndex].szDeviceType;
  318. }
  319. dwIndex++;
  320. }
  321. return NULL;
  322. }
  323. /*******************************************************************
  324. NAME: ENUM_MODEM::GetDeviceNameFromType
  325. SYNOPSIS: Returns type string for specified device.
  326. EXIT: Returns a pointer to device name string for first
  327. device type that matches. Returns
  328. NULL if no device with specified Type is found
  329. ********************************************************************/
  330. CHAR * ENUM_MODEM::GetDeviceNameFromType(LPSTR szDeviceType)
  331. {
  332. DWORD dwIndex = 0;
  333. while (dwIndex < m_dwNumEntries)
  334. {
  335. if (!lstrcmp(m_lpData[dwIndex].szDeviceType, szDeviceType))
  336. {
  337. return m_lpData[dwIndex].szDeviceName;
  338. }
  339. dwIndex++;
  340. }
  341. return NULL;
  342. }
  343. /*******************************************************************
  344. NAME: ENUM_MODEM::VerifyDeviceNameAndType
  345. SYNOPSIS: Determines whether there is a device with the name
  346. and type given.
  347. EXIT: Returns TRUE if the specified device was found,
  348. FALSE otherwise.
  349. ********************************************************************/
  350. BOOL ENUM_MODEM::VerifyDeviceNameAndType(LPSTR szDeviceName, LPSTR szDeviceType)
  351. {
  352. DWORD dwIndex = 0;
  353. while (dwIndex < m_dwNumEntries)
  354. {
  355. if (!lstrcmp(m_lpData[dwIndex].szDeviceType, szDeviceType) &&
  356. !lstrcmp(m_lpData[dwIndex].szDeviceName, szDeviceName))
  357. {
  358. return TRUE;
  359. }
  360. dwIndex++;
  361. }
  362. return FALSE;
  363. }
  364. /*******************************************************************
  365. NAME: GetApiProcAddresses
  366. SYNOPSIS: Gets proc addresses for a table of functions
  367. EXIT: returns TRUE if successful, FALSE if unable to retrieve
  368. any proc address in table
  369. HISTORY:
  370. 96/02/28 markdu If the api is not found in the module passed in,
  371. try the backup (RNAPH.DLL)
  372. ********************************************************************/
  373. BOOL GetApiProcAddresses(HMODULE hModDLL,APIFCN * pApiProcList,UINT nApiProcs)
  374. {
  375. DEBUGMSG("rnacall.c::GetApiProcAddresses()");
  376. UINT nIndex;
  377. // cycle through the API table and get proc addresses for all the APIs we
  378. // need
  379. for (nIndex = 0;nIndex < nApiProcs;nIndex++)
  380. {
  381. if (!(*pApiProcList[nIndex].ppFcnPtr = (PVOID) GetProcAddress(hModDLL,
  382. pApiProcList[nIndex].pszName)))
  383. {
  384. // Try to find the address in RNAPH.DLL. This is useful in the
  385. // case that RASAPI32.DLL did not contain the function that we
  386. // were trying to load.
  387. if (FALSE == IsNT())
  388. {
  389. if (!ghInstRNAPHDll)
  390. {
  391. CHAR szRNAPHDll[SMALL_BUF_LEN];
  392. LoadSz(IDS_RNAPHDLL_FILENAME,szRNAPHDll,sizeof(szRNAPHDll));
  393. ghInstRNAPHDll = LoadLibrary(szRNAPHDll);
  394. }
  395. if ((!ghInstRNAPHDll) || !(*pApiProcList[nIndex].ppFcnPtr =
  396. (PVOID) GetProcAddress(ghInstRNAPHDll,pApiProcList[nIndex].pszName)))
  397. {
  398. DEBUGMSG("Unable to get address of function %s",
  399. pApiProcList[nIndex].pszName);
  400. for (nIndex = 0;nIndex<nApiProcs;nIndex++)
  401. *pApiProcList[nIndex].ppFcnPtr = NULL;
  402. return FALSE;
  403. }
  404. }
  405. }
  406. }
  407. return TRUE;
  408. }
  409. //+----------------------------------------------------------------------------
  410. //
  411. // Function: InitTAPILocation
  412. //
  413. // Synopsis: Ensure that TAPI location information is configured correctly;
  414. // if not, prompt user to fill it in.
  415. //
  416. // Arguments: hwndParent -- parent window for TAPI dialog to use
  417. // (_must_ be a valid window HWND, see note below)
  418. //
  419. // Returns: void
  420. //
  421. // Notes: The docs for lineTranslateDialog lie when they say that the
  422. // fourth parameter (hwndOwner) can be null. In fact, if this
  423. // is null, the call will return with LINEERR_INVALPARAM.
  424. //
  425. //
  426. // History: 7/15/97 jmazner Created for Olympus #6294
  427. //
  428. //-----------------------------------------------------------------------------
  429. void InitTAPILocation(HWND hwndParent)
  430. {
  431. HLINEAPP hLineApp=NULL;
  432. char szTempCountryCode[8];
  433. char szTempCityCode[8];
  434. DWORD dwTapiErr = 0;
  435. DWORD cDevices=0;
  436. DWORD dwCurDevice = 0;
  437. ASSERT( IsWindow(hwndParent) );
  438. //
  439. // see if we can get location info from TAPI
  440. //
  441. dwTapiErr = tapiGetLocationInfo(szTempCountryCode,szTempCityCode);
  442. if( 0 != dwTapiErr )
  443. {
  444. //
  445. // GetLocation failed. let's try calling the TAPI mini dialog. Note
  446. // that when called in this fashion, the dialog has _no_ cancel option,
  447. // the user is forced to enter info and hit OK.
  448. //
  449. DEBUGMSG("InitTAPILocation, tapiGetLocationInfo failed");
  450. dwTapiErr = lineInitialize(&hLineApp,ghInstance,LineCallback," ",&cDevices);
  451. if (dwTapiErr == ERROR_SUCCESS)
  452. {
  453. //
  454. // loop through all TAPI devices and try to call lineTranslateDialog
  455. // The call might fail for VPN devices, thus we want to try every
  456. // device until we get a success.
  457. //
  458. dwTapiErr = LINEERR_INVALPARAM;
  459. while( (dwTapiErr != 0) && (dwCurDevice < cDevices) )
  460. {
  461. dwTapiErr = lineTranslateDialog(hLineApp,dwCurDevice,0x10004,hwndParent,NULL);
  462. if( 0 != dwTapiErr )
  463. {
  464. DEBUGMSG("InitTAPILocation, lineTranslateDialog on device %d failed with err = %d!",
  465. dwCurDevice, dwTapiErr);
  466. }
  467. dwCurDevice++;
  468. }
  469. }
  470. else
  471. {
  472. DEBUGMSG("InitTAPILocation, lineInitialize failed with err = %d", dwTapiErr);
  473. }
  474. dwTapiErr = tapiGetLocationInfo(szTempCountryCode,szTempCityCode);
  475. if( 0 != dwTapiErr )
  476. {
  477. DEBUGMSG("InitTAPILocation still failed on GetLocationInfo, bummer.");
  478. }
  479. else
  480. {
  481. DEBUGMSG("InitTAPILocation, TAPI location is initialized now");
  482. }
  483. }
  484. if( hLineApp )
  485. {
  486. lineShutdown(hLineApp);
  487. hLineApp = NULL;
  488. }
  489. }