00516454bd35cf8c97573973e081fae2e47a519a
[reactos.git] / reactos / ntoskrnl / lpc / close.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/lpc/close.c
6 * PURPOSE: Communication mechanism
7 *
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* FUNCTIONS *****************************************************************/
18
19 /**********************************************************************
20 * NAME
21 *
22 * DESCRIPTION
23 *
24 * ARGUMENTS
25 *
26 * RETURN VALUE
27 *
28 * REVISIONS
29 */
30 VOID STDCALL
31 LpcpClosePort (IN PEPROCESS Process OPTIONAL,
32 IN PVOID ObjectBody,
33 IN ACCESS_MASK GrantedAccess,
34 IN ULONG HandleCount,
35 IN ULONG SystemHandleCount)
36 {
37 PEPORT Port = (PEPORT)ObjectBody;
38 PORT_MESSAGE Message;
39
40 /* FIXME Race conditions here! */
41
42 DPRINT("NiClosePort 0x%p OtherPort 0x%p State %d\n", Port, Port->OtherPort, Port->State);
43
44 /*
45 * If the client has just closed its handle then tell the server what
46 * happened and disconnect this port.
47 */
48 if (HandleCount == 1 && Port->State == EPORT_CONNECTED_CLIENT)
49 {
50 DPRINT("Informing server\n");
51 Message.u1.s1.TotalLength = sizeof(PORT_MESSAGE);
52 Message.u1.s1.DataLength = 0;
53 EiReplyOrRequestPort (Port->OtherPort,
54 &Message,
55 LPC_PORT_CLOSED,
56 Port);
57 Port->OtherPort->OtherPort = NULL;
58 Port->OtherPort->State = EPORT_DISCONNECTED;
59 KeReleaseSemaphore( &Port->OtherPort->Semaphore,
60 IO_NO_INCREMENT,
61 1,
62 FALSE );
63 ObDereferenceObject (Port);
64 }
65
66 /*
67 * If the server has closed all of its handles then disconnect the port,
68 * don't actually notify the client until it attempts an operation.
69 */
70 if (HandleCount == 1 && Port->State == EPORT_CONNECTED_SERVER)
71 {
72 DPRINT("Cleaning up server\n");
73 Port->OtherPort->OtherPort = NULL;
74 Port->OtherPort->State = EPORT_DISCONNECTED;
75 ObDereferenceObject(Port->OtherPort);
76 }
77 }
78
79
80 /**********************************************************************
81 * NAME
82 *
83 * DESCRIPTION
84 *
85 * ARGUMENTS
86 *
87 * RETURN VALUE
88 *
89 * REVISIONS
90 */
91 VOID STDCALL
92 LpcpDeletePort (PVOID ObjectBody)
93 {
94 PLIST_ENTRY Entry;
95 PQUEUEDMESSAGE Message;
96
97 PEPORT Port = (PEPORT)ObjectBody;
98
99 DPRINT("Deleting port %x\n", Port);
100
101 /* Free all waiting messages */
102 while (!IsListEmpty(&Port->QueueListHead))
103 {
104 Entry = RemoveHeadList(&Port->QueueListHead);
105 Message = CONTAINING_RECORD (Entry, QUEUEDMESSAGE, QueueListEntry);
106 ExFreePool(Message);
107 }
108
109 while (!IsListEmpty(&Port->ConnectQueueListHead))
110 {
111 Entry = RemoveHeadList(&Port->ConnectQueueListHead);
112 Message = CONTAINING_RECORD (Entry, QUEUEDMESSAGE, QueueListEntry);
113 ExFreePool(Message);
114 }
115 }
116
117
118 /* EOF */