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.

1871 lines
46 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. frstest.c
  5. Abstract:
  6. Test some internals.
  7. Author:
  8. Billy J. Fuller 20-Mar-1997
  9. Environment
  10. User mode winnt
  11. --*/
  12. #include <ntreppch.h>
  13. #pragma hdrstop
  14. #include <frs.h>
  15. #include <test.h>
  16. #if DBG
  17. #define FID_BEGIN ( 0)
  18. #define FID_CONFLICT_FILE ( 1)
  19. #define FID_DONE_CONFLICT_FILE ( 2)
  20. #define FID_DONE (128)
  21. ULONG FidStep = FID_BEGIN;
  22. //
  23. // DBS RENAME FID
  24. //
  25. VOID
  26. TestDbsRenameFidTop(
  27. IN PCHANGE_ORDER_ENTRY Coe
  28. )
  29. /*++
  30. Routine Description:
  31. Test dbs rename fid. Called before DbsRenameFid()
  32. Arguments:
  33. Coe - change order entry containing the final name.
  34. Return Value:
  35. None.
  36. --*/
  37. {
  38. #undef DEBSUB
  39. #define DEBSUB "TestDbsRenameFidTop:"
  40. DWORD WStatus;
  41. HANDLE Handle;
  42. PWCHAR MorphName;
  43. PCHANGE_ORDER_COMMAND Coc = &Coe->Cmd;
  44. if (!DebugInfo.TestFid)
  45. return;
  46. switch (FidStep) {
  47. case FID_DONE_CONFLICT_FILE:
  48. case FID_DONE:
  49. break;
  50. case FID_BEGIN:
  51. DPRINT(0, "TEST: FID BEGIN\n");
  52. FidStep = FID_CONFLICT_FILE;
  53. /* FALL THROUGH */
  54. case FID_CONFLICT_FILE:
  55. DPRINT(0, "TEST: FID CONFLICT BEGIN\n");
  56. //
  57. // Open the conflicting file
  58. //
  59. WStatus = FrsCreateFileRelativeById(&Handle,
  60. Coe->NewReplica->pVme->VolumeHandle,
  61. &Coe->NewParentFid,
  62. FILE_ID_LENGTH,
  63. 0,
  64. Coc->FileName,
  65. Coc->FileNameLength,
  66. NULL,
  67. FILE_CREATE,
  68. READ_ACCESS | DELETE);
  69. if (!WIN_SUCCESS(WStatus)) {
  70. DPRINT1(0, "TEST FID CONFLICT ERROR; could not create file %ws\n",
  71. Coc->FileName);
  72. FidStep = FID_DONE;
  73. break;
  74. }
  75. CloseHandle(Handle);
  76. FidStep = FID_DONE_CONFLICT_FILE;
  77. break;
  78. default:
  79. DPRINT1(0, "TEST: FID ERROR; unknown step %d\n", FidStep);
  80. return;
  81. }
  82. }
  83. VOID
  84. TestDbsRenameFidBottom(
  85. IN PCHANGE_ORDER_ENTRY Coe,
  86. IN DWORD WStatus
  87. )
  88. /*++
  89. Routine Description:
  90. Test dbs rename fid. Called after DbsRenameFid()
  91. Arguments:
  92. Coe - change order entry containing the final name.
  93. Ret
  94. Return Value:
  95. None.
  96. --*/
  97. {
  98. #undef DEBSUB
  99. #define DEBSUB "TestDbsRenameFidBottom:"
  100. if (!DebugInfo.TestFid)
  101. return;
  102. switch (FidStep) {
  103. case FID_DONE:
  104. case FID_CONFLICT_FILE:
  105. break;
  106. case FID_DONE_CONFLICT_FILE:
  107. DPRINT_WS(0, "TEST: NO FID CONFLICT ERROR;", WStatus);
  108. FidStep = FID_DONE;
  109. DPRINT(0, "TEST: FID CONFLICT DONE\n");
  110. break;
  111. default:
  112. DPRINT1(0, "TEST: FID ERROR; unknown step %d\n", FidStep);
  113. return;
  114. }
  115. }
  116. //
  117. // BEGIN QUEUE TEST SUBROUTINES
  118. //
  119. DWORD DesiredStatus;
  120. BOOL CompletionRet = TRUE;
  121. VOID
  122. CompletionRoutine(
  123. IN PCOMMAND_PACKET Cmd,
  124. IN PVOID Arg
  125. )
  126. {
  127. #undef DEBSUB
  128. #define DEBSUB "CompletionRoutine:"
  129. if (Cmd->ErrorStatus != DesiredStatus) {
  130. DPRINT2(0, "ERROR -- ErrorStatus is %x; not %x\n", Cmd->ErrorStatus, DesiredStatus);
  131. CompletionRet = FALSE;
  132. }
  133. //
  134. // move on to the next queue
  135. //
  136. FrsRtlInsertTailQueue(Arg, &Cmd->ListEntry);
  137. }
  138. #define NUMPKTS (97)
  139. #define NUMQUEUES (17)
  140. BOOL
  141. TestEmptyQueues(
  142. PWCHAR Str,
  143. PFRS_QUEUE Queues,
  144. PFRS_QUEUE Control,
  145. DWORD ExpectedErr
  146. )
  147. /*++
  148. Routine Description:
  149. Check that the queues are empty
  150. Arguments:
  151. None.
  152. Return Value:
  153. TRUE - test passed
  154. FALSE - test failed; see listing
  155. --*/
  156. {
  157. #undef DEBSUB
  158. #define DEBSUB "TestEmptyQueues:"
  159. BOOL Ret = TRUE;
  160. DWORD Err;
  161. INT i;
  162. //
  163. // Make sure the queues are empty
  164. //
  165. for (i = 0; i < NUMQUEUES; ++i, ++Queues) {
  166. if (FrsRtlRemoveHeadQueueTimeout(Queues, 0)) {
  167. DPRINT2(0, "ERROR -- %ws -- Queue %d is not empty\n", Str, i);
  168. Ret = FALSE;
  169. } else {
  170. Err = GetLastError();
  171. if (Err != ExpectedErr) {
  172. DPRINT3(0, "ERROR -- %ws -- Error is %d; not %d\n",
  173. Str, Err, ExpectedErr);
  174. Ret = FALSE;
  175. }
  176. }
  177. }
  178. if (FrsRtlRemoveHeadQueueTimeout(Control, 0)) {
  179. DPRINT1(0, "ERROR -- %ws -- control is not empty\n", Str);
  180. Ret = FALSE;
  181. }
  182. return Ret;
  183. }
  184. VOID
  185. TestInitQueues(
  186. PWCHAR Str,
  187. PFRS_QUEUE Queues,
  188. PFRS_QUEUE Control,
  189. BOOL Controlled
  190. )
  191. /*++
  192. Routine Description:
  193. Initialize queues
  194. Arguments:
  195. None.
  196. Return Value:
  197. TRUE - test passed
  198. FALSE - test failed; see listing
  199. --*/
  200. {
  201. #undef DEBSUB
  202. #define DEBSUB "TestInitQueues:"
  203. DWORD Err;
  204. INT i;
  205. //
  206. // Create queues
  207. //
  208. FrsInitializeQueue(Control, Control);
  209. for (i = 0; i < NUMQUEUES; ++i, ++Queues) {
  210. if (Controlled)
  211. FrsInitializeQueue(Queues, Control);
  212. else
  213. FrsInitializeQueue(Queues, Queues);
  214. }
  215. }
  216. VOID
  217. TestPopQueues(
  218. PFRS_QUEUE Queues,
  219. PLIST_ENTRY Entries,
  220. BOOL Tailwise
  221. )
  222. /*++
  223. Routine Description:
  224. Populate a queue
  225. Arguments:
  226. None.
  227. Return Value:
  228. TRUE - test passed
  229. FALSE - test failed; see listing
  230. --*/
  231. {
  232. #undef DEBSUB
  233. #define DEBSUB "TestPopQueues:"
  234. INT EntryIdx, i, j;
  235. PLIST_ENTRY Entry;
  236. PFRS_QUEUE Queue;
  237. PFRS_QUEUE IdledQueue;
  238. //
  239. // Idle the last queue
  240. //
  241. Queue = Queues + (NUMQUEUES - 1);
  242. if (Tailwise)
  243. FrsRtlInsertTailQueue(Queue, Entries);
  244. else
  245. FrsRtlInsertHeadQueue(Queue, Entries);
  246. Entry = FrsRtlRemoveHeadQueueTimeoutIdled(Queue, 0, &IdledQueue);
  247. FRS_ASSERT(Entry == Entries);
  248. if (Tailwise)
  249. FrsRtlInsertTailQueue(Queue, Entries);
  250. else
  251. FrsRtlInsertHeadQueue(Queue, Entries);
  252. //
  253. // Make sure we can extract an entry from an idled queue
  254. //
  255. FrsRtlAcquireQueueLock(Queue);
  256. FrsRtlRemoveEntryQueueLock(Queue, Entry);
  257. FrsRtlReleaseQueueLock(Queue);
  258. FRS_ASSERT(Queue->Count == 0);
  259. FRS_ASSERT(Queue->Control->ControlCount == 0);
  260. //
  261. // Populate the queues
  262. //
  263. EntryIdx = 0;
  264. for (i = 0; i < NUMQUEUES; ++i)
  265. for (j = 0; j < NUMPKTS; ++j, ++EntryIdx) {
  266. if (Tailwise)
  267. FrsRtlInsertTailQueue(Queues + i, Entries + EntryIdx);
  268. else
  269. FrsRtlInsertHeadQueue(Queues + i, Entries + EntryIdx);
  270. }
  271. //
  272. // Unidle the last queue
  273. //
  274. FrsRtlUnIdledQueue(Queue);
  275. }
  276. BOOL
  277. TestCheckQueues(
  278. PWCHAR Str,
  279. PFRS_QUEUE Queues,
  280. PFRS_QUEUE Control,
  281. PLIST_ENTRY Entries,
  282. BOOL Tailwise,
  283. BOOL Controlled,
  284. BOOL DoRundown,
  285. BOOL PullControl,
  286. PFRS_QUEUE *IdledQueue
  287. )
  288. /*++
  289. Routine Description:
  290. test populating a queue
  291. Arguments:
  292. None.
  293. Return Value:
  294. TRUE - test passed
  295. FALSE - test failed; see listing
  296. --*/
  297. {
  298. #undef DEBSUB
  299. #define DEBSUB "TestCheckQueues:"
  300. LIST_ENTRY Rundown;
  301. PLIST_ENTRY Entry;
  302. INT EntryIdx, i, j;
  303. BOOL Ret = TRUE;
  304. //
  305. // Create queues
  306. //
  307. TestInitQueues(Str, Queues, Control, Controlled);
  308. //
  309. // Populate the queues
  310. //
  311. TestPopQueues(Queues, Entries, Tailwise);
  312. //
  313. // Check the population
  314. //
  315. InitializeListHead(&Rundown);
  316. if (Controlled && !DoRundown) {
  317. for (j = 0; j < NUMPKTS; ++j) {
  318. for (i = 0; i < NUMQUEUES; ++i) {
  319. if (PullControl)
  320. Entry = FrsRtlRemoveHeadQueueTimeoutIdled(Control, 0, IdledQueue);
  321. else
  322. Entry = FrsRtlRemoveHeadQueueTimeoutIdled(Queues + i, 0, IdledQueue);
  323. if (Tailwise)
  324. EntryIdx = (i * NUMPKTS) + j;
  325. else
  326. EntryIdx = (i * NUMPKTS) + ((NUMPKTS - 1) - j);
  327. //
  328. // WRONG ENTRY
  329. //
  330. if (Entry != Entries + EntryIdx) {
  331. DPRINT4(0, "ERROR -- %ws -- entry is %x; not %x (Queue %d)\n",
  332. Str, Entry, Entries + EntryIdx, i);
  333. Ret = FALSE;
  334. }
  335. }
  336. if (IdledQueue) {
  337. //
  338. // Make sure the queues are "empty"
  339. //
  340. if (!TestEmptyQueues(Str, Queues, Control, WAIT_TIMEOUT))
  341. Ret = FALSE;
  342. //
  343. // Unidle the queues
  344. //
  345. for (i = 0; i < NUMQUEUES; ++i)
  346. FrsRtlUnIdledQueue(Queues + i);
  347. }
  348. }
  349. } else for (i = 0; i < NUMQUEUES; ++i) {
  350. //
  351. // For rundown, we simply fetch the whole queue at one shot
  352. //
  353. if (DoRundown)
  354. FrsRtlRunDownQueue(Queues + i, &Rundown);
  355. for (j = 0; j < NUMPKTS; ++j) {
  356. //
  357. // For rundown, the entry comes from the list we populated
  358. // above. Otherwise, pull the entry from the queue
  359. //
  360. if (DoRundown) {
  361. Entry = RemoveHeadList(&Rundown);
  362. } else
  363. //
  364. // Pulling from the control queue should get the same
  365. // results as pulling from any of the controlled queues
  366. //
  367. if (PullControl)
  368. Entry = FrsRtlRemoveHeadQueueTimeoutIdled(Control, 0, IdledQueue);
  369. else
  370. Entry = FrsRtlRemoveHeadQueueTimeoutIdled(Queues + i, 0, IdledQueue);
  371. //
  372. // Entries come out of the queue differently depending on
  373. // how they were inserted (tailwise or headwise)
  374. //
  375. if (Tailwise)
  376. EntryIdx = (i * NUMPKTS) + j;
  377. else
  378. EntryIdx = (i * NUMPKTS) + ((NUMPKTS - 1) - j);
  379. //
  380. // WRONG ENTRY
  381. //
  382. if (Entry != Entries + EntryIdx) {
  383. DPRINT4(0, "ERROR -- %ws -- entry is %x; not %x (Queue %d)\n",
  384. Str, Entry, Entries + EntryIdx, i);
  385. Ret = FALSE;
  386. }
  387. //
  388. // Unidle the queue
  389. //
  390. if (IdledQueue && *IdledQueue && !DoRundown)
  391. FrsRtlUnIdledQueue(*IdledQueue);
  392. }
  393. }
  394. //
  395. // Make sure the rundown list is empty
  396. //
  397. if (!IsListEmpty(&Rundown)) {
  398. DPRINT1(0, "ERROR -- %ws -- Rundown is not empty\n", Str);
  399. Ret = FALSE;
  400. }
  401. //
  402. // Make sure the queues are empty
  403. //
  404. if (!TestEmptyQueues(Str, Queues, Control,
  405. (DoRundown) ? ERROR_INVALID_HANDLE : WAIT_TIMEOUT))
  406. Ret = FALSE;
  407. return Ret;
  408. }
  409. #define NUMCOMMANDS (16)
  410. #define NUMSERVERS (16)
  411. COMMAND_SERVER Css[NUMSERVERS];
  412. BOOL TestCommandsRet = TRUE;
  413. DWORD TestCommandsAborted = 0;
  414. VOID
  415. TestCommandsCheckCmd(
  416. IN PCOMMAND_SERVER Cs,
  417. IN PCOMMAND_PACKET Cmd
  418. )
  419. /*++
  420. Routine Description:
  421. Check the consistency of the command packet
  422. Arguments:
  423. None.
  424. Return Value:
  425. None.
  426. --*/
  427. {
  428. #undef DEBSUB
  429. #define DEBSUB "TestCommandsCheckCmd:"
  430. DWORD CsIdx;
  431. PFRS_QUEUE Control;
  432. PCOMMAND_SERVER CmdCs;
  433. //
  434. // Check the command
  435. //
  436. if (Cmd->Command != CMD_INIT_SUBSYSTEM) {
  437. DPRINT2(0, "ERROR -- Command is %d; not %d\n",
  438. Cmd->Command, CMD_INIT_SUBSYSTEM);
  439. TestCommandsRet = FALSE;
  440. }
  441. Control = Cmd->TargetQueue->Control;
  442. CmdCs = CONTAINING_RECORD(Control, COMMAND_SERVER, Control);
  443. if (Cs && CmdCs != Cs) {
  444. DPRINT2(0, "ERROR -- Command Cs is %x; not %x\n", CmdCs, Cs);
  445. TestCommandsRet = FALSE;
  446. }
  447. //
  448. // Check the completion argument
  449. //
  450. if (CmdCs != Cmd->CompletionArg) {
  451. DPRINT2(0, "ERROR -- Completion Cs is %x; not %x\n",
  452. Cmd->CompletionArg, CmdCs);
  453. TestCommandsRet = FALSE;
  454. }
  455. //
  456. // Check our argument
  457. //
  458. CsIdx = TestIndex(Cmd);
  459. if (CmdCs != &Css[CsIdx]) {
  460. DPRINT2(0, "ERROR -- Server index is %d; not %d\n",
  461. CsIdx, (CmdCs - &Css[0]) / sizeof(COMMAND_SERVER));
  462. TestCommandsRet = FALSE;
  463. }
  464. }
  465. #if _MSC_FULL_VER >= 13008827
  466. #pragma warning(push)
  467. #pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
  468. #endif
  469. DWORD
  470. TestCommandsMain(
  471. IN PVOID Arg
  472. )
  473. /*++
  474. Routine Description:
  475. Test command server subsystem completion routine. Move the command
  476. on to the next command server.
  477. Arguments:
  478. None.
  479. Return Value:
  480. None.
  481. --*/
  482. {
  483. #undef DEBSUB
  484. #define DEBSUB "TestCommandsMain:"
  485. PFRS_THREAD FrsThread = Arg;
  486. PCOMMAND_PACKET Cmd;
  487. PCOMMAND_SERVER Cs;
  488. DWORD CsIdx;
  489. DWORD Status;
  490. Cs = FrsThread->Data;
  491. cant_exit_yet:
  492. while (Cmd = FrsGetCommandServer(Cs)) {
  493. TestCommandsCheckCmd(Cs, Cmd);
  494. //
  495. // Make sure the command server is not idle
  496. //
  497. Status = FrsWaitForCommandServer(Cs, 0);
  498. if (Status != WAIT_TIMEOUT) {
  499. DPRINT(0, "ERROR -- command server is idle\n");
  500. TestCommandsRet = FALSE;
  501. }
  502. //
  503. // Propagate to next command server
  504. //
  505. CsIdx = TestIndex(Cmd) + 1;
  506. if (CsIdx >= NUMSERVERS) {
  507. DPRINT(0, "ERROR -- Last server index\n");
  508. TestCommandsRet = FALSE;
  509. } else {
  510. TestIndex(Cmd) = CsIdx;
  511. Cmd->TargetQueue = &Css[CsIdx].Queue;
  512. Cmd->CompletionArg = &Css[CsIdx];
  513. FrsSubmitCommandServer(&Css[CsIdx], Cmd);
  514. }
  515. }
  516. FrsExitCommandServer(Cs, FrsThread);
  517. goto cant_exit_yet;
  518. return ERROR_SUCCESS;
  519. }
  520. #if _MSC_FULL_VER >= 13008827
  521. #pragma warning(pop)
  522. #endif
  523. VOID
  524. TestCommandsCompletion(
  525. IN PCOMMAND_PACKET Cmd,
  526. IN PVOID Arg
  527. )
  528. /*++
  529. Routine Description:
  530. Test command server subsystem completion routine. Move the command
  531. on to the next command server.
  532. Arguments:
  533. None.
  534. Return Value:
  535. None.
  536. --*/
  537. {
  538. #undef DEBSUB
  539. #define DEBSUB "TestCommandsCompletion:"
  540. if (Cmd->ErrorStatus == ERROR_ACCESS_DENIED) {
  541. ++TestCommandsAborted;
  542. if (!WIN_SUCCESS(Cmd->ErrorStatus)) {
  543. DPRINT2(0, "ERROR -- ErrorStatus is %d; not %d\n",
  544. Cmd->ErrorStatus, ERROR_SUCCESS);
  545. }
  546. }
  547. TestCommandsCheckCmd(NULL, Cmd);
  548. FrsSetCompletionRoutine(Cmd, FrsFreeCommand, NULL);
  549. FrsCompleteCommand(Cmd, ERROR_SUCCESS);
  550. }
  551. BOOL
  552. TestCommands(
  553. VOID
  554. )
  555. /*++
  556. Routine Description:
  557. Test command server subsystem
  558. Arguments:
  559. None.
  560. Return Value:
  561. TRUE - test passed
  562. FALSE - test failed; see listing
  563. --*/
  564. {
  565. #undef DEBSUB
  566. #define DEBSUB "TestCommands:"
  567. DWORD i;
  568. DWORD Status;
  569. PCOMMAND_PACKET Cmd;
  570. PCOMMAND_PACKET Cmds[NUMCOMMANDS];
  571. FRS_ASSERT(NUMSERVERS > 1);
  572. FRS_ASSERT(NUMCOMMANDS > 1);
  573. //
  574. // Initialize the servers. The last server disables automatic
  575. // thread management so that this thread can manage the last
  576. // command queue itself.
  577. //
  578. for (i = 0; i < NUMSERVERS - 1; ++i)
  579. FrsInitializeCommandServer(&Css[i], 4, L"TestCs", TestCommandsMain);
  580. FrsInitializeCommandServer(&Css[i], 0, L"TestCs", NULL);
  581. //
  582. // Submit commands to the first server. These commands will
  583. // propagate thru the command servers until they end up on the
  584. // last command queue where we will extract them.
  585. //
  586. for (i = 0; i < NUMCOMMANDS; ++i) {
  587. Cmds[i] = FrsAllocCommand(&Css[0].Queue, CMD_INIT_SUBSYSTEM);
  588. FrsSetCompletionRoutine(Cmds[i], TestCommandsCompletion, &Css[0]);
  589. FrsSubmitCommandServer(&Css[0], Cmds[i]);
  590. }
  591. //
  592. // Extract all but the last command from the last queue. We
  593. // will allow the abort code to clean up the last command.
  594. //
  595. for (i = 0; i < NUMCOMMANDS - 1; ++i) {
  596. Cmd = FrsGetCommandServer(&Css[NUMSERVERS - 1]);
  597. if (Cmd != Cmds[i]) {
  598. DPRINT2(0, "ERROR -- Cmd is %x; not %x\n", Cmd, Cmds[i]);
  599. TestCommandsRet = FALSE;
  600. }
  601. //
  602. // Probably timed out
  603. //
  604. if (Cmd == NULL) {
  605. DPRINT(0, "ERROR -- Cmd is NULL; probably timed out\n");
  606. TestCommandsRet = FALSE;
  607. break;
  608. }
  609. TestCommandsCheckCmd(NULL, Cmd);
  610. FrsSetCompletionRoutine(Cmd, FrsFreeCommand, NULL);
  611. FrsCompleteCommand(Cmd, ERROR_SUCCESS);
  612. }
  613. //
  614. // All but the last command server should be idle
  615. //
  616. for (i = 0; i < NUMSERVERS - 1; ++i) {
  617. Status = FrsWaitForCommandServer(&Css[i], 0);
  618. if (Status != WAIT_OBJECT_0) {
  619. DPRINT(0, "ERROR -- command server is not idle\n");
  620. TestCommandsRet = FALSE;
  621. }
  622. }
  623. //
  624. // Last command server should always be idle
  625. //
  626. Status = FrsWaitForCommandServer(&Css[NUMSERVERS - 1], 0);
  627. if (Status != WAIT_OBJECT_0) {
  628. DPRINT(0, "ERROR -- last command server is not idle (w/command)\n");
  629. TestCommandsRet = FALSE;
  630. }
  631. //
  632. // Abort the command servers
  633. //
  634. for (i = 0; i < NUMSERVERS; ++i)
  635. FrsRunDownCommandServer(&Css[i], &Css[i].Queue);
  636. //
  637. // Wait for the threads to exit
  638. //
  639. ThSupExitThreadGroup(TestCommandsMain);
  640. //
  641. // We should have aborted one command
  642. //
  643. if (TestCommandsAborted != 1) {
  644. DPRINT1(0, "ERROR -- Aborted is %d; not 1\n", TestCommandsAborted);
  645. TestCommandsRet = FALSE;
  646. }
  647. //
  648. // Last command server should be idle
  649. //
  650. Status = FrsWaitForCommandServer(&Css[NUMSERVERS - 1], 0);
  651. if (Status != WAIT_OBJECT_0) {
  652. DPRINT(0, "ERROR -- last command server is not idle\n");
  653. TestCommandsRet = FALSE;
  654. }
  655. return TestCommandsRet;
  656. }
  657. BOOL
  658. TestQueues(
  659. VOID
  660. )
  661. /*++
  662. Routine Description:
  663. Test queue subsystem
  664. Arguments:
  665. None.
  666. Return Value:
  667. TRUE - test passed
  668. FALSE - test failed; see listing
  669. --*/
  670. {
  671. #undef DEBSUB
  672. #define DEBSUB "TestQueues:"
  673. BOOL Ret = TRUE;
  674. LONG Err;
  675. INT i, j;
  676. INT EntryIdx;
  677. PLIST_ENTRY Entry;
  678. PCOMMAND_PACKET ECmdPkt;
  679. FRS_QUEUE Control;
  680. PFRS_QUEUE IdledQueue;
  681. FRS_QUEUE Queues[NUMQUEUES];
  682. PCOMMAND_PACKET CmdPkt[NUMPKTS];
  683. LIST_ENTRY Entries[NUMPKTS * NUMQUEUES];
  684. FRS_ASSERT(NUMQUEUES > 1);
  685. DPRINT(0, "scheduled queue is not implemented!!!\n");
  686. Ret = FALSE;
  687. //
  688. // +++++ NORMAL QUEUES
  689. //
  690. if (!TestCheckQueues(L"Tailwise", &Queues[0], &Control, &Entries[0],
  691. TRUE, FALSE, FALSE, FALSE, NULL)) {
  692. Ret = FALSE;
  693. }
  694. if (!TestCheckQueues(L"Tailwise Rundown", &Queues[0], &Control, &Entries[0],
  695. TRUE, FALSE, TRUE, FALSE, NULL)) {
  696. Ret = FALSE;
  697. }
  698. if (!TestCheckQueues(L"Headwise", &Queues[0], &Control, &Entries[0],
  699. FALSE, FALSE, FALSE, FALSE, NULL)) {
  700. Ret = FALSE;
  701. }
  702. if (!TestCheckQueues(L"Headwise Rundown", &Queues[0], &Control, &Entries[0],
  703. FALSE, FALSE, TRUE, FALSE, NULL)) {
  704. Ret = FALSE;
  705. }
  706. //
  707. // +++++ CONTROLLED QUEUES
  708. //
  709. if (!TestCheckQueues(L"Tailwise Controlled", &Queues[0], &Control, &Entries[0],
  710. TRUE, TRUE, FALSE, FALSE, NULL)) {
  711. Ret = FALSE;
  712. }
  713. if (!TestCheckQueues(L"Tailwise Rundown Controlled", &Queues[0], &Control, &Entries[0],
  714. TRUE, TRUE, TRUE, FALSE, NULL)) {
  715. Ret = FALSE;
  716. }
  717. if (!TestCheckQueues(L"Headwise Controlled", &Queues[0], &Control, &Entries[0],
  718. FALSE, TRUE, FALSE, FALSE, NULL)) {
  719. Ret = FALSE;
  720. }
  721. if (!TestCheckQueues(L"Headwise Rundown Controlled", &Queues[0], &Control, &Entries[0],
  722. FALSE, TRUE, TRUE, FALSE, NULL)) {
  723. Ret = FALSE;
  724. }
  725. //
  726. // PULL THE ENTRIES OFF THE CONTROLING QUEUE
  727. //
  728. if (!TestCheckQueues(L"Tailwise Controlled Pull", &Queues[0], &Control, &Entries[0],
  729. TRUE, TRUE, FALSE, TRUE, NULL)) {
  730. Ret = FALSE;
  731. }
  732. if (!TestCheckQueues(L"Headwise Controlled Pull", &Queues[0], &Control, &Entries[0],
  733. FALSE, TRUE, FALSE, TRUE, NULL)) {
  734. Ret = FALSE;
  735. }
  736. //
  737. // +++++ NORMAL QUEUES W/IDLED
  738. //
  739. if (!TestCheckQueues(L"Tailwise Idled", &Queues[0], &Control, &Entries[0],
  740. TRUE, FALSE, FALSE, FALSE, &IdledQueue)) {
  741. Ret = FALSE;
  742. }
  743. //
  744. // +++++ CONTROLLED QUEUES W/IDLED
  745. //
  746. if (!TestCheckQueues(L"Tailwise Controlled Idled", &Queues[0], &Control, &Entries[0],
  747. TRUE, TRUE, FALSE, FALSE, &IdledQueue)) {
  748. Ret = FALSE;
  749. }
  750. if (!TestCheckQueues(L"Tailwise Rundown Controlled Idled", &Queues[0], &Control, &Entries[0],
  751. TRUE, TRUE, TRUE, FALSE, &IdledQueue)) {
  752. Ret = FALSE;
  753. }
  754. //
  755. // PULL THE ENTRIES OFF THE CONTROLING QUEUE
  756. //
  757. if (!TestCheckQueues(L"Tailwise Controlled Pull Idled", &Queues[0], &Control, &Entries[0],
  758. TRUE, TRUE, FALSE, TRUE, &IdledQueue)) {
  759. Ret = FALSE;
  760. }
  761. //
  762. // COMMAND QUEUES
  763. //
  764. //
  765. // Check the command subsystem; assumes that queues[0 and 1] are
  766. // initialized and empty
  767. //
  768. //
  769. // Create queues
  770. //
  771. TestInitQueues(L"Start command", &Queues[0], &Control, FALSE);
  772. //
  773. // Put an entry on the queue in a bit
  774. //
  775. for (i = 0; i < NUMPKTS; ++i) {
  776. CmdPkt[i] = FrsAllocCommand(&Queues[0], CMD_INIT_SUBSYSTEM);
  777. FrsSetCompletionRoutine(CmdPkt[i], CompletionRoutine, &Queues[1]);
  778. FrsSubmitCommand(CmdPkt[i], FALSE);
  779. }
  780. //
  781. // Remove them from the first queue
  782. //
  783. for (i = 0; i < NUMPKTS; ++i) {
  784. Entry = FrsRtlRemoveHeadQueueTimeout(&Queues[0], 0);
  785. if (Entry == NULL) {
  786. DPRINT(0, "ERROR -- Entry is not on command queue\n");
  787. Ret = FALSE;
  788. continue;
  789. }
  790. ECmdPkt = CONTAINING_RECORD(Entry, COMMAND_PACKET, ListEntry);
  791. if (CmdPkt[i] != ECmdPkt) {
  792. DPRINT2(0, "ERROR -- Cmd is %x; not %x\n", ECmdPkt, CmdPkt[i]);
  793. Ret = FALSE;
  794. }
  795. if (CmdPkt[i]->ErrorStatus != 0) {
  796. DPRINT1(0, "ERROR -- ErrorStatus is %d, not 0\n", CmdPkt[i]->ErrorStatus);
  797. Ret = FALSE;
  798. }
  799. //
  800. // Move CmdPkt to next queue (calling CompletionRoutine() first)
  801. //
  802. DesiredStatus = -5;
  803. FrsCompleteCommand(CmdPkt[i], -5);
  804. if (Ret)
  805. Ret = CompletionRet;
  806. }
  807. //
  808. // Remove entry from second queue
  809. //
  810. for (i = 0; i < NUMPKTS; ++i) {
  811. Entry = FrsRtlRemoveHeadQueueTimeout(&Queues[1], 0);
  812. if (Entry == NULL) {
  813. DPRINT(0, "ERROR -- Entry is not on command queue 2\n");
  814. Ret = FALSE;
  815. continue;
  816. }
  817. ECmdPkt = CONTAINING_RECORD(Entry, COMMAND_PACKET, ListEntry);
  818. if (CmdPkt[i] != ECmdPkt) {
  819. DPRINT2(0, "ERROR -- Cmd 2 is %x; not %x\n", ECmdPkt, CmdPkt[i]);
  820. Ret = FALSE;
  821. }
  822. if (CmdPkt[i]->ErrorStatus != -5) {
  823. DPRINT1(0, "ERROR -- ErrorStatus 2 is %d, not -5\n", CmdPkt[i]->ErrorStatus);
  824. Ret = FALSE;
  825. }
  826. FrsSetCompletionRoutine(CmdPkt[i], FrsFreeCommand, NULL);
  827. FrsCompleteCommand(CmdPkt[i], ERROR_SUCCESS);
  828. }
  829. //
  830. // Delete the queues
  831. //
  832. for (i = 0; i < NUMQUEUES; ++i)
  833. FrsRtlDeleteQueue(&Queues[i]);
  834. FrsRtlDeleteQueue(&Control);
  835. return Ret;
  836. }
  837. BOOL
  838. TestExceptions(
  839. VOID
  840. )
  841. /*++
  842. Routine Description:
  843. Test exception handler.
  844. Arguments:
  845. None.
  846. Return Value:
  847. TRUE - test passed
  848. FALSE - test failed; see listing
  849. --*/
  850. {
  851. #undef DEBSUB
  852. #define DEBSUB "TestExceptions:"
  853. DWORD i;
  854. ULONG_PTR Err;
  855. BOOL Ret = TRUE;
  856. PWCHAR Msg = TEXT("Testing Exceptions");
  857. //
  858. // Test the exceptions
  859. //
  860. FrsExceptionQuiet(TRUE);
  861. for (i = 0; i < FRS_MAX_ERROR_CODE; ++i) {
  862. try {
  863. Err = i;
  864. if (i == FRS_ERROR_LISTEN) {
  865. Err = (ULONG_PTR)Msg;
  866. }
  867. FrsRaiseException(i, Err);
  868. } except (FrsException(GetExceptionInformation())) {
  869. if (i != FrsExceptionLastCode() || Err != FrsExceptionLastInfo()) {
  870. DPRINT1(0, "\t\tException %d is not working\n", i);
  871. Ret = FALSE;
  872. }
  873. }
  874. }
  875. FrsExceptionQuiet(FALSE);
  876. return Ret;
  877. }
  878. //
  879. // Test concurrency and threads subsystem
  880. //
  881. #define NUMBER_OF_HANDLES (16)
  882. handle_t FrsRpcHandle[NUMBER_OF_HANDLES];
  883. static NTSTATUS
  884. FrsRpcThread(
  885. PVOID Arg
  886. )
  887. /*++
  888. Routine Description:
  889. Bind to the server, call the FRS NOP RPC function, and unbind.
  890. Arguments:
  891. Arg - Address of this thread's context
  892. Return Value:
  893. ERROR_OPERATION_ABORTED or the status returned by the RPC call.
  894. --*/
  895. {
  896. #undef DEBSUB
  897. #define DEBSUB "FrsRpcThread:"
  898. NTSTATUS Status;
  899. handle_t *Handle;
  900. PGNAME Name;
  901. Status = ERROR_OPERATION_ABORTED;
  902. try {
  903. try {
  904. Handle = (handle_t *)ThSupGetThreadData((PFRS_THREAD)Arg);
  905. Name = FrsBuildGName(FrsDupGuid(ServerGuid), FrsWcsDup(ComputerName));
  906. FrsRpcBindToServer(Name, NULL, CXTION_AUTH_NONE, Handle);
  907. FrsFreeGName(Name);
  908. Status = FrsNOP(*Handle);
  909. FrsRpcUnBindFromServer(Handle);
  910. } except (FrsException(GetExceptionInformation())) {
  911. Status = FrsExceptionLastCode();
  912. }
  913. } finally {
  914. }
  915. return Status;
  916. }
  917. BOOL
  918. TestRpc(
  919. VOID
  920. )
  921. /*++
  922. Routine Description:
  923. Test RPC
  924. Arguments:
  925. None.
  926. Return Value:
  927. TRUE - test passed
  928. FALSE - test failed; see listing
  929. --*/
  930. {
  931. #undef DEBSUB
  932. #define DEBSUB "TestRpc:"
  933. DWORD i;
  934. DWORD Err;
  935. PFRS_THREAD FrsThread;
  936. BOOL Ret = TRUE;
  937. handle_t Handle;
  938. PGNAME Name;
  939. //
  940. // Testing RPC
  941. //
  942. //
  943. // Wait for the comm subsystem to be initialized
  944. //
  945. WaitForSingleObject(CommEvent, INFINITE);
  946. //
  947. // Test RPC concurrency
  948. //
  949. for (i = 0; i < NUMBER_OF_HANDLES; ++i) {
  950. if (!ThSupCreateThread(L"TestThread", (PVOID)&FrsRpcHandle[i], FrsRpcThread, NULL)) {
  951. DPRINT1(0, "\t\tCould not create RPC thread %d\n", i);
  952. Ret = FALSE;
  953. }
  954. }
  955. for (i = 0; i < NUMBER_OF_HANDLES; ++i) {
  956. FrsThread = ThSupGetThread(FrsRpcThread);
  957. if (FrsThread) {
  958. Err = ThSupWaitThread(FrsThread, INFINITE);
  959. if (!WIN_SUCCESS(Err)) {
  960. DPRINT1(0, "\t\tRPC thread returned %d\n", Err);
  961. Ret = FALSE;
  962. }
  963. ThSupReleaseRef(FrsThread);
  964. } else {
  965. DPRINT1(0, "\t\tCould not find RPC thread %d\n", i);
  966. Ret = FALSE;
  967. }
  968. }
  969. //
  970. // quick check of the threads subsystem
  971. //
  972. for (i = 0; i < NUMBER_OF_HANDLES; ++i) {
  973. FrsThread = ThSupGetThread(FrsRpcThread);
  974. if (FrsThread) {
  975. DPRINT1(0, "\t\tRPC thread %d still exists!\n", i);
  976. Ret = FALSE;
  977. ThSupReleaseRef(FrsThread);
  978. }
  979. }
  980. Name = FrsBuildGName(FrsDupGuid(ServerGuid), FrsWcsDup(ComputerName));
  981. FrsRpcBindToServer(Name, NULL, CXTION_AUTH_NONE, &Handle);
  982. FrsFreeGName(Name);
  983. Err = FrsEnumerateReplicaPathnames(Handle);
  984. if (Err != ERROR_CALL_NOT_IMPLEMENTED) {
  985. DPRINT1(0, "\t\tFrsEnumerateReplicaPathnames returned %d\n", Err);
  986. Ret = FALSE;
  987. }
  988. Err = FrsFreeReplicaPathnames(Handle);
  989. if (Err != ERROR_CALL_NOT_IMPLEMENTED) {
  990. DPRINT1(0, "\t\tFrsFreeReplicaPathnames returned %d\n", Err);
  991. Ret = FALSE;
  992. }
  993. Err = FrsPrepareForBackup(Handle);
  994. if (Err != ERROR_CALL_NOT_IMPLEMENTED) {
  995. DPRINT1(0, "\t\tFrsPrepareForBackup returned %d\n", Err);
  996. Ret = FALSE;
  997. }
  998. Err = FrsBackupComplete(Handle);
  999. if (Err != ERROR_CALL_NOT_IMPLEMENTED) {
  1000. DPRINT1(0, "\t\tFrsBackupComplete returned %d\n", Err);
  1001. Ret = FALSE;
  1002. }
  1003. Err = FrsPrepareForRestore(Handle);
  1004. if (Err != ERROR_CALL_NOT_IMPLEMENTED) {
  1005. DPRINT1(0, "\t\tFrsPrepareForRestore returned %d\n", Err);
  1006. Ret = FALSE;
  1007. }
  1008. Err = FrsRestoreComplete(Handle);
  1009. if (Err != ERROR_CALL_NOT_IMPLEMENTED) {
  1010. DPRINT1(0, "\t\tFrsRestoreComplete returned %d\n", Err);
  1011. Ret = FALSE;
  1012. }
  1013. FrsRpcUnBindFromServer(&Handle);
  1014. return Ret;
  1015. }
  1016. #define TEST_OPLOCK_FILE L"C:\\TEMP\\OPLOCK.TMP"
  1017. ULONG
  1018. TestOpLockThread(
  1019. PVOID Arg
  1020. )
  1021. /*++
  1022. Routine Description:
  1023. Test oplock support
  1024. Arguments:
  1025. Arg.
  1026. Return Value:
  1027. TRUE - test passed
  1028. FALSE - test failed; see listing
  1029. --*/
  1030. {
  1031. #undef DEBSUB
  1032. #define DEBSUB "TestOpLockThread:"
  1033. PFRS_THREAD Thread = Arg;
  1034. PVOID DoWrite = Thread->Data;
  1035. HANDLE Handle = INVALID_HANDLE_VALUE;
  1036. //
  1037. // Trigger the oplock filter
  1038. //
  1039. FrsOpenSourceFileW(&Handle,
  1040. TEST_OPLOCK_FILE,
  1041. (DoWrite) ? GENERIC_WRITE | SYNCHRONIZE :
  1042. GENERIC_READ | GENERIC_EXECUTE | SYNCHRONIZE,
  1043. OPEN_OPTIONS);
  1044. if (!HANDLE_IS_VALID(Handle)) {
  1045. return ERROR_FILE_NOT_FOUND;
  1046. }
  1047. CloseHandle(Handle);
  1048. return ERROR_SUCCESS;
  1049. }
  1050. BOOL
  1051. TestOpLocks(
  1052. VOID
  1053. )
  1054. /*++
  1055. Routine Description:
  1056. Test oplock support
  1057. Arguments:
  1058. None.
  1059. Return Value:
  1060. TRUE - test passed
  1061. FALSE - test failed; see listing
  1062. --*/
  1063. {
  1064. #undef DEBSUB
  1065. #define DEBSUB "TestOpLocks:"
  1066. OVERLAPPED OverLap;
  1067. DWORD BytesReturned;
  1068. HANDLE Handle;
  1069. PFRS_THREAD Thread;
  1070. DWORD Status;
  1071. //
  1072. // Initialize for later cleanup
  1073. //
  1074. Handle = INVALID_HANDLE_VALUE;
  1075. Thread = NULL;
  1076. OverLap.hEvent = INVALID_HANDLE_VALUE;
  1077. //
  1078. // Create the temp file
  1079. //
  1080. Status = StuCreateFile(TEST_OPLOCK_FILE, &Handle);
  1081. if (!HANDLE_IS_VALID(Handle) || !WIN_SUCCESS(Status)) {
  1082. DPRINT1(0, "Can't create %ws\n", TEST_OPLOCK_FILE);
  1083. goto errout;
  1084. }
  1085. if (!CloseHandle(Handle))
  1086. goto errout;
  1087. //
  1088. // Create the asynchronous oplock event
  1089. //
  1090. OverLap.Internal = 0;
  1091. OverLap.InternalHigh = 0;
  1092. OverLap.Offset = 0;
  1093. OverLap.OffsetHigh = 0;
  1094. OverLap.hEvent = FrsCreateEvent(TRUE, FALSE);
  1095. //
  1096. // Reserve an oplock filter
  1097. //
  1098. FrsOpenSourceFileW(&Handle, TEST_OPLOCK_FILE, OPLOCK_ACCESS, OPEN_OPLOCK_OPTIONS);
  1099. if (!HANDLE_IS_VALID(Handle)) {
  1100. DPRINT1(0, "Can't open %ws\n", TEST_OPLOCK_FILE);
  1101. goto errout;
  1102. }
  1103. //
  1104. // Pull the hammer back on the oplock trigger
  1105. //
  1106. if (!DeviceIoControl(Handle,
  1107. FSCTL_REQUEST_FILTER_OPLOCK,
  1108. NULL,
  1109. 0,
  1110. NULL,
  1111. 0,
  1112. &BytesReturned,
  1113. &OverLap)) {
  1114. if (GetLastError() != ERROR_IO_PENDING) {
  1115. DPRINT1(0, "Could not cock the oplock; error %d\n", GetLastError());
  1116. goto errout;
  1117. }
  1118. } else
  1119. goto errout;
  1120. //
  1121. // READONLY OPEN BY ANOTHER THREAD
  1122. //
  1123. if (!ThSupCreateThread(L"TestOpLockThread", NULL, TestOpLockThread, NULL)) {
  1124. DPRINT(0, "Can't create thread TestOpLockThread for read\n");
  1125. goto errout;
  1126. }
  1127. if (WaitForSingleObject(OverLap.hEvent, (3 * 1000)) != WAIT_TIMEOUT) {
  1128. DPRINT(0, "***** ERROR -- OPLOCK TRIGGERED ON RO OPEN\n");
  1129. goto errout;
  1130. }
  1131. Thread = ThSupGetThread(TestOpLockThread);
  1132. if (Thread == NULL) {
  1133. DPRINT(0, "Can't find thread TestOpLockThread for read\n");
  1134. goto errout;
  1135. }
  1136. Status = ThSupWaitThread(Thread, 10 * 1000);
  1137. ThSupReleaseRef(Thread);
  1138. Thread = NULL;
  1139. CLEANUP_WS(0, "Read thread terminated with status", Status, errout);
  1140. //
  1141. // WRITE OPEN BY ANOTHER THREAD
  1142. //
  1143. if (!ThSupCreateThread(L"TestOpLockThread", (PVOID)OverLap.hEvent, TestOpLockThread, NULL)) {
  1144. DPRINT(0, "Can't create thread TestOpLockThread for write\n");
  1145. goto errout;
  1146. }
  1147. if (WaitForSingleObject(OverLap.hEvent, (3 * 1000)) != WAIT_OBJECT_0) {
  1148. DPRINT(0, "***** ERROR -- OPLOCK DID NOT TRIGGER ON WRITE OPEN\n");
  1149. goto errout;
  1150. }
  1151. //
  1152. // Release the oplock
  1153. //
  1154. if (!CloseHandle(Handle))
  1155. goto errout;
  1156. Thread = ThSupGetThread(TestOpLockThread);
  1157. if (Thread == NULL) {
  1158. DPRINT(0, "Can't find thread TestOpLockThread for write\n");
  1159. goto errout;
  1160. }
  1161. Status = ThSupWaitThread(Thread, 10 * 1000);
  1162. ThSupReleaseRef(Thread);
  1163. Thread = NULL;
  1164. CLEANUP_WS(0, "Write thread terminated with status", Status, errout);
  1165. FRS_CLOSE(OverLap.hEvent);
  1166. return TRUE;
  1167. errout:
  1168. FRS_CLOSE(Handle);
  1169. FRS_CLOSE(OverLap.hEvent);
  1170. if (Thread) {
  1171. ThSupExitSingleThread(Thread);
  1172. ThSupReleaseRef(Thread);
  1173. }
  1174. return FALSE;
  1175. }
  1176. PWCHAR NestedDirs[] = {
  1177. L"c:\\a\\b", L"c:\\a\\b\\c",
  1178. L"c:\\a\\b\\", L"c:\\a\\b\\c",
  1179. L"c:\\a\\b\\c", L"c:\\a\\b\\c",
  1180. L"c:\\\\a\\b\\c\\\\", L"c:\\a\\\\b\\c",
  1181. L"c:\\\\a\\b\\c", L"c:\\a\\\\b\\c\\\\\\",
  1182. L"\\c:\\\\a\\b\\c", L"\\c:\\a\\\\b\\c\\\\\\",
  1183. L"\\\\\\c:\\\\a\\b\\c", L"\\c:\\a\\\\b\\c\\\\\\",
  1184. L"\\\\\\c:\\\\a\\b\\", L"\\c:\\a\\\\b\\c\\\\\\",
  1185. L"\\\\\\c:\\\\a\\b", L"\\c:\\a\\\\b\\c\\\\\\",
  1186. L"\\\\\\c:\\\\a\\", L"\\c:\\a\\\\b\\c\\\\\\",
  1187. L"\\\\\\c:\\\\a", L"\\c:\\a\\\\b\\c\\\\\\",
  1188. L"\\\\\\c:\\\\", L"\\c:\\a\\\\b\\c\\\\\\",
  1189. L"\\\\\\c:\\", L"\\c:\\a\\\\b\\c\\\\\\",
  1190. L"\\\\\\c:\\", L"\\c:\\a\\\\b\\c",
  1191. NULL, NULL
  1192. };
  1193. PWCHAR NotNestedDirs[] = {
  1194. L"c:\\a\\b\\c", L"e:\\a\\b\\c",
  1195. L"c:\\a\\b\\c", L"c:\\a\\b\\cdef",
  1196. L"c:\\\\a\\b\\c\\", L"c:\\a\\b\\cdef",
  1197. L"c:\\\\a\\b\\c\\\\", L"c:\\a\\b\\cdef\\",
  1198. L"c:\\\\a\\b\\cdef\\\\",L"c:\\a\\b\\c",
  1199. NULL, NULL
  1200. };
  1201. PWCHAR DirsNested[] = {
  1202. L"c:\\a\\b\\c\\d", L"c:\\a\\b\\c",
  1203. L"c:\\a\\b\\c\\d", L"c:\\a\\b",
  1204. L"c:\\a\\b\\c\\d", L"c:\\a",
  1205. L"c:\\a\\b\\c\\d", L"c:\\",
  1206. NULL, NULL
  1207. };
  1208. BOOL
  1209. TestNestedDirs(
  1210. VOID
  1211. )
  1212. /*++
  1213. Routine Description:
  1214. Test nested dirs
  1215. Arguments:
  1216. None.
  1217. Return Value:
  1218. TRUE - test passed
  1219. FALSE - test failed; see listing
  1220. --*/
  1221. {
  1222. #undef DEBSUB
  1223. #define DEBSUB "TestNestedDirs:"
  1224. DWORD i;
  1225. LONG Ret;
  1226. BOOL Passed = TRUE;
  1227. BOOL FinalPassed = TRUE;
  1228. //
  1229. // Nested dirs
  1230. //
  1231. for (i = 0, Ret = TRUE; NestedDirs[i]; i += 2) {
  1232. Ret = FrsIsParent(NestedDirs[i], NestedDirs[i + 1]);
  1233. if (Ret != -1) {
  1234. DPRINT3(0, "ERROR - nested dirs %ws %d %ws\n",
  1235. NestedDirs[i], Ret, NestedDirs[i + 1]);
  1236. Passed = FALSE;
  1237. }
  1238. }
  1239. if (Passed) {
  1240. DPRINT(0, "\t\tPassed nested dirs\n");
  1241. } else {
  1242. FinalPassed = Passed;
  1243. }
  1244. Passed = TRUE;
  1245. //
  1246. // Nested dirs
  1247. //
  1248. for (i = 0; NotNestedDirs[i]; i += 2) {
  1249. Ret = FrsIsParent(NotNestedDirs[i], NotNestedDirs[i + 1]);
  1250. if (Ret != 0) {
  1251. DPRINT3(0, "ERROR - not nested dirs %ws %d %ws\n",
  1252. NotNestedDirs[i], Ret, NotNestedDirs[i + 1]);
  1253. Passed = FALSE;
  1254. }
  1255. }
  1256. if (Passed) {
  1257. DPRINT(0, "\t\tPassed not nested dirs\n");
  1258. } else {
  1259. FinalPassed = Passed;
  1260. }
  1261. Passed = TRUE;
  1262. //
  1263. // Dirs Nested
  1264. //
  1265. for (i = 0; DirsNested[i]; i += 2) {
  1266. Ret = FrsIsParent(DirsNested[i], DirsNested[i + 1]);
  1267. if (Ret != 1) {
  1268. DPRINT3(0, "ERROR - dirs nested %ws %d %ws\n",
  1269. DirsNested[i], Ret, DirsNested[i + 1]);
  1270. Passed = FALSE;
  1271. }
  1272. }
  1273. if (Passed) {
  1274. DPRINT(0, "\t\tPassed dirs nested\n");
  1275. } else {
  1276. FinalPassed = Passed;
  1277. }
  1278. return FinalPassed;
  1279. }
  1280. LONGLONG WaitableNow;
  1281. DWORD WaitableProcessed;
  1282. #define WAITABLE_TIMER_CMDS (8) // must be even
  1283. #define WAITABLE_TIMER_TIMEOUT (3 * 1000) // 3 seconds
  1284. #define WAITABLE_TIMER_TIMEOUT_PLUS ((3 * 1000) + 500) // 3.5 seconds
  1285. PCOMMAND_PACKET WTCmds[WAITABLE_TIMER_CMDS];
  1286. BOOL
  1287. TestWaitableTimerCompletion(
  1288. IN PCOMMAND_PACKET Cmd,
  1289. IN PVOID Ignore
  1290. )
  1291. /*++
  1292. Routine Description:
  1293. Test waitable timer
  1294. Arguments:
  1295. None.
  1296. Return Value:
  1297. TRUE - test passed
  1298. FALSE - test failed; see listing
  1299. --*/
  1300. {
  1301. #undef DEBSUB
  1302. #define DEBSUB "TestWaitableTimerCompletion:"
  1303. DWORD i;
  1304. LONGLONG Now;
  1305. LONGLONG Min;
  1306. LONGLONG Max;
  1307. FrsNowAsFileTime(&Now);
  1308. if (Cmd->Command == CMD_START_SUBSYSTEM) {
  1309. Min = WaitableNow + ((WAITABLE_TIMER_TIMEOUT - 1) * 1000 * 10);
  1310. Max = WaitableNow + ((WAITABLE_TIMER_TIMEOUT + 1) * 1000 * 10);
  1311. } else {
  1312. Min = WaitableNow + (((WAITABLE_TIMER_TIMEOUT - 1) * 1000 * 10) << 1);
  1313. Max = WaitableNow + (((WAITABLE_TIMER_TIMEOUT + 1) * 1000 * 10) << 1);
  1314. }
  1315. if (Now < Min || Now > Max) {
  1316. DPRINT1(0, "\t\tERROR - timer misfired in %d seconds\n",
  1317. (Now > Cmd->WaitFileTime) ?
  1318. (DWORD)((Now - Cmd->WaitFileTime) / (10 * 1000 * 1000)) :
  1319. (DWORD)((Cmd->WaitFileTime - Now) / (10 * 1000 * 1000)));
  1320. FrsSetCompletionRoutine(Cmd, FrsFreeCommand, NULL);
  1321. FrsCompleteCommand(Cmd, Cmd->ErrorStatus);
  1322. return ERROR_SUCCESS;
  1323. }
  1324. DPRINT1(0, "\t\tSUCCESS hit at %d seconds\n",
  1325. (WaitableNow > Cmd->WaitFileTime) ?
  1326. (DWORD)((WaitableNow - Cmd->WaitFileTime) / (10 * 1000 * 1000)) :
  1327. (DWORD)((Cmd->WaitFileTime - WaitableNow) / (10 * 1000 * 1000)));
  1328. ++WaitableProcessed;
  1329. if (Cmd->Command == CMD_STOP_SUBSYSTEM) {
  1330. FrsSetCompletionRoutine(Cmd, FrsFreeCommand, NULL);
  1331. FrsCompleteCommand(Cmd, Cmd->ErrorStatus);
  1332. return ERROR_SUCCESS;
  1333. }
  1334. Cmd->Command = CMD_STOP_SUBSYSTEM;
  1335. WaitSubmit(Cmd, WAITABLE_TIMER_TIMEOUT, CMD_DELAYED_COMPLETE);
  1336. return ERROR_SUCCESS;
  1337. }
  1338. BOOL
  1339. TestWaitableTimer(
  1340. VOID
  1341. )
  1342. /*++
  1343. Routine Description:
  1344. Test waitable timer
  1345. Arguments:
  1346. None.
  1347. Return Value:
  1348. TRUE - test passed
  1349. FALSE - test failed; see listing
  1350. --*/
  1351. {
  1352. #undef DEBSUB
  1353. #define DEBSUB "TestWaitableTimer:"
  1354. DWORD i;
  1355. WaitableProcessed = 0;
  1356. for (i = 0; i < WAITABLE_TIMER_CMDS; ++i) {
  1357. WTCmds[i] = FrsAllocCommand(NULL, CMD_START_SUBSYSTEM);
  1358. FrsSetCompletionRoutine(WTCmds[i], TestWaitableTimerCompletion, NULL);
  1359. }
  1360. FrsNowAsFileTime(&WaitableNow);
  1361. for (i = 0; i < (WAITABLE_TIMER_CMDS >> 1); ++i) {
  1362. WaitSubmit(WTCmds[i], WAITABLE_TIMER_TIMEOUT, CMD_DELAYED_COMPLETE);
  1363. }
  1364. for (i = (WAITABLE_TIMER_CMDS >> 1); i < WAITABLE_TIMER_CMDS; ++i) {
  1365. WaitSubmit(WTCmds[i], WAITABLE_TIMER_TIMEOUT_PLUS, CMD_DELAYED_COMPLETE);
  1366. }
  1367. Sleep(WAITABLE_TIMER_TIMEOUT_PLUS +
  1368. WAITABLE_TIMER_TIMEOUT_PLUS +
  1369. WAITABLE_TIMER_TIMEOUT_PLUS);
  1370. if (WaitableProcessed != (WAITABLE_TIMER_CMDS << 1)) {
  1371. DPRINT2(0, "\t\tERROR - processed %d of %d waitable timer commands.\n",
  1372. WaitableProcessed, WAITABLE_TIMER_CMDS << 1);
  1373. return FALSE;
  1374. }
  1375. return TRUE;
  1376. }
  1377. BOOL
  1378. TestEventLog(
  1379. VOID
  1380. )
  1381. /*++
  1382. Routine Description:
  1383. Generate all eventlog messages
  1384. Arguments:
  1385. None.
  1386. Return Value:
  1387. TRUE - test passed
  1388. --*/
  1389. {
  1390. #undef DEBSUB
  1391. #define DEBSUB "TestEventLog:"
  1392. DWORD i;
  1393. for (i = 0; i < 6; i++) {
  1394. EPRINT0(EVENT_FRS_ERROR);
  1395. Sleep(10000);
  1396. }
  1397. EPRINT0(EVENT_FRS_STARTING);
  1398. EPRINT0(EVENT_FRS_STOPPING);
  1399. EPRINT0(EVENT_FRS_STOPPED);
  1400. EPRINT0(EVENT_FRS_STOPPED_FORCE);
  1401. EPRINT0(EVENT_FRS_STOPPED_ASSERT);
  1402. EPRINT3(EVENT_FRS_ASSERT, L"Module.c", L"456", L"test assertion");
  1403. for (i = 0; i < 6; i++) {
  1404. EPRINT4(EVENT_FRS_VOLUME_NOT_SUPPORTED, L"ReplicaSet", L"ThisComputer",
  1405. L"d:a\\b\\c", L"a:\\");
  1406. Sleep(10000);
  1407. }
  1408. EPRINT3(EVENT_FRS_LONG_JOIN, L"Source", L"Target", L"ThisComputer");
  1409. EPRINT3(EVENT_FRS_LONG_JOIN_DONE, L"Source", L"Target", L"ThisComputer");
  1410. EPRINT2(EVENT_FRS_CANNOT_COMMUNICATE, L"ThisComputer", L"OtherComputer");
  1411. EPRINT2(EVENT_FRS_DATABASE_SPACE, L"ThisComputer", L"a:\\dir\\root");
  1412. EPRINT2(EVENT_FRS_DISK_WRITE_CACHE_ENABLED, L"ThisComputer", L"a:\\dir\\root");
  1413. EPRINT4(EVENT_FRS_JET_1414,
  1414. L"ThisComputer",
  1415. L"a:\\dir\\ntfrs\\jet\\ntfrs.jdb",
  1416. L"a:\\dir\\ntfrs\\jet\\log",
  1417. L"a:\\dir\\ntfrs\\jet\\sys");
  1418. EPRINT1(EVENT_FRS_SYSVOL_NOT_READY, L"ThisComputer");
  1419. EPRINT1(EVENT_FRS_SYSVOL_NOT_READY_PRIMARY, L"ThisComputer");
  1420. EPRINT1(EVENT_FRS_SYSVOL_READY, L"ThisComputer");
  1421. EPRINT1(EVENT_FRS_STAGING_AREA_FULL, L"100000");
  1422. EPRINT2(EVENT_FRS_HUGE_FILE, L"10000", L"10000000");
  1423. return TRUE;
  1424. }
  1425. BOOL
  1426. TestOneDnsToBios(
  1427. IN PWCHAR HostName,
  1428. IN DWORD HostLen,
  1429. IN BOOL ExpectError
  1430. )
  1431. /*++
  1432. Routine Description:
  1433. Test the conversion of one DNS computer name to a NetBIOS computer name.
  1434. Arguments:
  1435. HostName - DNS name
  1436. ExpectError - conversion should fail
  1437. Return Value:
  1438. TRUE - test passed
  1439. --*/
  1440. {
  1441. #undef DEBSUB
  1442. #define DEBSUB "TestOneDnsToBios:"
  1443. BOOL Ret = TRUE;
  1444. DWORD Len;
  1445. WCHAR NetBiosName[MAX_PATH + 1];
  1446. //
  1447. // Bios -> Bios
  1448. //
  1449. NetBiosName[0] = 0;
  1450. Len = HostLen;
  1451. Ret = DnsHostnameToComputerName(HostName, NetBiosName, &Len);
  1452. if (Ret) {
  1453. DPRINT5(0, "\t\t%sConverted %ws -> %ws (%d -> %d)\n",
  1454. (ExpectError) ? "ERROR - " : "", HostName, NetBiosName, HostLen, Len);
  1455. Ret = !ExpectError;
  1456. } else {
  1457. DPRINT4_WS(0, "\t\t%sCan't convert %ws (%d -> %d);",
  1458. (!ExpectError) ? "ERROR - " : "", HostName, HostLen, Len, GetLastError());
  1459. Ret = ExpectError;
  1460. }
  1461. return Ret;
  1462. }
  1463. BOOL
  1464. TestDnsToBios(
  1465. VOID
  1466. )
  1467. /*++
  1468. Routine Description:
  1469. Test the conversion of DNS computer names to NetBIOS computer names.
  1470. Arguments:
  1471. None.
  1472. Return Value:
  1473. TRUE - test passed
  1474. --*/
  1475. {
  1476. #undef DEBSUB
  1477. #define DEBSUB "TestDnsToBios:"
  1478. BOOL Ret = TRUE;
  1479. DWORD Len;
  1480. WCHAR NetBiosName[MAX_PATH + 1];
  1481. //
  1482. // Bios -> Bios
  1483. //
  1484. if (!TestOneDnsToBios(L"01234567", 9, FALSE)) {
  1485. Ret = FALSE;
  1486. }
  1487. //
  1488. // Bios -> Bios not enough space
  1489. //
  1490. if (!TestOneDnsToBios(L"01234567", 1, TRUE)) {
  1491. Ret = FALSE;
  1492. }
  1493. //
  1494. // Dns -> Bios
  1495. //
  1496. if (!TestOneDnsToBios(L"01234567.abc.dd.a.com", MAX_PATH, FALSE)) {
  1497. Ret = FALSE;
  1498. }
  1499. if (!TestOneDnsToBios(L"01234567.abc.dd.a.com.", MAX_PATH, FALSE)) {
  1500. Ret = FALSE;
  1501. }
  1502. if (!TestOneDnsToBios(L"[email protected].", MAX_PATH, FALSE)) {
  1503. Ret = FALSE;
  1504. }
  1505. if (!TestOneDnsToBios(L"[email protected][email protected].", MAX_PATH, FALSE)) {
  1506. Ret = FALSE;
  1507. }
  1508. return Ret;
  1509. }
  1510. DWORD
  1511. FrsTest(
  1512. PVOID FrsThread
  1513. )
  1514. /*++
  1515. Routine Description:
  1516. Test:
  1517. - queues
  1518. - command servers
  1519. - exception handling
  1520. - test service interface
  1521. - RPC
  1522. - version vector
  1523. - configuration handling
  1524. Then die.
  1525. Arguments:
  1526. None.
  1527. Return Value:
  1528. ERROR_OPERATION_ABORTED
  1529. ERROR_SUCCESS
  1530. --*/
  1531. {
  1532. #undef DEBSUB
  1533. #define DEBSUB "FrsTest:"
  1534. //
  1535. // DISABLED
  1536. //
  1537. return ERROR_SUCCESS;
  1538. DPRINT(0, "Testing in progress...\n");
  1539. try {
  1540. //
  1541. // Test Dns to Bios
  1542. //
  1543. DPRINT(0, "\tTesting Dns to Bios...\n");
  1544. if (TestDnsToBios()) {
  1545. DPRINT(0, "\tPASS Testing Dns to Bios\n\n");
  1546. } else {
  1547. DPRINT(0, "\tFAIL Testing Dns to Bios\n\n");
  1548. }
  1549. //
  1550. // Test event log messages
  1551. //
  1552. DPRINT(0, "\tTesting event log messges...\n");
  1553. if (TestEventLog()) {
  1554. DPRINT(0, "\tPASS Testing event log messges\n\n");
  1555. } else {
  1556. DPRINT(0, "\tFAIL Testing event log messges\n\n");
  1557. }
  1558. //
  1559. // Test waitable timer
  1560. //
  1561. DPRINT(0, "\tTesting waitable timer...\n");
  1562. if (TestWaitableTimer()) {
  1563. DPRINT(0, "\tPASS Testing waitable timer \n\n");
  1564. } else {
  1565. DPRINT(0, "\tFAIL Testing waitable timer \n\n");
  1566. }
  1567. //
  1568. // Test nested dirs
  1569. //
  1570. DPRINT(0, "\tTesting nested dirs...\n");
  1571. if (TestNestedDirs()) {
  1572. DPRINT(0, "\tPASS Testing nested dirs\n\n");
  1573. } else {
  1574. DPRINT(0, "\tFAIL Testing nested dirs\n\n");
  1575. }
  1576. //
  1577. // Test oplocks
  1578. //
  1579. DPRINT(0, "\tTesting oplocks...\n");
  1580. if (TestOpLocks()) {
  1581. DPRINT(0, "\tPASS Testing oplocks\n\n");
  1582. } else {
  1583. DPRINT(0, "\tFAIL Testing oplocks\n\n");
  1584. }
  1585. //
  1586. // Test queues
  1587. //
  1588. DPRINT(0, "\tTesting queues...\n");
  1589. if (TestQueues()) {
  1590. DPRINT(0, "\tPASS Testing queues\n\n");
  1591. } else {
  1592. DPRINT(0, "\tFAIL Testing queues\n\n");
  1593. }
  1594. //
  1595. // Test command servers
  1596. //
  1597. DPRINT(0, "\tTesting command servers...\n");
  1598. if (TestCommands()) {
  1599. DPRINT(0, "\tPASS Testing command servers\n\n");
  1600. } else {
  1601. DPRINT(0, "\tFAIL Testing command servers\n\n");
  1602. }
  1603. //
  1604. // Test the exceptions
  1605. //
  1606. DPRINT(0, "\tTesting exceptions...\n");
  1607. if (TestExceptions()) {
  1608. DPRINT(0, "\tPASS Testing exceptions\n\n");
  1609. } else {
  1610. DPRINT(0, "\tFAIL Testing exceptions\n\n");
  1611. }
  1612. //
  1613. // Testing RPC
  1614. //
  1615. DPRINT(0, "\tTesting RPC\n");
  1616. if (TestRpc()) {
  1617. DPRINT(0, "\tPASS Testing Rpc\n\n");
  1618. } else {
  1619. DPRINT(0, "\tFAIL Testing Rpc\n\n");
  1620. }
  1621. } finally {
  1622. if (AbnormalTermination()) {
  1623. DPRINT(0, "Test aborted\n");
  1624. } else {
  1625. DPRINT(0, "Test Done\n");
  1626. }
  1627. FrsIsShuttingDown = TRUE;
  1628. SetEvent(ShutDownEvent);
  1629. }
  1630. return ERROR_SUCCESS;
  1631. }
  1632. #endif DBG