00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 }