Index: minilibc/file.c |
— | — | @@ -116,6 +116,8 @@ |
117 | 117 |
|
118 | 118 | FILE *fopen(const char *filename, const char *mode)
|
119 | 119 | {
|
| 120 | + int ptr = -1;
|
| 121 | + int i;
|
120 | 122 | if(!filename) return NULL;
|
121 | 123 | if(!mode) return NULL;
|
122 | 124 | if(!minilibc_files)
|
— | — | @@ -129,23 +131,165 @@ |
130 | 132 | memset(minilibc_files,0,128*sizeof(minilibc_FILE));
|
131 | 133 | maxfiles = 128;
|
132 | 134 | }
|
133 | | - minilibc_files[filecount].mode = decode_filemode(mode);
|
134 | | - if(minilibc_files[filecount].mode & MODE_ERROR)
|
| 135 | + for(i = 0; i < filecount; i++)
|
135 | 136 | {
|
| 137 | + if(minilibc_files[i].handle == INVALID_HANDLE_VALUE)
|
| 138 | + {
|
| 139 | + ptr = i;
|
| 140 | + break;
|
| 141 | + }
|
| 142 | + }
|
| 143 | + if(ptr == -1) ptr = filecount++;
|
| 144 | + if(filecount >= maxfiles)
|
| 145 | + {
|
| 146 | + minilibc_FILE *tmpptr = (minilibc_FILE*)realloc(minilibc_files,(128+maxfiles)*sizeof(minilibc_FILE));
|
| 147 | + if(!tmpptr)
|
| 148 | + {
|
| 149 | + errno = ENOMEM;
|
| 150 | + return NULL;
|
| 151 | + }
|
| 152 | + maxfiles += 128;
|
| 153 | + minilibc_files = tmpptr;
|
| 154 | + }
|
| 155 | + minilibc_files[ptr].mode = decode_filemode(mode,&minilibc_files[ptr]);
|
| 156 | + if(minilibc_files[ptr].mode & MODE_ERROR)
|
| 157 | + {
|
136 | 158 | errno = EINVAL;
|
137 | 159 | return NULL;
|
138 | 160 | }
|
139 | | - minilibc_files[filecount].handle = CreateFileA(filename,minilibc_files[filecount].DesiredAccess,
|
140 | | - minilibc_files[filecount].ShareMode,NULL,minilibc_files[filecount].CreationDisposition,
|
| 161 | + minilibc_files[ptr].handle = CreateFileA(filename,minilibc_files[ptr].DesiredAccess,
|
| 162 | + minilibc_files[ptr].ShareMode,NULL,minilibc_files[ptr].CreationDisposition,
|
141 | 163 | FILE_ATTRIBUTE_NORMAL,NULL);
|
142 | | - if(minilibc_files[filecount].handle == INVALID_HANDLE_VALUE)
|
| 164 | + if(minilibc_files[ptr].handle == INVALID_HANDLE_VALUE)
|
143 | 165 | {
|
144 | 166 | errno = EINVAL;
|
145 | 167 | return NULL;
|
146 | 168 | }
|
147 | | - filecount++;
|
148 | | - if(filecount > maxfiles)
|
| 169 | + return (FILE*)&minilibc_files[ptr];
|
| 170 | +}
|
| 171 | +
|
| 172 | +static unsigned int _w_decode_filemode(const WCHAR *mode, minilibc_FILE *file)
|
| 173 | +{
|
| 174 | + unsigned int ret = 0;
|
| 175 | + int i = 0;
|
| 176 | + while(mode[i] != 0)
|
149 | 177 | {
|
| 178 | + switch(mode[i])
|
| 179 | + {
|
| 180 | + case L'r':
|
| 181 | + ret |= MODE_READ;
|
| 182 | + break;
|
| 183 | + case L'w':
|
| 184 | + ret |= MODE_WRITE;
|
| 185 | + break;
|
| 186 | + case L'a':
|
| 187 | + ret |= MODE_APPEND;
|
| 188 | + break;
|
| 189 | + case L'+':
|
| 190 | + ret |= MODE_PLUS;
|
| 191 | + break;
|
| 192 | + case L't':
|
| 193 | + ret |= MODE_TEXT;
|
| 194 | + break;
|
| 195 | + case L'b':
|
| 196 | + ret |= MODE_BINARY;
|
| 197 | + break;
|
| 198 | + }
|
| 199 | + i++;
|
| 200 | + }
|
| 201 | + if(((ret & MODE_READ) && (ret & MODE_WRITE)) || ((ret & MODE_READ) && (ret & MODE_APPEND))
|
| 202 | + || ((ret & MODE_WRITE) && (ret & MODE_APPEND)) || ((ret & MODE_TEXT) && (ret & MODE_BINARY)))
|
| 203 | + ret |= MODE_ERROR;
|
| 204 | + switch(ret & MODE_RWMASK)
|
| 205 | + {
|
| 206 | + case 0:
|
| 207 | + case MODE_PLUS:
|
| 208 | + ret |= MODE_ERROR;
|
| 209 | + break;
|
| 210 | + case MODE_READ:
|
| 211 | + file->DesiredAccess = GENERIC_READ;
|
| 212 | + file->ShareMode = FILE_SHARE_READ;
|
| 213 | + file->CreationDisposition = OPEN_EXISTING;
|
| 214 | + break;
|
| 215 | + case MODE_WRITE:
|
| 216 | + file->DesiredAccess = GENERIC_WRITE;
|
| 217 | + file->ShareMode = 0;
|
| 218 | + file->CreationDisposition = CREATE_ALWAYS;
|
| 219 | + break;
|
| 220 | + case MODE_APPEND:
|
| 221 | + file->DesiredAccess = GENERIC_READ|GENERIC_WRITE;
|
| 222 | + file->ShareMode = 0;
|
| 223 | + file->CreationDisposition = OPEN_ALWAYS;
|
| 224 | + break;
|
| 225 | + case MODE_READ|MODE_PLUS:
|
| 226 | + file->DesiredAccess = GENERIC_READ|GENERIC_WRITE;
|
| 227 | + file->ShareMode = 0;
|
| 228 | + file->CreationDisposition = OPEN_EXISTING;
|
| 229 | + break;
|
| 230 | + case MODE_WRITE|MODE_PLUS:
|
| 231 | + file->DesiredAccess = GENERIC_READ|GENERIC_WRITE;
|
| 232 | + file->ShareMode = 0;
|
| 233 | + file->CreationDisposition = CREATE_ALWAYS;
|
| 234 | + break;
|
| 235 | + case MODE_APPEND|MODE_PLUS:
|
| 236 | + file->DesiredAccess = GENERIC_READ|GENERIC_WRITE;
|
| 237 | + file->ShareMode = 0;
|
| 238 | + file->CreationDisposition = OPEN_ALWAYS;
|
| 239 | + break;
|
| 240 | + }
|
| 241 | + return ret;
|
| 242 | +}
|
150 | 243 |
|
| 244 | +FILE *_wfopen(const WCHAR *filename, const WCHAR *mode)
|
| 245 | +{
|
| 246 | + int ptr = -1;
|
| 247 | + int i;
|
| 248 | + if(!filename) return NULL;
|
| 249 | + if(!mode) return NULL;
|
| 250 | + if(!minilibc_files)
|
| 251 | + {
|
| 252 | + minilibc_files = (minilibc_FILE*)malloc(128*sizeof(minilibc_FILE));
|
| 253 | + if(!minilibc_files)
|
| 254 | + {
|
| 255 | + errno = ENOMEM;
|
| 256 | + return NULL;
|
| 257 | + }
|
| 258 | + memset(minilibc_files,0,128*sizeof(minilibc_FILE));
|
| 259 | + maxfiles = 128;
|
151 | 260 | }
|
152 | | -} |
\ No newline at end of file |
| 261 | + for(i = 0; i < filecount; i++)
|
| 262 | + {
|
| 263 | + if(minilibc_files[i].handle == INVALID_HANDLE_VALUE)
|
| 264 | + {
|
| 265 | + ptr = i;
|
| 266 | + break;
|
| 267 | + }
|
| 268 | + }
|
| 269 | + if(ptr == -1) ptr = filecount++;
|
| 270 | + if(filecount >= maxfiles)
|
| 271 | + {
|
| 272 | + minilibc_FILE *tmpptr = (minilibc_FILE*)realloc(minilibc_files,(128+maxfiles)*sizeof(minilibc_FILE));
|
| 273 | + if(!tmpptr)
|
| 274 | + {
|
| 275 | + errno = ENOMEM;
|
| 276 | + return NULL;
|
| 277 | + }
|
| 278 | + maxfiles += 128;
|
| 279 | + minilibc_files = tmpptr;
|
| 280 | + }
|
| 281 | + minilibc_files[ptr].mode = _w_decode_filemode(mode,&minilibc_files[ptr]);
|
| 282 | + if(minilibc_files[ptr].mode & MODE_ERROR)
|
| 283 | + {
|
| 284 | + errno = EINVAL;
|
| 285 | + return NULL;
|
| 286 | + }
|
| 287 | + minilibc_files[ptr].handle = CreateFileW(filename,minilibc_files[ptr].DesiredAccess,
|
| 288 | + minilibc_files[ptr].ShareMode,NULL,minilibc_files[ptr].CreationDisposition,
|
| 289 | + FILE_ATTRIBUTE_NORMAL,NULL);
|
| 290 | + if(minilibc_files[ptr].handle == INVALID_HANDLE_VALUE)
|
| 291 | + {
|
| 292 | + errno = EINVAL;
|
| 293 | + return NULL;
|
| 294 | + }
|
| 295 | + return (FILE*)&minilibc_files[ptr];
|
| 296 | +}
|