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 */ 201