2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Interface between Win32k and USERSRV
5 * FILE: win32ss/user/ntuser/csr.c
6 * PROGRAMMER: 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.
13 DBG_DEFAULT_CHANNEL(UserCsr
);
15 PEPROCESS gpepCSRSS
= NULL
;
16 PVOID CsrApiPort
= NULL
;
19 InitCsrProcess(VOID
/*IN PEPROCESS CsrProcess*/)
21 /* Save the EPROCESS of CSRSS */
22 gpepCSRSS
= PsGetCurrentProcess();
23 // gpepCSRSS = CsrProcess;
24 ObReferenceObject(gpepCSRSS
);
31 ObDereferenceObject(gpepCSRSS
);
37 InitCsrApiPort(IN HANDLE CsrPortHandle
)
41 Status
= ObReferenceObjectByHandle(CsrPortHandle
,
43 /* * */LpcPortObjectType
, // or NULL,
47 if (!NT_SUCCESS(Status
))
50 ERR("Failed to set CSR API Port.\n");
60 ObDereferenceObject(CsrApiPort
);
66 * Function copied from ntdll/csr/connect.c::CsrClientCallServer
67 * and adapted for kernel-mode.
69 * NOTE: This is really a co_* function!
73 CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage
,
74 IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL
,
75 IN CSR_API_NUMBER ApiNumber
,
81 PULONG_PTR OffsetPointer
;
84 /* Do we have a connection to CSR yet? */
86 return STATUS_INVALID_PORT_HANDLE
;
88 /* Fill out the Port Message Header */
89 ApiMessage
->Header
.u2
.ZeroInit
= 0;
90 ApiMessage
->Header
.u1
.s1
.TotalLength
= FIELD_OFFSET(CSR_API_MESSAGE
, Data
) + DataLength
;
91 ApiMessage
->Header
.u1
.s1
.DataLength
= ApiMessage
->Header
.u1
.s1
.TotalLength
-
92 sizeof(ApiMessage
->Header
);
94 /* Fill out the CSR Header */
95 ApiMessage
->ApiNumber
= ApiNumber
;
96 ApiMessage
->CsrCaptureData
= NULL
;
98 TRACE("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n",
100 ApiMessage
->Header
.u1
.s1
.DataLength
,
101 ApiMessage
->Header
.u1
.s1
.TotalLength
);
104 /* Check if we got a Capture Buffer */
108 * We have to convert from our local (client) view
109 * to the remote (server) view.
111 ApiMessage
->CsrCaptureData
= (PCSR_CAPTURE_BUFFER
)
112 ((ULONG_PTR
)CaptureBuffer
+ CsrPortMemoryDelta
);
114 /* Lock the buffer. */
115 CaptureBuffer
->BufferEnd
= NULL
;
118 * Each client pointer inside the CSR message is converted into
119 * a server pointer, and each pointer to these message pointers
120 * is converted into an offset.
122 PointerCount
= CaptureBuffer
->PointerCount
;
123 OffsetPointer
= CaptureBuffer
->PointerOffsetsArray
;
124 while (PointerCount
--)
126 if (*OffsetPointer
!= 0)
128 *(PULONG_PTR
)*OffsetPointer
+= CsrPortMemoryDelta
;
129 *OffsetPointer
-= (ULONG_PTR
)ApiMessage
;
138 /* Send the LPC Message */
140 // The wait logic below is subject to change in the future. One can
141 // imagine adding an external parameter to CsrClientCallServer, or write
142 // two versions of CsrClientCallServer, synchronous and asynchronous.
143 if (PsGetCurrentProcess() == gpepCSRSS
)
145 Status
= LpcRequestPort(CsrApiPort
,
146 &ApiMessage
->Header
);
150 Status
= LpcRequestWaitReplyPort(CsrApiPort
,
152 &ApiMessage
->Header
);
158 /* Check if we got a Capture Buffer */
162 * We have to convert back from the remote (server) view
163 * to our local (client) view.
165 ApiMessage
->CsrCaptureData
= (PCSR_CAPTURE_BUFFER
)
166 ((ULONG_PTR
)ApiMessage
->CsrCaptureData
- CsrPortMemoryDelta
);
169 * Convert back the offsets into pointers to CSR message
170 * pointers, and convert back these message server pointers
171 * into client pointers.
173 PointerCount
= CaptureBuffer
->PointerCount
;
174 OffsetPointer
= CaptureBuffer
->PointerOffsetsArray
;
175 while (PointerCount
--)
177 if (*OffsetPointer
!= 0)
179 *OffsetPointer
+= (ULONG_PTR
)ApiMessage
;
180 *(PULONG_PTR
)*OffsetPointer
-= CsrPortMemoryDelta
;
187 /* Check for success */
188 if (!NT_SUCCESS(Status
))
190 /* We failed. Overwrite the return value with the failure. */
191 ERR("LPC Failed: %lx\n", Status
);
192 ApiMessage
->Status
= Status
;
195 /* Return the CSR Result */
196 TRACE("Got back: 0x%lx\n", ApiMessage
->Status
);
197 return ApiMessage
->Status
;