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.

1529 lines
37 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. ortest.c
  5. Abstract:
  6. Simple test application for testing OR features directly.
  7. Author:
  8. Mario Goertzel [MarioGo]
  9. Revision History:
  10. MarioGo 1/24/1996 Bits 'n pieces
  11. --*/
  12. #include <or.h>
  13. #include <stdio.h>
  14. #include <umisc.h>
  15. #include <uor.h>
  16. #include <epmp.h>
  17. typedef struct {
  18. ID oid;
  19. BOOL fReady;
  20. BOOL fForceSecond;
  21. } RundownRecord;
  22. // Constants
  23. const PWSTR pwstrOr = L"ncalrpc:[epmapper]";
  24. // Globals
  25. HANDLE hLocalOr = 0;
  26. HANDLE hServerOrTest = 0;
  27. PHPROCESS hMyProcess = 0;
  28. BOOL fServer = TRUE;
  29. BOOL fInternet = FALSE;
  30. DWORD TestCase = 0;
  31. DWORD Errors = 0;
  32. OXID aOxids[5]; /* shared \ */
  33. OXID_INFO aOxidInfo[5]; /* shared > between client and server */
  34. OID aOids[100]; /* shared / */
  35. RundownRecord aRundowns[100];
  36. DWORD dwlimRundowns = 0;
  37. OID reservedBase;
  38. DUALSTRINGARRAY *pdsaMyExpandedStringBindings;
  39. DUALSTRINGARRAY *pdsaMyCompressedSecurityBindings;
  40. DUALSTRINGARRAY *pdsaMyTestBindings;
  41. DUALSTRINGARRAY *pdsaLocalOrBindings;
  42. MID gLocalMid;
  43. void SyncWithClient(DWORD testcase);
  44. error_status_t SyncWithServer(DWORD testcase);
  45. void AddRundown(ID oid, BOOL fRundownTwice);
  46. void WaitForAllRundowns();
  47. RPC_STATUS ConnectToLocalOr();
  48. RPC_STATUS Startup(PSZ, PSZ);
  49. // Test events
  50. HANDLE hServerEvent;
  51. HANDLE hClientEvent;
  52. HANDLE hRundownEvent;
  53. //
  54. // Intenet port tests - not really related to DCOM
  55. // but is just a client to the endpoint mapper process
  56. // so it runs fine here.
  57. //
  58. // Assumes the following config: (regini dcomtest.ini)
  59. //
  60. extern RPC_STATUS RPC_ENTRY
  61. I_RpcServerAllocatePort(DWORD, PUSHORT);
  62. RPC_STATUS
  63. RunInternetPortTests()
  64. {
  65. RPC_STATUS status;
  66. long allocstatus;
  67. PVOID process1, process2, process3;
  68. unsigned short port;
  69. int i;
  70. for (i = 0; i < 2; i++)
  71. {
  72. process1 = process2 = process3 = 0;
  73. if (hLocalOr == 0)
  74. {
  75. status =
  76. RpcBindingFromStringBinding(pwstrOr, &hLocalOr);
  77. ASSERT(status == RPC_S_OK);
  78. }
  79. status = OpenEndpointMapper(hLocalOr,
  80. &process1);
  81. ASSERT(status == RPC_S_OK);
  82. status = OpenEndpointMapper(hLocalOr,
  83. &process2);
  84. ASSERT(status == RPC_S_OK);
  85. status = OpenEndpointMapper(hLocalOr,
  86. &process3);
  87. ASSERT(status == RPC_S_OK);
  88. status = AllocateReservedIPPort(process1,
  89. PORT_DEFAULT,
  90. &allocstatus,
  91. &port);
  92. ASSERT(status == RPC_S_OK);
  93. EQUAL(allocstatus, RPC_S_OK);
  94. EQUAL(port, 1026);
  95. status = AllocateReservedIPPort(process1,
  96. PORT_INTERNET,
  97. &allocstatus,
  98. &port);
  99. ASSERT(status == RPC_S_OK);
  100. EQUAL(allocstatus, RPC_S_OK);
  101. EQUAL(port, 1028);
  102. status = AllocateReservedIPPort(process1,
  103. PORT_INTERNET,
  104. &allocstatus,
  105. &port);
  106. ASSERT(status == RPC_S_OK);
  107. EQUAL(allocstatus, RPC_S_OK);
  108. EQUAL(port, 1029);
  109. status = AllocateReservedIPPort(process2,
  110. PORT_INTRANET,
  111. &allocstatus,
  112. &port);
  113. ASSERT(status == RPC_S_OK);
  114. EQUAL(allocstatus, RPC_S_OK);
  115. EQUAL(port, 499);
  116. status = AllocateReservedIPPort(process2,
  117. PORT_INTRANET,
  118. &allocstatus,
  119. &port);
  120. ASSERT(status == RPC_S_OK);
  121. EQUAL(allocstatus, RPC_S_OK);
  122. EQUAL(port, 500);
  123. status = AllocateReservedIPPort(process2,
  124. PORT_INTRANET,
  125. &allocstatus,
  126. &port);
  127. ASSERT(status == RPC_S_OK);
  128. EQUAL(allocstatus, RPC_S_OK);
  129. EQUAL(port, 501);
  130. status = AllocateReservedIPPort(process2,
  131. PORT_INTRANET,
  132. &allocstatus,
  133. &port);
  134. ASSERT(status == RPC_S_OK);
  135. EQUAL(allocstatus, RPC_S_OK);
  136. EQUAL(port, 502);
  137. status = AllocateReservedIPPort(process2,
  138. PORT_INTRANET,
  139. &allocstatus,
  140. &port);
  141. ASSERT(status == RPC_S_OK);
  142. EQUAL(allocstatus, RPC_S_OK);
  143. EQUAL(port, 1025);
  144. status = AllocateReservedIPPort(process2,
  145. PORT_INTRANET,
  146. &allocstatus,
  147. &port);
  148. ASSERT(status == RPC_S_OK);
  149. EQUAL(allocstatus, RPC_S_OK);
  150. EQUAL(port, 1027);
  151. status = AllocateReservedIPPort(process2,
  152. PORT_INTRANET,
  153. &allocstatus,
  154. &port);
  155. ASSERT(status == RPC_S_OK);
  156. EQUAL(allocstatus, RPC_S_OUT_OF_RESOURCES);
  157. EQUAL(port, 0);
  158. status = AllocateReservedIPPort(process3,
  159. PORT_INTRANET,
  160. &allocstatus,
  161. &port);
  162. ASSERT(status == RPC_S_OK);
  163. EQUAL(allocstatus, RPC_S_OUT_OF_RESOURCES);
  164. EQUAL(port, 0);
  165. status = AllocateReservedIPPort(process3,
  166. PORT_INTERNET,
  167. &allocstatus,
  168. &port);
  169. ASSERT(status == RPC_S_OK);
  170. EQUAL(allocstatus, RPC_S_OK);
  171. EQUAL(port, 1030);
  172. status =
  173. RpcSmDestroyClientContext(&process2);
  174. ASSERT(status == RPC_S_OK);
  175. status =
  176. RpcSmDestroyClientContext(&process3);
  177. ASSERT(status == RPC_S_OK);
  178. status =
  179. RpcSmDestroyClientContext(&process1);
  180. ASSERT(status == RPC_S_OK);
  181. status =
  182. RpcBindingFree(&hLocalOr);
  183. ASSERT(status == RPC_S_OK);
  184. }
  185. status = I_RpcServerAllocatePort(RPC_C_USE_INTERNET_PORT,
  186. &port);
  187. ASSERT(status == RPC_S_OK);
  188. EQUAL(port, 1026);
  189. status = I_RpcServerAllocatePort(0,
  190. &port);
  191. ASSERT(status == RPC_S_OK);
  192. EQUAL(port, 1028);
  193. status = I_RpcServerAllocatePort(RPC_C_USE_INTRANET_PORT,
  194. &port);
  195. ASSERT(status == RPC_S_OK);
  196. EQUAL(port, 499);
  197. status = I_RpcServerAllocatePort(RPC_C_USE_INTRANET_PORT,
  198. &port);
  199. ASSERT(status == RPC_S_OK);
  200. EQUAL(port, 500);
  201. status = I_RpcServerAllocatePort(RPC_C_USE_INTRANET_PORT,
  202. &port);
  203. ASSERT(status == RPC_S_OK);
  204. EQUAL(port, 501);
  205. status = I_RpcServerAllocatePort(RPC_C_USE_INTRANET_PORT,
  206. &port);
  207. ASSERT(status == RPC_S_OK);
  208. EQUAL(port, 502);
  209. status = I_RpcServerAllocatePort(RPC_C_USE_INTRANET_PORT,
  210. &port);
  211. ASSERT(status == RPC_S_OK);
  212. EQUAL(port, 1025);
  213. status = I_RpcServerAllocatePort(RPC_C_USE_INTRANET_PORT,
  214. &port);
  215. ASSERT(status == RPC_S_OK);
  216. EQUAL(port, 1027);
  217. status = I_RpcServerAllocatePort(RPC_C_USE_INTRANET_PORT,
  218. &port);
  219. ASSERT(status == RPC_S_OUT_OF_RESOURCES);
  220. EQUAL(port, 0);
  221. status = I_RpcServerAllocatePort( RPC_C_USE_INTERNET_PORT
  222. | RPC_C_USE_INTRANET_PORT,
  223. &port);
  224. ASSERT(status == RPC_S_INVALID_ARG);
  225. EQUAL(port, 0);
  226. return(RPC_S_OK);
  227. }
  228. // Server side
  229. RPC_STATUS
  230. RunServer()
  231. {
  232. RPC_STATUS status;
  233. DWORD t;
  234. OXID_INFO oi;
  235. OID oidT;
  236. int i;
  237. OID aOidDels[2];
  238. SyncWithClient(++TestCase);
  239. // Allocate Oxids and Oids
  240. aOxidInfo[0].dwTid = 1;
  241. aOxidInfo[0].dwPid = 42;
  242. aOxidInfo[0].dwAuthnHint = 4;
  243. aOxidInfo[0].psa = 0;
  244. status = UuidCreate(&aOxidInfo[0].ipidRemUnknown);
  245. ASSERT(status == RPC_S_OK);
  246. status = ServerAllocateOXIDAndOIDs(
  247. hLocalOr,
  248. hMyProcess,
  249. &aOxids[0],
  250. FALSE,
  251. 5,
  252. &aOids[0],
  253. &t,
  254. &aOxidInfo[0],
  255. pdsaMyExpandedStringBindings,
  256. pdsaMyCompressedSecurityBindings);
  257. ASSERT(status == RPC_S_OK);
  258. EQUAL(t, 5);
  259. status = ServerAllocateOIDs(
  260. hLocalOr,
  261. hMyProcess,
  262. &aOxids[0],
  263. 5,
  264. &aOids[5],
  265. &t);
  266. ASSERT(status == RPC_S_OK);
  267. EQUAL(t, 5);
  268. PrintToConsole("Allocated oxid %I64x with OIDs:\n", aOxids[0]);
  269. for(i = 0; i < 10; i++)
  270. {
  271. PrintToConsole("\t%I64x\n", aOids[i]);
  272. }
  273. aOxidInfo[1].dwTid = 2;
  274. aOxidInfo[1].dwPid = 42;
  275. aOxidInfo[1].dwAuthnHint = 99;
  276. aOxidInfo[1].psa = 0;
  277. status = UuidCreate(&aOxidInfo[1].ipidRemUnknown);
  278. ASSERT(status == RPC_S_OK);
  279. status = ServerAllocateOXIDAndOIDs(
  280. hLocalOr,
  281. hMyProcess,
  282. &aOxids[1],
  283. FALSE,
  284. 10,
  285. &aOids[10],
  286. &t,
  287. &aOxidInfo[1],
  288. pdsaMyExpandedStringBindings,
  289. pdsaMyTestBindings);
  290. ASSERT(status == RPC_S_OK);
  291. EQUAL(t, 10);
  292. PrintToConsole("Allocated oxid %I64x with OIDs:\n", aOxids[1]);
  293. for(i = 10; i < 20; i++)
  294. {
  295. PrintToConsole("\t%I64x\n", aOids[i]);
  296. }
  297. aOxidInfo[2].dwTid = 3;
  298. aOxidInfo[2].dwPid = 42;
  299. aOxidInfo[2].dwAuthnHint = 17171717;
  300. aOxidInfo[2].psa = 0;
  301. status = UuidCreate(&aOxidInfo[2].ipidRemUnknown);
  302. ASSERT(status == RPC_S_OK);
  303. status = ServerAllocateOXIDAndOIDs(
  304. hLocalOr,
  305. hMyProcess,
  306. &aOxids[2],
  307. FALSE,
  308. 10,
  309. &aOids[20],
  310. &t,
  311. &aOxidInfo[2],
  312. pdsaMyExpandedStringBindings,
  313. pdsaMyTestBindings);
  314. ASSERT(status == RPC_S_OK);
  315. EQUAL(t, 10);
  316. PrintToConsole("Allocated oxid %I64x with OIDs:\n", aOxids[2]);
  317. for(i = 20; i < 30; i++)
  318. {
  319. PrintToConsole("\t%I64x\n", aOids[i]);
  320. }
  321. SyncWithClient(++TestCase);
  322. status = ServerFreeOXIDAndOIDs(
  323. hLocalOr,
  324. hMyProcess,
  325. aOxids[1],
  326. 10,
  327. &aOids[10]
  328. );
  329. ASSERT(status == OR_OK);
  330. status = ServerFreeOXIDAndOIDs(
  331. hLocalOr,
  332. hMyProcess,
  333. aOxids[2],
  334. 10,
  335. &aOids[20]
  336. );
  337. ASSERT(status == OR_OK);
  338. PrintToConsole("Freed OXID %I64x and %I64x\n", aOxids[1], aOxids[2]);
  339. SyncWithClient(++TestCase);
  340. // Wait for rundowns on oxid 0 of OIDs 0, 1, 7 and 9
  341. AddRundown(aOids[0], FALSE);
  342. AddRundown(aOids[1], FALSE);
  343. AddRundown(aOids[7], FALSE);
  344. AddRundown(aOids[9], FALSE);
  345. WaitForAllRundowns();
  346. SyncWithClient(++TestCase);
  347. TestCase = ~0;
  348. SyncWithClient(TestCase);
  349. // Free OID 3 it shouldn't rundown after this; and an invalid oid.
  350. aOidDels[0] = aOids[3];
  351. aOidDels[1] = reservedBase;
  352. status =
  353. BulkUpdateOIDs(hLocalOr,
  354. hMyProcess,
  355. 0,
  356. 0,
  357. 0,
  358. 0,
  359. 0,
  360. 2,
  361. aOidDels,
  362. 0,
  363. 0
  364. );
  365. // Wait for rundowns on oxid 0 of OIDs 2, 4, 5, 6 and 8
  366. // Client has exited
  367. AddRundown(aOids[2], FALSE);
  368. AddRundown(aOids[4], TRUE);
  369. AddRundown(aOids[5], FALSE);
  370. AddRundown(aOids[6], FALSE);
  371. AddRundown(aOids[8], TRUE);
  372. WaitForAllRundowns();
  373. return(RPC_S_OK);
  374. }
  375. // Client side
  376. RPC_STATUS
  377. RunClient()
  378. {
  379. RPC_STATUS status;
  380. DUALSTRINGARRAY *pdaRemoteOrBindings = 0;
  381. OXID_INFO oi;
  382. MID mid;
  383. int i;
  384. OXID_OID_PAIR aUpdates[10];
  385. OID_MID_PAIR aDeletes[6];
  386. OXID_REF aoxidRefs[2];
  387. LONG aStatus[10];
  388. SyncWithServer(++TestCase);
  389. // Server has allocated oxids and oids
  390. status =
  391. GetState(hServerOrTest,
  392. 3,
  393. 30,
  394. 3,
  395. aOxids,
  396. aOids,
  397. aOxidInfo,
  398. &pdaRemoteOrBindings);
  399. ASSERT(status == RPC_S_OK);
  400. ASSERT(pdaRemoteOrBindings);
  401. EQUAL(aOxidInfo[0].psa, 0);
  402. // Resolve OXID 0
  403. oi.psa =0;
  404. status =
  405. ClientResolveOXID(hLocalOr,
  406. hMyProcess,
  407. &aOxids[0],
  408. pdaRemoteOrBindings,
  409. FALSE,
  410. &oi,
  411. &mid);
  412. ASSERT(status == RPC_S_OK);
  413. PrintToConsole("Resolved OXID: %I64x on MID %I64x\n", aOxids[0], mid);
  414. EQUAL( ( (oi.dwTid == aOxidInfo[0].dwTid) || oi.dwTid == 0), 1);
  415. EQUAL( ( (oi.dwPid == aOxidInfo[0].dwPid) || oi.dwPid == 0), 1);
  416. EQUAL(oi.dwAuthnHint, aOxidInfo[0].dwAuthnHint);
  417. if (memcmp(&oi.ipidRemUnknown, &aOxidInfo[0].ipidRemUnknown, sizeof(IPID)) != 0)
  418. {
  419. EQUAL(0, 1);
  420. }
  421. PrintDualStringArray("Expanded binding", oi.psa, FALSE);
  422. MIDL_user_free(oi.psa);
  423. // Add some valid and invalid oids
  424. for (i = 0; i < 10; i++)
  425. {
  426. aUpdates[i].mid = mid;
  427. aUpdates[i].oxid = aOxids[0];
  428. aUpdates[i].oid = aOids[i];
  429. }
  430. aUpdates[9].mid = reservedBase;
  431. aUpdates[8].oxid = reservedBase;
  432. aUpdates[7].oid = reservedBase;
  433. status =
  434. BulkUpdateOIDs(hLocalOr,
  435. hMyProcess,
  436. 10,
  437. aUpdates,
  438. aStatus,
  439. 0,
  440. 0,
  441. 0,
  442. 0,
  443. 0,
  444. 0);
  445. ASSERT(status == OR_PARTIAL_UPDATE);
  446. for(i = 0; i < 7; i++)
  447. {
  448. EQUAL(aStatus[i], 0);
  449. }
  450. EQUAL(aStatus[7], 0); // Okay to register unknown OID
  451. EQUAL(aStatus[8], OR_BADOXID);
  452. EQUAL(aStatus[9], OR_BADOXID);
  453. // Delete a few
  454. // Add three not added last call
  455. // .oxid and .mid correct
  456. aUpdates[0].oid = aOids[8];
  457. aUpdates[1].oid = aOids[9];
  458. // Remove 2 added last call, 1 from this call and 2 invalid
  459. for(i = 0; i < 6; i++)
  460. {
  461. aDeletes[i].oid = aOids[i];
  462. aDeletes[i].mid = mid;
  463. }
  464. aDeletes[2].oid = aOids[9];
  465. aDeletes[3].oid = reservedBase;
  466. aDeletes[4].mid = reservedBase;
  467. aDeletes[5].oid = aOids[6];
  468. status =
  469. BulkUpdateOIDs(hLocalOr,
  470. hMyProcess,
  471. 2,
  472. aUpdates,
  473. aStatus,
  474. 6,
  475. aDeletes,
  476. 0,
  477. 0,
  478. 0,
  479. 0);
  480. ASSERT(status == OR_OK);
  481. EQUAL(aStatus[0], OR_OK);
  482. EQUAL(aStatus[1], OR_OK);
  483. // 6 has been added and deleted, add it again.
  484. aUpdates[0].oid = aOids[6];
  485. status =
  486. BulkUpdateOIDs(hLocalOr,
  487. hMyProcess,
  488. 1,
  489. aUpdates,
  490. aStatus,
  491. 0,
  492. 0,
  493. 0,
  494. 0,
  495. 0,
  496. 0);
  497. ASSERT(status == OR_OK);
  498. EQUAL(aStatus[0], OR_OK);
  499. // Final state: D - added and deleted, A - added, E - D + added, N not added
  500. // OID: 0 1 2 3 4 5 6 7 8 9
  501. // State: D D A A A A E N A D
  502. // Resolve OXID 1
  503. if (mid != gLocalMid)
  504. {
  505. MID mid2;
  506. // No resolve required for local machine.
  507. PrintToConsole("Remote server; resolving second OXID\n");
  508. oi.psa = 0;
  509. status =
  510. ClientResolveOXID(hLocalOr,
  511. hMyProcess,
  512. &aOxids[1],
  513. pdaRemoteOrBindings,
  514. FALSE,
  515. &oi,
  516. &mid2);
  517. ASSERT(status == RPC_S_OK);
  518. PrintToConsole("Resolved OXID: %I64x on MID %I64x\n", aOxids[1], mid);
  519. EQUAL(mid, mid2);
  520. EQUAL(oi.dwTid, 0);
  521. EQUAL(oi.dwPid, 0);
  522. EQUAL(oi.dwAuthnHint, aOxidInfo[1].dwAuthnHint);
  523. if (memcmp(&oi.ipidRemUnknown, &aOxidInfo[1].ipidRemUnknown, sizeof(IPID)) != 0)
  524. {
  525. EQUAL(0, 1);
  526. }
  527. PrintDualStringArray("Expanded binding", oi.psa, FALSE);
  528. MIDL_user_free(oi.psa);
  529. }
  530. // Add some of the oids.
  531. for (i = 0; i < 5; i++)
  532. {
  533. aUpdates[i].mid = mid;
  534. aUpdates[i].oxid = aOxids[1];
  535. aUpdates[i].oid = aOids[i+10];
  536. }
  537. // Release our processes hold on the oxids, this is okay since the OIDs
  538. // are keeping them alive.
  539. for (i = 0; i < 2; i++)
  540. {
  541. aoxidRefs[i].oxid = aOxids[i];
  542. aoxidRefs[i].mid = mid;
  543. }
  544. aoxidRefs[0].refs = 1;
  545. aoxidRefs[1].refs = 4; // invalid, will cause an DbgPrint in checked or.
  546. status =
  547. BulkUpdateOIDs(hLocalOr,
  548. hMyProcess,
  549. 5,
  550. aUpdates,
  551. aStatus,
  552. 0,
  553. 0,
  554. 0,
  555. 0,
  556. 2,
  557. aoxidRefs);
  558. ASSERT(status == OR_OK);
  559. for(i = 0; i < 5; i++)
  560. {
  561. EQUAL(aStatus[i], 0);
  562. }
  563. SyncWithServer(++TestCase);
  564. // Server has freed oxids and oids
  565. // Can't test that adding an invalid OID is caught, because it
  566. // isn't until the client actually pings the real server.
  567. // Since the client has already resolved oxid1 we can re-resolve it.
  568. // Try to lookup oxid 2 which has also been freed, it should fail.
  569. oi.psa = 0;
  570. status =
  571. ClientResolveOXID(hLocalOr,
  572. hMyProcess,
  573. &aOxids[2],
  574. pdaRemoteOrBindings,
  575. FALSE,
  576. &oi,
  577. &mid);
  578. ASSERT(status == OR_BADOXID);
  579. EQUAL(oi.psa,0);
  580. SyncWithServer(++TestCase);
  581. // Server waited for first set of rundowns
  582. SyncWithServer(++TestCase);
  583. SyncWithServer(~0);
  584. // Server will wait for the last set of rundowns.
  585. return(RPC_S_OK);
  586. }
  587. int main (int argc, char *argv[])
  588. {
  589. RPC_STATUS status;
  590. PSZ pszProtseq, pszServer;
  591. argc--;
  592. argv++;
  593. pszServer = 0;
  594. pszProtseq = "ncalrpc";
  595. while(argc)
  596. {
  597. switch(argv[0][1])
  598. {
  599. case 't':
  600. pszProtseq = argv[1];
  601. argc--;
  602. argv++;
  603. break;
  604. case 'l':
  605. case 'c':
  606. fServer = FALSE;
  607. break;
  608. case 'i':
  609. fInternet = TRUE;
  610. break;
  611. case 's':
  612. pszServer = argv[1];
  613. argc--;
  614. argv++;
  615. break;
  616. default:
  617. PrintToConsole("Usage: ortest [client|-client] [-internet] [-t protseq ] [-s server addr]\n"
  618. );
  619. return(0);
  620. }
  621. argc--;
  622. argv++;
  623. }
  624. PrintToConsole("OrTest: %s starting...\n", fInternet ? "internet test" :
  625. ( fServer ? "server" : "client") );
  626. if (fInternet)
  627. {
  628. status = RunInternetPortTests();
  629. }
  630. else
  631. {
  632. status = Startup(pszProtseq, pszServer);
  633. ASSERT(status == RPC_S_OK);
  634. status = ConnectToLocalOr();
  635. ASSERT(status == RPC_S_OK);
  636. if (fServer)
  637. {
  638. status = RunServer();
  639. }
  640. else
  641. {
  642. status = RunClient();
  643. }
  644. }
  645. if (status == RPC_S_OK)
  646. {
  647. PrintToConsole("Test Passed\n");
  648. }
  649. else
  650. {
  651. PrintToConsole("Test Failed %d\n", Errors);
  652. }
  653. if (hLocalOr) RpcBindingFree(&hLocalOr);
  654. if (hMyProcess) RpcSsDestroyClientContext(&hMyProcess);
  655. if (hServerOrTest) RpcBindingFree(&hServerOrTest);
  656. Sleep(1000);
  657. return(0);
  658. }
  659. // Shared initialization code
  660. RPC_STATUS
  661. Startup(PSZ protseq, PSZ server)
  662. {
  663. RPC_STATUS status;
  664. DUALSTRINGARRAY *pdsaT, *pdsaT2;
  665. RPC_BINDING_VECTOR *pbv;
  666. pdsaMyExpandedStringBindings = (DUALSTRINGARRAY *)MIDL_user_allocate(500*2);
  667. pdsaMyCompressedSecurityBindings = (DUALSTRINGARRAY *)MIDL_user_allocate(4 + 6*2);
  668. pdsaMyTestBindings = (DUALSTRINGARRAY *)MIDL_user_allocate(4 + 19*2);
  669. ASSERT( pdsaMyExpandedStringBindings
  670. && pdsaMyCompressedSecurityBindings
  671. && pdsaMyTestBindings);
  672. pdsaMyCompressedSecurityBindings->wNumEntries = 6;
  673. pdsaMyCompressedSecurityBindings->wSecurityOffset = 2;
  674. pdsaMyCompressedSecurityBindings->aStringArray[0] = 0;
  675. pdsaMyCompressedSecurityBindings->aStringArray[1] = 0;
  676. pdsaMyCompressedSecurityBindings->aStringArray[2] = 10; // authn winnt
  677. pdsaMyCompressedSecurityBindings->aStringArray[3] = -1; // authz none
  678. pdsaMyCompressedSecurityBindings->aStringArray[4] = 0;
  679. pdsaMyCompressedSecurityBindings->aStringArray[5] = 0;
  680. _UseProtseq(0, L"ncalrpc", &pdsaT, &pdsaT2); // inits psaMyExpandedStringBindings
  681. EQUAL( (pdsaT != 0), 1);
  682. EQUAL( (pdsaT2 != 0), 1);
  683. MIDL_user_free(pdsaT);
  684. MIDL_user_free(pdsaT2);
  685. pdsaMyTestBindings->wNumEntries = 19;
  686. pdsaMyTestBindings->wSecurityOffset = 2;
  687. memcpy(pdsaMyTestBindings->aStringArray,
  688. L"\0\0\x7\xff" L"APrincipal\0\x9\xD\0\0",
  689. 19*2);
  690. if (fServer)
  691. {
  692. // Listen to the remote (if any) protseq. Not part of the bindings
  693. // registered with the OR until a callback to UseProtseq is made.
  694. if (protseq)
  695. {
  696. status = RpcServerUseProtseqA(protseq, 0, 0);
  697. ASSERT(status == RPC_S_OK);
  698. }
  699. status = RpcServerInqBindings(&pbv);
  700. ASSERT(status == RPC_S_OK);
  701. status =
  702. RpcEpRegister(_IOrTest_ServerIfHandle, pbv, 0, 0);
  703. ASSERT(status == RPC_S_OK);
  704. status =
  705. RpcBindingVectorFree(&pbv);
  706. ASSERT(status == RPC_S_OK);
  707. // Register UseProtseq callback IF
  708. status =
  709. RpcServerRegisterIf(_IOrCallback_ServerIfHandle, 0, 0);
  710. ASSERT(status == RPC_S_OK);
  711. // Register test to test IF
  712. status =
  713. RpcServerRegisterIf(_IOrTest_ServerIfHandle, 0, 0);
  714. ASSERT(status == RPC_S_OK);
  715. // Register rundown OID (fake ORPC) callback IF
  716. status =
  717. RpcServerRegisterIf(_IRundown_ServerIfHandle, 0, 0);
  718. ASSERT(status == RPC_S_OK);
  719. status =
  720. RpcServerListen(1, 10, TRUE);
  721. ASSERT(status == RPC_S_OK);
  722. hServerEvent = CreateEvent(0, FALSE, FALSE, 0);
  723. hClientEvent = CreateEvent(0, FALSE, FALSE, 0);
  724. hRundownEvent = CreateEvent(0, FALSE, FALSE, 0);
  725. ASSERT(hServerEvent && hClientEvent && hRundownEvent);
  726. PrintToConsole("\tWaiting for client...\n");
  727. SyncWithClient(++TestCase);
  728. status = RPC_S_OK;
  729. }
  730. else
  731. {
  732. PSZ stringbinding;
  733. // Make binding to remote OR
  734. status =
  735. RpcStringBindingComposeA(0, protseq, server, 0, 0, &stringbinding);
  736. ASSERT(status == RPC_S_OK);
  737. status =
  738. RpcBindingFromStringBindingA(stringbinding, &hServerOrTest);
  739. if (status == RPC_S_OK)
  740. {
  741. status = TestBinding(hServerOrTest);
  742. if (status != RPC_S_OK)
  743. {
  744. PrintToConsole("Connect to server failed %d\n", status);
  745. return(status);
  746. }
  747. status = SyncWithServer(++TestCase);
  748. }
  749. }
  750. return(status);
  751. }
  752. RPC_STATUS
  753. ConnectToLocalOr()
  754. {
  755. RPC_STATUS status;
  756. DWORD timeout;
  757. OXID reservedOxid;
  758. BOOL disable;
  759. DWORD authn;
  760. DWORD imp;
  761. BOOL mutual;
  762. BOOL secref;
  763. DWORD cServerSvc = 0;
  764. PUSHORT pServerSvc = 0;
  765. DWORD cClientSvc = 0;
  766. PUSHORT pClientSvc = 0;
  767. int i;
  768. PWSTR pwstrLegacy = 0;
  769. DWORD cAuthId = 0;
  770. PSZ pszAuthId = 0;
  771. DWORD flags, pid, scm_pid, tokenid;
  772. status =
  773. RpcBindingFromStringBinding(pwstrOr, &hLocalOr);
  774. EQUAL(status, RPC_S_OK);
  775. status = Connect(hLocalOr,
  776. &hMyProcess,
  777. &timeout,
  778. &pdsaLocalOrBindings,
  779. &gLocalMid,
  780. 5,
  781. &reservedBase,
  782. &flags,
  783. &pwstrLegacy,
  784. &authn,
  785. &imp,
  786. &cServerSvc,
  787. &pServerSvc,
  788. &cClientSvc,
  789. &pClientSvc,
  790. &pid,
  791. &scm_pid,
  792. &tokenid);
  793. ASSERT(status == RPC_S_OK);
  794. ASSERT(pdsaLocalOrBindings);
  795. ASSERT(pServerSvc);
  796. ASSERT(pClientSvc);
  797. PrintToConsole("Connected to local object resolver:\n\tFlags:\n");
  798. if (flags & CONNECT_DISABLEDCOM)
  799. {
  800. flags &= ~CONNECT_DISABLEDCOM;
  801. PrintToConsole("\t\tDCOM DISABLED");
  802. }
  803. else
  804. PrintToConsole("\t\tDCOM enabled");
  805. if (flags & CONNECT_MUTUALAUTH)
  806. {
  807. flags &= ~CONNECT_MUTUALAUTH;
  808. PrintToConsole("\tMutal authn");
  809. }
  810. else
  811. PrintToConsole("\tNo Mutal authn");
  812. if (flags & CONNECT_SECUREREF)
  813. {
  814. flags &= ~CONNECT_SECUREREF;
  815. PrintToConsole("\tSecure reference counting\n");
  816. }
  817. else
  818. PrintToConsole("\tStandard reference counting\n");
  819. PrintToConsole("\tSecurity: authn: %d, imp: %d, legacy %S\n", authn, imp, pwstrLegacy);
  820. PrintToConsole("\tTimeout %d seconds, mid %I64x\n"
  821. "\tpid %d, scm pid %d, token id: %d\n",
  822. timeout, gLocalMid, pid, scm_pid, tokenid);
  823. PrintToConsole("\tReserved 5 oids, starting at %I64x\n", reservedBase);
  824. PrintToConsole("\tServer security services: %d\n", cServerSvc);
  825. for (i = 0; i < cServerSvc; i++ )
  826. {
  827. PrintToConsole("\t\tService: %d is %d\n", i, pServerSvc[i]);
  828. }
  829. PrintToConsole("\tClient security services: %d\n", cClientSvc);
  830. for (i = 0; i < cClientSvc; i++ )
  831. {
  832. PrintToConsole("\t\tService: %d is %d\n", i, pClientSvc[i]);
  833. }
  834. PrintDualStringArray("Local OR bindings", pdsaLocalOrBindings, TRUE);
  835. PrintToConsole("\n\n");
  836. MIDL_user_free(pServerSvc);
  837. MIDL_user_free(pClientSvc);
  838. return(RPC_S_OK);
  839. }
  840. // Synchronization between ortest clients and servers
  841. void
  842. SyncWithClient(DWORD Test)
  843. // Called by server thread at start of each test sequence
  844. {
  845. DWORD status;
  846. if (Test > 1) SetEvent(hClientEvent);
  847. PrintToConsole("Waiting for client sync: Test case %d\n", Test);
  848. // Wait for the client to finish his test case
  849. status = WaitForSingleObject(hServerEvent, 120*1000);
  850. if (status == WAIT_TIMEOUT)
  851. {
  852. ASSERT(("Client never called back", 0));
  853. }
  854. if (Test == ~0)
  855. {
  856. SetEvent(hClientEvent);
  857. Sleep(1000);
  858. }
  859. return;
  860. }
  861. // Managers for ortest servers
  862. error_status_t
  863. _TestBinding(
  864. handle_t hClient
  865. )
  866. {
  867. return(RPC_S_OK);
  868. }
  869. error_status_t
  870. _WaitForNextTest(handle_t hClient,
  871. DWORD Test)
  872. // Called by client after each test sequence.
  873. {
  874. DWORD status;
  875. if (Test != TestCase)
  876. {
  877. ASSERT(("Test case sync wrong", 0));
  878. }
  879. SetEvent(hServerEvent);
  880. PrintToConsole("Client ready for test case %d\n", Test);
  881. status = WaitForSingleObject(hClientEvent, 60*20*1000);
  882. if (status == WAIT_TIMEOUT)
  883. {
  884. ASSERT(("Server never finished test case", 0));
  885. }
  886. }
  887. error_status_t
  888. SyncWithServer(DWORD Test)
  889. {
  890. RPC_STATUS status;
  891. status = WaitForNextTest(hServerOrTest, Test);
  892. EQUAL(status, RPC_S_OK);
  893. return(status);
  894. }
  895. error_status_t
  896. _GetState(
  897. handle_t hClient,
  898. long cOxids,
  899. long cOids,
  900. long cOxidInfos,
  901. OXID aoxids[],
  902. OID aoids[],
  903. OXID_INFO aois[],
  904. DUALSTRINGARRAY **ppdsaRemoteOrBindings
  905. )
  906. {
  907. int i;
  908. for (i = 0; i < cOxids; i++)
  909. {
  910. aoxids[i] = aOxids[i];
  911. }
  912. for (i = 0; i < cOids; i++)
  913. {
  914. aoids[i] = aOids[i];
  915. }
  916. for(i = 0; i < cOxidInfos; i++)
  917. {
  918. aois[i].dwTid = aOxidInfo[i].dwTid;
  919. aois[i].dwPid = aOxidInfo[i].dwPid;
  920. aois[i].dwAuthnHint = aOxidInfo[i].dwAuthnHint;
  921. memcpy(&aois[i].ipidRemUnknown, &aOxidInfo[i].ipidRemUnknown, sizeof(IPID));
  922. aois[i].psa = 0;
  923. }
  924. *ppdsaRemoteOrBindings = MIDL_user_allocate(4 + pdsaLocalOrBindings->wNumEntries * 2);
  925. memcpy(*ppdsaRemoteOrBindings, pdsaLocalOrBindings, 4 + pdsaLocalOrBindings->wNumEntries * 2);
  926. return(RPC_S_OK);
  927. }
  928. // Managers for OR callbacks
  929. error_status_t
  930. _UseProtseq(
  931. IN handle_t hRpc,
  932. IN PWSTR pwstrProtseq,
  933. OUT DUALSTRINGARRAY **ppdsa,
  934. OUT DUALSTRINGARRAY **ppdsaSecurity
  935. )
  936. {
  937. RPC_STATUS status;
  938. BOOL f;
  939. DWORD t;
  940. HANDLE hT;
  941. TOKEN_USER *ptu;
  942. BYTE buffer[512];
  943. WCHAR buffer1[256];
  944. if (hRpc)
  945. {
  946. status = RpcImpersonateClient(0);
  947. ASSERT(status == RPC_S_OK);
  948. f = OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_QUERY, TRUE, &hT);
  949. EQUAL(f, TRUE);
  950. CloseHandle(hT);
  951. f = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hT);
  952. EQUAL(f, TRUE);
  953. }
  954. else
  955. {
  956. f = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hT);
  957. EQUAL(f, TRUE);
  958. }
  959. f = GetTokenInformation(hT,
  960. TokenUser,
  961. buffer,
  962. 512,
  963. &t);
  964. EQUAL(f, TRUE);
  965. ptu = (TOKEN_USER *)buffer;
  966. CloseHandle(hT);
  967. t = 256;
  968. f = GetUserNameW(buffer1, &t);
  969. if (f == FALSE)
  970. {
  971. PrintToConsole("Get user name failed %d\n", GetLastError());
  972. }
  973. PrintToConsole("UseProtseq %S called by %S:\n\t", pwstrProtseq, buffer1);
  974. PrintSid(ptu->User.Sid);
  975. RpcRevertToSelf();
  976. if (!fServer && _wcsicmp(pwstrProtseq, L"ncalrpc") != 0)
  977. {
  978. ASSERT(0);
  979. }
  980. status = RpcServerUseProtseqW(pwstrProtseq, 0, 0);
  981. ASSERT(status == RPC_S_OK);
  982. // Construct new bindings array.
  983. {
  984. RPC_BINDING_VECTOR * pbv;
  985. int i, j = 0;
  986. PWSTR pT = pdsaMyExpandedStringBindings->aStringArray;
  987. status = RpcServerInqBindings(&pbv);
  988. EQUAL(status, RPC_S_OK);
  989. for(i = 0; i < pbv->Count; i++)
  990. {
  991. PWSTR pStringBinding = 0;
  992. status = RpcBindingToStringBinding(pbv->BindingH[i], &pStringBinding);
  993. EQUAL(status, RPC_S_OK);
  994. wcscpy(pT, pStringBinding);
  995. j += wcslen(pT) + 1;
  996. pT = wcschr(pT, 0);
  997. pT++;
  998. status = RpcStringFree(&pStringBinding);
  999. EQUAL(status, RPC_S_OK);
  1000. EQUAL(pStringBinding, 0);
  1001. }
  1002. *pT = 0;
  1003. pdsaMyExpandedStringBindings->wNumEntries = j + 1 + 2;
  1004. pdsaMyExpandedStringBindings->wSecurityOffset = j + 1;
  1005. pT[1] = 0; // no security
  1006. pT[2] = 0;
  1007. }
  1008. *ppdsa = MIDL_user_allocate(sizeof(DUALSTRINGARRAY) + pdsaMyExpandedStringBindings->wNumEntries * 2);
  1009. ASSERT(*ppdsa);
  1010. (*ppdsa)->wNumEntries = pdsaMyExpandedStringBindings->wNumEntries;
  1011. (*ppdsa)->wSecurityOffset = pdsaMyExpandedStringBindings->wSecurityOffset;
  1012. memcpy((*ppdsa)->aStringArray,
  1013. pdsaMyExpandedStringBindings->aStringArray,
  1014. pdsaMyExpandedStringBindings->wNumEntries * 2);
  1015. *ppdsaSecurity = MIDL_user_allocate(sizeof(DUALSTRINGARRAY) + 6*2);
  1016. ASSERT(*ppdsaSecurity);
  1017. (*ppdsaSecurity)->wNumEntries = 6;
  1018. (*ppdsaSecurity)->wSecurityOffset = 2;
  1019. (*ppdsaSecurity)->aStringArray[0] = 0;
  1020. (*ppdsaSecurity)->aStringArray[1] = 0;
  1021. (*ppdsaSecurity)->aStringArray[2] = 10; // authn winnt
  1022. (*ppdsaSecurity)->aStringArray[3] = -1; // authz none
  1023. (*ppdsaSecurity)->aStringArray[4] = 0;
  1024. (*ppdsaSecurity)->aStringArray[5] = 0;
  1025. return(0);
  1026. }
  1027. error_status_t
  1028. _RawRundownOid(
  1029. handle_t hRpc,
  1030. ORPCTHIS *pthis,
  1031. LOCALTHIS *plocalthis,
  1032. ORPCTHAT *pthat,
  1033. ULONG cOid,
  1034. OID aOid[],
  1035. UCHAR afOk[]
  1036. )
  1037. {
  1038. int i, j;
  1039. RPC_STATUS status;
  1040. BOOL fFound;
  1041. IPID ipidT;
  1042. UCHAR buffer[512];
  1043. WCHAR buffer1[256];
  1044. DWORD t;
  1045. BOOL f;
  1046. HANDLE hT;
  1047. TOKEN_USER *ptu;
  1048. ASSERT(cOid);
  1049. ASSERT(plocalthis->callcat == CALLCAT_SYNCHRONOUS);
  1050. ASSERT(plocalthis->dwClientThread == 0);
  1051. ASSERT(pthis->extensions == 0);
  1052. ASSERT(pthis->version.MajorVersion == COM_MAJOR_VERSION);
  1053. ASSERT(pthis->version.MinorVersion == COM_MINOR_VERSION);
  1054. ASSERT(pthis->flags == ORPCF_LOCAL);
  1055. ASSERT(pthis->reserved1 == 0);
  1056. ASSERT(pthat->extensions == 0);
  1057. pthat->flags = 0;
  1058. status = RpcImpersonateClient(0);
  1059. ASSERT(status == RPC_S_OK);
  1060. t = 256;
  1061. f = GetUserNameW(buffer1, &t);
  1062. if (f == FALSE)
  1063. {
  1064. PrintToConsole("Get user name failed %d\n", GetLastError());
  1065. }
  1066. f = OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_QUERY, TRUE, &hT);
  1067. EQUAL(f, TRUE);
  1068. CloseHandle(hT);
  1069. f = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hT);
  1070. EQUAL(f, TRUE);
  1071. f = GetTokenInformation(hT,
  1072. TokenUser,
  1073. buffer,
  1074. 512,
  1075. &t);
  1076. EQUAL(f, TRUE);
  1077. ptu = (TOKEN_USER *)buffer;
  1078. CloseHandle(hT);
  1079. status = RpcBindingInqObject(hRpc, &ipidT);
  1080. ASSERT(status == RPC_S_OK);
  1081. PrintToConsole("Rundown of %d oids called by %S:\n\t", cOid, buffer1);
  1082. PrintSid(ptu->User.Sid);
  1083. for (j = 0; j < cOid; j++)
  1084. {
  1085. fFound = FALSE;
  1086. PrintToConsole("Oid %I64x randown\n", aOid[j]);
  1087. for(i = 0; i < dwlimRundowns; i++)
  1088. {
  1089. if (aOid[j] == aRundowns[i].oid)
  1090. {
  1091. fFound = TRUE;
  1092. if (aRundowns[i].fForceSecond)
  1093. {
  1094. aRundowns[i].fForceSecond = FALSE;
  1095. afOk[j] = 0;
  1096. }
  1097. else
  1098. {
  1099. afOk[j] = 1;
  1100. EQUAL(aRundowns[i].fReady, TRUE);
  1101. aRundowns[i].fReady = FALSE;
  1102. aRundowns[i].oid = aRundowns[dwlimRundowns - 1].oid;
  1103. aRundowns[i].fReady = aRundowns[dwlimRundowns - 1].fReady;
  1104. aRundowns[i].fForceSecond = aRundowns[dwlimRundowns - 1].fForceSecond;
  1105. dwlimRundowns--;
  1106. SetEvent(hRundownEvent);
  1107. }
  1108. }
  1109. }
  1110. if (!fFound)
  1111. {
  1112. PrintToConsole("Unexpected oid rundown: %I64x\n", aOid[j]);
  1113. afOk[j] = 1;
  1114. }
  1115. }
  1116. RpcRevertToSelf();
  1117. return(0);
  1118. }
  1119. // Unimplement IRundown base methods
  1120. HRESULT
  1121. _DummyQueryInterfaceIOSCM(
  1122. handle_t rpc,
  1123. ORPCTHIS *pthis,
  1124. LOCALTHIS *plocalthis,
  1125. ORPCTHAT *pthat,
  1126. DWORD dummy)
  1127. {
  1128. ASSERT(0);
  1129. }
  1130. HRESULT
  1131. _DummyAddRefIOSCM(
  1132. handle_t rpc,
  1133. ORPCTHIS *pthis,
  1134. LOCALTHIS *plocalthis,
  1135. ORPCTHAT *pthat,
  1136. DWORD dummy)
  1137. {
  1138. ASSERT(0);
  1139. }
  1140. HRESULT
  1141. _DummyReleaseIOSCM(
  1142. handle_t rpc,
  1143. ORPCTHIS *pthis,
  1144. LOCALTHIS *plocalthis,
  1145. ORPCTHAT *pthat,
  1146. DWORD dummy)
  1147. {
  1148. ASSERT(0);
  1149. }
  1150. HRESULT
  1151. _DummyRemQuery(
  1152. handle_t handle
  1153. )
  1154. {
  1155. ASSERT(0);
  1156. }
  1157. HRESULT
  1158. _DummyRemAddRef(
  1159. handle_t handle
  1160. )
  1161. {
  1162. ASSERT(0);
  1163. }
  1164. HRESULT
  1165. _DummyRemRelease(
  1166. handle_t handle
  1167. )
  1168. {
  1169. ASSERT(0);
  1170. }
  1171. HRESULT
  1172. _DummyRemChangeRef(
  1173. handle_t handle
  1174. )
  1175. {
  1176. ASSERT(0);
  1177. }
  1178. HRESULT
  1179. _DummyRemQueryInterface2(
  1180. handle_t handle
  1181. )
  1182. {
  1183. ASSERT(0);
  1184. }
  1185. // Rundown helpers
  1186. void
  1187. AddRundown(ID oid, BOOL fRundownTwice)
  1188. {
  1189. aRundowns[dwlimRundowns].oid = oid;
  1190. aRundowns[dwlimRundowns].fReady = TRUE;
  1191. aRundowns[dwlimRundowns].fForceSecond = fRundownTwice;
  1192. dwlimRundowns++;
  1193. }
  1194. void WaitForAllRundowns()
  1195. {
  1196. DWORD status;
  1197. int i;
  1198. BOOL fDone;
  1199. PrintToConsole("Waiting for rundowns...\n");
  1200. for(;;)
  1201. {
  1202. status = WaitForSingleObject(hRundownEvent, 19 * 60 * 1000);
  1203. if (status == WAIT_TIMEOUT)
  1204. {
  1205. PrintToConsole("Wait for rundowns took a long time...\n");
  1206. ASSERT(0);
  1207. }
  1208. fDone = TRUE;
  1209. for(i = 0; i < dwlimRundowns; i++)
  1210. {
  1211. if (aRundowns[i].fReady)
  1212. {
  1213. fDone = FALSE;
  1214. }
  1215. }
  1216. if (fDone)
  1217. {
  1218. return;
  1219. }
  1220. }
  1221. }
  1222. // Needs to link rtifs.lib, but shouldn't be called..
  1223. void FixupForUniquePointerServers(void *p)
  1224. {
  1225. ASSERT(0);
  1226. }