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
#ifdef ALLOC_PRAGMA
00024
#pragma alloc_text(PAGE,NtRequestPort)
00025
#pragma alloc_text(PAGE,NtRequestWaitReplyPort)
00026
#pragma alloc_text(PAGE,LpcRequestPort)
00027
#pragma alloc_text(PAGE,LpcRequestWaitReplyPort)
00028
#endif
00029
00030
00031
NTSTATUS
00032 NtRequestPort (
00033 IN HANDLE PortHandle,
00034 IN PPORT_MESSAGE RequestMessage
00035 )
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 {
00065
PLPCP_PORT_OBJECT PortObject;
00066
PLPCP_PORT_OBJECT QueuePort;
00067 PORT_MESSAGE CapturedRequestMessage;
00068 ULONG MsgType;
00069
KPROCESSOR_MODE PreviousMode;
00070
NTSTATUS Status;
00071
PLPCP_MESSAGE Msg;
00072
00073
PAGED_CODE();
00074
00075
00076
00077
00078
00079 PreviousMode = KeGetPreviousMode();
00080
00081
if (PreviousMode !=
KernelMode) {
00082
00083
try {
00084
00085
ProbeForRead(
RequestMessage,
00086
sizeof( *
RequestMessage ),
00087
sizeof( ULONG ));
00088
00089 CapturedRequestMessage = *
RequestMessage;
00090 CapturedRequestMessage.u2.s2.Type &= ~LPC_KERNELMODE_MESSAGE;
00091
00092 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00093
00094
return GetExceptionCode();
00095 }
00096
00097
if (CapturedRequestMessage.u2.s2.Type != 0) {
00098
00099
return STATUS_INVALID_PARAMETER;
00100 }
00101
00102 }
else {
00103
00104
00105
00106
00107
00108 CapturedRequestMessage = *
RequestMessage;
00109
00110
if ((CapturedRequestMessage.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE) != 0) {
00111
00112
return STATUS_INVALID_PARAMETER;
00113 }
00114 }
00115
00116
00117
00118
00119
00120
if (CapturedRequestMessage.u2.s2.DataInfoOffset != 0) {
00121
00122
return STATUS_INVALID_PARAMETER;
00123 }
00124
00125
00126
00127
00128
00129
if ((((CLONG)CapturedRequestMessage.u1.s1.DataLength) +
sizeof( PORT_MESSAGE )) >
00130 ((CLONG)CapturedRequestMessage.u1.s1.TotalLength)) {
00131
00132
return STATUS_INVALID_PARAMETER;
00133 }
00134
00135
00136
00137
00138
00139
00140
Status =
LpcpReferencePortObject(
PortHandle,
00141 0,
00142 PreviousMode,
00143 &PortObject );
00144
00145
if (!
NT_SUCCESS(
Status )) {
00146
00147
return Status;
00148 }
00149
00150
00151
00152
00153
00154
if (((ULONG)CapturedRequestMessage.u1.s1.TotalLength > PortObject->
MaxMessageLength) ||
00155 ((ULONG)CapturedRequestMessage.u1.s1.TotalLength <= (ULONG)CapturedRequestMessage.u1.s1.DataLength)) {
00156
00157
ObDereferenceObject( PortObject );
00158
00159
return STATUS_PORT_MESSAGE_TOO_LONG;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
LpcpAcquireLpcpLock();
00173
00174 Msg = (
PLPCP_MESSAGE)
LpcpAllocateFromPortZone( CapturedRequestMessage.u1.s1.TotalLength );
00175
00176
LpcpReleaseLpcpLock();
00177
00178
if (Msg ==
NULL) {
00179
00180
ObDereferenceObject( PortObject );
00181
00182
return STATUS_NO_MEMORY;
00183 }
00184
00185 Msg->
RepliedToThread =
NULL;
00186 Msg->
PortContext =
NULL;
00187 MsgType = CapturedRequestMessage.u2.s2.Type | LPC_DATAGRAM;
00188
00189
try {
00190
00191
LpcpMoveMessage( &Msg->
Request,
00192 &CapturedRequestMessage,
00193 (
RequestMessage + 1),
00194 MsgType,
00195 &
PsGetCurrentThread()->Cid );
00196
00197 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00198
00199
Status = GetExceptionCode();
00200 }
00201
00202
if (!
NT_SUCCESS(
Status )) {
00203
00204
LpcpFreeToPortZone( Msg,
FALSE );
00205
00206
ObDereferenceObject( PortObject );
00207
00208
return Status;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
KeEnterCriticalRegion();
00224
00225
LpcpAcquireLpcpLock();
00226
00227
00228
00229
00230
00231
00232
if ((PortObject->
Flags &
PORT_TYPE) !=
SERVER_CONNECTION_PORT) {
00233
00234
00235
00236
00237
00238
00239
00240 QueuePort = PortObject->
ConnectedPort;
00241
00242
00243
00244
00245
00246
if ( (QueuePort !=
NULL) &&
00247 (QueuePort->
Flags &
PORT_DELETED) ){
00248
00249
00250
00251 QueuePort =
NULL;
00252 }
00253
00254
if ( QueuePort !=
NULL) {
00255
00256
00257
00258
00259
00260
00261
if ((PortObject->
Flags &
PORT_TYPE) ==
CLIENT_COMMUNICATION_PORT) {
00262
00263 Msg->
PortContext = QueuePort->
PortContext;
00264 QueuePort = PortObject->
ConnectionPort;
00265
00266
00267
00268
00269
00270
00271 }
else if ((PortObject->
Flags &
PORT_TYPE) !=
SERVER_COMMUNICATION_PORT) {
00272
00273 QueuePort = PortObject->
ConnectionPort;
00274 }
00275 }
00276
00277 }
else {
00278
00279
00280
00281
00282
00283
00284 QueuePort = PortObject;
00285 }
00286
00287
00288
00289
00290
00291
00292
if (QueuePort !=
NULL) {
00293
00294
00295
00296
00297
00298
ObReferenceObject( QueuePort );
00299
00300
00301
00302
00303
00304 Msg->
Request.MessageId =
LpcpGenerateMessageId();
00305 Msg->
Request.CallbackId = 0;
00306
00307
PsGetCurrentThread()->LpcReplyMessageId = 0;
00308
00309 InsertTailList( &QueuePort->
MsgQueue.
ReceiveHead, &Msg->
Entry );
00310
00311
LpcpTrace((
"%s Send DataGram (%s) Msg %lx [%08x %08x %08x %08x] to Port %lx (%s)\n",
00312
PsGetCurrentProcess()->ImageFileName,
00313 LpcpMessageTypeName[ Msg->
Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE ],
00314 Msg,
00315 *((PULONG)(Msg+1)+0),
00316 *((PULONG)(Msg+1)+1),
00317 *((PULONG)(Msg+1)+2),
00318 *((PULONG)(Msg+1)+3),
00319 QueuePort,
00320
LpcpGetCreatorName( QueuePort )));
00321
00322
00323
00324
00325
00326
00327
00328
LpcpReleaseLpcpLock();
00329
00330
KeReleaseSemaphore( QueuePort->
MsgQueue.
Semaphore,
00331
LPC_RELEASE_WAIT_INCREMENT,
00332 1
L,
00333
FALSE );
00334
00335
00336
00337
00338
00339
00340
if ( QueuePort->
Flags &
PORT_WAITABLE ) {
00341
00342
KeSetEvent( &QueuePort->
WaitEvent,
00343
LPC_RELEASE_WAIT_INCREMENT,
00344
FALSE );
00345 }
00346
00347
00348
00349
00350
00351
KeLeaveCriticalRegion();
00352
00353
ObDereferenceObject( QueuePort );
00354
ObDereferenceObject( PortObject );
00355
00356
00357
00358
00359
00360
00361
return Status;
00362
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
LpcpFreeToPortZone( Msg,
TRUE );
00375
00376
00377
00378
00379
00380
LpcpReleaseLpcpLock();
00381
00382
ObDereferenceObject( PortObject );
00383
00384
KeLeaveCriticalRegion();
00385
00386
00387
00388
00389
00390
return STATUS_PORT_DISCONNECTED;
00391 }
00392
00393
00394
NTSTATUS
00395 NtRequestWaitReplyPort (
00396 IN HANDLE PortHandle,
00397 IN PPORT_MESSAGE RequestMessage,
00398 OUT PPORT_MESSAGE ReplyMessage
00399 )
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 {
00445
PLPCP_PORT_OBJECT PortObject;
00446
PLPCP_PORT_OBJECT QueuePort;
00447
PLPCP_PORT_OBJECT RundownPort;
00448 PORT_MESSAGE CapturedRequestMessage;
00449 ULONG MsgType;
00450
PKSEMAPHORE ReleaseSemaphore;
00451
KPROCESSOR_MODE PreviousMode;
00452
NTSTATUS Status;
00453
PLPCP_MESSAGE Msg;
00454
PETHREAD CurrentThread;
00455
PETHREAD WakeupThread;
00456 BOOLEAN CallbackRequest;
00457 PORT_DATA_INFORMATION CapturedDataInfo;
00458
00459
PAGED_CODE();
00460
00461
00462
00463
00464
00465 CurrentThread =
PsGetCurrentThread();
00466
00467
if (CurrentThread->
LpcExitThreadCalled) {
00468
00469
return STATUS_THREAD_IS_TERMINATING;
00470 }
00471
00472
00473
00474
00475
00476 PreviousMode = KeGetPreviousMode();
00477
00478
if (PreviousMode !=
KernelMode) {
00479
00480
try {
00481
00482
ProbeForRead(
RequestMessage,
00483
sizeof( *
RequestMessage ),
00484
sizeof( ULONG ));
00485
00486 CapturedRequestMessage = *
RequestMessage;
00487 CapturedRequestMessage.u2.s2.Type &= ~LPC_KERNELMODE_MESSAGE;
00488
00489
ProbeForWrite(
ReplyMessage,
00490
sizeof( *
ReplyMessage ),
00491
sizeof( ULONG ));
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
if (CapturedRequestMessage.u2.s2.DataInfoOffset != 0) {
00510
00511 PPORT_DATA_INFORMATION DataInfo;
00512 PPORT_DATA_ENTRY DataEntry;
00513
00514
if (((ULONG)CapturedRequestMessage.u2.s2.DataInfoOffset) > (CapturedRequestMessage.u1.s1.TotalLength -
sizeof(PORT_DATA_INFORMATION))) {
00515
00516
return STATUS_INVALID_PARAMETER;
00517 }
00518
00519
if ((ULONG)CapturedRequestMessage.u2.s2.DataInfoOffset <
sizeof(PORT_MESSAGE)) {
00520
00521
return STATUS_INVALID_PARAMETER;
00522 }
00523
00524 DataInfo = (PPORT_DATA_INFORMATION)(((PUCHAR)
RequestMessage) + CapturedRequestMessage.u2.s2.DataInfoOffset);
00525
00526
ProbeForRead( DataInfo,
00527
sizeof( *DataInfo ),
00528
sizeof( ULONG ));
00529
00530 CapturedDataInfo = *DataInfo;
00531
00532 DataEntry = &(DataInfo->DataEntries[CapturedDataInfo.CountDataEntries]);
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
if (((PUCHAR)DataEntry < (PUCHAR)DataInfo +
sizeof(CapturedDataInfo.CountDataEntries) + CapturedDataInfo.CountDataEntries) ||
00553 ((((PUCHAR)
RequestMessage) + CapturedRequestMessage.u1.s1.TotalLength) < (PUCHAR)DataEntry)) {
00554
00555
return STATUS_INVALID_PARAMETER;
00556 }
00557 }
00558
00559 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00560
00561
Status = GetExceptionCode();
00562
00563
return Status;
00564 }
00565
00566 }
else {
00567
00568 CapturedRequestMessage = *
RequestMessage;
00569
00570
if (CapturedRequestMessage.u2.s2.DataInfoOffset != 0) {
00571
00572 PPORT_DATA_INFORMATION DataInfo;
00573
00574 DataInfo = (PPORT_DATA_INFORMATION)(((PUCHAR)
RequestMessage) + CapturedRequestMessage.u2.s2.DataInfoOffset);
00575
00576 CapturedDataInfo = *DataInfo;
00577 }
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
if ((CapturedRequestMessage.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE) == LPC_REQUEST) {
00589
00590 CallbackRequest =
TRUE;
00591
00592 }
else if ((CapturedRequestMessage.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE) != 0) {
00593
00594
return STATUS_INVALID_PARAMETER;
00595
00596 }
else {
00597
00598 CapturedRequestMessage.u2.s2.Type |= LPC_REQUEST;
00599 CallbackRequest =
FALSE;
00600 }
00601
00602
00603
00604
00605
00606
if ((((CLONG)CapturedRequestMessage.u1.s1.DataLength) +
sizeof( PORT_MESSAGE )) >
00607 ((CLONG)CapturedRequestMessage.u1.s1.TotalLength)) {
00608
00609
return STATUS_INVALID_PARAMETER;
00610 }
00611
00612
00613
00614
00615
00616
00617
Status =
LpcpReferencePortObject(
PortHandle,
00618 0,
00619 PreviousMode,
00620 &PortObject );
00621
00622
if (!
NT_SUCCESS(
Status )) {
00623
00624
return Status;
00625 }
00626
00627
00628
00629
00630
00631
if (((ULONG)CapturedRequestMessage.u1.s1.TotalLength > PortObject->
MaxMessageLength) ||
00632 ((ULONG)CapturedRequestMessage.u1.s1.TotalLength <= (ULONG)CapturedRequestMessage.u1.s1.DataLength)) {
00633
00634
ObDereferenceObject( PortObject );
00635
00636
return STATUS_PORT_MESSAGE_TOO_LONG;
00637 }
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
LpcpAcquireLpcpLock();
00650
00651 Msg = (
PLPCP_MESSAGE)
LpcpAllocateFromPortZone( CapturedRequestMessage.u1.s1.TotalLength );
00652
00653
LpcpReleaseLpcpLock();
00654
00655
if (Msg ==
NULL) {
00656
00657
ObDereferenceObject( PortObject );
00658
00659
return STATUS_NO_MEMORY;
00660 }
00661
00662 MsgType = CapturedRequestMessage.u2.s2.Type;
00663
00664
00665
00666
00667
00668
if (CallbackRequest) {
00669
00670
00671
00672
00673
00674
if (CapturedRequestMessage.MessageId == 0) {
00675
00676
LpcpFreeToPortZone( Msg,
FALSE );
00677
00678
ObDereferenceObject( PortObject );
00679
00680
return STATUS_INVALID_PARAMETER;
00681 }
00682
00683
00684
00685
00686
00687
00688
00689
Status =
PsLookupProcessThreadByCid( &CapturedRequestMessage.ClientId,
00690
NULL,
00691 &WakeupThread );
00692
00693
if (!
NT_SUCCESS(
Status )) {
00694
00695
LpcpFreeToPortZone( Msg,
FALSE );
00696
00697
ObDereferenceObject( PortObject );
00698
00699
return Status;
00700 }
00701
00702
00703
00704
00705
00706
00707
00708
LpcpAcquireLpcpLock();
00709
00710
00711
00712
00713
00714
00715
00716
00717
if ((WakeupThread->
LpcReplyMessageId != CapturedRequestMessage.MessageId)
00718
00719 ||
00720
00721 ((WakeupThread->
LpcReplyMessage !=
NULL) &&
00722 (((
PLPCP_MESSAGE)(WakeupThread->
LpcReplyMessage))->Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE) != LPC_REQUEST)) {
00723
00724
LpcpPrint((
"%s Attempted CallBack Request to Thread %lx (%s)\n",
00725
PsGetCurrentProcess()->ImageFileName,
00726 WakeupThread,
00727
THREAD_TO_PROCESS( WakeupThread )->ImageFileName ));
00728
00729
LpcpPrint((
"failed. MessageId == %u Client Id: %x.%x\n",
00730 CapturedRequestMessage.MessageId,
00731 CapturedRequestMessage.ClientId.UniqueProcess,
00732 CapturedRequestMessage.ClientId.UniqueThread ));
00733
00734
LpcpPrint((
" Thread MessageId == %u Client Id: %x.%x\n",
00735 WakeupThread->
LpcReplyMessageId,
00736 WakeupThread->
Cid.UniqueProcess,
00737 WakeupThread->
Cid.UniqueThread ));
00738
00739
#if DBG
00740
if (LpcpStopOnReplyMismatch) {
00741
00742 DbgBreakPoint();
00743 }
00744
#endif
00745
00746
LpcpFreeToPortZone( Msg,
TRUE );
00747
00748
LpcpReleaseLpcpLock();
00749
00750
ObDereferenceObject( WakeupThread );
00751
ObDereferenceObject( PortObject );
00752
00753
return STATUS_REPLY_MESSAGE_MISMATCH;
00754 }
00755
00756
00757
00758
00759
00760
try {
00761
00762
LpcpMoveMessage( &Msg->
Request,
00763 &CapturedRequestMessage,
00764 (
RequestMessage + 1),
00765 MsgType,
00766 &CurrentThread->
Cid );
00767
00768
if (CapturedRequestMessage.u2.s2.DataInfoOffset != 0) {
00769
00770 PPORT_DATA_INFORMATION DataInfo;
00771
00772 DataInfo = (PPORT_DATA_INFORMATION)(((PUCHAR)
RequestMessage) + CapturedRequestMessage.u2.s2.DataInfoOffset);
00773
00774
if ( DataInfo->CountDataEntries != CapturedDataInfo.CountDataEntries ) {
00775
00776
Status = STATUS_INVALID_PARAMETER;
00777 }
00778 }
00779 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00780
00781
Status = GetExceptionCode();
00782 }
00783
00784
if (!
NT_SUCCESS(
Status )) {
00785
00786
LpcpFreeToPortZone( Msg,
FALSE );
00787
00788
LpcpReleaseLpcpLock();
00789
00790
ObDereferenceObject( WakeupThread );
00791
ObDereferenceObject( PortObject );
00792
00793
return Status;
00794 }
00795
00796
00797
00798
00799
00800
00801 QueuePort =
NULL;
00802 Msg->
PortContext =
NULL;
00803
00804
if ((PortObject->
Flags &
PORT_TYPE) ==
SERVER_CONNECTION_PORT) {
00805
00806 RundownPort = PortObject;
00807
00808 }
else {
00809
00810 RundownPort = PortObject->
ConnectedPort;
00811
00812
if (RundownPort ==
NULL) {
00813
00814
LpcpFreeToPortZone( Msg,
TRUE );
00815
00816
LpcpReleaseLpcpLock();
00817
00818
ObDereferenceObject( WakeupThread );
00819
ObDereferenceObject( PortObject );
00820
00821
return STATUS_PORT_DISCONNECTED;
00822 }
00823
00824
if ((PortObject->
Flags &
PORT_TYPE) ==
CLIENT_COMMUNICATION_PORT) {
00825
00826 Msg->
PortContext = RundownPort->
PortContext;
00827 }
00828 }
00829
00830 Msg->
Request.CallbackId =
LpcpGenerateCallbackId();
00831
00832
LpcpTrace((
"%s CallBack Request (%s) Msg %lx (%u.%u) [%08x %08x %08x %08x] to Thread %lx (%s)\n",
00833
PsGetCurrentProcess()->ImageFileName,
00834 LpcpMessageTypeName[ Msg->
Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE ],
00835 Msg,
00836 Msg->
Request.MessageId,
00837 Msg->
Request.CallbackId,
00838 *((PULONG)(Msg+1)+0),
00839 *((PULONG)(Msg+1)+1),
00840 *((PULONG)(Msg+1)+2),
00841 *((PULONG)(Msg+1)+3),
00842 WakeupThread,
00843
THREAD_TO_PROCESS( WakeupThread )->ImageFileName ));
00844
00845
00846
00847
00848
00849
00850
ObReferenceObject( WakeupThread );
00851
00852 Msg->RepliedToThread = WakeupThread;
00853
00854 WakeupThread->
LpcReplyMessageId = 0;
00855 WakeupThread->
LpcReplyMessage = (PVOID)Msg;
00856
00857
00858
00859
00860
00861
if (!IsListEmpty( &WakeupThread->
LpcReplyChain )) {
00862
00863 RemoveEntryList( &WakeupThread->
LpcReplyChain );
00864
00865 InitializeListHead( &WakeupThread->
LpcReplyChain );
00866 }
00867
00868 CurrentThread->
LpcReplyMessageId = Msg->Request.MessageId;
00869 CurrentThread->
LpcReplyMessage =
NULL;
00870
00871 InsertTailList( &RundownPort->
LpcReplyChainHead, &CurrentThread->
LpcReplyChain );
00872
00873
LpcpReleaseLpcpLock();
00874
00875
00876
00877
00878
00879
00880 ReleaseSemaphore = &WakeupThread->
LpcReplySemaphore;
00881
00882 }
else {
00883
00884
00885
00886
00887
00888
00889
try {
00890
00891
LpcpMoveMessage( &Msg->
Request,
00892 &CapturedRequestMessage,
00893 (
RequestMessage + 1),
00894 MsgType,
00895 &CurrentThread->
Cid );
00896
00897
if (CapturedRequestMessage.u2.s2.DataInfoOffset != 0) {
00898
00899 PPORT_DATA_INFORMATION DataInfo;
00900
00901 DataInfo = (PPORT_DATA_INFORMATION)(((PUCHAR)
RequestMessage) + CapturedRequestMessage.u2.s2.DataInfoOffset);
00902
00903
if ( DataInfo->CountDataEntries != CapturedDataInfo.CountDataEntries ) {
00904
00905
LpcpFreeToPortZone( Msg,
FALSE );
00906
00907
ObDereferenceObject( PortObject );
00908
00909
return STATUS_INVALID_PARAMETER;
00910 }
00911 }
00912 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00913
00914
LpcpFreeToPortZone( Msg,
FALSE );
00915
00916
ObDereferenceObject( PortObject );
00917
00918
return GetExceptionCode();
00919 }
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
LpcpAcquireLpcpLock();
00932
00933 Msg->
PortContext =
NULL;
00934
00935
if ((PortObject->
Flags &
PORT_TYPE) !=
SERVER_CONNECTION_PORT) {
00936
00937 QueuePort = PortObject->
ConnectedPort;
00938
00939
if (QueuePort ==
NULL) {
00940
00941
LpcpFreeToPortZone( Msg,
TRUE );
00942
00943
LpcpReleaseLpcpLock();
00944
00945
ObDereferenceObject( PortObject );
00946
00947
return STATUS_PORT_DISCONNECTED;
00948 }
00949
00950 RundownPort = QueuePort;
00951
00952
if ((PortObject->
Flags &
PORT_TYPE) ==
CLIENT_COMMUNICATION_PORT) {
00953
00954 Msg->
PortContext = QueuePort->PortContext;
00955 QueuePort = PortObject->
ConnectionPort;
00956
00957 }
else if ((PortObject->
Flags &
PORT_TYPE) !=
SERVER_COMMUNICATION_PORT) {
00958
00959 QueuePort = PortObject->
ConnectionPort;
00960 }
00961
00962 }
else {
00963
00964 QueuePort = PortObject;
00965 RundownPort = PortObject;
00966 }
00967
00968
00969
00970
00971
00972
00973 Msg->
RepliedToThread =
NULL;
00974 Msg->
Request.MessageId =
LpcpGenerateMessageId();
00975 Msg->
Request.CallbackId = 0;
00976
00977 CurrentThread->
LpcReplyMessageId = Msg->
Request.MessageId;
00978 CurrentThread->
LpcReplyMessage =
NULL;
00979
00980 InsertTailList( &QueuePort->
MsgQueue.
ReceiveHead, &Msg->
Entry );
00981 InsertTailList( &RundownPort->
LpcReplyChainHead, &CurrentThread->
LpcReplyChain );
00982
00983
LpcpTrace((
"%s Send Request (%s) Msg %lx (%u) [%08x %08x %08x %08x] to Port %lx (%s)\n",
00984
PsGetCurrentProcess()->ImageFileName,
00985 LpcpMessageTypeName[ Msg->
Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE ],
00986 Msg,
00987 Msg->
Request.MessageId,
00988 *((PULONG)(Msg+1)+0),
00989 *((PULONG)(Msg+1)+1),
00990 *((PULONG)(Msg+1)+2),
00991 *((PULONG)(Msg+1)+3),
00992 QueuePort,
00993
LpcpGetCreatorName( QueuePort )));
00994
00995
LpcpReleaseLpcpLock();
00996
00997
00998
00999
01000
01001
01002 ReleaseSemaphore = QueuePort->
MsgQueue.
Semaphore;
01003
01004
01005
01006
01007
01008
01009
if ( QueuePort->
Flags &
PORT_WAITABLE ) {
01010
01011
KeSetEvent( &QueuePort->
WaitEvent,
01012
LPC_RELEASE_WAIT_INCREMENT,
01013
FALSE );
01014 }
01015 }
01016
01017
01018
01019
01020
01021
01022
01023
01024
Status =
KeReleaseSemaphore( ReleaseSemaphore,
01025 1,
01026 1,
01027
FALSE );
01028
01029
if (CallbackRequest) {
01030
01031
ObDereferenceObject( WakeupThread );
01032 }
01033
01034
01035
01036
01037
01038
Status =
KeWaitForSingleObject( &CurrentThread->
LpcReplySemaphore,
01039
WrLpcReply,
01040 PreviousMode,
01041
FALSE,
01042
NULL );
01043
01044
if (
Status == STATUS_USER_APC) {
01045
01046
01047
01048
01049
01050
if (
KeReadStateSemaphore( &CurrentThread->
LpcReplySemaphore )) {
01051
01052
KeWaitForSingleObject( &CurrentThread->
LpcReplySemaphore,
01053
WrExecutive,
01054
KernelMode,
01055
FALSE,
01056
NULL );
01057
01058
Status = STATUS_SUCCESS;
01059 }
01060 }
01061
01062
01063
01064
01065
01066
LpcpAcquireLpcpLock();
01067
01068 Msg = CurrentThread->
LpcReplyMessage;
01069
01070 CurrentThread->
LpcReplyMessage =
NULL;
01071 CurrentThread->
LpcReplyMessageId = 0;
01072
01073
01074
01075
01076
01077
01078
if (!IsListEmpty( &CurrentThread->
LpcReplyChain )) {
01079
01080 RemoveEntryList( &CurrentThread->
LpcReplyChain );
01081
01082 InitializeListHead( &CurrentThread->
LpcReplyChain );
01083 }
01084
01085
#if DBG
01086
if (
Status == STATUS_SUCCESS && Msg !=
NULL) {
01087
01088
LpcpTrace((
"%s Got Reply Msg %lx (%u) [%08x %08x %08x %08x] for Thread %lx (%s)\n",
01089
PsGetCurrentProcess()->ImageFileName,
01090 Msg,
01091 Msg->
Request.MessageId,
01092 *((PULONG)(Msg+1)+0),
01093 *((PULONG)(Msg+1)+1),
01094 *((PULONG)(Msg+1)+2),
01095 *((PULONG)(Msg+1)+3),
01096 CurrentThread,
01097
THREAD_TO_PROCESS( CurrentThread )->ImageFileName ));
01098
01099
if (!IsListEmpty( &Msg->Entry )) {
01100
01101
LpcpTrace((
"Reply Msg %lx has non-empty list entry\n", Msg ));
01102 }
01103 }
01104
#endif
01105
01106
LpcpReleaseLpcpLock();
01107
01108
01109
01110
01111
01112
if (
Status == STATUS_SUCCESS) {
01113
01114
if (Msg !=
NULL) {
01115
01116
try {
01117
01118
LpcpMoveMessage(
ReplyMessage,
01119 &Msg->
Request,
01120 (&Msg->
Request) + 1,
01121 0,
01122
NULL );
01123
01124 } except(
EXCEPTION_EXECUTE_HANDLER ) {
01125
01126
Status = GetExceptionCode();
01127 }
01128
01129
01130
01131
01132
01133
01134
01135
if (((Msg->
Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE) == LPC_REQUEST) &&
01136 (Msg->
Request.u2.s2.DataInfoOffset != 0)) {
01137
01138
LpcpSaveDataInfoMessage( PortObject, Msg );
01139
01140 }
else {
01141
01142
LpcpFreeToPortZone( Msg,
FALSE );
01143 }
01144
01145 }
else {
01146
01147
Status = STATUS_LPC_REPLY_LOST;
01148 }
01149
01150 }
else {
01151
01152
01153
01154
01155
01156
LpcpAcquireLpcpLock();
01157
01158
LpcpTrace((
"%s NtRequestWaitReply wait failed - Status == %lx\n",
01159
PsGetCurrentProcess()->ImageFileName,
01160
Status ));
01161
01162
if (Msg !=
NULL) {
01163
01164
LpcpFreeToPortZone( Msg,
TRUE );
01165 }
01166
01167
LpcpReleaseLpcpLock();
01168 }
01169
01170
ObDereferenceObject( PortObject );
01171
01172
01173
01174
01175
01176
return Status;
01177 }
01178
01179
01180
NTSTATUS
01181 LpcRequestPort (
01182 IN PVOID PortAddress,
01183 IN PPORT_MESSAGE RequestMessage
01184 )
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 {
01209
PLPCP_PORT_OBJECT PortObject = (
PLPCP_PORT_OBJECT)PortAddress;
01210
PLPCP_PORT_OBJECT QueuePort;
01211 ULONG MsgType;
01212
PLPCP_MESSAGE Msg;
01213
KPROCESSOR_MODE PreviousMode;
01214
01215
PAGED_CODE();
01216
01217
01218
01219
01220
01221 PreviousMode = KeGetPreviousMode();
01222
01223
if (
RequestMessage->u2.s2.Type != 0) {
01224
01225 MsgType =
RequestMessage->u2.s2.Type & ~LPC_KERNELMODE_MESSAGE;
01226
01227
if ((MsgType < LPC_DATAGRAM) ||
01228 (MsgType > LPC_CLIENT_DIED)) {
01229
01230
return STATUS_INVALID_PARAMETER;
01231 }
01232
01233
01234
01235
01236
01237
01238
if ((PreviousMode ==
KernelMode) &&
01239 (
RequestMessage->u2.s2.Type & LPC_KERNELMODE_MESSAGE)) {
01240
01241 MsgType |= LPC_KERNELMODE_MESSAGE;
01242 }
01243
01244 }
else {
01245
01246 MsgType = LPC_DATAGRAM;
01247 }
01248
01249
if (
RequestMessage->u2.s2.DataInfoOffset != 0) {
01250
01251
return STATUS_INVALID_PARAMETER;
01252 }
01253
01254
01255
01256
01257
01258
if (((ULONG)
RequestMessage->u1.s1.TotalLength > PortObject->
MaxMessageLength) ||
01259 ((ULONG)
RequestMessage->u1.s1.TotalLength <= (ULONG)
RequestMessage->u1.s1.DataLength)) {
01260
01261
return STATUS_PORT_MESSAGE_TOO_LONG;
01262 }
01263
01264
01265
01266
01267
01268
LpcpAcquireLpcpLock();
01269
01270 Msg = (
PLPCP_MESSAGE)
LpcpAllocateFromPortZone(
RequestMessage->u1.s1.TotalLength );
01271
01272
LpcpReleaseLpcpLock();
01273
01274
if (Msg ==
NULL) {
01275
01276
return STATUS_NO_MEMORY;
01277 }
01278
01279
01280
01281
01282
01283 Msg->
RepliedToThread =
NULL;
01284 Msg->
PortContext =
NULL;
01285
01286
LpcpMoveMessage( &Msg->
Request,
01287
RequestMessage,
01288 (
RequestMessage + 1),
01289 MsgType,
01290 &
PsGetCurrentThread()->Cid );
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
KeEnterCriticalRegion();
01304
01305
LpcpAcquireLpcpLock();
01306
01307
if ((PortObject->
Flags &
PORT_TYPE) !=
SERVER_CONNECTION_PORT) {
01308
01309 QueuePort = PortObject->
ConnectedPort;
01310
01311
if (QueuePort !=
NULL) {
01312
01313
if ((PortObject->
Flags &
PORT_TYPE) ==
CLIENT_COMMUNICATION_PORT) {
01314
01315 Msg->
PortContext = QueuePort->
PortContext;
01316 QueuePort = PortObject->
ConnectionPort;
01317
01318
01319
01320
01321
01322
01323 }
else if ((PortObject->
Flags &
PORT_TYPE) !=
SERVER_COMMUNICATION_PORT) {
01324
01325 QueuePort = PortObject->
ConnectionPort;
01326 }
01327 }
01328
01329 }
else {
01330
01331 QueuePort = PortObject;
01332 }
01333
01334
01335
01336
01337
01338
01339
if (QueuePort !=
NULL) {
01340
01341 Msg->
Request.MessageId =
LpcpGenerateMessageId();
01342 Msg->
Request.CallbackId = 0;
01343
01344
PsGetCurrentThread()->LpcReplyMessageId = 0;
01345
01346 InsertTailList( &QueuePort->
MsgQueue.
ReceiveHead, &Msg->
Entry );
01347
01348
LpcpTrace((
"%s Send DataGram (%s) Msg %lx [%08x %08x %08x %08x] to Port %lx (%s)\n",
01349
PsGetCurrentProcess()->ImageFileName,
01350 LpcpMessageTypeName[ Msg->
Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE ],
01351 Msg,
01352 *((PULONG)(Msg+1)+0),
01353 *((PULONG)(Msg+1)+1),
01354 *((PULONG)(Msg+1)+2),
01355 *((PULONG)(Msg+1)+3),
01356 QueuePort,
01357
LpcpGetCreatorName( QueuePort )));
01358
01359
01360
01361
01362
01363
01364
01365
LpcpReleaseLpcpLock();
01366
01367
KeReleaseSemaphore( QueuePort->
MsgQueue.
Semaphore,
01368
LPC_RELEASE_WAIT_INCREMENT,
01369 1
L,
01370
FALSE );
01371
01372
01373
if ( QueuePort->
Flags &
PORT_WAITABLE ) {
01374
01375
KeSetEvent( &QueuePort->
WaitEvent,
01376
LPC_RELEASE_WAIT_INCREMENT,
01377
FALSE );
01378 }
01379
01380
KeLeaveCriticalRegion();
01381
01382
return STATUS_SUCCESS;
01383
01384 }
01385
01386
01387
01388
01389
01390
01391
01392
LpcpFreeToPortZone( Msg,
TRUE );
01393
01394
LpcpReleaseLpcpLock();
01395
01396
KeLeaveCriticalRegion();
01397
01398
01399
01400
01401
01402
return STATUS_PORT_DISCONNECTED;
01403 }
01404
01405
01406
NTSTATUS
01407 LpcRequestWaitReplyPort (
01408 IN PVOID PortAddress,
01409 IN PPORT_MESSAGE RequestMessage,
01410 OUT PPORT_MESSAGE ReplyMessage
01411 )
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438 {
01439
PLPCP_PORT_OBJECT PortObject = (
PLPCP_PORT_OBJECT)PortAddress;
01440
PLPCP_PORT_OBJECT QueuePort;
01441
PLPCP_PORT_OBJECT RundownPort;
01442
PKSEMAPHORE ReleaseSemaphore;
01443
NTSTATUS Status;
01444 ULONG MsgType;
01445
PLPCP_MESSAGE Msg;
01446
PETHREAD CurrentThread;
01447
PETHREAD WakeupThread;
01448 BOOLEAN CallbackRequest;
01449
KPROCESSOR_MODE PreviousMode;
01450
01451
PAGED_CODE();
01452
01453 CurrentThread =
PsGetCurrentThread();
01454
01455
if (CurrentThread->
LpcExitThreadCalled) {
01456
01457
return STATUS_THREAD_IS_TERMINATING;
01458 }
01459
01460
01461
01462
01463
01464 PreviousMode = KeGetPreviousMode();
01465 MsgType =
RequestMessage->u2.s2.Type & ~LPC_KERNELMODE_MESSAGE;
01466 CallbackRequest =
FALSE;
01467
01468
switch (MsgType) {
01469
01470
case 0:
01471
01472 MsgType = LPC_REQUEST;
01473
break;
01474
01475
case LPC_REQUEST:
01476
01477 CallbackRequest =
TRUE;
01478
break;
01479
01480
case LPC_CLIENT_DIED:
01481
case LPC_PORT_CLOSED:
01482
case LPC_EXCEPTION:
01483
case LPC_DEBUG_EVENT:
01484
case LPC_ERROR_EVENT:
01485
01486
break;
01487
01488
default :
01489
01490
return STATUS_INVALID_PARAMETER;
01491 }
01492
01493
01494
01495
01496
01497
01498
if (
RequestMessage->u2.s2.Type & LPC_KERNELMODE_MESSAGE) {
01499
01500 MsgType |= LPC_KERNELMODE_MESSAGE;
01501 }
01502
01503
RequestMessage->u2.s2.Type = (CSHORT)MsgType;
01504
01505
01506
01507
01508
01509
if (((ULONG)
RequestMessage->u1.s1.TotalLength > PortObject->
MaxMessageLength) ||
01510 ((ULONG)
RequestMessage->u1.s1.TotalLength <= (ULONG)
RequestMessage->u1.s1.DataLength)) {
01511
01512
return STATUS_PORT_MESSAGE_TOO_LONG;
01513 }
01514
01515
01516
01517
01518
01519
01520
01521
LpcpAcquireLpcpLock();
01522
01523 Msg = (
PLPCP_MESSAGE)
LpcpAllocateFromPortZone(
RequestMessage->u1.s1.TotalLength );
01524
01525
LpcpReleaseLpcpLock();
01526
01527
if (Msg ==
NULL) {
01528
01529
return STATUS_NO_MEMORY;
01530 }
01531
01532
if (CallbackRequest) {
01533
01534
01535
01536
01537
01538
if (
RequestMessage->MessageId == 0) {
01539
01540
LpcpFreeToPortZone( Msg,
FALSE );
01541
01542
return STATUS_INVALID_PARAMETER;
01543 }
01544
01545
01546
01547
01548
01549
01550
01551
Status =
PsLookupProcessThreadByCid( &
RequestMessage->ClientId,
01552
NULL,
01553 &WakeupThread );
01554
01555
if (!
NT_SUCCESS(
Status )) {
01556
01557
LpcpFreeToPortZone( Msg,
FALSE );
01558
01559
return Status;
01560 }
01561
01562
01563
01564
01565
01566
01567
01568
LpcpAcquireLpcpLock();
01569
01570
01571
01572
01573
01574
01575
01576
01577
if ((WakeupThread->
LpcReplyMessageId !=
RequestMessage->MessageId)
01578
01579 ||
01580
01581 ((WakeupThread->
LpcReplyMessage !=
NULL) &&
01582 (((
PLPCP_MESSAGE)(WakeupThread->
LpcReplyMessage))->Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE) != LPC_REQUEST)) {
01583
01584
LpcpFreeToPortZone( Msg,
TRUE );
01585
01586
LpcpReleaseLpcpLock();
01587
01588
ObDereferenceObject( WakeupThread );
01589
01590
return STATUS_REPLY_MESSAGE_MISMATCH;
01591 }
01592
01593 QueuePort =
NULL;
01594 Msg->
PortContext =
NULL;
01595
01596
if ((PortObject->
Flags &
PORT_TYPE) ==
SERVER_CONNECTION_PORT) {
01597
01598 RundownPort = PortObject;
01599
01600 }
else {
01601
01602 RundownPort = PortObject->
ConnectedPort;
01603
01604
if (RundownPort ==
NULL) {
01605
01606
LpcpFreeToPortZone( Msg,
TRUE );
01607
01608
LpcpReleaseLpcpLock();
01609
01610
ObDereferenceObject( WakeupThread );
01611
01612
return STATUS_PORT_DISCONNECTED;
01613 }
01614
01615
if ((PortObject->
Flags &
PORT_TYPE) ==
CLIENT_COMMUNICATION_PORT) {
01616
01617 Msg->
PortContext = RundownPort->
PortContext;
01618 }
01619 }
01620
01621
01622
01623
01624
01625
LpcpMoveMessage( &Msg->
Request,
01626
RequestMessage,
01627 (
RequestMessage + 1),
01628 0,
01629 &CurrentThread->
Cid );
01630
01631 Msg->
Request.CallbackId =
LpcpGenerateCallbackId();
01632
01633
LpcpTrace((
"%s CallBack Request (%s) Msg %lx (%u.%u) [%08x %08x %08x %08x] to Thread %lx (%s)\n",
01634
PsGetCurrentProcess()->ImageFileName,
01635 LpcpMessageTypeName[ Msg->
Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE ],
01636 Msg,
01637 Msg->
Request.MessageId,
01638 Msg->
Request.CallbackId,
01639 *((PULONG)(Msg+1)+0),
01640 *((PULONG)(Msg+1)+1),
01641 *((PULONG)(Msg+1)+2),
01642 *((PULONG)(Msg+1)+3),
01643 WakeupThread,
01644
THREAD_TO_PROCESS( WakeupThread )->ImageFileName ));
01645
01646
01647
01648
01649
01650
01651
ObReferenceObject( WakeupThread );
01652
01653 Msg->RepliedToThread = WakeupThread;
01654
01655 WakeupThread->
LpcReplyMessageId = 0;
01656 WakeupThread->
LpcReplyMessage = (PVOID)Msg;
01657
01658
01659
01660
01661
01662
if (!IsListEmpty( &WakeupThread->
LpcReplyChain )) {
01663
01664 RemoveEntryList( &WakeupThread->
LpcReplyChain );
01665
01666 InitializeListHead( &WakeupThread->
LpcReplyChain );
01667 }
01668
01669 CurrentThread->
LpcReplyMessageId = Msg->Request.MessageId;
01670 CurrentThread->
LpcReplyMessage =
NULL;
01671
01672 InsertTailList( &RundownPort->
LpcReplyChainHead, &CurrentThread->
LpcReplyChain );
01673
01674
LpcpReleaseLpcpLock();
01675
01676
01677
01678
01679
01680
01681 ReleaseSemaphore = &WakeupThread->
LpcReplySemaphore;
01682
01683 }
else {
01684
01685
01686
01687
01688
01689
LpcpMoveMessage( &Msg->
Request,
01690
RequestMessage,
01691 (
RequestMessage + 1),
01692 0,
01693 &CurrentThread->
Cid );
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
LpcpAcquireLpcpLock();
01704
01705 Msg->
PortContext =
NULL;
01706
01707
if ((PortObject->
Flags &
PORT_TYPE) !=
SERVER_CONNECTION_PORT) {
01708
01709 QueuePort = PortObject->
ConnectedPort;
01710
01711
if (QueuePort ==
NULL) {
01712
01713
LpcpFreeToPortZone( Msg,
TRUE );
01714
01715
LpcpReleaseLpcpLock();
01716
01717
return STATUS_PORT_DISCONNECTED;
01718 }
01719
01720 RundownPort = QueuePort;
01721
01722
if ((PortObject->
Flags &
PORT_TYPE) ==
CLIENT_COMMUNICATION_PORT) {
01723
01724 Msg->
PortContext = QueuePort->PortContext;
01725 QueuePort = PortObject->
ConnectionPort;
01726
01727 }
else if ((PortObject->
Flags &
PORT_TYPE) !=
SERVER_COMMUNICATION_PORT) {
01728
01729 QueuePort = PortObject->
ConnectionPort;
01730 }
01731
01732 }
else {
01733
01734 QueuePort = PortObject;
01735 RundownPort = PortObject;
01736 }
01737
01738 Msg->
RepliedToThread =
NULL;
01739 Msg->
Request.MessageId =
LpcpGenerateMessageId();
01740 Msg->
Request.CallbackId = 0;
01741
01742 CurrentThread->
LpcReplyMessageId = Msg->
Request.MessageId;
01743 CurrentThread->
LpcReplyMessage =
NULL;
01744
01745 InsertTailList( &QueuePort->
MsgQueue.
ReceiveHead, &Msg->
Entry );
01746 InsertTailList( &RundownPort->
LpcReplyChainHead, &CurrentThread->
LpcReplyChain );
01747
01748
LpcpTrace((
"%s Send Request (%s) Msg %lx (%u) [%08x %08x %08x %08x] to Port %lx (%s)\n",
01749
PsGetCurrentProcess()->ImageFileName,
01750 LpcpMessageTypeName[ Msg->
Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE ],
01751 Msg,
01752 Msg->
Request.MessageId,
01753 *((PULONG)(Msg+1)+0),
01754 *((PULONG)(Msg+1)+1),
01755 *((PULONG)(Msg+1)+2),
01756 *((PULONG)(Msg+1)+3),
01757 QueuePort,
01758
LpcpGetCreatorName( QueuePort )));
01759
01760
LpcpReleaseLpcpLock();
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770 ReleaseSemaphore = QueuePort->
MsgQueue.
Semaphore;
01771
01772
if ( QueuePort->
Flags &
PORT_WAITABLE ) {
01773
01774
KeSetEvent( &QueuePort->
WaitEvent,
01775
LPC_RELEASE_WAIT_INCREMENT,
01776
FALSE );
01777 }
01778 }
01779
01780
01781
01782
01783
01784
01785
01786
01787
Status =
KeReleaseSemaphore( ReleaseSemaphore,
01788 1,
01789 1,
01790
FALSE );
01791
01792
if (CallbackRequest) {
01793
01794
ObDereferenceObject( WakeupThread );
01795 }
01796
01797
01798
01799
01800
01801
Status =
KeWaitForSingleObject( &CurrentThread->
LpcReplySemaphore,
01802
WrLpcReply,
01803
KernelMode,
01804
FALSE,
01805
NULL );
01806
01807
if (
Status == STATUS_USER_APC) {
01808
01809
01810
01811
01812
01813
if (
KeReadStateSemaphore( &CurrentThread->
LpcReplySemaphore )) {
01814
01815
KeWaitForSingleObject( &CurrentThread->
LpcReplySemaphore,
01816
WrExecutive,
01817
KernelMode,
01818
FALSE,
01819
NULL );
01820
01821
Status = STATUS_SUCCESS;
01822 }
01823 }
01824
01825
01826
01827
01828
01829
LpcpAcquireLpcpLock();
01830
01831 Msg = CurrentThread->
LpcReplyMessage;
01832
01833 CurrentThread->
LpcReplyMessage =
NULL;
01834 CurrentThread->
LpcReplyMessageId = 0;
01835
01836
01837
01838
01839
01840
01841
if (!IsListEmpty( &CurrentThread->
LpcReplyChain )) {
01842
01843 RemoveEntryList( &CurrentThread->
LpcReplyChain );
01844
01845 InitializeListHead( &CurrentThread->
LpcReplyChain );
01846 }
01847
01848
#if DBG
01849
if (Msg !=
NULL) {
01850
01851
LpcpTrace((
"%s Got Reply Msg %lx (%u) [%08x %08x %08x %08x] for Thread %lx (%s)\n",
01852
PsGetCurrentProcess()->ImageFileName,
01853 Msg,
01854 Msg->
Request.MessageId,
01855 *((PULONG)(Msg+1)+0),
01856 *((PULONG)(Msg+1)+1),
01857 *((PULONG)(Msg+1)+2),
01858 *((PULONG)(Msg+1)+3),
01859 CurrentThread,
01860
THREAD_TO_PROCESS( CurrentThread )->ImageFileName ));
01861 }
01862
#endif
01863
01864
LpcpReleaseLpcpLock();
01865
01866
01867
01868
01869
01870
if (
Status == STATUS_SUCCESS) {
01871
01872
if (Msg !=
NULL) {
01873
01874
LpcpMoveMessage(
ReplyMessage,
01875 &Msg->
Request,
01876 (&Msg->
Request) + 1,
01877 0,
01878
NULL );
01879
01880
01881
01882
01883
01884
01885
01886
LpcpAcquireLpcpLock();
01887
01888
if (Msg->
RepliedToThread !=
NULL) {
01889
01890
ObDereferenceObject( Msg->
RepliedToThread );
01891
01892 Msg->
RepliedToThread =
NULL;
01893 }
01894
01895
LpcpFreeToPortZone( Msg,
TRUE );
01896
01897
LpcpReleaseLpcpLock();
01898
01899 }
else {
01900
01901
Status = STATUS_LPC_REPLY_LOST;
01902 }
01903
01904 }
else {
01905
01906
01907
01908
01909
01910
LpcpAcquireLpcpLock();
01911
01912
if (Msg !=
NULL) {
01913
01914
LpcpFreeToPortZone( Msg,
TRUE );
01915 }
01916
01917
LpcpReleaseLpcpLock();
01918 }
01919
01920
01921
01922
01923
01924
return Status;
01925 }
01926