fea9ea30cc5f2393acfeb2e5ed54a174a0b18867
[reactos.git] / lib / ntdll / csr / lpc.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            lib/ntdll/csr/lpc.c
6  * PURPOSE:         CSRSS Client/Server LPC API
7  *
8  * REVISIONS:
9  *      2001-06-16 (ea)
10  *              File api.c renamed lpc.c. Process/thread code moved
11  *              in thread.c. Check added on the LPC port.
12  */
13
14 /* INCLUDES *****************************************************************/
15
16 #include <ddk/ntddk.h>
17 #include <ntdll/csr.h>
18 #include <string.h>
19
20 #include <csrss/csrss.h>
21
22 #define NDEBUG
23 #include <ntdll/ntdll.h>
24
25 /* GLOBALS *******************************************************************/
26
27 HANDLE WindowsApiPort = INVALID_HANDLE_VALUE;
28 static PVOID CsrSectionMapBase = NULL;
29 static PVOID CsrSectionMapServerBase = NULL;
30 static HANDLE CsrCommHeap = NULL;
31
32 #define CSR_CONTROL_HEAP_SIZE (65536)
33
34 /* FUNCTIONS *****************************************************************/
35
36 /* Possible CsrClientCallServer (the NT one):
37
38 #define CSR_CCS_NATIVE  0x0000
39 #define CSR_CCS_CSR     0x0001
40 #define CSR_CCS_GUI     0x0002
41
42 typedef union _CSR_CCS_API
43 {
44         WORD    Index;          // CSRSS API number
45         WORD    Subsystem;      // 0=NTDLL;1=KERNEL32;2=KERNEL32
46
47 } CSR_CCS_API, * PCSR_CCS_API;
48
49 NTSTATUS STDCALL
50 CsrClientCallServer(PVOID Request,
51                     PVOID Unknown OPTIONAL,
52                     CSR_CCS_API CsrApi,
53                     ULONG SizeOfData);
54                     
55 Request is the family of PCSRSS_XXX_REQUEST objects.
56 XXX_REQUEST depend on the CsrApiNumber.Index.
57
58 */
59
60 NTSTATUS STDCALL
61 CsrCaptureParameterBuffer(PVOID ParameterBuffer,
62                           ULONG ParameterBufferSize,
63                           PVOID* ClientAddress,
64                           PVOID* ServerAddress)
65 {
66   PVOID Block;
67
68   Block = RtlAllocateHeap(CsrCommHeap, 0, ParameterBufferSize);
69   if (Block == NULL)
70     {
71       return(STATUS_NO_MEMORY);
72     }
73   memcpy(Block, ParameterBuffer, ParameterBufferSize);
74   *ClientAddress = Block;
75   *ServerAddress = Block - CsrSectionMapBase + CsrSectionMapServerBase;
76   return(STATUS_SUCCESS);
77 }
78
79 NTSTATUS STDCALL
80 CsrReleaseParameterBuffer(PVOID ClientAddress)
81 {
82   RtlFreeHeap(CsrCommHeap, 0, ClientAddress);
83   return(STATUS_SUCCESS);
84 }
85
86 NTSTATUS STDCALL
87 CsrClientCallServer(PCSRSS_API_REQUEST Request,
88                     PCSRSS_API_REPLY Reply OPTIONAL,
89                     ULONG Length,
90                     ULONG ReplyLength)
91 {
92   NTSTATUS Status;
93   
94   if (INVALID_HANDLE_VALUE == WindowsApiPort)
95     {
96       DbgPrint ("NTDLL.%s: client not connected to CSRSS!\n", __FUNCTION__);
97       return (STATUS_UNSUCCESSFUL);
98     }
99   
100    Request->Header.DataSize = Length - sizeof(LPC_MESSAGE_HEADER);
101    Request->Header.MessageSize = Length;
102    
103    Status = NtRequestWaitReplyPort(WindowsApiPort,
104                                    &Request->Header,
105                                    (Reply?&Reply->Header:&Request->Header));
106    
107    return(Status);
108 }
109
110 NTSTATUS STDCALL
111 CsrClientConnectToServer(VOID)
112 {
113    NTSTATUS Status;
114    UNICODE_STRING PortName;
115    ULONG ConnectInfoLength;
116    CSRSS_API_REQUEST Request;
117    CSRSS_API_REPLY Reply;
118    LPC_SECTION_WRITE LpcWrite;
119    HANDLE CsrSectionHandle;
120    LARGE_INTEGER CsrSectionViewSize;
121
122    CsrSectionViewSize.QuadPart = CSR_CSRSS_SECTION_SIZE;
123    Status = NtCreateSection(&CsrSectionHandle,
124                             SECTION_ALL_ACCESS,
125                             NULL,
126                             &CsrSectionViewSize,
127                             PAGE_READWRITE,
128                             SEC_COMMIT,
129                             NULL);
130    if (!NT_SUCCESS(Status))
131      {
132        return(Status);
133      }
134    RtlInitUnicodeStringFromLiteral(&PortName, L"\\Windows\\ApiPort");
135    ConnectInfoLength = 0;
136    LpcWrite.Length = sizeof(LPC_SECTION_WRITE);
137    LpcWrite.SectionHandle = CsrSectionHandle;
138    LpcWrite.SectionOffset = 0;
139    LpcWrite.ViewSize = CsrSectionViewSize.u.LowPart;
140    Status = NtConnectPort(&WindowsApiPort,
141                           &PortName,
142                           NULL,
143                           &LpcWrite,
144                           NULL,
145                           NULL,
146                           NULL,
147                           &ConnectInfoLength);
148    if (!NT_SUCCESS(Status))
149      {
150         return(Status);
151      }
152
153    NtClose(CsrSectionHandle);
154    CsrSectionMapBase = LpcWrite.ViewBase;
155    CsrSectionMapServerBase = LpcWrite.TargetViewBase;
156
157    /* Create the heap for communication for csrss. */
158    CsrCommHeap = RtlCreateHeap(HEAP_NO_VALLOC,
159                                CsrSectionMapBase,
160                                CsrSectionViewSize.u.LowPart,
161                                CsrSectionViewSize.u.LowPart,
162                                0,
163                                NULL);
164    if (CsrCommHeap == NULL)
165      {
166        return(STATUS_NO_MEMORY);
167      }
168    
169    Request.Type = CSRSS_CONNECT_PROCESS;
170    Status = CsrClientCallServer(&Request,
171                                 &Reply,
172                                 sizeof(CSRSS_API_REQUEST),
173                                 sizeof(CSRSS_API_REPLY));
174    if (!NT_SUCCESS(Status))
175      {
176         return(Status);
177      }
178    if (!NT_SUCCESS(Reply.Status))
179      {
180         return(Reply.Status);
181      }
182    return(STATUS_SUCCESS);
183 }
184
185 /* EOF */