00098 :
00099
00100
A client process can connect to a server process by name
using the
00101
NtConnectPort service.
00102
00103 The
PortName parameter specifies
the name of
the server port to
00104 connect to. It must correspond to an object name specified on a
00105 call to
NtCreatePort. The service sends a connection request to
the
00106 server thread that
is listening
for them with
the NtListenPort
00107 service. The client thread then blocks until a server thread
00108 receives
the connection request and responds with a call to
the
00109
NtCompleteConnectPort service. The server thread receives
the ID of
00110
the client thread, along with any information passed via
the
00111 ConnectionInformation parameter. The server thread then decides to
00112 either accept or reject
the connection request.
00113
00114 The server communicates
the acceptance or rejection with
the
00115
NtCompleteConnectPort service. The server can pass back data to
the
00116 client about
the acceptance or rejection via
the
00117 ConnectionInformation data block.
00118
00119 If
the server accepts
the connection request, then
the client
00120 receives a communication port object in
the location pointed to by
00121
the PortHandle parameter. This object handle has no name associated
00122 with
it and
is private to
the client process (i.e. it cannot be
00123 inherited by a child process). The client uses
the handle to send
00124 and receive messages to/from
the server process
using the
00125
NtRequestWaitReplyPort service.
00126
00127 If
the ClientView parameter was specified, then
the section handle
00128
is examined. If
it is a valid section handle, then
the portion of
00129
the section described by
the SectionOffset and ViewSize fields will
00130 be mapped into both
the client and server process' address spaces.
00131 The address in client address space will be returned in
the ViewBase
00132 field. The address in
the server address space will be returned in
00133
the ViewRemoteBase field. The actual offset and size used to map
00134
the section will be returned in
the SectionOffset and ViewSize
00135 fields.
00136
00137 If
the server rejects
the connection request, then no communication
00138 port object handle
is returned, and
the return status indicates an
00139 error occurred. The server may optionally
return information in
the
00140 ConnectionInformation data block giving
the reason the connection
00141 requests was rejected.
00142
00143 If
the PortName does not exist, or
the client process does not have
00144 sufficient access rights then
the returned status will indicate that
00145
the port was not found.
00146
00147 Arguments:
00148
00149
PortHandle -
A pointer to a variable that will receive
the client
00150 communication port object handle value.
00151
00152
PortName -
A pointer to a port name string. The form of
the name
00153
is [\name...\name]\port_name.
00154
00155
SecurityQos -
A pointer to security quality of service information
00156 to be applied to
the server on
the client's behalf.
00157
00158 ClientView - An optional pointer to a structure that specifies
the
00159 section that all client threads will use to send messages to
the
00160 server.
00161
00162 ClientView Structure
00163
00164 ULONG Length - Specifies
the size of
this data structure in
00165 bytes.
00166
00167 HANDLE SectionHandle - Specifies an open handle to a section
00168 object.
00169
00170 ULONG SectionOffset - Specifies a field that will receive
the
00171 actual offset, in bytes, from
the start of
the section. The
00172 initial value of
this parameter specifies
the byte offset
00173 within
the section that
the client's view
is based. The
00174 value
is rounded down to
the next host page size boundary.
00175
00176 ULONG ViewSize - Specifies a field that will receive
the
00177 actual size, in bytes, of
the view. If
the value of
this
00178 parameter
is zero, then
the client's view of
the section
00179 will be mapped starting at
the specified section offset and
00180 continuing to
the end of
the section. Otherwise,
the
00181 initial value of
this parameter specifies
the size, in
00182 bytes, of
the client's view and
is rounded up to
the next
00183 host page size boundary.
00184
00185 PVOID ViewBase - Specifies a field that will receive
the base
00186 address of
the section in
the client's address space.
00187
00188 PVOID ViewRemoteBase - Specifies a field that will receive
00189
the base address of
the client's section in
the server's
00190 address space. Used to generate pointers that are
00191 meaningful to
the server.
00192
00193 RequiredServerSid - Optionally specifies
the SID that we expect
the
00194 server side of
the port to possess. If not specified then we'll
00195 connect to any server SID.
00196
00197 ServerView - An optional pointer to a structure that will receive
00198 information about
the server process' view in
the client's
00199 address space. The client process can use
this information
00200 to validate pointers
it receives from
the server process.
00201
00202 ServerView Structure
00203
00204 ULONG Length - Specifies
the size of
this data structure in
00205 bytes.
00206
00207 PVOID ViewBase - Specifies a field that will receive
the base
00208 address of
the server's section in
the client's address
00209 space.
00210
00211 ULONG ViewSize - Specifies a field that will receive
the
00212 size, in bytes, of
the server's view in
the client's address
00213 space. If
this field
is zero, then server has no view in
00214
the client's address space.
00215
00216 MaxMessageLength - An optional pointer to a variable that will
00217 receive maximum length of messages that can be sent to
the
00218 server. The value of
this parameter will not exceed
00219 MAX_PORTMSG_LENGTH bytes.
00220
00221 ConnectionInformation - An optional pointer to uninterpreted data.
00222 This data
is intended
for clients to pass package, version and
00223 protocol identification information to
the server to allow
the
00224 server to determine
if it can satisify
the client before
00225 accepting
the connection. Upon
return to
the client,
the
00226 ConnectionInformation data block contains any information passed
00227 back from
the server by its call to
the NtCompleteConnectPort
00228 service. The output data overwrites
the input data.
00229
00230 ConnectionInformationLength - Pointer to
the length of
the
00231 ConnectionInformation data block. The output value
is the
00232 length of
the data stored in
the ConnectionInformation data
00233 block by
the server's call to
the NtCompleteConnectPort
00234 service. This parameter
is OPTIONAL
only if the
00235 ConnectionInformation parameter
is null, otherwise
it is
00236 required.
00237
00238 Return Value:
00239
00240
NTSTATUS - An appropriate status value.
00241
00242 --*/
00243
00244 {
00245
PLPCP_PORT_OBJECT ConnectionPort;
00246
PLPCP_PORT_OBJECT ClientPort;
00247 HANDLE
Handle;
00248
KPROCESSOR_MODE PreviousMode;
00249
NTSTATUS Status;
00250 ULONG ConnectionInfoLength;
00251 PVOID SectionToMap;
00252
PLPCP_MESSAGE Msg;
00253
PLPCP_CONNECTION_MESSAGE ConnectMsg;
00254
PETHREAD CurrentThread =
PsGetCurrentThread();
00255 LARGE_INTEGER SectionOffset;
00256 PORT_VIEW CapturedClientView;
00257 SECURITY_QUALITY_OF_SERVICE CapturedQos;
00258 PSID CapturedRequiredServerSid;
00259
00260
PAGED_CODE();
00261
00262
00263
00264
00265
00266
00267 PreviousMode = KeGetPreviousMode();
00268 ConnectionInfoLength = 0;
00269
00270
if (PreviousMode !=
KernelMode) {
00271
00272
try {
00273
00274
ProbeForWriteHandle( PortHandle );
00275
00276
if (ARGUMENT_PRESENT( ClientView )) {
00277
00278 CapturedClientView =
ProbeAndReadStructure( ClientView, PORT_VIEW );
00279
00280
if (CapturedClientView.Length !=
sizeof( *ClientView )) {
00281
00282
return( STATUS_INVALID_PARAMETER );
00283 }
00284
00285
ProbeForWrite( ClientView,
00286
sizeof( *ClientView ),
00287
sizeof( ULONG ));
00288 }
00289
00290
if (ARGUMENT_PRESENT( ServerView )) {
00291
00292
if (
ProbeAndReadUlong( &ServerView->Length ) !=
sizeof( *ServerView )) {
00293
00294
return( STATUS_INVALID_PARAMETER );
00295 }
00296
00297
ProbeForWrite( ServerView,
00298
sizeof( *ServerView ),
00299
sizeof( ULONG ));
00300 }
00301
00302
if (ARGUMENT_PRESENT( MaxMessageLength )) {
00303
00304
ProbeForWriteUlong( MaxMessageLength );
00305 }
00306
00307
if (ARGUMENT_PRESENT( ConnectionInformationLength )) {
00308
00309 ConnectionInfoLength =
ProbeAndReadUlong( ConnectionInformationLength );
00310
ProbeForWriteUlong( ConnectionInformationLength );
00311 }
00312
00313
if (ARGUMENT_PRESENT( ConnectionInformation )) {
00314
00315
ProbeForWrite( ConnectionInformation,
00316 ConnectionInfoLength,
00317
sizeof( UCHAR ));
00318 }
00319
00320 CapturedQos =
ProbeAndReadStructure( SecurityQos, SECURITY_QUALITY_OF_SERVICE );
00321
00322 CapturedRequiredServerSid = RequiredServerSid;
00323
00324
if (ARGUMENT_PRESENT( RequiredServerSid )) {
00325
00326
Status =
SeCaptureSid( RequiredServerSid,
00327 PreviousMode,
00328 NULL,
00329 0,
00330 PagedPool,
00331 TRUE,
00332 &CapturedRequiredServerSid );
00333
00334
if (!
NT_SUCCESS(Status)) {
00335
00336
return Status;
00337 }
00338 }
00339
00340 } except( EXCEPTION_EXECUTE_HANDLER ) {
00341
00342
return( GetExceptionCode() );
00343 }
00344
00345
00346
00347
00348
00349 }
else {
00350
00351
if (ARGUMENT_PRESENT( ClientView )) {
00352
00353
if (ClientView->Length !=
sizeof( *ClientView )) {
00354
00355
return( STATUS_INVALID_PARAMETER );
00356 }
00357
00358 CapturedClientView = *ClientView;
00359 }
00360
00361
if (ARGUMENT_PRESENT( ServerView )) {
00362
00363
if (ServerView->Length !=
sizeof( *ServerView )) {
00364
00365
return( STATUS_INVALID_PARAMETER );
00366 }
00367 }
00368
00369
if (ARGUMENT_PRESENT( ConnectionInformationLength )) {
00370
00371 ConnectionInfoLength = *ConnectionInformationLength;
00372 }
00373
00374 CapturedQos = *
SecurityQos;
00375 CapturedRequiredServerSid = RequiredServerSid;
00376 }
00377
00378
00379
00380
00381
00382
00383
Status =
ObReferenceObjectByName( PortName,
00384 0,
00385 NULL,
00386 PORT_CONNECT,
00387 LpcPortObjectType,
00388 PreviousMode,
00389 NULL,
00390 (PVOID *)&ConnectionPort );
00391
00392
00393
00394
00395
00396
00397
if (
Status == STATUS_OBJECT_TYPE_MISMATCH ) {
00398
00399
Status =
ObReferenceObjectByName( PortName,
00400 0,
00401 NULL,
00402 PORT_CONNECT,
00403 LpcWaitablePortObjectType,
00404 PreviousMode,
00405 NULL,
00406 (PVOID *)&ConnectionPort );
00407 }
00408
00409
00410
00411
00412
00413
00414
if (!
NT_SUCCESS( Status )) {
00415
00416
if (CapturedRequiredServerSid != RequiredServerSid) {
00417
00418
SeReleaseSid( CapturedRequiredServerSid, PreviousMode, TRUE);
00419 }
00420
00421
return Status;
00422 }
00423
00424
LpcpTrace((
"Connecting to port %wZ\n", PortName ));
00425
00426
00427
00428
00429
00430
if ((ConnectionPort->
Flags &
PORT_TYPE) !=
SERVER_CONNECTION_PORT) {
00431
00432
ObDereferenceObject( ConnectionPort );
00433
00434
if (CapturedRequiredServerSid != RequiredServerSid) {
00435
00436
SeReleaseSid( CapturedRequiredServerSid, PreviousMode, TRUE);
00437 }
00438
00439
return STATUS_INVALID_PORT_HANDLE;
00440 }
00441
00442
00443
00444
00445
00446
00447
if (ARGUMENT_PRESENT( RequiredServerSid )) {
00448
00449 PTOKEN_USER TokenInfo;
00450
00451
if (ConnectionPort->
ServerProcess !=
NULL) {
00452
00453 PACCESS_TOKEN
Token ;
00454
00455
Token =
PsReferencePrimaryToken( ConnectionPort->
ServerProcess );
00456
00457
00458
Status =
SeQueryInformationToken( Token,
00459 TokenUser,
00460 &TokenInfo );
00461
00462
PsDereferencePrimaryToken( Token );
00463
00464
if (
NT_SUCCESS( Status )) {
00465
00466
if (!
RtlEqualSid( CapturedRequiredServerSid, TokenInfo->User.Sid )) {
00467
00468
Status = STATUS_SERVER_SID_MISMATCH;
00469 }
00470
00471
ExFreePool( TokenInfo );
00472 }
00473
00474 }
else {
00475
00476
Status = STATUS_SERVER_SID_MISMATCH;
00477 }
00478
00479
00480
00481
00482
00483
00484
if (CapturedRequiredServerSid != RequiredServerSid) {
00485
00486
SeReleaseSid( CapturedRequiredServerSid, PreviousMode, TRUE);
00487 }
00488
00489
00490
00491
00492
00493
00494
if (!
NT_SUCCESS( Status )) {
00495
00496
ObDereferenceObject( ConnectionPort );
00497
00498
return Status;
00499 }
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509
Status =
ObCreateObject( PreviousMode,
00510 LpcPortObjectType,
00511 NULL,
00512 PreviousMode,
00513 NULL,
00514
sizeof(
LPCP_PORT_OBJECT ),
00515 0,
00516 0,
00517 (PVOID *)&ClientPort );
00518
00519
if (!
NT_SUCCESS( Status )) {
00520
00521
ObDereferenceObject( ConnectionPort );
00522
00523
return Status;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 RtlZeroMemory( ClientPort,
sizeof( LPCP_PORT_OBJECT ));
00540
00541 ClientPort->
Length =
sizeof(
LPCP_PORT_OBJECT );
00542 ClientPort->
Flags =
CLIENT_COMMUNICATION_PORT;
00543 ClientPort->
ConnectionPort = ConnectionPort;
00544 ClientPort->
MaxMessageLength = ConnectionPort->
MaxMessageLength;
00545 ClientPort->
SecurityQos = CapturedQos;
00546
00547 InitializeListHead( &ClientPort->
LpcReplyChainHead );
00548 InitializeListHead( &ClientPort->
LpcDataInfoChainHead );
00549
00550
00551
00552
00553
00554
00555
if (CapturedQos.ContextTrackingMode == SECURITY_DYNAMIC_TRACKING) {
00556
00557 ClientPort->
Flags |=
PORT_DYNAMIC_SECURITY;
00558
00559 }
else {
00560
00561
Status =
SeCreateClientSecurity( CurrentThread,
00562 &CapturedQos,
00563 FALSE,
00564 &ClientPort->
StaticSecurity );
00565
00566
if (!
NT_SUCCESS( Status )) {
00567
00568
ObDereferenceObject( ClientPort );
00569
00570
return Status;
00571 }
00572 }
00573
00574
00575
00576
00577
00578
00579
Status =
LpcpInitializePortQueue( ClientPort );
00580
00581
if (!
NT_SUCCESS( Status )) {
00582
00583
ObDereferenceObject( ClientPort );
00584
00585
return Status;
00586 }
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
if (ARGUMENT_PRESENT( ClientView )) {
00599
00600
Status =
ObReferenceObjectByHandle( CapturedClientView.SectionHandle,
00601 SECTION_MAP_READ |
00602 SECTION_MAP_WRITE,
00603 MmSectionObjectType,
00604 PreviousMode,
00605 (PVOID *)&SectionToMap,
00606 NULL );
00607
00608
if (!
NT_SUCCESS( Status )) {
00609
00610
ObDereferenceObject( ClientPort );
00611
00612
return Status;
00613 }
00614
00615 SectionOffset.LowPart = CapturedClientView.SectionOffset,
00616 SectionOffset.HighPart = 0;
00617
00618
00619
00620
00621
00622
00623
Status =
MmMapViewOfSection( SectionToMap,
00624
PsGetCurrentProcess(),
00625 &ClientPort->
ClientSectionBase,
00626 0,
00627 0,
00628 &SectionOffset,
00629 &CapturedClientView.ViewSize,
00630 ViewUnmap,
00631 0,
00632 PAGE_READWRITE );
00633
00634 CapturedClientView.SectionOffset = SectionOffset.LowPart;
00635
00636
if (!
NT_SUCCESS( Status )) {
00637
00638
ObDereferenceObject( SectionToMap );
00639
ObDereferenceObject( ClientPort );
00640
00641
return Status;
00642 }
00643
00644 CapturedClientView.ViewBase = ClientPort->
ClientSectionBase;
00645
00646 }
else {
00647
00648 SectionToMap =
NULL;
00649 }
00650
00651
00652
00653
00654
00655
00656
if (ConnectionInfoLength > ConnectionPort->
MaxConnectionInfoLength) {
00657
00658 ConnectionInfoLength = ConnectionPort->
MaxConnectionInfoLength;
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
LpcpAcquireLpcpLock();
00671
00672 Msg =
LpcpAllocateFromPortZone(
sizeof( *Msg ) +
00673
sizeof( *ConnectMsg ) +
00674 ConnectionInfoLength );
00675
00676
LpcpReleaseLpcpLock();
00677
00678
00679
00680
00681
00682
if (Msg ==
NULL) {
00683
00684
if (SectionToMap !=
NULL) {
00685
00686
ObDereferenceObject( SectionToMap );
00687 }
00688
00689
ObDereferenceObject( ClientPort );
00690
00691
return STATUS_NO_MEMORY;
00692 }
00693
00694
00695
00696
00697
00698
00699
00700 ConnectMsg = (
PLPCP_CONNECTION_MESSAGE)(Msg + 1);
00701
00702
00703
00704
00705
00706 Msg->Request.ClientId = CurrentThread->
Cid;
00707
00708
00709
00710
00711
00712
00713
if (ARGUMENT_PRESENT( ClientView )) {
00714
00715 Msg->Request.ClientViewSize = CapturedClientView.ViewSize;
00716
00717 RtlMoveMemory( &ConnectMsg->
ClientView,
00718 &CapturedClientView,
00719
sizeof( CapturedClientView ));
00720
00721 RtlZeroMemory( &ConnectMsg->
ServerView,
sizeof( ConnectMsg->
ServerView ));
00722
00723 }
else {
00724
00725 Msg->Request.ClientViewSize = 0;
00726 RtlZeroMemory( ConnectMsg,
sizeof( *ConnectMsg ));
00727 }
00728
00729 ConnectMsg->
ClientPort =
NULL;
00730 ConnectMsg->
SectionToMap = SectionToMap;
00731
00732
00733
00734
00735
00736
00737
00738 Msg->Request.u1.s1.DataLength = (CSHORT)(
sizeof( *ConnectMsg ) +
00739 ConnectionInfoLength);
00740
00741
00742
00743
00744
00745
00746
00747 Msg->Request.u1.s1.TotalLength = (CSHORT)(
sizeof( *Msg ) +
00748 Msg->Request.u1.s1.DataLength);
00749
00750
00751
00752
00753
00754 Msg->Request.u2.s2.Type = LPC_CONNECTION_REQUEST;
00755
00756
00757
00758
00759
00760
00761
if (ARGUMENT_PRESENT( ConnectionInformation )) {
00762
00763
try {
00764
00765 RtlMoveMemory( ConnectMsg + 1,
00766 ConnectionInformation,
00767 ConnectionInfoLength );
00768
00769 } except( EXCEPTION_EXECUTE_HANDLER ) {
00770
00771
00772
00773
00774
00775
00776
LpcpFreeToPortZone( Msg, FALSE );
00777
00778
if (SectionToMap !=
NULL) {
00779
00780
ObDereferenceObject( SectionToMap );
00781 }
00782
00783
ObDereferenceObject( ClientPort );
00784
00785
return GetExceptionCode();
00786 }
00787 }
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
LpcpAcquireLpcpLock();
00801
00802
00803
00804
00805
00806
00807
if (ConnectionPort->
Flags &
PORT_NAME_DELETED) {
00808
00809
Status = STATUS_OBJECT_NAME_NOT_FOUND;
00810
00811 }
else {
00812
00813
Status = STATUS_SUCCESS;
00814
00815
LpcpTrace((
"Send Connect Msg %lx to Port %wZ (%lx)\n", Msg, PortName, ConnectionPort ));
00816
00817
00818
00819
00820
00821
00822 Msg->RepliedToThread =
NULL;
00823 Msg->Request.MessageId =
LpcpGenerateMessageId();
00824
00825 CurrentThread->
LpcReplyMessageId = Msg->Request.MessageId;
00826
00827 InsertTailList( &ConnectionPort->
MsgQueue.
ReceiveHead, &Msg->Entry );
00828 InsertTailList( &ConnectionPort->
LpcReplyChainHead, &CurrentThread->
LpcReplyChain );
00829
00830 CurrentThread->
LpcReplyMessage = Msg;
00831
00832
00833
00834
00835
00836
00837
00838
ObReferenceObject( ClientPort );
00839
00840 ConnectMsg->
ClientPort = ClientPort;
00841 }
00842
00843
LpcpReleaseLpcpLock();
00844
00845
00846
00847
00848
00849
00850
00851
if (
NT_SUCCESS( Status )) {
00852
00853
00854
00855
00856
00857
00858
if ( ConnectionPort->
Flags &
PORT_WAITABLE ) {
00859
00860
KeSetEvent( &ConnectionPort->
WaitEvent, 1, FALSE );
00861 }
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
KeReleaseSemaphore( ConnectionPort->
MsgQueue.
Semaphore,
00872 1,
00873 1,
00874 FALSE );
00875
00876
Status =
KeWaitForSingleObject( &CurrentThread->
LpcReplySemaphore,
00877 Executive,
00878 PreviousMode,
00879 FALSE,
00880 NULL );
00881 }
00882
00883
if (
Status == STATUS_USER_APC) {
00884
00885
00886
00887
00888
00889
if (
KeReadStateSemaphore( &CurrentThread->
LpcReplySemaphore )) {
00890
00891
KeWaitForSingleObject( &CurrentThread->
LpcReplySemaphore,
00892 WrExecutive,
00893 KernelMode,
00894 FALSE,
00895 NULL );
00896
00897
Status = STATUS_SUCCESS;
00898 }
00899 }
00900
00901
00902
00903
00904
00905
00906
if (
Status == STATUS_SUCCESS) {
00907
00908 SectionToMap =
LpcpFreeConMsg( &Msg, &ConnectMsg, CurrentThread );
00909
00910
00911
00912
00913
00914
if (Msg !=
NULL) {
00915
00916
00917
00918
00919
00920
00921
00922
if ((Msg->Request.u1.s1.DataLength -
sizeof( *ConnectMsg )) < ConnectionInfoLength) {
00923
00924 ConnectionInfoLength = Msg->Request.u1.s1.DataLength -
sizeof( *ConnectMsg );
00925 }
00926
00927
if (ARGUMENT_PRESENT( ConnectionInformation )) {
00928
00929
try {
00930
00931
if (ARGUMENT_PRESENT( ConnectionInformationLength )) {
00932
00933 *ConnectionInformationLength = ConnectionInfoLength;
00934 }
00935
00936 RtlMoveMemory( ConnectionInformation,
00937 ConnectMsg + 1,
00938 ConnectionInfoLength );
00939
00940 } except( EXCEPTION_EXECUTE_HANDLER ) {
00941
00942
Status = GetExceptionCode();
00943 }
00944 }
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
if (ClientPort->
ConnectedPort !=
NULL) {
00956
00957 ULONG CapturedMaxMessageLength;
00958
00959
00960
00961
00962
00963
00964
00965 CapturedMaxMessageLength = ConnectionPort->
MaxMessageLength;
00966
00967
00968
00969
00970
00971
Status =
ObInsertObject( ClientPort,
00972 NULL,
00973 PORT_ALL_ACCESS,
00974 0,
00975 (PVOID *)NULL,
00976 &Handle );
00977
00978
if (
NT_SUCCESS( Status )) {
00979
00980
00981
00982
00983
00984
00985
00986
try {
00987
00988 *
PortHandle =
Handle;
00989
00990
if (ARGUMENT_PRESENT( MaxMessageLength )) {
00991
00992 *MaxMessageLength = CapturedMaxMessageLength;
00993 }
00994
00995
if (ARGUMENT_PRESENT( ClientView )) {
00996
00997 RtlMoveMemory( ClientView,
00998 &ConnectMsg->
ClientView,
00999
sizeof( *ClientView ));
01000 }
01001
01002
if (ARGUMENT_PRESENT( ServerView )) {
01003
01004 RtlMoveMemory( ServerView,
01005 &ConnectMsg->
ServerView,
01006
sizeof( *ServerView ));
01007 }
01008
01009 } except( EXCEPTION_EXECUTE_HANDLER ) {
01010
01011
Status = GetExceptionCode();
01012
NtClose( Handle );
01013 }
01014 }
01015
01016 }
else {
01017
01018
01019
01020
01021
01022
01023
LpcpTrace((
"Connection request refused.\n" ));
01024
01025
if ( SectionToMap !=
NULL ) {
01026
01027
ObDereferenceObject( SectionToMap );
01028 }
01029
01030
if (ConnectionPort->
Flags &
PORT_NAME_DELETED) {
01031
01032
Status = STATUS_OBJECT_NAME_NOT_FOUND;
01033
01034 }
else {
01035
01036
Status = STATUS_PORT_CONNECTION_REFUSED;
01037 }
01038
01039
ObDereferenceObject( ClientPort );
01040 }
01041
01042
01043
01044
01045
01046
LpcpFreeToPortZone( Msg, FALSE );
01047
01048 }
else {
01049
01050
01051
01052
01053
01054
01055
if (SectionToMap !=
NULL) {
01056
01057
ObDereferenceObject( SectionToMap );
01058 }
01059
01060
ObDereferenceObject( ClientPort );
01061
01062
Status = STATUS_PORT_CONNECTION_REFUSED;
01063 }
01064
01065 }
else {
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077 SectionToMap =
LpcpFreeConMsg( &Msg, &ConnectMsg, CurrentThread );
01078
01079
01080
01081
01082
01083
01084
01085
if (
KeReadStateSemaphore( &CurrentThread->
LpcReplySemaphore )) {
01086
01087
KeWaitForSingleObject( &CurrentThread->
LpcReplySemaphore,
01088 WrExecutive,
01089 KernelMode,
01090 FALSE,
01091 NULL );
01092 }
01093
01094
if (Msg !=
NULL) {
01095
01096
LpcpFreeToPortZone( Msg, FALSE );
01097 }
01098
01099
01100
01101
01102
01103
01104
if ( SectionToMap !=
NULL ) {
01105
01106
ObDereferenceObject( SectionToMap );
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
ObDereferenceObject( ClientPort );
01116 }
01117
01118
01119
01120
01121
01122
return Status;
01123 }