Leaked source code of windows server 2003
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.

747 lines
16 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996.
  5. //
  6. // File: tldap.cxx
  7. //
  8. // Contents: Command line test utility for LDAP link tracking db
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. //
  15. //
  16. // History: 18-Nov-96 BillMo Created.
  17. //
  18. // Notes:
  19. //
  20. // Codework:
  21. //
  22. //--------------------------------------------------------------------------
  23. #include <pch.cxx>
  24. #pragma hdrstop
  25. #include "teststub.cxx"
  26. #define TRKDATA_ALLOCATE
  27. #include <trksvr.hxx>
  28. #undef TRKDATA_ALLOCATE
  29. #if DBG
  30. class CTestSvrSvc
  31. {
  32. public:
  33. void Initialize()
  34. {
  35. _svc.Initialize(STANDALONE_DEBUGGABLE_PROCESS);
  36. }
  37. void UnInitialize(HRESULT hr)
  38. {
  39. _svc.UnInitialize(hr);
  40. }
  41. void DoSwitch(TCHAR ** &tszArgs, int & cArgs, BOOL & fError);
  42. private:
  43. void DoAdd(TCHAR * pszKey, TCHAR * ptszNew, TCHAR * ptszBirth);
  44. void DoDelete(TCHAR * ptszKey);
  45. void DoModify(TCHAR * ptszKey, TCHAR * ptszNew, TCHAR * ptszBirth);
  46. void DoQuery(TCHAR * ptszKey);
  47. void DoTouch(TCHAR * ptszKey);
  48. void DoFill(TCHAR * ptszNum);
  49. void DoPurge();
  50. void DoCachePurge();
  51. void DoVolumeTable();
  52. void DoShorten();
  53. void DoRunTests();
  54. void DoIdt();
  55. void TryCreateVolume(const CMachineId & mcid,
  56. const CVolumeSecret & secret,
  57. CVolumeId * pVolumeId);
  58. inline CIntraDomainTable & idt()
  59. {
  60. return(_svc._idt);
  61. }
  62. inline CVolumeTable & voltab()
  63. {
  64. return(_svc._voltab);
  65. }
  66. private:
  67. CTrkSvrSvc _svc;
  68. };
  69. void
  70. CTestSvrSvc::TryCreateVolume(const CMachineId & mcid,
  71. const CVolumeSecret & secret,
  72. CVolumeId * pVolumeId)
  73. {
  74. __try
  75. {
  76. voltab().CreateVolume(mcid, secret, pVolumeId);
  77. }
  78. __except(BreakOnDebuggableException())
  79. {
  80. printf("Exception %08X caught\n", GetExceptionCode());
  81. }
  82. }
  83. void
  84. CTestSvrSvc::DoAdd(TCHAR * ptszKey, TCHAR * ptszNew, TCHAR * ptszBirth)
  85. {
  86. __try
  87. {
  88. BOOL f = idt().Add(CDomainRelativeObjId(ptszKey), CDomainRelativeObjId(ptszNew), CDomainRelativeObjId(ptszBirth));
  89. printf("Add returns %s\n", f ? "TRUE" : "FALSE");
  90. }
  91. __except (BreakOnDebuggableException())
  92. {
  93. printf("Exception %08X caught\n", GetExceptionCode());
  94. }
  95. }
  96. void
  97. CTestSvrSvc::DoDelete(TCHAR * ptszKey)
  98. {
  99. __try
  100. {
  101. BOOL f = idt().Delete(CDomainRelativeObjId(ptszKey));
  102. printf("Delete returns %s\n", f ? "TRUE" : "FALSE");
  103. }
  104. __except (BreakOnDebuggableException())
  105. {
  106. printf("Exception %08X caught\n", GetExceptionCode());
  107. }
  108. }
  109. void
  110. CTestSvrSvc::DoModify(TCHAR * ptszKey, TCHAR * ptszNew, TCHAR * ptszBirth)
  111. {
  112. __try
  113. {
  114. BOOL f = idt().Modify(CDomainRelativeObjId(ptszKey), CDomainRelativeObjId(ptszNew), CDomainRelativeObjId(ptszBirth));
  115. printf("Modify returns %s\n", f ? "TRUE" : "FALSE");
  116. }
  117. __except (BreakOnDebuggableException())
  118. {
  119. printf("Exception %08X caught\n", GetExceptionCode());
  120. }
  121. }
  122. void
  123. CTestSvrSvc::DoQuery(TCHAR * ptszKey)
  124. {
  125. __try
  126. {
  127. CDomainRelativeObjId ldNew;
  128. CDomainRelativeObjId ldBirth;
  129. BOOL f = idt().Query(CDomainRelativeObjId(ptszKey), &ldNew, &ldBirth);
  130. printf("Query returns %s\n", f ? "TRUE" : "FALSE");
  131. if (f)
  132. {
  133. ldNew.DebugPrint(TEXT("ldNew="));
  134. ldBirth.DebugPrint(TEXT("ldBirth="));
  135. }
  136. }
  137. __except (BreakOnDebuggableException())
  138. {
  139. printf("Exception %08X caught\n", GetExceptionCode());
  140. }
  141. }
  142. void
  143. CTestSvrSvc::DoTouch(TCHAR * ptszKey)
  144. {
  145. __try
  146. {
  147. BOOL f = idt().Touch(CDomainRelativeObjId(ptszKey));
  148. printf("Touch returns %s\n", f ? "TRUE" : "FALSE");
  149. }
  150. __except (BreakOnDebuggableException())
  151. {
  152. printf("Exception %08X caught\n", GetExceptionCode());
  153. }
  154. }
  155. class CName
  156. {
  157. public:
  158. CName(int i)
  159. {
  160. _tsz[0] = i/(26*26) + TEXT('a');
  161. _tsz[1] = (i%(26*26))/26 + TEXT('a');
  162. _tsz[2] = i%26 + TEXT('a');
  163. _tsz[3] = 0;
  164. }
  165. operator TCHAR * ()
  166. {
  167. return(_tsz);
  168. }
  169. private:
  170. TCHAR _tsz[10];
  171. };
  172. void
  173. CTestSvrSvc::DoFill(TCHAR * ptszNum)
  174. {
  175. int cEntries;
  176. _stscanf(ptszNum, TEXT("%d"), &cEntries);
  177. __try
  178. {
  179. for (int i=0; i<cEntries; i++)
  180. {
  181. CDomainRelativeObjId ldNew, ldBirth;
  182. idt().Add(CDomainRelativeObjId(CName(i)), ldNew, ldBirth);
  183. }
  184. }
  185. __except (BreakOnDebuggableException())
  186. {
  187. printf("Exception %08X caught\n", GetExceptionCode());
  188. }
  189. }
  190. void
  191. CTestSvrSvc::DoPurge()
  192. {
  193. int cEntries;
  194. __try
  195. {
  196. idt().PurgeAll();
  197. voltab().PurgeAll();
  198. }
  199. __except (BreakOnDebuggableException())
  200. {
  201. printf("Exception %08X caught\n", GetExceptionCode());
  202. }
  203. }
  204. void
  205. CTestSvrSvc::DoCachePurge()
  206. {
  207. const int size = 64000000;
  208. LPDWORD p, pOrig;
  209. p = pOrig = (LPDWORD)GlobalAlloc(GMEM_FIXED, size);
  210. if (p)
  211. {
  212. for (int i=0; i<size/sizeof(*p); i++)
  213. {
  214. *p++ = 0;
  215. }
  216. GlobalFree((HGLOBAL)pOrig);
  217. }
  218. else
  219. printf("couldn't alloc 64M");
  220. }
  221. #define Check(exp) TrkAssert(exp)
  222. void
  223. CTestSvrSvc::DoVolumeTable()
  224. {
  225. // test out volume table functionality
  226. HRESULT hr;
  227. CMachineId mcid1("mcid1");
  228. CMachineId mcid2("mcid2");
  229. CMachineId mcid3("mcid3");
  230. CMachineId mcid4("mcid4");
  231. CVolumeSecret secret1;
  232. CVolumeSecret secret2;
  233. CVolumeSecret secret3;
  234. CVolumeSecret secret4;
  235. CVolumeId volume1;
  236. CVolumeId volume2;
  237. CVolumeId volume3;
  238. CVolumeId volume4;
  239. SequenceNumber seq;
  240. FILETIME ft;
  241. DoPurge();
  242. UuidCreate((GUID*)&volume1);
  243. UuidCreate((GUID*)&volume2);
  244. UuidCreate((GUID*)&volume3);
  245. UuidCreate((GUID*)&volume4);
  246. UuidCreate((GUID*)&secret1);
  247. UuidCreate((GUID*)&secret2);
  248. UuidCreate((GUID*)&secret3);
  249. UuidCreate((GUID*)&secret4);
  250. // Check Queries
  251. CFILETIME cftStart;
  252. // check non-existent volume
  253. hr = voltab().QueryVolume(mcid1, volume1, &seq, &ft);
  254. Check(hr == TRK_S_VOLUME_NOT_FOUND);
  255. // exception when setting seq number on non-existent volume
  256. hr = voltab().SetSequenceNumber(volume1, seq);
  257. Check(hr != S_OK);
  258. hr = voltab().QueryVolume(mcid1, volume1, &seq, &ft);
  259. Check(hr == TRK_S_VOLUME_NOT_FOUND);
  260. // exception when setting seq number on non-existent volume
  261. hr = voltab().SetSequenceNumber(volume1, seq);
  262. Check(hr != S_OK);
  263. // create a volume
  264. TryCreateVolume(mcid1, secret1, & volume1);
  265. // check we can query it if it is us
  266. hr = voltab().QueryVolume(mcid1, volume1, &seq, &ft);
  267. Check(hr == S_OK);
  268. // check we can't query it if it isn't us
  269. hr = voltab().QueryVolume(mcid2, volume1, &seq, &ft);
  270. Check(hr == TRK_S_VOLUME_NOT_OWNED);
  271. // Check Claims
  272. // claim a non-existent volume
  273. hr = voltab().ClaimVolume(mcid1, volume2, secret1, secret1, &seq, &ft);
  274. Check(hr == TRK_S_VOLUME_NOT_FOUND);
  275. // claim an existent volume using the wrong secret
  276. hr = voltab().ClaimVolume(mcid2, volume1, secret2, secret2, &seq, &ft);
  277. Check(hr == TRK_E_VOLUME_ACCESS_DENIED);
  278. // claim an existent volume using the right secret
  279. hr = voltab().ClaimVolume(mcid2, volume1, secret1, secret1, &seq, &ft);
  280. Check(hr == S_OK);
  281. // check the query fails from the original machine
  282. hr = voltab().QueryVolume(mcid1, volume1, &seq, &ft);
  283. Check(hr == TRK_S_VOLUME_NOT_OWNED);
  284. // check the query succeeds from the new machine
  285. hr = voltab().QueryVolume(mcid2, volume1, &seq, &ft);
  286. Check(hr == S_OK);
  287. // Check sequence numbers
  288. SequenceNumber seq2 = seq;
  289. seq ++;
  290. hr = voltab().SetSequenceNumber(volume1, seq);
  291. Check(hr == S_OK);
  292. SequenceNumber seq3;
  293. hr = voltab().QueryVolume(mcid2, volume1, &seq3, &ft);
  294. Check(hr == S_OK);
  295. Check(seq3 == seq);
  296. Check(seq2 + 1 == seq);
  297. }
  298. class CSegString
  299. {
  300. public:
  301. CSegString(int length);
  302. ~CSegString();
  303. private:
  304. };
  305. class CSegment
  306. {
  307. public:
  308. CSegment() { _fInitialized = FALSE; }
  309. ~CSegment();
  310. const CDomainRelativeObjId Current();
  311. const CDomainRelativeObjId New();
  312. const CDomainRelativeObjId Birth();
  313. private:
  314. BOOL _fInitialized;
  315. };
  316. class COrder
  317. {
  318. public:
  319. COrder(int iLength, int iCurrent) : _iLength(iLength) { }
  320. ~COrder();
  321. BOOL GetSegment(CSegment * pSegment);
  322. private:
  323. int _iLength;
  324. };
  325. class COrderEnum
  326. {
  327. public:
  328. COrderEnum(int length);
  329. ~COrderEnum();
  330. BOOL GetOrder(COrder * pOrder);
  331. private:
  332. int _iCurrent;
  333. int _iEnd;
  334. int _iLength;
  335. };
  336. COrderEnum::COrderEnum(int iLength)
  337. {
  338. _iLength = iLength;
  339. _iCurrent = 1;
  340. _iEnd = 1;
  341. while (iLength)
  342. {
  343. _iEnd *= iLength;
  344. iLength --;
  345. }
  346. }
  347. BOOL
  348. COrderEnum::GetOrder(COrder * pOrder)
  349. {
  350. if (_iCurrent > _iEnd)
  351. {
  352. return(FALSE);
  353. }
  354. return(TRUE);
  355. }
  356. void
  357. CTestSvrSvc::DoIdt()
  358. {
  359. int cChanges=0;
  360. CDomainRelativeObjId droidCurrent, droidBirth, droidNew;
  361. memcpy( &droidCurrent, "12345678", 8 );
  362. droidBirth = droidCurrent;
  363. memcpy( &droidNew, "87654321", 8 );
  364. _svc.MoveNotify(droidCurrent, droidBirth, droidNew, &cChanges);
  365. CDomainRelativeObjId droidNewRead, droidBirthRead;
  366. idt().Query(droidBirth, &droidNewRead, &droidBirthRead);
  367. Check( droidNewRead == droidNew );
  368. #if 0
  369. // Each letter represents a (volume,oid) pair
  370. //
  371. // Various string lengths:
  372. //
  373. // Length 1:
  374. // a->b a (1 order A)
  375. //
  376. //
  377. // Length 2:
  378. // a->b a, b->c a (2 orders AB, BA)
  379. //
  380. //
  381. // Length 3:
  382. // a->b a, b->c a, c->d a (6 orders ABC, ACB, BAC, BCA, CAB, CBA)
  383. //
  384. //
  385. // Each combination could have a non-matching birth id which should prevent shortening and search
  386. // Each segment can be created either through replication (directly to idt) or
  387. // through MoveNotify.
  388. // Each segment can be shortened through MoveNotify or Search
  389. //
  390. // three lengths
  391. for (int l=1; l<=3; l++)
  392. {
  393. COrderEnum oe(l);
  394. COrder o;
  395. while (oe.GetOrder(&o))
  396. {
  397. CSegString ss(l); // make segment string of length l
  398. BOOL fFirst = TRUE;
  399. CSegment seg, segFirst, segLast;
  400. int index;
  401. while (-1 != (index = o.GetIndex()))
  402. {
  403. seg = ss[index];
  404. if (fFirst)
  405. {
  406. segFirst = seg;
  407. fFirst = FALSE;
  408. }
  409. TRKSVR_MOVE_NOTIFICATION Notification;
  410. Notification.ldCurrent = seg.Current();
  411. Notification.ldNew = seg.New();
  412. Notification.ldBirth = seg.Birth();
  413. _svc.MoveNotify(Notification);
  414. segLast = seg;
  415. }
  416. CDomainRelativeObjId ldNew, ldBirth;
  417. idt().Query(segFirst.Birth(), &ldNew, &ldBirth);
  418. Check(ldNew == segLast.Current());
  419. }
  420. }
  421. #endif // #if 0
  422. }
  423. void
  424. CTestSvrSvc::DoRunTests()
  425. {
  426. DoVolumeTable();
  427. DoIdt();
  428. }
  429. void
  430. CTestSvrSvc::DoSwitch(TCHAR ** &tszArgs, int & cArgs, BOOL & fError)
  431. {
  432. if (cArgs == 0)
  433. {
  434. return;
  435. }
  436. switch (tszArgs[0][1])
  437. {
  438. case TEXT('a'):
  439. case TEXT('A'):
  440. if (cArgs >= 4)
  441. {
  442. DoAdd(tszArgs[1], tszArgs[2], tszArgs[3]);
  443. cArgs -= 4;
  444. tszArgs += 4;
  445. fError = FALSE;
  446. }
  447. break;
  448. case TEXT('d'):
  449. case TEXT('D'):
  450. if (cArgs >= 2)
  451. {
  452. DoDelete(tszArgs[1]);
  453. cArgs -= 2;
  454. tszArgs += 2;
  455. fError = FALSE;
  456. }
  457. break;
  458. case TEXT('m'):
  459. case TEXT('M'):
  460. if (cArgs >= 4)
  461. {
  462. DoModify(tszArgs[1], tszArgs[2], tszArgs[3]);
  463. cArgs -= 4;
  464. tszArgs += 4;
  465. fError = FALSE;
  466. }
  467. break;
  468. case TEXT('q'):
  469. case TEXT('Q'):
  470. if (cArgs >= 2)
  471. {
  472. DoQuery(tszArgs[1]);
  473. cArgs -= 2;
  474. tszArgs += 2;
  475. fError = FALSE;
  476. }
  477. break;
  478. case TEXT('t'):
  479. case TEXT('T'):
  480. if (cArgs >= 2)
  481. {
  482. DoTouch(tszArgs[1]);
  483. cArgs -= 2;
  484. tszArgs += 2;
  485. fError = FALSE;
  486. }
  487. break;
  488. case TEXT('f'):
  489. case TEXT('F'):
  490. if (cArgs >= 2)
  491. {
  492. DoFill(tszArgs[1]);
  493. cArgs -= 2;
  494. tszArgs += 2;
  495. fError = FALSE;
  496. }
  497. break;
  498. case TEXT('p'):
  499. case TEXT('P'):
  500. if (cArgs >= 1)
  501. {
  502. DoPurge();
  503. cArgs -= 1;
  504. tszArgs += 1;
  505. fError = FALSE;
  506. }
  507. break;
  508. case TEXT('c'):
  509. case TEXT('C'):
  510. DoCachePurge();
  511. cArgs -= 1;
  512. tszArgs += 1;
  513. fError = FALSE;
  514. break;
  515. case TEXT('r'):
  516. case TEXT('R'):
  517. DoRunTests();
  518. cArgs -= 1;
  519. tszArgs += 1;
  520. fError = FALSE;
  521. break;
  522. case TEXT('i'):
  523. case TEXT('I'):
  524. printf("Type a command line switch at the prompt (control-c to exit.)\n");
  525. do
  526. {
  527. TCHAR buf[256];
  528. TCHAR * tszArgs2[16];
  529. TCHAR ** tszArgsI = tszArgs2;
  530. int cArgsI=0;
  531. BOOL fError2;
  532. printf("> ");
  533. _getts(buf);
  534. TCHAR * p = buf;
  535. while (*p)
  536. {
  537. tszArgs2[cArgsI++] = p++;
  538. while (*p && *p != TEXT(' ')) p++;
  539. if (*p == ' ')
  540. {
  541. *p = 0;
  542. p++;
  543. }
  544. }
  545. DoSwitch(tszArgsI, cArgsI, fError2);
  546. }
  547. while (TRUE);
  548. break;
  549. default:
  550. break;
  551. }
  552. }
  553. EXTERN_C int __cdecl _tmain(int cArgs, TCHAR **tszArgs )
  554. {
  555. BOOL fError = FALSE;
  556. HRESULT hr;
  557. LARGE_INTEGER liFreq;
  558. CTestSvrSvc test;
  559. __try
  560. {
  561. TrkDebugCreate( TRK_DBG_FLAGS_WRITE_TO_DBG | TRK_DBG_FLAGS_WRITE_TO_STDOUT, "TLDAP" );
  562. g_Debug = 0xffffffff & ~TRKDBG_WORKMAN;
  563. test.Initialize();
  564. cArgs--;
  565. tszArgs++;
  566. redo:
  567. if (cArgs == 0)
  568. {
  569. fError = TRUE;
  570. }
  571. while (!fError && cArgs > 0)
  572. {
  573. fError = TRUE;
  574. if (tszArgs[0][0] == '-' || tszArgs[0][0] == '/')
  575. {
  576. test.DoSwitch(tszArgs, cArgs, fError);
  577. }
  578. }
  579. if (fError)
  580. {
  581. printf("Usage: \n");
  582. printf(" Operation Params\n");
  583. printf(" --------- ------\n");
  584. printf(" Add -a <key> <cur> <birthid>\n");
  585. printf(" Delete -d <key>\n");
  586. printf(" Modify -m <key> <cur> <birthid>\n");
  587. printf(" Query -q <key>\n");
  588. printf(" Touch -t <key>\n");
  589. printf(" Fill -f <number of entries> // aaa,aab,aac ...\n");
  590. printf(" Purge -p 'purge all server database state'\n");
  591. printf(" Cache Purge -c\n");
  592. printf(" Run tests -r\n");
  593. printf(" Interactive -i\n");
  594. }
  595. hr = S_OK;
  596. }
  597. __except (BreakOnDebuggableException())
  598. {
  599. printf("Exception number %08X caught\n", GetExceptionCode());
  600. hr = GetExceptionCode();
  601. }
  602. test.UnInitialize(hr);
  603. Exit:
  604. return(0);
  605. }
  606. #else
  607. EXTERN_C int __cdecl _tmain(int cArgs, TCHAR **tszArgs )
  608. {
  609. printf("Retail build of tldap.exe doesn't run\n");
  610. return(0);
  611. }
  612. #endif