ReactOS 0.4.16-dev-319-g6cf4263
handle.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: GPLv2+ - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/dos/dos32krnl/handle.c
5 * PURPOSE: DOS32 Handles (Job File Table)
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "ntvdm.h"
12
13#define NDEBUG
14#include <debug.h>
15
16#include "emulator.h"
17
18#include "dos.h"
19#include "dos/dem.h"
20#include "dosfiles.h"
21#include "handle.h"
22#include "memory.h"
23#include "process.h"
24
25/* PUBLIC FUNCTIONS ***********************************************************/
26
28{
29 UINT i;
30 PDOS_PSP PspBlock;
31 LPBYTE SourceTable;
33
34 /* Clear the table first */
35 for (i = 0; i < DEFAULT_JFT_SIZE; i++) DestinationTable[i] = 0xFF;
36
37 /* Check if this is the initial process */
39 {
40 BYTE DescriptorId;
41 HANDLE StandardHandles[3];
42
43 /* Get the native standard handles */
44 StandardHandles[0] = GetStdHandle(STD_INPUT_HANDLE);
45 StandardHandles[1] = GetStdHandle(STD_OUTPUT_HANDLE);
46 StandardHandles[2] = GetStdHandle(STD_ERROR_HANDLE);
47
48 for (i = 0; i < 3; i++)
49 {
50 /* Find the corresponding SFT entry */
51 if (IsConsoleHandle(StandardHandles[i]))
52 {
54 }
55 else
56 {
57 DescriptorId = DosFindWin32Descriptor(StandardHandles[i]);
58 }
59
60 if (DescriptorId != 0xFF)
61 {
62 Descriptor = DosGetFileDescriptor(DescriptorId);
63 }
64 else
65 {
66 /* Create a new SFT entry for it */
67 DescriptorId = DosFindFreeDescriptor();
68 if (DescriptorId == 0xFF)
69 {
70 DPRINT1("Cannot create standard handle %d, the SFT is full!\n", i);
71 continue;
72 }
73
74 Descriptor = DosGetFileDescriptor(DescriptorId);
77
78 if (IsConsoleHandle(StandardHandles[i]))
79 {
81
82 Descriptor->DeviceInfo = Node->DeviceAttributes | FILE_INFO_DEVICE;
83 Descriptor->DevicePointer = SysVars->ActiveCon;
84 RtlFillMemory(Descriptor->FileName, sizeof(Descriptor->FileName), ' ');
85 RtlCopyMemory(Descriptor->FileName, Node->Name.Buffer, Node->Name.Length);
86
87 /* Call the open routine */
88 if (Node->OpenRoutine) Node->OpenRoutine(Node);
89 }
90 else
91 {
92 Descriptor->Win32Handle = StandardHandles[i];
93 }
94 }
95
96 Descriptor->RefCount++;
97 DestinationTable[i] = DescriptorId;
98 }
99 }
100 else
101 {
102 /* Get the parent PSP block and handle table */
103 PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
104 SourceTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
105
106 /* Copy the first 20 handles into the new table */
107 for (i = 0; i < DEFAULT_JFT_SIZE; i++)
108 {
109 Descriptor = DosGetFileDescriptor(SourceTable[i]);
110 DestinationTable[i] = SourceTable[i];
111
112 /* Increase the reference count */
113 Descriptor->RefCount++;
114 }
115 }
116}
117
119{
120 PDOS_PSP PspBlock;
123
124 /* Get the PSP block */
125 PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
126
127 if (NewSize == PspBlock->HandleTableSize)
128 {
129 /* No change */
130 return TRUE;
131 }
132
133 if (PspBlock->HandleTableSize > DEFAULT_JFT_SIZE)
134 {
135 /* Get the segment of the current table */
136 Segment = (LOWORD(PspBlock->HandleTablePtr) >> 4) + HIWORD(PspBlock->HandleTablePtr);
137
139 {
140 /* Get the current handle table */
142
143 /* Copy it to the PSP */
145
146 /* Free the memory */
148
149 /* Update the handle table pointer and size */
150 PspBlock->HandleTableSize = NewSize;
151 PspBlock->HandleTablePtr = MAKELONG(0x18, Sda->CurrentPsp);
152 }
153 else
154 {
155 /* Resize the memory */
157 {
158 /* Unable to resize, try allocating it somewhere else */
160 if (Segment == 0) return FALSE;
161
162 /* Get the new handle table */
164
165 /* Copy the handles to the new table */
167 FAR_POINTER(PspBlock->HandleTablePtr),
168 PspBlock->HandleTableSize);
169
170 /* Update the handle table pointer */
171 PspBlock->HandleTablePtr = MAKELONG(0, Segment);
172 }
173
174 /* Update the handle table size */
175 PspBlock->HandleTableSize = NewSize;
176 }
177 }
178 else if (NewSize > DEFAULT_JFT_SIZE)
179 {
181 if (Segment == 0) return FALSE;
182
183 /* Get the new handle table */
185
186 /* Copy the handles from the PSP to the new table */
188 FAR_POINTER(PspBlock->HandleTablePtr),
189 PspBlock->HandleTableSize);
190
191 /* Update the handle table pointer and size */
192 PspBlock->HandleTableSize = NewSize;
193 PspBlock->HandleTablePtr = MAKELONG(0, Segment);
194 }
195
196 return TRUE;
197}
198
199
201{
202 WORD DosHandle;
203 PDOS_PSP PspBlock;
206
207 DPRINT("DosOpenHandle: DescriptorId 0x%02X\n", DescriptorId);
208
209 /* Make sure the descriptor ID is valid */
210 if (Descriptor == NULL) return INVALID_DOS_HANDLE;
211
212 /* The system PSP has no handle table */
214
215 /* Get a pointer to the handle table */
216 PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
218
219 /* Find a free entry in the JFT */
220 for (DosHandle = 0; DosHandle < PspBlock->HandleTableSize; DosHandle++)
221 {
222 if (HandleTable[DosHandle] == 0xFF) break;
223 }
224
225 /* If there are no free entries, fail */
226 if (DosHandle == PspBlock->HandleTableSize) return INVALID_DOS_HANDLE;
227
228 /* Reference the descriptor */
229 Descriptor->RefCount++;
230
231 /* Set the JFT entry to that descriptor ID */
232 HandleTable[DosHandle] = DescriptorId;
233
234 /* Return the new handle */
235 return DosHandle;
236}
237
239{
240 PDOS_PSP PspBlock;
242
243 DPRINT("DosQueryHandle: DosHandle 0x%04X\n", DosHandle);
244
245 /* The system PSP has no handle table */
246 if (Sda->CurrentPsp == SYSTEM_PSP) return 0xFF;
247
248 /* Get a pointer to the handle table */
249 PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
251
252 /* Return the descriptor ID */
253 return HandleTable[DosHandle];
254}
255
257{
258 BYTE DescriptorId = DosQueryHandle(DosHandle);
259
260 if (DescriptorId == 0xFF)
261 {
263 return INVALID_DOS_HANDLE;
264 }
265
266 return DosOpenHandle(DescriptorId);
267}
268
270{
271 BYTE DescriptorId;
272 PDOS_PSP PspBlock;
275
276 DPRINT("DosForceDuplicateHandle: OldHandle 0x%04X, NewHandle 0x%04X\n",
277 OldHandle,
278 NewHandle);
279
280 /* The system PSP has no handle table */
281 if (Sda->CurrentPsp == SYSTEM_PSP) return FALSE;
282
283 /* Get a pointer to the handle table */
284 PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
286
287 /* Make sure the old handle is open */
288 if (HandleTable[OldHandle] == 0xFF) return FALSE;
289
290 /* Check if the new handle is open */
291 if (HandleTable[NewHandle] != 0xFF)
292 {
293 /* Close it */
294 DosCloseHandle(NewHandle);
295 }
296
297 DescriptorId = HandleTable[OldHandle];
298 Descriptor = DosGetFileDescriptor(DescriptorId);
299 if (Descriptor == NULL) return FALSE;
300
301 /* Increment the reference count of the descriptor */
302 Descriptor->RefCount++;
303
304 /* Make the new handle point to that descriptor */
305 HandleTable[NewHandle] = DescriptorId;
306
307 /* Return success */
308 return TRUE;
309}
310
312{
313 PDOS_PSP PspBlock;
316
317 DPRINT("DosCloseHandle: DosHandle 0x%04X\n", DosHandle);
318
319 /* The system PSP has no handle table */
320 if (Sda->CurrentPsp == SYSTEM_PSP) return FALSE;
321
322 /* Get a pointer to the handle table */
323 PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
325
326 /* Make sure the handle is open */
327 if (HandleTable[DosHandle] == 0xFF) return FALSE;
328
329 /* Make sure the descriptor is valid */
331 if (Descriptor == NULL) return FALSE;
332
333 /* Decrement the reference count of the descriptor */
334 Descriptor->RefCount--;
335
336 /* Check if the reference count fell to zero */
337 if (!Descriptor->RefCount)
338 {
339 if (Descriptor->DeviceInfo & FILE_INFO_DEVICE)
340 {
342
343 /* Call the close routine, if it exists */
344 if (Node->CloseRoutine) Node->CloseRoutine(Node);
345 }
346 else
347 {
348 /* Close the Win32 handle */
349 CloseHandle(Descriptor->Win32Handle);
350 }
351 }
352
353 /* Clear the entry in the JFT */
354 HandleTable[DosHandle] = 0xFF;
355
356 return TRUE;
357}
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
PDOS_SYSVARS SysVars
Definition: dos.c:47
PDOS_SDA Sda
Definition: dos.c:48
BYTE DosFindWin32Descriptor(HANDLE Win32Handle)
Definition: dosfiles.c:93
PDOS_FILE_DESCRIPTOR DosGetFileDescriptor(BYTE Id)
Definition: dosfiles.c:153
BYTE DosFindFreeDescriptor(VOID)
Definition: dosfiles.c:69
BYTE DosFindDeviceDescriptor(DWORD DevicePointer)
Definition: dosfiles.c:123
#define FILE_INFO_DEVICE
Definition: dosfiles.h:16
#define FAR_POINTER(x)
Definition: emulator.h:35
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:32
unsigned short WORD
Definition: ntddk_ex.h:93
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define ASSERT(a)
Definition: mode.c:44
unsigned int UINT
Definition: ndis.h:50
#define LOWORD(l)
Definition: pedump.c:82
#define IsConsoleHandle(h)
Definition: console.h:14
#define DPRINT
Definition: sndvol32.h:73
BYTE HandleTable[20]
Definition: process.h:36
WORD HandleTableSize
Definition: process.h:39
DWORD HandleTablePtr
Definition: process.h:40
WORD LastErrorCode
Definition: dos.h:160
WORD CurrentPsp
Definition: dos.h:165
DWORD ActiveCon
Definition: dos.h:83
PDOS_DEVICE_NODE DosGetDriverNode(DWORD Driver)
Definition: device.c:305
#define INVALID_DOS_HANDLE
Definition: dos.h:41
#define SYSTEM_PSP
Definition: dos.h:39
VOID DosCopyHandleTable(LPBYTE DestinationTable)
Definition: handle.c:27
WORD DosDuplicateHandle(WORD DosHandle)
Definition: handle.c:256
BOOLEAN DosCloseHandle(WORD DosHandle)
Definition: handle.c:311
BOOLEAN DosResizeHandleTable(WORD NewSize)
Definition: handle.c:118
BOOLEAN DosForceDuplicateHandle(WORD OldHandle, WORD NewHandle)
Definition: handle.c:269
BYTE DosQueryHandle(WORD DosHandle)
Definition: handle.c:238
WORD DosOpenHandle(BYTE DescriptorId)
Definition: handle.c:200
#define DEFAULT_JFT_SIZE
Definition: handle.h:13
BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable)
Definition: memory.c:289
WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
Definition: memory.c:136
BOOLEAN DosFreeMemory(WORD BlockData)
Definition: memory.c:418
#define SEGMENT_TO_PSP(seg)
Definition: process.h:16
unsigned char * LPBYTE
Definition: typedefs.h:53
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
#define STD_OUTPUT_HANDLE
Definition: winbase.h:294
#define STD_INPUT_HANDLE
Definition: winbase.h:293
#define STD_ERROR_HANDLE
Definition: winbase.h:295
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
unsigned char BYTE
Definition: xxhash.c:193