| 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 | +}
|