Source code of Windows XP (NT5)
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.

1365 lines
32 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: CONTABLE.CPP
  4. //
  5. // Module: CMCONTBL.LIB
  6. //
  7. // Synopsis: Implements the CM connection table (CConnectionTable). The connection
  8. // table is a list of active conenctions stored in a (memory only) memory
  9. // mapped file, and shared by the various CM components in order to
  10. // manage CM connections.
  11. //
  12. // Copyright (c) 1998-1999 Microsoft Corporation
  13. //
  14. // Author: nickball Created 02/02/98
  15. //
  16. //+----------------------------------------------------------------------------
  17. #include <windows.h>
  18. #include "contable.h"
  19. #include "cmdebug.h"
  20. #include "cmutil.h"
  21. #include "uapi.h"
  22. #include "setacl.h"
  23. #if 0
  24. #include "DumpSecInfo.cpp"
  25. #endif
  26. #define CONN_TABLE_NAME TEXT("CmConnectionTable")
  27. #define CONN_TABLE_OPEN TEXT("CmConnectionOpen")
  28. static const int MAX_LOCK_WAIT = 1000; // wait timeout in milliseconds
  29. //
  30. // Constructor and destructor
  31. //
  32. CConnectionTable::CConnectionTable()
  33. {
  34. CMTRACE(TEXT("CConnectionTable::CConnectionTable()"));
  35. //
  36. // Initialize our data members
  37. //
  38. m_hMap = NULL;
  39. m_pConnTable = NULL;
  40. m_fLocked = FALSE;
  41. m_hEvent = NULL;
  42. }
  43. CConnectionTable::~CConnectionTable()
  44. {
  45. CMTRACE(TEXT("CConnectionTable::~CConnectionTable()"));
  46. //
  47. // Data should have been cleaned up in Close, etc. Double-Check
  48. //
  49. MYDBGASSERT(NULL == m_pConnTable);
  50. MYDBGASSERT(NULL == m_hMap);
  51. MYDBGASSERT(FALSE == m_fLocked);
  52. MYDBGASSERT(NULL == m_hEvent);
  53. //
  54. // Release handles and pointers
  55. //
  56. if (m_pConnTable)
  57. {
  58. MYVERIFY(NULL != UnmapViewOfFile(m_pConnTable));
  59. m_pConnTable = NULL;
  60. }
  61. if (m_hMap)
  62. {
  63. MYVERIFY(NULL != CloseHandle(m_hMap));
  64. m_hMap = NULL;
  65. }
  66. if (m_hEvent)
  67. {
  68. MYVERIFY(NULL != CloseHandle(m_hEvent));
  69. m_hEvent = NULL;
  70. }
  71. }
  72. //+----------------------------------------------------------------------------
  73. //
  74. // Function: CConnectionTable::LockTable
  75. //
  76. // Synopsis: Sets the internal lock on the table. Should be called internally
  77. // prior to any table access.
  78. //
  79. // Arguments: None
  80. //
  81. // Returns: HRESULT - Failure code or S_OK
  82. //
  83. // History: nickball Created 2/2/98
  84. //
  85. //+----------------------------------------------------------------------------
  86. HRESULT CConnectionTable::LockTable()
  87. {
  88. MYDBGASSERT(m_pConnTable);
  89. MYDBGASSERT(m_hMap);
  90. MYDBGASSERT(m_hEvent);
  91. CMTRACE(TEXT("CConnectionTable::LockTable()"));
  92. HRESULT hrRet = S_OK;
  93. //
  94. // Validate our current state
  95. //
  96. if (NULL == m_hEvent)
  97. {
  98. MYDBGASSERT(FALSE);
  99. return E_ACCESSDENIED;
  100. }
  101. //
  102. // Wait for the open event to be signaled
  103. //
  104. DWORD dwWait = WaitForSingleObject(m_hEvent, MAX_LOCK_WAIT);
  105. //
  106. // If our records indicate that we are already locked at this point
  107. // then something is wrong within the class implementation
  108. //
  109. MYDBGASSERT(FALSE == m_fLocked); // no double locks please
  110. if (TRUE == m_fLocked)
  111. {
  112. SetEvent(m_hEvent); // cleat the signal that we just set by clearing the wait
  113. return E_ACCESSDENIED;
  114. }
  115. //
  116. // Check the
  117. //
  118. if (WAIT_FAILED == dwWait)
  119. {
  120. MYDBGASSERT(FALSE);
  121. hrRet = GetLastError();
  122. return HRESULT_FROM_WIN32(hrRet);
  123. }
  124. //
  125. // If not signaled, bail
  126. //
  127. MYDBGASSERT(WAIT_OBJECT_0 == dwWait);
  128. if (WAIT_OBJECT_0 != dwWait)
  129. {
  130. if (WAIT_TIMEOUT == dwWait)
  131. {
  132. hrRet = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
  133. }
  134. else
  135. {
  136. hrRet = E_ACCESSDENIED;
  137. }
  138. }
  139. else
  140. {
  141. //
  142. // The event is signaled automatically by virtue of the
  143. // fact that we cleared the wait on the event. Its locked.
  144. //
  145. m_fLocked = TRUE;
  146. }
  147. return hrRet;
  148. }
  149. //+----------------------------------------------------------------------------
  150. //
  151. // Function: CConnectionTable::UnlockTable
  152. //
  153. // Synopsis: Clears the internal lock on the table. Should be cleared
  154. // following any access to the table.
  155. //
  156. // Arguments: None
  157. //
  158. // Returns: HRESULT - Failure code or S_OK
  159. //
  160. // History: nickball Created 2/2/98
  161. //
  162. //+----------------------------------------------------------------------------
  163. HRESULT CConnectionTable::UnlockTable()
  164. {
  165. MYDBGASSERT(m_pConnTable);
  166. MYDBGASSERT(m_hMap);
  167. MYDBGASSERT(m_hEvent);
  168. MYDBGASSERT(TRUE == m_fLocked);
  169. CMTRACE(TEXT("CConnectionTable::UnlockTable()"));
  170. HRESULT hrRet = S_OK;
  171. //
  172. // Validate our current state
  173. //
  174. if (FALSE == m_fLocked || NULL == m_hEvent)
  175. {
  176. return E_ACCESSDENIED;
  177. }
  178. //
  179. // Signal the open event, allowing access
  180. //
  181. if (SetEvent(m_hEvent))
  182. {
  183. m_fLocked = FALSE;
  184. }
  185. else
  186. {
  187. MYDBGASSERT(FALSE);
  188. hrRet = GetLastError();
  189. hrRet = HRESULT_FROM_WIN32(hrRet);
  190. }
  191. return hrRet;
  192. }
  193. //+----------------------------------------------------------------------------
  194. //
  195. // Function: CConnectionTable::FindEntry - pszEntry
  196. //
  197. // Synopsis: Determines the ID (index) of an entry in the table. Table should
  198. // be locked before making this call.
  199. //
  200. // Arguments: LPCTSTR pszEntry - Ptr to the name of the entry we are seeking.
  201. // LPINT piID - Ptr to buffer for ID (index) of connection
  202. //
  203. // Returns: HRESULT - Failure code, or S_OK if piID filled.
  204. //
  205. // History: nickball Created 2/2/98
  206. //
  207. //+----------------------------------------------------------------------------
  208. HRESULT CConnectionTable::FindEntry(LPCTSTR pszEntry, LPINT piID)
  209. {
  210. MYDBGASSERT(m_pConnTable);
  211. MYDBGASSERT(m_hMap);
  212. MYDBGASSERT(pszEntry);
  213. MYDBGASSERT(piID);
  214. MYDBGASSERT(TRUE == m_fLocked);
  215. CMTRACE1(TEXT("CConnectionTable::FindEntry(%s)"), pszEntry);
  216. if (FALSE == m_fLocked || NULL == m_pConnTable)
  217. {
  218. return E_ACCESSDENIED;
  219. }
  220. if (NULL == pszEntry || NULL == piID)
  221. {
  222. return E_POINTER;
  223. }
  224. if (0 == pszEntry[0])
  225. {
  226. return E_INVALIDARG;
  227. }
  228. //
  229. // Look for the entry
  230. //
  231. for (int i = 0; i < MAX_CM_CONNECTIONS; i++)
  232. {
  233. //
  234. // Name compare for a match
  235. //
  236. if (0 == lstrcmpU(pszEntry, m_pConnTable->Connections[i].szEntry))
  237. {
  238. MYDBGASSERT(m_pConnTable->Connections[i].dwUsage);
  239. MYDBGASSERT(m_pConnTable->Connections[i].CmState);
  240. *piID = i;
  241. return S_OK;
  242. }
  243. }
  244. return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  245. }
  246. //+----------------------------------------------------------------------------
  247. //
  248. // Function: CConnectionTable::FindEntry - hRasConn
  249. //
  250. // Synopsis: Determines the ID (index) of an entry in the table. Table should
  251. // be locked before making this call.
  252. //
  253. // Arguments: HRASCONN hRasConn - Tunnel or dial handle of the entry we are seeking.
  254. // LPINT piID - Ptr to buffer for ID (index) of connection
  255. //
  256. // Returns: HRESULT - Failure code, or S_OK if piID filled.
  257. //
  258. // History: nickball Created 2/2/98
  259. //
  260. //+----------------------------------------------------------------------------
  261. HRESULT CConnectionTable::FindEntry(HRASCONN hRasConn, LPINT piID)
  262. {
  263. MYDBGASSERT(m_pConnTable);
  264. MYDBGASSERT(m_hMap);
  265. MYDBGASSERT(hRasConn);
  266. MYDBGASSERT(piID);
  267. MYDBGASSERT(TRUE == m_fLocked);
  268. CMTRACE1(TEXT("CConnectionTable::FindEntry(%u)"), (DWORD_PTR) hRasConn);
  269. if (FALSE == m_fLocked || NULL == m_pConnTable)
  270. {
  271. return E_ACCESSDENIED;
  272. }
  273. if (NULL == piID)
  274. {
  275. return E_POINTER;
  276. }
  277. if (NULL == hRasConn)
  278. {
  279. return E_INVALIDARG;
  280. }
  281. //
  282. // Look for the entry
  283. //
  284. for (int i = 0; i < MAX_CM_CONNECTIONS; i++)
  285. {
  286. //
  287. // Compare for either handle for a match
  288. //
  289. if (hRasConn == m_pConnTable->Connections[i].hDial ||
  290. hRasConn == m_pConnTable->Connections[i].hTunnel)
  291. {
  292. MYDBGASSERT(m_pConnTable->Connections[i].dwUsage);
  293. MYDBGASSERT(m_pConnTable->Connections[i].CmState);
  294. *piID = i;
  295. return S_OK;
  296. }
  297. }
  298. return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  299. }
  300. //+----------------------------------------------------------------------------
  301. //
  302. // Function: CConnectionTable::FindUnused
  303. //
  304. // Synopsis: Determines the ID (index) of the first unused entry in the table.
  305. // Table should be locked before making this call.
  306. //
  307. // Arguments: LPINT piID - Ptr to buffer for ID (index) of connection
  308. //
  309. // Returns: HRESULT - Failure code, or S_OK if piID filled.
  310. //
  311. // History: nickball Created 2/2/98
  312. //
  313. //+----------------------------------------------------------------------------
  314. HRESULT CConnectionTable::FindUnused(LPINT piID)
  315. {
  316. MYDBGASSERT(m_pConnTable);
  317. MYDBGASSERT(m_hMap);
  318. MYDBGASSERT(piID);
  319. MYDBGASSERT(TRUE == m_fLocked);
  320. CMTRACE(TEXT("CConnectionTable::FindUnused()"));
  321. if (FALSE == m_fLocked || NULL == m_pConnTable)
  322. {
  323. return E_ACCESSDENIED;
  324. }
  325. if (NULL == piID)
  326. {
  327. return E_POINTER;
  328. }
  329. //
  330. // Look for an unused slot
  331. //
  332. for (int i = 0; i < MAX_CM_CONNECTIONS; i++)
  333. {
  334. if (0 == m_pConnTable->Connections[i].dwUsage)
  335. {
  336. MYDBGASSERT(CM_DISCONNECTED == m_pConnTable->Connections[i].CmState);
  337. *piID = i;
  338. return S_OK;
  339. }
  340. }
  341. return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  342. }
  343. //+----------------------------------------------------------------------------
  344. //
  345. // Function: Create
  346. //
  347. // Synopsis: Creates a new table. This function will fail if the table already exists.
  348. // The table should be released by calling Close.
  349. //
  350. // Arguments: None
  351. //
  352. // Returns: HRESULT - Failure code or S_OK
  353. //
  354. // History: nickball Created 2/2/98
  355. //
  356. //+----------------------------------------------------------------------------
  357. HRESULT CConnectionTable::Create()
  358. {
  359. MYDBGASSERT(NULL == m_hMap);
  360. MYDBGASSERT(NULL == m_pConnTable);
  361. MYDBGASSERT(FALSE == m_fLocked);
  362. CMTRACE(TEXT("CConnectionTable::Create()"));
  363. if (m_hMap || m_pConnTable)
  364. {
  365. return E_ACCESSDENIED;
  366. }
  367. SECURITY_ATTRIBUTES sa;
  368. PACL pAcl = NULL;
  369. // Initialize a default Security attributes, giving world permissions,
  370. // this is basically prevent Semaphores and other named objects from
  371. // being created because of default acls given by winlogon when perfmon
  372. // is being used remotely.
  373. sa.bInheritHandle = FALSE;
  374. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  375. sa.lpSecurityDescriptor = CmMalloc(sizeof(SECURITY_DESCRIPTOR));
  376. if ( !sa.lpSecurityDescriptor )
  377. {
  378. return E_OUTOFMEMORY;
  379. }
  380. if ( !InitializeSecurityDescriptor(sa.lpSecurityDescriptor,SECURITY_DESCRIPTOR_REVISION) )
  381. {
  382. return HRESULT_FROM_WIN32(GetLastError());
  383. }
  384. if (OS_NT)
  385. {
  386. if (FALSE == SetAclPerms(&pAcl))
  387. {
  388. return HRESULT_FROM_WIN32(GetLastError());
  389. }
  390. }
  391. if (FALSE == SetSecurityDescriptorDacl(sa.lpSecurityDescriptor, TRUE, pAcl, FALSE))
  392. {
  393. return HRESULT_FROM_WIN32(GetLastError());
  394. }
  395. //
  396. // Now use this 'sa' for the mapped file as well as the event (below)
  397. //
  398. m_hMap = CreateFileMappingU(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE,
  399. 0, sizeof(CM_CONNECTION_TABLE), CONN_TABLE_NAME);
  400. DWORD dwRet = GetLastError();
  401. if (NULL == m_hMap)
  402. {
  403. if (dwRet == ERROR_ALREADY_EXISTS)
  404. {
  405. if (m_hMap)
  406. {
  407. MYVERIFY(NULL != CloseHandle(m_hMap));
  408. m_hMap = NULL;
  409. }
  410. }
  411. else
  412. {
  413. CMTRACE1(TEXT("CreateFileMapping failed with error %d"), dwRet);
  414. MYDBGASSERT(FALSE);
  415. }
  416. }
  417. else
  418. {
  419. #if 0 // DBG
  420. DumpAclInfo(m_hMap);
  421. #endif
  422. //
  423. // File mapping created successfully, map a view of it
  424. //
  425. m_pConnTable = (LPCM_CONNECTION_TABLE) MapViewOfFile(m_hMap,
  426. FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
  427. if (NULL == m_pConnTable)
  428. {
  429. dwRet = GetLastError();
  430. MYVERIFY(NULL != CloseHandle(m_hMap));
  431. m_hMap = NULL;
  432. }
  433. else
  434. {
  435. //
  436. // Success, make sure mapping is empty becuase we are paranoid
  437. //
  438. ZeroMemory(m_pConnTable, sizeof(CM_CONNECTION_TABLE));
  439. //
  440. // Create the named event to be used for locking the file
  441. // Note: We use auto-reset.
  442. //
  443. m_hEvent = CreateEventU(&sa, FALSE, TRUE, CONN_TABLE_OPEN);
  444. if (NULL == m_hEvent)
  445. {
  446. MYDBGASSERT(FALSE);
  447. dwRet = GetLastError();
  448. m_hEvent = NULL;
  449. }
  450. }
  451. }
  452. CmFree(sa.lpSecurityDescriptor);
  453. if (pAcl)
  454. {
  455. LocalFree(pAcl);
  456. }
  457. return HRESULT_FROM_WIN32(dwRet);
  458. }
  459. //+----------------------------------------------------------------------------
  460. //
  461. // Function: CConnectionTable::Open
  462. //
  463. // Synopsis: Opens an existing table. This function will fail if no table exists.
  464. // The table should be released by calling Close.
  465. //
  466. // Arguments: None
  467. //
  468. // Returns: HRESULT - Failure code on S_OK
  469. //
  470. // History: nickball Created 2/2/98
  471. //
  472. //+----------------------------------------------------------------------------
  473. HRESULT CConnectionTable::Open()
  474. {
  475. MYDBGASSERT(NULL == m_hMap);
  476. MYDBGASSERT(NULL == m_pConnTable);
  477. MYDBGASSERT(FALSE == m_fLocked);
  478. CMTRACE(TEXT("CConnectionTable::Open()"));
  479. if (m_hMap || m_pConnTable)
  480. {
  481. return E_ACCESSDENIED;
  482. }
  483. LRESULT lRet = ERROR_SUCCESS;
  484. //
  485. // Open the file mapping
  486. //
  487. m_hMap = OpenFileMappingU(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, CONN_TABLE_NAME);
  488. if (NULL == m_hMap)
  489. {
  490. lRet = GetLastError();
  491. }
  492. else
  493. {
  494. //
  495. // File mapping opened successfully, map a view of it.
  496. //
  497. m_pConnTable = (LPCM_CONNECTION_TABLE) MapViewOfFile(m_hMap,
  498. FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
  499. MYDBGASSERT(m_pConnTable);
  500. if (NULL == m_pConnTable)
  501. {
  502. MYVERIFY(NULL != CloseHandle(m_hMap));
  503. m_hMap = NULL;
  504. lRet = GetLastError();
  505. }
  506. else
  507. {
  508. //
  509. // Open the named event used for locking the file
  510. //
  511. m_hEvent = OpenEventU(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
  512. NULL, CONN_TABLE_OPEN);
  513. if (NULL == m_hEvent)
  514. {
  515. MYDBGASSERT(FALSE);
  516. lRet = GetLastError();
  517. }
  518. }
  519. }
  520. return HRESULT_FROM_WIN32(lRet);
  521. }
  522. //+----------------------------------------------------------------------------
  523. //
  524. // Function: CConnectionTable::Close
  525. //
  526. // Synopsis: Closes an opened table. This function will fail if the table is
  527. // not open.
  528. //
  529. // Arguments: None
  530. //
  531. // Returns: HRESULT - Failure code or S_OK
  532. //
  533. // History: nickball Created 2/2/98
  534. //
  535. //+----------------------------------------------------------------------------
  536. HRESULT CConnectionTable::Close()
  537. {
  538. MYDBGASSERT(m_pConnTable);
  539. MYDBGASSERT(m_hMap);
  540. MYDBGASSERT(FALSE == m_fLocked);
  541. CMTRACE(TEXT("CConnectionTable::Close()"));
  542. if (m_pConnTable)
  543. {
  544. MYVERIFY(NULL != UnmapViewOfFile(m_pConnTable));
  545. m_pConnTable = NULL;
  546. }
  547. if (m_hMap)
  548. {
  549. MYVERIFY(NULL != CloseHandle(m_hMap));
  550. m_hMap = NULL;
  551. }
  552. if (m_hEvent)
  553. {
  554. MYVERIFY(NULL != CloseHandle(m_hEvent));
  555. m_hEvent = NULL;
  556. }
  557. return S_OK;
  558. }
  559. //+----------------------------------------------------------------------------
  560. //
  561. // Function: CConnectionTable::AddEntry
  562. //
  563. // Synopsis: Creates a new entry in the table with the specified name. Adding
  564. // an entry implies that the connection is being attempted, so the
  565. // connection state is set to CM_CONNECTING. If an entry for the
  566. // connection already exists, the usage count is incremented.
  567. //
  568. // Arguments: LPCTSTR pszEntry - The name of connection for which we're creating an entry.
  569. // BOOL fAllUser - The All User attribute of the profile
  570. //
  571. // Returns: HRESULT - Failure code or S_OK
  572. //
  573. // History: nickball Created 2/2/98
  574. //
  575. //+----------------------------------------------------------------------------
  576. HRESULT CConnectionTable::AddEntry(LPCTSTR pszEntry, BOOL fAllUser)
  577. {
  578. MYDBGASSERT(m_pConnTable);
  579. MYDBGASSERT(m_hMap);
  580. MYDBGASSERT(pszEntry);
  581. CMTRACE1(TEXT("CConnectionTable::AddEntry(%s)"), pszEntry);
  582. if (NULL == pszEntry)
  583. {
  584. return E_POINTER;
  585. }
  586. if (0 == pszEntry[0])
  587. {
  588. return E_INVALIDARG;
  589. }
  590. if (NULL == m_pConnTable)
  591. {
  592. return E_ACCESSDENIED;
  593. }
  594. HRESULT hrRet = LockTable();
  595. if (FAILED(hrRet))
  596. {
  597. return hrRet;
  598. }
  599. //
  600. // See if we already have an entry by this name
  601. //
  602. int iID = -1;
  603. hrRet = FindEntry(pszEntry, &iID);
  604. if (SUCCEEDED(hrRet))
  605. {
  606. //
  607. // We do, bump the usage count.
  608. //
  609. MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS);
  610. //
  611. // Don't bump ref count when reconnecting the same connection.
  612. //
  613. if (m_pConnTable->Connections[iID].CmState != CM_RECONNECTPROMPT)
  614. {
  615. m_pConnTable->Connections[iID].dwUsage += 1;
  616. }
  617. //
  618. // Unless this entry is already connected, make sure
  619. // its now in the connecting state. This allows us
  620. // to preserve the usage count across prompt reconnect
  621. // events.
  622. //
  623. if (m_pConnTable->Connections[iID].CmState != CM_CONNECTED)
  624. {
  625. m_pConnTable->Connections[iID].CmState = CM_CONNECTING;
  626. }
  627. MYDBGASSERT(m_pConnTable->Connections[iID].dwUsage < 1000); // Sanity check
  628. }
  629. else
  630. {
  631. if (HRESULT_CODE(hrRet) == ERROR_NOT_FOUND)
  632. {
  633. //
  634. // Its a new entry, find the first unused slot
  635. //
  636. hrRet = FindUnused(&iID);
  637. MYDBGASSERT(SUCCEEDED(hrRet));
  638. if (SUCCEEDED(hrRet))
  639. {
  640. MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS);
  641. ZeroMemory(&m_pConnTable->Connections[iID], sizeof(CM_CONNECTION));
  642. //
  643. // Set usage count, state and name
  644. //
  645. m_pConnTable->Connections[iID].dwUsage = 1;
  646. m_pConnTable->Connections[iID].CmState = CM_CONNECTING;
  647. lstrcpyU(m_pConnTable->Connections[iID].szEntry, pszEntry);
  648. m_pConnTable->Connections[iID].fAllUser = fAllUser;
  649. }
  650. }
  651. }
  652. MYVERIFY(SUCCEEDED(UnlockTable()));
  653. return hrRet;
  654. }
  655. //+----------------------------------------------------------------------------
  656. //
  657. // Function: CConnectionTable::RemoveEntry
  658. //
  659. // Synopsis: Decrements the usage count for the specified connection. If the
  660. // usage count falls to 0 the entire entry is cleared.
  661. //
  662. // Arguments: LPCTSTR pszEntry - The name of the entry to be removed
  663. //
  664. // Returns: HRESULT - Failure code or S_OK
  665. //
  666. // Note: If the entry does not exists the request fails.
  667. //
  668. // History: nickball Created 2/2/98
  669. //
  670. //+----------------------------------------------------------------------------
  671. HRESULT CConnectionTable::RemoveEntry(LPCTSTR pszEntry)
  672. {
  673. MYDBGASSERT(m_pConnTable);
  674. MYDBGASSERT(m_hMap);
  675. MYDBGASSERT(pszEntry);
  676. CMTRACE1(TEXT("CConnectionTable::RemoveEntry(%s)"), pszEntry);
  677. if (NULL == pszEntry)
  678. {
  679. return E_POINTER;
  680. }
  681. if (0 == pszEntry[0])
  682. {
  683. return E_INVALIDARG;
  684. }
  685. if (NULL == m_pConnTable)
  686. {
  687. return E_ACCESSDENIED;
  688. }
  689. //
  690. // Lock the table and locate the entry
  691. //
  692. HRESULT hrRet = LockTable();
  693. if (FAILED(hrRet))
  694. {
  695. return hrRet;
  696. }
  697. int iID = -1;
  698. hrRet = FindEntry(pszEntry, &iID);
  699. if (SUCCEEDED(hrRet))
  700. {
  701. MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS);
  702. if (m_pConnTable->Connections[iID].dwUsage == 1)
  703. {
  704. ZeroMemory(&m_pConnTable->Connections[iID], sizeof(CM_CONNECTION));
  705. }
  706. else
  707. {
  708. m_pConnTable->Connections[iID].dwUsage -= 1;
  709. MYDBGASSERT(m_pConnTable->Connections[iID].dwUsage != 0xFFFFFFFF);
  710. }
  711. }
  712. MYVERIFY(SUCCEEDED(UnlockTable()));
  713. return hrRet;
  714. }
  715. //+----------------------------------------------------------------------------
  716. //
  717. // Function: CConnectionTable::GetMonitorWnd
  718. //
  719. // Synopsis: Simple accessor to retrieve the hwnd of the CM Connection
  720. // Monitor from the table.
  721. //
  722. // Arguments: phWnd - Ptr to buffer to receive hWnd
  723. //
  724. // Returns: Failure code or S_OK
  725. //
  726. // History: nickball Created 2/2/98
  727. //
  728. //+----------------------------------------------------------------------------
  729. HRESULT CConnectionTable::GetMonitorWnd(HWND *phWnd)
  730. {
  731. MYDBGASSERT(m_pConnTable);
  732. MYDBGASSERT(m_hMap);
  733. CMTRACE(TEXT("CConnectionTable::GetMonitorWnd()"));
  734. if (NULL == m_pConnTable)
  735. {
  736. return E_ACCESSDENIED;
  737. }
  738. if (NULL == phWnd)
  739. {
  740. return E_POINTER;
  741. }
  742. //
  743. // Lock the table and retrieve the HWND
  744. //
  745. HRESULT hrRet = LockTable();
  746. if (FAILED(hrRet))
  747. {
  748. return hrRet;
  749. }
  750. *phWnd = m_pConnTable->hwndCmMon;
  751. MYVERIFY(SUCCEEDED(UnlockTable()));
  752. return S_OK;
  753. }
  754. //+----------------------------------------------------------------------------
  755. //
  756. // Function: CConnectionTable::SetMonitorWnd
  757. //
  758. // Synopsis: Simple assignment method for setting the CMMON HWND in the table
  759. // .
  760. // Arguments: HWND hwndMonitor - The HWND of CMMON
  761. //
  762. // Returns: HRESULT - Failure code or S_OK
  763. //
  764. // Note: hwndMonitor CAN be NULL. It is possible CMMON is unloaded, but
  765. // the table statys in memory
  766. // History: nickball Created 2/2/98
  767. // fengsun 2/20/98 change to allow NULL phwndMonitor
  768. //
  769. //+----------------------------------------------------------------------------
  770. HRESULT CConnectionTable::SetMonitorWnd(HWND hwndMonitor)
  771. {
  772. MYDBGASSERT(m_pConnTable);
  773. MYDBGASSERT(m_hMap);
  774. CMTRACE(TEXT("CConnectionTable::SetMonitorWnd()"));
  775. if (NULL == m_pConnTable)
  776. {
  777. return E_ACCESSDENIED;
  778. }
  779. //
  780. // Lock the table and set the HWND
  781. //
  782. HRESULT hrRet = LockTable();
  783. if (FAILED(hrRet))
  784. {
  785. return hrRet;
  786. }
  787. m_pConnTable->hwndCmMon = hwndMonitor;
  788. MYVERIFY(SUCCEEDED(UnlockTable()));
  789. return S_OK;
  790. }
  791. //+----------------------------------------------------------------------------
  792. //
  793. // Function: CConnectionTable::GetEntry - pszEntry
  794. //
  795. // Synopsis: Retrieves a copy the data for the specified connection based on
  796. // the entry name provided.
  797. //
  798. // Arguments: LPCTSTR pszEntry - The name of the connection
  799. // LPCM_CONNECTION pConnection - Ptr to a CM_CONNECTION sturct to be filled
  800. //
  801. // Returns: HRESULT - Failure Code or S_OK.
  802. //
  803. // Note: A NULL ptr may be passed for pConnection, if the existence of the
  804. // entry is the only information required.
  805. //
  806. // History: nickball Created 2/2/98
  807. //
  808. //+----------------------------------------------------------------------------
  809. HRESULT CConnectionTable::GetEntry(LPCTSTR pszEntry,
  810. LPCM_CONNECTION pConnection)
  811. {
  812. MYDBGASSERT(m_pConnTable);
  813. MYDBGASSERT(m_hMap);
  814. MYDBGASSERT(pszEntry);
  815. CMTRACE1(TEXT("CConnectionTable::GetEntry(%s)"), pszEntry);
  816. if (NULL == m_pConnTable)
  817. {
  818. return E_ACCESSDENIED;
  819. }
  820. if (NULL == pszEntry)
  821. {
  822. return E_POINTER;
  823. }
  824. if (0 == pszEntry[0])
  825. {
  826. return E_INVALIDARG;
  827. }
  828. //
  829. // Lock the table and retrieve the entry
  830. //
  831. HRESULT hrRet = LockTable();
  832. if (FAILED(hrRet))
  833. {
  834. return hrRet;
  835. }
  836. int iID = -1;
  837. hrRet = FindEntry(pszEntry, &iID);
  838. if (SUCCEEDED(hrRet))
  839. {
  840. MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS);
  841. //
  842. // If a buffer was given fill it.
  843. //
  844. if (pConnection)
  845. {
  846. memcpy(pConnection, &m_pConnTable->Connections[iID], sizeof(CM_CONNECTION));
  847. }
  848. }
  849. MYVERIFY(SUCCEEDED(UnlockTable()));
  850. return hrRet;
  851. }
  852. //+----------------------------------------------------------------------------
  853. //
  854. // Function: CConnectionTable::GetEntry - hRasConn
  855. //
  856. // Synopsis: Retrieves a copy the data for the specified connection based on the
  857. // Ras handle provided
  858. //
  859. // Arguments: HRASCONN hRasConn - Either the tunnel or dial handle of the connection
  860. // LPCM_CONNECTION pConnection - Ptr to a CM_CONNECTION sturct to be filled
  861. //
  862. // Returns: HRESULT - Failure Code or S_OK.
  863. //
  864. // Note: A NULL ptr may be passed for pConnection, if the existence of the
  865. // entry is the only information required.
  866. //
  867. // History: nickball Created 2/2/98
  868. //
  869. //+----------------------------------------------------------------------------
  870. HRESULT CConnectionTable::GetEntry(HRASCONN hRasConn,
  871. LPCM_CONNECTION pConnection)
  872. {
  873. MYDBGASSERT(m_pConnTable);
  874. MYDBGASSERT(m_hMap);
  875. MYDBGASSERT(hRasConn);
  876. CMTRACE1(TEXT("CConnectionTable::GetEntry(%u)"), (DWORD_PTR) hRasConn);
  877. if (NULL == m_pConnTable)
  878. {
  879. return E_ACCESSDENIED;
  880. }
  881. if (NULL == hRasConn)
  882. {
  883. return E_INVALIDARG;
  884. }
  885. //
  886. // Lock the table and retrieve the entry
  887. //
  888. HRESULT hrRet = LockTable();
  889. if (FAILED(hrRet))
  890. {
  891. return hrRet;
  892. }
  893. int iID = -1;
  894. hrRet = FindEntry(hRasConn, &iID);
  895. if (SUCCEEDED(hrRet))
  896. {
  897. MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS);
  898. //
  899. // If a buffer was given fill it.
  900. //
  901. if (pConnection)
  902. {
  903. memcpy(pConnection, &m_pConnTable->Connections[iID], sizeof(CM_CONNECTION));
  904. }
  905. }
  906. MYVERIFY(SUCCEEDED(UnlockTable()));
  907. return hrRet;
  908. }
  909. //+----------------------------------------------------------------------------
  910. //
  911. // Function: CConnectionTable::SetConnected
  912. //
  913. // Synopsis: Sets the connection to CM_CONNECTED indicating that a connection
  914. // has been established. The caller must provide either the hDial or
  915. // the hTunnel parameter or both in order for the function to succeed.
  916. //
  917. // Arguments: LPCTSTR pszEntry - The name of the connection.
  918. // HRASCONN hDial - A Dial-up connection handle.
  919. // HRASCONN hTunnel - A tunnel connection handle.
  920. //
  921. // Returns: HRESULT - Failure code or S_OK.
  922. //
  923. // History: nickball Created 2/2/98
  924. //
  925. //+----------------------------------------------------------------------------
  926. HRESULT CConnectionTable::SetConnected(LPCTSTR pszEntry,
  927. HRASCONN hDial,
  928. HRASCONN hTunnel)
  929. {
  930. MYDBGASSERT(m_pConnTable);
  931. MYDBGASSERT(m_hMap);
  932. MYDBGASSERT(pszEntry);
  933. CMTRACE1(TEXT("CConnectionTable::SetConnected(%s)"), pszEntry);
  934. if (NULL == m_pConnTable)
  935. {
  936. return E_ACCESSDENIED;
  937. }
  938. if (NULL == pszEntry)
  939. {
  940. return E_POINTER;
  941. }
  942. if (0 == pszEntry[0] || (NULL == hDial && NULL == hTunnel))
  943. {
  944. return E_INVALIDARG;
  945. }
  946. //
  947. // Lock the table and retrieve the entry
  948. //
  949. HRESULT hrRet = LockTable();
  950. if (FAILED(hrRet))
  951. {
  952. return hrRet;
  953. }
  954. int iID = -1;
  955. hrRet = FindEntry(pszEntry, &iID);
  956. MYDBGASSERT(SUCCEEDED(hrRet));
  957. if (SUCCEEDED(hrRet))
  958. {
  959. //
  960. // Found, set the state and Ras handles
  961. //
  962. MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS);
  963. MYDBGASSERT(m_pConnTable->Connections[iID].CmState != CM_CONNECTED);
  964. m_pConnTable->Connections[iID].CmState = CM_CONNECTED;
  965. m_pConnTable->Connections[iID].hDial = hDial;
  966. m_pConnTable->Connections[iID].hTunnel = hTunnel;
  967. }
  968. MYVERIFY(SUCCEEDED(UnlockTable()));
  969. return hrRet;
  970. }
  971. //+----------------------------------------------------------------------------
  972. //
  973. // Function: CConnectionTable::SetDisconnecting
  974. //
  975. // Synopsis: Set the state of the connection to CM_DISCONNECTING
  976. //
  977. // Arguments: LPCTSTR pszEntry - The name of the connection to be set.
  978. //
  979. // Returns: HRESULT - Failure code or S_OK
  980. //
  981. // History: nickball Created 2/2/98
  982. //
  983. //+----------------------------------------------------------------------------
  984. HRESULT CConnectionTable::SetDisconnecting(LPCTSTR pszEntry)
  985. {
  986. MYDBGASSERT(m_pConnTable);
  987. MYDBGASSERT(m_hMap);
  988. MYDBGASSERT(pszEntry);
  989. CMTRACE1(TEXT("CConnectionTable::Disconnecting(%s)"), pszEntry);
  990. if (NULL == m_pConnTable)
  991. {
  992. return E_ACCESSDENIED;
  993. }
  994. if (NULL == pszEntry)
  995. {
  996. return E_POINTER;
  997. }
  998. if (0 == pszEntry[0])
  999. {
  1000. return E_INVALIDARG;
  1001. }
  1002. //
  1003. // Lock the table and retrieve the entry
  1004. //
  1005. HRESULT hrRet = LockTable();
  1006. if (FAILED(hrRet))
  1007. {
  1008. return hrRet;
  1009. }
  1010. int iID = -1;
  1011. hrRet = FindEntry(pszEntry, &iID);
  1012. //MYDBGASSERT(SUCCEEDED(hrRet));
  1013. if (SUCCEEDED(hrRet))
  1014. {
  1015. //
  1016. // Found, set the state
  1017. //
  1018. MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS);
  1019. m_pConnTable->Connections[iID].CmState = CM_DISCONNECTING;
  1020. }
  1021. MYVERIFY(SUCCEEDED(UnlockTable()));
  1022. return hrRet;
  1023. }
  1024. //+----------------------------------------------------------------------------
  1025. //
  1026. // Function: SetPrompting
  1027. //
  1028. // Synopsis: Set the state of the connection to CM_RECONNECTPROMPT
  1029. //
  1030. // Arguments: LPCTSTR pszEntry - The name of the connection to be set.
  1031. //
  1032. // Returns: HRESULT - Failure code or S_OK
  1033. //
  1034. // History: nickball Created 2/2/98
  1035. //
  1036. //+----------------------------------------------------------------------------
  1037. HRESULT CConnectionTable::SetPrompting(LPCTSTR pszEntry)
  1038. {
  1039. MYDBGASSERT(m_pConnTable);
  1040. MYDBGASSERT(m_hMap);
  1041. MYDBGASSERT(pszEntry);
  1042. CMTRACE1(TEXT("CConnectionTable::SetPrompting(%s)"), pszEntry);
  1043. if (NULL == m_pConnTable)
  1044. {
  1045. return E_ACCESSDENIED;
  1046. }
  1047. if (NULL == pszEntry)
  1048. {
  1049. return E_POINTER;
  1050. }
  1051. if (0 == pszEntry[0])
  1052. {
  1053. return E_INVALIDARG;
  1054. }
  1055. //
  1056. // Lock the table and retrieve the entry
  1057. //
  1058. HRESULT hrRet = LockTable();
  1059. if (FAILED(hrRet))
  1060. {
  1061. return hrRet;
  1062. }
  1063. int iID = -1;
  1064. hrRet = FindEntry(pszEntry, &iID);
  1065. //MYDBGASSERT(SUCCEEDED(hrRet));
  1066. if (SUCCEEDED(hrRet))
  1067. {
  1068. //
  1069. // Found, set the state
  1070. //
  1071. MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS);
  1072. m_pConnTable->Connections[iID].CmState = CM_RECONNECTPROMPT;
  1073. }
  1074. MYVERIFY(SUCCEEDED(UnlockTable()));
  1075. return hrRet;
  1076. }
  1077. //+----------------------------------------------------------------------------
  1078. //
  1079. // Function: CConnectionTable::ClearEntry
  1080. //
  1081. // Synopsis: Clears the specified entry regardless of the usage count.
  1082. //
  1083. // Arguments: LPCTSTR pszEntry - The name of the entry to be cleared.
  1084. //
  1085. // Returns: HRESULT - Failure code or S_OK
  1086. //
  1087. // History: nickball Created 2/2/98
  1088. //
  1089. //+----------------------------------------------------------------------------
  1090. HRESULT CConnectionTable::ClearEntry(LPCTSTR pszEntry)
  1091. {
  1092. MYDBGASSERT(m_pConnTable);
  1093. MYDBGASSERT(m_hMap);
  1094. MYDBGASSERT(pszEntry);
  1095. CMTRACE1(TEXT("CConnectionTable::ClearEntry(%s)"), pszEntry);
  1096. if (NULL == m_pConnTable)
  1097. {
  1098. return E_ACCESSDENIED;
  1099. }
  1100. if (NULL == pszEntry)
  1101. {
  1102. return E_POINTER;
  1103. }
  1104. if (0 == pszEntry[0])
  1105. {
  1106. return E_INVALIDARG;
  1107. }
  1108. //
  1109. // Lock the table and retrieve the entry
  1110. //
  1111. HRESULT hrRet = LockTable();
  1112. if (FAILED(hrRet))
  1113. {
  1114. return hrRet;
  1115. }
  1116. int iID = -1;
  1117. hrRet = FindEntry(pszEntry, &iID);
  1118. if (SUCCEEDED(hrRet))
  1119. {
  1120. //
  1121. // Found, clear it
  1122. //
  1123. MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS);
  1124. ZeroMemory(&m_pConnTable->Connections[iID], sizeof(CM_CONNECTION));
  1125. }
  1126. MYVERIFY(SUCCEEDED(UnlockTable()));
  1127. return hrRet;
  1128. }