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.

1095 lines
32 KiB

  1. // --------------------------------------------------------------------------------
  2. // Ixpras.cpp
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // Steven J. Bailey
  5. // --------------------------------------------------------------------------------
  6. #include "pch.hxx"
  7. #include "dllmain.h"
  8. #include "ixpras.h"
  9. #include "strconst.h"
  10. #include "resource.h"
  11. #include "demand.h"
  12. #include "shlwapi.h"
  13. // --------------------------------------------------------------------------------
  14. // RAS API Typedefs
  15. // --------------------------------------------------------------------------------
  16. typedef DWORD (APIENTRY *RASDIALPROC)(LPRASDIALEXTENSIONS, LPTSTR, LPRASDIALPARAMS, DWORD, LPVOID, LPHRASCONN);
  17. typedef DWORD (APIENTRY *RASENUMCONNECTIONSPROC)(LPRASCONN, LPDWORD, LPDWORD);
  18. typedef DWORD (APIENTRY *RASENUMENTRIESPROC)(LPTSTR, LPTSTR, LPRASENTRYNAME, LPDWORD, LPDWORD);
  19. typedef DWORD (APIENTRY *RASGETCONNECTSTATUSPROC)(HRASCONN, LPRASCONNSTATUS);
  20. typedef DWORD (APIENTRY *RASGETERRORSTRINGPROC)(UINT, LPTSTR, DWORD);
  21. typedef DWORD (APIENTRY *RASHANGUPPROC)(HRASCONN);
  22. typedef DWORD (APIENTRY *RASSETENTRYDIALPARAMSPROC)(LPTSTR, LPRASDIALPARAMS, BOOL);
  23. typedef DWORD (APIENTRY *RASGETENTRYDIALPARAMSPROC)(LPTSTR, LPRASDIALPARAMS, BOOL*);
  24. typedef DWORD (APIENTRY *RASCREATEPHONEBOOKENTRYPROC)(HWND, LPTSTR);
  25. typedef DWORD (APIENTRY *RASEDITPHONEBOOKENTRYPROC)(HWND, LPTSTR, LPTSTR);
  26. // --------------------------------------------------------------------------------
  27. // RAS Function Pointers
  28. // --------------------------------------------------------------------------------
  29. static RASDIALPROC g_pRasDial=NULL;
  30. static RASENUMCONNECTIONSPROC g_pRasEnumConnections=NULL;
  31. static RASENUMENTRIESPROC g_pRasEnumEntries=NULL;
  32. static RASGETCONNECTSTATUSPROC g_pRasGetConnectStatus=NULL;
  33. static RASGETERRORSTRINGPROC g_pRasGetErrorString=NULL;
  34. static RASHANGUPPROC g_pRasHangup=NULL;
  35. static RASSETENTRYDIALPARAMSPROC g_pRasSetEntryDialParams=NULL;
  36. static RASGETENTRYDIALPARAMSPROC g_pRasGetEntryDialParams=NULL;
  37. static RASCREATEPHONEBOOKENTRYPROC g_pRasCreatePhonebookEntry=NULL;
  38. static RASEDITPHONEBOOKENTRYPROC g_pRasEditPhonebookEntry=NULL;
  39. #define DEF_HANGUP_WAIT 10 // Seconds
  40. // --------------------------------------------------------------------------------
  41. // Make our code look prettier
  42. // --------------------------------------------------------------------------------
  43. #undef RasDial
  44. #undef RasEnumConnections
  45. #undef RasEnumEntries
  46. #undef RasGetConnectStatus
  47. #undef RasGetErrorString
  48. #undef RasHangup
  49. #undef RasSetEntryDialParams
  50. #undef RasGetEntryDialParams
  51. #undef RasCreatePhonebookEntry
  52. #undef RasEditPhonebookEntry
  53. #define RasDial (*g_pRasDial)
  54. #define RasEnumConnections (*g_pRasEnumConnections)
  55. #define RasEnumEntries (*g_pRasEnumEntries)
  56. #define RasGetConnectStatus (*g_pRasGetConnectStatus)
  57. #define RasGetErrorString (*g_pRasGetErrorString)
  58. #define RasHangup (*g_pRasHangup)
  59. #define RasSetEntryDialParams (*g_pRasSetEntryDialParams)
  60. #define RasGetEntryDialParams (*g_pRasGetEntryDialParams)
  61. #define RasCreatePhonebookEntry (*g_pRasCreatePhonebookEntry)
  62. #define RasEditPhonebookEntry (*g_pRasEditPhonebookEntry)
  63. // --------------------------------------------------------------------------------
  64. // HrLoadRAS
  65. // --------------------------------------------------------------------------------
  66. HRESULT HrLoadRAS(void)
  67. {
  68. // Locals
  69. HRESULT hr=S_OK;
  70. UINT uOldErrorMode;
  71. // Thread Safety
  72. EnterCriticalSection(&g_csRAS);
  73. // If dll is loaded, lets verify all of my function pointers
  74. if (g_hinstRAS)
  75. goto exit;
  76. // Bug #20573 - Let's do a little voodoo here. On NT, it appears that they
  77. // have a key in the registry to show which protocols are
  78. // supported by RAS service. AKA - if this key doesn't exist,
  79. // then RAS isn't installed. This may enable us to avoid some
  80. // special bugs when RAS get's uninstalled on NT.
  81. OSVERSIONINFO os;
  82. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  83. GetVersionEx(&os);
  84. if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
  85. {
  86. HKEY hKey;
  87. const TCHAR c_szRegKeyRAS[] = TEXT("SOFTWARE\\Microsoft\\RAS");
  88. if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyRAS, 0, KEY_READ, &hKey))
  89. {
  90. hr = TrapError(IXP_E_RAS_NOT_INSTALLED);
  91. goto exit;
  92. }
  93. RegCloseKey(hKey);
  94. }
  95. // Try loading RAS
  96. uOldErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX);
  97. g_hinstRAS = LoadLibraryA("RASAPI32.DLL");
  98. SetErrorMode(uOldErrorMode);
  99. // Failure ?
  100. if (NULL == g_hinstRAS)
  101. {
  102. hr = TrapError(IXP_E_RAS_NOT_INSTALLED);
  103. goto exit;
  104. }
  105. // Did we load it
  106. g_pRasDial = (RASDIALPROC)GetProcAddress(g_hinstRAS, c_szRasDial);
  107. g_pRasEnumConnections = (RASENUMCONNECTIONSPROC)GetProcAddress(g_hinstRAS, c_szRasEnumConnections);
  108. g_pRasEnumEntries = (RASENUMENTRIESPROC)GetProcAddress(g_hinstRAS, c_szRasEnumEntries);
  109. g_pRasGetConnectStatus = (RASGETCONNECTSTATUSPROC)GetProcAddress(g_hinstRAS, c_szRasGetConnectStatus);
  110. g_pRasGetErrorString = (RASGETERRORSTRINGPROC)GetProcAddress(g_hinstRAS, c_szRasGetErrorString);
  111. g_pRasHangup = (RASHANGUPPROC)GetProcAddress(g_hinstRAS, c_szRasHangup);
  112. g_pRasSetEntryDialParams = (RASSETENTRYDIALPARAMSPROC)GetProcAddress(g_hinstRAS, c_szRasSetEntryDialParams);
  113. g_pRasGetEntryDialParams = (RASGETENTRYDIALPARAMSPROC)GetProcAddress(g_hinstRAS, c_szRasGetEntryDialParams);
  114. g_pRasCreatePhonebookEntry = (RASCREATEPHONEBOOKENTRYPROC)GetProcAddress(g_hinstRAS, c_szRasCreatePhonebookEntry);
  115. g_pRasEditPhonebookEntry = (RASEDITPHONEBOOKENTRYPROC)GetProcAddress(g_hinstRAS, c_szRasEditPhonebookEntry);
  116. // Make sure all functions have been loaded
  117. if (g_pRasDial &&
  118. g_pRasEnumConnections &&
  119. g_pRasEnumEntries &&
  120. g_pRasGetConnectStatus &&
  121. g_pRasGetErrorString &&
  122. g_pRasHangup &&
  123. g_pRasSetEntryDialParams &&
  124. g_pRasGetEntryDialParams &&
  125. g_pRasCreatePhonebookEntry &&
  126. g_pRasEditPhonebookEntry)
  127. goto exit;
  128. // Failure...
  129. hr = TrapError(IXP_E_RAS_PROCS_NOT_FOUND);
  130. exit:
  131. // Thread Safety
  132. LeaveCriticalSection(&g_csRAS);
  133. // Done
  134. return hr;
  135. }
  136. // --------------------------------------------------------------------------------
  137. // CRASTransport::CRASTransport
  138. // --------------------------------------------------------------------------------
  139. CRASTransport::CRASTransport(void)
  140. {
  141. DllAddRef();
  142. m_cRef = 1;
  143. m_pCallback = NULL;
  144. *m_szConnectoid = '\0';
  145. m_hConn = NULL;
  146. m_fConnOwner = FALSE;
  147. m_hwndRAS = NULL;
  148. m_uRASMsg = 0;
  149. ZeroMemory(&m_rServer, sizeof(INETSERVER));
  150. ZeroMemory(&m_rDialParams, sizeof(RASDIALPARAMS));
  151. InitializeCriticalSection(&m_cs);
  152. }
  153. // --------------------------------------------------------------------------------
  154. // CRASTransport::~CRASTransport
  155. // --------------------------------------------------------------------------------
  156. CRASTransport::~CRASTransport(void)
  157. {
  158. EnterCriticalSection(&m_cs);
  159. ZeroMemory(&m_rServer, sizeof(INETSERVER));
  160. SafeRelease(m_pCallback);
  161. *m_szConnectoid = '\0';
  162. m_hConn = NULL;
  163. if (m_hwndRAS)
  164. DestroyWindow(m_hwndRAS);
  165. LeaveCriticalSection(&m_cs);
  166. DeleteCriticalSection(&m_cs);
  167. DllRelease();
  168. }
  169. // --------------------------------------------------------------------------------
  170. // CRASTransport::QueryInterface
  171. // --------------------------------------------------------------------------------
  172. STDMETHODIMP CRASTransport::QueryInterface(REFIID riid, LPVOID *ppv)
  173. {
  174. // Locals
  175. HRESULT hr=S_OK;
  176. // Bad param
  177. if (ppv == NULL)
  178. {
  179. hr = TrapError(E_INVALIDARG);
  180. goto exit;
  181. }
  182. // Init
  183. *ppv=NULL;
  184. // IID_IUnknown
  185. if (IID_IUnknown == riid)
  186. *ppv = ((IUnknown *)this);
  187. // IID_IInternetTransport
  188. else if (IID_IInternetTransport == riid)
  189. *ppv = ((IInternetTransport *)this);
  190. // IID_IRASTransport
  191. else if (IID_IRASTransport == riid)
  192. *ppv = (IRASTransport *)this;
  193. // If not null, addref it and return
  194. if (NULL != *ppv)
  195. {
  196. ((LPUNKNOWN)*ppv)->AddRef();
  197. goto exit;
  198. }
  199. // No Interface
  200. hr = TrapError(E_NOINTERFACE);
  201. exit:
  202. // Done
  203. return hr;
  204. }
  205. // --------------------------------------------------------------------------------
  206. // CRASTransport::QueryInterface
  207. // --------------------------------------------------------------------------------
  208. STDMETHODIMP_(ULONG) CRASTransport::AddRef(void)
  209. {
  210. return ++m_cRef;
  211. }
  212. // --------------------------------------------------------------------------------
  213. // CRASTransport::QueryInterface
  214. // --------------------------------------------------------------------------------
  215. STDMETHODIMP_(ULONG) CRASTransport::Release(void)
  216. {
  217. if (0 != --m_cRef)
  218. return m_cRef;
  219. delete this;
  220. return 0;
  221. }
  222. // --------------------------------------------------------------------------------
  223. // CRASTransport::HandsOffCallback
  224. // --------------------------------------------------------------------------------
  225. STDMETHODIMP CRASTransport::HandsOffCallback(void)
  226. {
  227. // Locals
  228. HRESULT hr=S_OK;
  229. // Thread Safety
  230. EnterCriticalSection(&m_cs);
  231. // No current callback
  232. if (NULL == m_pCallback)
  233. {
  234. hr = TrapError(S_FALSE);
  235. goto exit;
  236. }
  237. // Release it
  238. SafeRelease(m_pCallback);
  239. exit:
  240. // Thread Safety
  241. LeaveCriticalSection(&m_cs);
  242. // Done
  243. return hr;
  244. }
  245. // --------------------------------------------------------------------------------
  246. // CRASTransport::InitNew
  247. // --------------------------------------------------------------------------------
  248. STDMETHODIMP CRASTransport::InitNew(IRASCallback *pCallback)
  249. {
  250. // Locals
  251. HRESULT hr=S_OK;
  252. // check params
  253. if (NULL == pCallback)
  254. return TrapError(E_INVALIDARG);
  255. // Thread Safety
  256. EnterCriticalSection(&m_cs);
  257. // Release current callback
  258. SafeRelease(m_pCallback);
  259. // Assume new callback
  260. m_pCallback = pCallback;
  261. m_pCallback->AddRef();
  262. // Have I Create my modeless window for RAS connections yet?
  263. if (NULL == m_hwndRAS)
  264. {
  265. // Create Modeless Window
  266. m_hwndRAS = CreateDialogParam(g_hLocRes, MAKEINTRESOURCE(IDD_RASCONNECT), NULL, RASConnectDlgProc, (LPARAM)this);
  267. if (NULL == m_hwndRAS)
  268. {
  269. hr = TrapError(E_FAIL);
  270. goto exit;
  271. }
  272. // Get registered RAS event message id
  273. m_uRASMsg = RegisterWindowMessageA(RASDIALEVENT);
  274. if (m_uRASMsg == 0)
  275. m_uRASMsg = WM_RASDIALEVENT;
  276. }
  277. exit:
  278. // Thread Safety
  279. LeaveCriticalSection(&m_cs);
  280. // Done
  281. return hr;
  282. }
  283. // --------------------------------------------------------------------------------
  284. // CRASTransport::GetCurrentConnectoid
  285. // --------------------------------------------------------------------------------
  286. STDMETHODIMP CRASTransport::GetCurrentConnectoid(LPSTR pszConnectoid, ULONG cchMax)
  287. {
  288. // Locals
  289. HRESULT hr=S_OK;
  290. LPRASCONN prgConnection=NULL;
  291. DWORD cConnection;
  292. // Invalid Arg
  293. if (NULL == pszConnectoid || cchMax < CCHMAX_CONNECTOID)
  294. return TrapError(E_INVALIDARG);
  295. // Thread Safety
  296. EnterCriticalSection(&m_cs);
  297. // Get Current RAS Connection
  298. if (FEnumerateConnections(&prgConnection, &cConnection) == 0 || 0 == cConnection)
  299. {
  300. hr = IXP_E_NOT_CONNECTED;
  301. goto exit;
  302. }
  303. // Is there at l
  304. StrCpyN(pszConnectoid, prgConnection[0].szEntryName, cchMax);
  305. exit:
  306. // Cleanup
  307. SafeMemFree(prgConnection);
  308. // Thread Safety
  309. LeaveCriticalSection(&m_cs);
  310. // Done
  311. return hr;
  312. }
  313. // --------------------------------------------------------------------------------
  314. // CRASTransport::Connect
  315. // --------------------------------------------------------------------------------
  316. STDMETHODIMP CRASTransport::Connect(LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging)
  317. {
  318. // Locals
  319. HRESULT hr=S_OK;
  320. LPRASCONN prgConn=NULL;
  321. DWORD cConn,
  322. dwError;
  323. // check params
  324. if (NULL == pInetServer)
  325. return TrapError(E_INVALIDARG);
  326. // RAS_CONNECT_RAS ?
  327. if (RAS_CONNECT_RAS != pInetServer->rasconntype)
  328. return IXP_S_RAS_NOT_NEEDED;
  329. // Empty Connectoid
  330. if (FIsEmptyA(pInetServer->szConnectoid))
  331. return TrapError(IXP_E_RAS_INVALID_CONNECTOID);
  332. // Thread Safety
  333. EnterCriticalSection(&m_cs);
  334. // Initialized
  335. if (NULL == m_pCallback)
  336. {
  337. hr = TrapError(IXP_E_NOT_INIT);
  338. goto exit;
  339. }
  340. // LoadRAS
  341. CHECKHR(hr = HrLoadRAS());
  342. // Save pInetServer
  343. CopyMemory(&m_rServer, pInetServer, sizeof(INETSERVER));
  344. // No Current Known Connection
  345. if (NULL == m_hConn)
  346. {
  347. // Get Current RAS Connection
  348. if (FEnumerateConnections(&prgConn, &cConn) && cConn > 0)
  349. {
  350. m_fConnOwner = FALSE;
  351. m_hConn = prgConn[0].hrasconn;
  352. StrCpyN(m_szConnectoid, prgConn[0].szEntryName, ARRAYSIZE(m_szConnectoid));
  353. }
  354. }
  355. // Otherwise, verify the connection status
  356. else
  357. {
  358. // Locals
  359. RASCONNSTATUS rcs;
  360. // Get Connection Status
  361. rcs.dwSize = sizeof(RASCONNSTATUS);
  362. dwError = RasGetConnectStatus(m_hConn, &rcs);
  363. if (dwError || rcs.dwError || RASCS_Disconnected == rcs.rasconnstate)
  364. {
  365. m_fConnOwner = FALSE;
  366. m_hConn = NULL;
  367. *m_szConnectoid = '\0';
  368. }
  369. }
  370. // If RAS Connection present, is it equal to suggested
  371. if (m_hConn)
  372. {
  373. // Better have a connectoid
  374. Assert(*m_szConnectoid);
  375. // Current connection is what I want ?
  376. if (lstrcmpi(m_szConnectoid, m_rServer.szConnectoid) == 0)
  377. {
  378. m_pCallback->OnRasDialStatus(RASCS_Connected, 0, this);
  379. hr = IXP_S_RAS_USING_CURRENT;
  380. goto exit;
  381. }
  382. // Otherwise, if we didn't start the RAS connection...
  383. else if (FALSE == m_fConnOwner)
  384. {
  385. // Prompt to Close un-owner current connection...
  386. hr = m_pCallback->OnReconnect(m_szConnectoid, m_rServer.szConnectoid, this);
  387. // Cancel ?
  388. if (IXP_E_USER_CANCEL == hr)
  389. goto exit;
  390. // Use Current Connection...
  391. else if (S_FALSE == hr)
  392. {
  393. hr = IXP_S_RAS_USING_CURRENT;
  394. goto exit;
  395. }
  396. // Close Current ?
  397. else
  398. {
  399. FRasHangupAndWait(DEF_HANGUP_WAIT);
  400. }
  401. }
  402. // Otherwise, I started the connection, so close it
  403. else if (m_fConnOwner == TRUE)
  404. {
  405. FRasHangupAndWait(DEF_HANGUP_WAIT);
  406. }
  407. }
  408. // We probably shouldn't have a connection handle at this point
  409. Assert(m_hConn == NULL);
  410. // Dial the connection
  411. CHECKHR(hr = HrStartRasDial());
  412. // If Synchronous -- Woo - hoo were connected and we started the connection
  413. m_fConnOwner = TRUE;
  414. StrCpyN(m_szConnectoid, m_rServer.szConnectoid, ARRAYSIZE(m_szConnectoid));
  415. exit:
  416. // Cleanup
  417. SafeMemFree(prgConn);
  418. // Thread Safety
  419. LeaveCriticalSection(&m_cs);
  420. // Done
  421. return hr;
  422. }
  423. // --------------------------------------------------------------------------------
  424. // CRASTransport::HrStartRasDial
  425. // --------------------------------------------------------------------------------
  426. HRESULT CRASTransport::HrStartRasDial(void)
  427. {
  428. // Locals
  429. HRESULT hr=S_OK;
  430. BOOL fRetry=FALSE;
  431. DWORD dwError;
  432. // Prompt for while
  433. while(1)
  434. {
  435. // Logon first ?
  436. hr = HrLogon(fRetry);
  437. if (FAILED(hr))
  438. goto exit;
  439. // If Succeeded
  440. #ifndef WIN16
  441. dwError = RasDial(NULL, NULL, &m_rDialParams, 0xFFFFFFFF, m_hwndRAS, &m_hConn);
  442. #else
  443. dwError = RasDial(NULL, NULL, &m_rDialParams, 0xFFFFFFFF, (LPVOID)m_hwndRAS, &m_hConn);
  444. #endif
  445. if (dwError == 0)
  446. break;
  447. // Lets feed the user the error
  448. m_pCallback->OnRasDialStatus(RASCS_Disconnected, dwError, this);
  449. // Retry Logon
  450. fRetry = TRUE;
  451. }
  452. exit:
  453. // Done
  454. return hr;
  455. }
  456. // --------------------------------------------------------------------------------
  457. // CRASTransport::RASConnectDlgProc
  458. // --------------------------------------------------------------------------------
  459. INT_PTR CALLBACK CRASTransport::RASConnectDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  460. {
  461. // Locals
  462. CRASTransport *pTransport=(CRASTransport *)GetWndThisPtr(hwnd);
  463. switch (uMsg)
  464. {
  465. case WM_INITDIALOG:
  466. pTransport = (CRASTransport *)lParam;
  467. Assert(pTransport);
  468. SetWndThisPtr(hwnd, pTransport);
  469. return 0;
  470. case WM_DESTROY:
  471. SetWndThisPtr(hwnd, NULL);
  472. break;
  473. default:
  474. if (NULL != pTransport)
  475. {
  476. // Thread Safety
  477. EnterCriticalSection(&pTransport->m_cs);
  478. // Our Message
  479. if (NULL != pTransport->m_pCallback && uMsg == pTransport->m_uRASMsg)
  480. {
  481. // Handle Error
  482. if (lParam)
  483. {
  484. // Hangup
  485. if (pTransport->m_hConn)
  486. pTransport->FRasHangupAndWait(DEF_HANGUP_WAIT);
  487. }
  488. // Give to callback
  489. pTransport->m_pCallback->OnRasDialStatus((RASCONNSTATE)wParam, (DWORD) lParam, pTransport);
  490. }
  491. // thread Safety
  492. LeaveCriticalSection(&pTransport->m_cs);
  493. }
  494. }
  495. // Done
  496. return 0;
  497. }
  498. // --------------------------------------------------------------------------------
  499. // CRASTransport::HrLogon
  500. // --------------------------------------------------------------------------------
  501. HRESULT CRASTransport::HrLogon(BOOL fForcePrompt)
  502. {
  503. // Locals
  504. HRESULT hr=S_OK;
  505. DWORD dwRasError;
  506. BOOL fSavePassword;
  507. // Do we need to prompt for logon information first ?
  508. ZeroMemory(&m_rDialParams, sizeof(RASDIALPARAMS));
  509. m_rDialParams.dwSize = sizeof(RASDIALPARAMS);
  510. Assert(sizeof(m_rDialParams.szEntryName) >= sizeof(m_rServer.szConnectoid));
  511. StrCpyN(m_rDialParams.szEntryName, m_rServer.szConnectoid, sizeof(m_rDialParams.szEntryName));
  512. // Get params
  513. dwRasError = RasGetEntryDialParams(NULL, &m_rDialParams, &fSavePassword);
  514. if (dwRasError)
  515. {
  516. hr = TrapError(IXP_E_RAS_GET_DIAL_PARAMS);
  517. goto exit;
  518. }
  519. // Do we need to get password / account information
  520. if (fForcePrompt ||
  521. !fSavePassword ||
  522. FIsEmpty(m_rDialParams.szUserName) ||
  523. FIsEmpty(m_rDialParams.szPassword))
  524. {
  525. // Locals
  526. IXPRASLOGON rLogon;
  527. // Init
  528. ZeroMemory(&rLogon, sizeof(IXPRASLOGON));
  529. // Fill Logon Data...
  530. StrCpyN(rLogon.szConnectoid, m_rDialParams.szEntryName, ARRAYSIZE(rLogon.szConnectoid));
  531. StrCpyN(rLogon.szUserName, m_rDialParams.szUserName, ARRAYSIZE(rLogon.szUserName));
  532. StrCpyN(rLogon.szPassword, m_rDialParams.szPassword, ARRAYSIZE(rLogon.szPassword));
  533. StrCpyN(rLogon.szDomain, m_rDialParams.szDomain, ARRAYSIZE(rLogon.szDomain));
  534. StrCpyN(rLogon.szPhoneNumber, m_rDialParams.szPhoneNumber, ARRAYSIZE(rLogon.szPhoneNumber));
  535. rLogon.fSavePassword = fSavePassword;
  536. // Prompt
  537. hr = m_pCallback->OnLogonPrompt(&rLogon, this);
  538. // If OK, lets save the settings
  539. if (S_OK == hr)
  540. {
  541. // Copy parameters back
  542. StrCpyN(m_rDialParams.szUserName, rLogon.szUserName, ARRAYSIZE(m_rDialParams.szUserName));
  543. StrCpyN(m_rDialParams.szPassword, rLogon.szPassword, ARRAYSIZE(m_rDialParams.szPassword));
  544. StrCpyN(m_rDialParams.szDomain, rLogon.szDomain, ARRAYSIZE(m_rDialParams.szDomain));
  545. StrCpyN(m_rDialParams.szPhoneNumber, rLogon.szPhoneNumber, ARRAYSIZE(m_rDialParams.szPhoneNumber));
  546. // Save the dial params
  547. if (RasSetEntryDialParams(NULL, &m_rDialParams, !rLogon.fSavePassword))
  548. {
  549. Assert(FALSE);
  550. TrapError(E_FAIL);
  551. }
  552. }
  553. // RAID-26845 - RAS Transport: Canceling RAS Logon doesn't cancel
  554. else
  555. {
  556. hr = TrapError(IXP_E_USER_CANCEL);
  557. goto exit;
  558. }
  559. }
  560. exit:
  561. // Done
  562. return hr;
  563. }
  564. // --------------------------------------------------------------------------------
  565. // CRASTransport::DropConnection
  566. // --------------------------------------------------------------------------------
  567. STDMETHODIMP CRASTransport::DropConnection(void)
  568. {
  569. // Thread Safety
  570. EnterCriticalSection(&m_cs);
  571. // Hangup
  572. if (m_hConn)
  573. FRasHangupAndWait(DEF_HANGUP_WAIT);
  574. // Thread Safety
  575. LeaveCriticalSection(&m_cs);
  576. // Done
  577. return S_OK;
  578. }
  579. // --------------------------------------------------------------------------------
  580. // CRASTransport::Disconnect
  581. // --------------------------------------------------------------------------------
  582. STDMETHODIMP CRASTransport::Disconnect(void)
  583. {
  584. // Locals
  585. HRESULT hr=S_OK;
  586. // Thread Safety
  587. EnterCriticalSection(&m_cs);
  588. // If not using RAS, who give a crap
  589. if (RAS_CONNECT_RAS != m_rServer.rasconntype)
  590. {
  591. Assert(m_hConn == NULL);
  592. Assert(m_fConnOwner == FALSE);
  593. goto exit;
  594. }
  595. // Do we have a RAS connection
  596. if (m_hConn)
  597. {
  598. if (m_pCallback->OnDisconnect(m_szConnectoid, (boolean) !!m_fConnOwner, this) == S_OK)
  599. FRasHangupAndWait(DEF_HANGUP_WAIT);
  600. }
  601. // Pretend the connection is owned by the user
  602. m_hConn = NULL;
  603. m_fConnOwner = FALSE;
  604. exit:
  605. // Thread Safety
  606. LeaveCriticalSection(&m_cs);
  607. // Done
  608. return hr;
  609. }
  610. // --------------------------------------------------------------------------------
  611. // CRASTransport::IsState
  612. // --------------------------------------------------------------------------------
  613. STDMETHODIMP CRASTransport::IsState(IXPISSTATE isstate)
  614. {
  615. // Locals
  616. HRESULT hr=S_FALSE;
  617. // Thread Safety
  618. EnterCriticalSection(&m_cs);
  619. // Initialized
  620. if (NULL == m_pCallback)
  621. {
  622. hr = TrapError(IXP_E_NOT_INIT);
  623. goto exit;
  624. }
  625. // Lets validate m_hConn first
  626. if (NULL != m_hConn)
  627. {
  628. // Get Connection Status
  629. RASCONNSTATUS rcs;
  630. DWORD dwError;
  631. // Setup Structure Size
  632. rcs.dwSize = sizeof(RASCONNSTATUS);
  633. // Get Ras Connection Status
  634. dwError = RasGetConnectStatus(m_hConn, &rcs);
  635. // Failure or not connected
  636. if (dwError || rcs.dwError || RASCS_Disconnected == rcs.rasconnstate)
  637. {
  638. m_fConnOwner = FALSE;
  639. m_hConn = NULL;
  640. *m_szConnectoid = '\0';
  641. }
  642. }
  643. // Handle IsType
  644. switch(isstate)
  645. {
  646. // Are we connected
  647. case IXP_IS_CONNECTED:
  648. hr = (m_hConn) ? S_OK : S_FALSE;
  649. break;
  650. // Are we busy
  651. case IXP_IS_BUSY:
  652. if (NULL == m_hConn)
  653. hr = IXP_E_NOT_CONNECTED;
  654. else
  655. hr = S_FALSE;
  656. break;
  657. // Are we busy
  658. case IXP_IS_READY:
  659. if (NULL == m_hConn)
  660. hr = IXP_E_NOT_CONNECTED;
  661. else
  662. hr = S_OK;
  663. break;
  664. // Have we been authenticated yet
  665. case IXP_IS_AUTHENTICATED:
  666. if (NULL == m_hConn)
  667. hr = IXP_E_NOT_CONNECTED;
  668. else
  669. hr = S_OK;
  670. break;
  671. // Unhandled ixpistype
  672. default:
  673. IxpAssert(FALSE);
  674. break;
  675. }
  676. exit:
  677. // Thread Safety
  678. LeaveCriticalSection(&m_cs);
  679. // Done
  680. return hr;
  681. }
  682. // --------------------------------------------------------------------------------
  683. // CRASTransport::GetServerInfo
  684. // --------------------------------------------------------------------------------
  685. STDMETHODIMP CRASTransport::GetServerInfo(LPINETSERVER pInetServer)
  686. {
  687. // check params
  688. if (NULL == pInetServer)
  689. return TrapError(E_INVALIDARG);
  690. // Thread Safety
  691. EnterCriticalSection(&m_cs);
  692. // Copy Server information
  693. CopyMemory(pInetServer, &m_rServer, sizeof(INETSERVER));
  694. // Thread Safety
  695. LeaveCriticalSection(&m_cs);
  696. // Done
  697. return S_OK;
  698. }
  699. // --------------------------------------------------------------------------------
  700. // CRASTransport::GetIXPType
  701. // --------------------------------------------------------------------------------
  702. STDMETHODIMP_(IXPTYPE) CRASTransport::GetIXPType(void)
  703. {
  704. return IXP_RAS;
  705. }
  706. // --------------------------------------------------------------------------------
  707. // CRASTransport::InetServerFromAccount
  708. // --------------------------------------------------------------------------------
  709. STDMETHODIMP CRASTransport::InetServerFromAccount(IImnAccount *pAccount, LPINETSERVER pInetServer)
  710. {
  711. return E_NOTIMPL;
  712. }
  713. // --------------------------------------------------------------------------------
  714. // CRASTransport::FEnumerateConnections
  715. // --------------------------------------------------------------------------------
  716. BOOL CRASTransport::FEnumerateConnections(LPRASCONN *pprgConn, ULONG *pcConn)
  717. {
  718. // Locals
  719. HRESULT hr=S_OK;
  720. DWORD dw,
  721. dwSize;
  722. BOOL fResult=FALSE;
  723. // Check Params
  724. Assert(pprgConn && pcConn);
  725. // Init
  726. *pprgConn = NULL;
  727. *pcConn = 0;
  728. // Sizeof my buffer
  729. dwSize = sizeof(RASCONN);
  730. // Allocate enough for 1 ras connection info object
  731. CHECKHR(hr = HrAlloc((LPVOID *)pprgConn, dwSize));
  732. // Buffer size
  733. (*pprgConn)->dwSize = dwSize;
  734. // Enumerate ras connections
  735. dw = RasEnumConnections(*pprgConn, &dwSize, pcConn);
  736. // Not enough memory ?
  737. if (dw == ERROR_BUFFER_TOO_SMALL)
  738. {
  739. // Reallocate
  740. CHECKHR(hr = HrRealloc((LPVOID *)pprgConn, dwSize));
  741. *pcConn = 0;
  742. (*pprgConn)->dwSize = sizeof(RASCONN);
  743. dw = RasEnumConnections(*pprgConn, &dwSize, pcConn);
  744. }
  745. // If still failed
  746. if (dw)
  747. {
  748. AssertSz(FALSE, "RasEnumConnections failed");
  749. goto exit;
  750. }
  751. // Success
  752. fResult = TRUE;
  753. exit:
  754. // Done
  755. return fResult;
  756. }
  757. // --------------------------------------------------------------------------------
  758. // CRASTransport::FFindConnection
  759. // --------------------------------------------------------------------------------
  760. BOOL CRASTransport::FFindConnection(LPSTR pszConnectoid, LPHRASCONN phConn)
  761. {
  762. // Locals
  763. ULONG cConn,
  764. i;
  765. LPRASCONN prgConn=NULL;
  766. BOOL fResult=FALSE;
  767. // Check Params
  768. Assert(pszConnectoid && phConn);
  769. // Init
  770. *phConn = NULL;
  771. // Enumerate Connections
  772. if (!FEnumerateConnections(&prgConn, &cConn))
  773. goto exit;
  774. // If still failed
  775. for (i=0; i<cConn; i++)
  776. {
  777. if (lstrcmpi(prgConn[i].szEntryName, pszConnectoid) == 0)
  778. {
  779. *phConn = prgConn[i].hrasconn;
  780. fResult = TRUE;
  781. goto exit;
  782. }
  783. }
  784. exit:
  785. // Cleanup
  786. SafeMemFree(prgConn);
  787. // Done
  788. return fResult;
  789. }
  790. // --------------------------------------------------------------------------------
  791. // CRASTransport::FRasHangupAndWait
  792. // --------------------------------------------------------------------------------
  793. BOOL CRASTransport::FRasHangupAndWait(DWORD dwMaxWaitSeconds)
  794. {
  795. // Locals
  796. RASCONNSTATUS rcs;
  797. DWORD dwTicks=GetTickCount();
  798. // Check Params
  799. Assert(m_hConn);
  800. if (NULL == m_hConn || RasHangup(m_hConn))
  801. {
  802. m_hConn = NULL;
  803. m_fConnOwner = FALSE;
  804. *m_szConnectoid = '\0';
  805. return FALSE;
  806. }
  807. // Wait for connection to really close
  808. ZeroMemory(&rcs, sizeof(RASCONNSTATUS));
  809. rcs.dwSize = sizeof(RASCONNSTATUS);
  810. while (RasGetConnectStatus(m_hConn, &rcs) == 0 && rcs.rasconnstate != RASCS_Disconnected)
  811. {
  812. // Wait timeout
  813. if (GetTickCount() - dwTicks >= dwMaxWaitSeconds * 1000)
  814. break;
  815. // Sleep and yields
  816. Sleep(0);
  817. }
  818. // Wait 2 seconds for modem to reset
  819. Sleep(2000);
  820. // Reset
  821. m_hConn = NULL;
  822. m_fConnOwner = FALSE;
  823. *m_szConnectoid = '\0';
  824. // Done
  825. return TRUE;
  826. }
  827. // --------------------------------------------------------------------------------
  828. // CRASTransport::FillConnectoidCombo
  829. // --------------------------------------------------------------------------------
  830. STDMETHODIMP CRASTransport::FillConnectoidCombo(HWND hwndComboBox, boolean fUpdateOnly, DWORD *pdwRASResult)
  831. {
  832. // Locals
  833. HRESULT hr=S_OK;
  834. // check params
  835. if (NULL == hwndComboBox || FALSE == IsWindow(hwndComboBox))
  836. return TrapError(E_INVALIDARG);
  837. // Thread Safety
  838. EnterCriticalSection(&m_cs);
  839. // Call global function
  840. CHECKHR(hr = HrFillRasCombo(hwndComboBox, fUpdateOnly, pdwRASResult));
  841. exit:
  842. // Thread Safety
  843. LeaveCriticalSection(&m_cs);
  844. // Done
  845. return hr;
  846. }
  847. // --------------------------------------------------------------------------------
  848. // CRASTransport::EditConnectoid
  849. // --------------------------------------------------------------------------------
  850. STDMETHODIMP CRASTransport::EditConnectoid(HWND hwndParent, LPSTR pszConnectoid, DWORD *pdwRASResult)
  851. {
  852. // Locals
  853. HRESULT hr=S_OK;
  854. // check params
  855. if (NULL == pszConnectoid)
  856. return TrapError(E_INVALIDARG);
  857. // Thread Safety
  858. EnterCriticalSection(&m_cs);
  859. // Call general function
  860. CHECKHR(hr = HrEditPhonebookEntry(hwndParent, pszConnectoid, pdwRASResult));
  861. exit:
  862. // Thread Safety
  863. LeaveCriticalSection(&m_cs);
  864. // Done
  865. return hr;
  866. }
  867. // --------------------------------------------------------------------------------
  868. // CRASTransport::GetRasErrorString
  869. // --------------------------------------------------------------------------------
  870. STDMETHODIMP CRASTransport::GetRasErrorString(UINT uRasErrorValue, LPSTR pszErrorString, ULONG cchMax, DWORD *pdwRASResult)
  871. {
  872. // Locals
  873. HRESULT hr=S_OK;
  874. // check params
  875. if (NULL == pdwRASResult || 0 == uRasErrorValue || NULL == pszErrorString || cchMax <= 1)
  876. return TrapError(E_INVALIDARG);
  877. // Thread Safety
  878. EnterCriticalSection(&m_cs);
  879. // Make Sure RAS is Loaded
  880. CHECKHR(hr = HrLoadRAS());
  881. // Call RAS Function
  882. *pdwRASResult = RasGetErrorString(uRasErrorValue, pszErrorString, cchMax);
  883. if (*pdwRASResult)
  884. {
  885. hr = TrapError(IXP_E_RAS_ERROR);
  886. goto exit;
  887. }
  888. exit:
  889. // Thread Safety
  890. LeaveCriticalSection(&m_cs);
  891. // Done
  892. return hr;
  893. }
  894. // --------------------------------------------------------------------------------
  895. // CRASTransport::CreateConnectoid
  896. // --------------------------------------------------------------------------------
  897. STDMETHODIMP CRASTransport::CreateConnectoid(HWND hwndParent, DWORD *pdwRASResult)
  898. {
  899. // Locals
  900. HRESULT hr=S_OK;
  901. // Thread Safety
  902. EnterCriticalSection(&m_cs);
  903. // Call General Function
  904. CHECKHR(hr = HrCreatePhonebookEntry(hwndParent, pdwRASResult));
  905. exit:
  906. // Thread Safety
  907. LeaveCriticalSection(&m_cs);
  908. // Done
  909. return hr;
  910. }