|
|
//---------------------------------------------------------------------------
//
// 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; }
|