|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996.
//
// File: utils.cxx
//
// Contents: Utility classes/functions for property implementation.
//
// Classes: CPropSetName -- wraps buffer and conversion of fmtids
// CStackBuffer -- utility class that allows a small number
// of items be on stack, but more be on heap.
//
// Functions: PropVariantClear
// FreePropVariantArray
// AllocAndCopy
// PropVariantCopy
// PropSysAllocString
// PropSysFreeString
//
//
//--------------------------------------------------------------------------
#include "pch.cxx"
//+-------------------------------------------------------------------
//
// Member: CPropSetName::CPropSetName
//
// Synopsis: Initialize internal buffer with converted FMTID
//
// Arguments: [rfmtid] -- FMTID to convert
//
//--------------------------------------------------------------------
CPropSetName::CPropSetName(REFFMTID rfmtid) { RtlGuidToPropertySetName(&rfmtid, _oszName); }
//+-------------------------------------------------------------------
//
// Member: CStackBuffer::Init
//
// Synopsis: Determine whether the class derived from this one
// needs to have additional buffer allocated on the
// heap and allocate it if neccessary. Otherwise, if
// there is space, use the internal buffer in the
// derived class.
//
// Arguments: [cElements] -- the number of elements required.
//
// Returns: S_OK if buffer available
// STG_E_INSUFFICIENTMEMORY if stack buffer was not
// big enough AND heap allocation failed.
//
// Notes: To be called directly by client after the derived
// classes constructor initialized CStackBuffer.
//
//--------------------------------------------------------------------
HRESULT CStackBuffer::Init(ULONG cElements) { if (cElements > _cStackElements) { _pbHeapBuf = new BYTE[cElements * _cbElementSize]; if (_pbHeapBuf == NULL) { return(STG_E_INSUFFICIENTMEMORY); } } return(S_OK); }
//+-------------------------------------------------------------------------
//
// Function: PropVariantClear
//
// Synopsis: Deallocates the members of the PROPVARIANT that require
// deallocation.
//
// Arguments: [pvarg] - variant to clear
//
// Returns: S_OK if successful,
// STG_E_INVALIDPARAMETER if any part of the variant has
// an unknown vt type. (In this case, ALL the elements
// that can be freed, will be freed.)
//
// Modifies: [pvarg] - the variant is left with vt = VT_EMPTY
//
//--------------------------------------------------------------------------
STDAPI PropVariantClear(PROPVARIANT *pvarg) {
ULONG l; HRESULT hr = S_OK;
if (pvarg == NULL) return(hr);
switch (pvarg->vt) { case VT_EMPTY: case VT_NULL: case VT_ILLEGAL:
#ifdef PROPVAR_VT_I1
case VT_I1: #endif
case VT_UI1: case VT_I2: case VT_UI2: case VT_I4: case VT_UI4: case VT_I8: case VT_UI8: case VT_R4: case VT_R8: case VT_CY: case VT_DATE: break;
case VT_BSTR: if (pvarg->bstrVal != NULL) PropSysFreeString( pvarg->bstrVal ); break;
case VT_BOOL: case VT_ERROR: case VT_FILETIME: break;
case VT_LPSTR: case VT_LPWSTR: case VT_CLSID: PROPASSERT((void**)&pvarg->pszVal == (void**)&pvarg->pwszVal); PROPASSERT((void**)&pvarg->pszVal == (void**)&pvarg->puuid); CoTaskMemFree(pvarg->pszVal); // ptr at 0
break; case VT_CF: if (pvarg->pclipdata != NULL) { CoTaskMemFree(pvarg->pclipdata->pClipData); // ptr at 8
CoTaskMemFree(pvarg->pclipdata); } break;
case VT_BLOB: case VT_BLOB_OBJECT: CoTaskMemFree(pvarg->blob.pBlobData); //ptr at 4
break;
#ifdef PROPVAR_VT_I1
case (VT_VECTOR | VT_I1): #endif
case (VT_VECTOR | VT_UI1): case (VT_VECTOR | VT_I2): case (VT_VECTOR | VT_UI2): case (VT_VECTOR | VT_I4): case (VT_VECTOR | VT_UI4): case (VT_VECTOR | VT_I8): case (VT_VECTOR | VT_UI8): case (VT_VECTOR | VT_R4): case (VT_VECTOR | VT_R8): case (VT_VECTOR | VT_CY): case (VT_VECTOR | VT_DATE):
FreeArray: PROPASSERT((void**)&pvarg->caub.pElems == (void**)&pvarg->cai.pElems); CoTaskMemFree(pvarg->caub.pElems); break;
case (VT_VECTOR | VT_BSTR): if (pvarg->cabstr.pElems != NULL) { for (l=0; l< pvarg->cabstr.cElems; l++) { if (pvarg->cabstr.pElems[l] != NULL) { PropSysFreeString( pvarg->cabstr.pElems[l] ); } } } goto FreeArray;
case (VT_VECTOR | VT_BOOL): case (VT_VECTOR | VT_ERROR): goto FreeArray;
case (VT_VECTOR | VT_LPSTR): case (VT_VECTOR | VT_LPWSTR): if (pvarg->calpstr.pElems != NULL) for (l=0; l< pvarg->calpstr.cElems; l++) { CoTaskMemFree(pvarg->calpstr.pElems[l]); } goto FreeArray;
case (VT_VECTOR | VT_FILETIME): case (VT_VECTOR | VT_CLSID): goto FreeArray;
case (VT_VECTOR | VT_CF): if (pvarg->caclipdata.pElems != NULL) for (l=0; l< pvarg->caclipdata.cElems; l++) { CoTaskMemFree(pvarg->caclipdata.pElems[l].pClipData); } goto FreeArray;
case (VT_VECTOR | VT_VARIANT): if (pvarg->capropvar.pElems != NULL) hr = FreePropVariantArray(pvarg->capropvar.cElems, pvarg->capropvar.pElems); goto FreeArray;
default: hr = STG_E_INVALIDPARAMETER; break; }
// We have all of the important information about the variant, so
// let's clear it out.
//
PropVariantInit(pvarg);
return (hr); }
//+---------------------------------------------------------------------------
//
// Function: FreePropVariantArray, public
//
// Synopsis: Frees a value array returned from ReadMultiple
//
// Arguments: [cval] - Number of elements
// [rgvar] - Array
//
// Returns: S_OK if all types recognised and all freeable items were freed.
// STG_E_INVALID_PARAMETER if one or more types were not
// recognised but all items are freed too.
//
// Notes: Even if a vt-type is not understood, all the ones that are
// understood are freed. The error code will indicate
// if *any* of the members were illegal types.
//
//----------------------------------------------------------------------------
STDAPI FreePropVariantArray ( ULONG cVariants, PROPVARIANT *rgvars) { HRESULT hr = S_OK;
if (rgvars != NULL) for ( ULONG I=0; I < cVariants; I++ ) if (STG_E_INVALIDPARAMETER == PropVariantClear ( rgvars + I )) hr = STG_E_INVALIDPARAMETER;
return hr; }
//+-------------------------------------------------------------------
//
// Function: AllocAndCopy
//
// Synopsis: Allocates enough memory to copy the passed data into and
// then copies the data into the new buffer.
//
// Arguments: [cb] -- number of bytes of data to allocate and copy
// [pvData] -- the source of the data to copy
// [phr] -- optional pointer to an HRESULT set to
// STG_E_INSUFFICIENTMEMORY if memory could
// not be allocated.
//
//
// Returns: NULL if no memory could be allocated,
// Otherwise, pointer to allocated and copied data.
//
//--------------------------------------------------------------------
void * AllocAndCopy(ULONG cb, void * pvData, HRESULT *phr = NULL) { PROPASSERT(cb!=0); void * pvNew = CoTaskMemAlloc(cb); if (pvNew != NULL) { memcpy(pvNew, pvData, cb); } else { if (phr != NULL) { *phr = STG_E_INSUFFICIENTMEMORY; } } return(pvNew); }
//+-------------------------------------------------------------------
//
// Function: SysAllocString
// SysFreeString
//
// Synopsis: Exported BSTR allocation and deallocation routines
//
//
//--------------------------------------------------------------------
STDAPI_(void) SysFreeString(BSTR bstr) { if (bstr) { BYTE* pab = (BYTE*) bstr; delete[] (pab - sizeof(DWORD)); } }
STDAPI_(BSTR) SysAllocString(LPOLECHAR pwsz) { if (!pwsz) return NULL;
DWORD cch = _tcslen(pwsz);
/* a BSTR points to a DWORD length, followed by the string */ BYTE *pab = new BYTE[sizeof(DWORD) + ((cch+1)*sizeof(OLECHAR))];
if (pab) { *((DWORD*) pab) = cch*sizeof(OLECHAR); pab += sizeof(DWORD); _tcscpy( (LPOLECHAR)pab, pwsz ); } return ((BSTR) pab); }
//+---------------------------------------------------------------------------
//
// Table: g_TypeSizes, g_TypeSizesB
//
// Synopsis: Tables containing byte sizes and flags for various VT_ types.
//
//----------------------------------------------------------------------------
#define BIT_VECTNOALLOC 0x80 // the VT_VECTOR with this type does not
// use heap allocation
#define BIT_SIMPNOALLOC 0x40 // the non VT_VECTOR with this type does not
// use heap allocation
#define BIT_INVALID 0x20 // marks an invalid type
#define BIT_SIZEMASK 0x1F // mask for size of underlying type
const unsigned char g_TypeSizes[] = { BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 0, //VT_EMPTY= 0,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 0, //VT_NULL = 1,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 2, //VT_I2 = 2,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 4, //VT_I4 = 3,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 4, //VT_R4 = 4,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 8, //VT_R8 = 5,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | sizeof(CY), //VT_CY = 6,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | sizeof(DATE), //VT_DATE = 7,
sizeof(BSTR), //VT_BSTR = 8,
BIT_INVALID | 0, //VT_DISPATCH = 9,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | sizeof(SCODE), //VT_ERROR = 10,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | sizeof(VARIANT_BOOL), //VT_BOOL = 11,
sizeof(PROPVARIANT), //VT_VARIANT = 12,
BIT_INVALID | BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 0, //VT_UNKNOWN = 13,
BIT_INVALID | BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 0, // 14
BIT_INVALID | BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 0, // 15
#ifdef PROPVAR_VT_I1
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 1, //VT_I1 = 16,
#else
BIT_INVALID /*BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 1,*/ | 0, //VT_I1 = 16,
#endif
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 1, //VT_UI1 = 17,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 2, //VT_UI2 = 18,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 4, //VT_UI4 = 19,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 8, //VT_I8 = 20,
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 8, //VT_UI8 = 21,
BIT_INVALID | BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 0, //VT_INT = 22,
BIT_INVALID | BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 0, //VT_UINT = 23,
BIT_INVALID | BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 0, //VT_VOID = 24,
BIT_INVALID | BIT_SIMPNOALLOC | BIT_VECTNOALLOC | 0, //VT_HRESULT = 25,
BIT_INVALID | 0, //VT_PTR = 26,
BIT_INVALID | 0, //VT_SAFEARRAY = 27,
BIT_INVALID | 0, //VT_CARRAY = 28,
BIT_INVALID | 0, //VT_USERDEFINED = 29,
sizeof(LPSTR), //VT_LPSTR = 30,
sizeof(LPWSTR) //VT_LPWSTR = 31,
};
const unsigned char g_TypeSizesB[] = { // NOTE: vectors of types marked ** are determined dynamically
BIT_SIMPNOALLOC | BIT_VECTNOALLOC | sizeof(FILETIME), //VT_FILETIME = 64,
0, //**VT_BLOB = 65,
0, //**VT_STREAM = 66,
0, //**VT_STORAGE = 67,
0, //**VT_STREAMED_OBJECT = 68,
0, //**VT_STORED_OBJECT = 69,
0, //**VT_BLOB_OBJECT = 70,
sizeof(CLIPDATA), //VT_CF = 71,
BIT_VECTNOALLOC | sizeof(CLSID) //VT_CLSID = 72
};
//+---------------------------------------------------------------------------
//
// Function: PropVariantCopy, public
//
// Synopsis: Copies a PROPVARIANT
//
// Arguments: [pDest] -- the destination PROPVARIANT
// [pvarg] - the source PROPVARIANT
//
// Returns: Appropriate status code
//
//----------------------------------------------------------------------------
STDAPI PropVariantCopy ( PROPVARIANT * pDest, const PROPVARIANT * pvarg ) { HRESULT hr = S_OK; register unsigned char TypeInfo; register int iBaseType;
// handle the simple types quickly
iBaseType = pvarg->vt & ~VT_VECTOR;
if (iBaseType <= VT_LPWSTR) { TypeInfo = g_TypeSizes[iBaseType]; } else if (VT_FILETIME <= iBaseType && iBaseType <= VT_CLSID) { TypeInfo = g_TypeSizesB[iBaseType-VT_FILETIME]; } else { hr = STG_E_INVALIDPARAMETER; goto errRet; }
if ((TypeInfo & BIT_INVALID) != 0) { hr = STG_E_INVALIDPARAMETER; goto errRet; }
*pDest = *pvarg;
if ((pvarg->vt & VT_VECTOR) == 0) { // handle non-vector types
if ((TypeInfo & BIT_SIMPNOALLOC) == 0) { void * pvAllocated = (void*)-1;
switch (pvarg->vt) { case VT_BSTR: pvAllocated = pDest->bstrVal = PropSysAllocString( pvarg->bstrVal ); break;
case VT_LPSTR: if (pvarg->pszVal != NULL) pvAllocated = pDest->pszVal = (CHAR *) AllocAndCopy(strlen(pvarg->pszVal)+1, pvarg->pszVal); break; case VT_LPWSTR: if (pvarg->pwszVal != NULL) { ULONG cbString = (Prop_wcslen(pvarg->pwszVal)+1) * sizeof(WCHAR); pvAllocated = pDest->pwszVal = (WCHAR *) AllocAndCopy(cbString, pvarg->pwszVal); } break; case VT_CLSID: if (pvarg->puuid != NULL) pvAllocated = pDest->puuid = (GUID *) AllocAndCopy(sizeof(*(pvarg->puuid)), pvarg->puuid); break; case VT_CF: // first check if CLIPDATA is present
if (pvarg->pclipdata != NULL) { // yes ... copy the clip data structure
pvAllocated = pDest->pclipdata = (CLIPDATA*)AllocAndCopy( sizeof(*(pvarg->pclipdata)), pvarg->pclipdata);
// did we allocate the CLIPDATA ?
if (pvAllocated != NULL) { // yes ... initialize the destination.
pDest->pclipdata->pClipData = NULL;
// Is the input valid?
if (NULL == pvarg->pclipdata->pClipData && 0 != CBPCLIPDATA(*pvarg->pclipdata)) { // no ... the input is not valid
hr = STG_E_INVALIDPARAMETER; }
// Is there is any actual clip data ?
else if (0 != CBPCLIPDATA(*pvarg->pclipdata)) { // yes ... copy the actual clip data
pvAllocated = pDest->pclipdata->pClipData = (BYTE*)AllocAndCopy(CBPCLIPDATA(*pvarg->pclipdata), pvarg->pclipdata->pClipData); } } // if (pvAllocated != NULL)
} // if (pvarg->pclipdata != NULL)
break;
case VT_BLOB: case VT_BLOB_OBJECT: if (pvarg->blob.pBlobData != NULL && pvarg->blob.cbSize != 0) { pvAllocated = pDest->blob.pBlobData = (BYTE *) AllocAndCopy(pvarg->blob.cbSize, pvarg->blob.pBlobData); } else { // if the cbsize is 0 or pBlobData is NULL, make
// sure both values are consistent in the destination
pDest->blob.pBlobData = NULL; pDest->blob.cbSize = 0; } break;
case VT_VARIANT: // drop through - this merely documents that VT_VARIANT has been thought of.
default: //PROPASSERT(!"Unexpected non-vector type in PropVariantCopy");
hr = STG_E_INVALIDPARAMETER; goto errRet; }
if( FAILED(hr) ) goto errRet;
if (pvAllocated == NULL) { hr = STG_E_INSUFFICIENTMEMORY; goto errRet; } } // if ((TypeInfo & BIT_SIMPNOALLOC) == 0)
} // if ((pvarg->vt & VT_VECTOR) == 0)
else { ULONG cbType = TypeInfo & BIT_SIZEMASK; if (cbType == 0) { hr = STG_E_INVALIDPARAMETER; goto errRet; }
// handle the vector types
// this depends on the pointer and count being in the same place in
// each of CAUI1 CAI2 etc
// allocate the array for pElems
if (pvarg->caub.pElems == NULL || pvarg->caub.cElems == 0) { PROPASSERT( hr == S_OK ); goto errRet; // not really an error
}
void *pvAllocated = pDest->caub.pElems = (BYTE *) AllocAndCopy(cbType * pvarg->caub.cElems, pvarg->caub.pElems);
if (pvAllocated == NULL) { hr = STG_E_INSUFFICIENTMEMORY; goto errRet; }
if ((TypeInfo & BIT_VECTNOALLOC) != 0) { // the vector needs no further allocation
PROPASSERT( hr == S_OK ); goto errRet; }
ULONG l;
// vector types that require allocation ...
// we first zero out the pointers so that we can use PropVariantClear
// to clean up in the error case
switch (pvarg->vt) { case (VT_VECTOR | VT_BSTR): // initialize for error case
for (l=0; l< pvarg->cabstr.cElems; l++) { pDest->cabstr.pElems[l] = NULL; } break;
case (VT_VECTOR | VT_LPSTR): case (VT_VECTOR | VT_LPWSTR): // initialize for error case
for (l=0; l< pvarg->calpstr.cElems; l++) { pDest->calpstr.pElems[l] = NULL; } break;
case (VT_VECTOR | VT_CF): // initialize for error case
for (l=0; l< pvarg->caclipdata.cElems; l++) { pDest->caclipdata.pElems[l].pClipData = NULL; } break;
case (VT_VECTOR | VT_VARIANT): // initialize for error case
for (l=0; l< pvarg->capropvar.cElems; l++) { pDest->capropvar.pElems[l].vt = VT_ILLEGAL; } break;
default: PROPASSERT(!"Internal error: Unexpected type in PropVariantCopy"); CoTaskMemFree(pvAllocated); hr = STG_E_INVALIDPARAMETER; goto errRet; }
// now do the vector copy...
switch (pvarg->vt) { case (VT_VECTOR | VT_BSTR): for (l=0; l< pvarg->cabstr.cElems; l++) { if (pvarg->cabstr.pElems[l] != NULL) { pDest->cabstr.pElems[l] = PropSysAllocString( pvarg->cabstr.pElems[l]); if (pDest->cabstr.pElems[l] == NULL) { hr = STG_E_INSUFFICIENTMEMORY; break; } } } break;
case (VT_VECTOR | VT_LPWSTR): for (l=0; l< pvarg->calpwstr.cElems; l++) { if (pvarg->calpwstr.pElems[l] != NULL) {
pDest->calpwstr.pElems[l] = (LPWSTR)AllocAndCopy( sizeof(WCHAR)*(Prop_wcslen(pvarg->calpwstr.pElems[l])+1), pvarg->calpwstr.pElems[l], &hr);
if (hr != S_OK) break; } } break;
case (VT_VECTOR | VT_LPSTR): for (l=0; l< pvarg->calpstr.cElems; l++) { if (pvarg->calpstr.pElems[l] != NULL) { pDest->calpstr.pElems[l] = (LPSTR)AllocAndCopy( strlen(pvarg->calpstr.pElems[l])+1, pvarg->calpstr.pElems[l], &hr);
if (hr != S_OK) break; } } break;
case (VT_VECTOR | VT_CF): for (l=0; l< pvarg->caclipdata.cElems; l++) { // Is the input valid?
if (NULL == pvarg->caclipdata.pElems[l].pClipData && 0 != CBPCLIPDATA(pvarg->caclipdata.pElems[l] )) { hr = STG_E_INVALIDPARAMETER; break; }
// Is there data to copy?
if (0 != CBPCLIPDATA(pvarg->caclipdata.pElems[l])) { pDest->caclipdata.pElems[l].pClipData = (BYTE*)AllocAndCopy( CBPCLIPDATA(pvarg->caclipdata.pElems[l]), pvarg->caclipdata.pElems[l].pClipData, &hr);
if (hr != S_OK) break; } } break;
case (VT_VECTOR | VT_VARIANT): for (l=0; l< pvarg->capropvar.cElems; l++) { hr = PropVariantCopy(pDest->capropvar.pElems + l, pvarg->capropvar.pElems + l); if (hr != S_OK) { break; } } break;
default: PROPASSERT(!"Internal error: Unexpected type in PropVariantCopy"); CoTaskMemFree(pvAllocated); hr = STG_E_INVALIDPARAMETER; goto errRet; }
if (hr != S_OK) { PropVariantClear(pDest); goto errRet; } }
errRet:
if (hr != S_OK) { // VT_EMPTY
PROPASSERT(VT_EMPTY == 0); memset(pDest, 0, sizeof(*pDest)); }
return(hr); }
//+---------------------------------------------------------------------------
//
// Function: NtStatusToScode, public
//
// Synopsis: Attempts to map an NTSTATUS code to an SCODE
//
// Arguments: [nts] - NTSTATUS
//
// Returns: Appropriate status code
//
// History: 29-Jun-93 DrewB Created
//
// Notes: Assumes [nts] is an error code
// This function is by no means exhaustively complete
//
//----------------------------------------------------------------------------
SCODE NtStatusToScode(NTSTATUS nts) { SCODE sc;
PropDbg((DEB_ITRACE, "In NtStatusToScode(%lX)\n", nts));
switch(nts) { case STATUS_INVALID_PARAMETER: case STATUS_INVALID_PARAMETER_MIX: case STATUS_INVALID_PARAMETER_1: case STATUS_INVALID_PARAMETER_2: case STATUS_INVALID_PARAMETER_3: case STATUS_INVALID_PARAMETER_4: case STATUS_INVALID_PARAMETER_5: case STATUS_INVALID_PARAMETER_6: case STATUS_INVALID_PARAMETER_7: case STATUS_INVALID_PARAMETER_8: case STATUS_INVALID_PARAMETER_9: case STATUS_INVALID_PARAMETER_10: case STATUS_INVALID_PARAMETER_11: case STATUS_INVALID_PARAMETER_12: sc = STG_E_INVALIDPARAMETER; break;
case STATUS_DUPLICATE_NAME: case STATUS_DUPLICATE_OBJECTID: case STATUS_OBJECTID_EXISTS: case STATUS_OBJECT_NAME_COLLISION: sc = STG_E_FILEALREADYEXISTS; break;
case STATUS_NO_SUCH_DEVICE: case STATUS_NO_SUCH_FILE: case STATUS_OBJECT_NAME_NOT_FOUND: case STATUS_NOT_A_DIRECTORY: case STATUS_FILE_IS_A_DIRECTORY: case STATUS_PROPSET_NOT_FOUND: case STATUS_NOT_FOUND: case STATUS_OBJECT_TYPE_MISMATCH: sc = STG_E_FILENOTFOUND; break;
case STATUS_OBJECT_NAME_INVALID: case STATUS_OBJECT_PATH_SYNTAX_BAD: case STATUS_OBJECT_PATH_INVALID: case STATUS_NAME_TOO_LONG: sc = STG_E_INVALIDNAME; break;
case STATUS_ACCESS_DENIED: sc = STG_E_ACCESSDENIED; break;
case STATUS_NO_MEMORY: case STATUS_INSUFFICIENT_RESOURCES: sc = STG_E_INSUFFICIENTMEMORY; break;
case STATUS_INVALID_HANDLE: case STATUS_FILE_INVALID: case STATUS_FILE_FORCED_CLOSED: sc = STG_E_INVALIDHANDLE; break;
case STATUS_INVALID_DEVICE_REQUEST: case STATUS_INVALID_SYSTEM_SERVICE: case STATUS_NOT_IMPLEMENTED: sc = STG_E_INVALIDFUNCTION; break;
case STATUS_NO_MEDIA_IN_DEVICE: case STATUS_UNRECOGNIZED_MEDIA: case STATUS_DISK_CORRUPT_ERROR: case STATUS_DATA_ERROR: sc = STG_E_WRITEFAULT; break;
case STATUS_OBJECT_PATH_NOT_FOUND: sc = STG_E_PATHNOTFOUND; break;
case STATUS_SHARING_VIOLATION: sc = STG_E_SHAREVIOLATION; break;
case STATUS_FILE_LOCK_CONFLICT: case STATUS_LOCK_NOT_GRANTED: sc = STG_E_LOCKVIOLATION; break;
case STATUS_DISK_FULL: sc = STG_E_MEDIUMFULL; break;
case STATUS_ACCESS_VIOLATION: case STATUS_INVALID_USER_BUFFER: sc = STG_E_INVALIDPOINTER; break;
case STATUS_TOO_MANY_OPENED_FILES: sc = STG_E_TOOMANYOPENFILES; break;
case STATUS_DIRECTORY_NOT_EMPTY: sc = WIN32_SCODE(ERROR_DIR_NOT_EMPTY); break;
case STATUS_DELETE_PENDING: sc = STG_E_REVERTED; break;
case STATUS_INTERNAL_DB_CORRUPTION: sc = STG_E_INVALIDHEADER; break;
case STATUS_UNSUCCESSFUL: sc = E_FAIL; break; case STATUS_UNMAPPABLE_CHARACTER: sc = HRESULT_FROM_WIN32( ERROR_NO_UNICODE_TRANSLATION ); break;
default: PropDbg((DEB_ERROR, "NtStatusToScode: Unknown status %lX\n", nts));
sc = HRESULT_FROM_NT(nts); break; }
PropDbg((DEB_ITRACE, "Out NtStatusToScode => %lX\n", sc)); return sc; }
#if DBG!=0
ULONG DbgPrint( PCHAR Format, ... ) { va_list arglist; CHAR Buffer[512]; int cb;
//
// Format the output into a buffer and then print it.
//
va_start(arglist, Format); cb = PropVsprintfA(Buffer, Format, arglist); if (cb == -1) { // detect buffer overflow
cb = sizeof(Buffer); Buffer[sizeof(Buffer) - 2] = '\n'; Buffer[sizeof(Buffer) - 1] = '\0'; }
OutputDebugString(Buffer);
return 0; } #endif
|