2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
9 /* INCLUDES *******************************************************************/
24 #include "bios/bios.h"
26 // This is needed because on UNICODE this symbol is redirected to
27 // GetEnvironmentStringsW whereas on ANSI it corresponds to the real
28 // "ANSI" function (and GetEnvironmentStringsA is aliased to it).
29 #undef GetEnvironmentStrings
31 // Symmetrize the dumbness of the previous symbol: on UNICODE
32 // FreeEnvironmentStrings aliases to FreeEnvironmentStringsW but
33 // on "ANSI" FreeEnvironmentStrings aliases to FreeEnvironmentStringsA
34 #undef FreeEnvironmentStrings
35 #define FreeEnvironmentStrings FreeEnvironmentStringsA
37 /* PRIVATE VARIABLES **********************************************************/
39 /* PUBLIC VARIABLES ***********************************************************/
41 /* Global DOS BIOS data area */
44 /* PRIVATE FUNCTIONS **********************************************************/
46 /* PUBLIC FUNCTIONS ***********************************************************/
48 VOID
DosEchoCharacter(CHAR Character
)
60 /* Erase the character */
61 DosPrintCharacter(DOS_OUTPUT_HANDLE
, '\b');
62 DosPrintCharacter(DOS_OUTPUT_HANDLE
, ' ');
63 DosPrintCharacter(DOS_OUTPUT_HANDLE
, '\b');
70 * Check if this is a special character
71 * NOTE: \r and \n are handled by the underlying driver!
73 if (Character
< 0x20 && Character
!= '\r' && Character
!= '\n')
75 DosPrintCharacter(DOS_OUTPUT_HANDLE
, '^');
79 /* Echo the character */
80 DosPrintCharacter(DOS_OUTPUT_HANDLE
, Character
);
85 CHAR
DosReadCharacter(WORD FileHandle
, BOOLEAN Echo
)
88 PDOS_FILE_DESCRIPTOR Descriptor
= NULL
;
91 /* Find the standard input descriptor and switch it to binary mode */
92 Descriptor
= DosGetHandleFileDescriptor(FileHandle
);
95 OldDeviceInfo
= Descriptor
->DeviceInfo
;
96 Descriptor
->DeviceInfo
|= FILE_INFO_BINARY
;
99 Sda
->ByteBuffer
= '\0';
100 DPRINT("DosReadCharacter\n");
102 /* Use the file reading function */
103 DosReadFile(FileHandle
,
104 MAKELONG(DOS_DATA_OFFSET(Sda
.ByteBuffer
), DOS_DATA_SEGMENT
),
108 /* Check if we should echo and the file is actually the CON device */
109 if (Echo
&& Descriptor
&& Descriptor
->DeviceInfo
& FILE_INFO_DEVICE
)
111 /* Echo the character */
112 DosEchoCharacter(Sda
->ByteBuffer
);
115 /* Restore the old mode and return the character */
116 if (Descriptor
) Descriptor
->DeviceInfo
= OldDeviceInfo
;
117 return Sda
->ByteBuffer
;
120 BOOLEAN
DosCheckInput(VOID
)
122 PDOS_FILE_DESCRIPTOR Descriptor
= DosGetHandleFileDescriptor(DOS_INPUT_HANDLE
);
124 if (Descriptor
== NULL
)
127 Sda
->LastErrorCode
= ERROR_INVALID_HANDLE
; // ERROR_FILE_NOT_FOUND
131 if (Descriptor
->DeviceInfo
& FILE_INFO_DEVICE
)
134 PDOS_DEVICE_NODE Node
= DosGetDriverNode(Descriptor
->DevicePointer
);
136 if (!Node
->InputStatusRoutine
) return FALSE
;
138 Result
= Node
->InputStatusRoutine(Node
);
139 return !(Result
& DOS_DEVSTAT_BUSY
);
144 DWORD FileSize
= GetFileSize(Descriptor
->Win32Handle
, &FileSizeHigh
);
145 LONG LocationHigh
= 0;
146 DWORD Location
= SetFilePointer(Descriptor
->Win32Handle
, 0, &LocationHigh
, FILE_CURRENT
);
148 return ((Location
!= FileSize
) || (LocationHigh
!= FileSizeHigh
));
152 VOID
DosPrintCharacter(WORD FileHandle
, CHAR Character
)
156 Sda
->ByteBuffer
= Character
;
158 /* Use the file writing function */
159 DosWriteFile(FileHandle
,
160 MAKELONG(DOS_DATA_OFFSET(Sda
.ByteBuffer
), DOS_DATA_SEGMENT
),
165 BOOLEAN
DosBuildSysEnvBlock(VOID
)
167 LPSTR SourcePtr
, Environment
;
168 LPSTR DestPtr
= (LPSTR
)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK
, 0);
171 * Get the environment strings
173 * NOTE: On non-STANDALONE builds, this corresponds to the VDM environment
174 * as created by BaseVDM for NTVDM. On STANDALONE builds this is the Win32
175 * environment. In this last case we need to convert it to a proper VDM env.
177 SourcePtr
= Environment
= GetEnvironmentStrings();
178 if (Environment
== NULL
) return FALSE
;
180 /* Fill the DOS system environment block */
184 * - Ignore environment strings starting with a '=',
185 * they describe current directories.
186 * - Ignore also the WINDIR environment variable since
187 * DOS apps should ignore that we started from ReactOS.
188 * - Upper-case the environment names, not their values.
190 if (*SourcePtr
!= '=' && _strnicmp(SourcePtr
, "WINDIR", 6) != 0)
194 /* Copy the environment string */
195 strcpy(DestPtr
, SourcePtr
);
197 /* Upper-case the environment name */
198 Delim
= strchr(DestPtr
, '='); // Find the '=' delimiter
199 if (Delim
) *Delim
= '\0'; // Temporarily replace it by NULL
200 _strupr(DestPtr
); // Upper-case
201 if (Delim
) *Delim
= '='; // Restore the delimiter
203 DestPtr
+= strlen(SourcePtr
);
205 /* NULL-terminate the environment string */
209 /* Move to the next string */
210 SourcePtr
+= strlen(SourcePtr
) + 1;
212 /* NULL-terminate the environment block */
215 /* Free the memory allocated for environment strings */
216 FreeEnvironmentStrings(Environment
);
221 BOOLEAN
DosBIOSInitialize(VOID
)
226 /* Set the data segment */
227 setDS(BIOS_DATA_SEGMENT
);
229 /* Initialize the global DOS BIOS data area */
230 BiosData
= (PBIOS_DATA
)SEG_OFF_TO_PTR(BIOS_DATA_SEGMENT
, 0x0000);
232 /* Initialize the DOS BIOS stack */
233 // FIXME: Add a block of fixed size for the stack in BIOS/DOS_DATA instead!
236 /// setBP(0x091E); // DOS base stack pointer relic value
239 * Initialize the INT 13h (BIOS Disk Services) handler chain support.
241 * The INT 13h handler chain is some functionality that allows DOS
242 * to insert disk filter drivers in between the (hooked) INT 13h handler
243 * and its original handler.
244 * Typically, those are:
245 * - filter for detecting disk changes (for floppy disks),
246 * - filter for tracking formatting calls and correcting DMA boundary errors,
247 * - a possible filter to work around a bug in a particular version of PC-AT's
248 * IBM's ROM BIOS (on systems with model byte FCh and BIOS date "01/10/84" only)
249 * (see http://www.ctyme.com/intr/rb-4453.htm for more details).
251 * This functionality is known to be used by some legitimate programs,
252 * by Windows 3.x, as well as some illegitimate ones (aka. virii).
254 * See extra information about this support in dos.h
256 // FIXME: Should be done by the DOS BIOS
257 BiosData
->RomBiosInt13
= ((PULONG
)BaseAddress
)[0x13];
258 BiosData
->PrevInt13
= BiosData
->RomBiosInt13
;
259 // RegisterDosInt32(0x13, DosInt13h); // Unused at the moment!
262 // HERE: Do all hardware initialization needed for DOS
269 /* Initialize the DOS kernel (DosInit) */
270 if (!DosKRNLInitialize())
272 BiosDisplayMessage("Failed to load the DOS kernel! Exiting...\n");
276 /* DOS kernel loading succeeded, we can finish the initialization */
278 /* Build the system master (pre-) environment block (inherited by the shell) */
279 if (!DosBuildSysEnvBlock())
281 DosDisplayMessage("An error occurred when setting up the system environment block.\n");
284 /* TODO: Read CONFIG.NT/SYS */
285 Stream
= _wfopen(DOS_CONFIG_PATH
, L
"r");
288 while (fgetws(Buffer
, ARRAYSIZE(Buffer
), Stream
))
290 // TODO: Parse the line