847 lines
26 KiB
C++
847 lines
26 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// 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);
|
|
|
|
}
|