|
|
//
// 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; }
|