[WIN32K] Fix 64 bit issues (#420)
[reactos.git] / 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: 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.
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 = FIELD_OFFSET(CSR_API_MESSAGE, Data) + DataLength;
91 ApiMessage->Header.u1.s1.DataLength = ApiMessage->Header.u1.s1.TotalLength -
92 sizeof(ApiMessage->Header);
93
94 /* Fill out the CSR Header */
95 ApiMessage->ApiNumber = ApiNumber;
96 ApiMessage->CsrCaptureData = NULL;
97
98 TRACE("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n",
99 ApiNumber,
100 ApiMessage->Header.u1.s1.DataLength,
101 ApiMessage->Header.u1.s1.TotalLength);
102
103 #if 0
104 /* Check if we got a Capture Buffer */
105 if (CaptureBuffer)
106 {
107 /*
108 * We have to convert from our local (client) view
109 * to the remote (server) view.
110 */
111 ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
112 ((ULONG_PTR)CaptureBuffer + CsrPortMemoryDelta);
113
114 /* Lock the buffer. */
115 CaptureBuffer->BufferEnd = NULL;
116
117 /*
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.
121 */
122 PointerCount = CaptureBuffer->PointerCount;
123 OffsetPointer = CaptureBuffer->PointerOffsetsArray;
124 while (PointerCount--)
125 {
126 if (*OffsetPointer != 0)
127 {
128 *(PULONG_PTR)*OffsetPointer += CsrPortMemoryDelta;
129 *OffsetPointer -= (ULONG_PTR)ApiMessage;
130 }
131 ++OffsetPointer;
132 }
133 }
134 #endif
135
136 UserLeaveCo();
137
138 /* Send the LPC Message */
139
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)
144 {
145 Status = LpcRequestPort(CsrApiPort,
146 &ApiMessage->Header);
147 }
148 else
149 {
150 Status = LpcRequestWaitReplyPort(CsrApiPort,
151 &ApiMessage->Header,
152 &ApiMessage->Header);
153 }
154
155 UserEnterCo();
156
157 #if 0
158 /* Check if we got a Capture Buffer */
159 if (CaptureBuffer)
160 {
161 /*
162 * We have to convert back from the remote (server) view
163 * to our local (client) view.
164 */
165 ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
166 ((ULONG_PTR)ApiMessage->CsrCaptureData - CsrPortMemoryDelta);
167
168 /*
169 * Convert back the offsets into pointers to CSR message
170 * pointers, and convert back these message server pointers
171 * into client pointers.
172 */
173 PointerCount = CaptureBuffer->PointerCount;
174 OffsetPointer = CaptureBuffer->PointerOffsetsArray;
175 while (PointerCount--)
176 {
177 if (*OffsetPointer != 0)
178 {
179 *OffsetPointer += (ULONG_PTR)ApiMessage;
180 *(PULONG_PTR)*OffsetPointer -= CsrPortMemoryDelta;
181 }
182 ++OffsetPointer;
183 }
184 }
185 #endif
186
187 /* Check for success */
188 if (!NT_SUCCESS(Status))
189 {
190 /* We failed. Overwrite the return value with the failure. */
191 ERR("LPC Failed: %lx\n", Status);
192 ApiMessage->Status = Status;
193 }
194
195 /* Return the CSR Result */
196 TRACE("Got back: 0x%lx\n", ApiMessage->Status);
197 return ApiMessage->Status;
198 }
199
200 /* EOF */