]>
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 VxD | |
26 | * | |
27 | * Description: C library compatible I/O functions for use within a VxD. | |
28 | * | |
29 | ****************************************************************************/ | |
30 | ||
31 | #include "pmapi.h" | |
32 | #include "vxdfile.h" | |
33 | ||
34 | /*------------------------ Main Code Implementation -----------------------*/ | |
35 | ||
36 | #define EOF -1 | |
37 | ||
38 | /**************************************************************************** | |
39 | REMARKS: | |
40 | VxD implementation of the ANSI C fopen function. | |
41 | ****************************************************************************/ | |
42 | FILE * fopen( | |
43 | const char *filename, | |
44 | const char *mode) | |
45 | { | |
46 | FILE *f = PM_malloc(sizeof(FILE)); | |
47 | long oldpos; | |
48 | ||
49 | if (f) { | |
8bde7f77 WD |
50 | f->offset = 0; |
51 | f->text = (mode[1] == 't' || mode[2] == 't'); | |
52 | f->writemode = (mode[0] == 'w') || (mode[0] == 'a'); | |
53 | if (initComplete) { | |
54 | WORD omode,error; | |
55 | BYTE action; | |
c7de829c | 56 | |
8bde7f77 WD |
57 | if (mode[0] == 'r') { |
58 | omode = OPEN_ACCESS_READONLY | OPEN_SHARE_COMPATIBLE; | |
59 | action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_FAIL; | |
60 | } | |
61 | else if (mode[0] == 'w') { | |
62 | omode = OPEN_ACCESS_WRITEONLY | OPEN_SHARE_COMPATIBLE; | |
63 | action = ACTION_IFEXISTS_TRUNCATE | ACTION_IFNOTEXISTS_CREATE; | |
64 | } | |
65 | else { | |
66 | omode = OPEN_ACCESS_READWRITE | OPEN_SHARE_COMPATIBLE; | |
67 | action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_CREATE; | |
68 | } | |
69 | f->handle = (int)R0_OpenCreateFile(false,(char*)filename,omode,ATTR_NORMAL,action,0,&error,&action); | |
70 | if (f->handle == 0) { | |
71 | PM_free(f); | |
72 | return NULL; | |
73 | } | |
74 | f->filesize = R0_GetFileSize((HANDLE)f->handle,&error); | |
75 | if (mode[0] == 'a') | |
76 | fseek(f,0,2); | |
77 | } | |
78 | else { | |
79 | int oflag,pmode; | |
c7de829c | 80 | |
8bde7f77 WD |
81 | if (mode[0] == 'r') { |
82 | pmode = _S_IREAD; | |
83 | oflag = _O_RDONLY; | |
84 | } | |
85 | else if (mode[0] == 'w') { | |
86 | pmode = _S_IWRITE; | |
87 | oflag = _O_WRONLY | _O_CREAT | _O_TRUNC; | |
88 | } | |
89 | else { | |
90 | pmode = _S_IWRITE; | |
91 | oflag = _O_RDWR | _O_CREAT | _O_APPEND; | |
92 | } | |
93 | if (f->text) | |
94 | oflag |= _O_TEXT; | |
95 | else | |
96 | oflag |= _O_BINARY; | |
97 | if ((f->handle = i_open(filename,oflag,pmode)) == -1) { | |
98 | PM_free(f); | |
99 | return NULL; | |
100 | } | |
101 | oldpos = i_lseek(f->handle,0,1); | |
102 | f->filesize = i_lseek(f->handle,0,2); | |
103 | i_lseek(f->handle,oldpos,0); | |
104 | } | |
105 | } | |
c7de829c WD |
106 | return f; |
107 | } | |
108 | ||
109 | /**************************************************************************** | |
110 | REMARKS: | |
111 | VxD implementation of the ANSI C fread function. Note that the VxD file I/O | |
112 | functions are layered on DOS, so can only read up to 64K at a time. Since | |
113 | we are expected to handle much larger chunks than this, we handle larger | |
114 | blocks automatically in here. | |
115 | ****************************************************************************/ | |
116 | size_t fread( | |
117 | void *ptr, | |
118 | size_t size, | |
119 | size_t n, | |
120 | FILE *f) | |
121 | { | |
122 | char *buf = ptr; | |
123 | WORD error; | |
124 | int bytes = size * n; | |
125 | int readbytes,totalbytes = 0; | |
126 | ||
127 | while (bytes > 0x10000) { | |
8bde7f77 WD |
128 | if (initComplete) { |
129 | readbytes = R0_ReadFile(false,(HANDLE)f->handle,buf,0x8000,f->offset,&error); | |
130 | readbytes += R0_ReadFile(false,(HANDLE)f->handle,buf+0x8000,0x8000,f->offset+0x8000,&error); | |
131 | } | |
132 | else { | |
133 | readbytes = i_read(f->handle,buf,0x8000); | |
134 | readbytes += i_read(f->handle,buf+0x8000,0x8000); | |
135 | } | |
136 | totalbytes += readbytes; | |
137 | f->offset += readbytes; | |
138 | buf += 0x10000; | |
139 | bytes -= 0x10000; | |
140 | } | |
c7de829c | 141 | if (bytes) { |
8bde7f77 WD |
142 | if (initComplete) |
143 | readbytes = R0_ReadFile(false,(HANDLE)f->handle,buf,bytes,f->offset,&error); | |
144 | else | |
145 | readbytes = i_read(f->handle,buf,bytes); | |
146 | totalbytes += readbytes; | |
147 | f->offset += readbytes; | |
148 | } | |
c7de829c WD |
149 | return totalbytes / size; |
150 | } | |
151 | ||
152 | /**************************************************************************** | |
153 | REMARKS: | |
154 | VxD implementation of the ANSI C fwrite function. Note that the VxD file I/O | |
155 | functions are layered on DOS, so can only read up to 64K at a time. Since | |
156 | we are expected to handle much larger chunks than this, we handle larger | |
157 | blocks automatically in here. | |
158 | ****************************************************************************/ | |
159 | size_t fwrite( | |
160 | const void *ptr, | |
161 | size_t size, | |
162 | size_t n, | |
163 | FILE *f) | |
164 | { | |
165 | const char *buf = ptr; | |
166 | WORD error; | |
167 | int bytes = size * n; | |
168 | int writtenbytes,totalbytes = 0; | |
169 | ||
170 | if (!f->writemode) | |
8bde7f77 | 171 | return 0; |
c7de829c | 172 | while (bytes > 0x10000) { |
8bde7f77 WD |
173 | if (initComplete) { |
174 | writtenbytes = R0_WriteFile(false,(HANDLE)f->handle,buf,0x8000,f->offset,&error); | |
175 | writtenbytes += R0_WriteFile(false,(HANDLE)f->handle,buf+0x8000,0x8000,f->offset+0x8000,&error); | |
176 | } | |
177 | else { | |
178 | writtenbytes = i_write(f->handle,buf,0x8000); | |
179 | writtenbytes += i_write(f->handle,buf+0x8000,0x8000); | |
180 | } | |
181 | totalbytes += writtenbytes; | |
182 | f->offset += writtenbytes; | |
183 | buf += 0x10000; | |
184 | bytes -= 0x10000; | |
185 | } | |
c7de829c | 186 | if (initComplete) |
8bde7f77 | 187 | writtenbytes = R0_WriteFile(false,(HANDLE)f->handle,buf,bytes,f->offset,&error); |
c7de829c | 188 | else |
8bde7f77 | 189 | writtenbytes = i_write(f->handle,buf,bytes); |
c7de829c WD |
190 | totalbytes += writtenbytes; |
191 | f->offset += writtenbytes; | |
192 | if (f->offset > f->filesize) | |
8bde7f77 | 193 | f->filesize = f->offset; |
c7de829c WD |
194 | return totalbytes / size; |
195 | } | |
196 | ||
197 | /**************************************************************************** | |
198 | REMARKS: | |
199 | VxD implementation of the ANSI C fflush function. | |
200 | ****************************************************************************/ | |
201 | int fflush( | |
202 | FILE *f) | |
203 | { | |
8bde7f77 | 204 | /* Nothing to do since we are not doing buffered file I/O */ |
c7de829c WD |
205 | (void)f; |
206 | return 0; | |
207 | } | |
208 | ||
209 | /**************************************************************************** | |
210 | REMARKS: | |
211 | VxD implementation of the ANSI C fseek function. | |
212 | ****************************************************************************/ | |
213 | int fseek( | |
214 | FILE *f, | |
215 | long int offset, | |
216 | int whence) | |
217 | { | |
218 | if (whence == 0) | |
8bde7f77 | 219 | f->offset = offset; |
c7de829c | 220 | else if (whence == 1) |
8bde7f77 | 221 | f->offset += offset; |
c7de829c | 222 | else if (whence == 2) |
8bde7f77 | 223 | f->offset = f->filesize + offset; |
c7de829c | 224 | if (!initComplete) |
8bde7f77 | 225 | i_lseek(f->handle,f->offset,0); |
c7de829c WD |
226 | return 0; |
227 | } | |
228 | ||
229 | /**************************************************************************** | |
230 | REMARKS: | |
231 | VxD implementation of the ANSI C ftell function. | |
232 | ****************************************************************************/ | |
233 | long ftell( | |
234 | FILE *f) | |
235 | { | |
236 | return f->offset; | |
237 | } | |
238 | ||
239 | /**************************************************************************** | |
240 | REMARKS: | |
241 | VxD implementation of the ANSI C feof function. | |
242 | ****************************************************************************/ | |
243 | int feof( | |
244 | FILE *f) | |
245 | { | |
246 | return (f->offset == f->filesize); | |
247 | } | |
248 | ||
249 | /**************************************************************************** | |
250 | REMARKS: | |
251 | NT driver implementation of the ANSI C fgets function. | |
252 | ****************************************************************************/ | |
253 | char *fgets( | |
254 | char *s, | |
255 | int n, | |
256 | FILE *f) | |
257 | { | |
258 | int len; | |
259 | char *cs; | |
260 | ||
8bde7f77 | 261 | /* Read the entire buffer into memory (our functions are unbuffered!) */ |
c7de829c | 262 | if ((len = fread(s,1,n,f)) == 0) |
8bde7f77 | 263 | return NULL; |
c7de829c | 264 | |
8bde7f77 | 265 | /* Search for '\n' or end of string */ |
c7de829c | 266 | if (n > len) |
8bde7f77 | 267 | n = len; |
c7de829c WD |
268 | cs = s; |
269 | while (--n > 0) { | |
8bde7f77 WD |
270 | if (*cs == '\n') |
271 | break; | |
272 | cs++; | |
273 | } | |
c7de829c WD |
274 | *cs = '\0'; |
275 | return s; | |
276 | } | |
277 | ||
278 | /**************************************************************************** | |
279 | REMARKS: | |
280 | NT driver implementation of the ANSI C fputs function. | |
281 | ****************************************************************************/ | |
282 | int fputs( | |
283 | const char *s, | |
284 | FILE *f) | |
285 | { | |
286 | return fwrite(s,1,strlen(s),f); | |
287 | } | |
288 | ||
289 | /**************************************************************************** | |
290 | REMARKS: | |
291 | VxD implementation of the ANSI C fclose function. | |
292 | ****************************************************************************/ | |
293 | int fclose( | |
294 | FILE *f) | |
295 | { | |
296 | WORD error; | |
297 | ||
298 | if (initComplete) | |
8bde7f77 | 299 | R0_CloseFile((HANDLE)f->handle,&error); |
c7de829c | 300 | else |
8bde7f77 | 301 | i_close(f->handle); |
c7de829c WD |
302 | PM_free(f); |
303 | return 0; | |
304 | } |