1314 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1314 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*==========================================================================
 | 
						|
 *
 | 
						|
 *  Copyright (C) 1998-2000 Microsoft Corporation.  All Rights Reserved.
 | 
						|
 *
 | 
						|
 *  File:       Utils.cpp
 | 
						|
 *  Content:	Serial service provider utility functions
 | 
						|
 *
 | 
						|
 *
 | 
						|
 *  History:
 | 
						|
 *   Date		By		Reason
 | 
						|
 *   ====		==		======
 | 
						|
 *	11/25/98	jtk		Created
 | 
						|
 ***************************************************************************/
 | 
						|
 | 
						|
#include "dnwsocki.h"
 | 
						|
 | 
						|
 | 
						|
#undef DPF_SUBCOMP
 | 
						|
#define DPF_SUBCOMP DN_SUBCOMP_WSOCK
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// Constant definitions
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
#define	DEFAULT_WIN9X_THREADS	2
 | 
						|
 | 
						|
#define REGSUBKEY_DPNATHELP_DIRECTPLAY8PRIORITY		L"DirectPlay8Priority"
 | 
						|
#define REGSUBKEY_DPNATHELP_DIRECTPLAY8INITFLAGS	L"DirectPlay8InitFlags"
 | 
						|
#define REGSUBKEY_DPNATHELP_GUID					L"Guid"
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// Macro definitions
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// Structure definitions
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// Variable definitions
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
//
 | 
						|
// global variables that are unique for the process
 | 
						|
//
 | 
						|
static	DNCRITICAL_SECTION		g_InterfaceGlobalsLock;
 | 
						|
 | 
						|
static volatile	LONG			g_iThreadPoolRefCount = 0;
 | 
						|
static	CThreadPool *			g_pThreadPool = NULL;
 | 
						|
 | 
						|
 | 
						|
static	DWSSTATE				g_dwsState;		// state info for the WS1/2 glue lib
 | 
						|
static volatile LONG			g_iWinsockRefCount = 0;
 | 
						|
 | 
						|
 | 
						|
static volatile LONG			g_iNATHelpRefCount = 0;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// Function prototypes
 | 
						|
//**********************************************************************
 | 
						|
static void			ReadSettingsFromRegistry( void );
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// Function definitions
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// ReadSettingsFromRegistry - read custom registry keys
 | 
						|
//
 | 
						|
// Entry:		Nothing
 | 
						|
//
 | 
						|
// Exit:		Nothing
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "ReadSettingsFromRegistry"
 | 
						|
 | 
						|
