[BASESRV]
[reactos.git] / subsystems / win / basesrv / vdm.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Base API Server DLL
4 * FILE: subsystems/win/basesrv/vdm.c
5 * PURPOSE: Virtual DOS Machines (VDM) Support
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 * Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include "basesrv.h"
13 #include "vdm.h"
14
15 #define NDEBUG
16 #include <debug.h>
17
18 /* GLOBALS ********************************************************************/
19
20 BOOLEAN FirstVDM = TRUE;
21 LIST_ENTRY VDMConsoleListHead;
22 RTL_CRITICAL_SECTION DosCriticalSection;
23
24 /* FUNCTIONS ******************************************************************/
25
26 NTSTATUS NTAPI BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD *Record)
27 {
28 PLIST_ENTRY i;
29 PVDM_CONSOLE_RECORD CurrentRecord = NULL;
30
31 /* Search for a record that has the same console handle */
32 for (i = VDMConsoleListHead.Flink; i != &VDMConsoleListHead; i = i->Flink)
33 {
34 CurrentRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
35 if (CurrentRecord->ConsoleHandle == ConsoleHandle) break;
36 }
37
38 *Record = CurrentRecord;
39 return CurrentRecord ? STATUS_SUCCESS : STATUS_NOT_FOUND;
40 }
41
42 VOID NTAPI BaseInitializeVDM(VOID)
43 {
44 /* Initialize the list head */
45 InitializeListHead(&VDMConsoleListHead);
46
47 /* Initialize the critical section */
48 RtlInitializeCriticalSection(&DosCriticalSection);
49 }
50
51 /* PUBLIC SERVER APIS *********************************************************/
52
53 CSR_API(BaseSrvCheckVDM)
54 {
55 PBASE_CHECK_VDM CheckVdmRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.CheckVDMRequest;
56
57 /* Validate the message buffers */
58 if (!CsrValidateMessageBuffer(ApiMessage,
59 (PVOID*)&CheckVdmRequest->CmdLine,
60 CheckVdmRequest->CmdLen,
61 sizeof(*CheckVdmRequest->CmdLine))
62 || !CsrValidateMessageBuffer(ApiMessage,
63 (PVOID*)&CheckVdmRequest->AppName,
64 CheckVdmRequest->AppLen,
65 sizeof(*CheckVdmRequest->AppName))
66 || !CsrValidateMessageBuffer(ApiMessage,
67 (PVOID*)&CheckVdmRequest->PifFile,
68 CheckVdmRequest->PifLen,
69 sizeof(*CheckVdmRequest->PifFile))
70 || !CsrValidateMessageBuffer(ApiMessage,
71 (PVOID*)&CheckVdmRequest->CurDirectory,
72 CheckVdmRequest->CurDirectoryLen,
73 sizeof(*CheckVdmRequest->CurDirectory))
74 || !CsrValidateMessageBuffer(ApiMessage,
75 (PVOID*)&CheckVdmRequest->Desktop,
76 CheckVdmRequest->DesktopLen,
77 sizeof(*CheckVdmRequest->Desktop))
78 || !CsrValidateMessageBuffer(ApiMessage,
79 (PVOID*)&CheckVdmRequest->Title,
80 CheckVdmRequest->TitleLen,
81 sizeof(*CheckVdmRequest->Title))
82 || !CsrValidateMessageBuffer(ApiMessage,
83 (PVOID*)&CheckVdmRequest->Reserved,
84 CheckVdmRequest->ReservedLen,
85 sizeof(*CheckVdmRequest->Reserved)))
86 {
87 return STATUS_INVALID_PARAMETER;
88 }
89
90 // TODO: NOT IMPLEMENTED
91 return STATUS_NOT_IMPLEMENTED;
92 }
93
94 CSR_API(BaseSrvUpdateVDMEntry)
95 {
96 DPRINT1("%s not yet implemented\n", __FUNCTION__);
97 return STATUS_NOT_IMPLEMENTED;
98 }
99
100 CSR_API(BaseSrvGetNextVDMCommand)
101 {
102 DPRINT1("%s not yet implemented\n", __FUNCTION__);
103 return STATUS_NOT_IMPLEMENTED;
104 }
105
106 CSR_API(BaseSrvExitVDM)
107 {
108 DPRINT1("%s not yet implemented\n", __FUNCTION__);
109 return STATUS_NOT_IMPLEMENTED;
110 }
111
112 CSR_API(BaseSrvIsFirstVDM)
113 {
114 PBASE_IS_FIRST_VDM IsFirstVDMRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.IsFirstVDMRequest;
115
116 /* Return the result */
117 IsFirstVDMRequest->FirstVDM = FirstVDM;
118
119 /* Clear the first VDM flag */
120 FirstVDM = FALSE;
121
122 return STATUS_SUCCESS;
123 }
124
125 CSR_API(BaseSrvGetVDMExitCode)
126 {
127 DPRINT1("%s not yet implemented\n", __FUNCTION__);
128 return STATUS_NOT_IMPLEMENTED;
129 }
130
131 CSR_API(BaseSrvSetReenterCount)
132 {
133 DPRINT1("%s not yet implemented\n", __FUNCTION__);
134 return STATUS_NOT_IMPLEMENTED;
135 }
136
137 CSR_API(BaseSrvSetVDMCurDirs)
138 {
139 NTSTATUS Status;
140 PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.VDMCurrentDirsRequest;
141 PVDM_CONSOLE_RECORD ConsoleRecord;
142 PCHAR Buffer = NULL;
143
144 /* Validate the input buffer */
145 if (!CsrValidateMessageBuffer(ApiMessage,
146 (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs,
147 VDMCurrentDirsRequest->cchCurDirs,
148 sizeof(*VDMCurrentDirsRequest->lpszzCurDirs)))
149 {
150 return STATUS_INVALID_PARAMETER;
151 }
152
153 /* Enter the critical section */
154 RtlEnterCriticalSection(&DosCriticalSection);
155
156 /* Find the console record */
157 Status = BaseSrvGetConsoleRecord(VDMCurrentDirsRequest->ConsoleHandle, &ConsoleRecord);
158 if (!NT_SUCCESS(Status)) goto Cleanup;
159
160 if (ConsoleRecord->CurrentDirs == NULL)
161 {
162 /* Allocate memory for the current directory information */
163 Buffer = RtlAllocateHeap(BaseSrvHeap,
164 HEAP_ZERO_MEMORY,
165 VDMCurrentDirsRequest->cchCurDirs);
166 }
167 else
168 {
169 /* Resize the amount of allocated memory */
170 Buffer = RtlReAllocateHeap(BaseSrvHeap,
171 HEAP_ZERO_MEMORY,
172 ConsoleRecord->CurrentDirs,
173 VDMCurrentDirsRequest->cchCurDirs);
174 }
175
176 if (Buffer == NULL)
177 {
178 /* Allocation failed */
179 Status = STATUS_NO_MEMORY;
180 goto Cleanup;
181 }
182
183 /* Update the console record */
184 ConsoleRecord->CurrentDirs = Buffer;
185 ConsoleRecord->CurDirsLength = VDMCurrentDirsRequest->cchCurDirs;
186
187 /* Copy the data */
188 RtlMoveMemory(ConsoleRecord->CurrentDirs,
189 VDMCurrentDirsRequest->lpszzCurDirs,
190 VDMCurrentDirsRequest->cchCurDirs);
191
192 Cleanup:
193 /* Leave the critical section */
194 RtlLeaveCriticalSection(&DosCriticalSection);
195
196 return Status;
197 }
198
199 CSR_API(BaseSrvGetVDMCurDirs)
200 {
201 NTSTATUS Status;
202 PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.VDMCurrentDirsRequest;
203 PVDM_CONSOLE_RECORD ConsoleRecord;
204
205 /* Validate the output buffer */
206 if (!CsrValidateMessageBuffer(ApiMessage,
207 (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs,
208 VDMCurrentDirsRequest->cchCurDirs,
209 sizeof(*VDMCurrentDirsRequest->lpszzCurDirs)))
210 {
211 return STATUS_INVALID_PARAMETER;
212 }
213
214 /* Enter the critical section */
215 RtlEnterCriticalSection(&DosCriticalSection);
216
217 /* Find the console record */
218 Status = BaseSrvGetConsoleRecord(VDMCurrentDirsRequest->ConsoleHandle, &ConsoleRecord);
219 if (!NT_SUCCESS(Status)) goto Cleanup;
220
221 /* Check if the buffer is large enough */
222 if (VDMCurrentDirsRequest->cchCurDirs < ConsoleRecord->CurDirsLength)
223 {
224 Status = STATUS_BUFFER_TOO_SMALL;
225 goto Cleanup;
226 }
227
228 /* Copy the data */
229 RtlMoveMemory(VDMCurrentDirsRequest->lpszzCurDirs,
230 ConsoleRecord->CurrentDirs,
231 ConsoleRecord->CurDirsLength);
232
233 Cleanup:
234 /* Leave the critical section */
235 RtlLeaveCriticalSection(&DosCriticalSection);
236
237 return Status;
238 }
239
240 CSR_API(BaseSrvBatNotification)
241 {
242 DPRINT1("%s not yet implemented\n", __FUNCTION__);
243 return STATUS_NOT_IMPLEMENTED;
244 }
245
246 CSR_API(BaseSrvRegisterWowExec)
247 {
248 DPRINT1("%s not yet implemented\n", __FUNCTION__);
249 return STATUS_NOT_IMPLEMENTED;
250 }
251
252 CSR_API(BaseSrvRefreshIniFileMapping)
253 {
254 DPRINT1("%s not yet implemented\n", __FUNCTION__);
255 return STATUS_NOT_IMPLEMENTED;
256 }
257
258 /* EOF */