313 lines
6 KiB
C++
313 lines
6 KiB
C++
|
//---------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// 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") ;
|
|||
|
}
|
|||
|
|
|||
|
|