static void	ReadSettingsFromRegistry( void )
 | 
						|
{
 | 
						|
	CRegistry	RegObject;
 | 
						|
	CRegistry	RegObjectTemp;
 | 
						|
	CRegistry	RegObjectAppEntry;
 | 
						|
	DWORD		dwRegValue;
 | 
						|
	BOOL		fGotPath;
 | 
						|
	WCHAR		wszExePath[_MAX_PATH];
 | 
						|
#ifndef WINNT
 | 
						|
	char		szExePath[_MAX_PATH];
 | 
						|
#endif // ! WINNT
 | 
						|
 | 
						|
 | 
						|
	if ( RegObject.Open( HKEY_LOCAL_MACHINE, g_RegistryBase ) != FALSE )
 | 
						|
	{
 | 
						|
 | 
						|
		//
 | 
						|
		// read receive buffer size
 | 
						|
		//
 | 
						|
		if ( RegObject.ReadDWORD( g_RegistryKeyReceiveBufferSize, dwRegValue ) != FALSE )
 | 
						|
		{
 | 
						|
			g_fWinsockReceiveBufferSizeOverridden = TRUE;
 | 
						|
			g_iWinsockReceiveBufferSize = dwRegValue;
 | 
						|
		}
 | 
						|
	
 | 
						|
		//
 | 
						|
		// read buffer multiplier, make sure this does note get set to zero
 | 
						|
		//
 | 
						|
		if ( RegObject.ReadDWORD( g_RegistryKeyReceiveBufferMultiplier, dwRegValue ) != FALSE )
 | 
						|
		{
 | 
						|
			if ( dwRegValue != 0 )
 | 
						|
			{
 | 
						|
				g_dwWinsockReceiveBufferMultiplier = dwRegValue;
 | 
						|
				DPFX(DPFPREP,  3, "Setting Winsock receive buffer multiplier to: %d", dwRegValue );
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		//
 | 
						|
		// read default threads
 | 
						|
		//
 | 
						|
		if ( RegObject.ReadDWORD( g_RegistryKeyThreadCount, dwRegValue ) != FALSE )
 | 
						|
		{
 | 
						|
			g_iThreadCount = dwRegValue;	
 | 
						|
		}
 | 
						|
	
 | 
						|
		//
 | 
						|
		// if thread count is zero, use the 'default' for the system
 | 
						|
		//
 | 
						|
		if ( g_iThreadCount == 0 )
 | 
						|
		{
 | 
						|
#ifdef WIN95
 | 
						|
			g_iThreadCount = DEFAULT_WIN9X_THREADS;
 | 
						|
#else // WINNT
 | 
						|
			SYSTEM_INFO		SystemInfo;
 | 
						|
			
 | 
						|
 | 
						|
			//
 | 
						|
			// as suggested by 'Multithreading Applications in Win32' book:
 | 
						|
			// dwNTThreadCount = ( ( processors * 2 ) + 2 )
 | 
						|
			//
 | 
						|
			memset( &SystemInfo, 0x00, sizeof( SystemInfo ) );
 | 
						|
			GetSystemInfo( &SystemInfo );
 | 
						|
			
 | 
						|
			g_iThreadCount = ( ( 2 * SystemInfo.dwNumberOfProcessors ) + 2 );
 | 
						|
#endif
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		//
 | 
						|
		// get global NAT traversal disablers, ignore registry reading error
 | 
						|
		//
 | 
						|
		RegObject.ReadBOOL( g_RegistryKeyDisableDPNHGatewaySupport, g_fDisableDPNHGatewaySupport );
 | 
						|
		RegObject.ReadBOOL( g_RegistryKeyDisableDPNHFirewallSupport, g_fDisableDPNHFirewallSupport );
 | 
						|
 | 
						|
		//
 | 
						|
		// get NAT Help alert mechanism disabler, ignore registry reading error
 | 
						|
		//
 | 
						|
		RegObject.ReadBOOL( g_RegistryKeyUseNATHelpAlert, g_fUseNATHelpAlert );
 | 
						|
 | 
						|
 | 
						|
		//
 | 
						|
		// Find out the current process name and see if enums are disabled.
 | 
						|
		//
 | 
						|
#ifdef WINNT
 | 
						|
		if (GetModuleFileNameW(NULL, wszExePath, _MAX_PATH) > 0)
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP, 3, "Loading DLL in process: %S", wszExePath);
 | 
						|
			_wsplitpath( wszExePath, NULL, NULL, wszExePath, NULL );
 | 
						|
			fGotPath = TRUE;
 | 
						|
		}
 | 
						|
#else // ! WINNT
 | 
						|
		if (GetModuleFileNameA(NULL, szExePath, _MAX_PATH) > 0)
 | 
						|
		{
 | 
						|
			HRESULT		hr;
 | 
						|
 | 
						|
			
 | 
						|
			DPFX(DPFPREP, 3, "Loading DLL in process: %s", szExePath);
 | 
						|
			_splitpath( szExePath, NULL, NULL, szExePath, NULL );
 | 
						|
 | 
						|
			dwRegValue = _MAX_PATH;
 | 
						|
			hr = STR_AnsiToWide(szExePath, -1, wszExePath, &dwRegValue );
 | 
						|
			if ( hr == DPN_OK )
 | 
						|
			{
 | 
						|
				//
 | 
						|
				// Successfully converted ANSI path to Wide characters.
 | 
						|
				//
 | 
						|
				fGotPath = TRUE;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				//
 | 
						|
				// Couldn't convert ANSI path to Wide characters
 | 
						|
				//
 | 
						|
				fGotPath = FALSE;
 | 
						|
			}
 | 
						|
		}
 | 
						|
#endif // ! WINNT
 | 
						|
		else
 | 
						|
		{
 | 
						|
			//
 | 
						|
			// Couldn't get current process path.
 | 
						|
			//
 | 
						|
			fGotPath = FALSE;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		//
 | 
						|
		// If we have an app name, try opening the subkey and looking up the app
 | 
						|
		// to see if enums are disabled or there are IP addresses to ban.
 | 
						|
		//
 | 
						|
		if ( fGotPath )
 | 
						|
		{
 | 
						|
			if ( RegObjectTemp.Open( RegObject.GetHandle(), g_RegistryKeyAppsToIgnoreEnums, TRUE, FALSE ) )
 | 
						|
			{
 | 
						|
				RegObjectTemp.ReadBOOL( wszExePath, g_fIgnoreEnums );
 | 
						|
				RegObjectTemp.Close();
 | 
						|
 | 
						|
				if ( g_fIgnoreEnums )
 | 
						|
				{
 | 
						|
					DPFX(DPFPREP, 0, "Ignoring all enumerations (app = %S).", wszExePath);
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					DPFX(DPFPREP, 2, "Not ignoring all enumerations (app = %S).", wszExePath);
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
#ifdef IPBANNING
 | 
						|
			if ( RegObjectTemp.Open( RegObject.GetHandle(), g_RegistryKeyAppsToBanIPs, TRUE, FALSE ) )
 | 
						|
			{
 | 
						|
				if ( RegObjectAppEntry.Open( RegObjectTemp.GetHandle(), wszExePath, TRUE, FALSE ) )
 | 
						|
				{
 | 
						|
					RegObjectTemp.Close();
 | 
						|
 | 
						|
					RegObjectAppEntry.EnumValues( wszExePath, g_fIgnoreEnums );
 | 
						|
 | 
						|
					//
 | 
						|
					// Read in IP addresses to ban from registry.
 | 
						|
					//
 | 
						|
					/*
 | 
						|
					if ( ? )
 | 
						|
					{
 | 
						|
					}
 | 
						|
					else
 | 
						|
					{
 | 
						|
					}
 | 
						|
					*/
 | 
						|
 | 
						|
					RegObjectAppEntry.Close();
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					RegObjectTemp.Close();
 | 
						|
				}
 | 
						|
			}
 | 
						|
#endif // IPBANNING
 | 
						|
		}
 | 
						|
	
 | 
						|
 | 
						|
		//
 | 
						|
		// Get the proxy support options, ignore registry reading error.
 | 
						|
		//
 | 
						|
		RegObject.ReadBOOL( g_RegistryKeyDontAutoDetectProxyLSP, g_fDontAutoDetectProxyLSP );
 | 
						|
		RegObject.ReadBOOL( g_RegistryKeyTreatAllResponsesAsProxied, g_fTreatAllResponsesAsProxied );
 | 
						|
 | 
						|
 | 
						|
		RegObject.Close();
 | 
						|
	}
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// InitProcessGlobals - initialize the global items needed for the SP to operate
 | 
						|
//
 | 
						|
// Entry:		Nothing
 | 
						|
//
 | 
						|
// Exit:		Boolean indicating success
 | 
						|
//				TRUE = success
 | 
						|
//				FALSE = failure
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "InitProcessGlobals"
 | 
						|
 | 
						|
BOOL	InitProcessGlobals( void )
 | 
						|
{
 | 
						|
	BOOL		fReturn;
 | 
						|
	BOOL		fCriticalSectionInitialized;
 | 
						|
 | 
						|
 | 
						|
	//
 | 
						|
	// initialize
 | 
						|
	//
 | 
						|
	fReturn = TRUE;
 | 
						|
	fCriticalSectionInitialized = FALSE;
 | 
						|
 | 
						|
	ReadSettingsFromRegistry();
 | 
						|
 | 
						|
	if ( DNInitializeCriticalSection( &g_InterfaceGlobalsLock ) == FALSE )
 | 
						|
	{
 | 
						|
		fReturn = FALSE;
 | 
						|
		goto Failure;
 | 
						|
	}
 | 
						|
 | 
						|
	fCriticalSectionInitialized = TRUE;
 | 
						|
	
 | 
						|
 | 
						|
	if ( InitializePools() == FALSE )
 | 
						|
	{
 | 
						|
		fReturn = FALSE;
 | 
						|
		goto Failure;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	DNASSERT( g_pThreadPool == NULL );
 | 
						|
 | 
						|
 | 
						|
Exit:
 | 
						|
	return	fReturn;
 | 
						|
 | 
						|
Failure:
 | 
						|
 | 
						|
	if ( fCriticalSectionInitialized != FALSE )
 | 
						|
	{
 | 
						|
		DNDeleteCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
		fCriticalSectionInitialized = FALSE;
 | 
						|
	}
 | 
						|
 | 
						|
	goto Exit;
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// DeinitProcessGlobals - deinitialize the global items
 | 
						|
//
 | 
						|
// Entry:		Nothing
 | 
						|
//
 | 
						|
// Exit:		Nothing
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "DeinitProcessGlobals"
 | 
						|
 | 
						|
void	DeinitProcessGlobals( void )
 | 
						|
{
 | 
						|
	DNASSERT( g_pThreadPool == NULL );
 | 
						|
	DNASSERT( g_iThreadPoolRefCount == 0 );
 | 
						|
 | 
						|
	DeinitializePools();
 | 
						|
	DNDeleteCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// LoadWinsock - load Winsock module into memory
 | 
						|
//
 | 
						|
// Entry:		Nothing
 | 
						|
//
 | 
						|
// Exit:		Boolean indicating success
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "LoadWinsock"
 | 
						|
 | 
						|
BOOL	LoadWinsock( void )
 | 
						|
{
 | 
						|
	BOOL	fReturn = TRUE;
 | 
						|
	INT_PTR	iVersion;
 | 
						|
 | 
						|
	
 | 
						|
	DNEnterCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
 | 
						|
	if ( g_iWinsockRefCount == 0 )
 | 
						|
	{
 | 
						|
		//
 | 
						|
		// initialize the bindings to Winsock
 | 
						|
		//
 | 
						|
		iVersion = DWSInitWinSock( &g_dwsState );
 | 
						|
		if ( iVersion == 0 )	// failure
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP, 0, "Problem binding dynamic winsock functions!" );
 | 
						|
			fReturn = FALSE;
 | 
						|
			goto Failure;
 | 
						|
		}
 | 
						|
		
 | 
						|
		DPFX(DPFPREP, 8, "Detected WinSock version %d.%d", LOBYTE( iVersion ), HIBYTE( iVersion ) );	
 | 
						|
	}
 | 
						|
 | 
						|
	DNInterlockedIncrement( &g_iWinsockRefCount );
 | 
						|
 | 
						|
Exit:
 | 
						|
	DNLeaveCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
	return	fReturn;
 | 
						|
 | 
						|
Failure:
 | 
						|
	goto Exit;
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// UnloadWinsock - unload Winsock module
 | 
						|
//
 | 
						|
// Entry:		Nothing
 | 
						|
//
 | 
						|
// Exit:		Nothing
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "UnloadWinsock"
 | 
						|
 | 
						|
void	UnloadWinsock( void )
 | 
						|
{
 | 
						|
	DNEnterCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
 | 
						|
	if ( DNInterlockedDecrement( &g_iWinsockRefCount ) == 0 )
 | 
						|
	{
 | 
						|
		BOOL	fFreeReturn;
 | 
						|
 | 
						|
 | 
						|
		fFreeReturn = DWSFreeWinSock( &g_dwsState );
 | 
						|
		if ( fFreeReturn == FALSE )
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  0, "Problem unbinding dynamic WinSock functions!" );
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  6, "Successfully unbound dynamic WinSock functions." );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	DNLeaveCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
#ifdef WIN95
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// GetWinsockVersion - get the version of Winsock
 | 
						|
//
 | 
						|
// Entry:		Nothing
 | 
						|
//
 | 
						|
// Exit:		Winsock version
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "GetWinsockVersion"
 | 
						|
 | 
						|
INT	GetWinsockVersion( void )
 | 
						|
{
 | 
						|
	return	g_dwsState.nVersion;
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// LoadNATHelp - create and initialize NAT Help object(s)
 | 
						|
//
 | 
						|
// Entry:		Nothing
 | 
						|
//
 | 
						|
// Exit:		TRUE if some objects were successfully loaded, FALSE otherwise
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "LoadNATHelp"
 | 
						|
 | 
						|
BOOL LoadNATHelp(void)
 | 
						|
{
 | 
						|
	BOOL		fReturn;
 | 
						|
	HRESULT		hr;
 | 
						|
	CRegistry	RegEntry;
 | 
						|
	CRegistry	RegSubentry;
 | 
						|
	DWORD		dwMaxKeyLen;
 | 
						|
	WCHAR *		pwszKeyName = NULL;
 | 
						|
	DWORD		dwEnumIndex;
 | 
						|
	DWORD		dwKeyLen;
 | 
						|
	DWORD		dwDirectPlay8Priority;
 | 
						|
	DWORD		dwDirectPlay8InitFlags;
 | 
						|
	DWORD		dwNumLoaded;
 | 
						|
	GUID		guid;
 | 
						|
 | 
						|
	
 | 
						|
	DNEnterCriticalSection(&g_InterfaceGlobalsLock);
 | 
						|
 | 
						|
	if ( g_iNATHelpRefCount == 0 )
 | 
						|
	{
 | 
						|
		//
 | 
						|
		// Enumerate all the DirectPlayNAT Helpers.
 | 
						|
		//
 | 
						|
		if (! RegEntry.Open(HKEY_LOCAL_MACHINE, DIRECTPLAYNATHELP_REGKEY, TRUE, FALSE))
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  0, "Couldn't open DirectPlayNATHelp registry key!");
 | 
						|
			goto Failure;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		//
 | 
						|
		// Find length of largest subkey.
 | 
						|
		//
 | 
						|
		if (!RegEntry.GetMaxKeyLen(dwMaxKeyLen))
 | 
						|
		{
 | 
						|
			DPFERR("RegistryEntry.GetMaxKeyLen() failed!");
 | 
						|
			goto Failure;
 | 
						|
		}
 | 
						|
		
 | 
						|
		dwMaxKeyLen++;	// Null terminator
 | 
						|
		DPFX(DPFPREP, 9, "dwMaxKeyLen = %ld", dwMaxKeyLen);
 | 
						|
 | 
						|
		pwszKeyName = (WCHAR*) DNMalloc(dwMaxKeyLen * sizeof(WCHAR));
 | 
						|
		if (pwszKeyName == NULL)
 | 
						|
		{
 | 
						|
			DPFERR("DNMalloc() failed");
 | 
						|
			goto Failure;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		//
 | 
						|
		// Allocate an array to hold the helper objects.
 | 
						|
		//
 | 
						|
		g_papNATHelpObjects = (IDirectPlayNATHelp**) DNMalloc(MAX_NUM_DIRECTPLAYNATHELPERS * sizeof(IDirectPlayNATHelp*));
 | 
						|
		if (g_papNATHelpObjects == NULL)
 | 
						|
		{
 | 
						|
			DPFERR("DNMalloc() failed");
 | 
						|
			goto Failure;
 | 
						|
		}
 | 
						|
		ZeroMemory(g_papNATHelpObjects,
 | 
						|
					(MAX_NUM_DIRECTPLAYNATHELPERS * sizeof(IDirectPlayNATHelp*)));
 | 
						|
 | 
						|
		
 | 
						|
		dwEnumIndex = 0;
 | 
						|
		dwNumLoaded = 0;
 | 
						|
 | 
						|
		//
 | 
						|
		// Enumerate the DirectPlay NAT helpers.
 | 
						|
		//
 | 
						|
		do
 | 
						|
		{
 | 
						|
			dwKeyLen = dwMaxKeyLen;
 | 
						|
			if (! RegEntry.EnumKeys(pwszKeyName, &dwKeyLen, dwEnumIndex))
 | 
						|
			{
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			dwEnumIndex++;
 | 
						|
			
 | 
						|
	
 | 
						|
			DPFX(DPFPREP, 8, "%ld - %S (%ld)", dwEnumIndex, pwszKeyName, dwKeyLen);
 | 
						|
			
 | 
						|
			if (!RegSubentry.Open(RegEntry, pwszKeyName, TRUE, FALSE))
 | 
						|
			{
 | 
						|
				DPFX(DPFPREP, 0, "Couldn't open subentry \"%S\"! Skipping.", pwszKeyName);
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
 | 
						|
			//
 | 
						|
			// Read the DirectPlay8 priority
 | 
						|
			//
 | 
						|
			if (!RegSubentry.ReadDWORD(REGSUBKEY_DPNATHELP_DIRECTPLAY8PRIORITY, dwDirectPlay8Priority))
 | 
						|
			{
 | 
						|
				DPFX(DPFPREP, 0, "RegSubentry.ReadDWORD \"%S\\%S\" failed!  Skipping.",
 | 
						|
					pwszKeyName, REGSUBKEY_DPNATHELP_DIRECTPLAY8PRIORITY);
 | 
						|
				RegSubentry.Close();
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
 | 
						|
			//
 | 
						|
			// Read the DirectPlay8 initialization flags
 | 
						|
			//
 | 
						|
			if (!RegSubentry.ReadDWORD(REGSUBKEY_DPNATHELP_DIRECTPLAY8INITFLAGS, dwDirectPlay8InitFlags))
 | 
						|
			{
 | 
						|
				DPFX(DPFPREP, 0, "RegSubentry.ReadDWORD \"%S\\%S\" failed!  Defaulting to 0.",
 | 
						|
					pwszKeyName, REGSUBKEY_DPNATHELP_DIRECTPLAY8INITFLAGS);
 | 
						|
				dwDirectPlay8InitFlags = 0;
 | 
						|
			}
 | 
						|
 | 
						|
			
 | 
						|
			//
 | 
						|
			// Read the object's CLSID.
 | 
						|
			//
 | 
						|
			if (!RegSubentry.ReadGUID(REGSUBKEY_DPNATHELP_GUID, guid))
 | 
						|
			{
 | 
						|
				DPFX(DPFPREP, 0,"RegSubentry.ReadGUID \"%S\\%S\" failed!  Skipping.",
 | 
						|
					pwszKeyName, REGSUBKEY_DPNATHELP_GUID);
 | 
						|
				RegSubentry.Close();
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
 | 
						|
			//
 | 
						|
			// Close the subkey.
 | 
						|
			//
 | 
						|
			RegSubentry.Close();
 | 
						|
 | 
						|
 | 
						|
			//
 | 
						|
			// If this helper should be loaded, do so.
 | 
						|
			//
 | 
						|
			if (dwDirectPlay8Priority != 0)
 | 
						|
			{
 | 
						|
				//
 | 
						|
				// Make sure this priority is valid.
 | 
						|
				//
 | 
						|
				if (dwDirectPlay8Priority > MAX_NUM_DIRECTPLAYNATHELPERS)
 | 
						|
				{
 | 
						|
					DPFX(DPFPREP, 0, "Ignoring DirectPlay NAT helper \"%S\" with invalid priority level set too high (%u > %u).",
 | 
						|
						pwszKeyName, dwDirectPlay8Priority, MAX_NUM_DIRECTPLAYNATHELPERS);
 | 
						|
					continue;
 | 
						|
				}
 | 
						|
 | 
						|
 | 
						|
				//
 | 
						|
				// Make sure this priority hasn't already been taken.
 | 
						|
				//
 | 
						|
				if (g_papNATHelpObjects[dwDirectPlay8Priority - 1] != NULL)
 | 
						|
				{
 | 
						|
					DPFX(DPFPREP, 0, "Ignoring DirectPlay NAT helper \"%S\" with duplicate priority level %u (existing object = 0x%p).",
 | 
						|
						pwszKeyName, dwDirectPlay8Priority,
 | 
						|
						g_papNATHelpObjects[dwDirectPlay8Priority - 1]);
 | 
						|
					continue;
 | 
						|
				}
 | 
						|
				
 | 
						|
 | 
						|
				//
 | 
						|
				// Try to create the NAT Help object.  COM should have been
 | 
						|
 				// initialized by now by someone else.
 | 
						|
				//
 | 
						|
				hr = COM_CoCreateInstance(guid,
 | 
						|
										NULL,
 | 
						|
										CLSCTX_INPROC_SERVER,
 | 
						|
										IID_IDirectPlayNATHelp,
 | 
						|
										(LPVOID*) (&g_papNATHelpObjects[dwDirectPlay8Priority - 1]));
 | 
						|
				if ( hr != S_OK )
 | 
						|
				{
 | 
						|
					DNASSERT( g_papNATHelpObjects[dwDirectPlay8Priority - 1] == NULL );
 | 
						|
					DPFX(DPFPREP,  0, "Failed to create \"%S\" IDirectPlayNATHelp interface (error = 0x%lx)!  Skipping.",
 | 
						|
						pwszKeyName, hr);
 | 
						|
					continue;
 | 
						|
				}
 | 
						|
 | 
						|
				
 | 
						|
				//
 | 
						|
				// Initialize NAT Help.
 | 
						|
				//
 | 
						|
 | 
						|
				DNASSERT((! g_fDisableDPNHGatewaySupport) || (! g_fDisableDPNHFirewallSupport));
 | 
						|
 | 
						|
				if (g_fDisableDPNHGatewaySupport)
 | 
						|
				{
 | 
						|
					dwDirectPlay8InitFlags |= DPNHINITIALIZE_DISABLEGATEWAYSUPPORT;
 | 
						|
				}
 | 
						|
 | 
						|
				if (g_fDisableDPNHFirewallSupport)
 | 
						|
				{
 | 
						|
					dwDirectPlay8InitFlags |= DPNHINITIALIZE_DISABLELOCALFIREWALLSUPPORT;
 | 
						|
				}
 | 
						|
 | 
						|
 | 
						|
				//
 | 
						|
				// Make sure the flags we're passing are valid.
 | 
						|
				//
 | 
						|
				if ((dwDirectPlay8InitFlags & (DPNHINITIALIZE_DISABLEGATEWAYSUPPORT | DPNHINITIALIZE_DISABLELOCALFIREWALLSUPPORT)) == (DPNHINITIALIZE_DISABLEGATEWAYSUPPORT | DPNHINITIALIZE_DISABLELOCALFIREWALLSUPPORT))
 | 
						|
				{
 | 
						|
					DPFX(DPFPREP, 1, "Not loading NAT Help \"%S\" because both DISABLEGATEWAYSUPPORT and DISABLELOCALFIREWALLSUPPORT would have been specified (priority = %u, flags = 0x%lx).", 
 | 
						|
						pwszKeyName, dwDirectPlay8Priority, dwDirectPlay8InitFlags);
 | 
						|
						
 | 
						|
					IDirectPlayNATHelp_Release(g_papNATHelpObjects[dwDirectPlay8Priority - 1]);
 | 
						|
					g_papNATHelpObjects[dwDirectPlay8Priority - 1] = NULL;
 | 
						|
					
 | 
						|
					continue;
 | 
						|
				}
 | 
						|
 | 
						|
				
 | 
						|
				hr = IDirectPlayNATHelp_Initialize(g_papNATHelpObjects[dwDirectPlay8Priority - 1], dwDirectPlay8InitFlags);
 | 
						|
				if (hr != DPNH_OK)
 | 
						|
				{
 | 
						|
					DPFX(DPFPREP, 0, "Couldn't initialize NAT Help \"%S\" (error = 0x%lx)!  Skipping.",
 | 
						|
						pwszKeyName, hr);
 | 
						|
					
 | 
						|
					IDirectPlayNATHelp_Release(g_papNATHelpObjects[dwDirectPlay8Priority - 1]);
 | 
						|
					g_papNATHelpObjects[dwDirectPlay8Priority - 1] = NULL;
 | 
						|
					
 | 
						|
					continue;
 | 
						|
				}
 | 
						|
			
 | 
						|
			
 | 
						|
				DPFX(DPFPREP, 8, "Initialized NAT Help \"%S\" (priority = %u, flags = 0x%lx, object = 0x%p).", 
 | 
						|
					pwszKeyName, dwDirectPlay8Priority, dwDirectPlay8InitFlags, g_papNATHelpObjects[dwDirectPlay8Priority - 1]);
 | 
						|
 | 
						|
				dwNumLoaded++;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				DPFX(DPFPREP, 1, "DirectPlay NAT Helper \"%S\" is not enabled for DirectPlay8.", pwszKeyName);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		while (TRUE);
 | 
						|
			
 | 
						|
		
 | 
						|
		//
 | 
						|
		// If we didn't load any NAT helper objects, free up the memory.
 | 
						|
		//
 | 
						|
		if (dwNumLoaded == 0)
 | 
						|
		{
 | 
						|
			DNFree(g_papNATHelpObjects);
 | 
						|
			g_papNATHelpObjects = NULL;
 | 
						|
	
 | 
						|
			//
 | 
						|
			// We never got anything.  Fail.
 | 
						|
			//
 | 
						|
			goto Failure;
 | 
						|
		}
 | 
						|
 | 
						|
		
 | 
						|
		DPFX(DPFPREP, 8, "Loaded %u DirectPlay NAT Helper objects.", dwNumLoaded);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP, 8, "Already loaded NAT Help objects.");	
 | 
						|
	}
 | 
						|
 | 
						|
	//
 | 
						|
	// We have the interface globals lock, don't need InterlockedIncrement.
 | 
						|
	//
 | 
						|
	g_iNATHelpRefCount++;
 | 
						|
 | 
						|
	//
 | 
						|
	// We succeeded.
 | 
						|
	//
 | 
						|
	fReturn = TRUE;
 | 
						|
 | 
						|
Exit:
 | 
						|
	
 | 
						|
	DNLeaveCriticalSection(&g_InterfaceGlobalsLock);
 | 
						|
 | 
						|
	if (pwszKeyName != NULL)
 | 
						|
	{
 | 
						|
		DNFree(pwszKeyName);
 | 
						|
		pwszKeyName = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	return	fReturn;
 | 
						|
 | 
						|
Failure:
 | 
						|
 | 
						|
	//
 | 
						|
	// We can only fail during the first initialize, so therefore we will never be freeing
 | 
						|
	// g_papNATHelpObjects when we didn't allocate it in this function.
 | 
						|
	//
 | 
						|
	if (g_papNATHelpObjects != NULL)
 | 
						|
	{
 | 
						|
		DNFree(g_papNATHelpObjects);
 | 
						|
		g_papNATHelpObjects = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	fReturn = FALSE;
 | 
						|
	
 | 
						|
	goto Exit;
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// UnloadNATHelp - release the NAT Help object
 | 
						|
//
 | 
						|
// Entry:		Nothing
 | 
						|
//
 | 
						|
// Exit:		Nothing
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "UnloadNATHelp"
 | 
						|
 | 
						|
void UnloadNATHelp(void)
 | 
						|
{
 | 
						|
	DWORD	dwTemp;
 | 
						|
	
 | 
						|
 | 
						|
	DNEnterCriticalSection(&g_InterfaceGlobalsLock);
 | 
						|
 | 
						|
	//
 | 
						|
	// We have the interface globals lock, don't need InterlockedDecrement.
 | 
						|
	//
 | 
						|
	DNASSERT(g_iNATHelpRefCount > 0);
 | 
						|
	g_iNATHelpRefCount--;
 | 
						|
	if (g_iNATHelpRefCount == 0 )
 | 
						|
	{
 | 
						|
		HRESULT		hr;
 | 
						|
 | 
						|
 | 
						|
		DNASSERT(g_papNATHelpObjects != NULL);
 | 
						|
		for(dwTemp = 0; dwTemp < MAX_NUM_DIRECTPLAYNATHELPERS; dwTemp++)
 | 
						|
		{
 | 
						|
			if (g_papNATHelpObjects[dwTemp] != NULL)
 | 
						|
			{
 | 
						|
				DPFX(DPFPREP, 8, "Closing NAT Help object priority %u (0x%p).",
 | 
						|
					dwTemp, g_papNATHelpObjects[dwTemp]);
 | 
						|
 | 
						|
				hr = IDirectPlayNATHelp_Close(g_papNATHelpObjects[dwTemp], 0);
 | 
						|
				if (hr != DPNH_OK)
 | 
						|
				{
 | 
						|
					DPFX(DPFPREP,  0, "Problem closing NAT Help object %u (error = 0x%lx), continuing.",
 | 
						|
						dwTemp, hr);
 | 
						|
				}
 | 
						|
 | 
						|
				IDirectPlayNATHelp_Release(g_papNATHelpObjects[dwTemp]);
 | 
						|
				g_papNATHelpObjects[dwTemp] = NULL;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		DNFree(g_papNATHelpObjects);
 | 
						|
		g_papNATHelpObjects = NULL;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP, 8, "NAT Help object(s) still have %i references.",
 | 
						|
			g_iNATHelpRefCount);
 | 
						|
	}
 | 
						|
 | 
						|
	DNLeaveCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// CreateSPData - create instance data for SP
 | 
						|
//
 | 
						|
// Entry:		Pointer to pointer to SPData
 | 
						|
//				Pointer to class GUID
 | 
						|
//				Interface type
 | 
						|
//				Pointer to COM interface vtable
 | 
						|
//
 | 
						|
// Exit:		Error code
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "CreateSPData"
 | 
						|
 | 
						|
HRESULT	CreateSPData( CSPData **const ppSPData,
 | 
						|
					  const CLSID *const pClassID,
 | 
						|
					  const SP_TYPE SPType,
 | 
						|
					  IDP8ServiceProviderVtbl *const pVtbl )
 | 
						|
{
 | 
						|
	HRESULT		hr;
 | 
						|
	CSPData		*pSPData;
 | 
						|
 | 
						|
 | 
						|
	DNASSERT( ppSPData != NULL );
 | 
						|
	DNASSERT( pClassID != NULL );
 | 
						|
	DNASSERT( pVtbl != NULL );
 | 
						|
 | 
						|
	//
 | 
						|
	// initialize
 | 
						|
	//
 | 
						|
	hr = DPN_OK;
 | 
						|
	*ppSPData = NULL;
 | 
						|
	pSPData = NULL;
 | 
						|
 | 
						|
	//
 | 
						|
	// create data
 | 
						|
	//
 | 
						|
	pSPData = new CSPData;
 | 
						|
	if ( pSPData == NULL )
 | 
						|
	{
 | 
						|
		hr = DPNERR_OUTOFMEMORY;
 | 
						|
		DPFX(DPFPREP,  0, "Cannot create data for Winsock interface!" );
 | 
						|
		goto Failure;
 | 
						|
	}
 | 
						|
	pSPData->AddRef();
 | 
						|
 | 
						|
	hr = pSPData->Initialize( pClassID, SPType, pVtbl );
 | 
						|
	if ( hr != DPN_OK  )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  0, "Failed to intialize SP data!" );
 | 
						|
		DisplayDNError( 0, hr );
 | 
						|
		goto Failure;
 | 
						|
	}
 | 
						|
 | 
						|
	DPFX(DPFPREP, 6, "Created SP Data object 0x%p.", pSPData);
 | 
						|
 | 
						|
Exit:
 | 
						|
	if ( hr != DPN_OK )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  0, "Problem with CreateSPData!" );
 | 
						|
		DisplayDNError( 0, hr );
 | 
						|
	}
 | 
						|
 | 
						|
	*ppSPData = pSPData;
 | 
						|
 | 
						|
	return	hr;
 | 
						|
 | 
						|
Failure:
 | 
						|
	if ( pSPData != NULL )
 | 
						|
	{
 | 
						|
		pSPData->DecRef();
 | 
						|
		pSPData = NULL;	
 | 
						|
	}
 | 
						|
 | 
						|
	goto Exit;
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// InitializeInterfaceGlobals - perform global initialization for an interface.
 | 
						|
//
 | 
						|
// Entry:		Pointer to SPData
 | 
						|
//
 | 
						|
// Exit:		Error code
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "InitializeInterfaceGlobals"
 | 
						|
 | 
						|
HRESULT	InitializeInterfaceGlobals( CSPData *const pSPData )
 | 
						|
{
 | 
						|
	HRESULT	hr;
 | 
						|
	CThreadPool	*pThreadPool;
 | 
						|
	CRsip		*pRsip;
 | 
						|
 | 
						|
 | 
						|
	DNASSERT( pSPData != NULL );
 | 
						|
 | 
						|
	//
 | 
						|
	// initialize
 | 
						|
	//
 | 
						|
	hr = DPN_OK;
 | 
						|
	pThreadPool = NULL;
 | 
						|
	pRsip = NULL;
 | 
						|
 | 
						|
	DNEnterCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
 | 
						|
	if ( g_pThreadPool == NULL )
 | 
						|
	{
 | 
						|
		DNASSERT( g_iThreadPoolRefCount == 0 );
 | 
						|
		g_pThreadPool = CreateThreadPool();
 | 
						|
		if ( g_pThreadPool != NULL )
 | 
						|
		{
 | 
						|
			hr = g_pThreadPool->Initialize();
 | 
						|
			if ( hr != DPN_OK )
 | 
						|
			{
 | 
						|
				g_pThreadPool->DecRef();
 | 
						|
				g_pThreadPool = NULL;
 | 
						|
				hr = DPNERR_OUTOFMEMORY;
 | 
						|
				goto Failure;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				g_iThreadPoolRefCount++;
 | 
						|
				pThreadPool = g_pThreadPool;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		DNASSERT( g_iThreadPoolRefCount != 0 );
 | 
						|
		g_iThreadPoolRefCount++;
 | 
						|
		g_pThreadPool->AddRef();
 | 
						|
		pThreadPool = g_pThreadPool;
 | 
						|
	}
 | 
						|
 | 
						|
Exit:
 | 
						|
	DNLeaveCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
 | 
						|
	pSPData->SetThreadPool( g_pThreadPool );
 | 
						|
 | 
						|
	return	hr;
 | 
						|
 | 
						|
Failure:
 | 
						|
 | 
						|
	goto Exit;
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// DeinitializeInterfaceGlobals - deinitialize thread pool and Rsip
 | 
						|
//
 | 
						|
// Entry:		Pointer to service provider
 | 
						|
//
 | 
						|
// Exit:		Nothing
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "DeinitializeInterfaceGlobals"
 | 
						|
 | 
						|
void	DeinitializeInterfaceGlobals( CSPData *const pSPData )
 | 
						|
{
 | 
						|
	CThreadPool		*pThreadPool;
 | 
						|
 | 
						|
 | 
						|
	DNASSERT( pSPData != NULL );
 | 
						|
 | 
						|
	//
 | 
						|
	// initialize
 | 
						|
	//
 | 
						|
	pThreadPool = NULL;
 | 
						|
 | 
						|
	//
 | 
						|
	// Process as little as possible inside the lock.  If any of the items
 | 
						|
	// need to be released, pointers to them will be set.
 | 
						|
	//
 | 
						|
	DNEnterCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
 | 
						|
	DNASSERT( g_pThreadPool != NULL );
 | 
						|
	DNASSERT( g_iThreadPoolRefCount != 0 );
 | 
						|
	DNASSERT( g_pThreadPool == pSPData->GetThreadPool() );
 | 
						|
 | 
						|
	pThreadPool = pSPData->GetThreadPool();
 | 
						|
 | 
						|
	//
 | 
						|
	// remove thread pool reference
 | 
						|
	//
 | 
						|
	DNASSERT( pThreadPool != NULL );
 | 
						|
	g_iThreadPoolRefCount--;
 | 
						|
	if ( g_iThreadPoolRefCount == 0 )
 | 
						|
	{
 | 
						|
		g_pThreadPool = NULL;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		pThreadPool = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	DNLeaveCriticalSection( &g_InterfaceGlobalsLock );
 | 
						|
 | 
						|
	//
 | 
						|
	// Now that we're outside of the lock, clean up any pointers we have.
 | 
						|
	// The thread pool will be cleaned up when all of the outstanding interfaces
 | 
						|
	// close.
 | 
						|
	//
 | 
						|
	if ( pThreadPool != NULL )
 | 
						|
	{
 | 
						|
		pThreadPool->StopAllIO();
 | 
						|
		pThreadPool = NULL;
 | 
						|
	}
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// AddNetworkAdapterToBuffer - add a network address to a packed buffer
 | 
						|
//
 | 
						|
// Entry:		Pointer to packed buffer
 | 
						|
//				Pointer to adapter name
 | 
						|
//				Pointer to adapter guid
 | 
						|
//
 | 
						|
// Exit:		Error code
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "AddNetworkAdapterToBuffer"
 | 
						|
 | 
						|
HRESULT	AddNetworkAdapterToBuffer( CPackedBuffer *const pPackedBuffer,
 | 
						|
								   const char *const pAdapterName,
 | 
						|
								   const GUID *const pAdapterGUID )
 | 
						|
{
 | 
						|
	HRESULT	hr;
 | 
						|
	DPN_SERVICE_PROVIDER_INFO	AdapterInfo;
 | 
						|
 | 
						|
 | 
						|
	DNASSERT( pPackedBuffer != NULL );
 | 
						|
	DNASSERT( pAdapterName != NULL );
 | 
						|
	DNASSERT( pAdapterGUID != NULL );
 | 
						|
 | 
						|
	//
 | 
						|
	// initialize
 | 
						|
	//
 | 
						|
	hr = DPN_OK;
 | 
						|
 | 
						|
	memset( &AdapterInfo, 0x00, sizeof( AdapterInfo ) );
 | 
						|
	DNASSERT( AdapterInfo.dwFlags == 0 );
 | 
						|
	DNASSERT( AdapterInfo.pvReserved == NULL );
 | 
						|
	DNASSERT( AdapterInfo.dwReserved == NULL );
 | 
						|
 | 
						|
	AdapterInfo.guid = *pAdapterGUID;
 | 
						|
 | 
						|
	hr = pPackedBuffer->AddStringToBack( pAdapterName );
 | 
						|
	if ( ( hr != DPNERR_BUFFERTOOSMALL ) && ( hr != DPN_OK ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  0, "Failed to add adapter name to buffer!" );
 | 
						|
		goto Failure;
 | 
						|
	}
 | 
						|
	AdapterInfo.pwszName = static_cast<WCHAR*>( pPackedBuffer->GetTailAddress() );
 | 
						|
 | 
						|
	hr = pPackedBuffer->AddToFront( &AdapterInfo, sizeof( AdapterInfo ) );
 | 
						|
 | 
						|
Exit:
 | 
						|
	return	hr;
 | 
						|
 | 
						|
Failure:
 | 
						|
	goto Exit;
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#if 0
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// ConvertURLDataToBinaryW - convert a Unicode string with URL escaped characters into a binary buffer
 | 
						|
//
 | 
						|
// Entry:		String to convert
 | 
						|
//				Destination buffer pointer
 | 
						|
//				Pointer to size of buffer.  If too small, size required will be stored here.  Otherwise bytes written will be stored here.
 | 
						|
//
 | 
						|
// Exit:		Error code
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "ConvertURLDataToBinaryW"
 | 
						|
 | 
						|
HRESULT	ConvertURLDataToBinaryW( const WCHAR * const wszURLData,
 | 
						|
								void * const pvBuffer,
 | 
						|
								DWORD * const pdwBufferSize )
 | 
						|
{
 | 
						|
	HRESULT					hr;
 | 
						|
	WCHAR *					pwszTemp = NULL;
 | 
						|
	IDirectPlay8Address *	pDP8AddressTemp = NULL;
 | 
						|
 | 
						|
 | 
						|
	DNASSERT(wszURLData != NULL);
 | 
						|
	DNASSERT(pdwBufferSize != NULL);
 | 
						|
 | 
						|
 | 
						|
	//
 | 
						|
	// Create a DirectPlay8Address object.
 | 
						|
	//
 | 
						|
	hr = COM_CoCreateInstance(CLSID_DirectPlay8Address,
 | 
						|
							NULL,
 | 
						|
							CLSCTX_INPROC_SERVER,
 | 
						|
							IID_IDirectPlay8Address,
 | 
						|
							(PVOID*) (&pDP8AddressTemp));
 | 
						|
	if (hr != S_OK)
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP, 0, "Couldn't create temporary DirectPlay8Address object (err = 0x%lx)!", hr);
 | 
						|
		goto Exit;
 | 
						|
	}
 | 
						|
 | 
						|
	//
 | 
						|
	// Allocate a buffer and stick "x-directplay:/#" in front of the
 | 
						|
	// data (i.e. make the string passed in user data for a bogus URL).
 | 
						|
	//
 | 
						|
 | 
						|
	pwszTemp = (WCHAR*) DNMalloc((wcslen(DPNA_HEADER) + 1 + wcslen(wszURLData) + 1) * sizeof(WCHAR));
 | 
						|
	if (pwszTemp == NULL)
 | 
						|
	{
 | 
						|
		hr = DPNERR_OUTOFMEMORY;
 | 
						|
		goto Exit;
 | 
						|
	}
 | 
						|
 | 
						|
	wcscpy(pwszTemp, DPNA_HEADER);
 | 
						|
	pwszTemp[wcslen(DPNA_HEADER)] = DPNA_SEPARATOR_USERDATA;
 | 
						|
	wcscpy((pwszTemp + wcslen(DPNA_HEADER) + 1), wszURLData);
 | 
						|
 | 
						|
 | 
						|
	//
 | 
						|
	// Let the addressing library's parsing routine handle the grunt
 | 
						|
	// work of converting the string to binary data.
 | 
						|
	//
 | 
						|
	hr = IDirectPlay8Address_BuildFromURLW(pDP8AddressTemp, pwszTemp);
 | 
						|
	if (hr != DPN_OK)
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP, 0, "Couldn't build URL from string \"%S\"!", pwszTemp);
 | 
						|
		goto Exit;
 | 
						|
	}
 | 
						|
 | 
						|
	hr = IDirectPlay8Address_GetUserData(pDP8AddressTemp, pvBuffer, pdwBufferSize);
 | 
						|
	if (hr != DPN_OK)
 | 
						|
	{
 | 
						|
		if (hr != DPNERR_BUFFERTOOSMALL)
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP, 0, "Couldn't get user data from temporary DirectPlay8Address object!");
 | 
						|
		}
 | 
						|
		goto Exit;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
Exit:
 | 
						|
 | 
						|
	if (pwszTemp != NULL)
 | 
						|
	{
 | 
						|
		DNFree(pwszTemp);
 | 
						|
		pwszTemp = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (pDP8AddressTemp != NULL)
 | 
						|
	{
 | 
						|
		IDirectPlay8Address_Release(pDP8AddressTemp);
 | 
						|
		pDP8AddressTemp = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
//**********************************************************************
 | 
						|
// ------------------------------
 | 
						|
// ConvertURLDataToBinaryA - convert an ANSI string with URL escaped characters into a binary buffer
 | 
						|
//
 | 
						|
// Entry:		String to convert
 | 
						|
//				Destination buffer pointer
 | 
						|
//				Pointer to size of buffer.  If too small, size required will be stored here.  Otherwise bytes written will be stored here.
 | 
						|
//
 | 
						|
// Exit:		Error code
 | 
						|
// ------------------------------
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define	DPF_MODNAME "ConvertURLDataToBinaryA"
 | 
						|
 | 
						|
HRESULT	ConvertURLDataToBinaryA( const char * const szURLData,
 | 
						|
								void * const pvBuffer,
 | 
						|
								DWORD * const pdwBufferSize )
 | 
						|
{
 | 
						|
	HRESULT					hr;
 | 
						|
	char *					pszTemp = NULL;
 | 
						|
	IDirectPlay8Address *	pDP8AddressTemp = NULL;
 | 
						|
 | 
						|
 | 
						|
	DNASSERT(szURLData != NULL);
 | 
						|
	DNASSERT(pdwBufferSize != NULL);
 | 
						|
 | 
						|
 | 
						|
	//
 | 
						|
	// Create a DirectPlay8Address object.
 | 
						|
	//
 | 
						|
	hr = COM_CoCreateInstance(CLSID_DirectPlay8Address,
 | 
						|
							NULL,
 | 
						|
							CLSCTX_INPROC_SERVER,
 | 
						|
							IID_IDirectPlay8Address,
 | 
						|
							(PVOID*) (&pDP8AddressTemp));
 | 
						|
	if (hr != S_OK)
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP, 0, "Couldn't create temporary DirectPlay8Address object (err = 0x%lx)!", hr);
 | 
						|
		goto Exit;
 | 
						|
	}
 | 
						|
 | 
						|
	//
 | 
						|
	// Allocate a buffer and stick "x-directplay:/#" in front of the
 | 
						|
	// data (i.e. make the string passed in user data for a bogus URL).
 | 
						|
	//
 | 
						|
 | 
						|
	pszTemp = (char*) DNMalloc((strlen(DPNA_HEADER_A) + 1 + strlen(szURLData) + 1) * sizeof(char));
 | 
						|
	if (pszTemp == NULL)
 | 
						|
	{
 | 
						|
		hr = DPNERR_OUTOFMEMORY;
 | 
						|
		goto Exit;
 | 
						|
	}
 | 
						|
 | 
						|
	strcpy(pszTemp, DPNA_HEADER_A);
 | 
						|
	pszTemp[strlen(DPNA_HEADER_A)] = DPNA_SEPARATOR_USERDATA_A;
 | 
						|
	strcpy((pszTemp + strlen(DPNA_HEADER_A) + 1), szURLData);
 | 
						|
 | 
						|
 | 
						|
	//
 | 
						|
	// Let the addressing library's parsing routine handle the grunt
 | 
						|
	// work of converting the string to binary data.
 | 
						|
	//
 | 
						|
	hr = IDirectPlay8Address_BuildFromURLA(pDP8AddressTemp, pszTemp);
 | 
						|
	if (hr != DPN_OK)
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP, 0, "Couldn't build URL from string \"%s\"!", pszTemp);
 | 
						|
		goto Exit;
 | 
						|
	}
 | 
						|
 | 
						|
	hr = IDirectPlay8Address_GetUserData(pDP8AddressTemp, pvBuffer, pdwBufferSize);
 | 
						|
	if (hr != DPN_OK)
 | 
						|
	{
 | 
						|
		if (hr != DPNERR_BUFFERTOOSMALL)
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP, 0, "Couldn't get user data from temporary DirectPlay8Address object!");
 | 
						|
		}
 | 
						|
		goto Exit;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
Exit:
 | 
						|
 | 
						|
	if (pszTemp != NULL)
 | 
						|
	{
 | 
						|
		DNFree(pszTemp);
 | 
						|
		pszTemp = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (pDP8AddressTemp != NULL)
 | 
						|
	{
 | 
						|
		IDirectPlay8Address_Release(pDP8AddressTemp);
 | 
						|
		pDP8AddressTemp = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
//**********************************************************************
 | 
						|
 | 
						|
 | 
						|
#endif // 0
 | 
						|
 |