2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: dos/dos32krnl/dosfiles.c
5 * PURPOSE: DOS32 Files Support
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
10 /* INCLUDES *******************************************************************/
15 // #include "callback.h"
20 #include "bios/bios.h"
22 /* PRIVATE VARIABLES **********************************************************/
24 /* PUBLIC FUNCTIONS ***********************************************************/
26 WORD
DosCreateFile(LPWORD Handle
, LPCSTR FilePath
, WORD CreationFlags
, WORD Attributes
)
31 DPRINT("DosCreateFile: FilePath \"%s\", CreationFlags 0x%04X, Attributes 0x%04X\n",
37 FileHandle
= CreateFileA(FilePath
,
38 GENERIC_READ
| GENERIC_WRITE
,
39 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
45 if (FileHandle
== INVALID_HANDLE_VALUE
)
47 /* Return the error code */
48 return (WORD
)GetLastError();
51 /* Open the DOS handle */
52 DosHandle
= DosOpenHandle(FileHandle
);
54 if (DosHandle
== INVALID_DOS_HANDLE
)
56 /* Close the handle */
57 CloseHandle(FileHandle
);
59 /* Return the error code */
60 return ERROR_TOO_MANY_OPEN_FILES
;
63 /* It was successful */
68 WORD
DosOpenFile(LPWORD Handle
, LPCSTR FilePath
, BYTE AccessShareModes
)
71 ACCESS_MASK AccessMode
= 0;
73 BOOL InheritableFile
= FALSE
;
74 SECURITY_ATTRIBUTES SecurityAttributes
;
77 DPRINT("DosOpenFile: FilePath \"%s\", AccessShareModes 0x%04X\n",
81 /* Parse the access mode */
82 switch (AccessShareModes
& 0x03)
87 AccessMode
= GENERIC_READ
;
94 AccessMode
= GENERIC_WRITE
;
101 AccessMode
= GENERIC_READ
| GENERIC_WRITE
;
108 return ERROR_INVALID_PARAMETER
;
112 /* Parse the share mode */
113 switch ((AccessShareModes
>> 4) & 0x07)
117 /* Compatibility mode */
118 ShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
;
124 /* No sharing "DenyAll" */
131 /* No write share "DenyWrite" */
132 ShareMode
= FILE_SHARE_READ
;
138 /* No read share "DenyRead" */
139 ShareMode
= FILE_SHARE_WRITE
;
145 /* Full share "DenyNone" */
146 ShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
153 return ERROR_INVALID_PARAMETER
;
157 /* Check for inheritance */
158 InheritableFile
= ((AccessShareModes
& 0x80) == 0);
160 /* Assign default security attributes to the file, and set the inheritance flag */
161 SecurityAttributes
.nLength
= sizeof(SecurityAttributes
);
162 SecurityAttributes
.lpSecurityDescriptor
= NULL
;
163 SecurityAttributes
.bInheritHandle
= InheritableFile
;
166 FileHandle
= CreateFileA(FilePath
,
171 FILE_ATTRIBUTE_NORMAL
,
174 if (FileHandle
== INVALID_HANDLE_VALUE
)
176 /* Return the error code */
177 return (WORD
)GetLastError();
180 /* Open the DOS handle */
181 DosHandle
= DosOpenHandle(FileHandle
);
183 if (DosHandle
== INVALID_DOS_HANDLE
)
185 /* Close the handle */
186 CloseHandle(FileHandle
);
188 /* Return the error code */
189 return ERROR_TOO_MANY_OPEN_FILES
;
192 /* It was successful */
194 return ERROR_SUCCESS
;
197 WORD
DosReadFile(WORD FileHandle
, LPVOID Buffer
, WORD Count
, LPWORD BytesRead
)
199 WORD Result
= ERROR_SUCCESS
;
200 DWORD BytesRead32
= 0;
201 HANDLE Handle
= DosGetRealHandle(FileHandle
);
203 DPRINT("DosReadFile: FileHandle 0x%04X, Count 0x%04X\n", FileHandle
, Count
);
205 /* Make sure the handle is valid */
206 if (Handle
== INVALID_HANDLE_VALUE
) return ERROR_INVALID_HANDLE
;
208 if (IsConsoleHandle(Handle
))
213 * Use BIOS Get Keystroke function
219 for (BytesRead32
= 0; BytesRead32
< Count
; BytesRead32
++)
221 /* Call the BIOS INT 16h, AH=00h "Get Keystroke" */
223 Int32Call(&DosContext
, BIOS_KBD_INTERRUPT
);
225 /* Retrieve the character in AL (scan code is in AH) */
228 if (DoEcho
) DosPrintCharacter(DOS_OUTPUT_HANDLE
, Character
);
230 ((PCHAR
)Buffer
)[BytesRead32
] = Character
;
232 /* Stop on first carriage return */
233 if (Character
== '\r')
235 if (DoEcho
) DosPrintCharacter(DOS_OUTPUT_HANDLE
, '\n');
248 if (!ReadFile(Handle
, Buffer
, Count
/* * sizeof(CHAR) */, &BytesRead32
, NULL
))
250 /* Store the error code */
251 Result
= (WORD
)GetLastError();
255 /* The number of bytes read is always 16-bit */
256 *BytesRead
= LOWORD(BytesRead32
);
258 /* Return the error code */
262 WORD
DosWriteFile(WORD FileHandle
, LPVOID Buffer
, WORD Count
, LPWORD BytesWritten
)
264 WORD Result
= ERROR_SUCCESS
;
265 DWORD BytesWritten32
= 0;
266 HANDLE Handle
= DosGetRealHandle(FileHandle
);
268 DPRINT("DosWriteFile: FileHandle 0x%04X, Count 0x%04X\n", FileHandle
, Count
);
270 /* Make sure the handle is valid */
271 if (Handle
== INVALID_HANDLE_VALUE
) return ERROR_INVALID_HANDLE
;
273 if (IsConsoleHandle(Handle
))
276 * Use BIOS Teletype function
283 // FIXME: Use BIOS Write String function INT 10h, AH=13h ??
285 for (BytesWritten32
= 0; BytesWritten32
< Count
; BytesWritten32
++)
287 /* Set the parameters */
288 setAL(((PCHAR
)Buffer
)[BytesWritten32
]);
289 setBL(DOS_CHAR_ATTRIBUTE
);
290 setBH(Bda
->VideoPage
);
292 /* Call the BIOS INT 10h, AH=0Eh "Teletype Output" */
294 Int32Call(&DosContext
, BIOS_VIDEO_INTERRUPT
);
299 /* Restore AX and BX */
306 if (!WriteFile(Handle
, Buffer
, Count
/* * sizeof(CHAR) */, &BytesWritten32
, NULL
))
308 /* Store the error code */
309 Result
= (WORD
)GetLastError();
313 /* The number of bytes written is always 16-bit */
314 *BytesWritten
= LOWORD(BytesWritten32
);
316 /* Return the error code */
320 WORD
DosSeekFile(WORD FileHandle
, LONG Offset
, BYTE Origin
, LPDWORD NewOffset
)
322 WORD Result
= ERROR_SUCCESS
;
324 HANDLE Handle
= DosGetRealHandle(FileHandle
);
326 DPRINT("DosSeekFile: FileHandle 0x%04X, Offset 0x%08X, Origin 0x%02X\n",
331 /* Make sure the handle is valid */
332 if (Handle
== INVALID_HANDLE_VALUE
) return ERROR_INVALID_HANDLE
;
334 /* Check if the origin is valid */
335 if (Origin
!= FILE_BEGIN
&& Origin
!= FILE_CURRENT
&& Origin
!= FILE_END
)
337 return ERROR_INVALID_FUNCTION
;
340 /* Move the file pointer */
341 if (IsConsoleHandle(Handle
))
343 /* Always succeeds when seeking a console handle */
345 Result
= ERROR_SUCCESS
;
349 FilePointer
= SetFilePointer(Handle
, Offset
, NULL
, Origin
);
352 /* Check if there's a possibility the operation failed */
353 if (FilePointer
== INVALID_SET_FILE_POINTER
)
355 /* Get the real error code */
356 Result
= (WORD
)GetLastError();
359 if (Result
!= ERROR_SUCCESS
)
361 /* The operation did fail */
365 /* Return the file pointer, if requested */
366 if (NewOffset
) *NewOffset
= FilePointer
;
369 return ERROR_SUCCESS
;
372 BOOL
DosFlushFileBuffers(WORD FileHandle
)
374 HANDLE Handle
= DosGetRealHandle(FileHandle
);
376 /* Make sure the handle is valid */
377 if (Handle
== INVALID_HANDLE_VALUE
) return FALSE
;
380 * This function can either flush files back to disks, or flush
381 * console input buffers, in which case there is no need to check
382 * whether the handle is a console handle. FlushFileBuffers()
383 * automatically does this check and calls FlushConsoleInputBuffer()
386 return FlushFileBuffers(Handle
);