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.
804 lines
16 KiB
804 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
oleutil.cpp
|
|
|
|
Abstract:
|
|
|
|
Provides Useful functions for dealing with OLE.
|
|
|
|
Author:
|
|
|
|
Magnus Hedlund (MagnusH) --
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "stdafx.h"
|
|
#include "iadm.h"
|
|
#include "oleutil.h"
|
|
#include "cmultisz.h"
|
|
#include "resource.h"
|
|
|
|
//$-------------------------------------------------------------------
|
|
//
|
|
// UpdateChangedMask
|
|
//
|
|
// Description:
|
|
//
|
|
// Marks a field as changed in the given bit vector
|
|
//
|
|
// Parameters:
|
|
//
|
|
// pbvChangedProps - points to the bit vector
|
|
// dwBitMask - Bit to turn on. (must have only one bit on)
|
|
//
|
|
//--------------------------------------------------------------------
|
|
|
|
static void UpdateChangedMask ( DWORD * pbvChangedProps, DWORD dwBitMask )
|
|
{
|
|
if ( pbvChangedProps == NULL ) {
|
|
// Legal, means that the caller doesn't want change tracking.
|
|
|
|
return;
|
|
}
|
|
|
|
_ASSERT ( dwBitMask != 0 );
|
|
|
|
*pbvChangedProps |= dwBitMask;
|
|
}
|
|
|
|
HRESULT LongArrayToVariantArray ( SAFEARRAY * psaLongs, SAFEARRAY ** ppsaVariants )
|
|
{
|
|
_ASSERT ( psaLongs );
|
|
|
|
HRESULT hr = NOERROR;
|
|
long lLBound = 0;
|
|
long lUBound = 0;
|
|
long i;
|
|
SAFEARRAYBOUND bounds;
|
|
SAFEARRAY * psaVariants;
|
|
|
|
*ppsaVariants = NULL;
|
|
|
|
_ASSERT ( SafeArrayGetDim ( psaLongs ) == 1 );
|
|
|
|
SafeArrayGetLBound ( psaLongs, 1, &lLBound );
|
|
SafeArrayGetUBound ( psaLongs, 1, &lUBound );
|
|
|
|
bounds.lLbound = lLBound;
|
|
bounds.cElements = lUBound - lLBound + 1;
|
|
|
|
psaVariants = SafeArrayCreate ( VT_VARIANT, 1, &bounds );
|
|
|
|
for ( i = lLBound; i <= lUBound; i++ ) {
|
|
VARIANT var;
|
|
long lTemp;
|
|
|
|
VariantInit ( &var );
|
|
|
|
hr = SafeArrayGetElement ( psaLongs, &i, &lTemp );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
V_VT (&var) = VT_I4;
|
|
V_I4 (&var) = lTemp;
|
|
|
|
hr = SafeArrayPutElement ( psaVariants, &i, &var );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
VariantClear ( &var );
|
|
}
|
|
|
|
*ppsaVariants = psaVariants;
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT StringArrayToVariantArray ( SAFEARRAY * psaStrings, SAFEARRAY ** ppsaVariants )
|
|
{
|
|
_ASSERT ( psaStrings );
|
|
|
|
HRESULT hr = NOERROR;
|
|
long lLBound = 0;
|
|
long lUBound = 0;
|
|
long i;
|
|
SAFEARRAYBOUND bounds;
|
|
SAFEARRAY * psaVariants;
|
|
|
|
*ppsaVariants = NULL;
|
|
|
|
_ASSERT ( SafeArrayGetDim ( psaStrings ) == 1 );
|
|
|
|
SafeArrayGetLBound ( psaStrings, 1, &lLBound );
|
|
SafeArrayGetUBound ( psaStrings, 1, &lUBound );
|
|
|
|
bounds.lLbound = lLBound;
|
|
bounds.cElements = lUBound - lLBound + 1;
|
|
|
|
psaVariants = SafeArrayCreate ( VT_VARIANT, 1, &bounds );
|
|
|
|
for ( i = lLBound; i <= lUBound; i++ ) {
|
|
VARIANT var;
|
|
CComBSTR strTemp;
|
|
|
|
VariantInit ( &var );
|
|
|
|
hr = SafeArrayGetElement ( psaStrings, &i, &strTemp );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
V_VT (&var) = VT_BSTR;
|
|
V_BSTR (&var) = ::SysAllocString ( strTemp );
|
|
|
|
hr = SafeArrayPutElement ( psaVariants, &i, &var );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
VariantClear ( &var );
|
|
}
|
|
|
|
*ppsaVariants = psaVariants;
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT VariantArrayToStringArray ( SAFEARRAY * psaVariants, SAFEARRAY ** ppsaStrings )
|
|
{
|
|
_ASSERT ( psaVariants );
|
|
|
|
HRESULT hr = NOERROR;
|
|
long lLBound = 0;
|
|
long lUBound = 0;
|
|
long i;
|
|
SAFEARRAYBOUND bounds;
|
|
SAFEARRAY * psaStrings;
|
|
|
|
_ASSERT ( SafeArrayGetDim ( psaVariants ) == 1 );
|
|
|
|
*ppsaStrings = NULL;
|
|
|
|
SafeArrayGetLBound ( psaVariants, 1, &lLBound );
|
|
SafeArrayGetUBound ( psaVariants, 1, &lUBound );
|
|
|
|
bounds.lLbound = lLBound;
|
|
bounds.cElements = lUBound - lLBound + 1;
|
|
|
|
psaStrings = SafeArrayCreate ( VT_BSTR, 1, &bounds );
|
|
|
|
for ( i = lLBound; i <= lUBound; i++ ) {
|
|
VARIANT var;
|
|
CComBSTR strTemp;
|
|
|
|
VariantInit ( &var );
|
|
|
|
hr = SafeArrayGetElement ( psaVariants, &i, &var );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
strTemp = V_BSTR (&var);
|
|
|
|
hr = SafeArrayPutElement ( psaStrings, &i, strTemp );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
VariantClear (&var);
|
|
}
|
|
|
|
*ppsaStrings = psaStrings;
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
//$-------------------------------------------------------------------
|
|
//
|
|
// StdPropertyGet < BSTR, long, DWORD, DATE >
|
|
//
|
|
// Description:
|
|
//
|
|
// Performs a default Property Get on a BSTR, long, DWORD or
|
|
// Ole DATE.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Property - The property to get.
|
|
// pOut - The resulting copy.
|
|
//
|
|
// Returns:
|
|
//
|
|
// E_POINTER - invalid arguments
|
|
// E_OUTOFMEMORY - Not enough memory to copy
|
|
// NOERROR - success.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
|
|
HRESULT StdPropertyGet ( const BSTR strProperty, BSTR * pstrOut )
|
|
{
|
|
TraceQuietEnter ( "StdPropertyGet <BSTR>" );
|
|
|
|
_ASSERT ( pstrOut != NULL );
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( pstrOut ) );
|
|
|
|
if ( pstrOut == NULL ) {
|
|
FatalTrace ( 0, "Bad return pointer" );
|
|
return E_POINTER;
|
|
}
|
|
|
|
*pstrOut = NULL;
|
|
|
|
if ( strProperty == NULL ) {
|
|
|
|
// If the property is NULL, use a blank string:
|
|
*pstrOut = ::SysAllocString ( _T("") );
|
|
}
|
|
else {
|
|
_ASSERT ( IS_VALID_STRING ( strProperty ) );
|
|
|
|
// Copy the property into the result:
|
|
*pstrOut = ::SysAllocString ( strProperty );
|
|
}
|
|
|
|
if ( *pstrOut == NULL ) {
|
|
|
|
// Allocation failed.
|
|
FatalTrace ( 0, "Out of memory" );
|
|
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT StdPropertyGet ( long lProperty, long * plOut )
|
|
{
|
|
TraceQuietEnter ( "StdPropertyGet <long>" );
|
|
|
|
_ASSERT ( plOut != NULL );
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( plOut ) );
|
|
|
|
if ( plOut == NULL ) {
|
|
FatalTrace ( 0, "Bad return pointer" );
|
|
|
|
return E_POINTER;
|
|
}
|
|
|
|
*plOut = lProperty;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT StdPropertyGet ( DATE dateProperty, DATE * pdateOut )
|
|
{
|
|
TraceQuietEnter ( "StdPropertyGet <DATE>" );
|
|
|
|
_ASSERT ( pdateOut != NULL );
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( pdateOut ) );
|
|
|
|
if ( pdateOut == NULL ) {
|
|
FatalTrace ( 0, "Bad return pointer" );
|
|
|
|
return E_POINTER;
|
|
}
|
|
|
|
*pdateOut = dateProperty;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT StdPropertyGet ( const CMultiSz * pmszProperty, SAFEARRAY ** ppsaStrings )
|
|
{
|
|
TraceFunctEnter ( "StdPropertyGet <MULTI_SZ>" );
|
|
|
|
_ASSERT ( pmszProperty );
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( ppsaStrings ) );
|
|
|
|
HRESULT hr = NOERROR;
|
|
|
|
*ppsaStrings = pmszProperty->ToSafeArray ( );
|
|
|
|
if ( *ppsaStrings == NULL ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
HRESULT StdPropertyGetBit ( DWORD bvBitVector, DWORD dwBit, BOOL * pfOut )
|
|
{
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( pfOut ) );
|
|
|
|
if ( !pfOut ) {
|
|
return E_POINTER;
|
|
}
|
|
|
|
*pfOut = GetBitFlag ( bvBitVector, dwBit );
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//$-------------------------------------------------------------------
|
|
//
|
|
// StdPropertyPut <BSTR, long, DWORD or DATE>
|
|
//
|
|
// Description:
|
|
//
|
|
// Performs a default Property Put on a BSTR, long, DWORD or
|
|
// Ole date.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// pProperty - The property to put.
|
|
// New - The new value.
|
|
// pbvChangedProps [optional] - Bit Vector which holds which
|
|
// properties have changed.
|
|
// dwBitMask [optional] - This property's bitmask for the
|
|
// changed bit vector.
|
|
//
|
|
// Returns:
|
|
//
|
|
// E_POINTER - invalid arguments
|
|
// E_OUTOFMEMORY - Not enough memory to copy
|
|
// NOERROR - success.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
|
|
HRESULT StdPropertyPut (
|
|
BSTR * pstrProperty,
|
|
const BSTR strNew,
|
|
DWORD * pbvChangedProps, // = NULL
|
|
DWORD dwBitMask // = 0
|
|
)
|
|
{
|
|
TraceQuietEnter ( "StdPropertyPut <BSTR>" );
|
|
|
|
// Validate Parameters:
|
|
_ASSERT ( pstrProperty != NULL );
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( pstrProperty ) );
|
|
|
|
_ASSERT ( strNew != NULL );
|
|
_ASSERT ( IS_VALID_STRING ( strNew ) );
|
|
|
|
if ( pstrProperty == NULL ) {
|
|
FatalTrace ( 0, "Bad property pointer" );
|
|
return E_POINTER;
|
|
}
|
|
|
|
if ( strNew == NULL ) {
|
|
FatalTrace ( 0, "Bad pointer" );
|
|
return E_POINTER;
|
|
}
|
|
|
|
HRESULT hr = NOERROR;
|
|
BSTR strCopy = NULL;
|
|
|
|
// Copy the new string:
|
|
strCopy = ::SysAllocString ( strNew );
|
|
|
|
if ( strCopy == NULL ) {
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
FatalTrace ( 0, "Out of memory" );
|
|
goto Error;
|
|
}
|
|
|
|
// Update the changed bit, if necessary:
|
|
if ( *pstrProperty && lstrcmp ( *pstrProperty, strCopy ) != 0 ) {
|
|
UpdateChangedMask ( pbvChangedProps, dwBitMask );
|
|
}
|
|
|
|
// Replace the old property with the new one.
|
|
SAFE_FREE_BSTR ( *pstrProperty );
|
|
|
|
*pstrProperty = strCopy;
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT StdPropertyPut (
|
|
long * plProperty,
|
|
long lNew,
|
|
DWORD * pbvChangedProps, // = NULL
|
|
DWORD dwBitMask // = 0
|
|
)
|
|
{
|
|
TraceQuietEnter ( "StdPropertyPut <long>" );
|
|
|
|
_ASSERT ( plProperty != NULL );
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( plProperty ) );
|
|
|
|
if ( plProperty == NULL ) {
|
|
FatalTrace ( 0, "Bad pointer" );
|
|
return E_POINTER;
|
|
}
|
|
|
|
if ( *plProperty != lNew ) {
|
|
UpdateChangedMask ( pbvChangedProps, dwBitMask );
|
|
}
|
|
|
|
*plProperty = lNew;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT StdPropertyPut (
|
|
DATE * pdateProperty,
|
|
DATE dateNew,
|
|
DWORD * pbvChangedProps, // = NULL
|
|
DWORD dwBitMask // = 0
|
|
)
|
|
{
|
|
TraceQuietEnter ( "StdPropertyPut <DATE>" );
|
|
|
|
_ASSERT ( pdateProperty != NULL );
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( pdateProperty ) );
|
|
|
|
if ( pdateProperty == NULL ) {
|
|
FatalTrace ( 0, "Bad pointer" );
|
|
return E_POINTER;
|
|
}
|
|
|
|
if ( *pdateProperty != dateNew ) {
|
|
UpdateChangedMask ( pbvChangedProps, dwBitMask );
|
|
}
|
|
|
|
*pdateProperty = dateNew;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT StdPropertyPut ( CMultiSz * pmszProperty, SAFEARRAY * psaStrings, DWORD * pbvChangedProps, DWORD dwBitMask )
|
|
{
|
|
TraceFunctEnter ( "StdPropertyPut <MULTI_SZ>" );
|
|
|
|
_ASSERT ( IS_VALID_IN_PARAM ( psaStrings ) );
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( pmszProperty ) );
|
|
|
|
if ( psaStrings == NULL ) {
|
|
FatalTrace ( 0, "Bad return pointer" );
|
|
|
|
TraceFunctLeave ();
|
|
return E_POINTER;
|
|
}
|
|
|
|
HRESULT hr = NOERROR;
|
|
|
|
pmszProperty->FromSafeArray ( psaStrings );
|
|
|
|
if ( !*pmszProperty ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
// Don't want to deal with comparing these properties:
|
|
UpdateChangedMask ( pbvChangedProps, dwBitMask );
|
|
|
|
Exit:
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
HRESULT StdPropertyPutBit ( DWORD * pbvBitVector, DWORD dwBit, BOOL fIn )
|
|
{
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( pbvBitVector ) );
|
|
_ASSERT ( dwBit );
|
|
|
|
SetBitFlag ( pbvBitVector, dwBit, fIn );
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//$-------------------------------------------------------------------
|
|
//
|
|
// PV_MaxChars
|
|
//
|
|
// Description:
|
|
//
|
|
// Validates a string to make sure it's not too long.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// strProperty - the string to check
|
|
// nMaxChars - the maximum number of characters in the string,
|
|
// not including the NULL terminator.
|
|
//
|
|
// Returns:
|
|
//
|
|
// FALSE if the string is too long.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
|
|
BOOL PV_MaxChars ( const BSTR strProperty, DWORD nMaxChars )
|
|
{
|
|
TraceQuietEnter ( "PV_MaxChars" );
|
|
|
|
_ASSERT ( strProperty != NULL );
|
|
_ASSERT ( IS_VALID_STRING ( strProperty ) );
|
|
|
|
_ASSERT ( nMaxChars > 0 );
|
|
|
|
if ( strProperty == NULL ) {
|
|
// This error should be caught somewhere else.
|
|
return TRUE;
|
|
}
|
|
|
|
if ( (DWORD) lstrlen ( strProperty ) > nMaxChars ) {
|
|
ErrorTrace ( 0, "String too long" );
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//$-------------------------------------------------------------------
|
|
//
|
|
// PV_MinMax <int, dword>
|
|
//
|
|
// Description:
|
|
//
|
|
// Makes sure a property is within a given range.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// nProperty - the value to test
|
|
// nMin - The minimum value the property could have
|
|
// nMax - The maximum value the property could have
|
|
//
|
|
// Returns:
|
|
//
|
|
// TRUE if the property is in the range (inclusive).
|
|
//
|
|
//--------------------------------------------------------------------
|
|
|
|
BOOL PV_MinMax ( int nProperty, int nMin, int nMax )
|
|
{
|
|
TraceQuietEnter ( "PV_MinMax" );
|
|
|
|
_ASSERT ( nMin <= nMax );
|
|
|
|
if ( nProperty < nMin || nProperty > nMax ) {
|
|
ErrorTrace ( 0, "Integer out of range" );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL PV_MinMax ( DWORD dwProperty, DWORD dwMin, DWORD dwMax )
|
|
{
|
|
TraceQuietEnter ( "PV_MinMax" );
|
|
|
|
_ASSERT ( dwMin <= dwMax );
|
|
|
|
if ( dwProperty < dwMin || dwProperty > dwMax ) {
|
|
|
|
ErrorTrace ( 0, "Dword out of range" );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL PV_Boolean ( BOOL fProperty )
|
|
{
|
|
TraceQuietEnter ( "PV_Boolean" );
|
|
|
|
if ( fProperty != TRUE && fProperty != FALSE ) {
|
|
|
|
ErrorTrace ( 0, "Boolean property is not true or false" );
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//$-------------------------------------------------------------------
|
|
//
|
|
// StdPropertyGetIDispatch
|
|
//
|
|
// Description:
|
|
//
|
|
// Gets a IDispatch pointer for the given cLSID
|
|
//
|
|
// Parameters:
|
|
//
|
|
// clsid - OLE CLSID of the object
|
|
// ppIDipsatch - the IDispatch pointer to that object.
|
|
//
|
|
// Returns:
|
|
//
|
|
// E_POINTER - invalid argument
|
|
// NOERROR - Success
|
|
// Others - defined by CoCreateInstance.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
|
|
HRESULT StdPropertyGetIDispatch (
|
|
REFCLSID clsid,
|
|
IDispatch ** ppIDispatch
|
|
)
|
|
{
|
|
TraceFunctEnter ( "StdPropertyGetIDispatch" );
|
|
|
|
CComPtr<IDispatch> pNewIDispatch;
|
|
HRESULT hr = NOERROR;
|
|
|
|
_ASSERT ( ppIDispatch );
|
|
|
|
if ( ppIDispatch == NULL ) {
|
|
FatalTrace ( 0, "Bad return pointer" );
|
|
TraceFunctLeave ();
|
|
return E_POINTER;
|
|
}
|
|
|
|
*ppIDispatch = NULL;
|
|
|
|
hr = ::CoCreateInstance (
|
|
clsid,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IDispatch,
|
|
(void **) &pNewIDispatch
|
|
);
|
|
|
|
if ( FAILED (hr) ) {
|
|
DebugTraceX ( 0, "CoCreate(IDispatch) failed %x", hr );
|
|
FatalTrace ( 0, "Failed to create IDispatch" );
|
|
goto Exit;
|
|
}
|
|
|
|
*ppIDispatch = pNewIDispatch;
|
|
pNewIDispatch.p->AddRef ();
|
|
|
|
Exit:
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
|
|
// Destructor releases pNewIDispatch
|
|
}
|
|
|
|
//$-------------------------------------------------------------------
|
|
//
|
|
// InetAddressToString
|
|
//
|
|
// Description:
|
|
//
|
|
// Converts a DWORD with an ip address to a string in the form
|
|
// "xxx.xxx.xxx.xxx"
|
|
//
|
|
// Parameters:
|
|
//
|
|
// dwAddress - The address to convert
|
|
// wszAddress - The resulting string
|
|
// cAddress - The maximum size of the resulting string
|
|
//
|
|
// Returns:
|
|
//
|
|
// TRUE if succeeded, FALSE otherwise.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
|
|
BOOL InetAddressToString ( DWORD dwAddress, LPWSTR wszAddress, DWORD cAddress )
|
|
{
|
|
TraceFunctEnter ( "InetAddressToString" );
|
|
|
|
_ASSERT ( wszAddress );
|
|
|
|
if ( wszAddress == NULL ) {
|
|
FatalTrace ( 0, "Bad pointer" );
|
|
TraceFunctLeave ();
|
|
return FALSE;
|
|
}
|
|
|
|
struct in_addr addr;
|
|
LPSTR szAnsiAddress;
|
|
DWORD cchCopied;
|
|
|
|
addr.s_addr = dwAddress;
|
|
|
|
szAnsiAddress = inet_ntoa ( addr );
|
|
|
|
if ( szAnsiAddress == NULL ) {
|
|
ErrorTraceX ( 0, "inet_ntoa failed: %x", GetLastError() );
|
|
TraceFunctLeave ();
|
|
return FALSE;
|
|
}
|
|
|
|
cchCopied = MultiByteToWideChar (
|
|
CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
szAnsiAddress,
|
|
-1,
|
|
wszAddress,
|
|
cAddress
|
|
);
|
|
|
|
if ( cchCopied == 0 ) {
|
|
ErrorTraceX ( 0, "MultiByteToWideChar failed: %x", GetLastError() );
|
|
TraceFunctLeave ();
|
|
return FALSE;
|
|
}
|
|
|
|
TraceFunctLeave ();
|
|
return TRUE;
|
|
}
|
|
|
|
//$-------------------------------------------------------------------
|
|
//
|
|
// StringToInetAddress
|
|
//
|
|
// Description:
|
|
//
|
|
// Converts a string in the form "xxx.xxx.xxx.xxx" to a DWORD
|
|
// IP Address.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// wszAddress - The string to convert
|
|
// pdwAddress - The resulting address
|
|
//
|
|
// Returns:
|
|
//
|
|
// TRUE if succeeded, FALSE otherwise.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
|
|
BOOL StringToInetAddress ( LPCWSTR wszAddress, DWORD * pdwAddress )
|
|
{
|
|
TraceFunctEnter ( "StringToInetAddress" );
|
|
|
|
_ASSERT ( wszAddress );
|
|
_ASSERT ( pdwAddress );
|
|
|
|
if ( wszAddress == NULL ) {
|
|
FatalTrace ( 0, "Bad pointer" );
|
|
TraceFunctLeave ();
|
|
return FALSE;
|
|
}
|
|
|
|
if ( pdwAddress == NULL ) {
|
|
FatalTrace ( 0, "Bad return pointer" );
|
|
TraceFunctLeave ();
|
|
return FALSE;
|
|
}
|
|
|
|
char szAnsiAddress[100];
|
|
DWORD cchCopied;
|
|
|
|
*pdwAddress = 0;
|
|
|
|
cchCopied = WideCharToMultiByte (
|
|
CP_ACP,
|
|
0,
|
|
wszAddress,
|
|
-1,
|
|
szAnsiAddress,
|
|
sizeof ( szAnsiAddress ),
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if ( cchCopied == 0 ) {
|
|
ErrorTraceX ( 0, "MultiByteToWideChar failed: %x", GetLastError() );
|
|
TraceFunctLeave ();
|
|
return FALSE;
|
|
}
|
|
|
|
*pdwAddress = inet_addr ( szAnsiAddress );
|
|
|
|
if ( !*pdwAddress ) {
|
|
ErrorTraceX ( 0, "inet_addr failed: %x", GetLastError () );
|
|
}
|
|
|
|
TraceFunctLeave ();
|
|
return TRUE;
|
|
}
|
|
|