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.

602 lines
18 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: drt.cxx
  7. //
  8. // Contents: Main for OleDs DRT
  9. //
  10. //
  11. // History: 28-Oct-94 KrishnaG, created OleDs DRT
  12. // 28-Oct-94 ChuckC, rewritten.
  13. //
  14. //----------------------------------------------------------------------------
  15. //
  16. // System Includes
  17. //
  18. #define INC_OLE2
  19. #include <windows.h>
  20. //
  21. // CRunTime Includes
  22. //
  23. #include <stdlib.h>
  24. #include <limits.h>
  25. #include <io.h>
  26. #include <stdio.h>
  27. //
  28. // Public OleDs includes
  29. //
  30. //
  31. // Private defines
  32. //
  33. #define BAIL_ON_NULL(p) \
  34. if (!(p)) { \
  35. goto error; \
  36. }
  37. #define BAIL_ON_FAILURE(hr) \
  38. if (FAILED(hr)) { \
  39. goto error; \
  40. }
  41. #include "activeds.h"
  42. #include "main.hxx"
  43. //
  44. // Globals representing the parameters
  45. //
  46. LPWSTR pszSearchBase, pszSearchFilter, pszAttrNames[10], pszAttrList;
  47. DWORD dwNumberAttributes = (DWORD) -1, dwMaxRows = (DWORD) -1;
  48. //
  49. // Preferences
  50. //
  51. BOOL fASynchronous=FALSE, fDerefAliases=FALSE, fAttrsOnly=FALSE;
  52. DWORD fSizeLimit, fTimeLimit, dwTimeOut, dwPageSize, dwSearchScope;
  53. ADS_SEARCHPREF_INFO pSearchPref[10];
  54. ADS_SORTKEY pSortKey[10];
  55. DWORD dwCurrPref = 0;
  56. LPWSTR pszUserName=NULL, pszPassword=NULL;
  57. DWORD dwAuthFlags=0;
  58. DWORD cErr=0;
  59. char *prefNameLookup[] =
  60. {
  61. "ADS_SEARCHPREF_ASYNCHRONOUS",
  62. "ADS_SEARCHPREF_DEREF_ALIASES",
  63. "ADS_SEARCHPREF_SIZE_LIMIT",
  64. "ADS_SEARCHPREF_TIME_LIMIT",
  65. "ADS_SEARCHPREF_ATTRIBTYPES_ONLY",
  66. "ADS_SEARCHPREF_SEARCH_SCOPE",
  67. "ADS_SEARCHPREF_TIMEOUT",
  68. "ADS_SEARCHPREF_PAGESIZE",
  69. "ADS_SEARCHPREF_PAGED_TIME_LIMIT",
  70. "ADS_SEARCHPREF_CHASE_REFERRALS"
  71. "ADS_SEARCHPREF_CACHE_RESULTS"
  72. };
  73. //+---------------------------------------------------------------------------
  74. //
  75. // Function: main
  76. //
  77. // Synopsis:
  78. //
  79. //----------------------------------------------------------------------------
  80. INT __cdecl
  81. main(int argc, char * argv[])
  82. {
  83. HRESULT hr=S_OK;
  84. IDirectorySearch *pDSSearch=NULL;
  85. ADS_SEARCH_HANDLE hSearchHandle=NULL;
  86. ADS_SEARCH_COLUMN Column;
  87. DWORD nRows = 0, i;
  88. LPWSTR pszColumnName = NULL;
  89. #if 0 // Enable if you want to test binary values in filters and send
  90. // pszBinaryFilter instead of pszSearchFilter in ExecuteSearch
  91. WCHAR pszBinaryFilter[256] = L"objectSid=";
  92. LPWSTR pszDest = NULL;
  93. BYTE column[100] = {
  94. 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00,
  95. 0x00, 0x00, 0x59, 0x51, 0xb8, 0x17, 0x66, 0x72, 0x5d, 0x25,
  96. 0x64, 0x63, 0x3b, 0x0b, 0x29, 0x99, 0x21, 0x00 };
  97. hr = ADsEncodeBinaryData (
  98. column,
  99. 28,
  100. &pszDest
  101. );
  102. wcscat( pszBinaryFilter, pszDest );
  103. FreeADsMem( pszDest );
  104. #endif
  105. //
  106. // Sets the global variables with the parameters
  107. //
  108. hr = ProcessArgs(argc, argv);
  109. BAIL_ON_FAILURE(hr);
  110. hr = CoInitialize(NULL);
  111. if (FAILED(hr)) {
  112. printf("CoInitialize failed\n") ;
  113. return(1) ;
  114. }
  115. hr = ADsOpenObject(
  116. pszSearchBase,
  117. pszUserName,
  118. pszPassword,
  119. dwAuthFlags,
  120. IID_IDirectorySearch,
  121. (void **)&pDSSearch
  122. );
  123. #if 0 // If you want to go with the default credentials
  124. hr = ADsGetObject(
  125. pszSearchBase,
  126. IID_IDirectorySearch,
  127. (void **)&pDSSearch
  128. );
  129. #endif
  130. BAIL_ON_FAILURE(hr);
  131. if (dwCurrPref) {
  132. hr = pDSSearch->SetSearchPreference(
  133. pSearchPref,
  134. dwCurrPref
  135. );
  136. BAIL_ON_FAILURE(hr);
  137. if (hr != S_OK) {
  138. for (i=0; i<dwCurrPref; i++) {
  139. if (pSearchPref[i].dwStatus != ADS_STATUS_S_OK) {
  140. printf(
  141. "Error in setting the preference %s: status = %d\n",
  142. prefNameLookup[pSearchPref[i].dwSearchPref],
  143. pSearchPref[i].dwStatus
  144. );
  145. cErr++;
  146. }
  147. }
  148. }
  149. }
  150. hr = pDSSearch->ExecuteSearch(
  151. pszSearchFilter,
  152. pszAttrNames,
  153. dwNumberAttributes,
  154. &hSearchHandle
  155. );
  156. BAIL_ON_FAILURE(hr);
  157. hr = pDSSearch->GetNextRow(
  158. hSearchHandle
  159. );
  160. BAIL_ON_FAILURE(hr);
  161. while (hr != S_ADS_NOMORE_ROWS && nRows < dwMaxRows) {
  162. nRows++;
  163. if (dwNumberAttributes == (DWORD) -1) {
  164. hr = pDSSearch->GetNextColumnName(
  165. hSearchHandle,
  166. &pszColumnName
  167. );
  168. BAIL_ON_FAILURE(hr);
  169. while (hr != S_ADS_NOMORE_COLUMNS) {
  170. hr = pDSSearch->GetColumn(
  171. hSearchHandle,
  172. pszColumnName,
  173. &Column
  174. );
  175. if (FAILED(hr) && hr != E_ADS_COLUMN_NOT_SET)
  176. goto error;
  177. if (SUCCEEDED(hr)) {
  178. PrintColumn(&Column, pszColumnName);
  179. pDSSearch->FreeColumn(&Column);
  180. }
  181. FreeADsMem(pszColumnName);
  182. hr = pDSSearch->GetNextColumnName(
  183. hSearchHandle,
  184. &pszColumnName
  185. );
  186. BAIL_ON_FAILURE(hr);
  187. }
  188. printf("\n");
  189. }
  190. else {
  191. for (DWORD i=0; i<dwNumberAttributes; i++) {
  192. hr = pDSSearch->GetColumn(
  193. hSearchHandle,
  194. pszAttrNames[i],
  195. &Column
  196. );
  197. if (hr == E_ADS_COLUMN_NOT_SET)
  198. continue;
  199. BAIL_ON_FAILURE(hr);
  200. PrintColumn(&Column, pszAttrNames[i]);
  201. pDSSearch->FreeColumn(&Column);
  202. }
  203. printf("\n");
  204. }
  205. hr = pDSSearch->GetNextRow(
  206. hSearchHandle
  207. );
  208. BAIL_ON_FAILURE(hr);
  209. }
  210. wprintf (L"Total Rows: %d\n", nRows);
  211. if (cErr) {
  212. wprintf (L"%d warning(s) ignored", cErr);
  213. }
  214. if (hSearchHandle)
  215. pDSSearch->CloseSearchHandle(hSearchHandle);
  216. FREE_INTERFACE(pDSSearch);
  217. FREE_UNICODE_STRING(pszSearchBase) ;
  218. FREE_UNICODE_STRING(pszSearchFilter) ;
  219. FREE_UNICODE_STRING(pszAttrList) ;
  220. CoUninitialize();
  221. return(0) ;
  222. error:
  223. if (hSearchHandle)
  224. pDSSearch->CloseSearchHandle(hSearchHandle);
  225. FREE_INTERFACE(pDSSearch);
  226. FREE_UNICODE_STRING(pszSearchBase) ;
  227. FREE_UNICODE_STRING(pszSearchFilter) ;
  228. FREE_UNICODE_STRING(pszAttrList) ;
  229. FREE_UNICODE_STRING(pszUserName) ;
  230. FREE_UNICODE_STRING(pszPassword) ;
  231. wprintf (L"Error! hr = 0x%x\n", hr);
  232. return(1) ;
  233. }
  234. //+---------------------------------------------------------------------------
  235. //
  236. // Function: ProcessArgs
  237. //
  238. // Synopsis:
  239. //
  240. //----------------------------------------------------------------------------
  241. HRESULT
  242. ProcessArgs(
  243. int argc,
  244. char * argv[]
  245. )
  246. {
  247. argc--;
  248. int currArg = 1;
  249. LPWSTR pTemp;
  250. char *pszCurrPref, *pszCurrPrefValue;
  251. char *pszAttr;
  252. DWORD nAttr=0;
  253. while (argc) {
  254. if (argv[currArg][0] != '/' && argv[currArg][0] != '-')
  255. BAIL_ON_FAILURE (E_FAIL);
  256. switch (argv[currArg][1]) {
  257. case 'b':
  258. argc--;
  259. currArg++;
  260. if (argc <= 0)
  261. BAIL_ON_FAILURE (E_FAIL);
  262. pszSearchBase = AllocateUnicodeString(argv[currArg]);
  263. BAIL_ON_NULL(pszSearchBase);
  264. break;
  265. case 'f':
  266. argc--;
  267. currArg++;
  268. if (argc <= 0)
  269. BAIL_ON_FAILURE (E_FAIL);
  270. pszSearchFilter = AllocateUnicodeString(argv[currArg]);
  271. BAIL_ON_NULL(pszSearchFilter);
  272. break;
  273. case 'a':
  274. argc--;
  275. currArg++;
  276. if (argc <= 0)
  277. BAIL_ON_FAILURE (E_FAIL);
  278. pszAttrList = AllocateUnicodeString(argv[currArg]);
  279. BAIL_ON_NULL(pszAttrList);
  280. dwNumberAttributes = 0;
  281. pTemp = wcstok(pszAttrList, L",");
  282. pszAttrNames[dwNumberAttributes] = RemoveWhiteSpaces(pTemp);
  283. dwNumberAttributes++;
  284. while (pTemp) {
  285. pTemp = wcstok(NULL, L",");
  286. pszAttrNames[dwNumberAttributes] = RemoveWhiteSpaces(pTemp);
  287. dwNumberAttributes++;
  288. }
  289. dwNumberAttributes--;
  290. break;
  291. case 'u':
  292. argc--;
  293. currArg++;
  294. if (argc <= 0)
  295. BAIL_ON_FAILURE (E_FAIL);
  296. pszUserName = AllocateUnicodeString(argv[currArg]);
  297. BAIL_ON_NULL(pszSearchBase);
  298. argc--;
  299. currArg++;
  300. if (argc <= 0)
  301. BAIL_ON_FAILURE (E_FAIL);
  302. pszPassword = AllocateUnicodeString(argv[currArg]);
  303. BAIL_ON_NULL(pszSearchBase);
  304. break;
  305. case 't':
  306. argc--;
  307. currArg++;
  308. if (argc <= 0)
  309. BAIL_ON_FAILURE (E_FAIL);
  310. pszCurrPref = strtok(argv[currArg], "=");
  311. pszCurrPrefValue = strtok(NULL, "=");
  312. if (!pszCurrPref || !pszCurrPrefValue)
  313. BAIL_ON_FAILURE(E_FAIL);
  314. if (!_stricmp(pszCurrPref, "SecureAuth")) {
  315. if (!_stricmp(pszCurrPrefValue, "yes" ))
  316. dwAuthFlags |= ADS_SECURE_AUTHENTICATION;
  317. else if (!_stricmp(pszCurrPrefValue, "no" ))
  318. dwAuthFlags &= ~ADS_SECURE_AUTHENTICATION;
  319. else
  320. BAIL_ON_FAILURE(E_FAIL);
  321. }
  322. else if (!_stricmp(pszCurrPref, "UseEncrypt")) {
  323. if (!_stricmp(pszCurrPrefValue, "yes" ))
  324. dwAuthFlags |= ADS_USE_ENCRYPTION;
  325. else if (!_stricmp(pszCurrPrefValue, "no" ))
  326. dwAuthFlags &= ~ADS_USE_ENCRYPTION;
  327. else
  328. BAIL_ON_FAILURE(E_FAIL);
  329. }
  330. else
  331. BAIL_ON_FAILURE(E_FAIL);
  332. break;
  333. case 'p':
  334. argc--;
  335. currArg++;
  336. if (argc <= 0)
  337. BAIL_ON_FAILURE (E_FAIL);
  338. pszCurrPref = strtok(argv[currArg], "=");
  339. pszCurrPrefValue = strtok(NULL, "=");
  340. if (!pszCurrPref || !pszCurrPrefValue)
  341. BAIL_ON_FAILURE(E_FAIL);
  342. if (!_stricmp(pszCurrPref, "asynchronous")) {
  343. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_ASYNCHRONOUS;
  344. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_BOOLEAN;
  345. if (!_stricmp(pszCurrPrefValue, "yes" ))
  346. pSearchPref[dwCurrPref].vValue.Boolean = TRUE;
  347. else if (!_stricmp(pszCurrPrefValue, "no" ))
  348. pSearchPref[dwCurrPref].vValue.Boolean = FALSE;
  349. else
  350. BAIL_ON_FAILURE(E_FAIL);
  351. }
  352. else if (!_stricmp(pszCurrPref, "attrTypesOnly")) {
  353. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_ATTRIBTYPES_ONLY;
  354. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_BOOLEAN;
  355. if (!_stricmp(pszCurrPrefValue, "yes" ))
  356. pSearchPref[dwCurrPref].vValue.Boolean = TRUE;
  357. else if (!_stricmp(pszCurrPrefValue, "no" ))
  358. pSearchPref[dwCurrPref].vValue.Boolean = FALSE;
  359. else
  360. BAIL_ON_FAILURE(E_FAIL);
  361. }
  362. else if (!_stricmp(pszCurrPref, "derefAliases")) {
  363. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_DEREF_ALIASES;
  364. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_INTEGER;
  365. if (!_stricmp(pszCurrPrefValue, "yes" ))
  366. pSearchPref[dwCurrPref].vValue.Integer = ADS_DEREF_ALWAYS;
  367. else if (!_stricmp(pszCurrPrefValue, "no" ))
  368. pSearchPref[dwCurrPref].vValue.Integer = ADS_DEREF_NEVER;
  369. else
  370. BAIL_ON_FAILURE(E_FAIL);
  371. }
  372. else if (!_stricmp(pszCurrPref, "timeOut")) {
  373. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_TIMEOUT;
  374. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_INTEGER;
  375. pSearchPref[dwCurrPref].vValue.Integer = atoi(pszCurrPrefValue);
  376. }
  377. else if (!_stricmp(pszCurrPref, "timeLimit")) {
  378. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_TIME_LIMIT;
  379. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_INTEGER;
  380. pSearchPref[dwCurrPref].vValue.Integer = atoi(pszCurrPrefValue);
  381. }
  382. else if (!_stricmp(pszCurrPref, "sizeLimit")) {
  383. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
  384. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_INTEGER;
  385. pSearchPref[dwCurrPref].vValue.Integer = atoi(pszCurrPrefValue);
  386. }
  387. else if (!_stricmp(pszCurrPref, "PageSize")) {
  388. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  389. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_INTEGER;
  390. pSearchPref[dwCurrPref].vValue.Integer = atoi(pszCurrPrefValue);
  391. }
  392. else if (!_stricmp(pszCurrPref, "PagedTimeLimit")) {
  393. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_PAGED_TIME_LIMIT;
  394. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_INTEGER;
  395. pSearchPref[dwCurrPref].vValue.Integer = atoi(pszCurrPrefValue);
  396. }
  397. else if (!_stricmp(pszCurrPref, "SearchScope")) {
  398. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  399. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_INTEGER;
  400. if (!_stricmp(pszCurrPrefValue, "Base" ))
  401. pSearchPref[dwCurrPref].vValue.Integer = ADS_SCOPE_BASE;
  402. else if (!_stricmp(pszCurrPrefValue, "OneLevel" ))
  403. pSearchPref[dwCurrPref].vValue.Integer = ADS_SCOPE_ONELEVEL;
  404. else if (!_stricmp(pszCurrPrefValue, "Subtree" ))
  405. pSearchPref[dwCurrPref].vValue.Integer = ADS_SCOPE_SUBTREE;
  406. else
  407. BAIL_ON_FAILURE(E_FAIL);
  408. }
  409. else if (!_stricmp(pszCurrPref, "ChaseReferrals")) {
  410. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_CHASE_REFERRALS;
  411. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_INTEGER;
  412. if (!_stricmp(pszCurrPrefValue, "always" ))
  413. pSearchPref[dwCurrPref].vValue.Integer = ADS_CHASE_REFERRALS_ALWAYS;
  414. else if (!_stricmp(pszCurrPrefValue, "never" ))
  415. pSearchPref[dwCurrPref].vValue.Integer = ADS_CHASE_REFERRALS_NEVER;
  416. else if (!_stricmp(pszCurrPrefValue, "external" ))
  417. pSearchPref[dwCurrPref].vValue.Integer = ADS_CHASE_REFERRALS_EXTERNAL;
  418. else if (!_stricmp(pszCurrPrefValue, "subordinate" ))
  419. pSearchPref[dwCurrPref].vValue.Integer = ADS_CHASE_REFERRALS_SUBORDINATE;
  420. else
  421. BAIL_ON_FAILURE(E_FAIL);
  422. }
  423. else if (!_stricmp(pszCurrPref, "SortOn")) {
  424. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_SORT_ON;
  425. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_PROV_SPECIFIC;
  426. pszAttr = strtok(pszCurrPrefValue, ",");
  427. for (nAttr=0; pszAttr && nAttr < 10; nAttr++) {
  428. pSortKey[nAttr].pszAttrType = AllocateUnicodeString(pszAttr);
  429. pSortKey[nAttr].pszReserved = NULL;
  430. pSortKey[nAttr].fReverseorder = 0;
  431. pszAttr = strtok(NULL, ",");
  432. }
  433. if (nAttr == 0 && nAttr >= 10) {
  434. BAIL_ON_FAILURE(E_FAIL);
  435. }
  436. pSearchPref[dwCurrPref].vValue.ProviderSpecific.dwLength = sizeof(ADS_SORTKEY) * nAttr;
  437. pSearchPref[dwCurrPref].vValue.ProviderSpecific.lpValue = (LPBYTE) pSortKey;
  438. }
  439. else if (!_stricmp(pszCurrPref, "cacheResults")) {
  440. pSearchPref[dwCurrPref].dwSearchPref = ADS_SEARCHPREF_CACHE_RESULTS;
  441. pSearchPref[dwCurrPref].vValue.dwType = ADSTYPE_BOOLEAN;
  442. if (!_stricmp(pszCurrPrefValue, "yes" ))
  443. pSearchPref[dwCurrPref].vValue.Boolean = TRUE;
  444. else if (!_stricmp(pszCurrPrefValue, "no" ))
  445. pSearchPref[dwCurrPref].vValue.Boolean = FALSE;
  446. else
  447. BAIL_ON_FAILURE(E_FAIL);
  448. }
  449. else
  450. BAIL_ON_FAILURE(E_FAIL);
  451. dwCurrPref++;
  452. break;
  453. case 'n':
  454. argc--;
  455. currArg++;
  456. if (argc <= 0)
  457. BAIL_ON_FAILURE (E_FAIL);
  458. dwMaxRows = atoi(argv[currArg]);
  459. break;
  460. default:
  461. BAIL_ON_FAILURE(E_FAIL);
  462. }
  463. argc--;
  464. currArg++;
  465. }
  466. //
  467. // Check for Mandatory arguments;
  468. //
  469. if (!pszSearchBase || !pszSearchFilter)
  470. BAIL_ON_FAILURE(E_FAIL);
  471. if (dwNumberAttributes == 0) {
  472. //
  473. // Get all the attributes
  474. //
  475. dwNumberAttributes = (DWORD) -1;
  476. }
  477. return (S_OK);
  478. error:
  479. PrintUsage();
  480. return E_FAIL;
  481. }
  482. LPWSTR
  483. RemoveWhiteSpaces(
  484. LPWSTR pszText)
  485. {
  486. LPWSTR pChar;
  487. if(!pszText)
  488. return (pszText);
  489. while(*pszText && iswspace(*pszText))
  490. pszText++;
  491. for(pChar = pszText + wcslen(pszText) - 1; pChar >= pszText; pChar--) {
  492. if(!iswspace(*pChar))
  493. break;
  494. else
  495. *pChar = L'\0';
  496. }
  497. return pszText;
  498. }