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.
 
 
 
 
 
 

1390 lines
35 KiB

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2002 Microsoft Corporation
//
// Module Name:
// LoadStringSrc.cpp
//
// Description:
// LoadStringIntoBSTR implementation.
//
// Maintained By:
// David Potter (DavidP) 01-FEB-2001
// Geoffrey Pease (GPease) 22-MAY-2000
//
//////////////////////////////////////////////////////////////////////////////
// #include <Pch.h> // should be included by includer of this file
#include <StrSafe.h> // in case it isn't included by header file
//////////////////////////////////////////////////////////////////////////////
// Global Variables
//////////////////////////////////////////////////////////////////////////////
const WCHAR g_szWbemClientDLL[] = L"\\WBEM\\WMIUTILS.DLL";
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrLoadStringIntoBSTR
//
// Description:
// Retrieves the string resource idsIn from the string table and makes it
// into a BSTR. If the BSTR is not NULL coming it, it will assume that
// you are trying reuse an existing BSTR.
//
// Arguments:
// hInstanceIn
// Handle to an instance of the module whose executable file
// contains the string resource. If not specified, defaults to
// g_hInstance.
//
// langidIn
// Language ID of string table resource.
//
// idsIn
// Specifies the integer identifier of the string to be loaded.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// Return Values:
// S_OK
// The call succeeded.
//
// E_OUTOFMEMORY
// Out of memory.
//
// E_POINTER
// pbstrInout is NULL.
//
// Other HRESULTs
// The call failed.
//
// Remarks:
// This routine uses LoadResource so that it can get the actual length
// of the string resource. If we didn't do this, we would need to call
// LoadString and allocate memory in a loop. Very inefficient!
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrLoadStringIntoBSTR(
HINSTANCE hInstanceIn
, LANGID langidIn
, UINT idsIn
, BSTR * pbstrInout
)
{
TraceFunc1( "idsIn = %d", idsIn );
HRESULT hr = S_OK;
HRSRC hrsrc = NULL;
HGLOBAL hgbl = NULL;
int cch = 0;
PBYTE pbStringData;
PBYTE pbStringDataMax;
PBYTE pbStringTable;
int cbStringTable;
int nTable;
int nOffset;
int idxString;
Assert( idsIn != 0 );
Assert( pbstrInout != NULL );
if ( pbstrInout == NULL )
{
hr = THR( E_POINTER );
goto Cleanup;
}
if ( hInstanceIn == NULL )
{
hInstanceIn = g_hInstance;
}
// The resource Id specified must be converted to an index into
// a Windows StringTable.
nTable = idsIn / 16;
nOffset = idsIn - (nTable * 16);
// Internal Table Id's start at 1 not 0.
nTable++;
//
// Find the part of the string table where the string resides.
//
// Find the table containing the string.
// First try to load the language specified. If we can't find it we
// try the "neutral" language.
hrsrc = FindResourceEx( hInstanceIn, RT_STRING, MAKEINTRESOURCE( nTable ), langidIn );
if ( ( hrsrc == NULL ) && ( GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND ) )
{
hrsrc = FindResourceEx(
hInstanceIn
, RT_STRING
, MAKEINTRESOURCE( nTable )
, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL )
);
}
if ( hrsrc == NULL )
{
hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
goto Cleanup;
}
// Load the table.
hgbl = LoadResource( hInstanceIn, hrsrc );
if ( hgbl == NULL )
{
hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
goto Cleanup;
}
// Lock the table so we access its data.
pbStringTable = reinterpret_cast< PBYTE >( LockResource( hgbl ) );
if ( pbStringTable == NULL )
{
hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
goto Cleanup;
}
cbStringTable = SizeofResource( hInstanceIn, hrsrc );
Assert( cbStringTable != 0 );
TraceFlow3( "HrLoadStringIntoBSTR() - Table = %#.08x, cb = %d, offset = %d", pbStringTable, cbStringTable, nOffset );
// Set the data pointer to the beginning of the table.
pbStringData = pbStringTable;
pbStringDataMax = pbStringTable + cbStringTable;
//
// Skip strings in the block of 16 which are before the desired string.
//
for ( idxString = 0 ; idxString <= nOffset ; idxString++ )
{
Assert( pbStringData != NULL );
Assert( pbStringData < pbStringDataMax );
// Get the number of characters excluding the '\0'.
cch = * ( (USHORT *) pbStringData );
TraceFlow3( "HrLoadStringIntoBSTR() - pbStringData[ %d ] = %#.08x, cch = %d", idxString, pbStringData, cch );
// Found the string.
if ( idxString == nOffset )
{
if ( cch == 0 )
{
hr = HRESULT_FROM_WIN32( TW32( ERROR_RESOURCE_NAME_NOT_FOUND ) );
goto Cleanup;
}
// Skip over the string length to get the string.
pbStringData += sizeof( WCHAR );
break;
} // if: found the string
// Add one to account for the string length.
// A string length of 0 still takes 1 WCHAR for the length portion.
cch++;
// Skip over this string to get to the next string.
pbStringData += ( cch * sizeof( WCHAR ) );
} // for: each string in the block of 16 strings in the table
// Note: nStringLen is the number of characters in the string not including the '\0'.
AssertMsg( cch > 0, "Length of string in resource file cannot be zero." );
//
// If previously allocated free it before re-allocating it.
//
if ( *pbstrInout != NULL )
{
TraceSysFreeString( *pbstrInout );
*pbstrInout = NULL;
} // if: string was allocated previously
//
// Allocate a BSTR for the string.
//
*pbstrInout = TraceSysAllocStringLen( (OLECHAR *) pbStringData, cch );
if ( *pbstrInout == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
TraceFlow1( "HrLoadStringIntoBSTR() - Loaded string = '%ws'", *pbstrInout );
Cleanup:
HRETURN( hr );
} //*** HrLoadStringIntoBSTR( langidIn )
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrFormatStringIntoBSTR
//
// Description:
// Format a string (specified by idsIn, a string resource ID) and
// variable arguments into a BSTR using the FormatMessage() Win32 API.
// If the BSTR is not NULL on entry, the BSTR will be reused.
//
// Calls HrFormatStringWithVAListIntoBSTR to perform the actual work.
//
// Arguments:
// hInstanceIn
// Handle to an instance of the module whose executable file
// contains the string resource.
//
// langidIn
// Language ID of string table resource.
//
// idsIn
// Specifies the integer identifier of the string to be loaded.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// ...
// Arguments for substitution points in the status text message.
// The FormatMessage() API is used for formatting the string, so
// substitution points must of the form %1!ws! and not %ws.
//
// Return Values:
// S_OK
// The call succeeded.
//
// Other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrFormatStringIntoBSTR(
HINSTANCE hInstanceIn
, LANGID langidIn
, UINT idsIn
, BSTR * pbstrInout
, ...
)
{
TraceFunc1( "ids = %d", idsIn );
HRESULT hr;
va_list valist;
va_start( valist, pbstrInout );
hr = HrFormatStringWithVAListIntoBSTR(
hInstanceIn
, langidIn
, idsIn
, pbstrInout
, valist
);
va_end( valist );
HRETURN( hr );
} //*** HrFormatStringIntoBSTR( langidIn, idsIn )
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrFormatStringWithVAListIntoBSTR
//
// Description:
// Format a string (specified by idsIn, a string resource ID) and
// variable arguments into a BSTR using the FormatMessage() Win32 API.
// If the BSTR is not NULL on entry, the BSTR will be reused.
//
// Arguments:
// hInstanceIn
// Handle to an instance of the module whose executable file
// contains the string resource.
//
// langidIn
// Language ID of string table resource.
//
// idsIn
// Specifies the integer identifier of the string to be loaded.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// valistIn
// Arguments for substitution points in the status text message.
// The FormatMessage() API is used for formatting the string, so
// substitution points must of the form %1!ws! and not %ws.
//
// Return Values:
// S_OK
// The call succeeded.
//
// E_OUTOFMEMORY
// Out of memory.
//
// E_POINTER
// pbstrInout is NULL.
//
// Other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrFormatStringWithVAListIntoBSTR(
HINSTANCE hInstanceIn
, LANGID langidIn
, UINT idsIn
, BSTR * pbstrInout
, va_list valistIn
)
{
TraceFunc1( "ids = %d", idsIn );
HRESULT hr = S_OK;
BSTR bstrStringResource = NULL;
DWORD cch;
LPWSTR psz = NULL;
Assert( pbstrInout != NULL );
if ( pbstrInout == NULL )
{
hr = THR( E_POINTER );
goto Cleanup;
}
//
// Load the string resource.
//
hr = HrLoadStringIntoBSTR( hInstanceIn, langidIn, idsIn, &bstrStringResource );
if ( FAILED( hr ) )
{
goto Cleanup;
}
//
// Format the message with the arguments.
//
cch = FormatMessageW(
( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING )
, bstrStringResource
, 0
, 0
, (LPWSTR) &psz
, 0
, &valistIn
);
AssertMsg( cch != 0, "Missing string??" );
if ( cch == 0 )
{
hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
goto Cleanup;
}
//
// If previously allocated free it before re-allocating it.
//
if ( *pbstrInout != NULL )
{
TraceSysFreeString( *pbstrInout );
*pbstrInout = NULL;
} // if:
//
// Allocate a BSTR for the string.
//
*pbstrInout = TraceSysAllocStringLen( psz, cch );
if ( *pbstrInout == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
Cleanup:
TraceSysFreeString( bstrStringResource );
LocalFree( psz );
HRETURN( hr );
} //*** HrFormatStringWithVAListIntoBSTR( langidIn, idsIn, valistIn )
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrFormatStringIntoBSTR
//
// Description:
// Format a string (specified by pcwszFmtIn) and variable arguments into
// a BSTR using the FormatMessage() Win32 API. If the BSTR is not NULL
// on entry, the BSTR will be reused.
//
// Calls HrFormatStringWithVAListIntoBSTR to perform the actual work.
//
// Arguments:
// pcwszFmtIn
// Specifies the format string.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// ...
// Arguments for substitution points in the status text message.
// The FormatMessage() API is used for formatting the string, so
// substitution points must of the form %1!ws! and not %ws.
//
// Return Values:
// S_OK
// The call succeeded.
//
// Other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrFormatStringIntoBSTR(
LPCWSTR pcwszFmtIn
, BSTR * pbstrInout
, ...
)
{
TraceFunc1( "pcwszFmtIn = %ws", pcwszFmtIn );
HRESULT hr;
va_list valist;
va_start( valist, pbstrInout );
hr = HrFormatStringWithVAListIntoBSTR( pcwszFmtIn, pbstrInout, valist );
va_end( valist );
HRETURN( hr );
} //*** HrFormatStringIntoBSTR( pcwszFmtIn )
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrFormatStringWithVAListIntoBSTR
//
// Description:
// Format a string (specified by pcwszFmtIn) and variable arguments into
// a BSTR using the FormatMessage() Win32 API. If the BSTR is not NULL
// on entry, the BSTR will be reused.
//
// Arguments:
// pcwszFmtIn
// Specifies the format string.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// valistIn
// Arguments for substitution points in the status text message.
// The FormatMessage() API is used for formatting the string, so
// substitution points must of the form %1!ws! and not %ws.
//
// Return Values:
// S_OK
// The call succeeded.
//
// E_OUTOFMEMORY
// Out of memory.
//
// E_POINTER
// pcwszFmtIn or pbstrInout is NULL.
//
// Other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrFormatStringWithVAListIntoBSTR(
LPCWSTR pcwszFmtIn
, BSTR * pbstrInout
, va_list valistIn
)
{
TraceFunc1( "pcwszFmtIn = %ws", pcwszFmtIn );
HRESULT hr = S_OK;
DWORD cch;
LPWSTR psz = NULL;
if ( ( pbstrInout == NULL )
|| ( pcwszFmtIn == NULL ) )
{
hr = THR( E_POINTER );
goto Cleanup;
}
//
// Format the message with the arguments.
//
cch = FormatMessageW(
( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING )
, pcwszFmtIn
, 0
, 0
, (LPWSTR) &psz
, 0
, &valistIn
);
AssertMsg( cch != 0, "Missing string??" );
if ( cch == 0 )
{
hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
goto Cleanup;
}
//
// If previously allocated free it before re-allocating it.
//
if ( *pbstrInout != NULL )
{
TraceSysFreeString( *pbstrInout );
*pbstrInout = NULL;
} // if:
//
// Allocate a BSTR for the string.
//
*pbstrInout = TraceSysAllocStringLen( psz, cch );
if ( *pbstrInout == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
Cleanup:
LocalFree( psz );
HRETURN( hr );
} //*** HrFormatStringWithVAListIntoBSTR( pcwszFmtIn, valistIn )
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// HrFormatMessageIntoBSTR(
// HINSTANCE hInstanceIn,
// UINT uIDIn,
// BSTR * pbstrInout,
// ...
// )
//
// Description:
// Retrieves the format string from the string resource uIDIn using
// FormatMessage.
//
// Arguments:
// hInstanceIn
// Handle to an instance of the module whose executable file
// contains the string resource.
//
// uIDIn
// Specifies the integer identifier of the string to be loaded.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// Return Values:
// S_OK
// The call succeeded.
//
// E_OUTOFMEMORY
// Out of memory.
//
// E_POINTER
// pbstrInout is NULL.
//
// other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrFormatMessageIntoBSTR(
HINSTANCE hInstanceIn,
UINT uIDIn,
BSTR * pbstrInout,
...
)
{
TraceFunc( "" );
va_list valist;
DWORD cch;
LPWSTR psz = NULL;
HRESULT hr = S_OK;
DWORD dw;
WCHAR szBuf[ 255 ];
if ( pbstrInout == NULL )
{
hr = THR( E_POINTER );
goto Cleanup;
}
va_start( valist, pbstrInout );
dw = LoadStringW( hInstanceIn, uIDIn, szBuf, RTL_NUMBER_OF( szBuf ) );
AssertMsg( dw != 0, "Missing string??" );
cch = FormatMessageW(
( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING )
, szBuf
, 0
, 0
, (LPWSTR) &psz
, 0
, &valist
);
va_end( valist );
AssertMsg( cch != 0, "Missing string??" );
if ( cch == 0 )
{
hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
goto Cleanup;
}
//
// If previously allocated free it before re-allocating it.
//
if ( *pbstrInout != NULL )
{
TraceSysFreeString( *pbstrInout );
*pbstrInout = NULL;
} // if:
//
// Allocate a BSTR for the string.
//
*pbstrInout = TraceSysAllocStringLen( psz, cch );
if ( *pbstrInout == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
Cleanup:
LocalFree( psz );
HRETURN( hr );
} //*** HrFormatMessageIntoBSTR
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrFormatErrorIntoBSTR
//
// Description:
// Retrieves the system error message associated with the HRESULT. If
// additional arguments are specified, it will use them in the formatting
// of the error string.
//
// Arguments:
// hrIn
// Error code to lookup the message for.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// ...
// Arguments for substitution points in the status text message.
// The FormatMessage() API is used for formatting the string, so
// substitution points must of the form %1!ws! and not %ws.
//
// Return Values:
// S_OK
// The call succeeded.
//
// E_OUTOFMEMORY
// Out of memory.
//
// E_POINTER
// pbstrInout is NULL.
//
// other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrFormatErrorIntoBSTR(
HRESULT hrIn
, BSTR * pbstrInout
, ...
)
{
TraceFunc1( "hrIn = 0x%08x", hrIn );
HRESULT hr = S_OK;
va_list valist;
va_start( valist, pbstrInout );
hr = HrFormatErrorWithVAListIntoBSTR( hrIn, pbstrInout, valist );
va_end( valist );
HRETURN( hr );
} //*** HrFormatErrorIntoBSTR
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrFormatErrorIntoBSTR
//
// Description:
// Retrieves the system error message associated with the HRESULT. If
// additional arguments are specified, it will use them in the formatting
// of the error string.
//
// Arguments:
// hrIn
// Error code to lookup the message for.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// phrStatusOut
// We may fix up the passed in error code to find better error
// message text. If we do that then we send the fixed up status
// code back to the caller using this argument.
//
// ...
// Arguments for substitution points in the status text message.
// The FormatMessage() API is used for formatting the string, so
// substitution points must of the form %1!ws! and not %ws.
//
// Return Values:
// S_OK
// The call succeeded.
//
// E_OUTOFMEMORY
// Out of memory.
//
// E_POINTER
// pbstrInout is NULL.
//
// other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrFormatErrorIntoBSTR(
HRESULT hrIn
, BSTR * pbstrInout
, HRESULT * phrStatusOut
, ...
)
{
TraceFunc1( "hrIn = 0x%08x", hrIn );
Assert( pbstrInout != NULL );
Assert( phrStatusOut != NULL );
HRESULT hr = S_OK;
HRESULT hrTemp = S_OK;
va_list valist;
*phrStatusOut = hrIn;
va_start( valist, phrStatusOut );
hr = HrFormatErrorWithVAListIntoBSTR( hrIn, pbstrInout, valist );
if ( ( hr == HRESULT_FROM_WIN32( ERROR_MR_MID_NOT_FOUND ) )
&& ( HRESULT_SEVERITY( hrIn ) == SEVERITY_SUCCESS ) )
{
//
// If the passed in status is a successful failure and we were unable
// to look up the error message text then it may be one that we cleared
// off the SEVERITY_ERROR bit to make it a warning instead of an error
// in the UI. If that's the case then set the SEVERITY_ERROR bit and
// try to lookup the error message text again.
//
hrTemp = MAKE_HRESULT( SEVERITY_ERROR, HRESULT_FACILITY( hrIn ), HRESULT_CODE( hrIn ) );
hr = HrFormatErrorWithVAListIntoBSTR( hrTemp, pbstrInout, valist );
if ( SUCCEEDED( hr ) )
{
//
// If the new status succeeded in finding error message text then
// send it back to the caller.
//
*phrStatusOut = hrTemp;
} // if:
} // if:
va_end( valist );
HRETURN( hr );
} //*** HrFormatErrorIntoBSTR
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrFormatErrorWithVAListIntoBSTR
//
// Description:
// Retrieves the system error message associated with the HRESULT. If
// additional arguments are specified, it will use them in the formatting
// of the error string.
//
// Arguments:
// hrIn
// Error code to lookup the message for.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// valistIn
// Arguments for substitution points in the status text message.
// The FormatMessage() API is used for formatting the string, so
// substitution points must of the form %1!ws! and not %ws.
//
// Return Values:
// S_OK
// The call succeeded.
//
// E_OUTOFMEMORY
// Out of memory.
//
// E_POINTER
// pbstrInout is NULL.
//
// other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrFormatErrorWithVAListIntoBSTR(
HRESULT hrIn
, BSTR * pbstrInout
, va_list valistIn
)
{
TraceFunc1( "hrIn = 0x%08x", hrIn );
HRESULT hr = S_OK;
HRESULT hrTemp;
DWORD sc = 0;
size_t cch;
LPWSTR psz = NULL;
LPWSTR pszBuf = NULL;
HMODULE hModule = NULL;
LPWSTR pszSysDir = NULL;
size_t cchSysDir = MAX_PATH + 1;
LPWSTR pszModule = NULL;
size_t cchModule = 0;
Assert( pbstrInout != NULL );
if ( pbstrInout == NULL )
{
hr = THR( E_POINTER );
goto Cleanup;
} // if:
//
// Look at the HRESULT coming in and see if we need to modify it a little
// to ensure that we get the best possible error message text.
//
if ( HRESULT_FACILITY( hrIn ) == FACILITY_WIN32 )
{
//
// If this is a Win32 wrapped in an HRESULT then remove the
// HRESULT stuff so that the Win32 error code will be formatted
// into the message correctly.
//
hrTemp = HRESULT_CODE( hrIn );
} // if: Win32 error code
else
{
hrTemp = hrIn;
} // else:
cch = FormatMessageW(
( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
/*| FORMAT_MESSAGE_IGNORE_INSERTS*/ )
, NULL
, hrTemp
, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL )
, (LPWSTR) &psz
, 0
, &valistIn
);
//
// If the error message was not found then try WMIUtils since we know
// that their error messages are not propertly located for a system lookup.
//
if ( cch == 0 )
{
pszSysDir = new WCHAR[ cchSysDir ];
if ( pszSysDir == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
sc = GetSystemDirectoryW( pszSysDir, static_cast< UINT >( cchSysDir ) );
if ( sc > ( cchSysDir - 1 ) )
{
delete [] pszSysDir;
pszSysDir = NULL;
cchSysDir = sc + 1;
pszSysDir = new WCHAR[ cchSysDir ];
if ( pszSysDir == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
sc = GetSystemDirectoryW( pszSysDir, static_cast< UINT >( cchSysDir ) );
} // if:
if ( sc == 0 )
{
sc = TW32( GetLastError() );
goto Win32Error;
} // if:
cchModule = wcslen( pszSysDir ) + wcslen( g_szWbemClientDLL ) + 1;
pszModule = new WCHAR[ cchModule ];
if ( pszModule == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
THR( StringCchCopyExW( pszModule, cchModule, pszSysDir, &pszBuf, &cch, 0 ) );
THR( StringCchCopyW( pszBuf, cch, g_szWbemClientDLL ) );
hModule = LoadLibraryExW( pszModule, NULL, DONT_RESOLVE_DLL_REFERENCES );
if ( hModule == NULL )
{
sc = TW32( GetLastError() );
goto Win32Error;
} // if:
cch = FormatMessageW(
( FORMAT_MESSAGE_FROM_HMODULE
| FORMAT_MESSAGE_ALLOCATE_BUFFER
/*| FORMAT_MESSAGE_IGNORE_INSERTS*/ )
, hModule
, hrTemp
, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL )
, (LPWSTR) &psz
, 0
, &valistIn
);
if ( cch == 0 )
{
sc = TW32( GetLastError() );
} // if:
} // if:
AssertMsg( cch != 0, "Missing string??" );
if ( cch == 0 )
{
goto Win32Error;
}
//
// If previously allocated free it before re-allocating it.
//
if ( *pbstrInout != NULL )
{
TraceSysFreeString( *pbstrInout );
*pbstrInout = NULL;
} // if:
//
// Allocate a BSTR for the string.
//
*pbstrInout = TraceSysAllocStringLen( psz, static_cast< UINT >( cch ) );
if ( *pbstrInout == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
//
// Remove CR's and LF's since they aren't printable and usually mess up
// the text when displayed.
//
for( cch = 0 ; cch < SysStringLen( *pbstrInout ) ; cch ++ )
{
if ( ( (*pbstrInout)[ cch ] == L'\n' )
|| ( (*pbstrInout)[ cch ] == L'\r' ) )
{
(*pbstrInout)[ cch ] = L' ';
} // if:
} // for:
goto Cleanup;
Win32Error:
hr = HRESULT_FROM_WIN32( sc );
goto Cleanup;
Cleanup:
if ( psz != NULL )
{
LocalFree( psz );
} // if:
delete [] pszModule;
delete [] pszSysDir;
if ( hModule != NULL )
{
FreeLibrary( hModule );
} // if:
HRETURN( hr );
} //*** HrFormatErrorWithVAListIntoBSTR( valistIn )
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrAnsiStringToBSTR
//
// Description:
// Convert and ANSI string into a BSTR.
//
// Arguments:
// pcszAnsiIn
// Pointer to the ANSI string to convert.
//
// pbstrOut
// Pointer to the BSTR to receive the string.HrAnsiStringToBSTR
//
// Return Values:
// S_OK
// The call succeeded.
//
// S_FALSE
// The input string was NULL.
//
// E_OUTOFMEMORY
// Out of memory.
//
// E_POINTER
// pbstrOut is NULL.
//
// other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrAnsiStringToBSTR( LPCSTR pcszAnsiIn, BSTR * pbstrOut )
{
TraceFunc( "" );
HRESULT hr = S_OK;
BSTR bstr = NULL;
DWORD cch;
DWORD sc;
int nRet;
if ( pbstrOut == NULL )
{
hr = THR( E_POINTER );
goto Cleanup;
} // if:
if ( pcszAnsiIn == NULL )
{
*pbstrOut = NULL;
hr = S_FALSE;
goto Cleanup;
} // if:
//
// Determine number of wide characters to be allocated for the
// Unicode string.
//
cch = (DWORD) strlen( pcszAnsiIn ) + 1;
bstr = TraceSysAllocStringLen( NULL, cch );
if ( bstr == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if:
nRet = MultiByteToWideChar( CP_ACP, 0, pcszAnsiIn, cch, bstr, cch );
if ( nRet == 0 )
{
sc = TW32( GetLastError() );
hr = HRESULT_FROM_WIN32( sc );
goto Cleanup;
} // if:
*pbstrOut = bstr;
Cleanup:
HRETURN( hr );
} //*** HrAnsiStringToBSTR
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrConcatenateBSTRs
//
// Description:
// Concatenate one BSTR onto another one.
//
// Arguments:
// pbstrDstInout
// Specifies the destination BSTR.
//
// bstrSrcIn
// Specifies the source BSTR whose contents will be concatenated
// onto pbstrDstInout.
//
// Return Values:
// S_OK
// The call succeeded.
//
// Other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrConcatenateBSTRs(
BSTR * pbstrDstInout
, BSTR bstrSrcIn
)
{
TraceFunc1( "bstrSrcIn = %ws", bstrSrcIn );
HRESULT hr = S_OK;
Assert( pbstrDstInout != NULL );
Assert( bstrSrcIn != NULL );
if ( *pbstrDstInout == NULL )
{
*pbstrDstInout = TraceSysAllocString( bstrSrcIn );
if ( pbstrDstInout == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
}
} // if: no destination string specified
else
{
size_t cchSrc;
size_t cchDst;
size_t cchTotal;
BSTR bstr = NULL;
LPWSTR pszBuf = NULL;
cchSrc = SysStringLen( bstrSrcIn );
cchDst = SysStringLen( *pbstrDstInout );
cchTotal = cchSrc + cchDst + 1;
bstr = TraceSysAllocStringLen( NULL, static_cast< UINT >( cchTotal ) );
if ( bstr == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
}
hr = THR( StringCchCopyExW( bstr, cchTotal, *pbstrDstInout, &pszBuf, &cchTotal, 0 ) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if:
hr = THR( StringCchCopyW( pszBuf, cchTotal, bstrSrcIn ) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if:
TraceSysFreeString( *pbstrDstInout );
*pbstrDstInout = bstr;
} // else: destination string was specified
Cleanup:
HRETURN( hr );
} //*** HrConcatenateBSTRs
//////////////////////////////////////////////////////////////////////////////
//++
//
// HrFormatGuidIntoBSTR
//
// Description:
// Format a GUID into a BSTR. If the BSTR is not NULL on entry,
// the BSTR will be reused.
//
// Arguments:
// pguidIn
// Specifies the GUID to format into a string.
//
// pbstrInout
// Pointer to the BSTR to receive the string. On a failure, the BSTR
// may be the same or NULL.
//
// Return Values:
// S_OK
// The call succeeded.
//
// Other HRESULTs
// The call failed.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
HrFormatGuidIntoBSTR(
GUID * pguidIn
, BSTR * pbstrInout
)
{
TraceFunc( "" );
HRESULT hr = S_OK;
WCHAR wszGuid[ 64 ];
size_t cch = 0;
size_t cchRemaining = 0;
if ( ( pbstrInout == NULL )
|| ( pguidIn == NULL ) )
{
hr = THR( E_POINTER );
goto Cleanup;
}
hr = THR( StringCchPrintfExW(
wszGuid
, RTL_NUMBER_OF( wszGuid )
, NULL
, &cchRemaining
, 0
, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"
, pguidIn->Data1
, pguidIn->Data2
, pguidIn->Data3
, pguidIn->Data4[ 0 ]
, pguidIn->Data4[ 1 ]
, pguidIn->Data4[ 2 ]
, pguidIn->Data4[ 3 ]
, pguidIn->Data4[ 4 ]
, pguidIn->Data4[ 5 ]
, pguidIn->Data4[ 6 ]
, pguidIn->Data4[ 7 ]
) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if:
cch = RTL_NUMBER_OF( wszGuid ) - cchRemaining;
if ( *pbstrInout != NULL )
{
TraceSysFreeString( *pbstrInout );
*pbstrInout = NULL;
} // if:
*pbstrInout = TraceSysAllocStringLen( wszGuid, static_cast< UINT >( cch ) );
if ( *pbstrInout == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
}
Cleanup:
HRETURN( hr );
} //*** HrFormatGuidIntoBSTR