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
= 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);
95 /* Fill out the CSR Header */
96 ApiMessage
->ApiNumber
= ApiNumber
;
97 ApiMessage
->CsrCaptureData
= NULL
;
99 TRACE("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n",
101 ApiMessage
->Header
.u1
.s1
.DataLength
,
102 ApiMessage
->Header
.u1
.s1
.TotalLength
);
105 /* Check if we got a Capture Buffer */
109 * We have to convert from our local (client) view
110 * to the remote (server) view.
112 ApiMessage
->CsrCaptureData
= (PCSR_CAPTURE_BUFFER
)
113 ((ULONG_PTR
)CaptureBuffer
+ CsrPortMemoryDelta
);
115 /* Lock the buffer. */
116 CaptureBuffer
->BufferEnd
= NULL
;
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.
123 PointerCount
= CaptureBuffer
->PointerCount
;
124 OffsetPointer
= CaptureBuffer
->PointerOffsetsArray
;
125 while (PointerCount
--)
127 if (*OffsetPointer
!= 0)
129 *(PULONG_PTR
)*OffsetPointer
+= CsrPortMemoryDelta
;
130 *OffsetPointer
-= (ULONG_PTR
)ApiMessage
;
139 /* Send the LPC Message */
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
)
146 Status
= LpcRequestPort(CsrApiPort
,
147 &ApiMessage
->Header
);
151 Status
= LpcRequestWaitReplyPort(CsrApiPort
,
153 &ApiMessage
->Header
);
159 /* Check if we got a Capture Buffer */
163 * We have to convert back from the remote (server) view
164 * to our local (client) view.
166 ApiMessage
->CsrCaptureData
= (PCSR_CAPTURE_BUFFER
)
167 ((ULONG_PTR
)ApiMessage
->CsrCaptureData
- CsrPortMemoryDelta
);
170 * Convert back the offsets into pointers to CSR message
171 * pointers, and convert back these message server pointers
172 * into client pointers.
174 PointerCount
= CaptureBuffer
->PointerCount
;
175 OffsetPointer
= CaptureBuffer
->PointerOffsetsArray
;
176 while (PointerCount
--)
178 if (*OffsetPointer
!= 0)
180 *OffsetPointer
+= (ULONG_PTR
)ApiMessage
;
181 *(PULONG_PTR
)*OffsetPointer
-= CsrPortMemoryDelta
;
188 /* Check for success */
189 if (!NT_SUCCESS(Status
))
191 /* We failed. Overwrite the return value with the failure. */
192 ERR("LPC Failed: %lx\n", Status
);
193 ApiMessage
->Status
= Status
;
196 /* Return the CSR Result */
197 TRACE("Got back: 0x%lx\n", ApiMessage
->Status
);
198 return ApiMessage
->Status
;