casynnet.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 786 行 · 第 1/2 页
CPP
786 行
m_ClientHandlesMap = new CHXMapPtrToPtr;
m_ClientSocketsMap = new CHXMapPtrToPtr;
m_ulSession = CAsyncSockN::GetSession();
m_bValid = Create();
}
// Workhorse construction method
BOOL 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 necessary
CAsyncSockN::~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 list
void 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 list
void 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 + =
减小字号Ctrl + -
显示快捷键?