Windows NT 4.0 source code leak
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.

346 lines
11 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. userver.c
  5. Abstract:
  6. User Mode Server Test program for the LPC subcomponent of the NTOS project
  7. Author:
  8. Steve Wood (stevewo) 28-Aug-1989
  9. Revision History:
  10. --*/
  11. #include "ulpc.h"
  12. #define MAX_REQUEST_THREADS 9
  13. #define MAX_CONNECTIONS 4
  14. HANDLE ServerConnectionPortHandle;
  15. HANDLE ServerThreadHandles[ MAX_REQUEST_THREADS ];
  16. DWORD ServerThreadClientIds[ MAX_REQUEST_THREADS ];
  17. HANDLE ServerClientPortHandles[ MAX_CONNECTIONS ];
  18. ULONG CountServerClientPortHandles = 0;
  19. ULONG CountClosedServerClientPortHandles = 0;
  20. BOOLEAN TestCallBacks;
  21. VOID
  22. ServerHandleConnectionRequest(
  23. IN PTLPC_PORTMSG Msg
  24. )
  25. {
  26. BOOLEAN AcceptConnection;
  27. LPSTR ConnectionInformation;
  28. ULONG ConnectionInformationLength;
  29. NTSTATUS Status;
  30. PORT_VIEW ServerView;
  31. REMOTE_PORT_VIEW ClientView;
  32. ULONG i;
  33. PULONG p;
  34. ConnectionInformation = (LPSTR)&Msg->Data[ 0 ];
  35. ConnectionInformationLength = Msg->h.u1.s1.DataLength;
  36. AcceptConnection = FALSE;
  37. fprintf( stderr, "\nConnection Request Received from CLIENT_ID 0x%08lx.0x%08lx:\n",
  38. Msg->h.ClientId.UniqueProcess,
  39. Msg->h.ClientId.UniqueThread
  40. );
  41. fprintf( stderr, " MessageId: %ld\n",
  42. Msg->h.MessageId
  43. );
  44. fprintf( stderr, " ClientViewSize: 0x%08lx\n",
  45. Msg->h.ClientViewSize
  46. );
  47. fprintf( stderr, " ConnectionInfo: (%ld) '%.*s'\n",
  48. ConnectionInformationLength,
  49. ConnectionInformationLength,
  50. (PSZ)&ConnectionInformation[0]
  51. );
  52. ClientView.Length = sizeof( ClientView );
  53. ClientView.ViewSize = 0;
  54. ClientView.ViewBase = 0;
  55. if (CountServerClientPortHandles >= MAX_CONNECTIONS) {
  56. AcceptConnection = FALSE;
  57. }
  58. else {
  59. AcceptConnection = TRUE;
  60. }
  61. if (AcceptConnection) {
  62. LARGE_INTEGER MaximumSize;
  63. fprintf( stderr, "Creating Port Memory Section" );
  64. MaximumSize.QuadPart = 0x4000;
  65. Status = NtCreateSection( &ServerView.SectionHandle,
  66. SECTION_MAP_READ | SECTION_MAP_WRITE,
  67. NULL,
  68. &MaximumSize,
  69. PAGE_READWRITE,
  70. SEC_COMMIT,
  71. NULL
  72. );
  73. if (ShowHandleOrStatus( Status, ServerView.SectionHandle )) {
  74. ServerView.Length = sizeof( ServerView );
  75. ServerView.SectionOffset = 0;
  76. ServerView.ViewSize = 0x4000;
  77. ServerView.ViewBase = 0;
  78. ServerView.ViewRemoteBase = 0;
  79. }
  80. else {
  81. AcceptConnection = FALSE;
  82. }
  83. }
  84. fprintf( stderr, "Server calling NtAcceptConnectPort( AcceptConnection = %ld )",
  85. AcceptConnection
  86. );
  87. if (AcceptConnection) {
  88. strcpy( ConnectionInformation, "Server Accepting Connection" );
  89. }
  90. else {
  91. strcpy( ConnectionInformation, "Server Rejecting Connection" );
  92. }
  93. Msg->h.u1.s1.DataLength = strlen( ConnectionInformation ) + 1;
  94. Msg->h.u1.s1.TotalLength = Msg->h.u1.s1.DataLength + sizeof( Msg->h );
  95. Status = NtAcceptConnectPort( &ServerClientPortHandles[ CountServerClientPortHandles ],
  96. (PVOID)(CountServerClientPortHandles+1),
  97. &Msg->h,
  98. AcceptConnection,
  99. &ServerView,
  100. &ClientView
  101. );
  102. if (ShowHandleOrStatus( Status, ServerClientPortHandles[ CountServerClientPortHandles ] )) {
  103. fprintf( stderr, " ServerView: Base=%lx, Size=%lx, RemoteBase: %lx\n",
  104. ServerView.ViewBase,
  105. ServerView.ViewSize,
  106. ServerView.ViewRemoteBase
  107. );
  108. fprintf( stderr, " ClientView: Base=%lx, Size=%lx\n",
  109. ClientView.ViewBase,
  110. ClientView.ViewSize
  111. );
  112. ClientMemoryBase = ServerView.ViewBase;
  113. ClientMemorySize = ServerView.ViewSize;
  114. ServerMemoryBase = ServerView.ViewRemoteBase;
  115. ServerMemoryDelta = (ULONG)ServerMemoryBase -
  116. (ULONG)ClientMemoryBase;
  117. p = (PULONG)(ClientView.ViewBase);
  118. i =ClientView.ViewSize;
  119. while (i) {
  120. *p = (ULONG)p;
  121. fprintf( stderr, "Server setting ClientView[ %lx ] = %lx\n",
  122. p,
  123. *p
  124. );
  125. p += (0x1000/sizeof(ULONG));
  126. i -= 0x1000;
  127. }
  128. p = (PULONG)(ServerView.ViewBase);
  129. i = ServerView.ViewSize;
  130. while (i) {
  131. *p = (ULONG)p - ServerMemoryDelta;
  132. fprintf( stderr, "Server setting ServerView[ %lx ] = %lx\n",
  133. p,
  134. *p
  135. );
  136. p += (0x1000/sizeof(ULONG));
  137. i -= 0x1000;
  138. }
  139. Status = NtCompleteConnectPort( ServerClientPortHandles[ CountServerClientPortHandles ] );
  140. CountServerClientPortHandles++;
  141. }
  142. return;
  143. }
  144. DWORD
  145. ServerThread(
  146. LPVOID Context
  147. )
  148. {
  149. NTSTATUS Status;
  150. CHAR ThreadName[ 64 ];
  151. TLPC_PORTMSG Msg;
  152. PTLPC_PORTMSG ReplyMsg;
  153. HANDLE ReplyPortHandle;
  154. ULONG PortContext;
  155. PTEB Teb = NtCurrentTeb();
  156. Teb->ActiveRpcHandle = NULL;
  157. strcpy( ThreadName, "Server Thread Id: " );
  158. RtlIntegerToChar( (ULONG)Teb->ClientId.UniqueProcess, 16, 9,
  159. ThreadName + strlen( ThreadName )
  160. );
  161. strcat( ThreadName, "." );
  162. RtlIntegerToChar( (ULONG)Teb->ClientId.UniqueThread, 16, 9,
  163. ThreadName + strlen( ThreadName )
  164. );
  165. EnterThread( ThreadName, (ULONG)Context );
  166. ReplyMsg = NULL;
  167. ReplyPortHandle = ServerConnectionPortHandle;
  168. while (TRUE) {
  169. fprintf( stderr, "%s waiting for message...\n", ThreadName );
  170. Status = NtReplyWaitReceivePort( ReplyPortHandle,
  171. (PVOID)&PortContext,
  172. (PPORT_MESSAGE)ReplyMsg,
  173. (PPORT_MESSAGE)&Msg
  174. );
  175. ReplyMsg = NULL;
  176. ReplyPortHandle = ServerConnectionPortHandle;
  177. fprintf( stderr, "%s Receive (%s) Id: %u", ThreadName, LpcMsgTypes[ Msg.h.u2.s2.Type ], Msg.h.MessageId );
  178. PortContext -= 1;
  179. if (!NT_SUCCESS( Status )) {
  180. fprintf( stderr, " (Status == %08x)\n", Status );
  181. }
  182. else
  183. if (Msg.h.u2.s2.Type == LPC_CONNECTION_REQUEST) {
  184. ServerHandleConnectionRequest( &Msg );
  185. continue;
  186. }
  187. else
  188. if (PortContext >= CountServerClientPortHandles) {
  189. fprintf( stderr, "*** Invalid PortContext (%lx) received\n",
  190. PortContext
  191. );
  192. }
  193. else
  194. if (Msg.h.u2.s2.Type == LPC_PORT_CLOSED ||
  195. Msg.h.u2.s2.Type == LPC_CLIENT_DIED
  196. ) {
  197. fprintf( stderr, " - disconnect for client %08x\n", PortContext );
  198. CloseHandle( ServerClientPortHandles[ (ULONG)PortContext ] );
  199. CountClosedServerClientPortHandles += 1;
  200. if (CountClosedServerClientPortHandles == CountServerClientPortHandles) {
  201. break;
  202. }
  203. }
  204. else
  205. if (Msg.h.u2.s2.Type == LPC_REQUEST) {
  206. CheckTlpcMsg( Status, &Msg );
  207. ReplyMsg = &Msg;
  208. ReplyPortHandle = ServerClientPortHandles[ PortContext ];
  209. if (TestCallBacks && (Msg.h.u1.s1.DataLength > 30)) {
  210. Status = SendRequest( 1,
  211. ThreadName,
  212. ReplyPortHandle,
  213. Context,
  214. Msg.h.u1.s1.DataLength >> 1,
  215. ReplyMsg,
  216. TRUE
  217. );
  218. }
  219. }
  220. }
  221. fprintf( stderr, "Exiting %s\n", ThreadName );
  222. return RtlNtStatusToDosError( Status );
  223. }
  224. VOID
  225. Usage( VOID )
  226. {
  227. fprintf( stderr, "usage: USERVER #threads\n" );
  228. ExitProcess( 1 );
  229. }
  230. int
  231. _cdecl
  232. main(
  233. int argc,
  234. char *argv[]
  235. )
  236. {
  237. NTSTATUS Status;
  238. DWORD rc;
  239. ULONG i, NumberOfThreads;
  240. OBJECT_ATTRIBUTES ObjectAttributes;
  241. Status = STATUS_SUCCESS;
  242. fprintf( stderr, "Entering USERVER User Mode LPC Test Program\n" );
  243. TestCallBacks = FALSE;
  244. if (argc < 2) {
  245. NumberOfThreads = 1;
  246. }
  247. else {
  248. NumberOfThreads = atoi( argv[ 1 ] );
  249. if (NumberOfThreads >= MAX_REQUEST_THREADS) {
  250. Usage();
  251. }
  252. if (argc > 2) {
  253. TestCallBacks = TRUE;
  254. }
  255. }
  256. RtlInitUnicodeString( &PortName, PORT_NAME );
  257. fprintf( stderr, "Creating %wZ connection port", (PUNICODE_STRING)&PortName );
  258. InitializeObjectAttributes( &ObjectAttributes, &PortName, 0, NULL, NULL );
  259. Status = NtCreatePort( &ServerConnectionPortHandle,
  260. &ObjectAttributes,
  261. 40,
  262. sizeof( TLPC_PORTMSG ),
  263. sizeof( TLPC_PORTMSG ) * 32
  264. );
  265. ShowHandleOrStatus( Status, ServerConnectionPortHandle );
  266. rc = RtlNtStatusToDosError( Status );
  267. if (rc == NO_ERROR) {
  268. ServerThreadHandles[ 0 ] = GetCurrentThread();
  269. ServerThreadClientIds[ 0 ] = GetCurrentThreadId();
  270. for (i=1; i<NumberOfThreads; i++) {
  271. fprintf( stderr, "Creating Server Request Thread %ld\n", i+1 );
  272. rc = NO_ERROR;
  273. ServerThreadHandles[ i ] = CreateThread( NULL,
  274. 0,
  275. (LPTHREAD_START_ROUTINE)ServerThread,
  276. (LPVOID)(i+1),
  277. CREATE_SUSPENDED,
  278. &ServerThreadClientIds[ i ]
  279. );
  280. if (ServerThreadHandles[ i ] == NULL) {
  281. rc = GetLastError();
  282. break;
  283. }
  284. }
  285. if (rc == NO_ERROR) {
  286. for (i=1; i<NumberOfThreads; i++) {
  287. ResumeThread( ServerThreadHandles[ i ] );
  288. }
  289. ServerThread( 0 );
  290. }
  291. }
  292. if (rc != NO_ERROR) {
  293. fprintf( stderr, "USERVER: Initialization Failed - %u\n", rc );
  294. }
  295. ExitProcess( rc );
  296. return( rc );
  297. }