//---------------------------------------------------------------------------- // // Microsoft Active Directory 1.1 Sample Code // // Copyright (C) Microsoft Corporation, 1996 // // File: main.cxx // // Contents: Main for adsqry // // //---------------------------------------------------------------------------- #include "main.hxx" #define MAX_SIZE 10 #define USE_OPENROWSET 0 // // Globals representing the properties // DBPROPSET rgDBPropSet[MAX_SIZE], rgCmdPropSet[MAX_SIZE]; DBPROP rgDBProp[MAX_SIZE], rgCmdProp[MAX_SIZE]; ULONG cDBPropSet, cCmdPropSet, cDBProp, cCmdProp; LPWSTR pszCommandText; LPWSTR pszSortAttrList = NULL; #if USE_OPENROWSET LPWSTR pszTableName; #endif GUID rguidDialect = DBGUID_DEFAULT; DWORD cErr; int __cdecl main( int argc, char ** argv) { HRESULT hr; ULONG i; DBCOUNTITEM j; HROW * phRows; WCHAR pszErrorBuf[MAX_PATH], pszNameBuf[MAX_PATH]; DWORD dwError; OLECHAR * szColNames = NULL; DBCOLUMNINFO * prgColInfo = NULL; DBCOLUMNINFO * rgInfo = NULL; WCHAR * pStringBuffer = NULL; WCHAR * pColInfoBuffer = NULL; IMalloc * pIMalloc = NULL; IDBInitialize * pIDBInit = NULL; IDBCreateSession * pIDBCS = NULL; IDBCreateCommand * pIDBCreateCommand = NULL; ICommandText * pICommandText = NULL; ICommand * pICommand = NULL; IRowset * pIRowset = NULL; IAccessor * pAccessor = NULL; IColumnsInfo * pIColsInfo = NULL; DBORDINAL cCol, nAttrs; DBCOUNTITEM cRowsObtained; Data * pMyData = NULL; DBBINDSTATUS * pMyStatus = NULL; HACCESSOR myAccessor = NULL; ICommandProperties * pICommandProperties; IDBProperties * pIDBProperties; #if USE_OPENROWSET DBID tableId; IOpenRowset * pIOpenRowset; #endif hr = ProcessArgs(argc, argv); BAIL_ON_FAILURE(hr); hr = CoInitialize(NULL); if (FAILED(hr)) { printf("CoInitialize failed\n"); exit(1); } // // Instantiate a data source object for LDAP provider // hr = CoCreateInstance( CLSID_ADsDSOObject, 0, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void **)&pIDBInit ); if(FAILED(hr)) { printf("CoCreateInstance failed \n"); goto error; } // // Initialize the Data Source // hr = pIDBInit->Initialize(); if(FAILED(hr)) { printf("IDBIntialize::Initialize failed \n"); goto error; } if (cDBPropSet) { pIDBInit->QueryInterface( IID_IDBProperties, (void**) &pIDBProperties); if(FAILED(hr)) { printf("QueryInterface for IDBProperties failed \n"); goto error; } hr = pIDBProperties->SetProperties( cDBPropSet, rgDBPropSet); if(FAILED(hr)) { printf("IDBProperties->SetProperties failed \n"); goto error; } FREE_INTERFACE(pIDBProperties); } pIDBInit->QueryInterface( IID_IDBCreateSession, (void**) &pIDBCS); if(FAILED(hr)) { printf("QueryInterface for IDBCreateSession failed \n"); goto error; } FREE_INTERFACE(pIDBInit); #if USE_OPENROWSET // // Create a session returning a pointer to its IOpenRowset interface // hr = pIDBCS->CreateSession( NULL, IID_IOpenRowset, (LPUNKNOWN*) &pIOpenRowset ); if(FAILED(hr)) { printf("IDBCreateSession::CreateSession failed \n"); goto error; } tableId.eKind = DBKIND_NAME; tableId.uName.pwszName = pszTableName; hr = pIOpenRowset->OpenRowset( NULL, &tableId, NULL, IID_IRowset, 0, NULL, (LPUNKNOWN *)&pIRowset ); BAIL_ON_FAILURE (hr); FREE_INTERFACE(pIOpenRowset); FREE_STRING(pszTableName); #else // // Create a session returning a pointer to its CreateCommand interface // hr = pIDBCS->CreateSession( NULL, IID_IDBCreateCommand, (LPUNKNOWN*) &pIDBCreateCommand ); if(FAILED(hr)) { printf("IDBCreateSession::CreateSession failed \n"); goto error; } FREE_INTERFACE(pIDBCS); // // // Create a command from the session object // hr = pIDBCreateCommand->CreateCommand( NULL, IID_ICommandText, (LPUNKNOWN*) &pICommandText ); if(FAILED(hr)) { printf(" IDBCreateCommand::CreateCommand failed\n"); goto error; } FREE_INTERFACE(pIDBCreateCommand); // // Set the CommandText for the Query // hr = pICommandText->SetCommandText( rguidDialect, pszCommandText ); if(FAILED(hr)) { printf("ICommandText::SetCommandText failed \n"); goto error; } if (cCmdPropSet) { hr = pICommandText->QueryInterface( IID_ICommandProperties, (void**) &pICommandProperties); if(FAILED(hr)) { printf("QueryInterface for ICommandProperties failed \n"); goto error; } hr = pICommandProperties->SetProperties( cCmdPropSet, rgCmdPropSet); if(FAILED(hr)) { printf("ICommandProperties:;SetProperties failed \n"); goto error; } FREE_INTERFACE(pICommandProperties); } hr = pICommandText->QueryInterface( IID_ICommand, (void**) &pICommand); if(FAILED(hr)) { printf("QueryInterface for ICommand failed \n"); goto error; } FREE_INTERFACE(pICommandText); // // Do the Query and get back a rowset // hr = pICommand->Execute( NULL, IID_IRowset, NULL, NULL, (LPUNKNOWN *)&pIRowset ); if(FAILED(hr)) { printf("ICommand::Execute failed \n"); goto error; } FREE_INTERFACE(pICommand); #endif hr = pIRowset->QueryInterface( IID_IColumnsInfo, (void**) &pIColsInfo ); if(FAILED(hr)) { printf("QueryInterface for IColumnsInfo failed \n"); goto error; } hr = pIColsInfo->GetColumnInfo( &cCol, &prgColInfo, &szColNames ); if(FAILED(hr)) { printf("IColumnsInfo::GetColumnInfo failed \n"); goto error; } // // The no. of attributes is one less than the no. of columns because of // the Bookmark column // nAttrs = cCol - 1; pMyStatus = (DBBINDSTATUS *) LocalAlloc( LPTR, sizeof(DBBINDSTATUS) * nAttrs ); BAIL_ON_NULL(pMyStatus); hr = CreateAccessorHelper( pIRowset, nAttrs, prgColInfo, &myAccessor, pMyStatus ); if(FAILED(hr)) { printf("CreateAccessorHelper failed \n"); goto error; } pMyData = (Data *) LocalAlloc( LPTR, sizeof(Data) * nAttrs ); if(!pMyData) { hr = E_OUTOFMEMORY; goto error; } // // Get the rows; 256 at a time // phRows = NULL; hr = pIRowset->GetNextRows( NULL, 0, 256, &cRowsObtained, &phRows ); if(FAILED(hr)) { printf("IRowset::GetNextRows failed \n"); goto error; } j = cRowsObtained; while (cRowsObtained) { for (i = 0; i < cRowsObtained; i++) { // // Get the data from each row // hr = pIRowset->GetData( phRows[i], myAccessor, (void*)pMyData ); if(FAILED(hr)) { printf("IRowset::GetData failed \n"); goto error; } PrintData(pMyData, nAttrs, prgColInfo); } pIRowset->ReleaseRows( cRowsObtained, phRows, NULL, NULL, NULL ); // // Get the next 256 rows // hr = pIRowset->GetNextRows( NULL, 0, 256, &cRowsObtained, &phRows ); if(FAILED(hr)) { printf("IRowset::GetNextRows failed \n"); goto error; } j+=cRowsObtained; } printf("Rows printed = %d\n", j); FREE_STRING(pszCommandText); hr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); // // Nothing much we can do at this point if this failed. // if (FAILED(hr)) { CoUninitialize(); exit(0); } IMALLOC_FREE(pIMalloc, prgColInfo); IMALLOC_FREE(pIMalloc, szColNames); FREE_INTERFACE(pIMalloc); FREE_INTERFACE(pAccessor); FREE_INTERFACE(pIColsInfo); FREE_INTERFACE(pIRowset); LOCAL_FREE(pMyStatus); LOCAL_FREE(pMyData); // // Uninitialize OLE. // CoUninitialize(); exit(0); error: CoGetMalloc(MEMCTX_TASK, &pIMalloc); IMALLOC_FREE(pIMalloc, prgColInfo); IMALLOC_FREE(pIMalloc, szColNames); FREE_STRING(pszCommandText); FREE_INTERFACE(pIMalloc); FREE_INTERFACE(pIDBInit); FREE_INTERFACE(pIDBCS); FREE_INTERFACE(pIDBCreateCommand); FREE_INTERFACE(pICommandText); FREE_INTERFACE(pICommand); FREE_INTERFACE(pIRowset); FREE_INTERFACE(pIColsInfo); FREE_INTERFACE(pAccessor); LOCAL_FREE(pMyStatus); LOCAL_FREE(pMyData); printf("Errors stopped the Query; hr = %x", hr); if(hr == ERROR_EXTENDED_ERROR) { hr = ADsGetLastError( &dwError, pszErrorBuf, MAX_PATH, pszNameBuf, MAX_PATH ); } if(SUCCEEDED(hr)) { wprintf(L"Error in %s; %s\n", pszNameBuf, pszErrorBuf); } exit(1); return(0); } //+--------------------------------------------------------------------------- // // Function: ProcessArgs // // Synopsis: // //---------------------------------------------------------------------------- HRESULT ProcessArgs( int argc, char * argv[] ) { argc--; int currArg = 1; LPWSTR pTemp = NULL; char *pszCurrPref = NULL, *pszCurrPrefValue = NULL; LPWSTR pszSearchBase = NULL, pszSearchFilter = NULL, pszAttrList = NULL; LPWSTR pszUserName = NULL, pszPassword = NULL; DWORD dwAuthFlags; cCmdProp = cDBProp = 0; while (argc) { if (argv[currArg][0] != '/' && argv[currArg][0] != '-') BAIL_ON_FAILURE (E_FAIL); switch (argv[currArg][1]) { case 'b': argc--; currArg++; if (argc <= 0) BAIL_ON_FAILURE (E_FAIL); pszSearchBase = AllocateUnicodeString(argv[currArg]); BAIL_ON_NULL(pszSearchBase); break; case 'f': argc--; currArg++; if (argc <= 0) BAIL_ON_FAILURE (E_FAIL); pszSearchFilter = AllocateUnicodeString(argv[currArg]); BAIL_ON_NULL(pszSearchFilter); break; case 'd': argc--; currArg++; if (argc <= 0) BAIL_ON_FAILURE (E_FAIL); if (!_stricmp(argv[currArg], "sql")) rguidDialect = DBGUID_SQL; else if (!_stricmp(argv[currArg], "ldap")) rguidDialect = DBGUID_LDAPDialect; else if (!_stricmp(argv[currArg], "default")) rguidDialect = DBGUID_DEFAULT; else BAIL_ON_FAILURE (E_FAIL); break; case 'a': argc--; currArg++; if (argc <= 0) BAIL_ON_FAILURE (E_FAIL); pszAttrList = AllocateUnicodeString(argv[currArg]); BAIL_ON_NULL(pszAttrList); break; case 'u': argc--; currArg++; if (argc <= 0) BAIL_ON_FAILURE (E_FAIL); pszUserName = AllocateUnicodeString(argv[currArg]); BAIL_ON_NULL(pszUserName); argc--; currArg++; if (argc <= 0) BAIL_ON_FAILURE (E_FAIL); pszPassword = AllocateUnicodeString(argv[currArg]); BAIL_ON_NULL(pszPassword); rgDBProp[cDBProp].dwPropertyID = DBPROP_AUTH_USERID; rgDBProp[cDBProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgDBProp[cDBProp].vValue.vt = VT_BSTR; V_BSTR (&rgDBProp[cDBProp].vValue) = SysAllocString(pszUserName); cDBProp++; rgDBProp[cDBProp].dwPropertyID = DBPROP_AUTH_PASSWORD; rgDBProp[cDBProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgDBProp[cDBProp].vValue.vt = VT_BSTR; V_BSTR (&rgDBProp[cDBProp].vValue) = SysAllocString(pszPassword); cDBProp++; break; case 'p': argc--; currArg++; if (argc <= 0) BAIL_ON_FAILURE (E_FAIL); pszCurrPref = strtok(argv[currArg], "="); pszCurrPrefValue = strtok(NULL, "="); if (!pszCurrPref || !pszCurrPrefValue) BAIL_ON_FAILURE(E_FAIL); if (!_stricmp(pszCurrPref, "asynchronous")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_ASYNCHRONOUS; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_BOOL; if (!_stricmp(pszCurrPrefValue, "yes" )) V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_TRUE; else if (!_stricmp(pszCurrPrefValue, "no" )) V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_FALSE; else BAIL_ON_FAILURE(E_FAIL); cCmdProp++; } else if (!_stricmp(pszCurrPref, "attrTypesOnly")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_ATTRIBTYPES_ONLY; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_BOOL; if (!_stricmp(pszCurrPrefValue, "yes" )) V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_TRUE; else if (!_stricmp(pszCurrPrefValue, "no" )) V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_FALSE; else BAIL_ON_FAILURE(E_FAIL); cCmdProp++; } else if (!_stricmp(pszCurrPref, "SecureAuth")) { if (!_stricmp(pszCurrPrefValue, "yes" )) dwAuthFlags |= ADS_SECURE_AUTHENTICATION; else if (!_stricmp(pszCurrPrefValue, "no" )) dwAuthFlags &= ~ADS_SECURE_AUTHENTICATION; else BAIL_ON_FAILURE(E_FAIL); rgDBProp[cDBProp].dwPropertyID = DBPROP_AUTH_ENCRYPT_PASSWORD; rgDBProp[cDBProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgDBProp[cDBProp].vValue.vt = VT_BSTR; V_BSTR (&rgDBProp[cDBProp].vValue) = SysAllocString(pszPassword); cDBProp++; } else if (!_stricmp(pszCurrPref, "derefAliases")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_DEREF_ALIASES; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_BOOL; if (!_stricmp(pszCurrPrefValue, "yes" )) V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_TRUE; else if (!_stricmp(pszCurrPrefValue, "no" )) V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_FALSE; else BAIL_ON_FAILURE(E_FAIL); cCmdProp++; } else if (!_stricmp(pszCurrPref, "timeOut")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_TIMEOUT; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_I4; V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue); cCmdProp++; } else if (!_stricmp(pszCurrPref, "timeLimit")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_TIME_LIMIT; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_I4; V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue); cCmdProp++; } else if (!_stricmp(pszCurrPref, "sizeLimit")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_SIZE_LIMIT; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_I4; V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue); cCmdProp++; } else if (!_stricmp(pszCurrPref, "PageSize")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_PAGESIZE; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_I4; V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue); cCmdProp++; } else if (!_stricmp(pszCurrPref, "PagedTimeLimit")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_PAGED_TIME_LIMIT; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_I4; V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue); cCmdProp++; } else if (!_stricmp(pszCurrPref, "SearchScope")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_SEARCH_SCOPE; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_I4; if (!_stricmp(pszCurrPrefValue, "Base" )) V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_SCOPE_BASE; else if (!_stricmp(pszCurrPrefValue, "OneLevel" )) V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_SCOPE_ONELEVEL; else if (!_stricmp(pszCurrPrefValue, "Subtree" )) V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_SCOPE_SUBTREE; else BAIL_ON_FAILURE(E_FAIL); cCmdProp++; } else if (!_stricmp(pszCurrPref, "ChaseReferrals")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_CHASE_REFERRALS; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_I4; if (!_stricmp(pszCurrPrefValue, "always" )) V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_CHASE_REFERRALS_ALWAYS; else if (!_stricmp(pszCurrPrefValue, "never" )) V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_CHASE_REFERRALS_NEVER; else if (!_stricmp(pszCurrPrefValue, "external" )) V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_CHASE_REFERRALS_EXTERNAL; else if (!_stricmp(pszCurrPrefValue, "subordinate" )) V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_CHASE_REFERRALS_SUBORDINATE; else BAIL_ON_FAILURE(E_FAIL); cCmdProp++; } else if (!_stricmp(pszCurrPref, "cacheResults")) { rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_CACHE_RESULTS; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_BOOL; if (!_stricmp(pszCurrPrefValue, "yes" )) V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_TRUE; else if (!_stricmp(pszCurrPrefValue, "no" )) V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_FALSE; else BAIL_ON_FAILURE(E_FAIL); cCmdProp++; } else if (!_stricmp(pszCurrPref, "sortOn")) { pszSortAttrList = AllocateUnicodeString(pszCurrPrefValue); } else BAIL_ON_FAILURE(E_FAIL); break; default: BAIL_ON_FAILURE(E_FAIL); } argc--; currArg++; } // // Check for Mandatory arguments; // if (!pszSearchBase || !pszSearchFilter || !pszAttrList) BAIL_ON_FAILURE(E_FAIL); #if USE_OPENROWSET pszTableName = AllocADsStr( pszSearchBase ); BAIL_ON_NULL(E_FAIL); #endif if (IsEqualGUID(rguidDialect, DBGUID_SQL) ) { // if sorting is specified, add to the command text itself // DWORD sortAttrLen = pszSortAttrList ? wcslen(L" ORDER BY ") + wcslen(pszSortAttrList) : 0; pszCommandText = (LPWSTR) AllocADsMem( (wcslen(pszSearchBase) + wcslen(pszSearchFilter) + wcslen(pszAttrList) + wcslen(L"''") + wcslen(L"SELECT ") + wcslen(L" FROM ") + wcslen(L" WHERE ") + sortAttrLen + 1) * sizeof(WCHAR) ); BAIL_ON_NULL(E_FAIL); wcscpy(pszCommandText, L"SELECT "); wcscat(pszCommandText, pszAttrList); wcscat(pszCommandText, L" FROM '"); wcscat(pszCommandText, pszSearchBase); wcscat(pszCommandText, L"' WHERE "); wcscat(pszCommandText, pszSearchFilter); if (pszSortAttrList) { wcscat(pszCommandText, L" ORDER BY "); wcscat(pszCommandText, pszSortAttrList); } } else { pszCommandText = (LPWSTR) AllocADsMem( (wcslen(pszSearchBase) + wcslen(pszSearchFilter) + wcslen(pszAttrList) + 5) * sizeof(WCHAR) ); BAIL_ON_NULL(E_FAIL); wcscpy(pszCommandText, L"<"); wcscat(pszCommandText, pszSearchBase); wcscat(pszCommandText, L">;"); wcscat(pszCommandText, pszSearchFilter); wcscat(pszCommandText, L";"); wcscat(pszCommandText, pszAttrList); if (pszSortAttrList) { // if sorting is specified, add as a command property rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_SORT_ON; rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED; rgCmdProp[cCmdProp].vValue.vt = VT_BSTR; V_BSTR (&rgCmdProp[cCmdProp].vValue) = AllocateUnicodeString(pszCurrPrefValue); cCmdProp++; } } if (cDBProp > 0) { cDBPropSet = 1; rgDBPropSet[0].rgProperties = rgDBProp; rgDBPropSet[0].cProperties = cDBProp; rgDBPropSet[0].guidPropertySet = DBPROPSET_DBINIT; } if (cCmdProp > 0) { cCmdPropSet = 1; rgCmdPropSet[0].rgProperties = rgCmdProp; rgCmdPropSet[0].cProperties = cCmdProp; rgCmdPropSet[0].guidPropertySet = DBPROPSET_ADSISEARCH; } FreeUnicodeString(pszSearchBase) ; FreeUnicodeString(pszSearchFilter) ; FreeUnicodeString(pszAttrList) ; return (S_OK); error: FreeUnicodeString(pszSearchBase) ; FreeUnicodeString(pszSearchFilter) ; FreeUnicodeString(pszAttrList) ; PrintUsage(); return E_FAIL; }