Sync up to trunk head.
[reactos.git] / subsystems / win32 / win32k / ntuser / csr.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Interface to csrss
6 * FILE: subsys/win32k/ntuser/csr.c
7 * PROGRAMER: Ge van Geldorp (ge@gse.nl)
8 */
9
10 #include <win32k.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 static HANDLE WindowsApiPort = NULL;
16 PEPROCESS CsrProcess = NULL;
17
18 NTSTATUS FASTCALL
19 CsrInit(void)
20 {
21 NTSTATUS Status;
22 UNICODE_STRING PortName;
23 ULONG ConnectInfoLength;
24 SECURITY_QUALITY_OF_SERVICE Qos;
25
26 RtlInitUnicodeString(&PortName, L"\\Windows\\ApiPort");
27 ConnectInfoLength = 0;
28 Qos.Length = sizeof(Qos);
29 Qos.ImpersonationLevel = SecurityDelegation;
30 Qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
31 Qos.EffectiveOnly = FALSE;
32
33 Status = ZwConnectPort(&WindowsApiPort,
34 &PortName,
35 &Qos,
36 NULL,
37 NULL,
38 NULL,
39 NULL,
40 &ConnectInfoLength);
41 if (! NT_SUCCESS(Status))
42 {
43 return Status;
44 }
45
46 CsrProcess = PsGetCurrentProcess();
47
48 return STATUS_SUCCESS;
49 }
50
51
52 NTSTATUS FASTCALL
53 co_CsrNotify(PCSR_API_MESSAGE Request)
54 {
55 NTSTATUS Status;
56 PEPROCESS OldProcess;
57
58 if (NULL == CsrProcess)
59 {
60 return STATUS_INVALID_PORT_HANDLE;
61 }
62
63 Request->Header.u2.ZeroInit = 0;
64 Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
65 Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
66
67 /* Switch to the process in which the WindowsApiPort handle is valid */
68 OldProcess = PsGetCurrentProcess();
69 if (CsrProcess != OldProcess)
70 {
71 KeAttachProcess(&CsrProcess->Pcb);
72 }
73
74 UserLeaveCo();
75
76 Status = ZwRequestWaitReplyPort(WindowsApiPort,
77 &Request->Header,
78 &Request->Header);
79
80 UserEnterCo();
81
82 if (CsrProcess != OldProcess)
83 {
84 KeDetachProcess();
85 }
86
87 if (NT_SUCCESS(Status))
88 {
89 Status = Request->Status;
90 }
91
92 return Status;
93 }
94
95
96 NTSTATUS
97 APIENTRY
98 CsrInsertObject(HANDLE ObjectHandle,
99 ACCESS_MASK DesiredAccess,
100 PHANDLE Handle)
101 {
102 NTSTATUS Status;
103 HANDLE CsrProcessHandle;
104 OBJECT_ATTRIBUTES ObjectAttributes;
105 CLIENT_ID Cid;
106
107 /* Put CSR'S CID */
108 Cid.UniqueProcess = CsrProcess->UniqueProcessId;
109 Cid.UniqueThread = 0;
110
111 /* Empty Attributes */
112 InitializeObjectAttributes(&ObjectAttributes,
113 NULL,
114 0,
115 NULL,
116 NULL);
117
118 /* Get a Handle to Csrss */
119 Status = ZwOpenProcess(&CsrProcessHandle,
120 PROCESS_DUP_HANDLE,
121 &ObjectAttributes,
122 &Cid);
123
124 if ((NT_SUCCESS(Status)))
125 {
126 /* Duplicate the Handle */
127 Status = ZwDuplicateObject(NtCurrentProcess(),
128 ObjectHandle,
129 CsrProcessHandle,
130 Handle,
131 DesiredAccess,
132 OBJ_INHERIT,
133 0);
134
135 /* Close our handle to CSRSS */
136 ZwClose(CsrProcessHandle);
137 }
138
139 return Status;
140 }
141
142 NTSTATUS FASTCALL
143 CsrCloseHandle(HANDLE Handle)
144 {
145 NTSTATUS Status;
146 PEPROCESS OldProcess;
147
148 /* Switch to the process in which the handle is valid */
149 OldProcess = PsGetCurrentProcess();
150 if (CsrProcess != OldProcess)
151 {
152 KeAttachProcess(&CsrProcess->Pcb);
153 }
154
155 Status = ZwClose(Handle);
156
157 if (CsrProcess != OldProcess)
158 {
159 KeDetachProcess();
160 }
161
162 return Status;
163 }
164
165 /* EOF */