//+---------------------------------------------------------------------------- // // File: CONTABLE.CPP // // Module: CMCONTBL.LIB // // Synopsis: Implements the CM connection table (CConnectionTable). The connection // table is a list of active conenctions stored in a (memory only) memory // mapped file, and shared by the various CM components in order to // manage CM connections. // // Copyright (c) 1998-1999 Microsoft Corporation // // Author: nickball Created 02/02/98 // //+---------------------------------------------------------------------------- #include #include "contable.h" #include "cmdebug.h" #include "cmutil.h" #include "uapi.h" #include "setacl.h" #if 0 #include "DumpSecInfo.cpp" #endif #define CONN_TABLE_NAME TEXT("CmConnectionTable") #define CONN_TABLE_OPEN TEXT("CmConnectionOpen") static const int MAX_LOCK_WAIT = 1000; // wait timeout in milliseconds // // Constructor and destructor // CConnectionTable::CConnectionTable() { CMTRACE(TEXT("CConnectionTable::CConnectionTable()")); // // Initialize our data members // m_hMap = NULL; m_pConnTable = NULL; m_fLocked = FALSE; m_hEvent = NULL; } CConnectionTable::~CConnectionTable() { CMTRACE(TEXT("CConnectionTable::~CConnectionTable()")); // // Data should have been cleaned up in Close, etc. Double-Check // MYDBGASSERT(NULL == m_pConnTable); MYDBGASSERT(NULL == m_hMap); MYDBGASSERT(FALSE == m_fLocked); MYDBGASSERT(NULL == m_hEvent); // // Release handles and pointers // if (m_pConnTable) { MYVERIFY(NULL != UnmapViewOfFile(m_pConnTable)); m_pConnTable = NULL; } if (m_hMap) { MYVERIFY(NULL != CloseHandle(m_hMap)); m_hMap = NULL; } if (m_hEvent) { MYVERIFY(NULL != CloseHandle(m_hEvent)); m_hEvent = NULL; } } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::LockTable // // Synopsis: Sets the internal lock on the table. Should be called internally // prior to any table access. // // Arguments: None // // Returns: HRESULT - Failure code or S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::LockTable() { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(m_hEvent); CMTRACE(TEXT("CConnectionTable::LockTable()")); HRESULT hrRet = S_OK; // // Validate our current state // if (NULL == m_hEvent) { MYDBGASSERT(FALSE); return E_ACCESSDENIED; } // // Wait for the open event to be signaled // DWORD dwWait = WaitForSingleObject(m_hEvent, MAX_LOCK_WAIT); // // If our records indicate that we are already locked at this point // then something is wrong within the class implementation // MYDBGASSERT(FALSE == m_fLocked); // no double locks please if (TRUE == m_fLocked) { SetEvent(m_hEvent); // cleat the signal that we just set by clearing the wait return E_ACCESSDENIED; } // // Check the // if (WAIT_FAILED == dwWait) { MYDBGASSERT(FALSE); hrRet = GetLastError(); return HRESULT_FROM_WIN32(hrRet); } // // If not signaled, bail // MYDBGASSERT(WAIT_OBJECT_0 == dwWait); if (WAIT_OBJECT_0 != dwWait) { if (WAIT_TIMEOUT == dwWait) { hrRet = HRESULT_FROM_WIN32(ERROR_TIMEOUT); } else { hrRet = E_ACCESSDENIED; } } else { // // The event is signaled automatically by virtue of the // fact that we cleared the wait on the event. Its locked. // m_fLocked = TRUE; } return hrRet; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::UnlockTable // // Synopsis: Clears the internal lock on the table. Should be cleared // following any access to the table. // // Arguments: None // // Returns: HRESULT - Failure code or S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::UnlockTable() { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(m_hEvent); MYDBGASSERT(TRUE == m_fLocked); CMTRACE(TEXT("CConnectionTable::UnlockTable()")); HRESULT hrRet = S_OK; // // Validate our current state // if (FALSE == m_fLocked || NULL == m_hEvent) { return E_ACCESSDENIED; } // // Signal the open event, allowing access // if (SetEvent(m_hEvent)) { m_fLocked = FALSE; } else { MYDBGASSERT(FALSE); hrRet = GetLastError(); hrRet = HRESULT_FROM_WIN32(hrRet); } return hrRet; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::FindEntry - pszEntry // // Synopsis: Determines the ID (index) of an entry in the table. Table should // be locked before making this call. // // Arguments: LPCTSTR pszEntry - Ptr to the name of the entry we are seeking. // LPINT piID - Ptr to buffer for ID (index) of connection // // Returns: HRESULT - Failure code, or S_OK if piID filled. // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::FindEntry(LPCTSTR pszEntry, LPINT piID) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(pszEntry); MYDBGASSERT(piID); MYDBGASSERT(TRUE == m_fLocked); CMTRACE1(TEXT("CConnectionTable::FindEntry(%s)"), pszEntry); if (FALSE == m_fLocked || NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == pszEntry || NULL == piID) { return E_POINTER; } if (0 == pszEntry[0]) { return E_INVALIDARG; } // // Look for the entry // for (int i = 0; i < MAX_CM_CONNECTIONS; i++) { // // Name compare for a match // if (0 == lstrcmpU(pszEntry, m_pConnTable->Connections[i].szEntry)) { MYDBGASSERT(m_pConnTable->Connections[i].dwUsage); MYDBGASSERT(m_pConnTable->Connections[i].CmState); *piID = i; return S_OK; } } return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::FindEntry - hRasConn // // Synopsis: Determines the ID (index) of an entry in the table. Table should // be locked before making this call. // // Arguments: HRASCONN hRasConn - Tunnel or dial handle of the entry we are seeking. // LPINT piID - Ptr to buffer for ID (index) of connection // // Returns: HRESULT - Failure code, or S_OK if piID filled. // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::FindEntry(HRASCONN hRasConn, LPINT piID) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(hRasConn); MYDBGASSERT(piID); MYDBGASSERT(TRUE == m_fLocked); CMTRACE1(TEXT("CConnectionTable::FindEntry(%u)"), (DWORD_PTR) hRasConn); if (FALSE == m_fLocked || NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == piID) { return E_POINTER; } if (NULL == hRasConn) { return E_INVALIDARG; } // // Look for the entry // for (int i = 0; i < MAX_CM_CONNECTIONS; i++) { // // Compare for either handle for a match // if (hRasConn == m_pConnTable->Connections[i].hDial || hRasConn == m_pConnTable->Connections[i].hTunnel) { MYDBGASSERT(m_pConnTable->Connections[i].dwUsage); MYDBGASSERT(m_pConnTable->Connections[i].CmState); *piID = i; return S_OK; } } return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::FindUnused // // Synopsis: Determines the ID (index) of the first unused entry in the table. // Table should be locked before making this call. // // Arguments: LPINT piID - Ptr to buffer for ID (index) of connection // // Returns: HRESULT - Failure code, or S_OK if piID filled. // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::FindUnused(LPINT piID) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(piID); MYDBGASSERT(TRUE == m_fLocked); CMTRACE(TEXT("CConnectionTable::FindUnused()")); if (FALSE == m_fLocked || NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == piID) { return E_POINTER; } // // Look for an unused slot // for (int i = 0; i < MAX_CM_CONNECTIONS; i++) { if (0 == m_pConnTable->Connections[i].dwUsage) { MYDBGASSERT(CM_DISCONNECTED == m_pConnTable->Connections[i].CmState); *piID = i; return S_OK; } } return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); } //+---------------------------------------------------------------------------- // // Function: Create // // Synopsis: Creates a new table. This function will fail if the table already exists. // The table should be released by calling Close. // // Arguments: None // // Returns: HRESULT - Failure code or S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::Create() { MYDBGASSERT(NULL == m_hMap); MYDBGASSERT(NULL == m_pConnTable); MYDBGASSERT(FALSE == m_fLocked); CMTRACE(TEXT("CConnectionTable::Create()")); if (m_hMap || m_pConnTable) { return E_ACCESSDENIED; } SECURITY_ATTRIBUTES sa; PACL pAcl = NULL; // Initialize a default Security attributes, giving world permissions, // this is basically prevent Semaphores and other named objects from // being created because of default acls given by winlogon when perfmon // is being used remotely. sa.bInheritHandle = FALSE; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = CmMalloc(sizeof(SECURITY_DESCRIPTOR)); if ( !sa.lpSecurityDescriptor ) { return E_OUTOFMEMORY; } if ( !InitializeSecurityDescriptor(sa.lpSecurityDescriptor,SECURITY_DESCRIPTOR_REVISION) ) { return HRESULT_FROM_WIN32(GetLastError()); } if (OS_NT) { if (FALSE == SetAclPerms(&pAcl)) { return HRESULT_FROM_WIN32(GetLastError()); } } if (FALSE == SetSecurityDescriptorDacl(sa.lpSecurityDescriptor, TRUE, pAcl, FALSE)) { return HRESULT_FROM_WIN32(GetLastError()); } // // Now use this 'sa' for the mapped file as well as the event (below) // m_hMap = CreateFileMappingU(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, sizeof(CM_CONNECTION_TABLE), CONN_TABLE_NAME); DWORD dwRet = GetLastError(); if (NULL == m_hMap) { if (dwRet == ERROR_ALREADY_EXISTS) { if (m_hMap) { MYVERIFY(NULL != CloseHandle(m_hMap)); m_hMap = NULL; } } else { CMTRACE1(TEXT("CreateFileMapping failed with error %d"), dwRet); MYDBGASSERT(FALSE); } } else { #if 0 // DBG DumpAclInfo(m_hMap); #endif // // File mapping created successfully, map a view of it // m_pConnTable = (LPCM_CONNECTION_TABLE) MapViewOfFile(m_hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); if (NULL == m_pConnTable) { dwRet = GetLastError(); MYVERIFY(NULL != CloseHandle(m_hMap)); m_hMap = NULL; } else { // // Success, make sure mapping is empty becuase we are paranoid // ZeroMemory(m_pConnTable, sizeof(CM_CONNECTION_TABLE)); // // Create the named event to be used for locking the file // Note: We use auto-reset. // m_hEvent = CreateEventU(&sa, FALSE, TRUE, CONN_TABLE_OPEN); if (NULL == m_hEvent) { MYDBGASSERT(FALSE); dwRet = GetLastError(); m_hEvent = NULL; } } } CmFree(sa.lpSecurityDescriptor); if (pAcl) { LocalFree(pAcl); } return HRESULT_FROM_WIN32(dwRet); } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::Open // // Synopsis: Opens an existing table. This function will fail if no table exists. // The table should be released by calling Close. // // Arguments: None // // Returns: HRESULT - Failure code on S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::Open() { MYDBGASSERT(NULL == m_hMap); MYDBGASSERT(NULL == m_pConnTable); MYDBGASSERT(FALSE == m_fLocked); CMTRACE(TEXT("CConnectionTable::Open()")); if (m_hMap || m_pConnTable) { return E_ACCESSDENIED; } LRESULT lRet = ERROR_SUCCESS; // // Open the file mapping // m_hMap = OpenFileMappingU(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, CONN_TABLE_NAME); if (NULL == m_hMap) { lRet = GetLastError(); } else { // // File mapping opened successfully, map a view of it. // m_pConnTable = (LPCM_CONNECTION_TABLE) MapViewOfFile(m_hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); MYDBGASSERT(m_pConnTable); if (NULL == m_pConnTable) { MYVERIFY(NULL != CloseHandle(m_hMap)); m_hMap = NULL; lRet = GetLastError(); } else { // // Open the named event used for locking the file // m_hEvent = OpenEventU(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, NULL, CONN_TABLE_OPEN); if (NULL == m_hEvent) { MYDBGASSERT(FALSE); lRet = GetLastError(); } } } return HRESULT_FROM_WIN32(lRet); } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::Close // // Synopsis: Closes an opened table. This function will fail if the table is // not open. // // Arguments: None // // Returns: HRESULT - Failure code or S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::Close() { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(FALSE == m_fLocked); CMTRACE(TEXT("CConnectionTable::Close()")); if (m_pConnTable) { MYVERIFY(NULL != UnmapViewOfFile(m_pConnTable)); m_pConnTable = NULL; } if (m_hMap) { MYVERIFY(NULL != CloseHandle(m_hMap)); m_hMap = NULL; } if (m_hEvent) { MYVERIFY(NULL != CloseHandle(m_hEvent)); m_hEvent = NULL; } return S_OK; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::AddEntry // // Synopsis: Creates a new entry in the table with the specified name. Adding // an entry implies that the connection is being attempted, so the // connection state is set to CM_CONNECTING. If an entry for the // connection already exists, the usage count is incremented. // // Arguments: LPCTSTR pszEntry - The name of connection for which we're creating an entry. // BOOL fAllUser - The All User attribute of the profile // // Returns: HRESULT - Failure code or S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::AddEntry(LPCTSTR pszEntry, BOOL fAllUser) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(pszEntry); CMTRACE1(TEXT("CConnectionTable::AddEntry(%s)"), pszEntry); if (NULL == pszEntry) { return E_POINTER; } if (0 == pszEntry[0]) { return E_INVALIDARG; } if (NULL == m_pConnTable) { return E_ACCESSDENIED; } HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } // // See if we already have an entry by this name // int iID = -1; hrRet = FindEntry(pszEntry, &iID); if (SUCCEEDED(hrRet)) { // // We do, bump the usage count. // MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS); // // Don't bump ref count when reconnecting the same connection. // if (m_pConnTable->Connections[iID].CmState != CM_RECONNECTPROMPT) { m_pConnTable->Connections[iID].dwUsage += 1; } // // Unless this entry is already connected, make sure // its now in the connecting state. This allows us // to preserve the usage count across prompt reconnect // events. // if (m_pConnTable->Connections[iID].CmState != CM_CONNECTED) { m_pConnTable->Connections[iID].CmState = CM_CONNECTING; } MYDBGASSERT(m_pConnTable->Connections[iID].dwUsage < 1000); // Sanity check } else { if (HRESULT_CODE(hrRet) == ERROR_NOT_FOUND) { // // Its a new entry, find the first unused slot // hrRet = FindUnused(&iID); MYDBGASSERT(SUCCEEDED(hrRet)); if (SUCCEEDED(hrRet)) { MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS); ZeroMemory(&m_pConnTable->Connections[iID], sizeof(CM_CONNECTION)); // // Set usage count, state and name // m_pConnTable->Connections[iID].dwUsage = 1; m_pConnTable->Connections[iID].CmState = CM_CONNECTING; lstrcpyU(m_pConnTable->Connections[iID].szEntry, pszEntry); m_pConnTable->Connections[iID].fAllUser = fAllUser; } } } MYVERIFY(SUCCEEDED(UnlockTable())); return hrRet; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::RemoveEntry // // Synopsis: Decrements the usage count for the specified connection. If the // usage count falls to 0 the entire entry is cleared. // // Arguments: LPCTSTR pszEntry - The name of the entry to be removed // // Returns: HRESULT - Failure code or S_OK // // Note: If the entry does not exists the request fails. // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::RemoveEntry(LPCTSTR pszEntry) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(pszEntry); CMTRACE1(TEXT("CConnectionTable::RemoveEntry(%s)"), pszEntry); if (NULL == pszEntry) { return E_POINTER; } if (0 == pszEntry[0]) { return E_INVALIDARG; } if (NULL == m_pConnTable) { return E_ACCESSDENIED; } // // Lock the table and locate the entry // HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } int iID = -1; hrRet = FindEntry(pszEntry, &iID); if (SUCCEEDED(hrRet)) { MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS); if (m_pConnTable->Connections[iID].dwUsage == 1) { ZeroMemory(&m_pConnTable->Connections[iID], sizeof(CM_CONNECTION)); } else { m_pConnTable->Connections[iID].dwUsage -= 1; MYDBGASSERT(m_pConnTable->Connections[iID].dwUsage != 0xFFFFFFFF); } } MYVERIFY(SUCCEEDED(UnlockTable())); return hrRet; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::GetMonitorWnd // // Synopsis: Simple accessor to retrieve the hwnd of the CM Connection // Monitor from the table. // // Arguments: phWnd - Ptr to buffer to receive hWnd // // Returns: Failure code or S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::GetMonitorWnd(HWND *phWnd) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); CMTRACE(TEXT("CConnectionTable::GetMonitorWnd()")); if (NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == phWnd) { return E_POINTER; } // // Lock the table and retrieve the HWND // HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } *phWnd = m_pConnTable->hwndCmMon; MYVERIFY(SUCCEEDED(UnlockTable())); return S_OK; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::SetMonitorWnd // // Synopsis: Simple assignment method for setting the CMMON HWND in the table // . // Arguments: HWND hwndMonitor - The HWND of CMMON // // Returns: HRESULT - Failure code or S_OK // // Note: hwndMonitor CAN be NULL. It is possible CMMON is unloaded, but // the table statys in memory // History: nickball Created 2/2/98 // fengsun 2/20/98 change to allow NULL phwndMonitor // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::SetMonitorWnd(HWND hwndMonitor) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); CMTRACE(TEXT("CConnectionTable::SetMonitorWnd()")); if (NULL == m_pConnTable) { return E_ACCESSDENIED; } // // Lock the table and set the HWND // HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } m_pConnTable->hwndCmMon = hwndMonitor; MYVERIFY(SUCCEEDED(UnlockTable())); return S_OK; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::GetEntry - pszEntry // // Synopsis: Retrieves a copy the data for the specified connection based on // the entry name provided. // // Arguments: LPCTSTR pszEntry - The name of the connection // LPCM_CONNECTION pConnection - Ptr to a CM_CONNECTION sturct to be filled // // Returns: HRESULT - Failure Code or S_OK. // // Note: A NULL ptr may be passed for pConnection, if the existence of the // entry is the only information required. // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::GetEntry(LPCTSTR pszEntry, LPCM_CONNECTION pConnection) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(pszEntry); CMTRACE1(TEXT("CConnectionTable::GetEntry(%s)"), pszEntry); if (NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == pszEntry) { return E_POINTER; } if (0 == pszEntry[0]) { return E_INVALIDARG; } // // Lock the table and retrieve the entry // HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } int iID = -1; hrRet = FindEntry(pszEntry, &iID); if (SUCCEEDED(hrRet)) { MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS); // // If a buffer was given fill it. // if (pConnection) { memcpy(pConnection, &m_pConnTable->Connections[iID], sizeof(CM_CONNECTION)); } } MYVERIFY(SUCCEEDED(UnlockTable())); return hrRet; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::GetEntry - hRasConn // // Synopsis: Retrieves a copy the data for the specified connection based on the // Ras handle provided // // Arguments: HRASCONN hRasConn - Either the tunnel or dial handle of the connection // LPCM_CONNECTION pConnection - Ptr to a CM_CONNECTION sturct to be filled // // Returns: HRESULT - Failure Code or S_OK. // // Note: A NULL ptr may be passed for pConnection, if the existence of the // entry is the only information required. // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::GetEntry(HRASCONN hRasConn, LPCM_CONNECTION pConnection) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(hRasConn); CMTRACE1(TEXT("CConnectionTable::GetEntry(%u)"), (DWORD_PTR) hRasConn); if (NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == hRasConn) { return E_INVALIDARG; } // // Lock the table and retrieve the entry // HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } int iID = -1; hrRet = FindEntry(hRasConn, &iID); if (SUCCEEDED(hrRet)) { MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS); // // If a buffer was given fill it. // if (pConnection) { memcpy(pConnection, &m_pConnTable->Connections[iID], sizeof(CM_CONNECTION)); } } MYVERIFY(SUCCEEDED(UnlockTable())); return hrRet; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::SetConnected // // Synopsis: Sets the connection to CM_CONNECTED indicating that a connection // has been established. The caller must provide either the hDial or // the hTunnel parameter or both in order for the function to succeed. // // Arguments: LPCTSTR pszEntry - The name of the connection. // HRASCONN hDial - A Dial-up connection handle. // HRASCONN hTunnel - A tunnel connection handle. // // Returns: HRESULT - Failure code or S_OK. // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::SetConnected(LPCTSTR pszEntry, HRASCONN hDial, HRASCONN hTunnel) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(pszEntry); CMTRACE1(TEXT("CConnectionTable::SetConnected(%s)"), pszEntry); if (NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == pszEntry) { return E_POINTER; } if (0 == pszEntry[0] || (NULL == hDial && NULL == hTunnel)) { return E_INVALIDARG; } // // Lock the table and retrieve the entry // HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } int iID = -1; hrRet = FindEntry(pszEntry, &iID); MYDBGASSERT(SUCCEEDED(hrRet)); if (SUCCEEDED(hrRet)) { // // Found, set the state and Ras handles // MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS); MYDBGASSERT(m_pConnTable->Connections[iID].CmState != CM_CONNECTED); m_pConnTable->Connections[iID].CmState = CM_CONNECTED; m_pConnTable->Connections[iID].hDial = hDial; m_pConnTable->Connections[iID].hTunnel = hTunnel; } MYVERIFY(SUCCEEDED(UnlockTable())); return hrRet; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::SetDisconnecting // // Synopsis: Set the state of the connection to CM_DISCONNECTING // // Arguments: LPCTSTR pszEntry - The name of the connection to be set. // // Returns: HRESULT - Failure code or S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::SetDisconnecting(LPCTSTR pszEntry) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(pszEntry); CMTRACE1(TEXT("CConnectionTable::Disconnecting(%s)"), pszEntry); if (NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == pszEntry) { return E_POINTER; } if (0 == pszEntry[0]) { return E_INVALIDARG; } // // Lock the table and retrieve the entry // HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } int iID = -1; hrRet = FindEntry(pszEntry, &iID); //MYDBGASSERT(SUCCEEDED(hrRet)); if (SUCCEEDED(hrRet)) { // // Found, set the state // MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS); m_pConnTable->Connections[iID].CmState = CM_DISCONNECTING; } MYVERIFY(SUCCEEDED(UnlockTable())); return hrRet; } //+---------------------------------------------------------------------------- // // Function: SetPrompting // // Synopsis: Set the state of the connection to CM_RECONNECTPROMPT // // Arguments: LPCTSTR pszEntry - The name of the connection to be set. // // Returns: HRESULT - Failure code or S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::SetPrompting(LPCTSTR pszEntry) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(pszEntry); CMTRACE1(TEXT("CConnectionTable::SetPrompting(%s)"), pszEntry); if (NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == pszEntry) { return E_POINTER; } if (0 == pszEntry[0]) { return E_INVALIDARG; } // // Lock the table and retrieve the entry // HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } int iID = -1; hrRet = FindEntry(pszEntry, &iID); //MYDBGASSERT(SUCCEEDED(hrRet)); if (SUCCEEDED(hrRet)) { // // Found, set the state // MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS); m_pConnTable->Connections[iID].CmState = CM_RECONNECTPROMPT; } MYVERIFY(SUCCEEDED(UnlockTable())); return hrRet; } //+---------------------------------------------------------------------------- // // Function: CConnectionTable::ClearEntry // // Synopsis: Clears the specified entry regardless of the usage count. // // Arguments: LPCTSTR pszEntry - The name of the entry to be cleared. // // Returns: HRESULT - Failure code or S_OK // // History: nickball Created 2/2/98 // //+---------------------------------------------------------------------------- HRESULT CConnectionTable::ClearEntry(LPCTSTR pszEntry) { MYDBGASSERT(m_pConnTable); MYDBGASSERT(m_hMap); MYDBGASSERT(pszEntry); CMTRACE1(TEXT("CConnectionTable::ClearEntry(%s)"), pszEntry); if (NULL == m_pConnTable) { return E_ACCESSDENIED; } if (NULL == pszEntry) { return E_POINTER; } if (0 == pszEntry[0]) { return E_INVALIDARG; } // // Lock the table and retrieve the entry // HRESULT hrRet = LockTable(); if (FAILED(hrRet)) { return hrRet; } int iID = -1; hrRet = FindEntry(pszEntry, &iID); if (SUCCEEDED(hrRet)) { // // Found, clear it // MYDBGASSERT(iID >= 0 && iID < MAX_CM_CONNECTIONS); ZeroMemory(&m_pConnTable->Connections[iID], sizeof(CM_CONNECTION)); } MYVERIFY(SUCCEEDED(UnlockTable())); return hrRet; }