2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: dos/dos32krnl/bios.c
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
9 /* INCLUDES *******************************************************************/
20 #include "bios/bios.h"
22 // This is needed because on UNICODE this symbol is redirected to
23 // GetEnvironmentStringsW whereas on ANSI it corresponds to the real
24 // "ANSI" function (and GetEnvironmentStringsA is aliased to it).
25 #undef GetEnvironmentStrings
27 // Symmetrize the dumbness of the previous symbol: on UNICODE
28 // FreeEnvironmentStrings aliases to FreeEnvironmentStringsW but
29 // on "ANSI" FreeEnvironmentStrings aliases to FreeEnvironmentStringsA
30 #undef FreeEnvironmentStrings
31 #define FreeEnvironmentStrings FreeEnvironmentStringsA
33 /* PRIVATE VARIABLES **********************************************************/
35 // static BYTE CurrentDrive;
36 // static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
38 /* PRIVATE FUNCTIONS **********************************************************/
40 /* PUBLIC FUNCTIONS ***********************************************************/
42 CHAR
DosReadCharacter(WORD FileHandle
)
46 Sda
->ByteBuffer
= '\0';
47 DPRINT("DosReadCharacter\n");
49 /* Use the file reading function */
50 DosReadFile(FileHandle
,
51 MAKELONG(DOS_DATA_OFFSET(Sda
.ByteBuffer
), DOS_DATA_SEGMENT
),
55 return Sda
->ByteBuffer
;
58 BOOLEAN
DosCheckInput(VOID
)
60 PDOS_FILE_DESCRIPTOR Descriptor
= DosGetHandleFileDescriptor(DOS_INPUT_HANDLE
);
62 if (Descriptor
== NULL
)
65 Sda
->LastErrorCode
= ERROR_INVALID_HANDLE
; // ERROR_FILE_NOT_FOUND
69 if (Descriptor
->DeviceInfo
& (1 << 7))
72 PDOS_DEVICE_NODE Node
= DosGetDriverNode(Descriptor
->DevicePointer
);
74 if (!Node
->InputStatusRoutine
) return FALSE
;
76 Result
= Node
->InputStatusRoutine(Node
);
77 return !(Result
& DOS_DEVSTAT_BUSY
);
82 DWORD FileSize
= GetFileSize(Descriptor
->Win32Handle
, &FileSizeHigh
);
83 LONG LocationHigh
= 0;
84 DWORD Location
= SetFilePointer(Descriptor
->Win32Handle
, 0, &LocationHigh
, FILE_CURRENT
);
86 return ((Location
!= FileSize
) || (LocationHigh
!= FileSizeHigh
));
90 VOID
DosPrintCharacter(WORD FileHandle
, CHAR Character
)
94 Sda
->ByteBuffer
= Character
;
96 /* Use the file writing function */
97 DosWriteFile(FileHandle
,
98 MAKELONG(DOS_DATA_OFFSET(Sda
.ByteBuffer
), DOS_DATA_SEGMENT
),
103 BOOLEAN
DosBuildSysEnvBlock(VOID
)
105 LPSTR SourcePtr
, Environment
;
106 LPSTR DestPtr
= (LPSTR
)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK
, 0);
108 /* Get the environment strings */
109 SourcePtr
= Environment
= GetEnvironmentStrings();
110 if (Environment
== NULL
) return FALSE
;
112 /* Fill the DOS system environment block */
116 * - Ignore environment strings starting with a '=',
117 * they describe current directories.
118 * - Ignore also the WINDIR environment variable since
119 * DOS apps should ignore that we started from ReactOS.
120 * - Upper-case the environment names, not their values.
122 if (*SourcePtr
!= '=' && _strnicmp(SourcePtr
, "WINDIR", 6) != 0)
126 /* Copy the environment string */
127 strcpy(DestPtr
, SourcePtr
);
129 /* Upper-case the environment name */
130 Delim
= strchr(DestPtr
, '='); // Find the '=' delimiter
131 if (Delim
) *Delim
= '\0'; // Temporarily replace it by NULL
132 _strupr(DestPtr
); // Upper-case
133 if (Delim
) *Delim
= '='; // Restore the delimiter
135 DestPtr
+= strlen(SourcePtr
);
137 /* NULL-terminate the environment string */
141 /* Move to the next string */
142 SourcePtr
+= strlen(SourcePtr
) + 1;
144 /* NULL-terminate the environment block */
147 /* Free the memory allocated for environment strings */
148 FreeEnvironmentStrings(Environment
);
153 BOOLEAN
DosBIOSInitialize(VOID
)
157 CHAR CurrentDirectory
[MAX_PATH
];
158 CHAR DosDirectory
[DOS_DIR_LENGTH
];
165 /* Set the data segment */
166 setDS(DOS_DATA_SEGMENT
);
168 /* Initialize the DOS stack */
169 // Stack just before FIRST_MCB_SEGMENT and after SYSTEM_ENV_BLOCK
170 // FIXME: Add a block of fixed size for the stack in DOS_DATA instead!
173 setBP(0x091E); // DOS base stack pointer relic value
175 /* Initialize memory management */
176 DosInitializeMemory();
178 /* Build the system master environment block (inherited by the shell) */
179 if (!DosBuildSysEnvBlock())
181 DPRINT1("An error occurred when setting up the system environment block.\n");
187 /* Clear the current directory buffer */
188 RtlZeroMemory(CurrentDirectories
, sizeof(CurrentDirectories
));
190 /* Get the current directory */
191 if (!GetCurrentDirectoryA(MAX_PATH
, CurrentDirectory
))
193 // TODO: Use some kind of default path?
197 /* Convert that to a DOS path */
198 if (!GetShortPathNameA(CurrentDirectory
, DosDirectory
, DOS_DIR_LENGTH
))
200 // TODO: Use some kind of default path?
205 Sda
->CurrentDrive
= DosDirectory
[0] - 'A';
207 /* Get the directory part of the path */
208 Path
= strchr(DosDirectory
, '\\');
211 /* Skip the backslash */
215 /* Set the directory */
218 strncpy(CurrentDirectories
[Sda
->CurrentDrive
], Path
, DOS_DIR_LENGTH
);
221 /* Read CONFIG.SYS */
222 Stream
= _wfopen(DOS_CONFIG_PATH
, L
"r");
225 while (fgetws(Buffer
, ARRAYSIZE(Buffer
), Stream
))
227 // TODO: Parse the line
235 /* Register the DOS 32-bit Interrupts */
236 // RegisterDosInt32(0x20, DosInt20h);
238 /* Initialize the DOS kernel */
239 return DosKRNLInitialize();