]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/MAI/bios_emulator/scitech/src/pm/ntdrv/stdio.c
* Patch by Thomas Frieden, 13 Nov 2002:
[karo-tx-uboot.git] / board / MAI / bios_emulator / scitech / src / pm / ntdrv / stdio.c
1 /****************************************************************************
2 *
3 *                   SciTech OS Portability Manager Library
4 *
5 *  ========================================================================
6 *
7 *    The contents of this file are subject to the SciTech MGL Public
8 *    License Version 1.0 (the "License"); you may not use this file
9 *    except in compliance with the License. You may obtain a copy of
10 *    the License at http://www.scitechsoft.com/mgl-license.txt
11 *
12 *    Software distributed under the License is distributed on an
13 *    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 *    implied. See the License for the specific language governing
15 *    rights and limitations under the License.
16 *
17 *    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18 *
19 *    The Initial Developer of the Original Code is SciTech Software, Inc.
20 *    All Rights Reserved.
21 *
22 *  ========================================================================
23 *
24 * Language:     ANSI C
25 * Environment:  32-bit Windows NT driver
26 *
27 * Description:  C library compatible I/O functions for use within a Windows
28 *               NT driver.
29 *
30 ****************************************************************************/
31
32 #include "pmapi.h"
33 #include "oshdr.h"
34
35 /*------------------------ Main Code Implementation -----------------------*/
36
37 /****************************************************************************
38 REMARKS:
39 NT driver implementation of the ANSI C fopen function.
40 ****************************************************************************/
41 FILE * fopen(
42     const char *filename,
43     const char *mode)
44 {
45     ACCESS_MASK                 DesiredAccess;      // for ZwCreateFile...
46     OBJECT_ATTRIBUTES           ObjectAttributes;
47     ULONG                       ShareAccess;
48     ULONG                       CreateDisposition;
49     NTSTATUS                    status;
50     HANDLE                      FileHandle;
51     UNICODE_STRING              *uniFile = NULL;
52     PWCHAR                      bufFile = NULL;
53     IO_STATUS_BLOCK             IoStatusBlock;
54     FILE_STANDARD_INFORMATION   FileInformation;
55     FILE_POSITION_INFORMATION   FilePosition;
56     char                        kernelFilename[PM_MAX_PATH+5];
57     FILE                        *f;
58
59     // Add prefix for addressing the file system. "\??\" is short for "\DosDevices\"
60     strcpy(kernelFilename, "\\??\\");
61     strcat(kernelFilename, filename);
62     if ((f = PM_malloc(sizeof(FILE))) == NULL)
63         goto Error;
64     f->offset = 0;
65     f->text = (mode[1] == 't' || mode[2] == 't');
66     f->writemode = (mode[0] == 'w') || (mode[0] == 'a');
67     if (mode[0] == 'r') {
68         // omode = OPEN_ACCESS_READONLY | OPEN_SHARE_COMPATIBLE;
69         // action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_FAIL;
70         DesiredAccess = GENERIC_READ;
71         ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE;
72         CreateDisposition = FILE_OPEN;
73         }
74     else if (mode[0] == 'w') {
75         // omode = OPEN_ACCESS_WRITEONLY | OPEN_SHARE_COMPATIBLE;
76         // action = ACTION_IFEXISTS_TRUNCATE | ACTION_IFNOTEXISTS_CREATE;
77         DesiredAccess = GENERIC_WRITE;
78         ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE;
79         CreateDisposition = FILE_SUPERSEDE;
80         }
81     else {
82         // omode = OPEN_ACCESS_READWRITE | OPEN_SHARE_COMPATIBLE;
83         // action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_CREATE;
84         DesiredAccess = GENERIC_READ | GENERIC_WRITE;
85         ShareAccess = FILE_SHARE_READ;
86         CreateDisposition = FILE_OPEN_IF;
87         }
88
89     // Convert filename string to ansi string and then to UniCode string
90     if ((uniFile = _PM_CStringToUnicodeString(kernelFilename)) == NULL)
91         return NULL;
92
93     // Create the file
94     InitializeObjectAttributes (&ObjectAttributes,
95                                 uniFile,
96                                 OBJ_CASE_INSENSITIVE,
97                                 NULL,
98                                 NULL);
99     status = ZwCreateFile( &FileHandle,
100                             DesiredAccess | SYNCHRONIZE,
101                             &ObjectAttributes,
102                             &IoStatusBlock,
103                             NULL,                   // AllocationSize  OPTIONAL,
104                             FILE_ATTRIBUTE_NORMAL,
105                             ShareAccess,
106                             CreateDisposition,
107                             FILE_RANDOM_ACCESS,     // CreateOptions,
108                             NULL,                   // EaBuffer  OPTIONAL,
109                             0                       // EaLength (required if EaBuffer)
110                             );
111     if (!NT_SUCCESS (status))
112         goto Error;
113     f->handle = (int)FileHandle;
114
115     // Determine size of the file
116     status = ZwQueryInformationFile(  FileHandle,
117                                       &IoStatusBlock,
118                                       &FileInformation,
119                                       sizeof(FILE_STANDARD_INFORMATION),
120                                       FileStandardInformation
121                                       );
122     if (!NT_SUCCESS (status))
123         goto Error;
124     f->filesize = FileInformation.EndOfFile.LowPart;
125
126     // Move to the end of the file if we are appending
127     if (mode[0] == 'a') {
128         FilePosition.CurrentByteOffset.HighPart = 0;
129         FilePosition.CurrentByteOffset.LowPart = f->filesize;
130         status = ZwSetInformationFile(  FileHandle,
131                                         &IoStatusBlock,
132                                         &FilePosition,
133                                         sizeof(FILE_POSITION_INFORMATION),
134                                         FilePositionInformation
135                                         );
136         if (!NT_SUCCESS (status))
137             goto Error;
138         }
139     return f;
140
141 Error:
142     if (f) PM_free(f);
143     if (uniFile) _PM_FreeUnicodeString(uniFile);
144     return NULL;
145 }
146
147 /****************************************************************************
148 REMARKS:
149 NT driver implementation of the ANSI C fread function.
150 ****************************************************************************/
151 size_t fread(
152     void *ptr,
153     size_t size,
154     size_t n,
155     FILE *f)
156 {
157     NTSTATUS        status;
158     IO_STATUS_BLOCK IoStatusBlock;
159     LARGE_INTEGER   ByteOffset;
160
161     // Read any extra bytes from the file
162     ByteOffset.HighPart = 0;
163     ByteOffset.LowPart = f->offset;
164     status = ZwReadFile( (HANDLE)f->handle,
165                          NULL,              //IN HANDLE  Event  OPTIONAL,
166                          NULL,              //  IN PIO_APC_ROUTINE  ApcRoutine  OPTIONAL,
167                          NULL,              //  IN PVOID  ApcContext  OPTIONAL,
168                          &IoStatusBlock,
169                          ptr,               //  OUT PVOID  Buffer,
170                          size * n,          //IN ULONG  Length,
171                          &ByteOffset,       //OPTIONAL,
172                          NULL               //IN PULONG  Key  OPTIONAL
173                          );
174     if (!NT_SUCCESS (status))
175         return 0;
176     f->offset += IoStatusBlock.Information;
177     return IoStatusBlock.Information / size;
178 }
179
180 /****************************************************************************
181 REMARKS:
182 NT driver implementation of the ANSI C fwrite function.
183 ****************************************************************************/
184 size_t fwrite(
185     const void *ptr,
186     size_t size,
187     size_t n,
188     FILE *f)
189 {
190     NTSTATUS        status;
191     IO_STATUS_BLOCK IoStatusBlock;
192     LARGE_INTEGER   ByteOffset;
193
194     if (!f->writemode)
195         return 0;
196     ByteOffset.HighPart = 0;
197     ByteOffset.LowPart = f->offset;
198     status = ZwWriteFile( (HANDLE)f->handle,
199                           NULL,             //IN HANDLE  Event  OPTIONAL,
200                           NULL,             //  IN PIO_APC_ROUTINE  ApcRoutine  OPTIONAL,
201                           NULL,             //  IN PVOID  ApcContext  OPTIONAL,
202                           &IoStatusBlock,
203                           (void*)ptr,       //  OUT PVOID  Buffer,
204                           size * n,         //IN ULONG  Length,
205                           &ByteOffset,      //OPTIONAL,
206                           NULL              //IN PULONG  Key  OPTIONAL
207                           );
208     if (!NT_SUCCESS (status))
209         return 0;
210     f->offset += IoStatusBlock.Information;
211     if (f->offset > f->filesize)
212         f->filesize = f->offset;
213     return IoStatusBlock.Information / size;
214 }
215
216 /****************************************************************************
217 REMARKS:
218 NT driver implementation of the ANSI C fflush function.
219 ****************************************************************************/
220 int fflush(
221     FILE *f)
222 {
223     // Nothing to do here as we are not doing buffered I/O
224     (void)f;
225     return 0;
226 }
227
228 /****************************************************************************
229 REMARKS:
230 NT driver implementation of the ANSI C fseek function.
231 ****************************************************************************/
232 int fseek(
233     FILE *f,
234     long int offset,
235     int whence)
236 {
237     NTSTATUS                    status;
238     FILE_POSITION_INFORMATION   FilePosition;
239     IO_STATUS_BLOCK             IoStatusBlock;
240
241     if (whence == 0)
242         f->offset = offset;
243     else if (whence == 1)
244         f->offset += offset;
245     else if (whence == 2)
246         f->offset = f->filesize + offset;
247     FilePosition.CurrentByteOffset.HighPart = 0;
248     FilePosition.CurrentByteOffset.LowPart = f->offset;
249     status = ZwSetInformationFile( (HANDLE)f->handle,
250                                    &IoStatusBlock,
251                                    &FilePosition,
252                                    sizeof(FILE_POSITION_INFORMATION),
253                                    FilePositionInformation
254                                    );
255     if (!NT_SUCCESS (status))
256         return -1;
257     return 0;
258 }
259
260 /****************************************************************************
261 REMARKS:
262 NT driver implementation of the ANSI C ftell function.
263 ****************************************************************************/
264 long ftell(
265     FILE *f)
266 {
267     return f->offset;
268 }
269
270 /****************************************************************************
271 REMARKS:
272 NT driver implementation of the ANSI C feof function.
273 ****************************************************************************/
274 int feof(
275     FILE *f)
276 {
277     return (f->offset == f->filesize);
278 }
279
280 /****************************************************************************
281 REMARKS:
282 NT driver implementation of the ANSI C fgets function.
283 ****************************************************************************/
284 char *fgets(
285     char *s,
286     int n,
287     FILE *f)
288 {
289     int     len;
290     char    *cs;
291
292     // Read the entire buffer into memory (our functions are unbuffered!)
293     if ((len = fread(s,1,n,f)) == 0)
294         return NULL;
295
296     // Search for '\n' or end of string
297     if (n > len)
298         n = len;
299     cs = s;
300     while (--n > 0) {
301         if (*cs == '\n')
302             break;
303         cs++;
304         }
305     *cs = '\0';
306     return s;
307 }
308
309 /****************************************************************************
310 REMARKS:
311 NT driver implementation of the ANSI C fputs function.
312 ****************************************************************************/
313 int fputs(
314     const char *s,
315     FILE *f)
316 {
317     return fwrite(s,1,strlen(s),f);
318 }
319
320 /****************************************************************************
321 REMARKS:
322 NT driver implementation of the ANSI C fclose function.
323 ****************************************************************************/
324 int fclose(
325     FILE *f)
326 {
327     ZwClose((HANDLE)f->handle);
328     PM_free(f);
329     return 0;
330 }
331