|
|
/*==========================================================================
* * Copyright (C) 1998-2002 Microsoft Corporation. All Rights Reserved. * * File: Unk.cpp * Content: IUnknown implementation * History: * Date By Reason * ==== == ====== * 11/25/98 jtk Copied from winsock provider * 11/30/98 jtk Initial checkin into SLM * 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles. ***************************************************************************/
#include "dnmdmi.h"
#define DPN_REG_LOCAL_MODEM_SERIAL_ROOT L"\\DPNSPModemSerial"
#define DPN_REG_LOCAL_MODEM_MODEM_ROOT L"\\DPNSPModemModem"
#undef DPF_SUBCOMP
#define DPF_SUBCOMP DN_SUBCOMP_MODEM
HRESULT ModemLoadAndAllocString( UINT uiResourceID, wchar_t **lpswzString );
#undef DPF_MODNAME
#define DPF_MODNAME "DNModemInit"
BOOL DNModemInit(HANDLE hModule) { DNASSERT( g_hModemDLLInstance == NULL ); g_hModemDLLInstance = (HINSTANCE) hModule;
//
// attempt to initialize process-global items
//
if ( ModemInitProcessGlobals() == FALSE ) { DPFX(DPFPREP, 0, "Failed to initialize globals!" );
return FALSE; }
return TRUE; }
#undef DPF_MODNAME
#define DPF_MODNAME "DNModemDeInit"
void DNModemDeInit() { DPFX(DPFPREP, 5, "Deinitializing Serial SP");
DNASSERT( g_hModemDLLInstance != NULL ); g_hModemDLLInstance = NULL;
ModemDeinitProcessGlobals(); }
#ifndef DPNBUILD_NOCOMREGISTER
#undef DPF_MODNAME
#define DPF_MODNAME "DNModemRegister"
BOOL DNModemRegister(LPCWSTR wszDLLName) { HRESULT hr = S_OK; BOOL fReturn = TRUE;
if( !CRegistry::Register( L"DirectPlay8SPModem.Modem.1", L"DirectPlay8 Modem Provider Object", wszDLLName, &CLSID_DP8SP_MODEM, L"DirectPlay8SPModem.Modem") ) { DPFERR( "Could not register dp8 Modem object" ); fReturn = FALSE; }
if( !CRegistry::Register( L"DirectPlay8SPModem.Serial.1", L"DirectPlay8 Serial Provider Object", wszDLLName, &CLSID_DP8SP_SERIAL, L"DirectPlay8SPModem.Serial") ) { DPFERR( "Could not register dp8 Serial object" ); fReturn = FALSE; }
CRegistry creg; WCHAR *wszFriendlyName = NULL;
if( !creg.Open( HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY DPN_REG_LOCAL_MODEM_MODEM_ROOT, FALSE, TRUE ) ) { DPFERR( "Cannot create Modem sub-area" ); fReturn = FALSE; } else {
hr = ModemLoadAndAllocString( IDS_FRIENDLYNAME_MODEM, &wszFriendlyName );
if( FAILED( hr ) ) { DPFX(DPFPREP, 0, "Could not load Modem name hr=0x%x", hr ); fReturn = FALSE; } else { // Load from resource file
creg.WriteString( DPN_REG_KEYNAME_FRIENDLY_NAME, wszFriendlyName ); delete [] wszFriendlyName; creg.WriteGUID( DPN_REG_KEYNAME_GUID, CLSID_DP8SP_MODEM ); } creg.Close(); } if( !creg.Open( HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY DPN_REG_LOCAL_MODEM_SERIAL_ROOT, FALSE, TRUE ) ) { DPFERR( "Cannot create Serial sub-aread" ); fReturn = FALSE; } else { hr = ModemLoadAndAllocString( IDS_FRIENDLYNAME_SERIAL, &wszFriendlyName ); if( FAILED( hr ) ) { DPFX(DPFPREP, 0, "Could not load Serial name hr=0x%x", hr ); fReturn = FALSE; } else { // Load from resource file
creg.WriteString( DPN_REG_KEYNAME_FRIENDLY_NAME, wszFriendlyName ); delete [] wszFriendlyName; creg.WriteGUID( DPN_REG_KEYNAME_GUID, CLSID_DP8SP_SERIAL ); } creg.Close(); } return fReturn; }
#undef DPF_MODNAME
#define DPF_MODNAME "DNModemUnRegister"
BOOL DNModemUnRegister() { HRESULT hr = S_OK; BOOL fReturn = TRUE;
if( !CRegistry::UnRegister(&CLSID_DP8SP_MODEM) ) { DPFX(DPFPREP, 0, "Failed to unregister Modem object" ); fReturn = FALSE; }
if( !CRegistry::UnRegister(&CLSID_DP8SP_SERIAL) ) { DPFX(DPFPREP, 0, "Failed to unregister Serial object" ); fReturn = FALSE; }
CRegistry creg;
if( !creg.Open( HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY, FALSE, TRUE ) ) { DPFERR( "Cannot remove app, does not exist" ); } else { if( !creg.DeleteSubKey( &(DPN_REG_LOCAL_MODEM_MODEM_ROOT)[1] ) ) { DPFERR( "Cannot remove Modem sub-key, could have elements" ); }
if( !creg.DeleteSubKey( &(DPN_REG_LOCAL_MODEM_SERIAL_ROOT)[1] ) ) { DPFERR( "Cannot remove Serial sub-key, could have elements" ); }
}
return fReturn; }
#endif // ! DPNBUILD_NOCOMREGISTER
#ifndef DPNBUILD_LIBINTERFACE
#undef DPF_MODNAME
#define DPF_MODNAME "DNModemGetRemainingObjectCount"
DWORD DNModemGetRemainingObjectCount() { return g_lModemOutstandingInterfaceCount; }
#endif // ! DPNBUILD_LIBINTERFACE
//**********************************************************************
// Constant definitions
//**********************************************************************
//**********************************************************************
// Macro definitions
//**********************************************************************
#ifdef __MWERKS__
#define EXP __declspec(dllexport)
#else
#define EXP
#endif
//**********************************************************************
// Structure definitions
//**********************************************************************
//**********************************************************************
// Variable definitions
//**********************************************************************
//**********************************************************************
// Function prototypes
//**********************************************************************
static STDMETHODIMP DNMODEMSP_QueryInterface( IDP8ServiceProvider* lpDNSP, REFIID riid, LPVOID * ppvObj );
#define NOTSUPPORTED(parm) (HRESULT (__stdcall *) (struct IDP8ServiceProvider *, parm)) DNMODEMSP_NotSupported
//**********************************************************************
// Function pointers
//**********************************************************************
// these are the vtables for serial and modem. One or the other is used depending on
// what is passed to DoCreateInstance
static IDP8ServiceProviderVtbl g_SerialInterface = { DNMODEMSP_QueryInterface, DNMODEMSP_AddRef, DNMODEMSP_Release, DNMODEMSP_Initialize, DNMODEMSP_Close, DNMODEMSP_Connect, DNMODEMSP_Disconnect, DNMODEMSP_Listen, DNMODEMSP_SendData, DNMODEMSP_EnumQuery, DNMODEMSP_EnumRespond, DNMODEMSP_CancelCommand, NOTSUPPORTED(PSPENUMMULTICASTSCOPESDATA), // EnumMulticastScopes
NOTSUPPORTED(PSPSHAREENDPOINTINFODATA), // ShareEndpointInfo
NOTSUPPORTED(PSPGETENDPOINTBYADDRESSDATA), // GetEndpointByAddress
NOTSUPPORTED(PSPUPDATEDATA), // Update
DNMODEMSP_GetCaps, DNMODEMSP_SetCaps, DNMODEMSP_ReturnReceiveBuffers, DNMODEMSP_GetAddressInfo, DNMODEMSP_IsApplicationSupported, DNMODEMSP_EnumAdapters, NOTSUPPORTED(PSPPROXYENUMQUERYDATA) // ProxyEnumQuery
};
static IDP8ServiceProviderVtbl g_ModemInterface = { DNMODEMSP_QueryInterface, DNMODEMSP_AddRef, DNMODEMSP_Release, DNMODEMSP_Initialize, DNMODEMSP_Close, DNMODEMSP_Connect, DNMODEMSP_Disconnect, DNMODEMSP_Listen, DNMODEMSP_SendData, DNMODEMSP_EnumQuery, DNMODEMSP_EnumRespond, DNMODEMSP_CancelCommand, NOTSUPPORTED(PSPENUMMULTICASTSCOPESDATA), // EnumMulticastScopes
NOTSUPPORTED(PSPSHAREENDPOINTINFODATA), // ShareEndpointInfo
NOTSUPPORTED(PSPGETENDPOINTBYADDRESSDATA), // GetEndpointByAddress
NOTSUPPORTED(PSPUPDATEDATA), // Update
DNMODEMSP_GetCaps, DNMODEMSP_SetCaps, DNMODEMSP_ReturnReceiveBuffers, DNMODEMSP_GetAddressInfo, DNMODEMSP_IsApplicationSupported, DNMODEMSP_EnumAdapters, NOTSUPPORTED(PSPPROXYENUMQUERYDATA) // ProxyEnumQuery
};
//**********************************************************************
// Function definitions
//**********************************************************************
//**********************************************************************
// ------------------------------
// DNMODEMSP_QueryInterface - query for a particular interface
//
// Entry: Pointer to current interface
// Desired interface ID
// Pointer to pointer to new interface
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "DNMODEMSP_QueryInterface"
static STDMETHODIMP DNMODEMSP_QueryInterface( IDP8ServiceProvider *lpDNSP, REFIID riid, LPVOID * ppvObj ) { HRESULT hr = S_OK;
// assume no interface
*ppvObj=NULL;
// hmmm, switch would be cleaner...
if( IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDP8ServiceProvider) ) { *ppvObj = lpDNSP; DNMODEMSP_AddRef( lpDNSP ); } else { hr = E_NOINTERFACE; }
return hr; } //**********************************************************************
//**********************************************************************
// ------------------------------
// CreateModemInterface - create a modem interface
//
// Entry: Pointer to pointer to SP interface
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CreateModemInterface"
#ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
HRESULT CreateModemInterface( const XDP8CREATE_PARAMS * const pDP8CreateParams, IDP8ServiceProvider **const ppiDP8SP ) #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
HRESULT CreateModemInterface( IDP8ServiceProvider **const ppiDP8SP ) #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
{ HRESULT hr; CModemSPData *pSPData;
DNASSERT( ppiDP8SP != NULL );
//
// initialize
//
hr = DPN_OK; pSPData = NULL; *ppiDP8SP = NULL;
//
// create main data class
//
hr = CreateSPData( &pSPData, TYPE_MODEM, #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
pDP8CreateParams, #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
&g_ModemInterface ); if ( hr != DPN_OK ) { DNASSERT( pSPData == NULL ); DPFX(DPFPREP, 0, "Problem creating SPData!" ); DisplayDNError( 0, hr ); goto Failure; }
DNASSERT( pSPData != NULL ); *ppiDP8SP = pSPData->COMInterface();
Exit: return hr;
Failure: if ( pSPData != NULL ) { pSPData->DecRef(); pSPData = NULL; }
goto Exit; } //**********************************************************************
//**********************************************************************
// ------------------------------
// CreateSerialInterface - create a serial interface
//
// Entry: Pointer to pointer to SP interface
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CreateSerialInterface"
#ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
HRESULT CreateSerialInterface( const XDP8CREATE_PARAMS * const pDP8CreateParams, IDP8ServiceProvider **const ppiDP8SP ) #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
HRESULT CreateSerialInterface( IDP8ServiceProvider **const ppiDP8SP ) #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
{ HRESULT hr; CModemSPData *pSPData;
DNASSERT( ppiDP8SP != NULL );
//
// initialize
//
hr = DPN_OK; pSPData = NULL; *ppiDP8SP = NULL;
//
// create main data class
//
hr = CreateSPData( &pSPData, TYPE_SERIAL, #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
pDP8CreateParams, #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL
&g_SerialInterface ); if ( hr != DPN_OK ) { DNASSERT( pSPData == NULL ); DPFX(DPFPREP, 0, "Problem creating SPData!" ); DisplayDNError( 0, hr ); goto Failure; }
DNASSERT( pSPData != NULL ); *ppiDP8SP = pSPData->COMInterface();
Exit: return hr;
Failure: if ( pSPData != NULL ) { pSPData->DecRef(); pSPData = NULL; }
goto Exit; } //**********************************************************************
#ifndef DPNBUILD_LIBINTERFACE
//**********************************************************************
// ------------------------------
// ModemDoCreateInstance - create an instance of an interface
//
// Entry: Pointer to class factory
// Pointer to unknown interface
// Refernce of GUID of desired interface
// Reference to another GUID?
// Pointer to pointer to interface
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "DoCreateInstance"
HRESULT ModemDoCreateInstance( LPCLASSFACTORY This, LPUNKNOWN pUnkOuter, REFCLSID rclsid, REFIID riid, LPVOID *ppvObj ) { HRESULT hr;
DNASSERT( ppvObj != NULL );
//
// initialize
//
*ppvObj = NULL;
//
// we can either create an IPX instance or an IP instance
//
if (IsEqualCLSID(rclsid, CLSID_DP8SP_MODEM)) { hr = CreateModemInterface( reinterpret_cast<IDP8ServiceProvider**>( ppvObj ) ); } else if (IsEqualCLSID(rclsid, CLSID_DP8SP_SERIAL)) { hr = CreateSerialInterface( reinterpret_cast<IDP8ServiceProvider**>( ppvObj ) ); } else { // this shouldn't happen if they called IClassFactory::CreateObject correctly
DPFX(DPFPREP, 0, "Got unexpected CLSID!"); hr = E_UNEXPECTED; }
return hr; } //**********************************************************************
#endif // ! DPNBUILD_LIBINTERFACE
//**********************************************************************
// ------------------------------
// IsClassImplemented - tells asked if this DLL implements a given class.
// DLLs may implement multiple classes and multiple interfaces on those classes
//
// Entry: Class reference
//
// Exit: Boolean indicating whether the class is implemented
// TRUE = class implemented
// FALSE = class not implemented
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "IsClassImplemented"
BOOL IsClassImplemented( REFCLSID rclsid ) { return IsSerialGUID( &rclsid ); } //**********************************************************************
#define MAX_RESOURCE_STRING_LENGTH _MAX_PATH
#undef DPF_MODNAME
#define DPF_MODNAME "ModemLoadAndAllocString"
HRESULT ModemLoadAndAllocString( UINT uiResourceID, wchar_t **lpswzString ) { int length; HRESULT hr;
TCHAR szTmpBuffer[MAX_RESOURCE_STRING_LENGTH]; length = LoadString( g_hModemDLLInstance, uiResourceID, szTmpBuffer, MAX_RESOURCE_STRING_LENGTH );
if( length == 0 ) { hr = GetLastError(); DPFX(DPFPREP, 0, "Unable to load resource ID %d error 0x%x", uiResourceID, hr ); *lpswzString = NULL;
return DPNERR_GENERIC; } else { *lpswzString = new wchar_t[length+1];
if( *lpswzString == NULL ) { DPFX(DPFPREP, 0, "Alloc failure" ); return DPNERR_OUTOFMEMORY; }
#ifdef UNICODE
wcscpy( *lpswzString, szTmpBuffer ); #else // !UNICODE
if( STR_jkAnsiToWide( *lpswzString, szTmpBuffer, length+1 ) != DPN_OK ) { hr = GetLastError(); delete[] *lpswzString; *lpswzString = NULL;
DPFX(DPFPREP, 0, "Unable to upconvert from ansi to unicode hr=0x%x", hr ); return DPNERR_GENERIC; } #endif // !UNICODE
return DPN_OK; } }
|