510 lines
14 KiB
C++
510 lines
14 KiB
C++
//
|
|
// Copyright 2001 - Microsoft Corporation
|
|
//
|
|
//
|
|
// Created By:
|
|
// Geoff Pease (GPease) 30-JAN-2001
|
|
//
|
|
// Maintained By:
|
|
// Geoff Pease (GPease) 30-JAN-2001
|
|
//
|
|
#include "pch.h"
|
|
#include "propvar.h"
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// Description:
|
|
// Since there isn't a PropVariantChangeType() API, we have to create our
|
|
// own string conversion routine.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success!
|
|
//
|
|
// E_POINTER
|
|
// pvarIn is NULL.
|
|
//
|
|
// OLE_E_CANTCONVERT
|
|
// Conversion of string to a particular type failed.
|
|
//
|
|
// HRESULT_FROM_WIN32(ERROR_INVALID_DATA)
|
|
// Unknown or invalid type - If the type is valid, then the function
|
|
// needs to be modified to handle this type.
|
|
//
|
|
// E_NOTIMPL
|
|
// Purposely not implemented type.
|
|
//
|
|
// other HRESULTs.
|
|
//
|
|
HRESULT
|
|
PropVariantFromString(
|
|
LPWSTR pszTextIn
|
|
, UINT nCodePageIn
|
|
, ULONG dwFlagsIn
|
|
, VARTYPE vtSaveIn
|
|
, PROPVARIANT * pvarIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
|
LCID lcid = GetUserDefaultLCID();
|
|
|
|
if ( NULL == pvarIn )
|
|
goto InvalidPointer;
|
|
|
|
THR( PropVariantClear( pvarIn ) );
|
|
|
|
// some strings are allowed
|
|
// to have an empty string
|
|
// otherwise we need to fail on empty
|
|
if ( ( NULL != pszTextIn )
|
|
&& ( ( 0 != *pszTextIn ) || ( VT_BSTR == vtSaveIn ) || ( VT_LPWSTR == vtSaveIn ) )
|
|
)
|
|
{
|
|
switch( vtSaveIn )
|
|
{
|
|
case VT_EMPTY:
|
|
case VT_NULL:
|
|
case VT_ILLEGAL:
|
|
break;
|
|
|
|
case VT_UI1:
|
|
hr = THR( VarUI1FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->bVal ) );
|
|
break;
|
|
|
|
case VT_I2:
|
|
hr = THR( VarI2FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->iVal ) );
|
|
break;
|
|
|
|
case VT_UI2:
|
|
hr = THR( VarUI2FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->uiVal ) );
|
|
break;
|
|
|
|
case VT_BOOL:
|
|
hr = THR( VarBoolFromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->boolVal ) );
|
|
break;
|
|
|
|
case VT_I4:
|
|
hr = THR( VarI4FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->lVal ) );
|
|
break;
|
|
|
|
case VT_UI4:
|
|
hr = THR( VarUI4FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->ulVal ) );
|
|
break;
|
|
|
|
case VT_R4:
|
|
hr = THR( VarR4FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->fltVal ) );
|
|
break;
|
|
|
|
case VT_ERROR:
|
|
hr = THR( VarI4FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->scode ) );
|
|
break;
|
|
|
|
//case VT_I8:
|
|
// return _i64tot(hVal.QuadPart, pszBuf, 10);
|
|
|
|
//case VT_UI8:
|
|
// return _ui64tot(hVal.QuadPart, pszBuf, 10);
|
|
|
|
case VT_R8:
|
|
hr = THR( VarR8FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->dblVal ) );
|
|
break;
|
|
|
|
case VT_CY:
|
|
hr = THR( VarCyFromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->cyVal ) );
|
|
break;
|
|
|
|
case VT_DATE:
|
|
hr = THR( VarDateFromStr( pszTextIn, lcid, VAR_DATEVALUEONLY, &pvarIn->date) );
|
|
break;
|
|
|
|
case VT_FILETIME:
|
|
{
|
|
SYSTEMTIME st;
|
|
DATE d;
|
|
|
|
hr = THR( VarDateFromStr( pszTextIn, lcid, VAR_DATEVALUEONLY, &d ) );
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
BOOL bRet;
|
|
|
|
hr = OLE_E_CANTCONVERT;
|
|
|
|
bRet = TBOOL( VariantTimeToSystemTime( d, &st ) );
|
|
if ( bRet )
|
|
{
|
|
bRet = TBOOL( SystemTimeToFileTime( &st, &pvarIn->filetime ) );
|
|
if ( bRet )
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case VT_CLSID:
|
|
{
|
|
CLSID clsid;
|
|
|
|
hr = THR( CLSIDFromString( pszTextIn, &clsid ) );
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
pvarIn->puuid = (CLSID*) CoTaskMemAlloc( sizeof(clsid) );
|
|
if ( NULL == pvarIn->puuid )
|
|
goto OutOfMemory;
|
|
|
|
*pvarIn->puuid = clsid;
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case VT_BSTR:
|
|
pvarIn->bstrVal = SysAllocString( pszTextIn );
|
|
if ( NULL == pvarIn->bstrVal )
|
|
goto OutOfMemory;
|
|
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case VT_LPWSTR:
|
|
hr = SHStrDup( pszTextIn, &pvarIn->pwszVal );
|
|
break;
|
|
|
|
case VT_LPSTR:
|
|
{
|
|
DWORD cchRet;
|
|
DWORD cch = wcslen( pszTextIn ) + 1;
|
|
|
|
pvarIn->pszVal = (LPSTR) CoTaskMemAlloc( cch );
|
|
if ( NULL == pvarIn->pszVal )
|
|
goto OutOfMemory;
|
|
|
|
cchRet = WideCharToMultiByte( nCodePageIn, dwFlagsIn, pszTextIn, cch, pvarIn->pszVal, cch, 0, NULL );
|
|
if (( 0 == cchRet ) && ( 1 < cch ))
|
|
{
|
|
DWORD dwErr = TW32( GetLastError( ) );
|
|
hr = HRESULT_FROM_WIN32( dwErr );
|
|
CoTaskMemFree( pvarIn->pszVal );
|
|
pvarIn->pszVal = NULL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
#ifdef DEBUG
|
|
case VT_VECTOR | VT_UI1:
|
|
//pvarIn->caub;
|
|
case VT_VECTOR | VT_I2:
|
|
//pvarIn->cai;
|
|
case VT_VECTOR | VT_UI2:
|
|
//pvarIn->caui;
|
|
case VT_VECTOR | VT_I4:
|
|
//pvarIn->cal;
|
|
case VT_VECTOR | VT_UI4:
|
|
//pvarIn->caul;
|
|
case VT_VECTOR | VT_I8:
|
|
//pvarIn->cah;
|
|
case VT_VECTOR | VT_UI8:
|
|
//pvarIn->cauh;
|
|
case VT_VECTOR | VT_R4:
|
|
//pvarIn->caflt;
|
|
case VT_VECTOR | VT_R8:
|
|
//pvarIn->cadbl;
|
|
case VT_VECTOR | VT_CY:
|
|
//pvarIn->cacy;
|
|
case VT_VECTOR | VT_DATE:
|
|
//pvarIn->cadate;
|
|
case VT_VECTOR | VT_BSTR:
|
|
//pvarIn->cabstr;
|
|
case VT_VECTOR | VT_BOOL:
|
|
//pvarIn->cabool;
|
|
case VT_VECTOR | VT_ERROR:
|
|
//pvarIn->cascode;
|
|
case VT_VECTOR | VT_LPSTR:
|
|
//pvarIn->calpstr;
|
|
case VT_VECTOR | VT_LPWSTR:
|
|
//pvarIn->calpwstr;
|
|
case VT_VECTOR | VT_FILETIME:
|
|
//pvarIn->cafiletime;
|
|
case VT_VECTOR | VT_CLSID:
|
|
//pvarIn->cauuid;
|
|
case VT_VECTOR | VT_CF:
|
|
//pvarIn->caclipdata;
|
|
case VT_VECTOR | VT_VARIANT:
|
|
//pvarIn->capropvar;
|
|
hr = THR( E_NOTIMPL );
|
|
|
|
// Illegal types for which to assign value from display text.
|
|
case VT_BLOB:
|
|
case VT_CF :
|
|
case VT_STREAM:
|
|
case VT_STORAGE:
|
|
#endif // DEBUG
|
|
|
|
// not handled
|
|
default:
|
|
hr = THR( HRESULT_FROM_WIN32(ERROR_INVALID_DATA) );
|
|
}
|
|
}
|
|
|
|
// set current VARTYPE always
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
pvarIn->vt = vtSaveIn;
|
|
}
|
|
|
|
Cleanup:
|
|
HRETURN( hr );
|
|
|
|
InvalidPointer:
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
|
|
OutOfMemory:
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Description:
|
|
// Since there isn't a PropVariantChangeType() API, we have to create our
|
|
// own string conversion routine.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success!
|
|
//
|
|
// E_POINTER
|
|
// pbstrOut is NULL.
|
|
//
|
|
// E_INVALIDARG
|
|
// ppropvarIn is NULL.
|
|
//
|
|
// HRESULT_FROM_WIN32(ERROR_INVALID_DATA)
|
|
// Unknown or invalid type - If the type is valid, then the function
|
|
// needs to be modified to handle this type.
|
|
//
|
|
// E_NOTIMPL
|
|
// Purposely not implemented type.
|
|
//
|
|
HRESULT
|
|
PropVariantToBSTR(
|
|
PROPVARIANT * pvarIn
|
|
, UINT nCodePageIn
|
|
, ULONG dwFlagsIn
|
|
, BSTR * pbstrOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr;
|
|
LCID lcid = GetUserDefaultLCID( );
|
|
|
|
//
|
|
// Check parameters
|
|
//
|
|
|
|
if ( NULL == pbstrOut )
|
|
goto InvalidPointer;
|
|
|
|
if ( NULL == pvarIn )
|
|
goto InvalidArg;
|
|
|
|
*pbstrOut = NULL;
|
|
|
|
switch ( pvarIn->vt )
|
|
{
|
|
case VT_UI1:
|
|
hr = THR( VarBstrFromUI1( pvarIn->bVal, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_I2:
|
|
hr = THR( VarBstrFromI2( pvarIn->iVal, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_UI2:
|
|
hr = THR( VarBstrFromUI2( pvarIn->uiVal, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_BOOL:
|
|
hr = THR( VarBstrFromBool( pvarIn->boolVal, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_I4:
|
|
hr = THR( VarBstrFromI4( pvarIn->lVal, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_UI4:
|
|
hr = THR( VarBstrFromUI4( pvarIn->ulVal, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_R4:
|
|
hr = THR( VarBstrFromR4( pvarIn->fltVal, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_ERROR:
|
|
hr = THR( VarBstrFromI4( pvarIn->scode, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
//case VT_I8:
|
|
// return _i64tot(hVal.QuadPart, pszBuf, 10); ????
|
|
|
|
//case VT_UI8:
|
|
// return _ui64tot(hVal.QuadPart, pszBuf, 10); ?????
|
|
|
|
case VT_R8:
|
|
hr = THR( VarBstrFromR8( pvarIn->dblVal, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_CY:
|
|
hr = THR( VarBstrFromCy( pvarIn->cyVal, lcid, dwFlagsIn, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_DATE:
|
|
hr = THR( VarBstrFromDate( pvarIn->date, lcid, VAR_DATEVALUEONLY, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_FILETIME:
|
|
{
|
|
BOOL bRet;
|
|
SYSTEMTIME st;
|
|
DATE d;
|
|
|
|
bRet = TBOOL( FileTimeToSystemTime( &pvarIn->filetime, &st ) );
|
|
if ( !bRet )
|
|
goto ErrorCantConvert;
|
|
|
|
bRet = TBOOL( SystemTimeToVariantTime( &st, &d ) );
|
|
if ( !bRet )
|
|
goto ErrorCantConvert;
|
|
|
|
hr = THR( VarBstrFromDate( d, lcid, VAR_DATEVALUEONLY, pbstrOut ) );
|
|
}
|
|
break;
|
|
|
|
case VT_CLSID:
|
|
hr = THR( StringFromCLSID( *pvarIn->puuid, pbstrOut ) );
|
|
break;
|
|
|
|
case VT_BSTR:
|
|
*pbstrOut = SysAllocString( pvarIn->bstrVal );
|
|
if ( NULL == *pbstrOut )
|
|
goto OutOfMemory;
|
|
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case VT_LPWSTR:
|
|
*pbstrOut = SysAllocString( pvarIn->pwszVal );
|
|
if ( NULL == *pbstrOut )
|
|
goto OutOfMemory;
|
|
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case VT_LPSTR:
|
|
{
|
|
DWORD cchRet;
|
|
DWORD cch = lstrlenA( pvarIn->pszVal );
|
|
|
|
*pbstrOut = SysAllocStringLen( NULL, cch );
|
|
if ( NULL == *pbstrOut )
|
|
goto OutOfMemory;
|
|
|
|
cchRet = MultiByteToWideChar( nCodePageIn, dwFlagsIn, pvarIn->pszVal, cch + 1, *pbstrOut, cch + 1 );
|
|
if (( 0 == cchRet ) && ( 0 != cch ))
|
|
{
|
|
DWORD dwErr = TW32( GetLastError( ) );
|
|
hr = HRESULT_FROM_WIN32( dwErr );
|
|
SysFreeString( *pbstrOut );
|
|
*pbstrOut = NULL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
|
|
#ifdef DEBUG
|
|
case VT_VECTOR | VT_UI1:
|
|
//pvarIn->caub;
|
|
case VT_VECTOR | VT_I2:
|
|
//pvarIn->cai;
|
|
case VT_VECTOR | VT_UI2:
|
|
//pvarIn->caui;
|
|
case VT_VECTOR | VT_I4:
|
|
//pvarIn->cal;
|
|
case VT_VECTOR | VT_UI4:
|
|
//pvarIn->caul;
|
|
case VT_VECTOR | VT_I8:
|
|
//pvarIn->cah;
|
|
case VT_VECTOR | VT_UI8:
|
|
//pvarIn->cauh;
|
|
case VT_VECTOR | VT_R4:
|
|
//pvarIn->caflt;
|
|
case VT_VECTOR | VT_R8:
|
|
//pvarIn->cadbl;
|
|
case VT_VECTOR | VT_CY:
|
|
//pvarIn->cacy;
|
|
case VT_VECTOR | VT_DATE:
|
|
//pvarIn->cadate;
|
|
case VT_VECTOR | VT_BSTR:
|
|
//pvarIn->cabstr;
|
|
case VT_VECTOR | VT_BOOL:
|
|
//pvarIn->cabool;
|
|
case VT_VECTOR | VT_ERROR:
|
|
//pvarIn->cascode;
|
|
case VT_VECTOR | VT_LPSTR:
|
|
//pvarIn->calpstr;
|
|
case VT_VECTOR | VT_LPWSTR:
|
|
//pvarIn->calpwstr;
|
|
case VT_VECTOR | VT_FILETIME:
|
|
//pvarIn->cafiletime;
|
|
case VT_VECTOR | VT_CLSID:
|
|
//pvarIn->cauuid;
|
|
case VT_VECTOR | VT_CF:
|
|
//pvarIn->caclipdata;
|
|
case VT_VECTOR | VT_VARIANT:
|
|
//pvarIn->capropvar;
|
|
hr = THR( E_NOTIMPL );
|
|
|
|
// Illegal types for which to assign value from display text.
|
|
case VT_BLOB:
|
|
case VT_CF :
|
|
case VT_STREAM:
|
|
case VT_STORAGE:
|
|
#endif // DEBUG
|
|
|
|
case VT_EMPTY:
|
|
case VT_NULL:
|
|
case VT_ILLEGAL:
|
|
default:
|
|
hr = THR( HRESULT_FROM_WIN32(ERROR_INVALID_DATA) );
|
|
}
|
|
|
|
Cleanup:
|
|
HRETURN( hr );
|
|
|
|
InvalidPointer:
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
|
|
InvalidArg:
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
|
|
ErrorCantConvert:
|
|
hr = OLE_E_CANTCONVERT;
|
|
goto Cleanup;
|
|
|
|
OutOfMemory:
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|