1 /****************************************************************************
3 * SciTech OS Portability Manager Library
5 * ========================================================================
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
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.
17 * The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
19 * The Initial Developer of the Original Code is SciTech Software, Inc.
20 * All Rights Reserved.
22 * ========================================================================
25 * Environment: 32-bit Windows NT driver
27 * Description: C library compatible I/O functions for use within a Windows
30 ****************************************************************************/
35 /*------------------------ Main Code Implementation -----------------------*/
37 /****************************************************************************
39 NT driver implementation of the ANSI C fopen function.
40 ****************************************************************************/
45 ACCESS_MASK DesiredAccess; /* for ZwCreateFile... */
46 OBJECT_ATTRIBUTES ObjectAttributes;
48 ULONG CreateDisposition;
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];
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)
65 f->text = (mode[1] == 't' || mode[2] == 't');
66 f->writemode = (mode[0] == 'w') || (mode[0] == 'a');
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;
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;
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;
89 /* Convert filename string to ansi string and then to UniCode string */
90 if ((uniFile = _PM_CStringToUnicodeString(kernelFilename)) == NULL)
94 InitializeObjectAttributes (&ObjectAttributes,
99 status = ZwCreateFile( &FileHandle,
100 DesiredAccess | SYNCHRONIZE,
103 NULL, /* AllocationSize OPTIONAL, */
104 FILE_ATTRIBUTE_NORMAL,
107 FILE_RANDOM_ACCESS, /* CreateOptions, */
108 NULL, /* EaBuffer OPTIONAL, */
109 0 /* EaLength (required if EaBuffer) */
111 if (!NT_SUCCESS (status))
113 f->handle = (int)FileHandle;
115 /* Determine size of the file */
116 status = ZwQueryInformationFile( FileHandle,
119 sizeof(FILE_STANDARD_INFORMATION),
120 FileStandardInformation
122 if (!NT_SUCCESS (status))
124 f->filesize = FileInformation.EndOfFile.LowPart;
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,
133 sizeof(FILE_POSITION_INFORMATION),
134 FilePositionInformation
136 if (!NT_SUCCESS (status))
143 if (uniFile) _PM_FreeUnicodeString(uniFile);
147 /****************************************************************************
149 NT driver implementation of the ANSI C fread function.
150 ****************************************************************************/
158 IO_STATUS_BLOCK IoStatusBlock;
159 LARGE_INTEGER ByteOffset;
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, */
169 ptr, /* OUT PVOID Buffer, */
170 size * n, /*IN ULONG Length, */
171 &ByteOffset, /*OPTIONAL, */
172 NULL /*IN PULONG Key OPTIONAL */
174 if (!NT_SUCCESS (status))
176 f->offset += IoStatusBlock.Information;
177 return IoStatusBlock.Information / size;
180 /****************************************************************************
182 NT driver implementation of the ANSI C fwrite function.
183 ****************************************************************************/
191 IO_STATUS_BLOCK IoStatusBlock;
192 LARGE_INTEGER ByteOffset;
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, */
203 (void*)ptr, /* OUT PVOID Buffer, */
204 size * n, /*IN ULONG Length, */
205 &ByteOffset, /*OPTIONAL, */
206 NULL /*IN PULONG Key OPTIONAL */
208 if (!NT_SUCCESS (status))
210 f->offset += IoStatusBlock.Information;
211 if (f->offset > f->filesize)
212 f->filesize = f->offset;
213 return IoStatusBlock.Information / size;
216 /****************************************************************************
218 NT driver implementation of the ANSI C fflush function.
219 ****************************************************************************/
223 /* Nothing to do here as we are not doing buffered I/O */
228 /****************************************************************************
230 NT driver implementation of the ANSI C fseek function.
231 ****************************************************************************/
238 FILE_POSITION_INFORMATION FilePosition;
239 IO_STATUS_BLOCK IoStatusBlock;
243 else if (whence == 1)
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,
252 sizeof(FILE_POSITION_INFORMATION),
253 FilePositionInformation
255 if (!NT_SUCCESS (status))
260 /****************************************************************************
262 NT driver implementation of the ANSI C ftell function.
263 ****************************************************************************/
270 /****************************************************************************
272 NT driver implementation of the ANSI C feof function.
273 ****************************************************************************/
277 return (f->offset == f->filesize);
280 /****************************************************************************
282 NT driver implementation of the ANSI C fgets function.
283 ****************************************************************************/
292 /* Read the entire buffer into memory (our functions are unbuffered!) */
293 if ((len = fread(s,1,n,f)) == 0)
296 /* Search for '\n' or end of string */
309 /****************************************************************************
311 NT driver implementation of the ANSI C fputs function.
312 ****************************************************************************/
317 return fwrite(s,1,strlen(s),f);
320 /****************************************************************************
322 NT driver implementation of the ANSI C fclose function.
323 ****************************************************************************/
327 ZwClose((HANDLE)f->handle);