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

lpcp.h File Reference

#include "ntos.h"
#include <zwapi.h>

Go to the source code of this file.

Classes

struct  _LPC_MUTEX

Defines

#define LpcpGenerateMessageId()   LpcpNextMessageId++; if (LpcpNextMessageId == 0) LpcpNextMessageId = 1;
#define LpcpGenerateCallbackId()   LpcpNextCallbackId++; if (LpcpNextCallbackId == 0) LpcpNextCallbackId = 1;
#define LpcpInitializeLpcpLock()
#define LpcpAcquireLpcpLock()
#define LpcpReleaseLpcpLock()
#define LpcpPortExtraDataCreate(x)
#define LpcpPortExtraDataDestroy(x)
#define LpcpSaveThread(x)
#define LpcpGetDynamicClientSecurity(Thread, Port, DynamicSecurity)   SeCreateClientSecurity((Thread),&(Port)->SecurityQos,FALSE,(DynamicSecurity))
#define LpcpFreeDynamicClientSecurity(DynamicSecurity)   SeDeleteClientSecurity( DynamicSecurity )
#define LpcpReferencePortObject(PortHandle, PortAccess, PreviousMode, PortObject)   ObReferenceObjectByHandle((PortHandle),(PortAccess),LpcPortObjectType,(PreviousMode),(PVOID *)(PortObject),NULL)
#define ENABLE_LPC_TRACING   0
#define LpcpPrint(_x_)
#define LpcpTrace(_x_)

Typedefs

typedef _LPC_MUTEX LPC_MUTEX
typedef _LPC_MUTEXPLPC_MUTEX

Functions

VOID LpcpClosePort (IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
VOID LpcpDeletePort (IN PVOID Object)
NTSTATUS LpcpInitializePortQueue (IN PLPCP_PORT_OBJECT Port)
VOID LpcpDestroyPortQueue (IN PLPCP_PORT_OBJECT Port, IN BOOLEAN CleanupAndDestroy)
NTSTATUS LpcpInitializePortZone (IN ULONG MaxEntrySize, IN ULONG SegmentSize, IN ULONG MaxPoolUsage)
NTSTATUS LpcpExtendPortZone (VOID)
PLPCP_MESSAGE FASTCALL LpcpAllocateFromPortZone (ULONG Size)
VOID FASTCALL LpcpFreeToPortZone (IN PLPCP_MESSAGE Msg, IN BOOLEAN MutexOwned)
VOID LpcpSaveDataInfoMessage (IN PLPCP_PORT_OBJECT Port, PLPCP_MESSAGE Msg)
VOID LpcpFreeDataInfoMessage (IN PLPCP_PORT_OBJECT Port, IN ULONG MessageId, IN ULONG CallbackId)
PLPCP_MESSAGE LpcpFindDataInfoMessage (IN PLPCP_PORT_OBJECT Port, IN ULONG MessageId, IN ULONG CallbackId)
VOID LpcpMoveMessage (OUT PPORT_MESSAGE DstMsg, IN PPORT_MESSAGE SrcMsg, IN PVOID SrcMsgData, IN ULONG MsgType OPTIONAL, IN PCLIENT_ID ClientId OPTIONAL)
VOID LpcpFreePortClientSecurity (IN PLPCP_PORT_OBJECT Port)
char * LpcpGetCreatorName (PLPCP_PORT_OBJECT PortObject)

Variables

LPC_MUTEX LpcpLock
LPCP_PORT_ZONE LpcpZone
ULONG LpcpNextMessageId
ULONG LpcpNextCallbackId


Define Documentation

#define ENABLE_LPC_TRACING   0
 

Definition at line 294 of file lpcp.h.

 
#define LpcpAcquireLpcpLock  ) 
 

Value:

{ \ if ( LpcpLock.Owner == PsGetCurrentThread() ) { \ \ ASSERT ( LpcpLock.Count >= 1 ); \ LpcpLock.Count += 1; \ \ } else { \ \ ExAcquireFastMutex( &LpcpLock.Lock ); \ LpcpLock.Owner = PsGetCurrentThread(); \ LpcpLock.Count = 1; \ } \ }

Definition at line 93 of file lpcp.h.

Referenced by LpcExitThread(), LpcpCopyRequestData(), LpcpDeletePort(), LpcpDestroyPortQueue(), LpcpExtendPortZone(), LpcpFreeConMsg(), LpcpFreeToPortZone(), LpcpSaveDataInfoMessage(), LpcRequestPort(), LpcRequestWaitReplyPort(), NtAcceptConnectPort(), NtCompleteConnectPort(), NtImpersonateClientOfPort(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtRequestPort(), NtRequestWaitReplyPort(), NtSecureConnectPort(), and ObfDereferenceObject().

#define LpcpFreeDynamicClientSecurity DynamicSecurity   )     SeDeleteClientSecurity( DynamicSecurity )
 

Definition at line 275 of file lpcp.h.

Referenced by NtImpersonateClientOfPort().

 
#define LpcpGenerateCallbackId  )     LpcpNextCallbackId++; if (LpcpNextCallbackId == 0) LpcpNextCallbackId = 1;
 

Definition at line 74 of file lpcp.h.

Referenced by LpcRequestWaitReplyPort(), and NtRequestWaitReplyPort().

 
#define LpcpGenerateMessageId  )     LpcpNextMessageId++; if (LpcpNextMessageId == 0) LpcpNextMessageId = 1;
 

Definition at line 71 of file lpcp.h.

Referenced by LpcRequestPort(), LpcRequestWaitReplyPort(), NtRequestPort(), NtRequestWaitReplyPort(), and NtSecureConnectPort().

#define LpcpGetDynamicClientSecurity Thread,
Port,
DynamicSecurity   )     SeCreateClientSecurity((Thread),&(Port)->SecurityQos,FALSE,(DynamicSecurity))
 

Definition at line 272 of file lpcp.h.

Referenced by NtImpersonateClientOfPort().

 
#define LpcpInitializeLpcpLock  ) 
 

Value:

Definition at line 86 of file lpcp.h.

Referenced by LpcInitSystem().

#define LpcpPortExtraDataCreate  ) 
 

Definition at line 149 of file lpcp.h.

#define LpcpPortExtraDataDestroy  ) 
 

Definition at line 151 of file lpcp.h.

Referenced by LpcpDeletePort().

#define LpcpPrint _x_   ) 
 

Definition at line 319 of file lpcp.h.

Referenced by LpcpCreatePort(), LpcpExtendPortZone(), LpcpFreeToPortZone(), NtAcceptConnectPort(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), and NtRequestWaitReplyPort().

#define LpcpReferencePortObject PortHandle,
PortAccess,
PreviousMode,
PortObject   )     ObReferenceObjectByHandle((PortHandle),(PortAccess),LpcPortObjectType,(PreviousMode),(PVOID *)(PortObject),NULL)
 

Definition at line 278 of file lpcp.h.

