MAIN.CXX

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

GUID rguidDialect = DBGUID_DEFAULT;

DWORD cErr;

int __cdecl
main( int argc, char ** argv)
{

HRESULT hr;
ULONG i, 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;
ULONG cCol, cRowsObtained, nAttrs;

Data * pMyData = NULL;
DBBINDSTATUS * pMyStatus = NULL;
HACCESSOR myAccessor = NULL;

ICommandProperties * pICommandProperties;
IDBProperties * pIDBProperties;


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);

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

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);

CoGetMalloc(MEMCTX_TASK, &pIMalloc);
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
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 (IsEqualGUID(rguidDialect, DBGUID_SQL) ) {

pszCommandText = (LPWSTR) AllocADsMem(
(wcslen(pszSearchBase) +
wcslen(pszSearchFilter) +
wcslen(pszAttrList) +
wcslen(L"''") +
wcslen(L"SELECT ") +
wcslen(L" FROM ") +
wcslen(L" WHERE ") +
1) * sizeof(WCHAR)
);
BAIL_ON_NULL(E_FAIL);

wsprintf(pszCommandText,
L"SELECT %s FROM '%s' WHERE %s",
pszAttrList,
pszSearchBase,
pszSearchFilter
);

} else {

pszCommandText = (LPWSTR) AllocADsMem(
(wcslen(pszSearchBase) +
wcslen(pszSearchFilter) +
wcslen(pszAttrList) +
5) * sizeof(WCHAR)
);
BAIL_ON_NULL(E_FAIL);

wsprintf(pszCommandText,
L"<%s>;%s;%s",
pszSearchBase,
pszSearchFilter,
pszAttrList
);

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

}