[BASESRV][NTVDM][TESTVDD] Improve the FILE header section. Brought to you by Adam...
[reactos.git] / reactos / subsystems / mvdm / ntvdm / dos / dos32krnl / bios.c
1 /*
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
5 * PURPOSE: DOS32 Bios
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #define NDEBUG
12
13 #include "ntvdm.h"
14 #include "emulator.h"
15 #include "int32.h"
16
17 #include "../dem.h"
18 #include "dos.h"
19 #include "dosfiles.h"
20 #include "memory.h"
21 #include "bios/bios.h"
22
23 // This is needed because on UNICODE this symbol is redirected to
24 // GetEnvironmentStringsW whereas on ANSI it corresponds to the real
25 // "ANSI" function (and GetEnvironmentStringsA is aliased to it).
26 #undef GetEnvironmentStrings
27
28 // Symmetrize the dumbness of the previous symbol: on UNICODE
29 // FreeEnvironmentStrings aliases to FreeEnvironmentStringsW but
30 // on "ANSI" FreeEnvironmentStrings aliases to FreeEnvironmentStringsA
31 #undef FreeEnvironmentStrings
32 #define FreeEnvironmentStrings FreeEnvironmentStringsA
33
34 /* PRIVATE VARIABLES **********************************************************/
35
36 /* PUBLIC VARIABLES ***********************************************************/
37
38 /* Global DOS BIOS data area */
39 PBIOS_DATA BiosData;
40
41 /* PRIVATE FUNCTIONS **********************************************************/
42
43 /* PUBLIC FUNCTIONS ***********************************************************/
44
45 CHAR DosReadCharacter(WORD FileHandle)
46 {
47 WORD BytesRead;
48
49 Sda->ByteBuffer = '\0';
50 DPRINT("DosReadCharacter\n");
51
52 /* Use the file reading function */
53 DosReadFile(FileHandle,
54 MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer), DOS_DATA_SEGMENT),
55 1,
56 &BytesRead);
57
58 return Sda->ByteBuffer;
59 }
60
61 BOOLEAN DosCheckInput(VOID)
62 {
63 PDOS_FILE_DESCRIPTOR Descriptor = DosGetHandleFileDescriptor(DOS_INPUT_HANDLE);
64
65 if (Descriptor == NULL)
66 {
67 /* Invalid handle */
68 Sda->LastErrorCode = ERROR_INVALID_HANDLE; // ERROR_FILE_NOT_FOUND
69 return FALSE;
70 }
71
72 if (Descriptor->DeviceInfo & FILE_INFO_DEVICE)
73 {
74 WORD Result;
75 PDOS_DEVICE_NODE Node = DosGetDriverNode(Descriptor->DevicePointer);
76
77 if (!Node->InputStatusRoutine) return FALSE;
78
79 Result = Node->InputStatusRoutine(Node);
80 return !(Result & DOS_DEVSTAT_BUSY);
81 }
82 else
83 {
84 DWORD FileSizeHigh;
85 DWORD FileSize = GetFileSize(Descriptor->Win32Handle, &FileSizeHigh);
86 LONG LocationHigh = 0;
87 DWORD Location = SetFilePointer(Descriptor->Win32Handle, 0, &LocationHigh, FILE_CURRENT);
88
89 return ((Location != FileSize) || (LocationHigh != FileSizeHigh));
90 }
91 }
92
93 VOID DosPrintCharacter(WORD FileHandle, CHAR Character)
94 {
95 WORD BytesWritten;
96
97 Sda->ByteBuffer = Character;
98
99 /* Use the file writing function */
100 DosWriteFile(FileHandle,
101 MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer), DOS_DATA_SEGMENT),
102 1,
103 &BytesWritten);
104 }
105
106 BOOLEAN DosBuildSysEnvBlock(VOID)
107 {
108 LPSTR SourcePtr, Environment;
109 LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
110
111 /*
112 * Get the environment strings
113 *
114 * NOTE: On non-STANDALONE builds, this corresponds to the VDM environment
115 * as created by BaseVDM for NTVDM. On STANDALONE builds this is the Win32
116 * environment. In this last case we need to convert it to a proper VDM env.
117 */
118 SourcePtr = Environment = GetEnvironmentStrings();
119 if (Environment == NULL) return FALSE;
120
121 /* Fill the DOS system environment block */
122 while (*SourcePtr)
123 {
124 /*
125 * - Ignore environment strings starting with a '=',
126 * they describe current directories.
127 * - Ignore also the WINDIR environment variable since
128 * DOS apps should ignore that we started from ReactOS.
129 * - Upper-case the environment names, not their values.
130 */
131 if (*SourcePtr != '=' && _strnicmp(SourcePtr, "WINDIR", 6) != 0)
132 {
133 PCHAR Delim = NULL;
134
135 /* Copy the environment string */
136 strcpy(DestPtr, SourcePtr);
137
138 /* Upper-case the environment name */
139 Delim = strchr(DestPtr, '='); // Find the '=' delimiter
140 if (Delim) *Delim = '\0'; // Temporarily replace it by NULL
141 _strupr(DestPtr); // Upper-case
142 if (Delim) *Delim = '='; // Restore the delimiter
143
144 DestPtr += strlen(SourcePtr);
145
146 /* NULL-terminate the environment string */
147 *(DestPtr++) = '\0';
148 }
149
150 /* Move to the next string */
151 SourcePtr += strlen(SourcePtr) + 1;
152 }
153 /* NULL-terminate the environment block */
154 *DestPtr = '\0';
155
156 /* Free the memory allocated for environment strings */
157 FreeEnvironmentStrings(Environment);
158
159 return TRUE;
160 }
161
162 BOOLEAN DosBIOSInitialize(VOID)
163 {
164 FILE *Stream;
165 WCHAR Buffer[256];
166
167 /* Set the data segment */
168 setDS(BIOS_DATA_SEGMENT);
169
170 /* Initialize the global DOS BIOS data area */
171 BiosData = (PBIOS_DATA)SEG_OFF_TO_PTR(BIOS_DATA_SEGMENT, 0x0000);
172
173 /* Initialize the DOS BIOS stack */
174 // FIXME: Add a block of fixed size for the stack in BIOS/DOS_DATA instead!
175 setSS(0x0F00);
176 setSP(0x0FF0);
177 /// setBP(0x091E); // DOS base stack pointer relic value
178
179 /*
180 * Initialize the INT 13h (BIOS Disk Services) handler chain support.
181 *
182 * The INT 13h handler chain is some functionality that allows DOS
183 * to insert disk filter drivers in between the (hooked) INT 13h handler
184 * and its original handler.
185 * Typically, those are:
186 * - filter for detecting disk changes (for floppy disks),
187 * - filter for tracking formatting calls and correcting DMA boundary errors,
188 * - a possible filter to work around a bug in a particular version of PC-AT's
189 * IBM's ROM BIOS (on systems with model byte FCh and BIOS date "01/10/84" only)
190 * (see http://www.ctyme.com/intr/rb-4453.htm for more details).
191 *
192 * This functionality is known to be used by some legitimate programs,
193 * by Windows 3.x, as well as some illegitimate ones (aka. virii).
194 *
195 * See extra information about this support in dos.h
196 */
197 // FIXME: Should be done by the DOS BIOS
198 BiosData->RomBiosInt13 = ((PULONG)BaseAddress)[0x13];
199 BiosData->PrevInt13 = BiosData->RomBiosInt13;
200 // RegisterDosInt32(0x13, DosInt13h); // Unused at the moment!
201
202 //
203 // HERE: Do all hardware initialization needed for DOS
204 //
205
206 /*
207 * SysInit part...
208 */
209
210 /* Initialize the DOS kernel (DosInit) */
211 if (!DosKRNLInitialize())
212 {
213 BiosDisplayMessage("Failed to load the DOS kernel! Exiting...\n");
214 return FALSE;
215 }
216
217 /* DOS kernel loading succeeded, we can finish the initialization */
218
219 /* Build the system master (pre-) environment block (inherited by the shell) */
220 if (!DosBuildSysEnvBlock())
221 {
222 DosDisplayMessage("An error occurred when setting up the system environment block.\n");
223 }
224
225 /* TODO: Read CONFIG.NT/SYS */
226 Stream = _wfopen(DOS_CONFIG_PATH, L"r");
227 if (Stream != NULL)
228 {
229 while (fgetws(Buffer, ARRAYSIZE(Buffer), Stream))
230 {
231 // TODO: Parse the line
232 }
233 fclose(Stream);
234 }
235
236 return TRUE;
237 }
238
239 /* EOF */