Referenced by LpcpCopyRequestData(), NtCompleteConnectPort(), NtImpersonateClientOfPort(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtRequestPort(), and NtRequestWaitReplyPort().

 
#define LpcpReleaseLpcpLock  ) 
 

Value:

{ \ ASSERT( LpcpLock.Owner == PsGetCurrentThread() ); \ ASSERT( LpcpLock.Count >= 1 ); \ \ LpcpLock.Count -= 1; \ \ if ( LpcpLock.Count == 0 ) { \ \ LpcpLock.Owner = NULL; \ ExReleaseFastMutex( &LpcpLock.Lock ); \ } \ }

Definition at line 108 of file lpcp.h.

Referenced by LpcExitThread(), LpcpCopyRequestData(), LpcpDeletePort(), LpcpDestroyPortQueue(), LpcpExtendPortZone(), LpcpFreeConMsg(), LpcpFreeToPortZone(), LpcpSaveDataInfoMessage(), LpcRequestPort(), LpcRequestWaitReplyPort(), NtAcceptConnectPort(), NtCompleteConnectPort(), NtImpersonateClientOfPort(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtRequestPort(), NtRequestWaitReplyPort(), NtSecureConnectPort(), and ObfDereferenceObject().

#define LpcpSaveThread  ) 
 

Definition at line 153 of file lpcp.h.

Referenced by LpcpCopyRequestData(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), and NtReplyWaitReplyPort().

#define LpcpTrace _x_   ) 
 

Definition at line 320 of file lpcp.h.

Referenced by LpcExitThread(), LpcpAllocateFromPortZone(), LpcpCreatePort(), LpcpDeletePort(), LpcpExtendPortZone(), LpcpFindDataInfoMessage(), LpcpFreeDataInfoMessage(), LpcpFreeToPortZone(), LpcpSaveDataInfoMessage(), LpcRequestPort(), LpcRequestWaitReplyPort(), NtAcceptConnectPort(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtRequestPort(), NtRequestWaitReplyPort(), and NtSecureConnectPort().


Typedef Documentation

typedef struct _LPC_MUTEX LPC_MUTEX
 

typedef struct _LPC_MUTEX * PLPC_MUTEX
 


Function Documentation

PLPCP_MESSAGE FASTCALL LpcpAllocateFromPortZone ULONG  Size  ) 
 

Definition at line 558 of file lpcqueue.c.

References _LPCP_MESSAGE::Entry, ExAllocateFromZone, LpcpExtendPortZone(), LpcpTrace, LpcpZone, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _LPCP_MESSAGE::RepliedToThread, Status, _LPCP_PORT_ZONE::Zone, and _LPCP_MESSAGE::ZoneIndex.

Referenced by LpcRequestPort(), LpcRequestWaitReplyPort(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtRequestPort(), NtRequestWaitReplyPort(), and NtSecureConnectPort().

00564 : 00565 00566 This procedure is used to allocate a new msg from the global port zone. 00567 00568 Note that we assume our caller owns the LpcpLock mutex. 00569 00570 Arguments: 00571 00572 Size - Specifies the size, in bytes, needed for the allocation. Currently 00573 this variable is ignored 00574 00575 Return Value: 00576 00577 PLPCP_MESSAGE - returns a pointer to the newly allocate message 00578 00579 --*/ 00580 00581 { 00582 NTSTATUS Status; 00583 PLPCP_MESSAGE Msg; 00584 00585 PAGED_CODE(); 00586 00587 // 00588 // Continue looping until we get a message to give back or until when we 00589 // extend the zone we get back and error 00590 // 00591 00592 do { 00593 00594 // 00595 // Pick off the next message from the zone and if we actually 00596 // did get one then initialize some of its fields and return it 00597 // to our caller 00598 // 00599 00600 Msg = (PLPCP_MESSAGE)ExAllocateFromZone( &LpcpZone.Zone ); 00601 00602 if (Msg != NULL) { 00603 00604 LpcpTrace(( "Allocate Msg %lx\n", Msg )); 00605 00606 InitializeListHead( &Msg->Entry ); 00607 00608 Msg->RepliedToThread = NULL; 00609 00610 #if DBG 00611 // 00612 // In the debug case mark the message as allocated 00613 // 00614 00615 Msg->ZoneIndex |= LPCP_ZONE_MESSAGE_ALLOCATED; 00616 #endif 00617 00618 return Msg; 00619 } 00620 00621 // 00622 // The zone didn't give us an entry so extend the zone and try the 00623 // allocation again 00624 // 00625 00626 LpcpTrace(( "Extending Zone %lx\n", &LpcpZone.Zone )); 00627 00628 Status = LpcpExtendPortZone( ); 00629 00630 } while (NT_SUCCESS(Status)); 00631 00632 // 00633 // Return NULL (i.e., an error) to our caller 00634 // 00635 00636 return NULL; 00637 }

VOID LpcpClosePort IN PEPROCESS Process  OPTIONAL,
IN PVOID  Object,
IN ACCESS_MASK  GrantedAccess,
IN ULONG  ProcessHandleCount,
IN ULONG  SystemHandleCount
 

Definition at line 31 of file lpcclose.c.

References FALSE, _LPCP_PORT_OBJECT::Flags, LpcpDestroyPortQueue(), PORT_TYPE, SERVER_CONNECTION_PORT, and TRUE.

Referenced by LpcInitSystem().

00041 : 00042 00043 This routine is the callback used for closing a port object. 00044 00045 Arguments: 00046 00047 Process - Supplies an optional pointer to the process whose port is being 00048 closed 00049 00050 Object - Supplies a pointer to the port object being closed 00051 00052 GrantedAccess - Supplies the access granted to the handle closing port 00053 object 00054 00055 ProcessHandleCount - Supplies the number of process handles remaining to 00056 the object 00057 00058 SystemHandleCount - Supplies the number of system handles remaining to 00059 the object 00060 00061 Return Value: 00062 00063 None. 00064 00065 --*/ 00066 00067 { 00068 // 00069 // Translate the object to what it really is, an LPCP port object 00070 // 00071 00072 PLPCP_PORT_OBJECT Port = Object; 00073 00074 // 00075 // We only have work to do if the object is a server communication port 00076 // 00077 00078 if ( (Port->Flags & PORT_TYPE) == SERVER_CONNECTION_PORT ) { 00079 00080 // 00081 // If this is a server commucation port without any system handles 00082 // then we can completely destroy the communication queue for the 00083 // port 00084 // 00085 00086 if ( SystemHandleCount == 0 ) { 00087 00088 LpcpDestroyPortQueue( Port, TRUE ); 00089 00090 // 00091 // If there is only one system handle left then we'll reset the 00092 // communication queue for the port 00093 // 00094 00095 } else if ( SystemHandleCount == 1 ) { 00096 00097 LpcpDestroyPortQueue( Port, FALSE ); 00098 } 00099 00100 // 00101 // Otherwise we do nothing 00102 // 00103 } 00104 00105 return; 00106 }

VOID LpcpDeletePort IN PVOID  Object  ) 
 

Definition at line 110 of file lpcclose.c.

References CLIENT_COMMUNICATION_PORT, _LPCP_PORT_OBJECT::ClientSectionBase, _LPCP_PORT_OBJECT::ClientThread, ClientThread(), _LPCP_PORT_OBJECT::ConnectionPort, _LPCP_MESSAGE::Entry, _LPCP_PORT_OBJECT::Flags, _LPCP_PORT_OBJECT::LpcDataInfoChainHead, LpcpAcquireLpcpLock, LpcpDestroyPortQueue(), LpcpFreePortClientSecurity(), LpcpFreeToPortZone(), LpcpPortExtraDataDestroy, LpcpReleaseLpcpLock, LpcpTrace, LpcRequestPort(), MmUnmapViewOfSection(), NULL, ObDereferenceObject, PAGED_CODE, PORT_TYPE, PsGetCurrentProcess, PsGetCurrentThread, _LPCP_MESSAGE::Request, SERVER_COMMUNICATION_PORT, SERVER_CONNECTION_PORT, _LPCP_PORT_OBJECT::ServerProcess, _LPCP_PORT_OBJECT::ServerSectionBase, and TRUE.

Referenced by LpcInitSystem().

00116 : 00117 00118 This routine is the callback used for deleting a port object. 00119 00120 Arguments: 00121 00122 Object - Supplies a pointer to the port object being deleted 00123 00124 Return Value: 00125 00126 None. 00127 00128 --*/ 00129 00130 { 00131 PLPCP_PORT_OBJECT Port = Object; 00132 PLPCP_PORT_OBJECT ConnectionPort; 00133 LPC_CLIENT_DIED_MSG ClientPortClosedDatagram; 00134 PLPCP_MESSAGE Msg; 00135 PLIST_ENTRY Head, Next; 00136 HANDLE CurrentProcessId; 00137 00138 PAGED_CODE(); 00139 00140 // 00141 // If the port is a server communication port then make sure that if 00142 // there is a dangling client thread that we get rid of it. This 00143 // handles the case of someone calling NtAcceptConnectPort and not 00144 // calling NtCompleteConnectPort 00145 // 00146 00147 LpcpPortExtraDataDestroy( Port ); 00148 00149 if ((Port->Flags & PORT_TYPE) == SERVER_COMMUNICATION_PORT) { 00150 00151 PETHREAD ClientThread; 00152 00153 LpcpAcquireLpcpLock(); 00154 00155 if ((ClientThread = Port->ClientThread) != NULL) { 00156 00157 Port->ClientThread = NULL; 00158 00159 LpcpReleaseLpcpLock(); 00160 00161 ObDereferenceObject( ClientThread ); 00162 00163 } else { 00164 00165 LpcpReleaseLpcpLock(); 00166 } 00167 } 00168 00169 // 00170 // Send an LPC_PORT_CLOSED datagram to whoever is connected 00171 // to this port so they know they are no longer connected. 00172 // 00173 00174 if ((Port->Flags & PORT_TYPE) == CLIENT_COMMUNICATION_PORT) { 00175 00176 ClientPortClosedDatagram.PortMsg.u1.s1.TotalLength = sizeof( ClientPortClosedDatagram ); 00177 ClientPortClosedDatagram.PortMsg.u1.s1.DataLength = sizeof( ClientPortClosedDatagram.CreateTime ); 00178 00179 ClientPortClosedDatagram.PortMsg.u2.s2.Type = LPC_PORT_CLOSED; 00180 ClientPortClosedDatagram.PortMsg.u2.s2.DataInfoOffset = 0; 00181 00182 ClientPortClosedDatagram.CreateTime = PsGetCurrentProcess()->CreateTime; 00183 00184 LpcRequestPort( Port, (PPORT_MESSAGE)&ClientPortClosedDatagram ); 00185 } 00186 00187 // 00188 // If connected, disconnect the port, and then scan the message queue 00189 // for this port and dereference any messages in the queue. 00190 // 00191 00192 LpcpDestroyPortQueue( Port, TRUE ); 00193 00194 // 00195 // If the client has a port memory view, then unmap it 00196 // 00197 00198 if (Port->ClientSectionBase != NULL) { 00199 00200 MmUnmapViewOfSection( PsGetCurrentProcess(), 00201 Port->ClientSectionBase ); 00202 00203 } 00204 00205 // 00206 // If the server has a port memory view, then unmap it 00207 // 00208 00209 if (Port->ServerSectionBase != NULL) { 00210 00211 MmUnmapViewOfSection( PsGetCurrentProcess(), 00212 Port->ServerSectionBase ); 00213 00214 } 00215 00216 // 00217 // Dereference the pointer to the connection port if it is not 00218 // this port. 00219 // 00220 00221 if (ConnectionPort = Port->ConnectionPort) { 00222 00223 CurrentProcessId = PsGetCurrentThread()->Cid.UniqueProcess; 00224 00225 LpcpAcquireLpcpLock(); 00226 00227 Head = &ConnectionPort->LpcDataInfoChainHead; 00228 Next = Head->Flink; 00229 00230 while (Next != Head) { 00231 00232 Msg = CONTAINING_RECORD( Next, LPCP_MESSAGE, Entry ); 00233 Next = Next->Flink; 00234 00235 if (Msg->Request.ClientId.UniqueProcess == CurrentProcessId) { 00236 00237 LpcpTrace(( "%s Freeing DataInfo Message %lx (%u.%u) Port: %lx\n", 00238 PsGetCurrentProcess()->ImageFileName, 00239 Msg, 00240 Msg->Request.MessageId, 00241 Msg->Request.CallbackId, 00242 ConnectionPort )); 00243 00244 RemoveEntryList( &Msg->Entry ); 00245 00246 LpcpFreeToPortZone( Msg, TRUE ); 00247 } 00248 } 00249 00250 LpcpReleaseLpcpLock(); 00251 00252 if (ConnectionPort != Port) { 00253 00254 ObDereferenceObject( ConnectionPort ); 00255 } 00256 } 00257 00258 if (((Port->Flags & PORT_TYPE) == SERVER_CONNECTION_PORT) && 00259 (ConnectionPort->ServerProcess != NULL)) { 00260 00261 ObDereferenceObject( ConnectionPort->ServerProcess ); 00262 00263 ConnectionPort->ServerProcess = NULL; 00264 } 00265 00266 // 00267 // Free any static client security context 00268 // 00269 00270 LpcpFreePortClientSecurity( Port ); 00271 00272 // 00273 // And return to our caller 00274 // 00275 00276 return; 00277 }

VOID LpcpDestroyPortQueue IN PLPCP_PORT_OBJECT  Port,
IN BOOLEAN  CleanupAndDestroy
 

Definition at line 104 of file lpcqueue.c.

References _LPCP_MESSAGE::Entry, ExFreePool(), FALSE, KeReadStateSemaphore(), KeReleaseSemaphore(), L, _ETHREAD::LpcExitThreadCalled, LpcpAcquireLpcpLock, LpcpFreeToPortZone(), LpcpReleaseLpcpLock, _ETHREAD::LpcReplyChain, _ETHREAD::LpcReplyMessage, _ETHREAD::LpcReplyMessageId, _ETHREAD::LpcReplySemaphore, NULL, ObDereferenceObject, PAGED_CODE, PORT_NAME_DELETED, PORT_TYPE, _LPCP_MESSAGE::Request, _LPCP_CONNECTION_MESSAGE::SectionToMap, SERVER_CONNECTION_PORT, and TRUE.

Referenced by LpcpClosePort(), and LpcpDeletePort().

00111 : 00112 00113 This routine is used to teardown the message queue of a port object. 00114 After running this message will either be empty (like it was just 00115 initialized) or completly gone (needs to be initialized) 00116 00117 Arguments: 00118 00119 Port - Supplies the port containing the message queue being modified 00120 00121 CleanupAndDestroy - Specifies if the message queue should be set back 00122 to the freshly initialized state (value of FALSE) or completely 00123 torn down (value of TRUE) 00124 00125 Return Value: 00126 00127 None. 00128 00129 --*/ 00130 00131 { 00132 PLIST_ENTRY Next, Head; 00133 PETHREAD ThreadWaitingForReply; 00134 PLPCP_MESSAGE Msg; 00135 00136 PAGED_CODE(); 00137 00138 // 00139 // If this port is connected to another port, then disconnect it. 00140 // Protect this with a lock in case the other side is going away 00141 // at the same time. 00142 // 00143 00144 LpcpAcquireLpcpLock(); 00145 00146 if (Port->ConnectedPort != NULL) { 00147 00148 Port->ConnectedPort->ConnectedPort = NULL; 00149 } 00150 00151 // 00152 // If connection port, then mark name as deleted 00153 // 00154 00155 if ((Port->Flags & PORT_TYPE) == SERVER_CONNECTION_PORT) { 00156 00157 Port->Flags |= PORT_NAME_DELETED; 00158 } 00159 00160 // 00161 // Walk list of threads waiting for a reply to a message sent to this 00162 // port. Signal each thread's LpcReplySemaphore to wake them up. They 00163 // will notice that there was no reply and return 00164 // STATUS_PORT_DISCONNECTED 00165 // 00166 00167 Head = &Port->LpcReplyChainHead; 00168 Next = Head->Flink; 00169 00170 while ((Next != NULL) && (Next != Head)) { 00171 00172 ThreadWaitingForReply = CONTAINING_RECORD( Next, ETHREAD, LpcReplyChain ); 00173 00174 // 00175 // If the thread is exiting, in the location of LpcReplyChain is stored the ExitTime 00176 // We'll stop to search throught the list. 00177 00178 if ( ThreadWaitingForReply->LpcExitThreadCalled ) { 00179 00180 break; 00181 } 00182 00183 Next = Next->Flink; 00184 00185 RemoveEntryList( &ThreadWaitingForReply->LpcReplyChain ); 00186 00187 InitializeListHead( &ThreadWaitingForReply->LpcReplyChain ); 00188 00189 if (!KeReadStateSemaphore( &ThreadWaitingForReply->LpcReplySemaphore )) { 00190 00191 // 00192 // Thread is waiting on a message. Signal the semaphore and free 00193 // the message 00194 // 00195 00196 Msg = ThreadWaitingForReply->LpcReplyMessage; 00197 00198 if ( Msg ) { 00199 00200 // 00201 // If the message is a connection request and has a section object 00202 // attached, then dereference that section object 00203 // 00204 00205 if ((Msg->Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE) == LPC_CONNECTION_REQUEST) { 00206 00207 PLPCP_CONNECTION_MESSAGE ConnectMsg; 00208 00209 ConnectMsg = (PLPCP_CONNECTION_MESSAGE)(Msg + 1); 00210 00211 if ( ConnectMsg->SectionToMap != NULL ) { 00212 00213 ObDereferenceObject( ConnectMsg->SectionToMap ); 00214 } 00215 } 00216 00217 ThreadWaitingForReply->LpcReplyMessage = NULL; 00218 00219 LpcpFreeToPortZone( Msg, TRUE ); 00220 } 00221 00222 ThreadWaitingForReply->LpcReplyMessageId = 0; 00223 00224 KeReleaseSemaphore( &ThreadWaitingForReply->LpcReplySemaphore, 00225 0, 00226 1L, 00227 FALSE ); 00228 } 00229 } 00230 00231 InitializeListHead( &Port->LpcReplyChainHead ); 00232 00233 // 00234 // Walk list of messages queued to this port. Remove each message from 00235 // the list and free it. 00236 // 00237 00238 Head = &Port->MsgQueue.ReceiveHead; 00239 Next = Head->Flink; 00240 00241 while ((Next != NULL) && (Next != Head)) { 00242 00243 Msg = CONTAINING_RECORD( Next, LPCP_MESSAGE, Entry ); 00244 00245 Next = Next->Flink; 00246 00247 InitializeListHead( &Msg->Entry ); 00248 00249 LpcpFreeToPortZone( Msg, TRUE ); 00250 } 00251 00252 // 00253 // Reinitialize the message queue 00254 // 00255 00256 InitializeListHead( &Port->MsgQueue.ReceiveHead ); 00257 00258 LpcpReleaseLpcpLock(); 00259 00260 // 00261 // Check if the caller wants it all to go away 00262 // 00263 00264 if ( CleanupAndDestroy ) { 00265 00266 // 00267 // Free semaphore associated with the queue. 00268 // 00269 00270 if (Port->MsgQueue.Semaphore != NULL) { 00271 00272 ExFreePool( CONTAINING_RECORD( Port->MsgQueue.Semaphore, 00273 LPCP_NONPAGED_PORT_QUEUE, 00274 Semaphore )); 00275 } 00276 } 00277 00278 // 00279 // And return to our caller 00280 // 00281 00282 return; 00283 }

NTSTATUS LpcpExtendPortZone VOID   ) 
 

Definition at line 397 of file lpcqueue.c.

References _ZONE_HEADER::BlockSize, ExAllocatePoolWithTag, Executive, ExExtendZone(), ExFreePool(), FALSE, _LPCP_PORT_ZONE::FreeEvent, _LPCP_PORT_ZONE::GrowSize, KernelMode, KeSetEvent(), KeWaitForSingleObject(), LPC_RELEASE_WAIT_INCREMENT, LpcpAcquireLpcpLock, LpcpPrint, LpcpReleaseLpcpLock, LpcpTrace, LpcpZone, _LPCP_PORT_ZONE::MaxPoolUsage, NT_SUCCESS, NTSTATUS(), NULL, PAGE_SIZE, PAGED_CODE, PagedPool, Status, _ZONE_HEADER::TotalSegmentSize, TRUE, USHORT, _LPCP_PORT_ZONE::Zone, and _LPCP_MESSAGE::ZoneIndex.

Referenced by LpcpAllocateFromPortZone().

00403 : 00404 00405 This routine is used to increase the size of the global port zone. 00406 00407 Note that our caller must have already acquired the LpcpLock mutex. 00408 00409 Arguments: 00410 00411 None. 00412 00413 Return Value: 00414 00415 NTSTATUS - An appropriate status value 00416 00417 --*/ 00418 00419 { 00420 NTSTATUS Status; 00421 PVOID Segment; 00422 PLPCP_MESSAGE Msg; 00423 LARGE_INTEGER WaitTimeout; 00424 BOOLEAN AlreadyRetried; 00425 LONG SegmentSize; 00426 00427 PAGED_CODE(); 00428 00429 AlreadyRetried = FALSE; 00430 00431 retry: 00432 00433 // 00434 // If we're going to grow across a threshold, we should wait a little in case 00435 // an entry gets freed. 00436 // 00437 00438 if ((LpcpZone.Zone.TotalSegmentSize + LpcpZone.GrowSize) > LpcpZone.MaxPoolUsage) { 00439 00440 LpcpPrint(( "Out of space in global LPC zone - current size is %08x\n", 00441 LpcpZone.Zone.TotalSegmentSize )); 00442 00443 // 00444 // Wait time is 1 second. 00445 // 00446 // We'll actually only go through this path once because on retry we 00447 // bump up max pool usage to avoid this wait 00448 // 00449 00450 WaitTimeout.QuadPart = Int32x32To64( 1000, -10000 ); 00451 00452 LpcpReleaseLpcpLock(); 00453 00454 Status = KeWaitForSingleObject( &LpcpZone.FreeEvent, 00455 Executive, 00456 KernelMode, 00457 FALSE, 00458 &WaitTimeout ); 00459 00460 LpcpAcquireLpcpLock(); 00461 00462 if (Status != STATUS_SUCCESS) { 00463 00464 LpcpPrint(( "Error waiting for %lx->FreeEvent - Status == %X\n", 00465 &LpcpZone, 00466 Status )); 00467 00468 if ( !AlreadyRetried ) { 00469 00470 AlreadyRetried = TRUE; 00471 00472 LpcpZone.MaxPoolUsage += LpcpZone.GrowSize; 00473 00474 goto retry; 00475 } 00476 } 00477 00478 // 00479 // return to our caller and let the caller retry the allocation 00480 // again 00481 // 00482 00483 return Status; 00484 } 00485 00486 // 00487 // We need to extend the zone, so allocate another chunk and add it 00488 // to the zone 00489 // 00490 00491 Segment = ExAllocatePoolWithTag( PagedPool, LpcpZone.GrowSize, 'ZcpL' ); 00492 00493 if (Segment == NULL) { 00494 00495 return STATUS_INSUFFICIENT_RESOURCES; 00496 } 00497 00498 Status = ExExtendZone( &LpcpZone.Zone, 00499 Segment, 00500 LpcpZone.GrowSize ); 00501 00502 if (!NT_SUCCESS( Status )) { 00503 00504 ExFreePool( Segment ); 00505 } 00506 00507 #if DEVL 00508 00509 else { 00510 00511 LpcpTrace(( "Extended LPC zone by %x for a total of %x\n", 00512 LpcpZone.GrowSize, LpcpZone.Zone.TotalSegmentSize )); 00513 00514 // 00515 // The following code sets up each msg in the zone by filling in its 00516 // index, and zeroing the rest. 00517 // 00518 // **** note, this is really a backdoor piece of code. First, it assumes 00519 // we grew by one page, and second, it assume the zone doesn't touch 00520 // those fields for its own bookkeeping. 00521 // 00522 00523 SegmentSize = PAGE_SIZE; 00524 00525 Msg = (PLPCP_MESSAGE)((PZONE_SEGMENT_HEADER)Segment + 1); 00526 00527 while (SegmentSize >= (LONG)LpcpZone.Zone.BlockSize) { 00528 00529 Msg->ZoneIndex = (USHORT)++LpcpTotalNumberOfMessages; 00530 00531 Msg = (PLPCP_MESSAGE)((PCHAR)Msg + LpcpZone.Zone.BlockSize); 00532 00533 SegmentSize -= LpcpZone.Zone.BlockSize; 00534 } 00535 00536 // 00537 // Now that we've completely initialized the new segment, go 00538 // and wake up any waiters 00539 // 00540 00541 LpcpReleaseLpcpLock(); 00542 00543 KeSetEvent( &LpcpZone.FreeEvent, 00544 LPC_RELEASE_WAIT_INCREMENT, 00545 FALSE ); 00546 00547 LpcpAcquireLpcpLock(); 00548 } 00549 00550 #endif 00551 00552 return Status; 00553 }

PLPCP_MESSAGE LpcpFindDataInfoMessage IN PLPCP_PORT_OBJECT  Port,
IN ULONG  MessageId,
IN ULONG  CallbackId
 

Definition at line 980 of file lpcqueue.c.

References LpcpTrace, NULL, PAGED_CODE, PORT_TYPE, PsGetCurrentProcess, _LPCP_MESSAGE::Request, and UNCONNECTED_COMMUNICATION_PORT.

Referenced by LpcpCopyRequestData().

00988 : 00989 00990 This routine is used to locate a specific message stored off the 00991 data info chain of a port 00992 00993 Arguments: 00994 00995 Port - Supplies the port being examined 00996 00997 MessageId - Supplies the ID of the message being searched for 00998 00999 CallbackId - Supplies the callback ID being searched for 01000 01001 Return Value: 01002 01003 PLPCP_MESSAGE - returns a pointer to the message satisfying the 01004 search criteria or NULL of none was found 01005 01006 --*/ 01007 01008 { 01009 PLPCP_MESSAGE Msg; 01010 PLIST_ENTRY Head, Next; 01011 01012 PAGED_CODE(); 01013 01014 // 01015 // Make sure we get to the connection port object of this port 01016 // 01017 01018 if ((Port->Flags & PORT_TYPE) > UNCONNECTED_COMMUNICATION_PORT) { 01019 01020 Port = Port->ConnectionPort; 01021 } 01022 01023 // 01024 // Zoom down the data info chain for the connection port object looking 01025 // for a match 01026 // 01027 01028 Head = &Port->LpcDataInfoChainHead; 01029 Next = Head->Flink; 01030 01031 while (Next != Head) { 01032 01033 Msg = CONTAINING_RECORD( Next, LPCP_MESSAGE, Entry ); 01034 01035 if ((Msg->Request.MessageId == MessageId) && 01036 (Msg->Request.CallbackId == CallbackId)) { 01037 01038 LpcpTrace(( "%s Found DataInfo Message %lx (%u.%u) Port: %lx\n", 01039 PsGetCurrentProcess()->ImageFileName, 01040 Msg, 01041 Msg->Request.MessageId, 01042 Msg->Request.CallbackId, 01043 Port )); 01044 01045 return Msg; 01046 01047 } else { 01048 01049 Next = Next->Flink; 01050 } 01051 } 01052 01053 // 01054 // We did not find a match so return null to our caller 01055 // 01056 01057 LpcpTrace(( "%s Unable to find DataInfo Message (%u.%u) Port: %lx\n", 01058 PsGetCurrentProcess()->ImageFileName, 01059 MessageId, 01060 CallbackId, 01061 Port )); 01062 01063 return NULL; 01064 } }

VOID LpcpFreeDataInfoMessage IN PLPCP_PORT_OBJECT  Port,
IN ULONG  MessageId,
IN ULONG  CallbackId
 

Definition at line 879 of file lpcqueue.c.

References _LPCP_MESSAGE::Entry, LpcpFreeToPortZone(), LpcpTrace, PAGED_CODE, PORT_TYPE, PsGetCurrentProcess, _LPCP_MESSAGE::Request, TRUE, and UNCONNECTED_COMMUNICATION_PORT.

Referenced by NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), and NtReplyWaitReplyPort().

00887 : 00888 00889 This routine is used to free up a saved message in a port 00890 00891 Arguments: 00892 00893 Port - Supplies the port being manipulated 00894 00895 MessageId - Supplies the id of the message being freed 00896 00897 CallbackId - Supplies the callback id of the message being freed 00898 00899 Return Value: 00900 00901 None. 00902 00903 --*/ 00904 00905 { 00906 PLPCP_MESSAGE Msg; 00907 PLIST_ENTRY Head, Next; 00908 00909 PAGED_CODE(); 00910 00911 // 00912 // Make sure we get to the connection port object of this port 00913 // 00914 00915 if ((Port->Flags & PORT_TYPE) > UNCONNECTED_COMMUNICATION_PORT) { 00916 00917 Port = Port->ConnectionPort; 00918 } 00919 00920 // 00921 // Zoom down the data info chain for the connection port object 00922 // 00923 00924 Head = &Port->LpcDataInfoChainHead; 00925 Next = Head->Flink; 00926 00927 while (Next != Head) { 00928 00929 Msg = CONTAINING_RECORD( Next, LPCP_MESSAGE, Entry ); 00930 00931 // 00932 // If this message matches the callers specification then remove 00933 // this message, free it back to the port zone, and return back 00934 // to our caller 00935 // 00936 00937 if ((Msg->Request.MessageId == MessageId) && 00938 (Msg->Request.CallbackId == CallbackId)) { 00939 00940 LpcpTrace(( "%s Removing DataInfo Message %lx (%u.%u) Port: %lx\n", 00941 PsGetCurrentProcess()->ImageFileName, 00942 Msg, 00943 Msg->Request.MessageId, 00944 Msg->Request.CallbackId, 00945 Port )); 00946 00947 RemoveEntryList( &Msg->Entry ); 00948 00949 InitializeListHead( &Msg->Entry ); 00950 00951 LpcpFreeToPortZone( Msg, TRUE ); 00952 00953 return; 00954 00955 } else { 00956 00957 // 00958 // Keep on going down the data info chain 00959 // 00960 00961 Next = Next->Flink; 00962 } 00963 } 00964 00965 // 00966 // We didn't find a match so just return to our caller 00967 // 00968 00969 LpcpTrace(( "%s Unable to find DataInfo Message (%u.%u) Port: %lx\n", 00970 PsGetCurrentProcess()->ImageFileName, 00971 MessageId, 00972 CallbackId, 00973 Port )); 00974 00975 return; 00976 }

VOID LpcpFreePortClientSecurity IN PLPCP_PORT_OBJECT  Port  ) 
 

Definition at line 296 of file lpcpriv.c.

References CLIENT_COMMUNICATION_PORT, PORT_DYNAMIC_SECURITY, PORT_TYPE, and SeDeleteClientSecurity.

Referenced by LpcpDeletePort().

00302 : 00303 00304 This routine cleans up the captured security context for a client port. 00305 The cleanup is typically done when we are deleting a port 00306 00307 Arguments: 00308 00309 Port - Supplies the client port being deleted 00310 00311 Return Value: 00312 00313 None. 00314 00315 --*/ 00316 00317 { 00318 // 00319 // We only do this action if supplied with a client communication port 00320 // 00321 00322 if ((Port->Flags & PORT_TYPE) == CLIENT_COMMUNICATION_PORT) { 00323 00324 // 00325 // We only do this action if the port has static security tracking, 00326 // and we have a captured client token. The action is to simply 00327 // delete the client token. 00328 // 00329 00330 if (!(Port->Flags & PORT_DYNAMIC_SECURITY)) { 00331 00332 if ( Port->StaticSecurity.ClientToken ) { 00333 00334 SeDeleteClientSecurity( &(Port)->StaticSecurity ); 00335 } 00336 } 00337 } 00338 00339 // 00340 // And return to our caller 00341 // 00342 00343 return; 00344 } }

VOID FASTCALL LpcpFreeToPortZone IN PLPCP_MESSAGE  Msg,
IN BOOLEAN  MutexOwned
 

Definition at line 642 of file lpcqueue.c.

References _LPCP_CONNECTION_MESSAGE::ClientPort, ExFreeToZone, FALSE, _LPCP_PORT_ZONE::FreeEvent, KeSetEvent(), LPC_RELEASE_WAIT_INCREMENT, LpcpAcquireLpcpLock, LpcpPrint, LpcpReleaseLpcpLock, LpcpTrace, LpcpZone, NULL, ObDereferenceObject, PAGED_CODE, and _LPCP_PORT_ZONE::Zone.

Referenced by LpcExitThread(), LpcpDeletePort(), LpcpDestroyPortQueue(), LpcpFreeDataInfoMessage(), LpcRequestPort(), LpcRequestWaitReplyPort(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtRequestPort(), NtRequestWaitReplyPort(), and NtSecureConnectPort().

00649 : 00650 00651 This routine is used to free an old msg back to the global message queue 00652 00653 Arguments: 00654 00655 Msg - Supplies the message being returned 00656 00657 MutexOwned - Specifies if the LpcpLock is already owned by the caller 00658 00659 Return Value: 00660 00661 None. 00662 00663 --*/ 00664 00665 { 00666 BOOLEAN ZoneMemoryAvailable = FALSE; 00667 PLPCP_CONNECTION_MESSAGE ConnectMsg; 00668 00669 PAGED_CODE(); 00670 00671 // 00672 // Take out the global lock if necessary 00673 // 00674 00675 if (!MutexOwned) { 00676 00677 LpcpAcquireLpcpLock(); 00678 } 00679 00680 LpcpTrace(( "Free Msg %lx\n", Msg )); 00681 00682 #if DBG 00683 00684 // 00685 // In the debug case if the message is not allocated then it's an error 00686 // 00687 00688 if (!(Msg->ZoneIndex & LPCP_ZONE_MESSAGE_ALLOCATED)) { 00689 00690 LpcpPrint(( "Msg %lx has already been freed.\n", Msg )); 00691 DbgBreakPoint(); 00692 00693 if (!MutexOwned) { 00694 00695 LpcpReleaseLpcpLock(); 00696 } 00697 00698 return; 00699 } 00700 00701 Msg->ZoneIndex &= ~LPCP_ZONE_MESSAGE_ALLOCATED; 00702 00703 #endif 00704 00705 // 00706 // The non zero reserved0 field tells us that the message has been used 00707 // 00708 00709 if (Msg->Reserved0 != 0) { 00710 00711 // 00712 // A entry field connects the message to the message queue of the 00713 // owning port object. If not already removed then remove this 00714 // message 00715 // 00716 00717 if (!IsListEmpty( &Msg->Entry )) { 00718 00719 RemoveEntryList( &Msg->Entry ); 00720 00721 InitializeListHead( &Msg->Entry ); 00722 } 00723 00724 // 00725 // If the replied to thread is not null then we have a reference 00726 // to the thread that we should now remove 00727 // 00728 00729 if (Msg->RepliedToThread != NULL) { 00730 00731 ObDereferenceObject( Msg->RepliedToThread ); 00732 00733 Msg->RepliedToThread = NULL; 00734 } 00735 00736 // 00737 // If the msg was for a connection request then we know that 00738 // right after the lpcp message is a connection message whose 00739 // client port field might need to be dereferenced 00740 // 00741 00742 if ((Msg->Request.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE) == LPC_CONNECTION_REQUEST) { 00743 00744 ConnectMsg = (PLPCP_CONNECTION_MESSAGE)(Msg + 1); 00745 00746 if (ConnectMsg->ClientPort) { 00747 00748 PLPCP_PORT_OBJECT ClientPort; 00749 00750 // 00751 // Capture a pointer to the client port then null it 00752 // out so that no one else can use it, then release 00753 // lpcp lock before we dereference the client port 00754 // 00755 00756 ClientPort = ConnectMsg->ClientPort; 00757 00758 ConnectMsg->ClientPort = NULL; 00759 00760 LpcpReleaseLpcpLock(); 00761 00762 ObDereferenceObject( ClientPort ); 00763 00764 LpcpAcquireLpcpLock(); 00765 } 00766 } 00767 00768 // 00769 // Now mark this message a free, and return it to the zone 00770 // 00771 00772 Msg->Reserved0 = 0; 00773 ZoneMemoryAvailable = (BOOLEAN)(ExFreeToZone( &LpcpZone.Zone, &Msg->FreeEntry ) == NULL); 00774 } 00775 00776 // 00777 // Check if we need to release the global lpcp lock 00778 // 00779 00780 if (!MutexOwned) { 00781 00782 LpcpReleaseLpcpLock(); 00783 } 00784 00785 // 00786 // If we've actually freed up memory then go wake any waiting allocators 00787 // 00788 // **** does this need to check to see if it owns the lpcp lock. The 00789 // release right above us and this test and set event should be 00790 // combined 00791 // 00792 00793 if (ZoneMemoryAvailable) { 00794 00795 KeSetEvent( &LpcpZone.FreeEvent, 00796 LPC_RELEASE_WAIT_INCREMENT, 00797 FALSE ); 00798 } 00799 00800 // 00801 // And return to our caller 00802 // 00803 00804 return; 00805 }

char* LpcpGetCreatorName PLPCP_PORT_OBJECT  PortObject  ) 
 

Definition at line 193 of file lpcinit.c.

References _LPCP_PORT_OBJECT::Creator, _EPROCESS::ImageFileName, NT_SUCCESS, NTSTATUS(), PsLookupProcessByProcessId(), and Status.

Referenced by LpcRequestPort(), LpcRequestWaitReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtRequestPort(), and NtRequestWaitReplyPort().

00199 : 00200 00201 This routine returns the name of the process that created the specified 00202 port object 00203 00204 Arguments: 00205 00206 PortObject - Supplies the port object being queried 00207 00208 Return Value: 00209 00210 char * - The image name of the process that created the port process 00211 00212 --*/ 00213 00214 { 00215 NTSTATUS Status; 00216 PEPROCESS Process; 00217 00218 // 00219 // First find the process that created the port object 00220 // 00221 00222 Status = PsLookupProcessByProcessId( PortObject->Creator.UniqueProcess, &Process ); 00223 00224 // 00225 // If we were able to get the process then return the name of the process 00226 // to our caller 00227 // 00228 00229 if (NT_SUCCESS( Status )) { 00230 00231 return Process->ImageFileName; 00232 00233 } else { 00234 00235 // 00236 // Otherwise tell our caller we don't know the name 00237 // 00238 00239 return "Unknown"; 00240 } 00241 }

NTSTATUS LpcpInitializePortQueue IN PLPCP_PORT_OBJECT  Port  ) 
 

Definition at line 37 of file lpcqueue.c.

References _LPCP_NONPAGED_PORT_QUEUE::BackPointer, ExAllocatePoolWithTag, KeInitializeSemaphore(), _LPCP_PORT_OBJECT::MsgQueue, NonPagedPool, NULL, PAGED_CODE, _LPCP_NONPAGED_PORT_QUEUE::Semaphore, and _LPCP_PORT_QUEUE::Semaphore.

Referenced by LpcpCreatePort(), and NtSecureConnectPort().

00043 : 00044 00045 This routine is used to initialize the message queue for a port object. 00046 00047 Arguments: 00048 00049 Port - Supplies the port object being initialized 00050 00051 Return Value: 00052 00053 NTSTATUS - An appropriate status value 00054 00055 --*/ 00056 00057 { 00058 PLPCP_NONPAGED_PORT_QUEUE NonPagedPortQueue; 00059 00060 PAGED_CODE(); 00061 00062 // 00063 // Allocate space for the port queue 00064 // 00065 00066 NonPagedPortQueue = ExAllocatePoolWithTag( NonPagedPool, 00067 sizeof(LPCP_NONPAGED_PORT_QUEUE), 00068 'troP' ); 00069 00070 if (NonPagedPortQueue == NULL) { 00071 00072 return STATUS_INSUFFICIENT_RESOURCES; 00073 } 00074 00075 // 00076 // Initialize the fields in the non paged port queue 00077 // 00078 00079 KeInitializeSemaphore( &NonPagedPortQueue->Semaphore, 0, 0x7FFFFFFF ); 00080 00081 NonPagedPortQueue->BackPointer = Port; 00082 00083 // 00084 // Have the port msg queue point to the non nonpaged port queue 00085 // 00086 00087 Port->MsgQueue.Semaphore = &NonPagedPortQueue->Semaphore; 00088 00089 // 00090 // Initailize the port msg queue to be empty 00091 // 00092 00093 InitializeListHead( &Port->MsgQueue.ReceiveHead ); 00094 00095 // 00096 // And return to our caller 00097 // 00098 00099 return STATUS_SUCCESS; 00100 }

NTSTATUS LpcpInitializePortZone IN ULONG  MaxEntrySize,
IN ULONG  SegmentSize,
IN ULONG  MaxPoolUsage
 

Definition at line 287 of file lpcqueue.c.

References _ZONE_HEADER::BlockSize, ExAllocatePoolWithTag, ExFreePool(), ExInitializeZone(), FALSE, _LPCP_PORT_ZONE::FreeEvent, _LPCP_PORT_ZONE::GrowSize, KeInitializeEvent, LpcpZone, _LPCP_PORT_ZONE::MaxPoolUsage, NT_SUCCESS, NTSTATUS(), NULL, PAGE_SIZE, PAGED_CODE, PagedPool, _LPCP_MESSAGE::Request, _LPCP_MESSAGE::Reserved0, Status, USHORT, _LPCP_PORT_ZONE::Zone, and _LPCP_MESSAGE::ZoneIndex.

Referenced by LpcInitSystem().

00295 : 00296 00297 This routine only executes once. It is used to initialize the zone 00298 allocator for LPC messages 00299 00300 Arguments: 00301 00302 MaxEntrySize - Specifies the maximum size, in bytes, that we'll allocate 00303 from the zone. 00304 00305 SegmentSize - Specifies the number of total bytes to use in the initial 00306 zone allocation. This is also the increment use to grow the zone. 00307 00308 MaxPoolUsage - Specifies the maximum number of bytes we every want to 00309 zone to grow to. 00310 00311 Return Value: 00312 00313 NTSTATUS - An appropriate status value 00314 00315 --*/ 00316 00317 { 00318 NTSTATUS Status; 00319 PVOID Segment; 00320 PLPCP_MESSAGE Msg; 00321 LONG SegSize; 00322 00323 PAGED_CODE(); 00324 00325 // 00326 // Set the sizes in the global port zone variable 00327 // 00328 00329 LpcpZone.MaxPoolUsage = MaxPoolUsage; 00330 LpcpZone.GrowSize = SegmentSize; 00331 00332 // 00333 // Allocate and initialize the initial zone 00334 // 00335 00336 Segment = ExAllocatePoolWithTag( PagedPool, SegmentSize, 'ZcpL' ); 00337 00338 if (Segment == NULL) { 00339 00340 return STATUS_INSUFFICIENT_RESOURCES; 00341 } 00342 00343 KeInitializeEvent( &LpcpZone.FreeEvent, SynchronizationEvent, FALSE ); 00344 00345 Status = ExInitializeZone( &LpcpZone.Zone, 00346 MaxEntrySize, 00347 Segment, 00348 SegmentSize ); 00349 00350 if (!NT_SUCCESS( Status )) { 00351 00352 ExFreePool( Segment ); 00353 } 00354 00355 // 00356 // The following code sets up each msg in the zone by filling in its 00357 // index, and zeroing the rest. 00358 // 00359 // **** note, this is really a backdoor piece of code. First, it assumes 00360 // segsize is pagesize, and second, it assume the zone doesn't touch 00361 // those fields for its own bookkeeping. 00362 // 00363 00364 SegSize = PAGE_SIZE; 00365 LpcpTotalNumberOfMessages = 0; 00366 00367 // 00368 // Skip over the segment header 00369 // 00370 00371 Msg = (PLPCP_MESSAGE)((PZONE_SEGMENT_HEADER)Segment + 1); 00372 00373 // 00374 // For each block in the zone pointed at by Msg, pre-initialize the Msg 00375 // 00376 00377 while (SegSize >= (LONG)LpcpZone.Zone.BlockSize) { 00378 00379 Msg->ZoneIndex = (USHORT)++LpcpTotalNumberOfMessages; 00380 Msg->Reserved0 = 0; 00381 Msg->Request.MessageId = 0; 00382 00383 Msg = (PLPCP_MESSAGE)((PCHAR)Msg + LpcpZone.Zone.BlockSize); 00384 00385 SegSize -= LpcpZone.Zone.BlockSize; 00386 } 00387 00388 // 00389 // And return to our caller 00390 // 00391 00392 return Status; 00393 }

VOID LpcpMoveMessage OUT PPORT_MESSAGE  DstMsg,
IN PPORT_MESSAGE  SrcMsg,
IN PVOID  SrcMsgData,
IN ULONG MsgType  OPTIONAL,
IN PCLIENT_ID ClientId  OPTIONAL
 

Referenced by LpcRequestPort(), LpcRequestWaitReplyPort(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtRequestPort(), and NtRequestWaitReplyPort().

VOID LpcpSaveDataInfoMessage IN PLPCP_PORT_OBJECT  Port,
PLPCP_MESSAGE  Msg
 

Definition at line 809 of file lpcqueue.c.

References _LPCP_MESSAGE::Entry, LpcpAcquireLpcpLock, LpcpReleaseLpcpLock, LpcpTrace, PAGED_CODE, PORT_TYPE, PsGetCurrentProcess, _LPCP_MESSAGE::Request, and UNCONNECTED_COMMUNICATION_PORT.

Referenced by NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), and NtRequestWaitReplyPort().

00816 : 00817 00818 This routine is used in place of freeing a message and instead saves the 00819 message off a seperate queue from the port. 00820 00821 Arguments: 00822 00823 Port - Specifies the port object under which to save this message 00824 00825 Msg - Supplies the message being saved 00826 00827 Return Value: 00828 00829 None. 00830 00831 --*/ 00832 00833 { 00834 PAGED_CODE(); 00835 00836 // 00837 // Take out the global lock 00838 // 00839 00840 LpcpAcquireLpcpLock(); 00841 00842 // 00843 // Make sure we get to the connection port object of this port 00844 // 00845 00846 if ((Port->Flags & PORT_TYPE) > UNCONNECTED_COMMUNICATION_PORT) { 00847 00848 Port = Port->ConnectionPort; 00849 } 00850 00851 LpcpTrace(( "%s Saving DataInfo Message %lx (%u.%u) Port: %lx\n", 00852 PsGetCurrentProcess()->ImageFileName, 00853 Msg, 00854 Msg->Request.MessageId, 00855 Msg->Request.CallbackId, 00856 Port )); 00857 00858 // 00859 // Enqueue this message onto the data info chain for the port 00860 // 00861 00862 InsertTailList( &Port->LpcDataInfoChainHead, &Msg->Entry ); 00863 00864 // 00865 // Free the global lock 00866 // 00867 00868 LpcpReleaseLpcpLock(); 00869 00870 // 00871 // And return to our caller 00872 // 00873 00874 return; 00875 }


Variable Documentation

LPC_MUTEX LpcpLock
 

Definition at line 63 of file lpcp.h.

ULONG LpcpNextCallbackId
 

Definition at line 69 of file lpcp.h.

Referenced by LpcInitSystem().

ULONG LpcpNextMessageId
 

Definition at line 67 of file lpcp.h.

Referenced by LpcInitSystem().

LPCP_PORT_ZONE LpcpZone
 

Definition at line 65 of file lpcp.h.

Referenced by LpcpAllocateFromPortZone(), LpcpCreatePort(), LpcpExtendPortZone(), LpcpFreeToPortZone(), and LpcpInitializePortZone().


Generated on Sat May 15 19:44:34 2004 for test by doxygen 1.3.7