📄 casynnet.cpp
字号:
m_ClientHandlesMap = new CHXMapPtrToPtr; m_ClientSocketsMap = new CHXMapPtrToPtr; m_ulSession = CAsyncSockN::GetSession(); m_bValid = Create();}// Workhorse construction methodBOOL CAsyncSockN::Create(){ char szClassName[MAX_WND_CLASS_LENGTH]; /* Flawfinder: ignore */ SafeSprintf(szClassName, MAX_WND_CLASS_LENGTH, "%s%d", WND_CLASS_BASE, &zm_bClassRegistered); if (!zm_bClassRegistered) { WNDCLASS internalClass; // First register our window class internalClass.style = 0; internalClass.lpfnWndProc = CAsyncSockN::AsyncNotifyProc; internalClass.cbClsExtra = 0; internalClass.cbWndExtra = sizeof(this); internalClass.hInstance = m_hInst; // Use app's instance internalClass.hIcon = 0; internalClass.hCursor = 0; internalClass.hbrBackground = 0; internalClass.lpszMenuName = NULL; internalClass.lpszClassName = szClassName; zm_bClassRegistered = RegisterClass(&internalClass); if(!zm_bClassRegistered) { UnregisterClass(szClassName, m_hInst); zm_bClassRegistered = RegisterClass(&internalClass); } } // Now create an instance of the window m_hWnd = CreateWindow(szClassName, "RealAudio Internal Messages", WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL, m_hInst, this); if (!m_hWnd) { return (FALSE); } return (TRUE);}// Destructor: Destroys the window and unregisters the class if necessaryCAsyncSockN::~CAsyncSockN(){ // Validate input HX_ASSERT(this); if (!this) { return; } m_bValid = FALSE; // UnlinkUs( this ); m_hWnd = NULL; m_hInst = NULL; if(m_ClientHandlesMap) { delete m_ClientHandlesMap; m_ClientHandlesMap = NULL; m_cbNumHandlesClients = 0; } if(m_ClientSocketsMap) { delete m_ClientSocketsMap; m_ClientSocketsMap = NULL; m_cbNumSocketsClients = 0; }}// This is the WndProc that handles async notifications on behalf of the client// win_net objects.LRESULT HXEXPORT CAsyncSockN::AsyncNotifyProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ CAsyncSockN* pThis = 0; // Make ourselves look like a non-static member function dig the this // pointer out of the window. if (msg == WM_NCCREATE) { CREATESTRUCT* lpCreate = 0; // Set our this pointer, so our WndProc can find us again lpCreate = (CREATESTRUCT FAR*) lParam; pThis = (CAsyncSockN*) lpCreate->lpCreateParams; SetWindowLong(hWnd, OFFSET_THIS, (long) pThis); } else if (msg == WM_NCDESTROY) { // remove our this pointer so if somebody calls this function // again after the window is gone (and the object is gone // too) we don't try to call a method from the pointer SetWindowLong(hWnd, OFFSET_THIS, 0L); } else { // Note: This MUST be a static function // However we make it appear to be a member function // By imbedding a this pointer in the window object pThis = (CAsyncSockN*) (LPHANDLE)GetWindowLong(hWnd, OFFSET_THIS); } if (pThis != NULL) { switch (msg) { case PWM_ASYNC_SELECT: return (pThis->OnAsyncSelect(wParam, lParam)); case PWM_ASYNC_DNS: return (pThis->OnAsyncDNS(wParam, lParam)); default: break; } } return (DefWindowProc(hWnd, msg, wParam, lParam));}LRESULT CAsyncSockN::CheckClients(){ ProcessDNSQueue(); if (!m_bInCancelMode && !m_cbNumHandlesClients && !m_cbNumSocketsClients) { UnlinkUs(this); DestroyWindow(m_hWnd); delete this; } return(TRUE);}// Message handler for PWM_ASYNC_DNS// Notifies the client win_net object that DNS has completed or// returned w/ an error.LRESULT CAsyncSockN::OnAsyncDNS(WPARAM wParam, LPARAM lParam){ void* handle = (void*) (HANDLE) wParam; void* pVoid = 0; win_net* pClient = 0; DNS_REQUEST* pDNSRequest = NULL; // Bail if the client map has been previously deleted, this // is a sure sign of us already being cleaned up! if(!m_ClientHandlesMap) { return(TRUE); } DEBUGOUTSTR( "AsyncDNS come back\r\n" ); // Based on the handle returned, find our client! // Note it might be missing from the map if we canceled // the DNS! if (m_ClientHandlesMap->Lookup(handle, pVoid)) { *((ULONG32 *)&pClient) = (ULONG32)pVoid; // We should already have an async operation active on this socket!#ifdef _DEBUG if ((void *)pClient->m_hAsyncHandle != handle) { char szMessage[256]; /* Flawfinder: ignore */ sprintf(szMessage,"pClient->m_hAsyncHandle = %#lx\nhandle = %#lx", /* Flawfinder: ignore */ pClient->m_hAsyncHandle, handle ); MessageBox(NULL,szMessage,"Oops!",MB_OK); } HX_ASSERT((void *)pClient->m_hAsyncHandle == handle);#endif // Tell win_net object to forget the Async handle pClient->m_hAsyncHandle = NULL; pClient->CB_DNSComplete(!WSAGETASYNCERROR(lParam)); // If async DNS is done, then we can forget the Async handle if (m_ClientHandlesMap->RemoveKey(handle)) { DecrementHandlesClientCount(); } }#ifdef _DEBUG if (m_ClientHandlesMap->GetCount() != m_cbNumHandlesClients) { char szMessage[256]; /* Flawfinder: ignore */ sprintf(szMessage,"m_ClientHandlesMap->GetCount() = %d\nm_cbNumHandlesClients = %d", /* Flawfinder: ignore */ m_ClientHandlesMap->GetCount(), m_cbNumHandlesClients ); MessageBox(NULL,szMessage,"Oops!",MB_OK); } HX_ASSERT(m_ClientHandlesMap->GetCount() == m_cbNumHandlesClients);#endif if (sockGlobals.m_bWinSock2Suck) { pDNSRequest = (DNS_REQUEST*) sockGlobals.m_DNSQueue.RemoveHead(); HX_DELETE(pDNSRequest); } // check to see if we are still in use. CheckClients(); return (TRUE);}// Message handler for PWM_ASYNC_SELECT// Notifies the win_net client when the corresponding socket// is ready to read/write/ or has connected.LRESULT CAsyncSockN::OnAsyncSelect(WPARAM wParam, LPARAM lParam){ LPVOID pVoid; UINT16 theEvent; UINT16 theError; SOCKET theSocket; win_net* pClient = NULL; theSocket = (SOCKET) wParam; theEvent = WSAGETSELECTEVENT(lParam); theError = WSAGETSELECTERROR(lParam); // Find out the win_net object we want to talk to if(m_ClientSocketsMap->Lookup((void*) theSocket, pVoid)) { *((ULONG32 *)&pClient) = (ULONG32) pVoid; } if (!pClient) { DEBUGOUTSTR( "Error OnAsyncSelect() no win_net object found\r\n" ); return(TRUE); } if (theError) { char acError[100]; /* Flawfinder: ignore */ wsprintf(acError, "Got error %d from Winsock\r\n", theError); DEBUGOUTSTR(acError); } switch (theEvent) { case FD_WRITE: DEBUGOUTSTR("Got AsyncWrite notification\r\n"); pClient->CB_ReadWriteNotification(theEvent); break; case FD_READ:#ifndef _DEMPSEY // Noisy debug output DEBUGOUTSTR("Got AsyncRead notification\r\n");#endif // _DEMPSEY pClient->CB_ReadWriteNotification(theEvent); break; case FD_CONNECT: DEBUGOUTSTR("Got AsyncConnect notification\r\n"); pClient->CB_ConnectionComplete(!theError); break; case FD_CLOSE: DEBUGOUTSTR("Got AsyncClose notification\r\n"); pClient->CB_CloseNotification(); break; case FD_ACCEPT: DEBUGOUTSTR("Got AsyncAccept notification\r\n"); pClient->CB_AcceptNotification(); break; } return (TRUE);}// Static method// Inserts us at the head of the listvoid CAsyncSockN::LinkUs(CAsyncSockN* pUs){ HX_ASSERT(pUs); if (!pUs) { return; } // Tack us on at the head of the list since order doesn't matter pUs->m_pNextNotifier = zm_pSockNotifiers; zm_pSockNotifiers = pUs;}// Static method// Removes us from the listvoid CAsyncSockN::UnlinkUs(CAsyncSockN* pUs){ CAsyncSockN* pWalk = 0; HX_ASSERT(pUs); // Don't try to remove NULL pointers if (!pUs) { return; } // If the desired node is at the head then it's simple if (zm_pSockNotifiers == pUs) { zm_pSockNotifiers = pUs->m_pNextNotifier; return; } // Otherwise we have to walk the list till we find our node else { // iterate till we find ourselves or reach the end of the list pWalk = zm_pSockNotifiers; while (pWalk && (pWalk->m_pNextNotifier != pUs)) { pWalk = pWalk->m_pNextNotifier; } // Did we find ourselves? if (pWalk) { // Ok, link to our successor pWalk->m_pNextNotifier = pUs->m_pNextNotifier; } } return;}// Static method// Returns correct notifier object for our current session (thread/task)CAsyncSockN *CAsyncSockN::FindSockNotifier(){ ULONG32 ulSession; CAsyncSockN* pWalk; ulSession = CAsyncSockN::GetSession(); pWalk = CAsyncSockN::zm_pSockNotifiers; while (pWalk && pWalk->m_ulSession != ulSession) { pWalk = pWalk->m_pNextNotifier; } return (pWalk);}DNS_REQUEST::DNS_REQUEST(){ fpSock = NULL; lpHostName = NULL; lpBuffer = NULL; cbBufferSize = 0;}DNS_REQUEST::~DNS_REQUEST(){ HX_VECTOR_DELETE(lpHostName);}SockGlobals::SockGlobals(){}SockGlobals::~SockGlobals(){ while (m_DNSQueue.GetCount()) { DNS_REQUEST* pDNSRequest = (DNS_REQUEST*) m_DNSQueue.RemoveHead(); HX_DELETE(pDNSRequest); } m_DNSQueue.RemoveAll();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -