Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1810 lines
48 KiB

/*==========================================================================
*
* 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 "dnmdmi.h"
//**********************************************************************
// Constant definitions
//**********************************************************************
#define DEFAULT_WIN9X_THREADS 1
static const WCHAR g_RegistryBase[] = L"SOFTWARE\\Microsoft\\DirectPlay8";
static const WCHAR g_RegistryKeyThreadCount[] = L"ThreadCount";
//
// default buffer size for getting TAPI device caps
//
static const DWORD g_dwDefaultTAPIDevCapsSize = 512;
//
// TAPI module name
//
static const TCHAR g_TAPIModuleName[] = TEXT("TAPI32.DLL");
//**********************************************************************
// Macro definitions
//**********************************************************************
//**********************************************************************
// Structure definitions
//**********************************************************************
//**********************************************************************
// Variable definitions
//**********************************************************************
//
// global variables that are unique for the process
//
#ifndef DPNBUILD_ONLYONETHREAD
static DNCRITICAL_SECTION g_InterfaceGlobalsLock;
#endif // !DPNBUILD_ONLYONETHREAD
static volatile LONG g_iThreadPoolRefCount = 0;
static CModemThreadPool *g_pThreadPool = NULL;
static volatile LONG g_iTAPIRefCount = 0;
static HMODULE g_hTAPIModule = NULL;
//**********************************************************************
// Function prototypes
//**********************************************************************
static void ReadSettingsFromRegistry( void );
static BYTE GetAddressEncryptionKey( void );
//**********************************************************************
// Function definitions
//**********************************************************************
//**********************************************************************
// ------------------------------
// ModemInitProcessGlobals - 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 "ModemInitProcessGlobals"
BOOL ModemInitProcessGlobals( void )
{
BOOL fReturn;
BOOL fCriticalSectionInitialized;
DWORD iIndex;
//
// initialize
//
fReturn = TRUE;
fCriticalSectionInitialized = FALSE;
#ifdef DBG
g_blDPNModemCritSecsHeld.Initialize();
#endif // DBG
ReadSettingsFromRegistry();
if ( DNInitializeCriticalSection( &g_InterfaceGlobalsLock ) == FALSE )
{
fReturn = FALSE;
goto Failure;
}
DebugSetCriticalSectionGroup( &g_InterfaceGlobalsLock, &g_blDPNModemCritSecsHeld ); // separate dpnmodem CSes from the rest of DPlay's CSes
fCriticalSectionInitialized = TRUE;
if ( ModemInitializePools() == FALSE )
{
fReturn = FALSE;
goto Failure;
}
// Load localized string from resources //////////////////////////////////////////////////////////////
for (iIndex = 0; iIndex < g_dwBaudRateCount; iIndex++)
{
if (!LoadString(g_hModemDLLInstance, IDS_BAUD_9600 + iIndex, g_BaudRate[iIndex].szLocalizedKey, 256))
{
fReturn = FALSE;
goto Failure;
}
}
for (iIndex = 0; iIndex < g_dwStopBitsCount; iIndex++)
{
if (!LoadString(g_hModemDLLInstance, IDS_STOPBITS_ONE + iIndex, g_StopBits[iIndex].szLocalizedKey, 256))
{
fReturn = FALSE;
goto Failure;
}
}
for (iIndex = 0; iIndex < g_dwParityCount; iIndex++)
{
if (!LoadString(g_hModemDLLInstance, IDS_PARITY_EVEN + iIndex, g_Parity[iIndex].szLocalizedKey, 256))
{
fReturn = FALSE;
goto Failure;
}
}
for (iIndex = 0; iIndex < g_dwFlowControlCount; iIndex++)
{
if (!LoadString(g_hModemDLLInstance, IDS_FLOW_NONE + iIndex, g_FlowControl[iIndex].szLocalizedKey, 256))
{
fReturn = FALSE;
goto Failure;
}
}
DNASSERT( g_pThreadPool == NULL );
Exit:
return fReturn;
Failure:
ModemDeinitializePools();
if ( fCriticalSectionInitialized != FALSE )
{
DNDeleteCriticalSection( &g_InterfaceGlobalsLock );
fCriticalSectionInitialized = FALSE;
}
goto Exit;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// ModemDeinitProcessGlobals - deinitialize the global items
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "ModemDeinitProcessGlobals"
void ModemDeinitProcessGlobals( void )
{
DNASSERT( g_pThreadPool == NULL );
DNASSERT( g_iThreadPoolRefCount == 0 );
ModemDeinitializePools();
DNDeleteCriticalSection( &g_InterfaceGlobalsLock );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// InitializeInterfaceGlobals - perform global initialization for an interface.
// This entails starting the thread pool and RSIP (if applicable).
//
// Entry: Pointer to SPData
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "InitializeInterfaceGlobals"
HRESULT InitializeInterfaceGlobals( CModemSPData *const pSPData )
{
HRESULT hr;
DNASSERT( pSPData != NULL );
//
// initialize
//
hr = DPN_OK;
DNEnterCriticalSection( &g_InterfaceGlobalsLock );
if ( g_pThreadPool == NULL )
{
DNASSERT( g_iThreadPoolRefCount == 0 );
g_pThreadPool = (CModemThreadPool*)g_ModemThreadPoolPool.Get();
if ( g_pThreadPool == NULL )
{
hr = DPNERR_OUTOFMEMORY;
goto Failure;
}
else
{
if (!g_pThreadPool->Initialize())
{
hr = DPNERR_OUTOFMEMORY;
g_ModemThreadPoolPool.Release(g_pThreadPool);
g_pThreadPool = NULL;
goto Failure;
}
g_iThreadPoolRefCount++;
}
}
else
{
DNASSERT( g_iThreadPoolRefCount != 0 );
g_iThreadPoolRefCount++;
g_pThreadPool->AddRef();
}
Exit:
pSPData->SetThreadPool( g_pThreadPool );
DNLeaveCriticalSection( &g_InterfaceGlobalsLock );
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( CModemSPData *const pSPData )
{
CModemThreadPool *pThreadPool;
BOOL fCleanUp;
DNASSERT( pSPData != NULL );
//
// initialize
//
pThreadPool = NULL;
fCleanUp = FALSE;
//
// 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
//
g_iThreadPoolRefCount--;
if ( g_iThreadPoolRefCount == 0 )
{
g_pThreadPool = NULL;
fCleanUp = TRUE;
}
DNLeaveCriticalSection( &g_InterfaceGlobalsLock );
//
// now that we're outside of the lock, clean up the thread pool if this
// was the last reference to it
//
DNASSERT( pThreadPool != NULL );
if ( fCleanUp != FALSE )
{
pThreadPool->Deinitialize();
}
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// LoadTAPILibrary - load TAPI library
//
// Entry: Nothing
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "LoadTAPILibrary"
HRESULT LoadTAPILibrary( void )
{
HRESULT hr;
//
// initialize
//
hr = DPN_OK;
DNEnterCriticalSection( &g_InterfaceGlobalsLock );
if ( g_iTAPIRefCount != 0 )
{
DNASSERT( p_lineAnswer != NULL );
DNASSERT( p_lineClose != NULL );
DNASSERT( p_lineConfigDialog != NULL );
DNASSERT( p_lineDeallocateCall != NULL );
DNASSERT( p_lineDrop != NULL );
DNASSERT( p_lineGetDevCaps != NULL );
DNASSERT( p_lineGetID != NULL );
DNASSERT( p_lineGetMessage != NULL );
DNASSERT( p_lineInitializeEx != NULL );
DNASSERT( p_lineMakeCall != NULL );
DNASSERT( p_lineNegotiateAPIVersion != NULL );
DNASSERT( p_lineOpen != NULL );
DNASSERT( p_lineShutdown != NULL );
}
else
{
DNASSERT( g_hTAPIModule == NULL );
DNASSERT( p_lineAnswer == NULL );
DNASSERT( p_lineClose == NULL );
DNASSERT( p_lineConfigDialog == NULL );
DNASSERT( p_lineDeallocateCall == NULL );
DNASSERT( p_lineDrop == NULL );
DNASSERT( p_lineGetDevCaps == NULL );
DNASSERT( p_lineGetID == NULL );
DNASSERT( p_lineGetMessage == NULL );
DNASSERT( p_lineInitializeEx == NULL );
DNASSERT( p_lineMakeCall == NULL );
DNASSERT( p_lineNegotiateAPIVersion == NULL );
DNASSERT( p_lineOpen == NULL );
DNASSERT( p_lineShutdown == NULL );
g_hTAPIModule = LoadLibrary( g_TAPIModuleName );
if ( g_hTAPIModule == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to load TAPI!" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineAnswer = reinterpret_cast<TAPI_lineAnswer*>( GetProcAddress( g_hTAPIModule, "lineAnswer" ) );
if ( p_lineAnswer == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineAnswer" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineClose = reinterpret_cast<TAPI_lineClose*>( GetProcAddress( g_hTAPIModule, "lineClose" ) );
if ( p_lineClose == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineClose" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineConfigDialog = reinterpret_cast<TAPI_lineConfigDialog*>( GetProcAddress( g_hTAPIModule, "lineConfigDialog" TAPI_APPEND_LETTER ) );
if ( p_lineConfigDialog == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineConfigDialog" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineDeallocateCall = reinterpret_cast<TAPI_lineDeallocateCall*>( GetProcAddress( g_hTAPIModule, "lineDeallocateCall" ) );
if ( p_lineDeallocateCall == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineDeallocateCall" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineDrop = reinterpret_cast<TAPI_lineDrop*>( GetProcAddress( g_hTAPIModule, "lineDrop" ) );
if ( p_lineDrop == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineDrop" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineGetDevCaps = reinterpret_cast<TAPI_lineGetDevCaps*>( GetProcAddress( g_hTAPIModule, "lineGetDevCaps" TAPI_APPEND_LETTER ) );
if ( p_lineGetDevCaps == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineGetDevCaps" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineGetID = reinterpret_cast<TAPI_lineGetID*>( GetProcAddress( g_hTAPIModule, "lineGetID" TAPI_APPEND_LETTER ) );
if ( p_lineGetID == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineGetID" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineGetMessage = reinterpret_cast<TAPI_lineGetMessage*>( GetProcAddress( g_hTAPIModule, "lineGetMessage" ) );
if ( p_lineGetMessage == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineGetMessage" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineInitializeEx = reinterpret_cast<TAPI_lineInitializeEx*>( GetProcAddress( g_hTAPIModule, "lineInitializeEx" TAPI_APPEND_LETTER ) );
if ( p_lineInitializeEx == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineInitializeEx" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineMakeCall = reinterpret_cast<TAPI_lineMakeCall*>( GetProcAddress( g_hTAPIModule, "lineMakeCall" TAPI_APPEND_LETTER ) );
if ( p_lineMakeCall == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineMakeCall" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineNegotiateAPIVersion = reinterpret_cast<TAPI_lineNegotiateAPIVersion*>( GetProcAddress( g_hTAPIModule, "lineNegotiateAPIVersion" ) );
if ( p_lineNegotiateAPIVersion == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineNegotiateAPIVersion" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineOpen = reinterpret_cast<TAPI_lineOpen*>( GetProcAddress( g_hTAPIModule, "lineOpen" TAPI_APPEND_LETTER ) );
if ( p_lineOpen == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineOpen" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
p_lineShutdown = reinterpret_cast<TAPI_lineShutdown*>( GetProcAddress( g_hTAPIModule, "lineShutdown" ) );
if ( p_lineShutdown == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to GetProcAddress for lineShutdown" );
DisplayErrorCode( 0, dwError );
goto Failure;
}
}
DNASSERT( g_iTAPIRefCount != -1 );
g_iTAPIRefCount++;
Exit:
DNLeaveCriticalSection( &g_InterfaceGlobalsLock );
return hr;
Failure:
hr = DPNERR_OUTOFMEMORY;
p_lineAnswer = NULL;
p_lineClose = NULL;
p_lineConfigDialog = NULL;
p_lineDeallocateCall = NULL;
p_lineDrop = NULL;
p_lineGetDevCaps = NULL;
p_lineGetID = NULL;
p_lineGetMessage = NULL;
p_lineInitializeEx = NULL;
p_lineMakeCall = NULL;
p_lineNegotiateAPIVersion = NULL;
p_lineOpen = NULL;
p_lineShutdown = NULL;
if ( g_hTAPIModule != NULL )
{
if ( FreeLibrary( g_hTAPIModule ) == FALSE )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Problem unloading TAPI module on failed load!" );
DisplayErrorCode( 0, dwError );
}
g_hTAPIModule = NULL;
}
goto Exit;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// UnloadTAPILibrary - unload TAPI library
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "UnloadTAPILibrary"
void UnloadTAPILibrary( void )
{
DNEnterCriticalSection( &g_InterfaceGlobalsLock );
DNASSERT( g_iTAPIRefCount != 0 );
g_iTAPIRefCount--;
if ( g_iTAPIRefCount == 0 )
{
DNASSERT( g_hTAPIModule != NULL );
DNASSERT( p_lineAnswer != NULL );
DNASSERT( p_lineClose != NULL );
DNASSERT( p_lineConfigDialog != NULL );
DNASSERT( p_lineDeallocateCall != NULL );
DNASSERT( p_lineDrop != NULL );
DNASSERT( p_lineGetDevCaps != NULL );
DNASSERT( p_lineGetID != NULL );
DNASSERT( p_lineGetMessage != NULL );
DNASSERT( p_lineInitializeEx != NULL );
DNASSERT( p_lineMakeCall != NULL );
DNASSERT( p_lineNegotiateAPIVersion != NULL );
DNASSERT( p_lineOpen != NULL );
DNASSERT( p_lineShutdown != NULL );
if ( FreeLibrary( g_hTAPIModule ) == FALSE )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Problem unloading TAPI module on failed load!" );
DisplayErrorCode( 0, dwError );
}
g_hTAPIModule = NULL;
p_lineAnswer = NULL;
p_lineClose = NULL;
p_lineConfigDialog = NULL;
p_lineDeallocateCall = NULL;
p_lineDrop = NULL;
p_lineGetDevCaps = NULL;
p_lineGetID = NULL;
p_lineGetMessage = NULL;
p_lineInitializeEx = NULL;
p_lineMakeCall = NULL;
p_lineNegotiateAPIVersion = NULL;
p_lineOpen = NULL;
p_lineShutdown = NULL;
}
DNLeaveCriticalSection( &g_InterfaceGlobalsLock );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// IsSerialGUID - is a GUID a serial GUID?
//
// Entry: Pointer to GUID
//
// Exit: Boolean inficating whether the GUID is a serial GUID
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "IsSerialGUID"
BOOL IsSerialGUID( const GUID *const pGuid )
{
BOOL fReturn;
DNASSERT( pGuid != NULL );
//
// assume guid is serial
//
fReturn = TRUE;
//
// is this modem or serial?
//
if ( IsEqualCLSID( *pGuid, CLSID_DP8SP_MODEM ) == FALSE )
{
if ( IsEqualCLSID( *pGuid, CLSID_DP8SP_SERIAL ) == FALSE )
{
// not a known GUID
fReturn = FALSE;
}
}
return fReturn;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// StringToValue - convert a string to an enumerated value
//
// Entry: Pointer to string
// Length of string
// Pointer to destination enum
// Pointer to string/enum pairs
// Count of string/enum pairs
//
// Exit: Boolean indicating success
// TRUE = value found
// FALSE = value not found
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "StringToValue"
BOOL StringToValue( const WCHAR *const pString,
const DWORD dwStringLength,
VALUE_ENUM_TYPE *const pEnum,
const STRING_BLOCK *const pStringBlock,
const DWORD dwPairCount )
{
BOOL fFound;
DWORD dwCount;
// initialize
fFound = FALSE;
dwCount = dwPairCount;
// loop through list
while ( ( dwCount > 0 ) && ( fFound == FALSE ) )
{
// make array index
dwCount--;
// are the strings the same length?
if ( pStringBlock[ dwCount ].dwWCHARKeyLength == dwStringLength )
{
// is this what we were looking for?
if ( memcmp( pString, pStringBlock[ dwCount ].pWCHARKey, dwStringLength ) == 0 )
{
// found it
fFound = TRUE;
*pEnum = pStringBlock[ dwCount ].dwEnumValue;
}
}
}
return fFound;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// ValueToString - split extra info into components
//
// Entry: Pointer to pointer to string
// Length of string
// Enumerated value
// Pointer to string-enum pairs
// Count of string-enum pairs
//
// Exit: Boolean indicating success
// TRUE = value was converted
// FALSE = value was not converted
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "ValueToString"
BOOL ValueToString( const WCHAR **const ppString,
DWORD *const pdwStringLength,
const DWORD Enum,
const STRING_BLOCK *const pStringBlock,
const DWORD dwPairCount )
{
BOOL fFound;
DWORD dwCount;
// initialize
fFound = FALSE;
dwCount = dwPairCount;
// loop through strings
while ( ( dwCount > 0 ) && ( fFound == FALSE ))
{
// make array index
dwCount--;
// is this the enum?
if ( pStringBlock[ dwCount ].dwEnumValue == Enum )
{
// note that we found the value
*ppString = pStringBlock[ dwCount ].pWCHARKey;
*pdwStringLength = pStringBlock[ dwCount ].dwWCHARKeyLength;
fFound = TRUE;
}
}
return fFound;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// ReadSettingsFromRegistry - read custom registry keys
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "ReadSettingsFromRegistry"
static void ReadSettingsFromRegistry( void )
{
CRegistry RegObject;
if ( RegObject.Open( HKEY_LOCAL_MACHINE, g_RegistryBase ) != FALSE )
{
DWORD 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 // WIN95
}
RegObject.Close();
}
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// GetAddressEncryptionKey - get a key used to encrypt device GUIDs
//
// Entry: Nothing
//
// Exit: Byte key
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "GetAddressEncryptionKey"
static BYTE GetAddressEncryptionKey( void )
{
BYTE bReturn;
UINT_PTR ProcessID;
bReturn = 0;
ProcessID = GetCurrentProcessId();
while ( ProcessID > 0 )
{
bReturn ^= ProcessID;
ProcessID >>= ( sizeof( bReturn ) * 8 );
}
return bReturn;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// DeviceIDToGuid - convert a device ID to an adapter GUID
//
// Entry: Reference of Guid to fill
// Device ID
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "DeviceIDToGuid"
void DeviceIDToGuid( GUID *const pGuid, const UINT_PTR DeviceID, const GUID *const pEncryptionGuid )
{
DNASSERT( DeviceID < MAX_DATA_PORTS );
DNASSERT( sizeof( *pGuid ) == sizeof( *pEncryptionGuid ) );
memset( pGuid, 0x00, sizeof( *pGuid ) );
reinterpret_cast<BYTE*>( pGuid )[ 0 ] = static_cast<BYTE>( DeviceID );
ModemEncryptGuid( pGuid, pGuid, pEncryptionGuid );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// GuidToDeviceID - convert an adapter GUID to a device ID
//
// Entry: Reference of Guid
//
//
// Exit: Device ID
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "GuidToDeviceID"
DWORD GuidToDeviceID( const GUID *const pGuid, const GUID *const pEncryptionGuid )
{
GUID DecryptedGuid;
DNASSERT( pGuid != NULL );
DNASSERT( pEncryptionGuid != NULL );
ModemDecryptGuid( pGuid, &DecryptedGuid, pEncryptionGuid );
return reinterpret_cast<const BYTE*>( &DecryptedGuid )[ 0 ];
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// ComDeviceIDToString - convert a COM device ID to a string
//
// Entry: Pointer to destination string (assumed to be large enough)
// Device ID
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "ComDeviceIDToString"
void ComDeviceIDToString( TCHAR *const pString, const UINT_PTR uDeviceID )
{
UINT_PTR uTemp;
DNASSERT( uDeviceID < MAX_DATA_PORTS );
uTemp = uDeviceID;
memcpy( pString, TEXT("COM000"), COM_PORT_STRING_LENGTH * sizeof(TCHAR) );
pString[ 5 ] = ( static_cast<char>( uTemp % 10 ) ) + TEXT('0');
uTemp /= 10;
pString[ 4 ] = ( static_cast<char>( uTemp % 10 ) ) + TEXT('0');
uTemp /= 10;
pString[ 3 ] = ( static_cast<char>( uTemp % 10 ) ) + TEXT('0');
DNASSERT( uTemp < 10 );
if ( uDeviceID < 100 )
{
if ( uDeviceID < 10 )
{
DNASSERT( pString[ 3 ] == TEXT('0') );
DNASSERT( pString[ 4 ] == TEXT('0') );
pString[ 3 ] = pString[ 5 ];
pString[ 4 ] = TEXT('\0');
pString[ 5 ] = TEXT('\0');
}
else
{
DNASSERT( pString[ 3 ] == TEXT('0') );
pString[ 3 ] = pString[ 4 ];
pString[ 4 ] = pString[ 5 ];
pString[ 5 ] = TEXT('\0');
}
}
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// WideToANSI - convert a wide string to an ANSI string
//
// Entry: Pointer to source wide string
// Size of source string (in WCHAR units, -1 implies NULL-terminated)
// Pointer to ANSI string destination
// Pointer to size of ANSI destination
//
// Exit: Error code:
// DPNERR_GENERIC = operation failed
// DPN_OK = operation succeded
// DPNERR_BUFFERTOOSMALL = destination buffer too small
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "WideToAnsi"
HRESULT WideToAnsi( const WCHAR *const pWCHARString, const DWORD dwWCHARStringLength, char *const pString, DWORD *const pdwStringLength )
{
HRESULT hr;
int iReturn;
BOOL fDefault;
DNASSERT( pWCHARString != NULL );
DNASSERT( pdwStringLength != NULL );
DNASSERT( ( pString != NULL ) || ( &pdwStringLength == 0 ) );
hr = DPN_OK;
fDefault = FALSE;
iReturn = WideCharToMultiByte( CP_ACP, // code page (default ANSI)
0, // flags (none)
pWCHARString, // pointer to WCHAR string
dwWCHARStringLength, // size of WCHAR string
pString, // pointer to destination ANSI string
*pdwStringLength, // size of destination string
NULL, // pointer to default for unmappable characters (none)
&fDefault // pointer to flag indicating that default was used
);
if ( iReturn == 0 )
{
hr = DPNERR_GENERIC;
}
else
{
if ( *pdwStringLength == 0 )
{
hr = DPNERR_BUFFERTOOSMALL;
}
else
{
DNASSERT( hr == DPN_OK );
}
*pdwStringLength = iReturn;
}
//
// if you hit this ASSERT it's because you've probably got ASCII text as your
// input WCHAR string. Double-check your input!!
//
DNASSERT( fDefault == FALSE );
return hr;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// ANSIToWide - convert an ANSI string to a wide string
//
// Entry: Pointer to source multi-byte (ANSI) string
// Size of source string (-1 imples NULL-terminated)
// Pointer to multi-byte string destination
// Pointer to size of multi-byte destination (in WCHAR units)
//
// Exit: Error code:
// ERR_FAIL - operation failed
// ERR_NONE - operation succeded
// ERR_BUFFER_TOO_SMALL - destination buffer too small
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "AnsiToWide"
HRESULT AnsiToWide( const char *const pString, const DWORD dwStringLength, WCHAR *const pWCHARString, DWORD *const pdwWCHARStringLength )
{
HRESULT hr;
int iReturn;
DNASSERT( pdwWCHARStringLength != 0 );
DNASSERT( ( pWCHARString != NULL ) || ( pdwWCHARStringLength == 0 ) );
DNASSERT( pString != NULL );
hr = DPN_OK;
iReturn = MultiByteToWideChar( CP_ACP, // code page (default ANSI)
0, // flags (none)
pString, // pointer to multi-byte string
dwStringLength, // size of string (assume null-terminated)
pWCHARString, // pointer to destination wide-char string
*pdwWCHARStringLength // size of destination in WCHARs
);
if ( iReturn == 0 )
{
hr = DPNERR_GENERIC;
}
else
{
if ( *pdwWCHARStringLength == 0 )
{
hr = DPNERR_BUFFERTOOSMALL;
}
else
{
DNASSERT( hr == DPN_OK );
}
*pdwWCHARStringLength = iReturn;
}
return hr;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CreateSPData - create instance data for SP
//
// Entry: Pointer to pointer to SPData
// Pionter to class GUID
// Interface type
// Pointer to COM interface vtable
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CreateSPData"
HRESULT CreateSPData( CModemSPData **const ppSPData,
const SP_TYPE SPType,
IDP8ServiceProviderVtbl *const pVtbl )
{
HRESULT hr;
CModemSPData *pSPData;
DNASSERT( ppSPData != NULL );
DNASSERT( pVtbl != NULL );
//
// initialize
//
hr = DPN_OK;
*ppSPData = NULL;
pSPData = NULL;
//
// create data
//
pSPData = new CModemSPData;
if ( pSPData == NULL )
{
hr = DPNERR_OUTOFMEMORY;
DPFX(DPFPREP, 0, "Cannot create data for interface!" );
goto Failure;
}
pSPData->AddRef();
hr = pSPData->Initialize( SPType, pVtbl );
if ( hr != DPN_OK )
{
DPFX(DPFPREP, 0, "Failed to intialize SP data!" );
DisplayDNError( 0, hr );
goto Failure;
}
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;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// GenerateAvailableComPortList - generate a list of available com ports
//
// Entry: Pointer to list of Booleans to indicate availablility
// Maximum index of comport to enumerate
// Pointer to number of com ports found
//
// Exit: Error code
//
// Note: This function will fill in indicies 1 through uMaxDeviceIndex.
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "GenerateAvailableComPortList"
HRESULT GenerateAvailableComPortList( BOOL *const pfPortAvailable,
const UINT_PTR uMaxDeviceIndex,
DWORD *const pdwPortCount )
{
HRESULT hr;
UINT_PTR uIndex;
UINT_PTR uPortCount;
DNASSERT( pfPortAvailable != NULL );
DNASSERT( uMaxDeviceIndex != 0 );
DNASSERT( pdwPortCount != NULL );
//
// initialize
//
hr = DPN_OK;
uPortCount = 0;
memset( pfPortAvailable, 0x00, ( sizeof( *pfPortAvailable ) * ( uMaxDeviceIndex + 1 ) ) );
*pdwPortCount = 0;
//
// attempt to open all COM ports in the specified range
//
uIndex = uMaxDeviceIndex;
while ( uIndex != 0 )
{
DNHANDLE hComFile;
TCHAR ComTemplate[ (COM_PORT_STRING_LENGTH+1) ];
DWORD dwError;
ComDeviceIDToString( ComTemplate, uIndex );
hComFile = DNCreateFile( ComTemplate, // comm port name
GENERIC_READ | GENERIC_WRITE, // read/write access
0, // don't share file with others
NULL, // default sercurity descriptor
OPEN_EXISTING, // comm port must exist to be opened
FILE_FLAG_OVERLAPPED, // use overlapped I/O
NULL // no handle for template file
);
if ( hComFile == DNINVALID_HANDLE_VALUE )
{
dwError = GetLastError();
if ( dwError != ERROR_ACCESS_DENIED )
{
//
// Don't bother displaying ERROR_FILE_NOT_FOUND, that's the usual
// error when you try to open a bogus COM port.
//
if ( dwError != ERROR_FILE_NOT_FOUND )
{
DPFX(DPFPREP, 9, "Couldn't open COM%u while enumerating com port adapters, err = %u.", uIndex, dwError );
DisplayErrorCode( 9, dwError );
}
goto SkipComPort;
}
DPFX(DPFPREP, 1, "Couldn't open COM%u, it is probably already in use.", uIndex );
//
// Consider the port as possibly available, continue.
//
}
//
// We found a valid COM port (it may be in use), note which COM port
// this is and then close our handle
//
pfPortAvailable[ uIndex ] = TRUE;
uPortCount++;
if ( hComFile != DNINVALID_HANDLE_VALUE )
{
if ( DNCloseHandle( hComFile ) == FALSE )
{
dwError = GetLastError();
DPFX(DPFPREP, 0, "Problem closing COM%u while enumerating com port adapters, err = %u!",
uIndex, dwError );
DisplayErrorCode( 0, dwError );
}
}
SkipComPort:
uIndex--;
}
DNASSERT( uPortCount <= UINT32_MAX );
DBG_CASSERT( sizeof( *pdwPortCount ) == sizeof( DWORD ) );
*pdwPortCount = static_cast<DWORD>( uPortCount );
return hr;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// GenerateAvailableModemList - generate list of available modems
//
// Entry: Pointer to TAPI data
// Pointer to modem count
// Pointer to data block
// Pointer to size of data block
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "GenerateAvailableModemList"
HRESULT GenerateAvailableModemList( const TAPI_INFO *const pTAPIInfo,
DWORD *const pdwModemCount,
MODEM_NAME_DATA *const pModemNameData,
DWORD *const pdwModemNameDataSize )
{
HRESULT hr;
LONG lLineReturn;
DWORD dwDeviceID;
DWORD dwDevCapsSize;
DWORD dwAPIVersion;
LINEDEVCAPS *pDevCaps;
LINEEXTENSIONID LineExtensionID;
DWORD dwRequiredBufferSize;
TCHAR *pOutputModemName;
DNASSERT( pdwModemCount != NULL );
DNASSERT( pdwModemNameDataSize != NULL );
DNASSERT( ( pModemNameData != NULL ) || ( *pdwModemNameDataSize == 0 ) );
//
// initialize
//
hr = DPN_OK;
dwRequiredBufferSize = 0;
*pdwModemCount = 0;
pDevCaps = NULL;
if ( pModemNameData != NULL )
{
pOutputModemName = &(reinterpret_cast<TCHAR*>( pModemNameData )[ *pdwModemNameDataSize / sizeof(TCHAR) ]);
memset( pModemNameData, 0x00, *pdwModemNameDataSize );
}
else
{
pOutputModemName = NULL;
}
dwDevCapsSize = g_dwDefaultTAPIDevCapsSize;
pDevCaps = static_cast<LINEDEVCAPS*>( DNMalloc( dwDevCapsSize ) );
if ( pDevCaps == NULL )
{
hr = DPNERR_OUTOFMEMORY;
goto Failure;
}
dwDeviceID = pTAPIInfo->dwLinesAvailable;
if ( dwDeviceID > ( MAX_DATA_PORTS - 2 ) )
{
dwDeviceID = MAX_DATA_PORTS - 2;
DPFX(DPFPREP, 0, "Truncating to %d devices!", dwDeviceID );
}
Reloop:
while ( dwDeviceID != 0 )
{
dwDeviceID--;
memset( &LineExtensionID, 0x00, sizeof( LineExtensionID ) );
DNASSERT( p_lineNegotiateAPIVersion != NULL );
lLineReturn = p_lineNegotiateAPIVersion( pTAPIInfo->hApplicationInstance, // handle to TAPI instance
dwDeviceID, // device ID
0,
pTAPIInfo->dwVersion, // maximum TAPI version
&dwAPIVersion, // pointer to negotiated line version
&LineExtensionID // pointer to line extension infromation (none)
);
if ( lLineReturn != LINEERR_NONE )
{
//
// let this slide, just return no name string
//
switch ( lLineReturn )
{
//
// this TAPI device isn't up to our standards, ignore it
//
case LINEERR_INCOMPATIBLEAPIVERSION:
{
DPFX(DPFPREP, 0, "Rejecting TAPI device 0x%x because of API version!", dwDeviceID );
goto Reloop;
break;
}
//
// Device is not present. I don't know what causes
// this, but I saw it on one of my dev machines after
// I switched the modem from COM2 to COM1.
//
case LINEERR_NODEVICE:
{
DPFX(DPFPREP, 0, "Rejecting TAPI device 0x%x because it's not there!", dwDeviceID );
goto Reloop;
break;
}
//
// This was seen in PnP stress.
//
case LINEERR_UNINITIALIZED:
{
DPFX(DPFPREP, 0, "Rejecting TAPI device 0x%x because it is not initialized!", dwDeviceID );
goto Reloop;
break;
}
//
// other, stop and see what happened
//
default:
{
DPFX(DPFPREP, 0, "Problem getting line API version for device: %d", dwDeviceID );
DisplayTAPIError( 0, lLineReturn );
goto Reloop;
break;
}
}
}
//
// ask for device caps
//
pDevCaps->dwTotalSize = dwDevCapsSize;
pDevCaps->dwNeededSize = dwDevCapsSize;
lLineReturn = LINEERR_STRUCTURETOOSMALL;
while ( lLineReturn == LINEERR_STRUCTURETOOSMALL )
{
DNASSERT( pDevCaps != NULL );
dwDevCapsSize = pDevCaps->dwNeededSize;
DNFree( pDevCaps );
pDevCaps = (LINEDEVCAPS*) DNMalloc( dwDevCapsSize );
if ( pDevCaps == NULL )
{
hr = DPNERR_OUTOFMEMORY;
DPFX(DPFPREP, 0, "GetAvailableModemList: Failed to realloc memory on device %d!", dwDeviceID );
goto Failure;
}
pDevCaps->dwTotalSize = dwDevCapsSize;
pDevCaps->dwNeededSize = 0;
DNASSERT( p_lineGetDevCaps != NULL );
lLineReturn = p_lineGetDevCaps( pTAPIInfo->hApplicationInstance, // TAPI instance handle
dwDeviceID, // TAPI device ID
dwAPIVersion, // negotiated API version
0, // extended data version (none)
pDevCaps // pointer to device caps data
);
//
// TAPI lies about structures being too small!
// Double check the structure size ourselves.
//
if ( pDevCaps->dwNeededSize > dwDevCapsSize )
{
lLineReturn = LINEERR_STRUCTURETOOSMALL;
}
}
//
// If caps have been gotten, process them. Otherwise skip this device.
//
if ( lLineReturn == LINEERR_NONE )
{
//
// is this really a modem?
//
if ( ( pDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM ) != 0 )
{
//
// is this the modem name information accerptable?
//
if ( ( pDevCaps->dwLineNameSize != 0 ) &&
( pDevCaps->dwLineNameOffset != 0 ) )
{
//
// get the name of the device
//
DBG_CASSERT( sizeof( pDevCaps ) == sizeof( char* ) );
DWORD dwSize;
switch (pDevCaps->dwStringFormat)
{
case STRINGFORMAT_ASCII:
{
char* pLineName;
pLineName = &( reinterpret_cast<char*>( pDevCaps )[ pDevCaps->dwLineNameOffset ] );
//
// Note the required storage size and only copy it to the output
// if there's enough room. TAPI drivers are inconsistent. Some
// drivers return NULL terminated strings and others return strings
// with no NULL termination. Be paranoid and reserve space for an
// extra NULL for termination so we can always guarantee termination.
// This may waste a byte or two, but the user will never notice.
//
dwRequiredBufferSize += sizeof( *pModemNameData ) + (pDevCaps->dwLineNameSize * sizeof(TCHAR)) + sizeof( g_NullToken );
if ( dwRequiredBufferSize <= *pdwModemNameDataSize )
{
pModemNameData[ *pdwModemCount ].dwModemID = ModemIDFromTAPIID( dwDeviceID );
pModemNameData[ *pdwModemCount ].dwModemNameSize = pDevCaps->dwLineNameSize * sizeof(TCHAR);
pOutputModemName = &pOutputModemName[ - (static_cast<INT_PTR>( ((pDevCaps->dwLineNameSize * sizeof(TCHAR)) + sizeof( g_NullToken ) ) / sizeof(TCHAR))) ];
#ifndef UNICODE
memcpy( pOutputModemName, pLineName, pDevCaps->dwLineNameSize );
#else
dwSize = pDevCaps->dwLineNameSize * sizeof(TCHAR);
AnsiToWide(pLineName, pDevCaps->dwLineNameSize, pOutputModemName, &dwSize);
#endif // UNICODE
pModemNameData[ *pdwModemCount ].pModemName = pOutputModemName;
//
// Be paranoid about NULL termination. We've accounted for enough
// space to add a terminating NULL to the TAPI device name if one
// wasn't provided.
//
if ( pOutputModemName[ ((pDevCaps->dwLineNameSize * sizeof(TCHAR)) - sizeof( g_NullToken )) / sizeof(TCHAR) ] != g_NullToken )
{
pOutputModemName[ pDevCaps->dwLineNameSize ] = g_NullToken;
pModemNameData[ *pdwModemCount ].dwModemNameSize += sizeof( g_NullToken );
}
}
else
{
//
// Note that the output buffer is too small, but still keep
// processing modem names.
//
hr = DPNERR_BUFFERTOOSMALL;
}
(*pdwModemCount)++;
DPFX(DPFPREP, 2, "Accepting modem device: 0x%x (ASCII)", dwDeviceID );
}
break;
case STRINGFORMAT_UNICODE:
{
WCHAR* pLineName;
pLineName = &( reinterpret_cast<WCHAR*>( pDevCaps )[ pDevCaps->dwLineNameOffset / sizeof(WCHAR)] );
//
// Note the required storage size and only copy it to the output
// if there's enough room. TAPI drivers are inconsistent. Some
// drivers return NULL terminated strings and others return strings
// with no NULL termination. Be paranoid and reserve space for an
// extra NULL for termination so we can always guarantee termination.
// This may waste a byte or two, but the user will never notice.
//
dwRequiredBufferSize += sizeof( *pModemNameData ) + ((pDevCaps->dwLineNameSize * sizeof(TCHAR)) / sizeof(WCHAR)) + sizeof( g_NullToken );
if ( dwRequiredBufferSize <= *pdwModemNameDataSize )
{
pModemNameData[ *pdwModemCount ].dwModemID = ModemIDFromTAPIID( dwDeviceID );
pModemNameData[ *pdwModemCount ].dwModemNameSize = pDevCaps->dwLineNameSize * (sizeof(TCHAR) / sizeof(WCHAR));
pOutputModemName = &pOutputModemName[ - (static_cast<INT_PTR>( (((pDevCaps->dwLineNameSize * sizeof(TCHAR)) / sizeof(WCHAR)) + sizeof( g_NullToken ) ) / sizeof(TCHAR))) ];
#ifdef UNICODE
memcpy( pOutputModemName, pLineName, pDevCaps->dwLineNameSize );
#else
dwSize = pDevCaps->dwLineNameSize / sizeof(TCHAR);
WideToAnsi(pLineName, pDevCaps->dwLineNameSize / sizeof(WCHAR), pOutputModemName, &dwSize);
#endif // UNICODE
pModemNameData[ *pdwModemCount ].pModemName = pOutputModemName;
//
// Be paranoid about NULL termination. We've accounted for enough
// space to add a terminating NULL to the TAPI device name if one
// wasn't provided.
//
if ( pOutputModemName[ (((pDevCaps->dwLineNameSize*sizeof(TCHAR))/sizeof(WCHAR)) - sizeof( g_NullToken )) / sizeof(TCHAR) ] != g_NullToken )
{
pOutputModemName[ pDevCaps->dwLineNameSize / sizeof(WCHAR) ] = g_NullToken;
pModemNameData[ *pdwModemCount ].dwModemNameSize += sizeof( g_NullToken );
}
}
else
{
//
// Note that the output buffer is too small, but still keep
// processing modem names.
//
hr = DPNERR_BUFFERTOOSMALL;
}
(*pdwModemCount)++;
DPFX(DPFPREP, 2, "Accepting modem device: 0x%x (Unicode)", dwDeviceID );
}
break;
default:
{
hr = DPNERR_GENERIC;
DPFX(DPFPREP, 0, "Problem with modem name for device: 0x%x!", dwDeviceID );
DNASSERT( FALSE );
}
}
}
else
{
hr = DPNERR_GENERIC;
DPFX(DPFPREP, 0, "Problem with modem name for device: 0x%x!", dwDeviceID );
DNASSERT( FALSE );
}
}
else
{
DPFX(DPFPREP, 1, "Ignoring non-datamodem device: 0x%x", dwDeviceID );
}
}
else
{
DPFX(DPFPREP, 0, "Failed to get device caps. Ignoring device: 0x%x", dwDeviceID );
}
}
*pdwModemNameDataSize = dwRequiredBufferSize;
Exit:
if ( pDevCaps != NULL )
{
DNFree( pDevCaps );
pDevCaps = NULL;
}
return hr;
Failure:
goto Exit;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// PhoneNumberToWCHAR - convert a phone number to WCHAR
//
// Entry: Pointer to phone number
// Pointer to WCHAR destination
// Pointer to size of WCHAR destintion
//
// Exit: Error code
// ------------------------------
#ifndef UNICODE
HRESULT PhoneNumberToWCHAR( const char *const pPhoneNumber,
WCHAR *const pWCHARPhoneNumber,
DWORD *const pdwWCHARPhoneNumberSize )
{
HRESULT hr;
char *pOutput;
DWORD dwInputIndex;
DWORD dwOutputIndex;
DNASSERT( pPhoneNumber != NULL );
DNASSERT( pWCHARPhoneNumber != NULL );
DNASSERT( pdwWCHARPhoneNumberSize != NULL );
//
// initialize
//
hr = DPN_OK;
pOutput = reinterpret_cast<char*>( pWCHARPhoneNumber );
dwInputIndex = 0;
dwOutputIndex = 0;
memset( pWCHARPhoneNumber, 0, ( (*pdwWCHARPhoneNumberSize) * sizeof( *pWCHARPhoneNumber ) ) );
while ( pPhoneNumber[ dwInputIndex ] != '\0' )
{
if ( dwInputIndex < ( *pdwWCHARPhoneNumberSize ) )
{
pOutput[ dwOutputIndex ] = pPhoneNumber[ dwInputIndex ];
}
dwOutputIndex += sizeof( *pWCHARPhoneNumber );
dwInputIndex += sizeof( *pPhoneNumber );
}
*pdwWCHARPhoneNumberSize = dwInputIndex + 1;
return hr;
}
#endif // !UNICODE
//**********************************************************************
//**********************************************************************
// ------------------------------
// PhoneNumberFromWCHAR - convert a phone number from WCHAR
//
// Entry: Pointer to WCHAR phone number
// Pointer to phone number destination
// Pointer to phone destination size
//
// Exit: Error code
// ------------------------------
#ifndef UNICODE
HRESULT PhoneNumberFromWCHAR( const WCHAR *const pWCHARPhoneNumber,
char *const pPhoneNumber,
DWORD *const pdwPhoneNumberSize )
{
HRESULT hr;
const char *pInput;
DWORD dwInputIndex;
DWORD dwOutputIndex;
DNASSERT( pWCHARPhoneNumber != NULL );
DNASSERT( pPhoneNumber != NULL );
DNASSERT( pdwPhoneNumberSize != NULL );
//
// initialize
//
hr = DPN_OK;
pInput = reinterpret_cast<const char*>( pWCHARPhoneNumber );
dwInputIndex = 0;
dwOutputIndex = 0;
memset( pPhoneNumber, 0x00, *pdwPhoneNumberSize );
while ( pInput[ dwInputIndex ] != '\0' )
{
if ( dwOutputIndex < *pdwPhoneNumberSize )
{
pPhoneNumber[ dwOutputIndex ] = pInput[ dwInputIndex ];
}
dwInputIndex += sizeof( *pWCHARPhoneNumber );
dwOutputIndex += sizeof( *pPhoneNumber );
}
*pdwPhoneNumberSize = dwOutputIndex + 1;
return hr;
}
#endif // !UNICODE
//**********************************************************************
//**********************************************************************
// ------------------------------
// ModemEncryptGuid - encrypt a guid
//
// Entry: Pointer to source guid
// Pointer to destination guid
// Pointer to encryption key
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "ModemEncryptGuid"
void ModemEncryptGuid( const GUID *const pSourceGuid,
GUID *const pDestinationGuid,
const GUID *const pEncryptionKey )
{
const char *pSourceBytes;
char *pDestinationBytes;
const char *pEncryptionBytes;
DWORD_PTR dwIndex;
DNASSERT( pSourceGuid != NULL );
DNASSERT( pDestinationGuid != NULL );
DNASSERT( pEncryptionKey != NULL );
DBG_CASSERT( sizeof( pSourceBytes ) == sizeof( pSourceGuid ) );
pSourceBytes = reinterpret_cast<const char*>( pSourceGuid );
DBG_CASSERT( sizeof( pDestinationBytes ) == sizeof( pDestinationGuid ) );
pDestinationBytes = reinterpret_cast<char*>( pDestinationGuid );
DBG_CASSERT( sizeof( pEncryptionBytes ) == sizeof( pEncryptionKey ) );
pEncryptionBytes = reinterpret_cast<const char*>( pEncryptionKey );
DBG_CASSERT( ( sizeof( *pSourceGuid ) == sizeof( *pEncryptionKey ) ) &&
( sizeof( *pDestinationGuid ) == sizeof( *pEncryptionKey ) ) );
dwIndex = sizeof( *pSourceGuid );
while ( dwIndex != 0 )
{
dwIndex--;
pDestinationBytes[ dwIndex ] = pSourceBytes[ dwIndex ] ^ pEncryptionBytes[ dwIndex ];
}
}
//**********************************************************************