dcfeb6d57300eeac9dfeb8c186b3b4314f06b49b
[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 /* Return the actual size of the current directory information */
222 VDMCurrentDirsRequest->cchCurDirs = ConsoleRecord->CurDirsLength;
223
224 /* Check if the buffer is large enough */
225 if (VDMCurrentDirsRequest->cchCurDirs < ConsoleRecord->CurDirsLength)
226 {
227 Status = STATUS_BUFFER_TOO_SMALL;
228 goto Cleanup;
229 }
230
231 /* Copy the data */
232 RtlMoveMemory(VDMCurrentDirsRequest->lpszzCurDirs,
233 ConsoleRecord->CurrentDirs,
234 ConsoleRecord->CurDirsLength);
235
236 Cleanup:
237 /* Leave the critical section */
238 RtlLeaveCriticalSection(&DosCriticalSection);
239
240 return Status;
241 }
242
243 CSR_API(BaseSrvBatNotification)
244 {
245 DPRINT1("%s not yet implemented\n", __FUNCTION__);
246 return STATUS_NOT_IMPLEMENTED;
247 }
248
249 CSR_API(BaseSrvRegisterWowExec)
250 {
251 DPRINT1("%s not yet implemented\n", __FUNCTION__);
252 return STATUS_NOT_IMPLEMENTED;
253 }
254
255 CSR_API(BaseSrvRefreshIniFileMapping)
256 {
257 DPRINT1("%s not yet implemented\n", __FUNCTION__);
258 return STATUS_NOT_IMPLEMENTED;
259 }
260
261 /* EOF */