update for HEAD-2003091401
[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 /*
87  * @implemented
88  */
89 NTSTATUS STDCALL
90 CsrClientCallServer(PCSRSS_API_REQUEST Request,
91                     PCSRSS_API_REPLY Reply OPTIONAL,
92                     ULONG Length,
93                     ULONG ReplyLength)
94 {
95   NTSTATUS Status;
96   
97   if (INVALID_HANDLE_VALUE == WindowsApiPort)
98     {
99       DbgPrint ("NTDLL.%s: client not connected to CSRSS!\n", __FUNCTION__);
100       return (STATUS_UNSUCCESSFUL);
101     }
102   
103    Request->Header.DataSize = Length - sizeof(LPC_MESSAGE);
104    Request->Header.MessageSize = Length;
105    
106    Status = NtRequestWaitReplyPort(WindowsApiPort,
107                                    &Request->Header,
108                                    (Reply?&Reply->Header:&Request->Header));
109    
110    return(Status);
111 }
112
113 /*
114  * @implemented
115  */
116 NTSTATUS STDCALL
117 CsrClientConnectToServer(VOID)
118 {
119    NTSTATUS Status;
120    UNICODE_STRING PortName;
121    ULONG ConnectInfoLength;
122    CSRSS_API_REQUEST Request;
123    CSRSS_API_REPLY Reply;
124    LPC_SECTION_WRITE LpcWrite;
125    HANDLE CsrSectionHandle;
126    LARGE_INTEGER CsrSectionViewSize;
127
128    CsrSectionViewSize.QuadPart = CSR_CSRSS_SECTION_SIZE;
129    Status = NtCreateSection(&CsrSectionHandle,
130                             SECTION_ALL_ACCESS,
131                             NULL,
132                             &CsrSectionViewSize,
133                             PAGE_READWRITE,
134                             SEC_COMMIT,
135                             NULL);
136    if (!NT_SUCCESS(Status))
137      {
138        return(Status);
139      }
140    RtlInitUnicodeStringFromLiteral(&PortName, L"\\Windows\\ApiPort");
141    ConnectInfoLength = 0;
142    LpcWrite.Length = sizeof(LPC_SECTION_WRITE);
143    LpcWrite.SectionHandle = CsrSectionHandle;
144    LpcWrite.SectionOffset = 0;
145    LpcWrite.ViewSize = CsrSectionViewSize.u.LowPart;
146    Status = NtConnectPort(&WindowsApiPort,
147                           &PortName,
148                           NULL,
149                           &LpcWrite,
150                           NULL,
151                           NULL,
152                           NULL,
153                           &ConnectInfoLength);
154    if (!NT_SUCCESS(Status))
155      {
156         return(Status);
157      }
158
159    NtClose(CsrSectionHandle);
160    CsrSectionMapBase = LpcWrite.ViewBase;
161    CsrSectionMapServerBase = LpcWrite.TargetViewBase;
162
163    /* Create the heap for communication for csrss. */
164    CsrCommHeap = RtlCreateHeap(HEAP_NO_VALLOC,
165                                CsrSectionMapBase,
166                                CsrSectionViewSize.u.LowPart,
167                                CsrSectionViewSize.u.LowPart,
168                                0,
169                                NULL);
170    if (CsrCommHeap == NULL)
171      {
172        return(STATUS_NO_MEMORY);
173      }
174    
175    Request.Type = CSRSS_CONNECT_PROCESS;
176    Status = CsrClientCallServer(&Request,
177                                 &Reply,
178                                 sizeof(CSRSS_API_REQUEST),
179                                 sizeof(CSRSS_API_REPLY));
180    if (!NT_SUCCESS(Status))
181      {
182         return(Status);
183      }
184    if (!NT_SUCCESS(Reply.Status))
185      {
186         return(Reply.Status);
187      }
188    return(STATUS_SUCCESS);
189 }
190
191 /* EOF */