00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "lpcp.h"
00022
00023
00024
00025
00026
00027
NTSTATUS
00028
LpcpCreatePort (
00029 OUT PHANDLE PortHandle,
00030 IN POBJECT_ATTRIBUTES ObjectAttributes,
00031 IN ULONG MaxConnectionInfoLength,
00032 IN ULONG MaxMessageLength,
00033 IN ULONG MaxPoolUsage,
00034 IN BOOLEAN Waitable
00035 );
00036
00037
#ifdef ALLOC_PRAGMA
00038
#pragma alloc_text(PAGE,NtCreatePort)
00039
#pragma alloc_text(PAGE,NtCreateWaitablePort)
00040
#pragma alloc_text(PAGE,LpcpCreatePort)
00041
#endif
00042
00043
00044
NTSTATUS
00045 NtCreatePort (
00046 OUT PHANDLE PortHandle,
00047 IN POBJECT_ATTRIBUTES ObjectAttributes,
00048 IN ULONG MaxConnectionInfoLength,
00049 IN ULONG MaxMessageLength,
00050 IN ULONG MaxPoolUsage
00051 )
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 {
00070
NTSTATUS Status;
00071
00072
PAGED_CODE();
00073
00074
Status =
LpcpCreatePort(
PortHandle,
00075
ObjectAttributes,
00076 MaxConnectionInfoLength,
00077 MaxMessageLength,
00078 MaxPoolUsage,
00079
FALSE );
00080
00081
return Status ;
00082
00083 }
00084
00085
00086
NTSTATUS
00087 NtCreateWaitablePort (
00088 OUT PHANDLE PortHandle,
00089 IN POBJECT_ATTRIBUTES ObjectAttributes,
00090 IN ULONG MaxConnectionInfoLength,
00091 IN ULONG MaxMessageLength,
00092 IN ULONG MaxPoolUsage
00093 )
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 {
00116
NTSTATUS Status ;
00117
00118
PAGED_CODE();
00119
00120
Status =
LpcpCreatePort(
PortHandle,
00121
ObjectAttributes,
00122 MaxConnectionInfoLength,
00123 MaxMessageLength,
00124 MaxPoolUsage,
00125
TRUE );
00126
00127
return Status ;
00128 }
00129
00130
00131
00132
00133
00134
00135
NTSTATUS
00136 LpcpCreatePort (
00137 OUT PHANDLE PortHandle,
00138 IN POBJECT_ATTRIBUTES ObjectAttributes,
00139 IN ULONG MaxConnectionInfoLength,
00140 IN ULONG MaxMessageLength,
00141 IN ULONG MaxPoolUsage,
00142 IN BOOLEAN Waitable
00143 )
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 {
00208
PLPCP_PORT_OBJECT ConnectionPort;
00209 HANDLE
Handle;
00210
KPROCESSOR_MODE PreviousMode;
00211
NTSTATUS Status;
00212 PUNICODE_STRING NamePtr;
00213 UNICODE_STRING CapturedObjectName;
00214
00215
PAGED_CODE();
00216
00217
00218
00219
00220
00221 PreviousMode = KeGetPreviousMode();
00222
RtlInitUnicodeString( &CapturedObjectName,
NULL );
00223
00224
if (PreviousMode !=
KernelMode) {
00225
00226
try {
00227
00228
ProbeForWriteHandle(
PortHandle );
00229
00230
ProbeForRead(
ObjectAttributes,
00231
sizeof( OBJECT_ATTRIBUTES ),
00232
sizeof( ULONG ));
00233
00234 NamePtr =
ObjectAttributes->ObjectName;
00235
00236
if (NamePtr !=
NULL) {
00237
00238 CapturedObjectName =
ProbeAndReadStructure( NamePtr,
00239 UNICODE_STRING );
00240 }
00241
00242 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00243
00244
return( GetExceptionCode() );
00245 }
00246
00247 }
else {
00248
00249
if (
ObjectAttributes->ObjectName !=
NULL) {
00250
00251 CapturedObjectName = *(
ObjectAttributes->ObjectName);
00252 }
00253 }
00254
00255
00256
00257
00258
00259
if (CapturedObjectName.Length == 0) {
00260
00261 CapturedObjectName.Buffer =
NULL;
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
Status =
ObCreateObject( PreviousMode,
00272 (Waitable ?
LpcWaitablePortObjectType
00273 :
LpcPortObjectType),
00274
ObjectAttributes,
00275 PreviousMode,
00276
NULL,
00277 (ULONG)
sizeof(
LPCP_PORT_OBJECT ),
00278 0,
00279 0,
00280 (PVOID *)&ConnectionPort );
00281
00282
if (!
NT_SUCCESS(
Status )) {
00283
00284
return(
Status );
00285 }
00286
00287
00288
00289
00290
00291 RtlZeroMemory( ConnectionPort, (ULONG)
sizeof(
LPCP_PORT_OBJECT ));
00292
00293 ConnectionPort->Length =
sizeof(
LPCP_PORT_OBJECT );
00294 ConnectionPort->ConnectionPort = ConnectionPort;
00295 ConnectionPort->Creator =
PsGetCurrentThread()->Cid;
00296
00297 InitializeListHead( &ConnectionPort->LpcReplyChainHead );
00298
00299 InitializeListHead( &ConnectionPort->LpcDataInfoChainHead );
00300
00301
00302
00303
00304
00305
if (CapturedObjectName.Buffer ==
NULL) {
00306
00307 ConnectionPort->Flags =
UNCONNECTED_COMMUNICATION_PORT;
00308 ConnectionPort->ConnectedPort = ConnectionPort;
00309 ConnectionPort->ServerProcess =
NULL;
00310
00311 }
else {
00312
00313 ConnectionPort->Flags =
SERVER_CONNECTION_PORT;
00314
00315
ObReferenceObject(
PsGetCurrentProcess() );
00316 ConnectionPort->ServerProcess =
PsGetCurrentProcess();
00317 }
00318
00319
if ( Waitable ) {
00320
00321 ConnectionPort->Flags |=
PORT_WAITABLE;
00322 }
00323
00324
00325
00326
00327
00328
Status =
LpcpInitializePortQueue( ConnectionPort );
00329
00330
if (!
NT_SUCCESS(
Status)) {
00331
00332
ObDereferenceObject( ConnectionPort );
00333
00334
return(
Status);
00335 }
00336
00337
00338
00339
00340
00341
00342
if (ConnectionPort->Flags &
PORT_WAITABLE) {
00343
00344
KeInitializeEvent( &ConnectionPort->WaitEvent,
00345 NotificationEvent,
00346
FALSE );
00347 }
00348
00349
00350
00351
00352
00353
00354 ConnectionPort->MaxMessageLength =
LpcpZone.
Zone.
BlockSize -
00355 FIELD_OFFSET(
LPCP_MESSAGE,
Request );
00356
00357 ConnectionPort->MaxConnectionInfoLength = ConnectionPort->MaxMessageLength -
00358
sizeof( PORT_MESSAGE ) -
00359
sizeof(
LPCP_CONNECTION_MESSAGE );
00360
00361
#if DBG
00362
LpcpTrace((
"Created port %ws (%x) - MaxMsgLen == %x MaxConnectInfoLen == %x\n",
00363 CapturedObjectName.Buffer ==
NULL ?
L"** UnNamed **" :
ObjectAttributes->ObjectName->Buffer,
00364 ConnectionPort,
00365 ConnectionPort->MaxMessageLength,
00366 ConnectionPort->MaxConnectionInfoLength ));
00367
#endif
00368
00369
00370
00371
00372
00373
00374
if (ConnectionPort->MaxMessageLength < MaxMessageLength) {
00375
00376
#if DBG
00377
LpcpPrint((
"MaxMessageLength granted is %x but requested %x\n",
00378 ConnectionPort->MaxMessageLength,
00379 MaxMessageLength ));
00380 DbgBreakPoint();
00381
#endif
00382
00383
ObDereferenceObject( ConnectionPort );
00384
00385
return STATUS_INVALID_PARAMETER_4;
00386 }
00387
00388
00389
00390
00391
00392 ConnectionPort->MaxMessageLength = MaxMessageLength;
00393
00394
00395
00396
00397
00398
00399
if (ConnectionPort->MaxConnectionInfoLength < MaxConnectionInfoLength) {
00400
00401
#if DBG
00402
LpcpPrint((
"MaxConnectionInfoLength granted is %x but requested %x\n",
00403 ConnectionPort->MaxConnectionInfoLength,
00404 MaxConnectionInfoLength ));
00405 DbgBreakPoint();
00406
#endif
00407
00408
ObDereferenceObject( ConnectionPort );
00409
00410
return STATUS_INVALID_PARAMETER_3;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
Status =
ObInsertObject( ConnectionPort,
00422
NULL,
00423 PORT_ALL_ACCESS,
00424 0,
00425 (PVOID *)
NULL,
00426 &
Handle );
00427
00428
if (
NT_SUCCESS(
Status )) {
00429
00430
00431
00432
00433
00434
try {
00435
00436 *
PortHandle =
Handle;
00437
00438 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00439
00440
NtClose(
Handle );
00441
00442
Status = GetExceptionCode();
00443 }
00444 }
00445
00446
00447
00448
00449
00450
return Status;
00451 }
00452
00453