Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

846 lines
24 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Active Directory 1.1 Sample Code
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996
  6. //
  7. // File: main.cxx
  8. //
  9. // Contents: Main for adsqry
  10. //
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "main.hxx"
  14. #define MAX_SIZE 10
  15. #define USE_OPENROWSET 0
  16. //
  17. // Globals representing the properties
  18. //
  19. DBPROPSET rgDBPropSet[MAX_SIZE], rgCmdPropSet[MAX_SIZE];
  20. DBPROP rgDBProp[MAX_SIZE], rgCmdProp[MAX_SIZE];
  21. ULONG cDBPropSet, cCmdPropSet, cDBProp, cCmdProp;
  22. LPWSTR pszCommandText;
  23. LPWSTR pszSortAttrList = NULL;
  24. #if USE_OPENROWSET
  25. LPWSTR pszTableName;
  26. #endif
  27. GUID rguidDialect = DBGUID_DEFAULT;
  28. DWORD cErr;
  29. int __cdecl
  30. main( int argc, char ** argv)
  31. {
  32. HRESULT hr;
  33. ULONG i;
  34. DBCOUNTITEM j;
  35. HROW * phRows;
  36. WCHAR pszErrorBuf[MAX_PATH], pszNameBuf[MAX_PATH];
  37. DWORD dwError;
  38. OLECHAR * szColNames = NULL;
  39. DBCOLUMNINFO * prgColInfo = NULL;
  40. DBCOLUMNINFO * rgInfo = NULL;
  41. WCHAR * pStringBuffer = NULL;
  42. WCHAR * pColInfoBuffer = NULL;
  43. IMalloc * pIMalloc = NULL;
  44. IDBInitialize * pIDBInit = NULL;
  45. IDBCreateSession * pIDBCS = NULL;
  46. IDBCreateCommand * pIDBCreateCommand = NULL;
  47. ICommandText * pICommandText = NULL;
  48. ICommand * pICommand = NULL;
  49. IRowset * pIRowset = NULL;
  50. IAccessor * pAccessor = NULL;
  51. IColumnsInfo * pIColsInfo = NULL;
  52. DBORDINAL cCol, nAttrs;
  53. DBCOUNTITEM cRowsObtained;
  54. Data * pMyData = NULL;
  55. DBBINDSTATUS * pMyStatus = NULL;
  56. HACCESSOR myAccessor = NULL;
  57. ICommandProperties * pICommandProperties;
  58. IDBProperties * pIDBProperties;
  59. #if USE_OPENROWSET
  60. DBID tableId;
  61. IOpenRowset * pIOpenRowset;
  62. #endif
  63. hr = ProcessArgs(argc, argv);
  64. BAIL_ON_FAILURE(hr);
  65. hr = CoInitialize(NULL);
  66. if (FAILED(hr)) {
  67. printf("CoInitialize failed\n");
  68. exit(1);
  69. }
  70. //
  71. // Instantiate a data source object for LDAP provider
  72. //
  73. hr = CoCreateInstance(
  74. CLSID_ADsDSOObject,
  75. 0,
  76. CLSCTX_INPROC_SERVER,
  77. IID_IDBInitialize,
  78. (void **)&pIDBInit
  79. );
  80. if(FAILED(hr)) {
  81. printf("CoCreateInstance failed \n");
  82. goto error;
  83. }
  84. //
  85. // Initialize the Data Source
  86. //
  87. hr = pIDBInit->Initialize();
  88. if(FAILED(hr)) {
  89. printf("IDBIntialize::Initialize failed \n");
  90. goto error;
  91. }
  92. if (cDBPropSet) {
  93. pIDBInit->QueryInterface(
  94. IID_IDBProperties,
  95. (void**) &pIDBProperties);
  96. if(FAILED(hr)) {
  97. printf("QueryInterface for IDBProperties failed \n");
  98. goto error;
  99. }
  100. hr = pIDBProperties->SetProperties(
  101. cDBPropSet,
  102. rgDBPropSet);
  103. if(FAILED(hr)) {
  104. printf("IDBProperties->SetProperties failed \n");
  105. goto error;
  106. }
  107. FREE_INTERFACE(pIDBProperties);
  108. }
  109. pIDBInit->QueryInterface(
  110. IID_IDBCreateSession,
  111. (void**) &pIDBCS);
  112. if(FAILED(hr)) {
  113. printf("QueryInterface for IDBCreateSession failed \n");
  114. goto error;
  115. }
  116. FREE_INTERFACE(pIDBInit);
  117. #if USE_OPENROWSET
  118. //
  119. // Create a session returning a pointer to its IOpenRowset interface
  120. //
  121. hr = pIDBCS->CreateSession(
  122. NULL,
  123. IID_IOpenRowset,
  124. (LPUNKNOWN*) &pIOpenRowset
  125. );
  126. if(FAILED(hr)) {
  127. printf("IDBCreateSession::CreateSession failed \n");
  128. goto error;
  129. }
  130. tableId.eKind = DBKIND_NAME;
  131. tableId.uName.pwszName = pszTableName;
  132. hr = pIOpenRowset->OpenRowset(
  133. NULL,
  134. &tableId,
  135. NULL,
  136. IID_IRowset,
  137. 0,
  138. NULL,
  139. (LPUNKNOWN *)&pIRowset
  140. );
  141. BAIL_ON_FAILURE (hr);
  142. FREE_INTERFACE(pIOpenRowset);
  143. FREE_STRING(pszTableName);
  144. #else
  145. //
  146. // Create a session returning a pointer to its CreateCommand interface
  147. //
  148. hr = pIDBCS->CreateSession(
  149. NULL,
  150. IID_IDBCreateCommand,
  151. (LPUNKNOWN*) &pIDBCreateCommand
  152. );
  153. if(FAILED(hr)) {
  154. printf("IDBCreateSession::CreateSession failed \n");
  155. goto error;
  156. }
  157. FREE_INTERFACE(pIDBCS);
  158. //
  159. //
  160. // Create a command from the session object
  161. //
  162. hr = pIDBCreateCommand->CreateCommand(
  163. NULL,
  164. IID_ICommandText,
  165. (LPUNKNOWN*) &pICommandText
  166. );
  167. if(FAILED(hr)) {
  168. printf(" IDBCreateCommand::CreateCommand failed\n");
  169. goto error;
  170. }
  171. FREE_INTERFACE(pIDBCreateCommand);
  172. //
  173. // Set the CommandText for the Query
  174. //
  175. hr = pICommandText->SetCommandText(
  176. rguidDialect,
  177. pszCommandText
  178. );
  179. if(FAILED(hr)) {
  180. printf("ICommandText::SetCommandText failed \n");
  181. goto error;
  182. }
  183. if (cCmdPropSet) {
  184. hr = pICommandText->QueryInterface(
  185. IID_ICommandProperties,
  186. (void**) &pICommandProperties);
  187. if(FAILED(hr)) {
  188. printf("QueryInterface for ICommandProperties failed \n");
  189. goto error;
  190. }
  191. hr = pICommandProperties->SetProperties(
  192. cCmdPropSet,
  193. rgCmdPropSet);
  194. if(FAILED(hr)) {
  195. printf("ICommandProperties:;SetProperties failed \n");
  196. goto error;
  197. }
  198. FREE_INTERFACE(pICommandProperties);
  199. }
  200. hr = pICommandText->QueryInterface(
  201. IID_ICommand,
  202. (void**) &pICommand);
  203. if(FAILED(hr)) {
  204. printf("QueryInterface for ICommand failed \n");
  205. goto error;
  206. }
  207. FREE_INTERFACE(pICommandText);
  208. //
  209. // Do the Query and get back a rowset
  210. //
  211. hr = pICommand->Execute(
  212. NULL,
  213. IID_IRowset,
  214. NULL,
  215. NULL,
  216. (LPUNKNOWN *)&pIRowset
  217. );
  218. if(FAILED(hr)) {
  219. printf("ICommand::Execute failed \n");
  220. goto error;
  221. }
  222. FREE_INTERFACE(pICommand);
  223. #endif
  224. hr = pIRowset->QueryInterface(
  225. IID_IColumnsInfo,
  226. (void**) &pIColsInfo
  227. );
  228. if(FAILED(hr)) {
  229. printf("QueryInterface for IColumnsInfo failed \n");
  230. goto error;
  231. }
  232. hr = pIColsInfo->GetColumnInfo(
  233. &cCol,
  234. &prgColInfo,
  235. &szColNames
  236. );
  237. if(FAILED(hr)) {
  238. printf("IColumnsInfo::GetColumnInfo failed \n");
  239. goto error;
  240. }
  241. //
  242. // The no. of attributes is one less than the no. of columns because of
  243. // the Bookmark column
  244. //
  245. nAttrs = cCol - 1;
  246. pMyStatus = (DBBINDSTATUS *) LocalAlloc(
  247. LPTR,
  248. sizeof(DBBINDSTATUS) * nAttrs
  249. );
  250. BAIL_ON_NULL(pMyStatus);
  251. hr = CreateAccessorHelper(
  252. pIRowset,
  253. nAttrs,
  254. prgColInfo,
  255. &myAccessor,
  256. pMyStatus
  257. );
  258. if(FAILED(hr)) {
  259. printf("CreateAccessorHelper failed \n");
  260. goto error;
  261. }
  262. pMyData = (Data *) LocalAlloc(
  263. LPTR,
  264. sizeof(Data) * nAttrs
  265. );
  266. if(!pMyData) {
  267. hr = E_OUTOFMEMORY;
  268. goto error;
  269. }
  270. //
  271. // Get the rows; 256 at a time
  272. //
  273. phRows = NULL;
  274. hr = pIRowset->GetNextRows(
  275. NULL,
  276. 0,
  277. 256,
  278. &cRowsObtained,
  279. &phRows
  280. );
  281. if(FAILED(hr)) {
  282. printf("IRowset::GetNextRows failed \n");
  283. goto error;
  284. }
  285. j = cRowsObtained;
  286. while (cRowsObtained) {
  287. for (i = 0; i < cRowsObtained; i++) {
  288. //
  289. // Get the data from each row
  290. //
  291. hr = pIRowset->GetData(
  292. phRows[i],
  293. myAccessor,
  294. (void*)pMyData
  295. );
  296. if(FAILED(hr)) {
  297. printf("IRowset::GetData failed \n");
  298. goto error;
  299. }
  300. PrintData(pMyData, nAttrs, prgColInfo);
  301. }
  302. pIRowset->ReleaseRows(
  303. cRowsObtained,
  304. phRows,
  305. NULL,
  306. NULL,
  307. NULL
  308. );
  309. //
  310. // Get the next 256 rows
  311. //
  312. hr = pIRowset->GetNextRows(
  313. NULL,
  314. 0,
  315. 256,
  316. &cRowsObtained,
  317. &phRows
  318. );
  319. if(FAILED(hr)) {
  320. printf("IRowset::GetNextRows failed \n");
  321. goto error;
  322. }
  323. j+=cRowsObtained;
  324. }
  325. printf("Rows printed = %d\n", j);
  326. FREE_STRING(pszCommandText);
  327. hr = CoGetMalloc(MEMCTX_TASK, &pIMalloc);
  328. //
  329. // Nothing much we can do at this point if this failed.
  330. //
  331. if (FAILED(hr)) {
  332. CoUninitialize();
  333. exit(0);
  334. }
  335. IMALLOC_FREE(pIMalloc, prgColInfo);
  336. IMALLOC_FREE(pIMalloc, szColNames);
  337. FREE_INTERFACE(pIMalloc);
  338. FREE_INTERFACE(pAccessor);
  339. FREE_INTERFACE(pIColsInfo);
  340. FREE_INTERFACE(pIRowset);
  341. LOCAL_FREE(pMyStatus);
  342. LOCAL_FREE(pMyData);
  343. //
  344. // Uninitialize OLE.
  345. //
  346. CoUninitialize();
  347. exit(0);
  348. error:
  349. CoGetMalloc(MEMCTX_TASK, &pIMalloc);
  350. IMALLOC_FREE(pIMalloc, prgColInfo);
  351. IMALLOC_FREE(pIMalloc, szColNames);
  352. FREE_STRING(pszCommandText);
  353. FREE_INTERFACE(pIMalloc);
  354. FREE_INTERFACE(pIDBInit);
  355. FREE_INTERFACE(pIDBCS);
  356. FREE_INTERFACE(pIDBCreateCommand);
  357. FREE_INTERFACE(pICommandText);
  358. FREE_INTERFACE(pICommand);
  359. FREE_INTERFACE(pIRowset);
  360. FREE_INTERFACE(pIColsInfo);
  361. FREE_INTERFACE(pAccessor);
  362. LOCAL_FREE(pMyStatus);
  363. LOCAL_FREE(pMyData);
  364. printf("Errors stopped the Query; hr = %x", hr);
  365. if(hr == ERROR_EXTENDED_ERROR) {
  366. hr = ADsGetLastError(
  367. &dwError,
  368. pszErrorBuf,
  369. MAX_PATH,
  370. pszNameBuf,
  371. MAX_PATH
  372. );
  373. }
  374. if(SUCCEEDED(hr)) {
  375. wprintf(L"Error in %s; %s\n", pszNameBuf, pszErrorBuf);
  376. }
  377. exit(1);
  378. return(0);
  379. }
  380. //+---------------------------------------------------------------------------
  381. //
  382. // Function: ProcessArgs
  383. //
  384. // Synopsis:
  385. //
  386. //----------------------------------------------------------------------------
  387. HRESULT
  388. ProcessArgs(
  389. int argc,
  390. char * argv[]
  391. )
  392. {
  393. argc--;
  394. int currArg = 1;
  395. LPWSTR pTemp = NULL;
  396. char *pszCurrPref = NULL, *pszCurrPrefValue = NULL;
  397. LPWSTR pszSearchBase = NULL, pszSearchFilter = NULL, pszAttrList = NULL;
  398. LPWSTR pszUserName = NULL, pszPassword = NULL;
  399. DWORD dwAuthFlags;
  400. cCmdProp = cDBProp = 0;
  401. while (argc) {
  402. if (argv[currArg][0] != '/' && argv[currArg][0] != '-')
  403. BAIL_ON_FAILURE (E_FAIL);
  404. switch (argv[currArg][1]) {
  405. case 'b':
  406. argc--;
  407. currArg++;
  408. if (argc <= 0)
  409. BAIL_ON_FAILURE (E_FAIL);
  410. pszSearchBase = AllocateUnicodeString(argv[currArg]);
  411. BAIL_ON_NULL(pszSearchBase);
  412. break;
  413. case 'f':
  414. argc--;
  415. currArg++;
  416. if (argc <= 0)
  417. BAIL_ON_FAILURE (E_FAIL);
  418. pszSearchFilter = AllocateUnicodeString(argv[currArg]);
  419. BAIL_ON_NULL(pszSearchFilter);
  420. break;
  421. case 'd':
  422. argc--;
  423. currArg++;
  424. if (argc <= 0)
  425. BAIL_ON_FAILURE (E_FAIL);
  426. if (!_stricmp(argv[currArg], "sql"))
  427. rguidDialect = DBGUID_SQL;
  428. else if (!_stricmp(argv[currArg], "ldap"))
  429. rguidDialect = DBGUID_LDAPDialect;
  430. else if (!_stricmp(argv[currArg], "default"))
  431. rguidDialect = DBGUID_DEFAULT;
  432. else
  433. BAIL_ON_FAILURE (E_FAIL);
  434. break;
  435. case 'a':
  436. argc--;
  437. currArg++;
  438. if (argc <= 0)
  439. BAIL_ON_FAILURE (E_FAIL);
  440. pszAttrList = AllocateUnicodeString(argv[currArg]);
  441. BAIL_ON_NULL(pszAttrList);
  442. break;
  443. case 'u':
  444. argc--;
  445. currArg++;
  446. if (argc <= 0)
  447. BAIL_ON_FAILURE (E_FAIL);
  448. pszUserName = AllocateUnicodeString(argv[currArg]);
  449. BAIL_ON_NULL(pszUserName);
  450. argc--;
  451. currArg++;
  452. if (argc <= 0)
  453. BAIL_ON_FAILURE (E_FAIL);
  454. pszPassword = AllocateUnicodeString(argv[currArg]);
  455. BAIL_ON_NULL(pszPassword);
  456. rgDBProp[cDBProp].dwPropertyID = DBPROP_AUTH_USERID;
  457. rgDBProp[cDBProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  458. rgDBProp[cDBProp].vValue.vt = VT_BSTR;
  459. V_BSTR (&rgDBProp[cDBProp].vValue) = SysAllocString(pszUserName);
  460. cDBProp++;
  461. rgDBProp[cDBProp].dwPropertyID = DBPROP_AUTH_PASSWORD;
  462. rgDBProp[cDBProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  463. rgDBProp[cDBProp].vValue.vt = VT_BSTR;
  464. V_BSTR (&rgDBProp[cDBProp].vValue) = SysAllocString(pszPassword);
  465. cDBProp++;
  466. break;
  467. case 'p':
  468. argc--;
  469. currArg++;
  470. if (argc <= 0)
  471. BAIL_ON_FAILURE (E_FAIL);
  472. pszCurrPref = strtok(argv[currArg], "=");
  473. pszCurrPrefValue = strtok(NULL, "=");
  474. if (!pszCurrPref || !pszCurrPrefValue)
  475. BAIL_ON_FAILURE(E_FAIL);
  476. if (!_stricmp(pszCurrPref, "asynchronous")) {
  477. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_ASYNCHRONOUS;
  478. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  479. rgCmdProp[cCmdProp].vValue.vt = VT_BOOL;
  480. if (!_stricmp(pszCurrPrefValue, "yes" ))
  481. V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_TRUE;
  482. else if (!_stricmp(pszCurrPrefValue, "no" ))
  483. V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_FALSE;
  484. else
  485. BAIL_ON_FAILURE(E_FAIL);
  486. cCmdProp++;
  487. }
  488. else if (!_stricmp(pszCurrPref, "attrTypesOnly")) {
  489. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_ATTRIBTYPES_ONLY;
  490. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  491. rgCmdProp[cCmdProp].vValue.vt = VT_BOOL;
  492. if (!_stricmp(pszCurrPrefValue, "yes" ))
  493. V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_TRUE;
  494. else if (!_stricmp(pszCurrPrefValue, "no" ))
  495. V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_FALSE;
  496. else
  497. BAIL_ON_FAILURE(E_FAIL);
  498. cCmdProp++;
  499. }
  500. else if (!_stricmp(pszCurrPref, "SecureAuth")) {
  501. if (!_stricmp(pszCurrPrefValue, "yes" ))
  502. dwAuthFlags |= ADS_SECURE_AUTHENTICATION;
  503. else if (!_stricmp(pszCurrPrefValue, "no" ))
  504. dwAuthFlags &= ~ADS_SECURE_AUTHENTICATION;
  505. else
  506. BAIL_ON_FAILURE(E_FAIL);
  507. rgDBProp[cDBProp].dwPropertyID = DBPROP_AUTH_ENCRYPT_PASSWORD;
  508. rgDBProp[cDBProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  509. rgDBProp[cDBProp].vValue.vt = VT_BSTR;
  510. V_BSTR (&rgDBProp[cDBProp].vValue) = SysAllocString(pszPassword);
  511. cDBProp++;
  512. }
  513. else if (!_stricmp(pszCurrPref, "derefAliases")) {
  514. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_DEREF_ALIASES;
  515. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  516. rgCmdProp[cCmdProp].vValue.vt = VT_BOOL;
  517. if (!_stricmp(pszCurrPrefValue, "yes" ))
  518. V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_TRUE;
  519. else if (!_stricmp(pszCurrPrefValue, "no" ))
  520. V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_FALSE;
  521. else
  522. BAIL_ON_FAILURE(E_FAIL);
  523. cCmdProp++;
  524. }
  525. else if (!_stricmp(pszCurrPref, "timeOut")) {
  526. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_TIMEOUT;
  527. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  528. rgCmdProp[cCmdProp].vValue.vt = VT_I4;
  529. V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue);
  530. cCmdProp++;
  531. }
  532. else if (!_stricmp(pszCurrPref, "timeLimit")) {
  533. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_TIME_LIMIT;
  534. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  535. rgCmdProp[cCmdProp].vValue.vt = VT_I4;
  536. V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue);
  537. cCmdProp++;
  538. }
  539. else if (!_stricmp(pszCurrPref, "sizeLimit")) {
  540. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_SIZE_LIMIT;
  541. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  542. rgCmdProp[cCmdProp].vValue.vt = VT_I4;
  543. V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue);
  544. cCmdProp++;
  545. }
  546. else if (!_stricmp(pszCurrPref, "PageSize")) {
  547. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_PAGESIZE;
  548. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  549. rgCmdProp[cCmdProp].vValue.vt = VT_I4;
  550. V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue);
  551. cCmdProp++;
  552. }
  553. else if (!_stricmp(pszCurrPref, "PagedTimeLimit")) {
  554. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_PAGED_TIME_LIMIT;
  555. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  556. rgCmdProp[cCmdProp].vValue.vt = VT_I4;
  557. V_I4 (&rgCmdProp[cCmdProp].vValue) = atoi(pszCurrPrefValue);
  558. cCmdProp++;
  559. }
  560. else if (!_stricmp(pszCurrPref, "SearchScope")) {
  561. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_SEARCH_SCOPE;
  562. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  563. rgCmdProp[cCmdProp].vValue.vt = VT_I4;
  564. if (!_stricmp(pszCurrPrefValue, "Base" ))
  565. V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_SCOPE_BASE;
  566. else if (!_stricmp(pszCurrPrefValue, "OneLevel" ))
  567. V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_SCOPE_ONELEVEL;
  568. else if (!_stricmp(pszCurrPrefValue, "Subtree" ))
  569. V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_SCOPE_SUBTREE;
  570. else
  571. BAIL_ON_FAILURE(E_FAIL);
  572. cCmdProp++;
  573. }
  574. else if (!_stricmp(pszCurrPref, "ChaseReferrals")) {
  575. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_CHASE_REFERRALS;
  576. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  577. rgCmdProp[cCmdProp].vValue.vt = VT_I4;
  578. if (!_stricmp(pszCurrPrefValue, "always" ))
  579. V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_CHASE_REFERRALS_ALWAYS;
  580. else if (!_stricmp(pszCurrPrefValue, "never" ))
  581. V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_CHASE_REFERRALS_NEVER;
  582. else if (!_stricmp(pszCurrPrefValue, "external" ))
  583. V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_CHASE_REFERRALS_EXTERNAL;
  584. else if (!_stricmp(pszCurrPrefValue, "subordinate" ))
  585. V_I4 (&rgCmdProp[cCmdProp].vValue) = ADS_CHASE_REFERRALS_SUBORDINATE;
  586. else
  587. BAIL_ON_FAILURE(E_FAIL);
  588. cCmdProp++;
  589. }
  590. else if (!_stricmp(pszCurrPref, "cacheResults")) {
  591. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_CACHE_RESULTS;
  592. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  593. rgCmdProp[cCmdProp].vValue.vt = VT_BOOL;
  594. if (!_stricmp(pszCurrPrefValue, "yes" ))
  595. V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_TRUE;
  596. else if (!_stricmp(pszCurrPrefValue, "no" ))
  597. V_BOOL (&rgCmdProp[cCmdProp].vValue) = VARIANT_FALSE;
  598. else
  599. BAIL_ON_FAILURE(E_FAIL);
  600. cCmdProp++;
  601. }
  602. else if (!_stricmp(pszCurrPref, "sortOn")) {
  603. pszSortAttrList = AllocateUnicodeString(pszCurrPrefValue);
  604. }
  605. else
  606. BAIL_ON_FAILURE(E_FAIL);
  607. break;
  608. default:
  609. BAIL_ON_FAILURE(E_FAIL);
  610. }
  611. argc--;
  612. currArg++;
  613. }
  614. //
  615. // Check for Mandatory arguments;
  616. //
  617. if (!pszSearchBase || !pszSearchFilter || !pszAttrList)
  618. BAIL_ON_FAILURE(E_FAIL);
  619. #if USE_OPENROWSET
  620. pszTableName = AllocADsStr(
  621. pszSearchBase
  622. );
  623. BAIL_ON_NULL(E_FAIL);
  624. #endif
  625. if (IsEqualGUID(rguidDialect, DBGUID_SQL) ) {
  626. // if sorting is specified, add to the command text itself
  627. //
  628. DWORD sortAttrLen = pszSortAttrList ?
  629. wcslen(L" ORDER BY ") + wcslen(pszSortAttrList) : 0;
  630. pszCommandText = (LPWSTR) AllocADsMem(
  631. (wcslen(pszSearchBase) +
  632. wcslen(pszSearchFilter) +
  633. wcslen(pszAttrList) +
  634. wcslen(L"''") +
  635. wcslen(L"SELECT ") +
  636. wcslen(L" FROM ") +
  637. wcslen(L" WHERE ") +
  638. sortAttrLen +
  639. 1) * sizeof(WCHAR)
  640. );
  641. BAIL_ON_NULL(E_FAIL);
  642. wcscpy(pszCommandText, L"SELECT ");
  643. wcscat(pszCommandText, pszAttrList);
  644. wcscat(pszCommandText, L" FROM '");
  645. wcscat(pszCommandText, pszSearchBase);
  646. wcscat(pszCommandText, L"' WHERE ");
  647. wcscat(pszCommandText, pszSearchFilter);
  648. if (pszSortAttrList) {
  649. wcscat(pszCommandText, L" ORDER BY ");
  650. wcscat(pszCommandText, pszSortAttrList);
  651. }
  652. } else {
  653. pszCommandText = (LPWSTR) AllocADsMem(
  654. (wcslen(pszSearchBase) +
  655. wcslen(pszSearchFilter) +
  656. wcslen(pszAttrList) +
  657. 5) * sizeof(WCHAR)
  658. );
  659. BAIL_ON_NULL(E_FAIL);
  660. wcscpy(pszCommandText, L"<");
  661. wcscat(pszCommandText, pszSearchBase);
  662. wcscat(pszCommandText, L">;");
  663. wcscat(pszCommandText, pszSearchFilter);
  664. wcscat(pszCommandText, L";");
  665. wcscat(pszCommandText, pszAttrList);
  666. if (pszSortAttrList) {
  667. // if sorting is specified, add as a command property
  668. rgCmdProp[cCmdProp].dwPropertyID = ADSIPROP_SORT_ON;
  669. rgCmdProp[cCmdProp].dwOptions = DBPROPOPTIONS_REQUIRED;
  670. rgCmdProp[cCmdProp].vValue.vt = VT_BSTR;
  671. V_BSTR (&rgCmdProp[cCmdProp].vValue) = AllocateUnicodeString(pszCurrPrefValue);
  672. cCmdProp++;
  673. }
  674. }
  675. if (cDBProp > 0) {
  676. cDBPropSet = 1;
  677. rgDBPropSet[0].rgProperties = rgDBProp;
  678. rgDBPropSet[0].cProperties = cDBProp;
  679. rgDBPropSet[0].guidPropertySet = DBPROPSET_DBINIT;
  680. }
  681. if (cCmdProp > 0) {
  682. cCmdPropSet = 1;
  683. rgCmdPropSet[0].rgProperties = rgCmdProp;
  684. rgCmdPropSet[0].cProperties = cCmdProp;
  685. rgCmdPropSet[0].guidPropertySet = DBPROPSET_ADSISEARCH;
  686. }
  687. FreeUnicodeString(pszSearchBase) ;
  688. FreeUnicodeString(pszSearchFilter) ;
  689. FreeUnicodeString(pszAttrList) ;
  690. return (S_OK);
  691. error:
  692. FreeUnicodeString(pszSearchBase) ;
  693. FreeUnicodeString(pszSearchFilter) ;
  694. FreeUnicodeString(pszAttrList) ;
  695. PrintUsage();
  696. return E_FAIL;
  697. }