/*========================================================================== * * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved. * * File: enumsvr.cpp * Content: DirectPlay8 <--> DPNSVR Utility functions * *@@BEGIN_MSINTERNAL * History: * Date By Reason * ==== == ====== * 03/24/00 rmt Created * 03/25/00 rmt Updated to handle new status/table format for n providers * 09/04/00 mjn Changed DPNSVR_Register() and DPNSVR_UnRegister() to use guids directly (rather than ApplicationDesc) *@@END_MSINTERNAL * ***************************************************************************/ #include "dnsvlibi.h" #undef DPF_SUBCOMP #define DPF_SUBCOMP DN_SUBCOMP_DPNSVR #define DPNSVR_WAIT_STARTUP 30000 #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_IsRunning" BOOL DPNSVR_IsRunning() { DNHANDLE hRunningHandle = NULL; // // Check to see if running by opening the running event // hRunningHandle = DNOpenEvent( SYNCHRONIZE, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_RUNNING ); if( hRunningHandle != NULL ) { DNCloseHandle(hRunningHandle); return( TRUE ); } return( FALSE ); } #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_WaitForStartup" HRESULT DPNSVR_WaitForStartup( DNHANDLE hWaitHandle ) { HRESULT hr; LONG lWaitResult; DPFX(DPFPREP,4,"Parameters: (none)" ); // // Wait for startup.. just in case it's starting up. // if ((lWaitResult = DNWaitForSingleObject( hWaitHandle,DPNSVR_WAIT_STARTUP )) == WAIT_TIMEOUT) { DPFX(DPFPREP,5,"Timed out waiting for DPNSVR to startup" ); hr = DPNERR_TIMEDOUT; } else { DPFX(DPFPREP,5,"DPNSVR has started up" ); hr = DPN_OK; } DPFX(DPFPREP,4,"Returning: [0x%lx]",hr ); return( hr ); } #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_SendMessage" HRESULT DPNSVR_SendMessage( void *pvMessage, DWORD dwSize ) { HRESULT hr; CDPNSVRIPCQueue ipcQueue; DPFX(DPFPREP,4,"Parameters: pvMessage [0x%p],dwSize [%ld]",pvMessage,dwSize); if ((hr = ipcQueue.Open( &GUID_DPNSVR_QUEUE,DPNSVR_MSGQ_SIZE,DPNSVR_MSGQ_OPEN_FLAG_NO_CREATE )) == DPN_OK) { if ((hr = ipcQueue.Send(static_cast(pvMessage), dwSize, DPNSVR_TIMEOUT_REQUEST, DPNSVR_MSGQ_MSGFLAGS_USER1, 0 )) != DPN_OK) { DPFX(DPFPREP,5,"Send failed to DPNSVR request queue"); } ipcQueue.Close(); } else { DPFX(DPFPREP,5,"Could not open DPNSVR request queue"); } DPFX(DPFPREP,4,"Returning: [0x%lx]",hr ); return( hr ); } #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_WaitForResult" HRESULT DPNSVR_WaitForResult( CDPNSVRIPCQueue *pQueue ) { HRESULT hr; BYTE *pBuffer = NULL; DWORD dwBufferSize = 0; DPNSVR_MSGQ_HEADER MsgHeader; DPNSVR_MSG_RESULT *pMsgResult; DPFX(DPFPREP,4,"Parameters: pQueue [0x%p]",pQueue); DNASSERT( pQueue != NULL ); if( DNWaitForSingleObject( pQueue->GetReceiveSemaphoreHandle(),DPNSVR_TIMEOUT_RESULT ) == WAIT_TIMEOUT ) { DPFX(DPFPREP,5,"Wait for response timed out" ); hr = DPNERR_TIMEDOUT; goto Failure; } while((hr = pQueue->GetNextMessage( &MsgHeader,pBuffer,&dwBufferSize )) == DPNERR_BUFFERTOOSMALL ) { if (pBuffer) { delete [] pBuffer; pBuffer = NULL; } pBuffer = new BYTE[dwBufferSize]; if( pBuffer==NULL ) { hr = DPNERR_OUTOFMEMORY; goto Failure; } } if (hr != DPN_OK) { goto Failure; } if (pBuffer == NULL) { DPFERR( "Getting message failed" ); hr = DPNERR_GENERIC; goto Failure; } pMsgResult = reinterpret_cast(pBuffer); if( pMsgResult->dwType != DPNSVR_MSGID_RESULT ) { DPFERR( "Invalid message from DPNSVR" ); DPFX(DPFPREP,5,"Recieved [0x%lx]",pMsgResult->dwType ); hr = DPNERR_GENERIC; goto Failure; } hr = pMsgResult->hrCommandResult; Exit: if( pBuffer ) { delete [] pBuffer; pBuffer = NULL; } DPFX(DPFPREP,4,"Returning: [0x%lx]",hr ); return( hr ); Failure: goto Exit; } #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_StartDPNSVR" HRESULT DPNSVR_StartDPNSVR( void ) { HRESULT hr; DNHANDLE hRunningEvent = NULL; DNHANDLE hStartupEvent = NULL; DNPROCESS_INFORMATION pi; #if !defined(WINCE) || defined(WINCE_ON_DESKTOP) TCHAR szSystemDir[MAX_PATH+1]; DWORD dwSystemDirLen; TCHAR *pszApplicationName = NULL; DWORD dwApplicationNameLen; STARTUPINFO si; #endif //!WINCE #if defined(WINCE) && !defined(WINCE_ON_DESKTOP) TCHAR szDPNSVR[] = _T("dpnsvr.exe"); #else // CreateProcess will attempt to add a terminating NULL so this must be writeable #if !defined(DBG) || !defined( DIRECTX_REDIST ) TCHAR szDPNSVR[] = _T("\"dpnsvr.exe\""); #else // For redist debug builds we append a 'd' to the name to allow both debug and retail to be installed on the system TCHAR szDPNSVR[] = _T("\"dpnsvrd.exe\""); #endif // !defined(DBG) || !defined( DIRECTX_REDIST ) #endif DPFX(DPFPREP,4,"Parameters: (none)"); #if !defined(WINCE) || defined(WINCE_ON_DESKTOP) // // Get Windows system directory name // if ((dwSystemDirLen = GetSystemDirectory(szSystemDir,MAX_PATH+1)) == 0) { DPFERR("Could not get system directory"); hr = DPNERR_GENERIC; goto Failure; } // // Create application name for CreateProcess // dwApplicationNameLen = dwSystemDirLen + (1 + _tcslen(_T("dpnsvrd.exe")) + 1); // slash and NULL terminator if ((pszApplicationName = static_cast(DNMalloc(dwApplicationNameLen * sizeof(TCHAR)))) == NULL) { DPFERR("Could not allocate space for application name"); hr = DPNERR_OUTOFMEMORY; goto Failure; } pszApplicationName[0] = _T('\0'); _tcscat(pszApplicationName,szSystemDir); _tcscat(pszApplicationName,_T("\\")); #if !defined(DBG) || !defined( DIRECTX_REDIST ) _tcscat(pszApplicationName,_T("dpnsvr.exe")); #else // // For redist debug builds we append a 'd' to the name to allow both debug and retail to be installed on the system // _tcscat(pszApplicationName,_T("dpnsvrd.exe")); #endif // !defined(DBG) || !defined( DIRECTX_REDIST ) #endif //!WINCE // // Create startup event which we will wait on once we launch DPNSVR // if ((hStartupEvent = DNCreateEvent( DNGetNullDacl(),TRUE,FALSE,GLOBALIZE_STR STRING_GUID_DPNSVR_STARTUP )) == NULL) { DPFERR("Could not create DPNSVR startup event"); hr = DPNERR_OUTOFMEMORY; goto Failure; } // // Attempt to open the running event // if ((hRunningEvent = DNOpenEvent( SYNCHRONIZE, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_RUNNING )) != NULL) { DPFX(DPFPREP,5,"DPNSVR is already running"); hr = DPNSVR_WaitForStartup(hStartupEvent); goto Failure; } #if !defined(WINCE) || defined(WINCE_ON_DESKTOP) memset(&si,0x00,sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); #endif // !WINCE DPFX(DPFPREP,5,"Launching DPNSVR" ); #if defined(WINCE) && !defined(WINCE_ON_DESKTOP) // // WinCE AV's on a NULL first param and requires that Environment and CurrentDirectory be NULL. // It also ignores STARTUPINFO. // if( !DNCreateProcess(szDPNSVR, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, NULL, &pi) ) #else // !WINCE if( !DNCreateProcess(pszApplicationName, szDPNSVR, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi) ) #endif // WINCE { DPFERR("CreateProcess() failed!"); DPFX(DPFPREP,5,"Error = [0x%lx]",GetLastError()); hr = DPNERR_GENERIC; goto Failure; } DNCloseHandle( pi.hProcess ); DNCloseHandle( pi.hThread ); DPFX(DPFPREP,5,"DPNSVR started" ); hr = DPNSVR_WaitForStartup(hStartupEvent); Exit: if ( hRunningEvent != NULL ) { DNCloseHandle( hRunningEvent ); hRunningEvent = NULL; } if ( hStartupEvent != NULL ) { DNCloseHandle( hStartupEvent ); hStartupEvent = NULL; } #if !defined(WINCE) || defined(WINCE_ON_DESKTOP) if (pszApplicationName) { DNFree(pszApplicationName); pszApplicationName = NULL; } #endif // !WINCE DPFX(DPFPREP,4,"Returning: [0x%lx]",hr ); return( hr ); Failure: goto Exit; } // DPNSVR_Register // // This function asks the DPNSVR process to add the application specified to it's list of applications and forward // enumeration requests from the main port to the specified addresses. // // If the DPNSVR process is not running, it will be started by this function. // #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_Register" HRESULT DPNSVR_Register(const GUID *const pguidApplication, const GUID *const pguidInstance, IDirectPlay8Address *const pAddress) { HRESULT hr; BOOL fQueueOpen = FALSE; BYTE *pSendBuffer = NULL; DWORD dwSendBufferSize = 0; DWORD dwURLSize = 0; GUID guidSP; CDPNSVRIPCQueue appQueue; DPNSVR_MSG_OPENPORT *pMsgOpen; DPFX(DPFPREP,2,"Parameters: pguidApplication [0x%p],pguidInstance [0x%p],pAddress [0x%p]", pguidApplication,pguidInstance,pAddress); DNASSERT( pguidApplication != NULL ); DNASSERT( pguidInstance != NULL ); DNASSERT( pAddress != NULL ); // // Get SP and URL size from address // if ((hr = IDirectPlay8Address_GetSP( pAddress,&guidSP )) != DPN_OK) { DPFERR("Could not get SP from address"); DisplayDNError(0,hr); goto Failure; } if ((hr = IDirectPlay8Address_GetURLA( pAddress,reinterpret_cast(pSendBuffer),&dwURLSize )) != DPNERR_BUFFERTOOSMALL) { DPFERR("Could not get URL from address"); DisplayDNError(0,hr); goto Failure; } dwSendBufferSize = sizeof( DPNSVR_MSG_OPENPORT ) + dwURLSize; // // Create message buffer // pSendBuffer = new BYTE[dwSendBufferSize]; if( pSendBuffer == NULL ) { DPFERR("Could not allocate send buffer"); hr = DPNERR_OUTOFMEMORY; goto Failure; } // // Attempt to launch DPNSVR if it has not yet been launched // if ((hr = DPNSVR_StartDPNSVR()) != DPN_OK) { DPFERR("Could not start DPNSVR"); DisplayDNError(0,hr); goto Failure; } // // Open queue // if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK) { DPFERR("Could not open DPNSVR request queue"); DisplayDNError(0,hr); goto Failure; } fQueueOpen = TRUE; // // Create open port message pMsgOpen = (DPNSVR_MSG_OPENPORT*) pSendBuffer; pMsgOpen->Header.dwType = DPNSVR_MSGID_OPENPORT; pMsgOpen->Header.guidInstance = *pguidInstance; pMsgOpen->dwProcessID = GetCurrentProcessId(); pMsgOpen->guidApplication = *pguidApplication; pMsgOpen->guidSP = guidSP; pMsgOpen->dwAddressSize = dwURLSize; if ((hr = IDirectPlay8Address_GetURLA( pAddress,(char *)&pMsgOpen[1],&dwURLSize )) != DPN_OK) { DPFERR("Could not get URL from address"); DisplayDNError(0,hr); goto Failure; } // // Send request to DPNSVR // if ((hr = DPNSVR_SendMessage( pSendBuffer,dwSendBufferSize )) != DPN_OK) { DPFERR("Could not send message to DPNSVR"); DisplayDNError(0,hr); goto Failure; } // // Wait for DPNSVR to respond // if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK) { DPFERR("Could not get response from DPNSVR"); DisplayDNError(0,hr); goto Failure; } Exit: if( pSendBuffer != NULL ) { delete [] pSendBuffer; pSendBuffer = NULL; } if (fQueueOpen) { appQueue.Close(); fQueueOpen = FALSE; } DPFX(DPFPREP,2,"Returning: [0x%lx]",hr); return( hr ); Failure: goto Exit; } #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_UnRegister" HRESULT DPNSVR_UnRegister(const GUID *const pguidApplication,const GUID *const pguidInstance) { HRESULT hr; BOOL fQueueOpen = FALSE; CDPNSVRIPCQueue appQueue; DPNSVR_MSG_CLOSEPORT MsgClose; DPFX(DPFPREP,2,"Parameters: pguidApplication [0x%p],pguidInstance [0x%p]",pguidApplication,pguidInstance); DNASSERT( pguidApplication != NULL ); DNASSERT( pguidInstance != NULL ); // // Ensure DPNSVR is running // if( !DPNSVR_IsRunning() ) { DPFX(DPFPREP,3,"DPNSVR is not running" ); hr = DPNERR_INVALIDAPPLICATION; goto Failure; } // // Open DPNSVR request queue // if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK) { DPFERR("Could not open DPNSVR queue"); DisplayDNError(0,hr); goto Failure; } fQueueOpen = TRUE; // // Create close port message // MsgClose.Header.dwType = DPNSVR_MSGID_CLOSEPORT; MsgClose.Header.guidInstance = *pguidInstance; MsgClose.dwProcessID = GetCurrentProcessId(); MsgClose.guidApplication = *pguidApplication; // // Send message to DPNSVR // if ((hr = DPNSVR_SendMessage( &MsgClose,sizeof(DPNSVR_MSG_CLOSEPORT) )) != DPN_OK) { DPFERR("Could not send message to DPNSVR"); DisplayDNError(0,hr); goto Failure; } // // Wait for DPNSVR to respond // if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK) { DPFERR("Could not get response from DPNSVR"); DisplayDNError(0,hr); goto Failure; } Exit: if (fQueueOpen) { appQueue.Close(); fQueueOpen = FALSE; } DPFX(DPFPREP,2,"Returning: [0x%lx]",hr); return( hr ); Failure: goto Exit; } #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_RequestTerminate" HRESULT DPNSVR_RequestTerminate( const GUID *pguidInstance ) { HRESULT hr; BOOL fQueueOpen = FALSE; CDPNSVRIPCQueue appQueue; DPNSVR_MSG_COMMAND MsgCommand; DPFX(DPFPREP,2,"Parameters: pguidInstance [0x%p]",pguidInstance); DNASSERT( pguidInstance != NULL ); // // Ensure DPNSVR is running // if( !DPNSVR_IsRunning() ) { DPFX(DPFPREP,3,"DPNSVR is not running" ); hr = DPNERR_INVALIDAPPLICATION; goto Failure; } // // Open DPNSVR request queue // if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK) { DPFERR("Could not open DPNSVR queue"); DisplayDNError(0,hr); goto Failure; } fQueueOpen = TRUE; // // Create terminate message // MsgCommand.Header.dwType = DPNSVR_MSGID_COMMAND; MsgCommand.Header.guidInstance = *pguidInstance; MsgCommand.dwCommand = DPNSVR_COMMAND_KILL; MsgCommand.dwParam1 = 0; MsgCommand.dwParam2 = 0; // // Send message to DPNSVR // if ((hr = DPNSVR_SendMessage( &MsgCommand,sizeof(DPNSVR_MSG_COMMAND) )) != DPN_OK) { DPFERR("Could not send message to DPNSVR"); DisplayDNError(0,hr); goto Failure; } // // Wait for DPNSVR to respond // if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK) { DPFERR("Could not get response from DPNSVR"); DisplayDNError(0,hr); goto Failure; } Exit: if (fQueueOpen) { appQueue.Close(); fQueueOpen = FALSE; } DPFX(DPFPREP,2,"Returning: [0x%lx]",hr); return hr; Failure: goto Exit; } #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_RequestStatus" HRESULT DPNSVR_RequestStatus( const GUID *pguidInstance,PSTATUSHANDLER pStatusHandler,PVOID pvContext ) { HRESULT hr; CDPNSVRIPCQueue appQueue; DPNSVR_MSG_COMMAND dpnCommand; DNHANDLE hStatusMutex = NULL; DNHANDLE hStatusSharedMemory = NULL; void *pServerStatus = NULL; DWORD dwSize; BOOL fOpened = FALSE; BOOL fHaveMutex = FALSE; // // Ensure DPNSVR is running // if( !DPNSVR_IsRunning() ) { DPFERR( "DPNSVR is not running" ); hr = DPNERR_INVALIDAPPLICATION; goto Failure; } // // Open DPNSVR request queue // if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK) { DPFERR( "Failed to open DPNSVR request queue" ); DisplayDNError( 0,hr ); goto Failure; } fOpened = TRUE; // // Create request // dpnCommand.Header.dwType = DPNSVR_MSGID_COMMAND; dpnCommand.Header.guidInstance = *pguidInstance; dpnCommand.dwCommand = DPNSVR_COMMAND_STATUS; dpnCommand.dwParam1 = 0; dpnCommand.dwParam2 = 0; // // Send command request to DPNSVR // if ((hr = DPNSVR_SendMessage( &dpnCommand,sizeof(DPNSVR_MSG_COMMAND) )) != DPN_OK) { DPFERR( "Failed to send command to DPNSVR request queue" ); DisplayDNError( 0,hr ); goto Failure; } // // Wait for DPNSVR to respond // if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK) { DPFERR( "Failed to receive response from DPNSVR" ); DisplayDNError( 0,hr ); goto Failure; } #ifdef WINNT hStatusMutex = DNOpenMutex( SYNCHRONIZE, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_STATUSSTORAGE ); #else hStatusMutex = DNOpenMutex( MUTEX_ALL_ACCESS, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_STATUSSTORAGE ); #endif // WINNT if( hStatusMutex == NULL ) { DPFERR( "Server exited before table was retrieved" ); hr = DPNERR_INVALIDAPPLICATION; goto Failure; } // // Get mutex for shared memory // DNWaitForSingleObject( hStatusMutex, INFINITE ); fHaveMutex = TRUE; // // Map shared memory // if ((hStatusSharedMemory = DNOpenFileMapping(FILE_MAP_READ,FALSE,STRING_GUID_DPNSVR_STATUS_MEMORY)) == NULL) { hr = GetLastError(); DPFERR( "Unable to open file mapping" ); DisplayDNError( 0,hr ); goto Failure; } if ((pServerStatus = MapViewOfFile( HANDLE_FROM_DNHANDLE(hStatusSharedMemory), FILE_MAP_READ, 0, 0, sizeof(DPNSVR_STATUSHEADER)) ) == NULL) { hr = GetLastError(); DPFERR( "Unable to map view of file" ); DisplayDNError( 0,hr ); goto Failure; } dwSize = sizeof(DPNSVR_STATUSHEADER) + (static_cast(pServerStatus)->dwSPCount * sizeof(DPNSVR_SPSTATUS)); UnmapViewOfFile( pServerStatus ); pServerStatus = NULL; if ((pServerStatus = MapViewOfFile( HANDLE_FROM_DNHANDLE(hStatusSharedMemory), FILE_MAP_READ, 0, 0, dwSize) ) == NULL) { hr = GetLastError(); DPFERR( "Unable to re-map view of file" ); DisplayDNError( 0,hr ); goto Failure; } (*pStatusHandler)(pServerStatus,pvContext); DNReleaseMutex( hStatusMutex ); fHaveMutex = FALSE; hr = DPN_OK; Exit: if ( hStatusMutex ) { if ( fHaveMutex ) { DNReleaseMutex( hStatusMutex ); fHaveMutex = FALSE; } DNCloseHandle( hStatusMutex ); hStatusMutex = NULL; } if ( fOpened ) { appQueue.Close(); fOpened = FALSE; } if( pServerStatus ) { UnmapViewOfFile(pServerStatus); pServerStatus = NULL; } if( hStatusSharedMemory ) { DNCloseHandle(hStatusSharedMemory); hStatusSharedMemory = NULL; } return( hr ); Failure: goto Exit; } #undef DPF_MODNAME #define DPF_MODNAME "DPNSVR_RequestTable" HRESULT DPNSVR_RequestTable( const GUID *pguidInstance,PTABLEHANDLER pTableHandler,PVOID pvContext ) { HRESULT hr; CDPNSVRIPCQueue appQueue; DPNSVR_MSG_COMMAND dpnCommand; DNHANDLE hTableMutex = NULL; DNHANDLE hSharedMemory = NULL; void *pServerTable = NULL; DWORD dwSize; BOOL fOpened = FALSE; BOOL fHaveMutex = FALSE; // // Ensure DPNSVR is running // if( !DPNSVR_IsRunning() ) { DPFERR( "DPNSVR is not running" ); hr = DPNERR_INVALIDAPPLICATION; goto Failure; } // // Open DPNSVR request queue // if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK) { DPFERR( "Failed to open DPNSVR request queue" ); DisplayDNError( 0,hr ); goto Failure; } fOpened = TRUE; // // Create request // dpnCommand.Header.dwType = DPNSVR_MSGID_COMMAND; dpnCommand.Header.guidInstance = *pguidInstance; dpnCommand.dwCommand = DPNSVR_COMMAND_TABLE; dpnCommand.dwParam1 = 0; dpnCommand.dwParam2 = 0; // // Send command request to DPNSVR // if ((hr = DPNSVR_SendMessage( &dpnCommand,sizeof(DPNSVR_MSG_COMMAND) )) != DPN_OK) { DPFERR( "Failed to send command to DPNSVR request queue" ); DisplayDNError( 0,hr ); goto Failure; } // // Wait for DPNSVR to respond // if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK) { DPFERR( "Failed to receive response from DPNSVR" ); DisplayDNError( 0,hr ); goto Failure; } #ifdef WINNT hTableMutex = DNOpenMutex( SYNCHRONIZE, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_TABLESTORAGE ); #else hTableMutex = DNOpenMutex( MUTEX_ALL_ACCESS, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_TABLESTORAGE ); #endif // WINNT if( hTableMutex == NULL ) { DPFERR( "Server exited before table was retrieved" ); hr = DPNERR_INVALIDAPPLICATION; goto Failure; } // // Get mutex for shared memory // DNWaitForSingleObject( hTableMutex, INFINITE ); fHaveMutex = TRUE; // // Map shared memory // if ((hSharedMemory = DNOpenFileMapping(FILE_MAP_READ,FALSE,STRING_GUID_DPNSVR_TABLE_MEMORY)) == NULL) { hr = GetLastError(); DPFERR( "Unable to open file mapping" ); DisplayDNError( 0,hr ); goto Failure; } if ((pServerTable = MapViewOfFile( HANDLE_FROM_DNHANDLE(hSharedMemory), FILE_MAP_READ, 0, 0, sizeof(DPNSVR_TABLEHEADER)) ) == NULL) { hr = GetLastError(); DPFERR( "Unable to map view of file" ); DisplayDNError( 0,hr ); goto Failure; } dwSize = static_cast(pServerTable)->dwTableSize; UnmapViewOfFile( pServerTable ); pServerTable = NULL; if ((pServerTable = MapViewOfFile( HANDLE_FROM_DNHANDLE(hSharedMemory), FILE_MAP_READ, 0, 0, dwSize) ) == NULL) { hr = GetLastError(); DPFERR( "Unable to re-map view of file" ); DisplayDNError( 0,hr ); goto Failure; } (*pTableHandler)(pServerTable,pvContext); DNReleaseMutex( hTableMutex ); fHaveMutex = FALSE; hr = DPN_OK; Exit: if ( hTableMutex ) { if ( fHaveMutex ) { DNReleaseMutex( hTableMutex ); fHaveMutex = FALSE; } DNCloseHandle( hTableMutex ); hTableMutex = NULL; } if ( fOpened ) { appQueue.Close(); fOpened = FALSE; } if( pServerTable ) { UnmapViewOfFile(pServerTable); pServerTable = NULL; } if( hSharedMemory ) { DNCloseHandle(hSharedMemory); hSharedMemory = NULL; } return( hr ); Failure: goto Exit; }