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

497 lines
14 KiB
C++

//---------------------------------------------------------------------------
//
// Microsoft Active Directory 1.1 Sample Code
//
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: util.cxx
//
// Contents: Ansi to Unicode conversions and misc helper functions
//
//----------------------------------------------------------------------------//------------------------------------------------------------------------------
#include "main.hxx"
void
PrintUsage(
void
)
{
printf("\nUsage: adsqry /b <baseObject> /f <search_filter> /a <attrlist> [/p <preference=value>] ");
printf(" [/u <UserName> <Password>] /d <dialect> \n");
printf("\n where:\n" );
printf(" baseObject = ADsPath of the base of the search\n");
printf(" search_filter = search filter string in LDAP format\n" );
printf(" attrlist = list of the attributes to display\n" );
printf(" dialect is one of \"ldap\", \"sql\", or \"default\"\n");
printf(" preference could be one of:\n");
printf(" Asynchronous, AttrTypesOnly, DerefAliases, SizeLimit, TimeLimit, sortOn \n");
printf(" TimeOut, PageSize, SearchScope, CacheResults, SecureAuth and EncryptPassword\n");
printf(" value is yes/no for a Boolean and the respective integer for integers\n");
printf(" list of comma separated attributes for sortOn\n");
printf(" scope is one of \"Base\", \"OneLevel\", or \"Subtree\"\n");
printf("\nFor Example: adsqry /b \"LDAP://ntdsdc0/DC=COM/");
printf("DC=MICROSOFT/DC=NTDEV\" /f \"(objectClass=Group)\" /a \"ADsPath, name, description\" ");
printf(" /u \"CN=NTDEV,CN=Users,DC=NTDEV,DC=MICROSOFT,DC=COM,O=INTERNET\" \"NTDEV\" \n");
printf("\nFor Example: adsqry /b \"LDAP://ntdsdc0/DC=COM/");
printf("DC=MICROSOFT/DC=NTDEV\" /f \"objectClass='Group'\" /a \"ADsPath, name, description\" ");
printf(" /d sql /u \"CN=NTDEV,CN=Users,DC=NTDEV,DC=MICROSOFT,DC=COM,O=INTERNET\" \"NTDEV\" \n");
}
//
// Form the bindings array to specify the way the provider has to put the
// data in consumer's buffers; Create the Accessor from the bindings
//
HRESULT
CreateAccessorHelper(
IRowset *pIRowset,
DBORDINAL nAttrs,
DBCOLUMNINFO *prgColInfo,
HACCESSOR *phAccessor,
DBBINDSTATUS *pBindStatus
)
{
DBBINDING *prgBindings = NULL;
HRESULT hr;
ULONG i;
IAccessor *pIAccessor = NULL;
if(!phAccessor || !pBindStatus)
return(E_INVALIDARG);
prgBindings = (DBBINDING *) LocalAlloc(
LPTR,
sizeof(DBBINDING) * nAttrs
);
BAIL_ON_NULL(prgBindings);
//
// Set up rest of the attributes
//
for (i=0; i < nAttrs; i++) {
prgBindings[i].iOrdinal = i+1;
prgBindings[i].wType= prgColInfo[i+1].wType;
if (prgBindings[i].wType == DBTYPE_DATE || prgBindings[i].wType == DBTYPE_I8)
prgBindings[i].obValue = sizeof(Data)*i + offsetof(Data, obValue2);
else
prgBindings[i].obValue = sizeof(Data)*i + offsetof(Data, obValue);
prgBindings[i].obLength= sizeof(Data)*i + offsetof(Data, obLength);
prgBindings[i].obStatus= sizeof(Data)*i + offsetof(Data, status);
prgBindings[i].dwPart= DBPART_VALUE|DBPART_LENGTH|DBPART_STATUS;
if(prgBindings[i].wType & DBTYPE_BYREF)
prgBindings[i].dwMemOwner= DBMEMOWNER_PROVIDEROWNED;
else
prgBindings[i].dwMemOwner= DBMEMOWNER_CLIENTOWNED;
prgBindings[i].dwFlags= 0;
}
hr= pIRowset->QueryInterface(
IID_IAccessor,
(void**) &pIAccessor
);
BAIL_ON_FAILURE(hr);
//
// With the bindings create the accessor
//
hr = pIAccessor->CreateAccessor(
DBACCESSOR_ROWDATA,
nAttrs,
prgBindings,
0,
phAccessor,
pBindStatus
);
pIAccessor->Release();
LOCAL_FREE(prgBindings);
return(hr);
error:
LOCAL_FREE(prgBindings);
return(hr);
}
//
// Print the data depending on its type.
//
void
PrintData(
Data *prgData,
DBORDINAL nAttrs,
DBCOLUMNINFO *prgColInfo
)
{
ULONG i, j;
HRESULT hr;
for (i=0; i < nAttrs; i++) {
if(prgData[i].status == DBSTATUS_S_OK) {
switch(prgColInfo[i+1].wType) {
case DBTYPE_I4:
wprintf(
L"%s = %d \n",
prgColInfo[i+1].pwszName,
(DWORD_PTR) prgData[i].obValue
);
break;
case DBTYPE_I8:
wprintf(
L"%s = %I64d \n",
prgColInfo[i+1].pwszName,
*((__int64 *) &prgData[i].obValue2)
);
break;
case DBTYPE_BOOL:
wprintf(
L"%s = %s \n",
prgColInfo[i+1].pwszName,
*((VARIANT_BOOL *) &(prgData[i].obValue)) == VARIANT_TRUE ?
L"TRUE" : L"FALSE"
);
break;
case DBTYPE_STR | DBTYPE_BYREF:
wprintf(
L"%s = ",
prgColInfo[i+1].pwszName
);
printf(
"%s \n",
(char *)prgData[i].obValue
);
break;
case DBTYPE_BYTES | DBTYPE_BYREF:
wprintf(
L"%s = ",
prgColInfo[i+1].pwszName
);
for (j=0; j<prgData[i].obLength; j++) {
printf(
"%x",
((BYTE *)prgData[i].obValue)[j]
);
}
printf("\n");
break;
case DBTYPE_WSTR | DBTYPE_BYREF:
wprintf(
L"%s = %s \n",
prgColInfo[i+1].pwszName,
(WCHAR *) prgData[i].obValue
);
break;
case DBTYPE_DATE:
SYSTEMTIME UTCTime;
hr = VariantTimeToSystemTime(
prgData[i].obValue2,
&UTCTime);
BAIL_ON_FAILURE(hr);
wprintf(L"%s = %d %d %d",
prgColInfo[i+1].pwszName,
UTCTime.wYear,
UTCTime.wMonth,
UTCTime.wDay);
break;
case DBTYPE_VARIANT | DBTYPE_BYREF:
wprintf(
L"%s = ",
prgColInfo[i+1].pwszName
);
ULONG dwSLBound;
ULONG dwSUBound;
VARIANT *pVarArray;
VARIANT *pVariant;
pVarArray = NULL;
pVariant = (VARIANT*) prgData[i].obValue;
if (pVariant->vt == VT_DISPATCH) {
IDispatch *pDispatch = NULL;
IADsLargeInteger *pLargeInteger = NULL;
LARGE_INTEGER LargeInteger;
pDispatch = V_DISPATCH(pVariant);
hr = pDispatch->QueryInterface(
IID_IADsLargeInteger,
(void **)&pLargeInteger
);
BAIL_ON_FAILURE(hr);
hr = pLargeInteger->get_HighPart((LONG*)&LargeInteger.HighPart);
BAIL_ON_FAILURE(hr);
hr = pLargeInteger->get_LowPart((LONG*)&LargeInteger.LowPart);
BAIL_ON_FAILURE(hr);
wprintf(
L"High:%ld, low:%ld",
LargeInteger.HighPart,
LargeInteger.LowPart
);
break;
}
else {
if( !(pVariant->vt == (VT_ARRAY | VT_VARIANT)))
BAIL_ON_FAILURE(hr = E_FAIL);
hr = SafeArrayGetLBound(V_ARRAY(pVariant),
1,
(long FAR *) &dwSLBound );
BAIL_ON_FAILURE(hr);
hr = SafeArrayGetUBound(V_ARRAY(pVariant),
1,
(long FAR *) &dwSUBound );
BAIL_ON_FAILURE(hr);
hr = SafeArrayAccessData( V_ARRAY(pVariant),
(void **) &pVarArray );
BAIL_ON_FAILURE(hr);
for (j=dwSLBound; j<=dwSUBound; j++) {
switch((pVarArray[j]).vt) {
case VT_DATE:
SYSTEMTIME UTCTime;
hr = VariantTimeToSystemTime(
V_DATE(pVarArray+j),
&UTCTime
);
BAIL_ON_FAILURE(hr);
wprintf(L"%d %d %d #",
UTCTime.wYear,
UTCTime.wMonth,
UTCTime.wDay);
break;
case VT_BSTR:
wprintf(
L"%s # ",
V_BSTR(pVarArray+j)
);
break;
case VT_I4:
wprintf(
L"%d # ",
V_I4(pVarArray+j)
);
break;
case VT_BOOL:
wprintf(
L"%s # ",
V_BOOL(pVarArray+j) == VARIANT_TRUE ?
L"TRUE" : L"FALSE"
);
break;
#if 0
case VT_I8:
wprintf(
L"%I64d # ",
V_I8(pVarArray+j)
);
break;
#endif
default:
wprintf(
L"Unsupported # \n"
);
}
}
printf("\n");
SafeArrayUnaccessData( V_ARRAY(pVariant) );
break;
}
default:
wprintf(
L"Unsupported type for attribute %s\n",
prgColInfo[i+1].pwszName
);
break;
}
}
}
if(nAttrs != 0)
wprintf(L"\n");
return;
error:
wprintf(
L"Error in Printing data for %s\n",
prgColInfo[i+1].pwszName
);
return;
}
int
AnsiToUnicodeString(
LPSTR pAnsi,
LPWSTR pUnicode,
DWORD StringLength
)
{
int iReturn;
if( StringLength == NULL_TERMINATED )
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 == NULL_TERMINATED ) {
//
// 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,
NULL_TERMINATED
);
}
return pUnicodeString;
}
void
FreeUnicodeString(
LPWSTR pUnicodeString
)
{
if (!pUnicodeString)
return;
LocalFree(pUnicodeString);
return;
}