]>
Commit | Line | Data |
---|---|---|
c7de829c WD |
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 | { | |
8bde7f77 | 45 | ACCESS_MASK DesiredAccess; /* for ZwCreateFile... */ |
c7de829c WD |
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 | ||
8bde7f77 | 59 | /* Add prefix for addressing the file system. "\??\" is short for "\DosDevices\" */ |
c7de829c WD |
60 | strcpy(kernelFilename, "\\??\\"); |
61 | strcat(kernelFilename, filename); | |
62 | if ((f = PM_malloc(sizeof(FILE))) == NULL) | |
8bde7f77 | 63 | goto Error; |
c7de829c WD |
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') { | |
8bde7f77 WD |
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 | } | |
c7de829c | 74 | else if (mode[0] == 'w') { |
8bde7f77 WD |
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 | } | |
c7de829c | 81 | else { |
8bde7f77 WD |
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 | } | |
c7de829c | 88 | |
8bde7f77 | 89 | /* Convert filename string to ansi string and then to UniCode string */ |
c7de829c | 90 | if ((uniFile = _PM_CStringToUnicodeString(kernelFilename)) == NULL) |
8bde7f77 | 91 | return NULL; |
c7de829c | 92 | |
8bde7f77 | 93 | /* Create the file */ |
c7de829c | 94 | InitializeObjectAttributes (&ObjectAttributes, |
8bde7f77 WD |
95 | uniFile, |
96 | OBJ_CASE_INSENSITIVE, | |
97 | NULL, | |
98 | NULL); | |
c7de829c | 99 | status = ZwCreateFile( &FileHandle, |
8bde7f77 WD |
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 | ); | |
c7de829c | 111 | if (!NT_SUCCESS (status)) |
8bde7f77 | 112 | goto Error; |
c7de829c WD |
113 | f->handle = (int)FileHandle; |
114 | ||
8bde7f77 | 115 | /* Determine size of the file */ |
c7de829c | 116 | status = ZwQueryInformationFile( FileHandle, |
8bde7f77 WD |
117 | &IoStatusBlock, |
118 | &FileInformation, | |
119 | sizeof(FILE_STANDARD_INFORMATION), | |
120 | FileStandardInformation | |
121 | ); | |
c7de829c | 122 | if (!NT_SUCCESS (status)) |
8bde7f77 | 123 | goto Error; |
c7de829c WD |
124 | f->filesize = FileInformation.EndOfFile.LowPart; |
125 | ||
8bde7f77 | 126 | /* Move to the end of the file if we are appending */ |
c7de829c | 127 | if (mode[0] == 'a') { |
8bde7f77 WD |
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 | } | |
c7de829c WD |
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 | ||
8bde7f77 | 161 | /* Read any extra bytes from the file */ |
c7de829c WD |
162 | ByteOffset.HighPart = 0; |
163 | ByteOffset.LowPart = f->offset; | |
164 | status = ZwReadFile( (HANDLE)f->handle, | |
8bde7f77 WD |
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 | ); | |
c7de829c | 174 | if (!NT_SUCCESS (status)) |
8bde7f77 | 175 | return 0; |
c7de829c WD |
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) | |
8bde7f77 | 195 | return 0; |
c7de829c WD |
196 | ByteOffset.HighPart = 0; |
197 | ByteOffset.LowPart = f->offset; | |
198 | status = ZwWriteFile( (HANDLE)f->handle, | |
8bde7f77 WD |
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 | ); | |
c7de829c | 208 | if (!NT_SUCCESS (status)) |
8bde7f77 | 209 | return 0; |
c7de829c WD |
210 | f->offset += IoStatusBlock.Information; |
211 | if (f->offset > f->filesize) | |
8bde7f77 | 212 | f->filesize = f->offset; |
c7de829c WD |
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 | { | |
8bde7f77 | 223 | /* Nothing to do here as we are not doing buffered I/O */ |
c7de829c WD |
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) | |
8bde7f77 | 242 | f->offset = offset; |
c7de829c | 243 | else if (whence == 1) |
8bde7f77 | 244 | f->offset += offset; |
c7de829c | 245 | else if (whence == 2) |
8bde7f77 | 246 | f->offset = f->filesize + offset; |
c7de829c WD |
247 | FilePosition.CurrentByteOffset.HighPart = 0; |
248 | FilePosition.CurrentByteOffset.LowPart = f->offset; | |
249 | status = ZwSetInformationFile( (HANDLE)f->handle, | |
8bde7f77 WD |
250 | &IoStatusBlock, |
251 | &FilePosition, | |
252 | sizeof(FILE_POSITION_INFORMATION), | |
253 | FilePositionInformation | |
254 | ); | |
c7de829c | 255 | if (!NT_SUCCESS (status)) |
8bde7f77 | 256 | return -1; |
c7de829c WD |
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 | ||
8bde7f77 | 292 | /* Read the entire buffer into memory (our functions are unbuffered!) */ |
c7de829c | 293 | if ((len = fread(s,1,n,f)) == 0) |
8bde7f77 | 294 | return NULL; |
c7de829c | 295 | |
8bde7f77 | 296 | /* Search for '\n' or end of string */ |
c7de829c | 297 | if (n > len) |
8bde7f77 | 298 | n = len; |
c7de829c WD |
299 | cs = s; |
300 | while (--n > 0) { | |
8bde7f77 WD |
301 | if (*cs == '\n') |
302 | break; | |
303 | cs++; | |
304 | } | |
c7de829c WD |
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 | } |