[Win32k]
[reactos.git] / reactos / win32ss / user / ntuser / csr.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Interface between Win32k and USERSRV
5 * FILE: subsystems/win32/win32k/ntuser/csr.c
6 * PROGRAMER: Hermes Belusca-Maito (hermes.belusca@sfr.fr), based on
7 * the original code by Ge van Geldorp (ge@gse.nl) and by
8 * the CSR code in NTDLL.
9 */
10
11 #include <win32k.h>
12
13 DBG_DEFAULT_CHANNEL(UserCsr);
14
15 PEPROCESS gpepCSRSS = NULL;
16 PVOID CsrApiPort = NULL;
17
18 VOID
19 InitCsrProcess(VOID /*IN PEPROCESS CsrProcess*/)
20 {
21 /* Save the EPROCESS of CSRSS */
22 gpepCSRSS = PsGetCurrentProcess();
23 // gpepCSRSS = CsrProcess;
24 ObReferenceObject(gpepCSRSS);
25 }
26
27 VOID
28 ResetCsrProcess(VOID)
29 {
30 if (gpepCSRSS)
31 ObDereferenceObject(gpepCSRSS);
32
33 gpepCSRSS = NULL;
34 }
35
36 NTSTATUS
37 InitCsrApiPort(IN HANDLE CsrPortHandle)
38 {
39 NTSTATUS Status;
40
41 Status = ObReferenceObjectByHandle(CsrPortHandle,
42 0,
43 /* * */LpcPortObjectType, // or NULL,
44 UserMode,
45 &CsrApiPort,
46 NULL);
47 if (!NT_SUCCESS(Status))
48 {
49 CsrApiPort = NULL;
50 ERR("Failed to set CSR API Port.\n");
51 }
52
53 return Status;
54 }
55
56 VOID
57 ResetCsrApiPort(VOID)
58 {
59 if (CsrApiPort)
60 ObDereferenceObject(CsrApiPort);
61
62 CsrApiPort = NULL;
63 }
64
65 /*
66 * Function copied from ntdll/csr/connect.c::CsrClientCallServer
67 * and adapted for kernel-mode.
68 *
69 * NOTE: This is really a co_* function!
70 */
71 NTSTATUS
72 NTAPI
73 CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage,
74 IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL,
75 IN CSR_API_NUMBER ApiNumber,
76 IN ULONG DataLength)
77 {
78 NTSTATUS Status;
79 #if 0
80 ULONG PointerCount;
81 PULONG_PTR OffsetPointer;
82 #endif
83
84 /* Do we have a connection to CSR yet? */
85 if (!CsrApiPort)
86 return STATUS_INVALID_PORT_HANDLE;
87
88 /* Fill out the Port Message Header */
89 ApiMessage->Header.u2.ZeroInit = 0;
90 ApiMessage->Header.u1.s1.TotalLength = DataLength +
91 sizeof(CSR_API_MESSAGE) - sizeof(ApiMessage->Data); // FIELD_OFFSET(CSR_API_MESSAGE, Data) + DataLength;
92 ApiMessage->Header.u1.s1.DataLength = DataLength +
93 FIELD_OFFSET(CSR_API_MESSAGE, Data) - sizeof(ApiMessage->Header); // ApiMessage->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
94
95 /* Fill out the CSR Header */
96 ApiMessage->ApiNumber = ApiNumber;
97 ApiMessage->CsrCaptureData = NULL;
98
99 TRACE("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n",
100 ApiNumber,
101 ApiMessage->Header.u1.s1.DataLength,
102 ApiMessage->Header.u1.s1.TotalLength);
103
104 #if 0
105 /* Check if we got a Capture Buffer */
106 if (CaptureBuffer)
107 {
108 /*
109 * We have to convert from our local (client) view
110 * to the remote (server) view.
111 */
112 ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
113 ((ULONG_PTR)CaptureBuffer + CsrPortMemoryDelta);
114
115 /* Lock the buffer. */
116 CaptureBuffer->BufferEnd = NULL;
117
118 /*
119 * Each client pointer inside the CSR message is converted into
120 * a server pointer, and each pointer to these message pointers
121 * is converted into an offset.
122 */
123 PointerCount = CaptureBuffer->PointerCount;
124 OffsetPointer = CaptureBuffer->PointerOffsetsArray;
125 while (PointerCount--)
126 {
127 if (*OffsetPointer != 0)
128 {
129 *(PULONG_PTR)*OffsetPointer += CsrPortMemoryDelta;
130 *OffsetPointer -= (ULONG_PTR)ApiMessage;
131 }
132 ++OffsetPointer;
133 }
134 }
135 #endif
136
137 UserLeaveCo();
138
139 /* Send the LPC Message */
140
141 // The wait logic below is subject to change in the future. One can
142 // imagine adding an external parameter to CsrClientCallServer, or write
143 // two versions of CsrClientCallServer, synchronous and asynchronous.
144 if (PsGetCurrentProcess() == gpepCSRSS)
145 {
146 Status = LpcRequestPort(CsrApiPort,
147 &ApiMessage->Header);
148 }
149 else
150 {
151 Status = LpcRequestWaitReplyPort(CsrApiPort,
152 &ApiMessage->Header,
153 &ApiMessage->Header);
154 }
155
156 UserEnterCo();
157
158 #if 0
159 /* Check if we got a Capture Buffer */
160 if (CaptureBuffer)
161 {
162 /*
163 * We have to convert back from the remote (server) view
164 * to our local (client) view.
165 */
166 ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
167 ((ULONG_PTR)ApiMessage->CsrCaptureData - CsrPortMemoryDelta);
168
169 /*
170 * Convert back the offsets into pointers to CSR message
171 * pointers, and convert back these message server pointers
172 * into client pointers.
173 */
174 PointerCount = CaptureBuffer->PointerCount;
175 OffsetPointer = CaptureBuffer->PointerOffsetsArray;
176 while (PointerCount--)
177 {
178 if (*OffsetPointer != 0)
179 {
180 *OffsetPointer += (ULONG_PTR)ApiMessage;
181 *(PULONG_PTR)*OffsetPointer -= CsrPortMemoryDelta;
182 }
183 ++OffsetPointer;
184 }
185 }
186 #endif
187
188 /* Check for success */
189 if (!NT_SUCCESS(Status))
190 {
191 /* We failed. Overwrite the return value with the failure. */
192 ERR("LPC Failed: %lx\n", Status);
193 ApiMessage->Status = Status;
194 }
195
196 /* Return the CSR Result */
197 TRACE("Got back: 0x%lx\n", ApiMessage->Status);
198 return ApiMessage->Status;
199 }
200
201 /* EOF */