/*========================================================================== * * Copyright (C) 1998-2002 Microsoft Corporation. All Rights Reserved. * * File: Unk.cpp * Content: IUnknown implementation * History: * Date By Reason * ==== == ====== * 08/06/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles. ***************************************************************************/ #include "dnwsocki.h" #ifndef DPNBUILD_NOIPX #define DPN_REG_LOCAL_WSOCK_IPX_ROOT L"\\DPNSPWinsockIPX" #endif // ! DPNBUILD_NOIPX #ifndef DPNBUILD_NOIPV6 #define DPN_REG_LOCAL_WSOCK_IPV6_ROOT L"\\DPNSPWinsockIPv6" #endif // ! DPNBUILD_NOIPV6 #define DPN_REG_LOCAL_WSOCK_TCPIP_ROOT L"\\DPNSPWinsockTCP" #if ((! defined(WINCE)) && (! defined(_XBOX))) #define MAX_RESOURCE_STRING_LENGTH _MAX_PATH HRESULT LoadAndAllocString( UINT uiResourceID, wchar_t **lpswzString ); #endif // ! WINCE and ! _XBOX #undef DPF_MODNAME #define DPF_MODNAME "DNWsockInit" BOOL DNWsockInit(HANDLE hModule) { DNASSERT( hModule != NULL ); #ifdef _XBOX XDP8STARTUP_PARAMS * pStartupParams; XNetStartupParams xnsp; int iResult; // // The instance handle is actually a pointer to the startup parameters. // pStartupParams = (XDP8STARTUP_PARAMS*) hModule; // // Initialize the Xbox networking layer, unless we were forbidden. // if (! (pStartupParams->dwFlags & XDP8STARTUP_BYPASSXNETSTARTUP)) { memset(&xnsp, 0, sizeof(xnsp)); xnsp.cfgSizeOfStruct = sizeof(xnsp); #pragma TODO(vanceo, "Does this actually do anything?") if (pStartupParams->dwFlags & XDP8STARTUP_BYPASSSECURITY) { xnsp.cfgFlags |= XNET_STARTUP_BYPASS_SECURITY; } DPFX(DPFPREP, 1, "Initializing Xbox networking layer."); iResult = XNetStartup(&xnsp); if (iResult != 0) { DPFX(DPFPREP, 0, "Couldn't start XNet (err = %i)!", iResult); return FALSE; } g_fStartedXNet = TRUE; } #else // ! _XBOX #ifndef WINCE DNASSERT( g_hDLLInstance == NULL ); g_hDLLInstance = (HINSTANCE) hModule; #endif // ! WINCE #endif // ! _XBOX // // attempt to initialize process-global items // if ( InitProcessGlobals() == FALSE ) { DPFX(DPFPREP, 0, "Failed to initialize globals!" ); #ifdef _XBOX if (g_fStartedXNet) { XNetCleanup(); } #endif // _XBOX return FALSE; } #ifdef DPNBUILD_LIBINTERFACE // // Attempt to load Winsock. // if ( LoadWinsock() == FALSE ) { DPFX(DPFPREP, 0, "Failed to load winsock!" ); DeinitProcessGlobals(); #ifdef _XBOX if (g_fStartedXNet) { XNetCleanup(); } #endif // _XBOX return FALSE; } #endif // DPNBUILD_LIBINTERFACE #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL // // Pre-allocate a threadpool object. // if ( g_ThreadPoolPool.Preallocate( 1, NULL ) < 1 ) { DPFX(DPFPREP, 0, "Failed to preallocate a threadpool object!" ); #ifdef DPNBUILD_LIBINTERFACE UnloadWinsock(); #endif // DPNBUILD_LIBINTERFACE DeinitProcessGlobals(); #ifdef _XBOX if (g_fStartedXNet) { XNetCleanup(); } #endif // _XBOX return FALSE; } #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL return TRUE; } #undef DPF_MODNAME #define DPF_MODNAME "DNWsockDeInit" void DNWsockDeInit() { DPFX(DPFPREP, 5, "Deinitializing Wsock SP"); #if ((! defined(WINCE)) && (! defined(_XBOX))) DNASSERT( g_hDLLInstance != NULL ); g_hDLLInstance = NULL; #endif // ! WINCE and ! _XBOX #ifdef DPNBUILD_LIBINTERFACE // // Unload Winsock. // UnloadWinsock(); #endif // DPNBUILD_LIBINTERFACE DeinitProcessGlobals(); #ifdef _XBOX // // Clean up the Xbox networking layer if we started it. // if (g_fStartedXNet) { DPFX(DPFPREP, 1, "Cleaning up Xbox networking layer."); #ifdef DBG DNASSERT(XNetCleanup() == 0); #else // ! DBG XNetCleanup(); #endif // ! DBG g_fStartedXNet = FALSE; } #endif // _XBOX } #ifndef DPNBUILD_NOCOMREGISTER #undef DPF_MODNAME #define DPF_MODNAME "DNWsockRegister" BOOL DNWsockRegister(LPCWSTR wszDLLName) { HRESULT hr = S_OK; BOOL fReturn = TRUE; CRegistry creg; #if ((! defined(WINCE)) && (! defined(_XBOX))) WCHAR *wszFriendlyName = NULL; #endif // ! WINCE and ! _XBOX #ifndef DPNBUILD_NOIPX if( !CRegistry::Register( L"DirectPlay8SPWSock.IPX.1", L"DirectPlay8 WSock IPX Provider Object", wszDLLName, &CLSID_DP8SP_IPX, L"DirectPlay8SPWSock.IPX") ) { DPFERR( "Could not register dp8 IPX object" ); fReturn = FALSE; } #endif // ! DPNBUILD_NOIPX if( !CRegistry::Register( L"DirectPlay8SPWSock.TCPIP.1", L"DirectPlay8 WSock TCPIP Provider Object", wszDLLName, &CLSID_DP8SP_TCPIP, L"DirectPlay8SPWSock.TCPIP") ) { DPFERR( "Could not register dp8 IP object" ); fReturn = FALSE; } #ifndef DPNBUILD_NOIPX if( !creg.Open( HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY DPN_REG_LOCAL_WSOCK_IPX_ROOT, FALSE, TRUE ) ) { DPFERR( "Cannot create IPX sub-area!" ); fReturn = FALSE; } else { #if ((! defined(WINCE)) && (! defined(_XBOX))) hr = LoadAndAllocString( IDS_FRIENDLYNAME_IPX, &wszFriendlyName ); if( FAILED( hr ) ) { DPFX(DPFPREP, 0, "Could not load IPX 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_IPX ); } #else // ! WINCE and ! _XBOX // Don't use the resource, just do it directly creg.WriteString( DPN_REG_KEYNAME_FRIENDLY_NAME, L"DirectPlay8 IPX Service Provider" ); creg.WriteGUID( DPN_REG_KEYNAME_GUID, CLSID_DP8SP_IPX ); #endif // ! WINCE and ! _XBOX creg.Close(); } #endif // ! DPNBUILD_NOIPX if( !creg.Open( HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY DPN_REG_LOCAL_WSOCK_TCPIP_ROOT, FALSE, TRUE ) ) { DPFERR( "Cannot create TCPIP sub-area!" ); fReturn = FALSE; } else { #if ((! defined(WINCE)) && (! defined(_XBOX))) hr = LoadAndAllocString( IDS_FRIENDLYNAME_TCPIP, &wszFriendlyName ); if( FAILED( hr ) ) { DPFX(DPFPREP, 0, "Could not load IPX 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_TCPIP ); } #else // ! WINCE and ! _XBOX // Don't use the resource, just do it directly creg.WriteString( DPN_REG_KEYNAME_FRIENDLY_NAME, L"DirectPlay8 TCP/IP Service Provider" ); creg.WriteGUID( DPN_REG_KEYNAME_GUID, CLSID_DP8SP_TCPIP ); #endif // ! WINCE and ! _XBOX creg.Close(); } return fReturn; } #undef DPF_MODNAME #define DPF_MODNAME "DNWsockUnRegister" BOOL DNWsockUnRegister() { HRESULT hr = S_OK; BOOL fReturn = TRUE; #ifndef DPNBUILD_NOIPX if( !CRegistry::UnRegister(&CLSID_DP8SP_IPX) ) { DPFX(DPFPREP, 0, "Failed to unregister IPX object" ); fReturn = FALSE; } #endif // ! DPNBUILD_NOIPX if( !CRegistry::UnRegister(&CLSID_DP8SP_TCPIP) ) { DPFX(DPFPREP, 0, "Failed to unregister IP 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 { #ifndef DPNBUILD_NOIPX if( !creg.DeleteSubKey( &(DPN_REG_LOCAL_WSOCK_IPX_ROOT)[1] ) ) { DPFERR( "Cannot remove IPX sub-key, could have elements" ); } #endif // ! DPNBUILD_NOIPX #pragma TODO(vanceo, "Uncomment IPv6 when ready") /* #ifndef DPNBUILD_NOIPV6 if( !creg.DeleteSubKey( &(DPN_REG_LOCAL_WSOCK_IPV6_ROOT)[1] ) ) { DPFERR( "Cannot remove IPv6 sub-key, could have elements" ); } #endif // ! DPNBUILD_NOIPV6 */ if( !creg.DeleteSubKey( &(DPN_REG_LOCAL_WSOCK_TCPIP_ROOT)[1] ) ) { DPFERR( "Cannot remove TCPIP sub-key, could have elements" ); } } return fReturn; } #endif // ! DPNBUILD_NOCOMREGISTER #ifndef DPNBUILD_LIBINTERFACE #undef DPF_MODNAME #define DPF_MODNAME "DNWsockGetRemainingObjectCount" DWORD DNWsockGetRemainingObjectCount() { return g_lOutstandingInterfaceCount; } #endif // ! DPNBUILD_LIBINTERFACE //********************************************************************** // Constant definitions //********************************************************************** #ifdef __MWERKS__ #define EXP __declspec(dllexport) #else #define EXP #endif // __MWERKS__ //********************************************************************** // Macro definitions //********************************************************************** //********************************************************************** // Structure definitions //********************************************************************** //********************************************************************** // Variable definitions //********************************************************************** //********************************************************************** // Function prototypes //********************************************************************** STDMETHODIMP DNSP_QueryInterface( IDP8ServiceProvider *lpDNSP, REFIID riid, LPVOID * ppvObj); #define NOTSUPPORTED(parm) (HRESULT (__stdcall *) (struct IDP8ServiceProvider *, parm)) DNSP_NotSupported //********************************************************************** // Function definitions //********************************************************************** // these are the vtables for the various WSock service providers One or the // other is used depending on what is passed to DoCreateInstance. #ifndef DPNBUILD_NOIPX static IDP8ServiceProviderVtbl ipxInterface = { DNSP_QueryInterface, DNSP_AddRef, DNSP_Release, DNSP_Initialize, DNSP_Close, DNSP_Connect, DNSP_Disconnect, DNSP_Listen, DNSP_SendData, DNSP_EnumQuery, DNSP_EnumRespond, DNSP_CancelCommand, NOTSUPPORTED(PSPENUMMULTICASTSCOPESDATA), // EnumMulticastScopes NOTSUPPORTED(PSPSHAREENDPOINTINFODATA), // ShareEndpointInfo NOTSUPPORTED(PSPGETENDPOINTBYADDRESSDATA), // GetEndpointByAddress DNSP_Update, DNSP_GetCaps, DNSP_SetCaps, DNSP_ReturnReceiveBuffers, DNSP_GetAddressInfo, #ifdef DPNBUILD_LIBINTERFACE NOTSUPPORTED(PSPISAPPLICATIONSUPPORTEDDATA), // IsApplicationSupported #else // ! DPNBUILD_LIBINTERFACE DNSP_IsApplicationSupported, #endif // ! DPNBUILD_LIBINTERFACE #ifdef DPNBUILD_ONLYONEADAPTER NOTSUPPORTED(PSPENUMADAPTERSDATA), // EnumAdapters #else // ! DPNBUILD_ONLYONEADAPTER DNSP_EnumAdapters, #endif // ! DPNBUILD_ONLYONEADAPTER #ifdef DPNBUILD_SINGLEPROCESS NOTSUPPORTED(PSPPROXYENUMQUERYDATA), // ProxyEnumQuery #else // ! DPNBUILD_SINGLEPROCESS DNSP_ProxyEnumQuery #endif // ! DPNBUILD_SINGLEPROCESS }; #endif // DPNBUILD_NOIPX #ifndef DPNBUILD_NOIPV6 static IDP8ServiceProviderVtbl ipv6Interface = { DNSP_QueryInterface, DNSP_AddRef, DNSP_Release, DNSP_Initialize, DNSP_Close, DNSP_Connect, DNSP_Disconnect, DNSP_Listen, DNSP_SendData, DNSP_EnumQuery, DNSP_EnumRespond, DNSP_CancelCommand, #ifdef DPNBUILD_NOMULTICAST NOTSUPPORTED(PSPENUMMULTICASTSCOPESDATA), // EnumMulticastScopes NOTSUPPORTED(PSPSHAREENDPOINTINFODATA), // ShareEndpointInfo NOTSUPPORTED(PSPGETENDPOINTBYADDRESSDATA), // GetEndpointByAddress #else // ! DPNBUILD_NOMULTICAST DNSP_EnumMulticastScopes, DNSP_ShareEndpointInfo, DNSP_GetEndpointByAddress, #endif // ! DPNBUILD_NOMULTICAST DNSP_Update, DNSP_GetCaps, DNSP_SetCaps, DNSP_ReturnReceiveBuffers, DNSP_GetAddressInfo, #ifdef DPNBUILD_LIBINTERFACE NOTSUPPORTED(PSPISAPPLICATIONSUPPORTEDDATA), // IsApplicationSupported #else // ! DPNBUILD_LIBINTERFACE DNSP_IsApplicationSupported, #endif // ! DPNBUILD_LIBINTERFACE #ifdef DPNBUILD_ONLYONEADAPTER NOTSUPPORTED(PSPENUMADAPTERSDATA), // EnumAdapters #else // ! DPNBUILD_ONLYONEADAPTER DNSP_EnumAdapters, #endif // ! DPNBUILD_ONLYONEADAPTER #ifdef DPNBUILD_SINGLEPROCESS NOTSUPPORTED(PSPPROXYENUMQUERYDATA), // ProxyEnumQuery #else // ! DPNBUILD_SINGLEPROCESS DNSP_ProxyEnumQuery #endif // ! DPNBUILD_SINGLEPROCESS }; #endif // DPNBUILD_NOIPV6 static IDP8ServiceProviderVtbl ipInterface = { DNSP_QueryInterface, DNSP_AddRef, DNSP_Release, DNSP_Initialize, DNSP_Close, DNSP_Connect, DNSP_Disconnect, DNSP_Listen, DNSP_SendData, DNSP_EnumQuery, DNSP_EnumRespond, DNSP_CancelCommand, #ifdef DPNBUILD_NOMULTICAST NOTSUPPORTED(PSPENUMMULTICASTSCOPESDATA), // EnumMulticastScopes NOTSUPPORTED(PSPSHAREENDPOINTINFODATA), // ShareEndpointInfo NOTSUPPORTED(PSPGETENDPOINTBYADDRESSDATA), // GetEndpointByAddress #else // ! DPNBUILD_NOMULTICAST DNSP_EnumMulticastScopes, DNSP_ShareEndpointInfo, DNSP_GetEndpointByAddress, #endif // ! DPNBUILD_NOMULTICAST DNSP_Update, DNSP_GetCaps, DNSP_SetCaps, DNSP_ReturnReceiveBuffers, DNSP_GetAddressInfo, #ifdef DPNBUILD_LIBINTERFACE NOTSUPPORTED(PSPISAPPLICATIONSUPPORTEDDATA), // IsApplicationSupported #else // ! DPNBUILD_LIBINTERFACE DNSP_IsApplicationSupported, #endif // ! DPNBUILD_LIBINTERFACE #ifdef DPNBUILD_ONLYONEADAPTER NOTSUPPORTED(PSPENUMADAPTERSDATA), // EnumAdapters #else // ! DPNBUILD_ONLYONEADAPTER DNSP_EnumAdapters, #endif // ! DPNBUILD_ONLYONEADAPTER #ifdef DPNBUILD_SINGLEPROCESS NOTSUPPORTED(PSPPROXYENUMQUERYDATA), // ProxyEnumQuery #else // ! DPNBUILD_SINGLEPROCESS DNSP_ProxyEnumQuery #endif // ! DPNBUILD_SINGLEPROCESS }; //********************************************************************** // ------------------------------ // DNSP_QueryInterface - query for interface // // Entry: Pointer to current interface // GUID of desired interface // Pointer to pointer to new interface // // Exit: Error code // ------------------------------ #undef DPF_MODNAME #define DPF_MODNAME "DNSP_QueryInterface" STDMETHODIMP DNSP_QueryInterface( IDP8ServiceProvider *lpDNSP, REFIID riid, LPVOID * ppvObj) { HRESULT hr = S_OK; #ifndef DPNBUILD_LIBINTERFACE // hmmm, switch would be cleaner... if ((! IsEqualIID(riid, IID_IUnknown)) && (! IsEqualIID(riid, IID_IDP8ServiceProvider))) { *ppvObj = NULL; hr = E_NOINTERFACE; } else #endif // ! DPNBUILD_LIBINTERFACE { #ifdef DPNBUILD_LIBINTERFACE DNASSERT(! "Querying SP interface when using DPNBUILD_LIBINTERFACE!"); #endif // DPNBUILD_LIBINTERFACE *ppvObj = lpDNSP; DNSP_AddRef(lpDNSP); } return hr; } //********************************************************************** #ifndef DPNBUILD_NOIPX //********************************************************************** // ------------------------------ // CreateIPXInterface - create an IPX interface // // Entry: Pointer to pointer to SP interface // Pointer to pointer to associated SP data // // Exit: Error code // ------------------------------ #undef DPF_MODNAME #define DPF_MODNAME "CreateIPXInterface" #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL HRESULT CreateIPXInterface( const XDP8CREATE_PARAMS * const pDP8CreateParams, IDP8ServiceProvider **const ppiDP8SP ) #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL HRESULT CreateIPXInterface( IDP8ServiceProvider **const ppiDP8SP ) #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL { HRESULT hr; CSPData *pSPData; DNASSERT( ppiDP8SP != NULL ); // // initialize // hr = DPN_OK; pSPData = NULL; *ppiDP8SP = NULL; // // create main data class // hr = CreateSPData( &pSPData, AF_IPX, #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL pDP8CreateParams, #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL &ipxInterface ); 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; } //********************************************************************** #endif // ! DPNBUILD_NOIPX //********************************************************************** // ------------------------------ // CreateIPInterface - create an IP interface // // Entry: Pointer to pointer to SP interface // // Exit: Error code // ------------------------------ #undef DPF_MODNAME #define DPF_MODNAME "CreateIPInterface" #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL HRESULT CreateIPInterface( const XDP8CREATE_PARAMS * const pDP8CreateParams, IDP8ServiceProvider **const ppiDP8SP ) #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL HRESULT CreateIPInterface( IDP8ServiceProvider **const ppiDP8SP ) #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL { HRESULT hr; CSPData *pSPData; DNASSERT( ppiDP8SP != NULL ); // // initialize // hr = DPN_OK; pSPData = NULL; *ppiDP8SP = NULL; // // create main data class // hr = CreateSPData( &pSPData, #if ((! defined(DPNBUILD_NOIPX)) || (! defined(DPNBUILD_NOIPV6))) AF_INET, #endif // ! DPNBUILD_NOIPX or ! DPNBUILD_NOIPV6 #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL pDP8CreateParams, #endif // DPNBUILD_PREALLOCATEDMEMORYMODEL &ipInterface ); 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 //********************************************************************** // ------------------------------ // DoCreateInstance - 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 DoCreateInstance( 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_TCPIP)) { hr = CreateIPInterface( reinterpret_cast( ppvObj ) ); } #ifndef DPNBUILD_NOIPX else if (IsEqualCLSID(rclsid, CLSID_DP8SP_IPX)) { hr = CreateIPXInterface( reinterpret_cast( ppvObj ) ); } #endif // ! DPNBUILD_NOIPX 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 #if ((! defined(WINCE)) && (! defined(_XBOX))) #define MAX_RESOURCE_STRING_LENGTH _MAX_PATH #undef DPF_MODNAME #define DPF_MODNAME "LoadAndAllocString" HRESULT LoadAndAllocString( UINT uiResourceID, wchar_t **lpswzString ) { int length; HRESULT hr; TCHAR szTmpBuffer[MAX_RESOURCE_STRING_LENGTH]; length = LoadString( g_hDLLInstance, 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; } } #endif // !WINCE and ! _XBOX