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.

327 lines
8.9 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. ulpc.h
  5. Abstract:
  6. User Mode Test header file for common definitions shared by userver.c
  7. and uclient.c
  8. Author:
  9. Steve Wood (stevewo) 28-Aug-1989
  10. Revision History:
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #define PORT_NAME L"\\RPC Control\\LpcTestPort"
  20. UNICODE_STRING PortName;
  21. char * LpcMsgTypes[] = {
  22. "** INVALID **",
  23. "LPC_REQUEST",
  24. "LPC_REPLY",
  25. "LPC_DATAGRAM",
  26. "LPC_LOST_REPLY",
  27. "LPC_PORT_CLOSED",
  28. "LPC_CLIENT_DIED",
  29. "LPC_EXCEPTION",
  30. "LPC_DEBUG_EVENT",
  31. "LPC_ERROR_EVENT",
  32. "LPC_CONNECTION_REQUEST",
  33. NULL
  34. };
  35. SECURITY_QUALITY_OF_SERVICE DynamicQos = {
  36. SecurityImpersonation,
  37. SECURITY_DYNAMIC_TRACKING,
  38. TRUE
  39. };
  40. #define TLPC_MAX_MSG_DATA_LENGTH 16
  41. typedef struct _TLPC_PORTMSG {
  42. PORT_MESSAGE h;
  43. ULONG Data[ TLPC_MAX_MSG_DATA_LENGTH ];
  44. } TLPC_PORTMSG, *PTLPC_PORTMSG;
  45. PCH ClientMemoryBase = 0;
  46. ULONG ClientMemorySize = 0;
  47. PCH ServerMemoryBase = 0;
  48. ULONG ServerMemoryDelta = 0;
  49. typedef struct _PAGE {
  50. CHAR Data[ 4096 ];
  51. } PAGE, *PPAGE;
  52. PPORT_MESSAGE
  53. InitTlpcMsg(
  54. PTLPC_PORTMSG Msg,
  55. PVOID Context,
  56. ULONG MsgLength
  57. )
  58. {
  59. ULONG i;
  60. ULONG ClientIndex;
  61. ULONG cbData = MsgLength % (TLPC_MAX_MSG_DATA_LENGTH * sizeof( ULONG ));
  62. PULONG ClientMemoryPtr;
  63. Msg->h.u1.Length = ((sizeof( Msg->h ) + cbData) << 16) | cbData;
  64. Msg->h.u2.ZeroInit = 0;
  65. ClientIndex = (ULONG)Context & 0xF;
  66. ClientIndex -= 1;
  67. if (cbData) {
  68. Msg->Data[ 0 ] = (ULONG)Context;
  69. ClientMemoryPtr = (PULONG)(ClientMemoryBase + (ClientIndex * 0x1000));
  70. for (i=1; i<(cbData/sizeof(ULONG)); i++) {
  71. *ClientMemoryPtr = (ULONG)Context;
  72. Msg->Data[ i ] = (ULONG)ClientMemoryPtr + ServerMemoryDelta;
  73. ClientMemoryPtr++;
  74. }
  75. }
  76. return( (PPORT_MESSAGE)Msg );
  77. }
  78. BOOLEAN
  79. CheckTlpcMsg(
  80. NTSTATUS Status,
  81. PTLPC_PORTMSG Msg
  82. )
  83. {
  84. ULONG i;
  85. ULONG ClientIndex;
  86. ULONG cbData = Msg->h.u1.s1.DataLength;
  87. ULONG Context;
  88. PULONG ServerMemoryPtr;
  89. PULONG ClientMemoryPtr;
  90. ULONG ExpectedContext;
  91. BOOLEAN Result;
  92. if (!NT_SUCCESS( Status )) {
  93. fprintf( stderr, " - FAILED. Status == %X\n", Status );
  94. return( FALSE );
  95. }
  96. if (Msg->h.u2.s2.Type == LPC_CONNECTION_REQUEST) {
  97. fprintf( stderr, " connection request" );
  98. }
  99. else
  100. if (cbData) {
  101. Context = Msg->Data[ 0 ];
  102. ClientIndex = Context & 0xF;
  103. ClientIndex -= 1;
  104. ClientMemoryPtr = (PULONG)(ClientMemoryBase + (ClientIndex * 0x1000));
  105. for (i=1; i<(cbData/sizeof( ULONG )); i++) {
  106. if (Msg->h.u2.s2.Type == LPC_REPLY) {
  107. if (Msg->Data[ i ] != ((ULONG)ClientMemoryPtr + ServerMemoryDelta) ||
  108. *ClientMemoryPtr != (ULONG)Context
  109. ) {
  110. fprintf( stderr, " incorrectly\n" );
  111. fprintf( stderr, " Msg->Data[ %ld ] == %lx != %lx || %lx -> %lx != %lx\n",
  112. i, Msg->Data[ i ], (ULONG)ClientMemoryPtr + ServerMemoryDelta,
  113. ClientMemoryPtr, *ClientMemoryPtr, Context
  114. );
  115. return( FALSE );
  116. }
  117. ClientMemoryPtr++;
  118. }
  119. else {
  120. ServerMemoryPtr = (PULONG)(Msg->Data[ i ]);
  121. try {
  122. ExpectedContext = *ServerMemoryPtr;
  123. Result = (ExpectedContext != Context) ? FALSE : TRUE;
  124. }
  125. except( EXCEPTION_EXECUTE_HANDLER ) {
  126. ExpectedContext = 0xFEFEFEFE;
  127. Result = FALSE;
  128. }
  129. if (!Result) {
  130. fprintf( stderr, " incorrectly\n" );
  131. fprintf( stderr, " Msg->Data[ %ld ] == %lx -> %lx != %lx\n",
  132. i, Msg->Data[ i ], ExpectedContext, Context
  133. );
  134. return( FALSE );
  135. }
  136. }
  137. }
  138. }
  139. fprintf( stderr, " correctly\n" );
  140. return( TRUE );
  141. }
  142. BOOLEAN
  143. ShowHandleOrStatus(
  144. NTSTATUS Status,
  145. HANDLE Handle
  146. )
  147. {
  148. if (NT_SUCCESS( Status )) {
  149. fprintf( stderr, " - Handle = 0x%lx\n", Handle );
  150. return( TRUE );
  151. }
  152. else {
  153. fprintf( stderr, " - *** FAILED *** Status == %X\n", Status );
  154. return( FALSE );
  155. }
  156. }
  157. BOOLEAN
  158. ShowStatus(
  159. NTSTATUS Status
  160. )
  161. {
  162. if (NT_SUCCESS( Status )) {
  163. fprintf( stderr, " - success\n" );
  164. return( TRUE );
  165. }
  166. else {
  167. fprintf( stderr, " - *** FAILED *** Status == %X\n", Status );
  168. return( FALSE );
  169. }
  170. }
  171. PCH EnterString = ">>>>>>>>>>";
  172. PCH InnerString = "||||||||||";
  173. PCH LeaveString = "<<<<<<<<<<";
  174. NTSTATUS
  175. SendRequest(
  176. ULONG Level,
  177. PSZ ThreadName,
  178. HANDLE PortHandle,
  179. PVOID Context,
  180. ULONG MsgLength,
  181. PTLPC_PORTMSG CallBackTarget,
  182. BOOLEAN ServerCallingClient
  183. )
  184. {
  185. NTSTATUS Status;
  186. TLPC_PORTMSG Request, Reply;
  187. PTEB Teb = NtCurrentTeb();
  188. fprintf( stderr, "%.*sEnter SendRequest, %lx.%lx",
  189. Level, EnterString,
  190. Teb->ClientId.UniqueProcess,
  191. Teb->ClientId.UniqueThread
  192. );
  193. InitTlpcMsg( &Request, Context, MsgLength );
  194. if (CallBackTarget == NULL) {
  195. fprintf( stderr, " - Request");
  196. }
  197. else {
  198. Request.h.u2.s2.Type = LPC_REQUEST;
  199. Request.h.ClientId = CallBackTarget->h.ClientId;
  200. Request.h.MessageId = CallBackTarget->h.MessageId;
  201. fprintf( stderr, " - Callback to %lx.%lx, ID: %ld",
  202. Request.h.ClientId.UniqueProcess,
  203. Request.h.ClientId.UniqueThread,
  204. Request.h.MessageId
  205. );
  206. }
  207. fprintf( stderr, " (%ld bytes)...\n", Request.h.u1.s1.DataLength );
  208. Status = NtRequestWaitReplyPort( PortHandle,
  209. (PPORT_MESSAGE)&Request,
  210. (PPORT_MESSAGE)&Reply
  211. );
  212. fprintf( stderr, "%.*s %lx.%lx, ID: %u received ",
  213. Level, InnerString,
  214. Teb->ClientId.UniqueProcess,
  215. Teb->ClientId.UniqueThread,
  216. Reply.h.MessageId
  217. );
  218. if (Reply.h.u2.s2.Type == LPC_REPLY) {
  219. if (!CheckTlpcMsg( Status, &Reply )) {
  220. Status = STATUS_UNSUCCESSFUL;
  221. fprintf( stderr, "SendRequest got invalid reply message at %x\n", &Reply );
  222. DbgBreakPoint();
  223. }
  224. }
  225. else {
  226. fprintf( stderr, "callback from %lx.%lx, ID: %ld",
  227. Reply.h.ClientId.UniqueProcess,
  228. Reply.h.ClientId.UniqueThread,
  229. Reply.h.MessageId
  230. );
  231. if (!CheckTlpcMsg( Status, &Reply )) {
  232. Status = STATUS_UNSUCCESSFUL;
  233. fprintf( stderr, "SendRequest got invalid callback message at %x\n", &Reply );
  234. DbgBreakPoint();
  235. }
  236. else {
  237. MsgLength = Reply.h.u1.s1.DataLength / 2;
  238. if (MsgLength) {
  239. Status = SendRequest( Level+1,
  240. ThreadName,
  241. PortHandle,
  242. Context,
  243. MsgLength,
  244. &Reply,
  245. ServerCallingClient
  246. );
  247. }
  248. if (!ServerCallingClient || Level > 1) {
  249. fprintf( stderr, "%.*s %lx.%lx sending ",
  250. Level, InnerString,
  251. Teb->ClientId.UniqueProcess,
  252. Teb->ClientId.UniqueThread
  253. );
  254. fprintf( stderr, " callback (%u) reply to %lx.%lx, ID: %u (%ld bytes)...\n",
  255. Level,
  256. Reply.h.ClientId.UniqueProcess,
  257. Reply.h.ClientId.UniqueThread,
  258. Reply.h.MessageId,
  259. Reply.h.u1.s1.DataLength
  260. );
  261. if (Level > 1) {
  262. Status = NtReplyWaitReplyPort( PortHandle,
  263. (PPORT_MESSAGE)&Reply
  264. );
  265. }
  266. }
  267. }
  268. }
  269. fprintf( stderr, "%.*sLeave SendRequest, %lx.%lx - Status == %X\n",
  270. Level, LeaveString,
  271. Teb->ClientId.UniqueProcess,
  272. Teb->ClientId.UniqueThread,
  273. Status
  274. );
  275. return( Status );
  276. }
  277. VOID
  278. EnterThread(
  279. PSZ ThreadName,
  280. ULONG Context
  281. )
  282. {
  283. fprintf( stderr, "Entering %s thread, Context = 0x%lx\n",
  284. ThreadName,
  285. Context
  286. );
  287. }