test: userver.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# userver.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1989  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     userver.c
    00008
    00009 Abstract:
    00010
    00011     User Mode Server Test program for the LPC subcomponent of the NTOS project
    00012
    00013 Author:
    00014
    00015     Steve Wood (stevewo) 28-Aug-1989
    00016
    00017 Revision History:
    00018
    00019 --*/
    00020
    00021 #include "ulpc.h"
    00022
    00023 #define MAX_REQUEST_THREADS 9
    00024 #define MAX_CONNECTIONS 4
    00025
    00026 HANDLE ServerConnectionPortHandle;
    00027 HANDLE ServerThreadHandles[ MAX_REQUEST_THREADS ];
    00028 DWORD  ServerThreadClientIds[ MAX_REQUEST_THREADS ];
    00029
    00030 HANDLE ServerClientPortHandles[ MAX_CONNECTIONS ];
    00031 ULONG CountServerClientPortHandles = 0;
    00032 ULONG CountClosedServerClientPortHandles = 0;
    00033
    00034 BOOLEAN TestCallBacks;
    00035
    00036 VOID
    00037 ServerHandleConnectionRequest(
    00038     IN PTLPC_PORTMSG Msg
    00039     )
    00040 {
    00041     BOOLEAN AcceptConnection;
    00042     LPSTR ConnectionInformation;
    00043     ULONG ConnectionInformationLength;
    00044     NTSTATUS Status;
    00045     PORT_VIEW ServerView;
    00046     REMOTE_PORT_VIEW ClientView;
    00047     ULONG i;
    00048     PULONG p;
    00049
    00050     ConnectionInformation = (LPSTR)&Msg->Data[ 0 ];
    00051     ConnectionInformationLength = Msg->h.u1.s1.DataLength;
    00052     AcceptConnection = FALSE;
    00053     fprintf( stderr, "\nConnection Request Received from CLIENT_ID 0x%08lx.0x%08lx:\n",
    00054               Msg->h.ClientId.UniqueProcess,
    00055               Msg->h.ClientId.UniqueThread
    00056             );
    00057     fprintf( stderr, "    MessageId: %ld\n",
    00058               Msg->h.MessageId
    00059             );
    00060     fprintf( stderr, "    ClientViewSize: 0x%08lx\n",
    00061               Msg->h.ClientViewSize
    00062             );
    00063     fprintf( stderr, "    ConnectionInfo: (%ld) '%.*s'\n",
    00064               ConnectionInformationLength,
    00065               ConnectionInformationLength,
    00066               (PSZ)&ConnectionInformation[0]
    00067             );
    00068
    00069     ClientView.Length = sizeof( ClientView );
    00070     ClientView.ViewSize = 0;
    00071     ClientView.ViewBase = 0;
    00072     if (CountServerClientPortHandles >= MAX_CONNECTIONS) {
    00073         AcceptConnection = FALSE;
    00074         }
    00075     else {
    00076         AcceptConnection = TRUE;
    00077         }
    00078
    00079     if (AcceptConnection) {
    00080         LARGE_INTEGER MaximumSize;
    00081
    00082         fprintf( stderr, "Creating Port Memory Section" );
    00083         MaximumSize.QuadPart = 0x4000;
    00084         Status = NtCreateSection( &ServerView.SectionHandle,
    00085                                   SECTION_MAP_READ | SECTION_MAP_WRITE,
    00086                                   NULL,
    00087                                   &MaximumSize,
    00088                                   PAGE_READWRITE,
    00089                                   SEC_COMMIT,
    00090                                   NULL
    00091                                 );
    00092
    00093         if (ShowHandleOrStatus( Status, ServerView.SectionHandle )) {
    00094             ServerView.Length = sizeof( ServerView );
    00095             ServerView.SectionOffset = 0;
    00096             ServerView.ViewSize = 0x4000;
    00097             ServerView.ViewBase = 0;
    00098             ServerView.ViewRemoteBase = 0;
    00099             }
    00100         else {
    00101             AcceptConnection = FALSE;
    00102             }
    00103         }
    00104
    00105     fprintf( stderr, "Server calling NtAcceptConnectPort( AcceptConnection = %ld )",
    00106               AcceptConnection
    00107             );
    00108
    00109     if (AcceptConnection) {
    00110         strcpy( ConnectionInformation, "Server Accepting Connection" );
    00111         }
    00112     else {
    00113         strcpy( ConnectionInformation, "Server Rejecting Connection" );
    00114         }
    00115
    00116     Msg->h.u1.s1.DataLength = strlen( ConnectionInformation ) + 1;
    00117     Msg->h.u1.s1.TotalLength = Msg->h.u1.s1.DataLength + sizeof( Msg->h );
    00118     Status = NtAcceptConnectPort( &ServerClientPortHandles[ CountServerClientPortHandles ],
    00119                                   (PVOID)(CountServerClientPortHandles+1),
    00120                                   &Msg->h,
    00121                                   AcceptConnection,
    00122                                   &ServerView,
    00123                                   &ClientView
    00124                                 );
    00125
    00126     if (ShowHandleOrStatus( Status, ServerClientPortHandles[ CountServerClientPortHandles ] )) {
    00127         fprintf( stderr, "    ServerView: Base=%lx, Size=%lx, RemoteBase: %lx\n",
    00128                   ServerView.ViewBase,
    00129                   ServerView.ViewSize,
    00130                   ServerView.ViewRemoteBase
    00131                 );
    00132         fprintf( stderr, "    ClientView: Base=%lx, Size=%lx\n",
    00133                   ClientView.ViewBase,
    00134                   ClientView.ViewSize
    00135                 );
    00136
    00137         ClientMemoryBase = ServerView.ViewBase;
    00138         ClientMemorySize = ServerView.ViewSize;
    00139         ServerMemoryBase = ServerView.ViewRemoteBase;
    00140         ServerMemoryDelta = (ULONG)ServerMemoryBase -
    00141                             (ULONG)ClientMemoryBase;
    00142         p = (PULONG)(ClientView.ViewBase);
    00143         i =ClientView.ViewSize;
    00144         while (i) {
    00145             *p = (ULONG)p;
    00146             fprintf( stderr, "Server setting ClientView[ %lx ] = %lx\n",
    00147                       p,
    00148                       *p
    00149                     );
    00150             p += (0x1000/sizeof(ULONG));
    00151             i -= 0x1000;
    00152             }
    00153
    00154         p = (PULONG)(ServerView.ViewBase);
    00155         i = ServerView.ViewSize;
    00156         while (i) {
    00157             *p = (ULONG)p - ServerMemoryDelta;
    00158             fprintf( stderr, "Server setting ServerView[ %lx ] = %lx\n",
    00159                       p,
    00160                       *p
    00161                     );
    00162             p += (0x1000/sizeof(ULONG));
    00163             i -= 0x1000;
    00164             }
    00165         Status = NtCompleteConnectPort( ServerClientPortHandles[ CountServerClientPortHandles ] );
    00166         CountServerClientPortHandles++;
    00167         }
    00168
    00169     return;
    00170 }
    00171
    00172 DWORD
    00173 ServerThread(
    00174     LPVOID Context
    00175     )
    00176 {
    00177     NTSTATUS Status;
    00178     CHAR ThreadName[ 64 ];
    00179     TLPC_PORTMSG Msg;
    00180     PTLPC_PORTMSG ReplyMsg;
    00181     HANDLE ReplyPortHandle;
    00182     ULONG PortContext;
    00183     PTEB Teb = NtCurrentTeb();
    00184
    00185     Teb->ActiveRpcHandle = NULL;
    00186
    00187     strcpy( ThreadName, "Server Thread Id: " );
    00188     RtlIntegerToChar( (ULONG)Teb->ClientId.UniqueProcess, 16, 9,
    00189                     ThreadName + strlen( ThreadName )
    00190                   );
    00191     strcat( ThreadName, "." );
    00192     RtlIntegerToChar( (ULONG)Teb->ClientId.UniqueThread, 16, 9,
    00193                     ThreadName + strlen( ThreadName )
    00194                   );
    00195
    00196     EnterThread( ThreadName, (ULONG)Context );
    00197
    00198     ReplyMsg = NULL;
    00199     ReplyPortHandle = ServerConnectionPortHandle;
    00200     while (TRUE) {
    00201         fprintf( stderr, "%s waiting for message...\n", ThreadName );
    00202         Status = NtReplyWaitReceivePort( ReplyPortHandle,
    00203                                          (PVOID)&PortContext,
    00204                                          (PPORT_MESSAGE)ReplyMsg,
    00205                                          (PPORT_MESSAGE)&Msg
    00206                                        );
    00207
    00208         ReplyMsg = NULL;
    00209         ReplyPortHandle = ServerConnectionPortHandle;
    00210         fprintf( stderr, "%s Receive (%s)  Id: %u", ThreadName, LpcMsgTypes[ Msg.h.u2.s2.Type ], Msg.h.MessageId );
    00211         PortContext -= 1;
    00212         if (!NT_SUCCESS( Status )) {
    00213             fprintf( stderr, " (Status == %08x)\n", Status );
    00214             }
    00215         else
    00216         if (Msg.h.u2.s2.Type == LPC_CONNECTION_REQUEST) {
    00217             ServerHandleConnectionRequest( &Msg );
    00218             continue;
    00219             }
    00220         else
    00221         if (PortContext >= CountServerClientPortHandles) {
    00222             fprintf( stderr, "*** Invalid PortContext (%lx) received\n",
    00223                      PortContext
    00224                    );
    00225             }
    00226         else
    00227         if (Msg.h.u2.s2.Type == LPC_PORT_CLOSED ||
    00228             Msg.h.u2.s2.Type == LPC_CLIENT_DIED
    00229            ) {
    00230             fprintf( stderr, " - disconnect for client %08x\n", PortContext );
    00231             CloseHandle( ServerClientPortHandles[ (ULONG)PortContext ] );
    00232             CountClosedServerClientPortHandles += 1;
    00233             if (CountClosedServerClientPortHandles == CountServerClientPortHandles) {
    00234                 break;
    00235                 }
    00236             }
    00237         else
    00238         if (Msg.h.u2.s2.Type == LPC_REQUEST) {
    00239             CheckTlpcMsg( Status, &Msg );
    00240             ReplyMsg = &Msg;
    00241             ReplyPortHandle = ServerClientPortHandles[ PortContext ];
    00242             if (TestCallBacks && (Msg.h.u1.s1.DataLength > 30)) {
    00243                 Status = SendRequest( 1,
    00244                                       ThreadName,
    00245                                       ReplyPortHandle,
    00246                                       Context,
    00247                                       Msg.h.u1.s1.DataLength >> 1,
    00248                                       ReplyMsg,
    00249                                       TRUE
    00250                                     );
    00251                 }
    00252             }
    00253         }
    00254
    00255     fprintf( stderr, "Exiting %s\n", ThreadName );
    00256
    00257     return RtlNtStatusToDosError( Status );
    00258 }
    00259
    00260
    00261
    00262 VOID
    00263 Usage( VOID )
    00264 {
    00265     fprintf( stderr, "usage: USERVER #threads\n" );
    00266     ExitProcess( 1 );
    00267 }
    00268
    00269
    00270 int
    00271 _cdecl
    00272 main(
    00273     int argc,
    00274     char *argv[]
    00275     )
    00276 {
    00277     NTSTATUS Status;
    00278     DWORD rc;
    00279     ULONG i, NumberOfThreads;
    00280     OBJECT_ATTRIBUTES ObjectAttributes;
    00281
    00282     Status = STATUS_SUCCESS;
    00283
    00284     fprintf( stderr, "Entering USERVER User Mode LPC Test Program\n" );
    00285
    00286     TestCallBacks = FALSE;
    00287     if (argc < 2) {
    00288         NumberOfThreads = 1;
    00289         }
    00290     else {
    00291         NumberOfThreads = atoi( argv[ 1 ] );
    00292         if (NumberOfThreads >= MAX_REQUEST_THREADS) {
    00293             Usage();
    00294             }
    00295
    00296         if (argc > 2) {
    00297             TestCallBacks = TRUE;
    00298             }
    00299         }
    00300
    00301     RtlInitUnicodeString( &PortName, PORT_NAME );
    00302     fprintf( stderr, "Creating %wZ connection port", (PUNICODE_STRING)&PortName );
    00303     InitializeObjectAttributes( &ObjectAttributes, &PortName, 0, NULL, NULL );
    00304     Status = NtCreatePort( &ServerConnectionPortHandle,
    00305                            &ObjectAttributes,
    00306                            40,
    00307                            sizeof( TLPC_PORTMSG ),
    00308                            sizeof( TLPC_PORTMSG ) * 32
    00309                          );
    00310     ShowHandleOrStatus( Status, ServerConnectionPortHandle );
    00311     rc = RtlNtStatusToDosError( Status );
    00312     if (rc == NO_ERROR) {
    00313         ServerThreadHandles[ 0 ] = GetCurrentThread();
    00314         ServerThreadClientIds[ 0 ] = GetCurrentThreadId();
    00315         for (i=1; i<NumberOfThreads; i++) {
    00316             fprintf( stderr, "Creating Server Request Thread %ld\n", i+1 );
    00317             rc = NO_ERROR;
    00318             ServerThreadHandles[ i ] = CreateThread( NULL,
    00319                                                      0,
    00320                                                      (LPTHREAD_START_ROUTINE)ServerThread,
    00321                                                      (LPVOID)(i+1),
    00322                                                      CREATE_SUSPENDED,
    00323                                                      &ServerThreadClientIds[ i ]
    00324                                                    );
    00325             if (ServerThreadHandles[ i ] == NULL) {
    00326                 rc = GetLastError();
    00327                 break;
    00328                 }
    00329             }
    00330
    00331         if (rc == NO_ERROR) {
    00332             for (i=1; i<NumberOfThreads; i++) {
    00333                 ResumeThread( ServerThreadHandles[ i ] );
    00334                 }
    00335
    00336             ServerThread( 0 );
    00337             }
    00338         }
    00339
    00340     if (rc != NO_ERROR) {
    00341         fprintf( stderr, "USERVER: Initialization Failed - %u\n", rc );
    00342         }
    00343
    00344     ExitProcess( rc );
    00345     return( rc );
    00346 }