windows-nt/Source/XPSP1/NT/ds/adsi/winnt/umi2nt.cxx
2020-09-26 16:20:57 +08:00

666 lines
20 KiB
C++

//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 2000.
//
// File: umi2nt.cxx
//
// Contents: Contains the routines to convert from UMI_PROPERTY structures to
// NT objects that can be stored in the cache.
//
// History: 02-28-00 SivaramR Created.
//
//----------------------------------------------------------------------------
#include "winnt.hxx"
//----------------------------------------------------------------------------
// Function: UmiToBooleans
//
// Synopsis: Converts from UMI_PROPERTY structure to array of NT objects,
// each containing a boolean.
//
// Arguments:
//
// pPropArray Pointer to UMI_PROPERTY structure
// pNtObjects Array of NT objects that returns the values.
// ulNumValues Number of values stored in pPropArray
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise (none now).
//
// Modifies: *pNtObject to return the converted value.
//
//----------------------------------------------------------------------------
HRESULT UmiToBooleans(
UMI_PROPERTY *pPropArray,
LPNTOBJECT pNtObjects,
ULONG ulNumValues
)
{
ULONG ulIndex = 0;
BOOL bVal;
ADsAssert( (pPropArray != NULL) && (pNtObjects != NULL) );
ADsAssert(pPropArray->pUmiValue != NULL);
for(ulIndex = 0; ulIndex < ulNumValues; ulIndex++)
{
bVal = pPropArray->pUmiValue->bValue[ulIndex];
pNtObjects[ulIndex].NTType = NT_SYNTAX_ID_BOOL;
if(bVal)
pNtObjects[ulIndex].NTValue.fValue = TRUE;
else
pNtObjects[ulIndex].NTValue.fValue = FALSE;
}
RRETURN(UMI_S_NO_ERROR);
}
//----------------------------------------------------------------------------
// Function: ConvertSystemTimeToUTCTime
//
// Synopsis: Converts a system time structure containing a local time to a
// system time structure containing UTC time.
//
// Arguments:
//
// pLocalTime Pointer to local time
// pUTCTime Returns UTC time
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise.
//
// Modifies: *pUTCTime to contain the UTC time.
//
//----------------------------------------------------------------------------
HRESULT ConvertSystemTimeToUTCTime(
SYSTEMTIME *pLocalTime,
SYSTEMTIME *pUTCTime
)
{
HRESULT hr = UMI_S_NO_ERROR;
FILETIME localft, ft;
BOOL fRetVal;
ADsAssert( (pLocalTime != NULL) && (pUTCTime != NULL) );
fRetVal = SystemTimeToFileTime(pLocalTime, &localft);
if(!fRetVal)
BAIL_ON_FAILURE( hr = HRESULT_FROM_WIN32(GetLastError()) );
fRetVal = LocalFileTimeToFileTime(&localft, &ft);
if(!fRetVal)
BAIL_ON_FAILURE( hr = HRESULT_FROM_WIN32(GetLastError()) );
fRetVal = FileTimeToSystemTime(&ft, pUTCTime);
if(!fRetVal)
BAIL_ON_FAILURE( hr = HRESULT_FROM_WIN32(GetLastError()) );
RRETURN(UMI_S_NO_ERROR);
error:
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: UmiToSystemTimes
//
// Synopsis: Converts from UMI_PROPERTY structure to array of NT objects,
// each containing a system time. The time sent in by the user
// is local time, so we need to convert it to UTC.
//
// Arguments:
//
// pPropArray Pointer to UMI_PROPERTY structure
// pNtObjects Array of NT objects that returns the values.
// ulNumValues Number of values stored in pPropArray
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise.
//
// Modifies: *pNtObject to return the converted value.
//
//----------------------------------------------------------------------------
HRESULT UmiToSystemTimes(
UMI_PROPERTY *pPropArray,
LPNTOBJECT pNtObjects,
ULONG ulNumValues
)
{
ULONG ulIndex = 0;
SYSTEMTIME *pSysTime, UTCTime;
HRESULT hr = UMI_S_NO_ERROR;
ADsAssert( (pPropArray != NULL) && (pNtObjects != NULL) );
ADsAssert(pPropArray->pUmiValue != NULL);
for(ulIndex = 0; ulIndex < ulNumValues; ulIndex++)
{
pSysTime = &(pPropArray->pUmiValue->sysTimeValue[ulIndex]);
hr = ConvertSystemTimeToUTCTime(pSysTime, &UTCTime);
BAIL_ON_FAILURE(hr);
pNtObjects[ulIndex].NTType = NT_SYNTAX_ID_SYSTEMTIME;
pNtObjects[ulIndex].NTValue.stSystemTimeValue = UTCTime;
}
RRETURN(UMI_S_NO_ERROR);
error:
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: UmiToDwords
//
// Synopsis: Converts from UMI_PROPERTY structure to array of NT objects,
// each containing a DWORD.
//
// Arguments:
//
// pPropArray Pointer to UMI_PROPERTY structure
// pNtObjects Array of NT objects that returns the values.
// ulNumValues Number of values stored in pPropArray
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise (none now).
//
// Modifies: *pNtObject to return the converted value.
//
//----------------------------------------------------------------------------
HRESULT UmiToDwords(
UMI_PROPERTY *pPropArray,
LPNTOBJECT pNtObjects,
ULONG ulNumValues
)
{
ULONG ulIndex = 0;
DWORD dwVal;
ADsAssert( (pPropArray != NULL) && (pNtObjects != NULL) );
ADsAssert(pPropArray->pUmiValue != NULL);
for(ulIndex = 0; ulIndex < ulNumValues; ulIndex++)
{
dwVal = pPropArray->pUmiValue->uValue[ulIndex];
pNtObjects[ulIndex].NTType = NT_SYNTAX_ID_DWORD;
pNtObjects[ulIndex].NTValue.dwValue = dwVal;
}
RRETURN(UMI_S_NO_ERROR);
}
//----------------------------------------------------------------------------
// Function: UmiToDates
//
// Synopsis: Converts from UMI_PROPERTY structure to array of NT objects,
// each containing a DATE. Only the hours and minutes in the
// system time are stored in the NT object. Again, the input
// is local time, so it needs to be converted to UTC.
//
// Arguments:
//
// pPropArray Pointer to UMI_PROPERTY structure
// pNtObjects Array of NT objects that returns the values.
// ulNumValues Number of values stored in pPropArray
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise.
//
// Modifies: *pNtObject to return the converted value.
//
//----------------------------------------------------------------------------
HRESULT UmiToDates(
UMI_PROPERTY *pPropArray,
LPNTOBJECT pNtObjects,
ULONG ulNumValues
)
{
ULONG ulIndex = 0;
SYSTEMTIME *pSysTime, UTCTime;
HRESULT hr = UMI_S_NO_ERROR;
ADsAssert( (pPropArray != NULL) && (pNtObjects != NULL) );
ADsAssert(pPropArray->pUmiValue != NULL);
for(ulIndex = 0; ulIndex < ulNumValues; ulIndex++)
{
pSysTime = &(pPropArray->pUmiValue->sysTimeValue[ulIndex]);
hr = ConvertSystemTimeToUTCTime(pSysTime, &UTCTime);
BAIL_ON_FAILURE(hr);
pNtObjects[ulIndex].NTType = NT_SYNTAX_ID_DATE;
pNtObjects[ulIndex].NTValue.dwValue =
UTCTime.wHour*60 + UTCTime.wMinute;
}
RRETURN(UMI_S_NO_ERROR);
error:
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: ConvertSystemTimeToUTCFileTime
//
// Synopsis: Converts a system time structure containing a local time to a
// file time structure containing UTC time.
//
// Arguments:
//
// pLocalTime Pointer to local time
// pUTCTime Returns UTC file time
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise.
//
// Modifies: *pUTCFileTime to contain the UTC file time.
//
//----------------------------------------------------------------------------
HRESULT ConvertSystemTimeToUTCFileTime(
SYSTEMTIME *pLocalTime,
FILETIME *pUTCFileTime
)
{
HRESULT hr = UMI_S_NO_ERROR;
FILETIME localft;
BOOL fRetVal;
ADsAssert( (pLocalTime != NULL) && (pUTCFileTime != NULL) );
fRetVal = SystemTimeToFileTime(pLocalTime, &localft);
if(!fRetVal)
BAIL_ON_FAILURE( hr = HRESULT_FROM_WIN32(GetLastError()) );
fRetVal = LocalFileTimeToFileTime(&localft, pUTCFileTime);
if(!fRetVal)
BAIL_ON_FAILURE( hr = HRESULT_FROM_WIN32(GetLastError()) );
RRETURN(UMI_S_NO_ERROR);
error:
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: UmiToDate70s
//
// Synopsis: Converts from UMI_PROPERTY structure to array of NT objects,
// each containing the number of seconds from 1970 to the date
// in UMI_PROPERTY. Again the input is local time, so it needs
// to be converted to UTC.
//
// Arguments:
//
// pPropArray Pointer to UMI_PROPERTY structure
// pNtObjects Array of NT objects that returns the values.
// ulNumValues Number of values stored in pPropArray
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise.
//
// Modifies: *pNtObject to return the converted value.
//
//----------------------------------------------------------------------------
HRESULT UmiToDate70s(
UMI_PROPERTY *pPropArray,
LPNTOBJECT pNtObjects,
ULONG ulNumValues
)
{
ULONG ulIndex = 0;
SYSTEMTIME *pSysTime;
FILETIME UTCFileTime;
HRESULT hr = UMI_S_NO_ERROR;
LARGE_INTEGER tmpTime;
DWORD dwSeconds1970 = 0;
ADsAssert( (pPropArray != NULL) && (pNtObjects != NULL) );
ADsAssert(pPropArray->pUmiValue != NULL);
for(ulIndex = 0; ulIndex < ulNumValues; ulIndex++)
{
pSysTime = &(pPropArray->pUmiValue->sysTimeValue[ulIndex]);
hr = ConvertSystemTimeToUTCFileTime(pSysTime, &UTCFileTime);
BAIL_ON_FAILURE(hr);
tmpTime.LowPart = UTCFileTime.dwLowDateTime;
tmpTime.HighPart = UTCFileTime.dwHighDateTime;
RtlTimeToSecondsSince1970(&tmpTime, (ULONG *) (&dwSeconds1970) );
pNtObjects[ulIndex].NTType = NT_SYNTAX_ID_DATE_1970;
pNtObjects[ulIndex].NTValue.dwSeconds1970 = dwSeconds1970;
}
RRETURN(UMI_S_NO_ERROR);
error:
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: UmiToLPWSTRs
//
// Synopsis: Converts from UMI_PROPERTY structure to array of NT objects,
// each containing a string.
//
// Arguments:
//
// pPropArray Pointer to UMI_PROPERTY structure
// pNtObjects Array of NT objects that returns the values.
// ulNumValues Number of values stored in pPropArray
// dwSyntaxId Syntax of the property. There are different syntaxes for
// strings - Delimited_Strings, Nulled_Strings etc.
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise.
//
// Modifies: *pNtObject to return the converted value.
//
//----------------------------------------------------------------------------
HRESULT UmiToLPWSTRs(
UMI_PROPERTY *pPropArray,
LPNTOBJECT pNtObjects,
ULONG ulNumValues,
DWORD dwSyntaxId
)
{
ULONG ulIndex = 0, i = 0;
LPWSTR pszStr = NULL;
HRESULT hr = UMI_S_NO_ERROR;
ADsAssert( (pPropArray != NULL) && (pNtObjects != NULL) );
ADsAssert(pPropArray->pUmiValue != NULL);
for(ulIndex = 0; ulIndex < ulNumValues; ulIndex++)
{
pszStr = pPropArray->pUmiValue->pszStrValue[ulIndex];
pNtObjects[ulIndex].NTType = dwSyntaxId;
if(pszStr != NULL) {
pNtObjects[ulIndex].NTValue.pszValue = AllocADsStr(pszStr);
if(NULL == pNtObjects[ulIndex].NTValue.pszValue)
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
}
else
pNtObjects[ulIndex].NTValue.pszValue = NULL;
}
RRETURN(UMI_S_NO_ERROR);
error:
for(i = 0; i < ulIndex; i++)
if(pNtObjects[i].NTValue.pszValue != NULL)
FreeADsStr(pNtObjects[i].NTValue.pszValue);
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: UmiToOctetStrings
//
// Synopsis: Converts from UMI_PROPERTY structure to array of NT objects,
// each containing an octet string.
//
// Arguments:
//
// pPropArray Pointer to UMI_PROPERTY structure
// pNtObjects Array of NT objects that returns the values.
// ulNumValues Number of values stored in pPropArray
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise.
//
// Modifies: *pNtObject to return the converted value.
//
//----------------------------------------------------------------------------
HRESULT UmiToOctetStrings(
UMI_PROPERTY *pPropArray,
LPNTOBJECT pNtObjects,
ULONG ulNumValues
)
{
ULONG ulIndex = 0, i = 0;
UMI_OCTET_STRING *pUmiOctetStr;
HRESULT hr = UMI_S_NO_ERROR;
ADsAssert( (pPropArray != NULL) && (pNtObjects != NULL) );
ADsAssert(pPropArray->pUmiValue != NULL);
for(ulIndex = 0; ulIndex < ulNumValues; ulIndex++)
{
pUmiOctetStr = &(pPropArray->pUmiValue->octetStr[ulIndex]);
pNtObjects[ulIndex].NTType = NT_SYNTAX_ID_OCTETSTRING;
pNtObjects[ulIndex].NTValue.octetstring.pByte =
(BYTE *) AllocADsMem(pUmiOctetStr->uLength);
if(NULL == pNtObjects[ulIndex].NTValue.octetstring.pByte)
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
memcpy(pNtObjects[ulIndex].NTValue.octetstring.pByte,
pUmiOctetStr->lpValue, pUmiOctetStr->uLength);
pNtObjects[ulIndex].NTValue.octetstring.dwSize = pUmiOctetStr->uLength;
}
RRETURN(UMI_S_NO_ERROR);
error:
for(i = 0; i < ulIndex; i++)
if(pNtObjects[i].NTValue.octetstring.pByte != NULL)
FreeADsMem(pNtObjects[i].NTValue.octetstring.pByte);
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: UmiToEncryptedLPWSTRs
//
// Synopsis: Converts from UMI_PROPERTY structure to array of NT objects,
// each containing an encrypted string. Used so that passwords
// are not stored in cleartext.
//
// Arguments:
//
// pPropArray Pointer to UMI_PROPERTY structure
// pNtObjects Array of NT objects that returns the values.
// ulNumValues Number of values stored in pPropArray
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise.
//
// Modifies: *pNtObject to return the converted value.
//
//----------------------------------------------------------------------------
HRESULT UmiToEncryptedLPWSTRs(
UMI_PROPERTY *pPropArray,
LPNTOBJECT pNtObjects,
ULONG ulNumValues
)
{
ULONG ulIndex = 0, i = 0;
LPWSTR pszStr = NULL;
HRESULT hr = UMI_S_NO_ERROR;
UNICODE_STRING Password;
UCHAR Seed = UMI_ENCODE_SEED3;
ADsAssert( (pPropArray != NULL) && (pNtObjects != NULL) );
ADsAssert(pPropArray->pUmiValue != NULL);
for(ulIndex = 0; ulIndex < ulNumValues; ulIndex++)
{
pszStr = pPropArray->pUmiValue->pszStrValue[ulIndex];
pNtObjects[ulIndex].NTType = NT_SYNTAX_ID_EncryptedString;
if(pszStr != NULL) {
pNtObjects[ulIndex].NTValue.pszValue = AllocADsStr(pszStr);
if(NULL == pNtObjects[ulIndex].NTValue.pszValue)
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
RtlInitUnicodeString(&Password,
pNtObjects[ulIndex].NTValue.pszValue);
RtlRunEncodeUnicodeString(&Seed, &Password);
}
else
pNtObjects[ulIndex].NTValue.pszValue = NULL;
}
RRETURN(UMI_S_NO_ERROR);
error:
for(i = 0; i < ulIndex; i++)
if(pNtObjects[i].NTValue.pszValue != NULL)
FreeADsStr(pNtObjects[i].NTValue.pszValue);
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: UmiToWinNTType
//
// Synopsis: Converts from UMI_PROPERTY structure to NT objects that can be
// stored in the cache.
//
// Arguments:
//
// dwSyntaxId Syntax of property
// pPropArray Pointer to UMI_PROPERTY structure
// ppNtObjects Returns a pointer to an NT object that can be stored in the
// cache.
//
// Returns: UMI_S_NO_ERROR if successful. Error code otherwise.
//
// Modifies: *ppNtObjects to return a pointer to NT object
//
//----------------------------------------------------------------------------
HRESULT UmiToWinNTType(
DWORD dwSyntaxId,
UMI_PROPERTY *pPropArray,
LPNTOBJECT *ppNtObjects
)
{
ULONG ulNumValues = 0;
HRESULT hr = UMI_S_NO_ERROR;
LPNTOBJECT pNtObjects = NULL;
ADsAssert((pPropArray != NULL) && (ppNtObjects != NULL));
*ppNtObjects = NULL;
ulNumValues = pPropArray->uCount;
pNtObjects = (LPNTOBJECT) AllocADsMem(ulNumValues * sizeof(NTOBJECT));
if(NULL == pNtObjects)
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
switch(dwSyntaxId) {
case NT_SYNTAX_ID_BOOL:
if(pPropArray->uType != UMI_TYPE_BOOL)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToBooleans(pPropArray, pNtObjects, ulNumValues);
BAIL_ON_FAILURE(hr);
break;
case NT_SYNTAX_ID_SYSTEMTIME:
if(pPropArray->uType != UMI_TYPE_SYSTEMTIME)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToSystemTimes(pPropArray, pNtObjects, ulNumValues);
BAIL_ON_FAILURE(hr);
break;
case NT_SYNTAX_ID_DWORD:
if(pPropArray->uType != UMI_TYPE_I4)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToDwords(pPropArray, pNtObjects, ulNumValues);
BAIL_ON_FAILURE(hr);
break;
case NT_SYNTAX_ID_DATE:
if(pPropArray->uType != UMI_TYPE_SYSTEMTIME)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToDates(pPropArray, pNtObjects, ulNumValues);
BAIL_ON_FAILURE(hr);
break;
case NT_SYNTAX_ID_DATE_1970:
if(pPropArray->uType != UMI_TYPE_SYSTEMTIME)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToDate70s(pPropArray, pNtObjects, ulNumValues);
BAIL_ON_FAILURE(hr);
break;
case NT_SYNTAX_ID_LPTSTR:
if(pPropArray->uType != UMI_TYPE_LPWSTR)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToLPWSTRs(pPropArray, pNtObjects, ulNumValues,
NT_SYNTAX_ID_LPTSTR);
BAIL_ON_FAILURE(hr);
break;
case NT_SYNTAX_ID_DelimitedString:
if(pPropArray->uType != UMI_TYPE_LPWSTR)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToLPWSTRs(pPropArray, pNtObjects, ulNumValues,
NT_SYNTAX_ID_DelimitedString);
BAIL_ON_FAILURE(hr);
break;
case NT_SYNTAX_ID_NulledString:
if(pPropArray->uType != UMI_TYPE_LPWSTR)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToLPWSTRs(pPropArray, pNtObjects, ulNumValues,
NT_SYNTAX_ID_NulledString);
BAIL_ON_FAILURE(hr);
break;
case NT_SYNTAX_ID_OCTETSTRING:
if(pPropArray->uType != UMI_TYPE_OCTETSTRING)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToOctetStrings(pPropArray, pNtObjects, ulNumValues);
BAIL_ON_FAILURE(hr);
break;
case NT_SYNTAX_ID_EncryptedString:
if(pPropArray->uType != UMI_TYPE_LPWSTR)
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
hr = UmiToEncryptedLPWSTRs(pPropArray, pNtObjects, ulNumValues);
BAIL_ON_FAILURE(hr);
break;
default:
BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
} // switch
*ppNtObjects = pNtObjects;
RRETURN(UMI_S_NO_ERROR);
error:
if(pNtObjects != NULL)
FreeADsMem(pNtObjects);
RRETURN(hr);
}