Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

846 lines
26 KiB

//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 2000.
//
// File: nt2umi.cxx
//
// Contents: Contains the routines to convert from NT objects to
// UMI_PROPERTY structures.
//
// History: 02-29-00 SivaramR Created.
//
//----------------------------------------------------------------------------
#include "winnt.hxx"
//----------------------------------------------------------------------------
// Function: WinNTTypeToUmiIntegers
//
// Synopsis: Converts from NT object to UMI_PROPERTY structure containing
// one of the signed/unsigned integers (1, 2, 4 or 8 bytes each).
//
// Arguments:
//
// pNtObject Pointer to NT object
// dwNumValues Number of values in pNtObject
// pPropArray Pointer to UMI_PROPERTY that returns the converted values
// pExistingMem If non-NULL, the provider does not allocate memory. Instead,
// the memory pointed to by this argument is used.
// dwMemSize Number of bytes of memory pointed to by pExistingMem
// UmiType UMI type to convert the NT object to
//
// Returns: UMI_S_NO_ERROR on success. Error code otherwise.
//
// Modifies: *pExistingMem if pExistingMem is non-NULL
// *pPropArray otherwise
//
//----------------------------------------------------------------------------
HRESULT WinNTTypeToUmiIntegers(
LPNTOBJECT pNtObject,
DWORD dwNumValues,
UMI_PROPERTY *pPropArray,
LPVOID pExistingMem,
DWORD dwMemSize,
UMI_TYPE UmiType
)
{
DWORD dwSize = 0, dwMemRequired = 0, dwNtValue = 0, i = 0;
void *pIntArray = NULL;
HRESULT hr = UMI_S_NO_ERROR;
// Check if the NT type can be converted to the requested UMI type
if(pNtObject->NTType != NT_SYNTAX_ID_DWORD)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
switch(UmiType) {
case UMI_TYPE_I1:
case UMI_TYPE_UI1:
dwSize = 1;
break;
case UMI_TYPE_I2:
case UMI_TYPE_UI2:
dwSize = 2;
break;
case UMI_TYPE_I4:
case UMI_TYPE_UI4:
dwSize = 4;
break;
case UMI_TYPE_I8:
case UMI_TYPE_UI8:
dwSize = 8;
break;
default:
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
}
dwMemRequired = dwNumValues * dwSize;
if(NULL == pExistingMem) {
// provider has to allocate memory
pIntArray = (void *) AllocADsMem(dwMemRequired);
if(NULL == pIntArray)
BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
}
else {
// user provided memory to return data
if(dwMemSize < dwMemRequired)
BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
pIntArray = pExistingMem;
}
for(i = 0; i < dwNumValues; i++) {
dwNtValue = pNtObject[i].NTValue.dwValue;
switch(UmiType) {
case UMI_TYPE_I1:
case UMI_TYPE_UI1:
*((CHAR *)(pIntArray) + i) = (CHAR) dwNtValue;
break;
case UMI_TYPE_I2:
case UMI_TYPE_UI2:
*((WCHAR *)(pIntArray) + i) = (WCHAR) dwNtValue;
break;
case UMI_TYPE_I4:
case UMI_TYPE_UI4:
*((DWORD *)(pIntArray) + i) = dwNtValue;
break;
case UMI_TYPE_I8:
case UMI_TYPE_UI8:
*((__int64 *)(pIntArray) + i) = (__int64) dwNtValue;
break;
default:
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
} // switch
} // for
if(pPropArray != NULL)
pPropArray->pUmiValue = (UMI_VALUE *) pIntArray;
RRETURN(hr);
error:
if( (pIntArray != NULL) && (NULL == pExistingMem) )
FreeADsMem(pIntArray);
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: WinNTTypeToUmiFileTimes
//
// Synopsis: Converts from NT object to UMI_PROPERTY structure containing
// a filetime.
//
// Arguments:
//
// pNtObject Pointer to NT object
// dwNumValues Number of values in pNtObject
// pPropArray Pointer to UMI_PROPERTY that returns the converted values
// pExistingMem If non-NULL, the provider does not allocate memory. Instead,
// the memory pointed to by this argument is used.
// dwMemSize Number of bytes of memory pointed to by pExistingMem
//
// Returns: UMI_S_NO_ERROR on success. Error code otherwise.
//
// Modifies: *pExistingMem if pExistingMem is non-NULL
// *pPropArray otherwise
//
//----------------------------------------------------------------------------
HRESULT WinNTTypeToUmiFileTimes(
LPNTOBJECT pNtObject,
DWORD dwNumValues,
UMI_PROPERTY *pPropArray,
LPVOID pExistingMem,
DWORD dwMemSize
)
{
DWORD dwMemRequired = 0, i = 0;
void *pFileTimeArray = NULL;
HRESULT hr = UMI_S_NO_ERROR;
BOOL fRetVal = FALSE;
SYSTEMTIME LocalTime, SystemTime;
FILETIME LocalFileTime, FileTime;
LARGE_INTEGER tmpTime;
// Check if the NT type can be converted to the requested UMI type
if(pNtObject->NTType != NT_SYNTAX_ID_SYSTEMTIME)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
dwMemRequired = dwNumValues * sizeof(FILETIME);
if(NULL == pExistingMem) {
// provider has to allocate memory
pFileTimeArray = (void *) AllocADsMem(dwMemRequired);
if(NULL == pFileTimeArray)
BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
}
else {
// user provided memory to return data
if(dwMemSize < dwMemRequired)
BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
pFileTimeArray = pExistingMem;
}
for(i = 0; i < dwNumValues; i++) {
if(NT_SYNTAX_ID_SYSTEMTIME == pNtObject->NTType) {
// convert from UTC to local time
fRetVal = SystemTimeToTzSpecificLocalTime(
NULL,
&(pNtObject[i].NTValue.stSystemTimeValue),
&LocalTime
);
if(FALSE == fRetVal)
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
fRetVal = SystemTimeToFileTime(
&LocalTime,
&LocalFileTime
);
if(FALSE == fRetVal)
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
}
else if(NT_SYNTAX_ID_DATE == pNtObject->NTType) {
GetSystemTime(&SystemTime);
// only the hours and minutes are valid. Rest is no-op.
SystemTime.wHour = (WORD) ((pNtObject[i].NTValue.dwValue)/60);
SystemTime.wMinute = (WORD) ((pNtObject[i].NTValue.dwValue)%60);
SystemTime.wSecond =0;
SystemTime.wMilliseconds = 0;
// now convert UTC To local time
fRetVal = SystemTimeToTzSpecificLocalTime(
NULL,
&SystemTime,
&LocalTime
);
if(FALSE == fRetVal)
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
fRetVal = SystemTimeToFileTime(
&LocalTime,
&LocalFileTime
);
if(FALSE == fRetVal)
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
}
else if(NT_SYNTAX_ID_DATE_1970 == pNtObject->NTType) {
memset(&FileTime, 0, sizeof(FILETIME));
RtlSecondsSince1970ToTime(
pNtObject[i].NTValue.dwSeconds1970,
&tmpTime
);
FileTime.dwLowDateTime = tmpTime.LowPart;
FileTime.dwHighDateTime = tmpTime.HighPart;
fRetVal = FileTimeToLocalFileTime(
&FileTime,
&LocalFileTime
);
if(FALSE == fRetVal)
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
}
*((FILETIME *)pFileTimeArray + i) = LocalFileTime;
}
if(pPropArray != NULL)
pPropArray->pUmiValue = (UMI_VALUE *) pFileTimeArray;
RRETURN(hr);
error:
if( (pFileTimeArray != NULL) && (NULL == pExistingMem) )
FreeADsMem(pFileTimeArray);
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: WinNTTypeToUmiSystemTimes
//
// Synopsis: Converts from NT object to UMI_PROPERTY structure containing
// a systemtime.
//
// Arguments:
//
// pNtObject Pointer to NT object
// dwNumValues Number of values in pNtObject
// pPropArray Pointer to UMI_PROPERTY that returns the converted values
// pExistingMem If non-NULL, the provider does not allocate memory. Instead,
// the memory pointed to by this argument is used.
// dwMemSize Number of bytes of memory pointed to by pExistingMem
//
// Returns: UMI_S_NO_ERROR on success. Error code otherwise.
//
// Modifies: *pExistingMem if pExistingMem is non-NULL
// *pPropArray otherwise
//
//----------------------------------------------------------------------------
HRESULT WinNTTypeToUmiSystemTimes(
LPNTOBJECT pNtObject,
DWORD dwNumValues,
UMI_PROPERTY *pPropArray,
LPVOID pExistingMem,
DWORD dwMemSize
)
{
DWORD dwMemRequired = 0, i = 0;
void *pSysTimeArray = NULL;
HRESULT hr = UMI_S_NO_ERROR;
SYSTEMTIME LocalTime, SystemTime;
BOOL fRetVal = FALSE;
FILETIME FileTime, LocalFileTime;
LARGE_INTEGER tmpTime;
// Check if the NT type can be converted to the requested UMI type
if( (pNtObject->NTType != NT_SYNTAX_ID_SYSTEMTIME) &&
(pNtObject->NTType != NT_SYNTAX_ID_DATE) &&
(pNtObject->NTType != NT_SYNTAX_ID_DATE_1970) )
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
dwMemRequired = dwNumValues * sizeof(SYSTEMTIME);
if(NULL == pExistingMem) {
// provider has to allocate memory
pSysTimeArray = (void *) AllocADsMem(dwMemRequired);
if(NULL == pSysTimeArray)
BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
}
else {
// user provided memory to return data
if(dwMemSize < dwMemRequired)
BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
pSysTimeArray = pExistingMem;
}
for(i = 0; i < dwNumValues; i++) {
if(NT_SYNTAX_ID_SYSTEMTIME == pNtObject->NTType) {
// convert from UTC to local time
fRetVal = SystemTimeToTzSpecificLocalTime(
NULL,
&pNtObject[i].NTValue.stSystemTimeValue,
&LocalTime
);
if(FALSE == fRetVal)
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
}
else if(NT_SYNTAX_ID_DATE == pNtObject->NTType) {
GetSystemTime(&SystemTime);
// only the hours and minutes are valid. Rest is no-op.
SystemTime.wHour = (WORD) ((pNtObject[i].NTValue.dwValue)/60);
SystemTime.wMinute = (WORD) ((pNtObject[i].NTValue.dwValue)%60);
SystemTime.wSecond =0;
SystemTime.wMilliseconds = 0;
// now convert UTC To local time
fRetVal = SystemTimeToTzSpecificLocalTime(
NULL,
&SystemTime,
&LocalTime
);
if(FALSE == fRetVal)
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
}
else if(NT_SYNTAX_ID_DATE_1970 == pNtObject->NTType) {
memset(&FileTime, 0, sizeof(FILETIME));
RtlSecondsSince1970ToTime(
pNtObject[i].NTValue.dwSeconds1970,
&tmpTime
);
FileTime.dwLowDateTime = tmpTime.LowPart;
FileTime.dwHighDateTime = tmpTime.HighPart;
fRetVal = FileTimeToLocalFileTime(
&FileTime,
&LocalFileTime
);
if(FALSE == fRetVal)
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
fRetVal = FileTimeToSystemTime(
&LocalFileTime,
&LocalTime
);
if(FALSE == fRetVal)
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
}
*((SYSTEMTIME *)pSysTimeArray + i) = LocalTime;
}
if(pPropArray != NULL)
pPropArray->pUmiValue = (UMI_VALUE *) pSysTimeArray;
RRETURN(hr);
error:
if( (pSysTimeArray != NULL) && (NULL == pExistingMem) )
FreeADsMem(pSysTimeArray);
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: WinNTTypeToUmiBools
//
// Synopsis: Converts from NT object to UMI_PROPERTY structure containing
// a boolean
//
// Arguments:
//
// pNtObject Pointer to NT object
// dwNumValues Number of values in pNtObject
// pPropArray Pointer to UMI_PROPERTY that returns the converted values
// pExistingMem If non-NULL, the provider does not allocate memory. Instead,
// the memory pointed to by this argument is used.
// dwMemSize Number of bytes of memory pointed to by pExistingMem
//
// Returns: UMI_S_NO_ERROR on success. Error code otherwise.
//
// Modifies: *pExistingMem if pExistingMem is non-NULL
// *pPropArray otherwise
//
//----------------------------------------------------------------------------
HRESULT WinNTTypeToUmiBools(
LPNTOBJECT pNtObject,
DWORD dwNumValues,
UMI_PROPERTY *pPropArray,
LPVOID pExistingMem,
DWORD dwMemSize
)
{
DWORD dwMemRequired = 0, i = 0;
void *pBoolArray = NULL;
HRESULT hr = UMI_S_NO_ERROR;
// Check if the NT type can be converted to the requested UMI type
if(pNtObject->NTType != NT_SYNTAX_ID_BOOL)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
dwMemRequired = dwNumValues * sizeof(BOOL);
if(NULL == pExistingMem) {
// provider has to allocate memory
pBoolArray = (void *) AllocADsMem(dwMemRequired);
if(NULL == pBoolArray)
BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
}
else {
// user provided memory to return data
if(dwMemSize < dwMemRequired)
BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
pBoolArray = pExistingMem;
}
for(i = 0; i < dwNumValues; i++) {
if(pNtObject[i].NTValue.fValue)
*((BOOL *)pBoolArray + i) = TRUE;
else
*((BOOL *)pBoolArray + i) = FALSE;
}
if(pPropArray != NULL)
pPropArray->pUmiValue = (UMI_VALUE *) pBoolArray;
RRETURN(hr);
error:
if( (pBoolArray != NULL) && (NULL == pExistingMem) )
FreeADsMem(pBoolArray);
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: WinNTTypeToUmiLPWSTRs
//
// Synopsis: Converts from NT object to UMI_PROPERTY structure containing
// a string
//
// Arguments:
//
// pNtObject Pointer to NT object
// dwNumValues Number of values in pNtObject
// pPropArray Pointer to UMI_PROPERTY that returns the converted values
// pExistingMem If non-NULL, the provider does not allocate memory. Instead,
// the memory pointed to by this argument is used.
// dwMemSize Number of bytes of memory pointed to by pExistingMem
//
// Returns: UMI_S_NO_ERROR on success. Error code otherwise.
//
// Modifies: *pExistingMem if pExistingMem is non-NULL
// *pPropArray otherwise
//
//----------------------------------------------------------------------------
HRESULT WinNTTypeToUmiLPWSTRs(
LPNTOBJECT pNtObject,
DWORD dwNumValues,
UMI_PROPERTY *pPropArray,
LPVOID pExistingMem,
DWORD dwMemSize
)
{
DWORD dwMemRequired = 0, i = 0;
void *pStrArray = NULL;
HRESULT hr = UMI_S_NO_ERROR;
LPWSTR pszTmpStr = NULL;
UCHAR Seed = UMI_ENCODE_SEED3;
UNICODE_STRING Password;
// Check if the NT type can be converted to the requested UMI type
if( (pNtObject->NTType != NT_SYNTAX_ID_LPTSTR) &&
(pNtObject->NTType != NT_SYNTAX_ID_DelimitedString) &&
(pNtObject->NTType != NT_SYNTAX_ID_NulledString) &&
(pNtObject->NTType != NT_SYNTAX_ID_EncryptedString) )
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
dwMemRequired = dwNumValues * sizeof(LPWSTR);
if(NULL == pExistingMem) {
// provider has to allocate memory
pStrArray = (void *) AllocADsMem(dwMemRequired);
if(NULL == pStrArray)
BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
}
else {
// user provided memory to return data. GetAs() will call this function
// only if the property is single-valued. Copy the string into the
// memory supplied y the caller.
//
ADsAssert(1 == dwNumValues);
dwMemRequired = (wcslen(pNtObject->NTValue.pszValue) + 1) *
sizeof(WCHAR);
if(dwMemSize < dwMemRequired)
BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
wcscpy((WCHAR *) pExistingMem, pNtObject->NTValue.pszValue);
if(NT_SYNTAX_ID_EncryptedString == pNtObject->NTType) {
// decrypt the string (typically password)
RtlInitUnicodeString(&Password, (WCHAR *) pExistingMem);
RtlRunDecodeUnicodeString(Seed, &Password);
}
RRETURN(UMI_S_NO_ERROR);
}
memset(pStrArray, 0, dwMemRequired);
for(i = 0; i < dwNumValues; i++) {
if(pNtObject[i].NTValue.pszValue != NULL) {
pszTmpStr = AllocADsStr(pNtObject[i].NTValue.pszValue);
if(NULL == pszTmpStr)
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
if(NT_SYNTAX_ID_EncryptedString == pNtObject->NTType) {
// decrypt the string (typically password)
RtlInitUnicodeString(&Password, pszTmpStr);
RtlRunDecodeUnicodeString(Seed, &Password);
}
}
*((LPWSTR *)pStrArray + i) = pszTmpStr;
}
if(pPropArray != NULL)
pPropArray->pUmiValue = (UMI_VALUE *) pStrArray;
RRETURN(hr);
error:
if(pStrArray != NULL) {
// free any strings allocated
for(i = 0; i < dwNumValues; i++)
if(((LPWSTR *) pStrArray)[i] != NULL)
FreeADsStr(((LPWSTR *) pStrArray)[i]);
if(NULL == pExistingMem)
// provider allocated memory
FreeADsMem(pStrArray);
}
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: WinNTTypeToUmiOctetStrings
//
// Synopsis: Converts from NT object to UMI_PROPERTY structure containing
// an octet string
//
// Arguments:
//
// pNtObject Pointer to NT object
// dwNumValues Number of values in pNtObject
// pPropArray Pointer to UMI_PROPERTY that returns the converted values
// pExistingMem If non-NULL, the provider does not allocate memory. Instead,
// the memory pointed to by this argument is used.
// dwMemSize Number of bytes of memory pointed to by pExistingMem
//
// Returns: UMI_S_NO_ERROR on success. Error code otherwise.
//
// Modifies: *pExistingMem if pExistingMem is non-NULL
// *pPropArray otherwise
//
//----------------------------------------------------------------------------
HRESULT WinNTTypeToUmiOctetStrings(
LPNTOBJECT pNtObject,
DWORD dwNumValues,
UMI_PROPERTY *pPropArray,
LPVOID pExistingMem,
DWORD dwMemSize
)
{
DWORD dwMemRequired = 0, i = 0;
void *pOctetStrArray = NULL;
HRESULT hr = UMI_S_NO_ERROR;
LPWSTR pTmpOctetStr = NULL;
// Check if the NT type can be converted to the requested UMI type
if(pNtObject->NTType != NT_SYNTAX_ID_OCTETSTRING)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
dwMemRequired = dwNumValues * sizeof(UMI_OCTET_STRING);
if(NULL == pExistingMem) {
// provider has to allocate memory
pOctetStrArray = (void *) AllocADsMem(dwMemRequired);
if(NULL == pOctetStrArray)
BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
}
else {
// user provided memory to return data
if(dwMemSize < dwMemRequired)
BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
pOctetStrArray = pExistingMem;
}
memset(pOctetStrArray, 0, dwMemRequired);
for(i = 0; i < dwNumValues; i++) {
pTmpOctetStr = (LPWSTR)
AllocADsMem(pNtObject[i].NTValue.octetstring.dwSize);
if(NULL == pTmpOctetStr)
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
memcpy(
pTmpOctetStr,
pNtObject[i].NTValue.octetstring.pByte,
pNtObject[i].NTValue.octetstring.dwSize
);
((UMI_OCTET_STRING *)pOctetStrArray + i)->uLength =
pNtObject[i].NTValue.octetstring.dwSize;
((UMI_OCTET_STRING *)pOctetStrArray + i)->lpValue =
(BYTE *) pTmpOctetStr;
}
if(pPropArray != NULL)
pPropArray->pUmiValue = (UMI_VALUE *) pOctetStrArray;
RRETURN(hr);
error:
if(pOctetStrArray != NULL) {
// free any strings allocated
for(i = 0; i < dwNumValues; i++)
if(((UMI_OCTET_STRING *) pOctetStrArray)[i].lpValue != NULL)
FreeADsMem(((UMI_OCTET_STRING *) pOctetStrArray)[i].lpValue);
if(NULL == pExistingMem)
// provider allocated memory
FreeADsMem(pOctetStrArray);
}
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: WinNTTypeToUmi
//
// Synopsis: Converts from NT object to UMI_PROPERTY structure.
//
// Arguments:
//
// pNtObject Pointer to NT object
// dwNumValues Number of values in pNtObject
// pPropArray Pointer to UMI_PROPERTY that returns the converted values
// pExistingMem If non-NULL, the provider does not allocate memory. Instead,
// the memory pointed to by this argument is used.
// dwMemSize Number of bytes of memory pointed to by pExistingMem
// UmiType UMI type to convert the NT object to
//
// Returns: UMI_S_NO_ERROR on success. Error code otherwise.
//
// Modifies: *pExistingMem if pExistingMem is non-NULL
// *pPropArray otherwise
//
//----------------------------------------------------------------------------
HRESULT WinNTTypeToUmi(
LPNTOBJECT pNtObject,
DWORD dwNumValues,
UMI_PROPERTY *pPropArray,
LPVOID pExistingMem,
DWORD dwMemSize,
UMI_TYPE UmiType
)
{
HRESULT hr = UMI_S_NO_ERROR;
ADsAssert( (pNtObject != NULL) &&
((pPropArray != NULL) || (pExistingMem != NULL)) );
// only one of pPropArray and pExistingMem can be non-NULL
ADsAssert( (NULL == pPropArray) || (NULL == pExistingMem) );
// Enclose code in try/except to catch AVs caused by the user passing in
// a bad pointer in pExistingMem
__try {
switch(UmiType) {
case UMI_TYPE_NULL:
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
case UMI_TYPE_I1:
case UMI_TYPE_I2:
case UMI_TYPE_I4:
case UMI_TYPE_I8:
case UMI_TYPE_UI1:
case UMI_TYPE_UI2:
case UMI_TYPE_UI4:
case UMI_TYPE_UI8:
hr = WinNTTypeToUmiIntegers(
pNtObject,
dwNumValues,
pPropArray,
pExistingMem,
dwMemSize,
UmiType
);
break;
case UMI_TYPE_R4:
case UMI_TYPE_R8:
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
case UMI_TYPE_FILETIME:
hr = WinNTTypeToUmiFileTimes(
pNtObject,
dwNumValues,
pPropArray,
pExistingMem,
dwMemSize
);
break;
case UMI_TYPE_SYSTEMTIME:
hr = WinNTTypeToUmiSystemTimes(
pNtObject,
dwNumValues,
pPropArray,
pExistingMem,
dwMemSize
);
break;
case UMI_TYPE_BOOL:
hr = WinNTTypeToUmiBools(
pNtObject,
dwNumValues,
pPropArray,
pExistingMem,
dwMemSize
);
break;
case UMI_TYPE_IDISPATCH:
case UMI_TYPE_IUNKNOWN:
case UMI_TYPE_VARIANT: // TODO later
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
case UMI_TYPE_LPWSTR:
hr = WinNTTypeToUmiLPWSTRs(
pNtObject,
dwNumValues,
pPropArray,
pExistingMem,
dwMemSize
);
break;
case UMI_TYPE_OCTETSTRING:
hr = WinNTTypeToUmiOctetStrings(
pNtObject,
dwNumValues,
pPropArray,
pExistingMem,
dwMemSize
);
break;
case UMI_TYPE_UMIARRAY:
case UMI_TYPE_DISCOVERY:
case UMI_TYPE_UNDEFINED:
case UMI_TYPE_DEFAULT:
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
default:
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
} // switch
} __except( EXCEPTION_EXECUTE_HANDLER ) {
if(pExistingMem != NULL) {
// assume this is the cause of the exception
BAIL_ON_FAILURE(hr = UMI_E_INTERNAL_EXCEPTION);
}
else
// don't mask bugs in provider
throw;
}
if(pPropArray != NULL) {
pPropArray->uType = UmiType;
pPropArray->uCount = dwNumValues;
}
error:
RRETURN(hr);
}