#define NO_MFC #define CObject TObject #define CString TString #define CStringArray TString_array #include "NetUtils.h" OsType GetOsType() { OsType ver; DWORD dwVersion = GetVersion(); if (dwVersion < 0x80000000) ver = WINDOWS_NT; else { if (LOBYTE(LOWORD(dwVersion)) < 4) ver = WINDOWS_31; else ver = WINDOWS_95; } return ver; } TLanManager::TLanManager() { } TLanManager::~TLanManager() { RemoveAllConnections(); } TConnection* TLanManager::OnCreateConnection(DWORD id) { return new TConnection(this, id); } BOOL TLanManager::HasConnections() const { #ifdef NO_MFC return m_mapConn.items() > 0; #else return m_mapConn.GetCount() > 0; #endif } BOOL TLanManager::Request(DWORD id, const char* cmd) { TConnection* conn = GetConnection(id) ; return conn ? conn->Request(cmd) : FALSE; } BOOL TLanManager::Execute(DWORD id, const char* cmd) { TConnection* conn = GetConnection(id) ; return conn ? conn->Execute(cmd) : FALSE; } // Physically disconnect BOOL TLanManager::OnRemoveConnection(DWORD id) { return id != NULL; } DWORD TLanManager::AddConnection(TConnection* pConn) { DWORD id = 0; if (pConn) { id = pConn->Id(); #ifdef NO_MFC TString16 key; key.format("%lu", id); m_mapConn.add(key, pConn, TRUE); #else TConnection* c; BOOL ok = m_mapConn.Lookup(id, c); if (ok) delete c; m_mapConn.SetAt(id, pConn); #endif } return id; } BOOL TLanManager::RemoveConnection(DWORD id) { TConnection* pConn = GetConnection(id); BOOL ok = FALSE; if (pConn != NULL && OnRemoveConnection(id)) { #ifdef NO_MFC TString16 key; key.format("%lu", id); m_mapConn.remove(key); #else delete pConn; VERIFY(m_mapConn.RemoveKey(id)); #endif ok = TRUE; } return ok; } void TLanManager::RemoveAllConnections() { TConnection* pConn; #ifdef NO_MFC m_mapConn.restart(); for (pConn = (TConnection*)m_mapConn.get(); pConn; pConn = (TConnection*)m_mapConn.get()) OnRemoveConnection(pConn->Id()); m_mapConn.destroy(); #else for (POSITION pos = m_mapConn.GetStartPosition(); pos != NULL;) { DWORD key; m_mapConn.GetNextAssoc(pos, key, pConn); { OnRemoveConnection(pConn->Id()); delete pConn; } } m_mapConn.RemoveAll(); #endif } TConnection* TLanManager::GetConnection(DWORD id) const { TConnection* pConn = NULL; #ifdef NO_MFC TString16 key; key.format("%lu", id); pConn = (TConnection*)m_mapConn.objptr(key); #else m_mapConn.Lookup(id, pConn); #endif return pConn; } int TLanManager::ForEachConnection(ConnectionFunction f, void* pJolly) { int result = 0; TConnection* pConn; #ifdef NO_MFC m_mapConn.restart(); for (pConn = (TConnection*)m_mapConn.get(); pConn != NULL; pConn = (TConnection*)m_mapConn.get()) result += f(*pConn, pJolly); #else DWORD key; for (POSITION pos = m_mapConn.GetStartPosition(); pos != NULL; ) { m_mapConn.GetNextAssoc(pos, key, pConn); result += f(*pConn, pJolly); } #endif return result; } /////////////////////////////////////////////////////////// // TLanServer /////////////////////////////////////////////////////////// BYTE* TLanServer::GetBufferSetString(const char* str) { if (str == NULL) str = ""; const size_t dwSize = strlen(str)+1; BYTE* buff = GetBuffer(dwSize); memcpy(buff, str, dwSize); return buff; } BYTE* TLanServer::GetBufferSetBool(BOOL n) { const size_t dwSize = sizeof(DWORD); BYTE* buff = GetBuffer(dwSize); *(DWORD*)buff = n ? -1 : 0; return buff; } BYTE* TLanServer::GetBufferSetInteger(long n) { const size_t dwSize = sizeof(DWORD); BYTE* buff = GetBuffer(dwSize); *(DWORD*)buff = n; return buff; } /////////////////////////////////////////////////////////// // TLanClient /////////////////////////////////////////////////////////// DWORD TLanClient::QueryConnection(const char* service, const char* server) { TConnection* pConn = OnQueryConnection(service, server); return AddConnection(pConn) ; } BOOL TLanClient::Execute(DWORD id, const char* cmd) { return FALSE; } BOOL TLanClient::Request(DWORD id, const char* cmd) { return FALSE; } BOOL TLanClient::RequestString(DWORD id, const char* cmd, CString& res) { BOOL valid = Request(id, cmd); if (valid) { DWORD dwSize; BYTE* pData = GetBuffer(dwSize); #ifdef NO_MFC char* ptr = res.get_buffer((int)dwSize); memcpy(ptr, pData, (size_t)dwSize); #else char* ptr = res.GetBuffer((int)dwSize); memcpy(ptr, pData, dwSize); res.ReleaseBuffer(); #endif ReleaseBuffer(); } return valid; } BOOL TLanClient::RequestInteger(DWORD id, const char* cmd, long& num) { BOOL valid = Request(id, cmd); if (valid) { DWORD dwSize; BYTE* pData = GetBuffer(dwSize); num = *(long*)pData; ReleaseBuffer(); } return valid; } BOOL TLanClient::RequestBool(DWORD id, const char* cmd, BOOL& ok) { BOOL valid = Request(id, cmd); if (valid) { DWORD dwSize; BYTE* pData = GetBuffer(dwSize); ok = *(DWORD*)pData != 0; ReleaseBuffer(); } return valid; } /////////////////////////////////////////////////////////// // TConnection /////////////////////////////////////////////////////////// TConnection::TConnection(TLanManager* pManager, DWORD id) : m_pManager(pManager), m_dwId(id) { } TConnection::~TConnection() { } TLanServer& TConnection::Server() const { #ifdef NO_MFC CHECK(Manager().IsServer(), "Can't cast client to server"); #else ASSERT(Manager().IsServer()); #endif return (TLanServer&)Manager(); } int TConnection::ParseCommand(const char* cmd, CStringArray& argv) { #ifdef NO_MFC argv.destroy(); #else argv.RemoveAll(); #endif BOOL is_quoted = FALSE; char end_quote = '\0'; CString token; const char* token_start = NULL; for (char* c = (char*)cmd; *c; c++) { if (end_quote) { if (*c == end_quote) { *c = '\0'; token = token_start; *c = end_quote; end_quote = '\0'; is_quoted = TRUE; } continue; } if (*c == '(' || *c == ')' || *c == ',') { if (token_start) { if (is_quoted) { } else { const char old = *c; *c = '\0'; token = token_start; *c = old; #ifdef NO_MFC token.rtrim(); #else token.TrimRight(); #endif } } #ifdef NO_MFC argv.add(token); #else argv.Add(token); #endif token_start = NULL; token = ""; is_quoted = FALSE; continue; } if (*c == '"' || *c == '\'' || *c == '|' || BYTE(*c) >= 254) { end_quote = *c; token_start = c+1; } if (token_start == NULL && *c > ' ') { token_start = c; } } #ifdef NO_MFC return argv.items(); #else return argv.GetSize(); #endif } BOOL TConnection::Execute(const char* cmd) { CStringArray argv; return ParseCommand(cmd, argv) > 0; } BOOL TConnection::Request(const char* cmd) { CStringArray argv; return ParseCommand(cmd, argv) > 0; }