//---------------------------------------------------------------------------
//
// Microsoft Active Directory 1.0 Sample Code
//
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: util.cxx
//
// Contents: Ansi to Unicode conversions and misc helper functions
//
//----------------------------------------------------------------------------
#include "main.hxx"
//
// Local functions
//
int
AnsiToUnicodeString(
LPSTR pAnsi,
LPWSTR pUnicode,
DWORD StringLength
)
{
int iReturn;
if( StringLength == 0 )
StringLength = strlen( pAnsi );
iReturn = MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED,
pAnsi,
StringLength + 1,
pUnicode,
StringLength + 1 );
//
// Ensure NULL termination.
//
pUnicode[StringLength] = 0;
return iReturn;
}
int
UnicodeToAnsiString(
LPWSTR pUnicode,
LPSTR pAnsi,
DWORD StringLength
)
{
LPSTR pTempBuf = NULL;
INT rc = 0;
if( StringLength == 0 ) {
//
// StringLength is just the
// number of characters in the string
//
StringLength = wcslen( pUnicode );
}
//
// WideCharToMultiByte doesn't NULL terminate if we're copying
// just part of the string, so terminate here.
//
pUnicode[StringLength] = 0;
//
// Include one for the NULL
//
StringLength++;
//
// Unfortunately, WideCharToMultiByte doesn't do conversion in place,
// so allocate a temporary buffer, which we can then copy:
//
if( pAnsi == (LPSTR)pUnicode )
{
pTempBuf = (LPSTR)LocalAlloc( LPTR, StringLength );
pAnsi = pTempBuf;
}
if( pAnsi )
{
rc = WideCharToMultiByte( CP_ACP,
0,
pUnicode,
StringLength,
pAnsi,
StringLength,
NULL,
NULL );
}
/* If pTempBuf is non-null, we must copy the resulting string
* so that it looks as if we did it in place:
*/
if( pTempBuf && ( rc > 0 ) )
{
pAnsi = (LPSTR)pUnicode;
strcpy( pAnsi, pTempBuf );
LocalFree( pTempBuf );
}
return rc;
}
LPWSTR
AllocateUnicodeString(
LPSTR pAnsiString
)
{
LPWSTR pUnicodeString = NULL;
if (!pAnsiString)
return NULL;
pUnicodeString = (LPWSTR)LocalAlloc(
LPTR,
strlen(pAnsiString)*sizeof(WCHAR) + sizeof(WCHAR)
);
if (pUnicodeString) {
AnsiToUnicodeString(
pAnsiString,
pUnicodeString,
0
);
}
return pUnicodeString;
}
void
FreeUnicodeString(
LPWSTR pUnicodeString
)
{
LocalFree(pUnicodeString);
return;
}
//
// Misc helper functions for displaying data.
//
HRESULT
PrintVariant(
VARIANT varPropData
)
{
HRESULT hr;
BSTR bstrValue;
switch (varPropData.vt) {
case VT_I4:
printf("%d", varPropData.lVal);
break;
case VT_BSTR:
printf("%S", varPropData.bstrVal);
break;
case VT_BOOL:
printf("%d", V_BOOL(&varPropData));
break;
case (VT_ARRAY | VT_VARIANT):
PrintVariantArray(varPropData);
break;
case VT_DATE:
hr = VarBstrFromDate(
varPropData.date,
LOCALE_SYSTEM_DEFAULT,
LOCALE_NOUSEROVERRIDE,
&bstrValue
);
printf("%S", bstrValue);
break;
default:
printf("Data type is %d\n", varPropData.vt);
break;
}
printf("\n");
return(S_OK);
}
HRESULT
PrintVariantArray(
VARIANT var
)
{
LONG dwSLBound = 0;
LONG dwSUBound = 0;
VARIANT v;
LONG i;
HRESULT hr = S_OK;
if(!((V_VT(&var) & VT_VARIANT) && V_ISARRAY(&var))) {
return(E_FAIL);
}
//
// Check that there is only one dimension in this array
//
if ((V_ARRAY(&var))->cDims != 1) {
hr = E_FAIL;
BAIL_ON_FAILURE(hr);
}
//
// Check that there is atleast one element in this array
//
if ((V_ARRAY(&var))->rgsabound[0].cElements == 0){
hr = E_FAIL;
BAIL_ON_FAILURE(hr);
}
//
// We know that this is a valid single dimension array
//
hr = SafeArrayGetLBound(V_ARRAY(&var),
1,
(long FAR *)&dwSLBound
);
BAIL_ON_FAILURE(hr);
hr = SafeArrayGetUBound(V_ARRAY(&var),
1,
(long FAR *)&dwSUBound
);
BAIL_ON_FAILURE(hr);
for (i = dwSLBound; i <= dwSUBound; i++) {
VariantInit(&v);
hr = SafeArrayGetElement(V_ARRAY(&var),
(long FAR *)&i,
&v
);
if (FAILED(hr)) {
continue;
}
if (i < dwSUBound) {
printf("%S, ", v.bstrVal);
} else {
printf("%S", v.bstrVal);
}
}
return(S_OK);
error:
return(hr);
}
HRESULT
PrintProperty(
BSTR bstrPropName,
HRESULT hRetVal,
VARIANT varPropData
)
{
HRESULT hr = S_OK;
switch (hRetVal) {
case 0:
printf("%-32S: ", bstrPropName);
PrintVariant(varPropData);
break;
case E_ADS_CANT_CONVERT_DATATYPE:
printf("%-32S: ", bstrPropName);
printf("<Data could not be converted for display>\n");
break;
default:
printf("%-32S: ", bstrPropName);
printf("<Data not available>\n");
break;
}
return(hr);
}
void
PrintUsage(
void
)
{
printf("usage: adscmd [list|dump] <ADsPath>\n") ;
}