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

lpcclose.c File Reference

#include "lpcp.h"

Go to the source code of this file.

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)
VOID LpcExitThread (PETHREAD Thread)


Function Documentation

VOID LpcExitThread PETHREAD  Thread  ) 
 

Definition at line 281 of file lpcclose.c.

References _LPCP_MESSAGE::Entry, _ETHREAD::LpcExitThreadCalled, LpcpAcquireLpcpLock, LpcpFreeToPortZone(), LpcpReleaseLpcpLock, LpcpTrace, _ETHREAD::LpcReplyChain, _ETHREAD::LpcReplyMessage, _ETHREAD::LpcReplyMessageId, NULL, ObDereferenceObject, _LPCP_MESSAGE::RepliedToThread, and TRUE.

Referenced by PspExitThread().

00287 : 00288 00289 This routine is called whenever a thread is exiting and need to cleanup the 00290 lpc port for the thread. 00291 00292 Arguments: 00293 00294 Thread - Supplies the thread being terminated 00295 00296 Return Value: 00297 00298 None. 00299 00300 --*/ 00301 00302 { 00303 PLPCP_MESSAGE Msg; 00304 00305 // 00306 // Acquire the mutex that protects the LpcReplyMessage field of 00307 // the thread. Zero the field so nobody else tries to process it 00308 // when we release the lock. 00309 // 00310 00311 LpcpAcquireLpcpLock(); 00312 00313 if (!IsListEmpty( &Thread->LpcReplyChain )) { 00314 00315 RemoveEntryList( &Thread->LpcReplyChain ); 00316 } 00317 00318 // 00319 // Indicate that this thread is exiting 00320 // 00321 00322 Thread->LpcExitThreadCalled = TRUE; 00323 Thread->LpcReplyMessageId = 0; 00324 00325 // 00326 // If we need to reply to a message then if the thread that we need to reply 00327 // to is still around we want to dereference the thread and free the message 00328 // 00329 00330 Msg = Thread->LpcReplyMessage; 00331 00332 if (Msg != NULL) { 00333 00334 Thread->LpcReplyMessage = NULL; 00335 00336 if (Msg->RepliedToThread != NULL) { 00337 00338 ObDereferenceObject( Msg->RepliedToThread ); 00339 00340 Msg->RepliedToThread = NULL; 00341 } 00342 00343 LpcpTrace(( "Cleanup Msg %lx (%d) for Thread %lx allocated\n", Msg, IsListEmpty( &Msg->Entry ), Thread )); 00344 00345 LpcpFreeToPortZone( Msg, TRUE ); 00346 } 00347 00348 // 00349 // Free the global lpc lock 00350 // 00351 00352 LpcpReleaseLpcpLock(); 00353 00354 // 00355 // And return to our caller 00356 // 00357 00358 return; 00359 } }

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, ClientThread(), _LPCP_PORT_OBJECT::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 }


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