24 |
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 |
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 |
25 |
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 |
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 |
26 |
#define FILE_ATTRIBUTE_DEVICE 0x00000040 |
#define FILE_ATTRIBUTE_DEVICE 0x00000040 |
27 |
|
#define FILE_ATTRIBUTE_UNKNOWNXXX0 0x00000060 /* ??? ACTION i.e. 0x860 == compress this file ? */ |
28 |
#define FILE_ATTRIBUTE_NORMAL 0x00000080 |
#define FILE_ATTRIBUTE_NORMAL 0x00000080 |
29 |
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 |
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 |
30 |
#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 |
#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 |
34 |
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 |
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 |
35 |
#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 |
#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 |
36 |
|
|
37 |
|
#define FILE_FLAG_OPEN_NO_RECALL 0x00100000 |
38 |
|
#define FILE_FLAG_OPEN_REPARSE_POINT 0x00200000 |
39 |
|
#define FILE_FLAG_POSIX_SEMANTICS 0x01000000 |
40 |
|
#define FILE_FLAG_BACKUP_SEMANTICS 0x02000000 /* sometimes used to create a directory */ |
41 |
|
#define FILE_FLAG_DELETE_ON_CLOSE 0x04000000 |
42 |
|
#define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000 |
43 |
|
#define FILE_FLAG_RANDOM_ACCESS 0x10000000 |
44 |
|
#define FILE_FLAG_NO_BUFFERING 0x20000000 |
45 |
|
#define FILE_FLAG_OVERLAPPED 0x40000000 |
46 |
|
#define FILE_FLAG_WRITE_THROUGH 0x80000000 |
47 |
|
|
48 |
|
#define FILE_SHARE_READ 0x01 |
49 |
|
#define FILE_SHARE_WRITE 0x02 |
50 |
|
#define FILE_SHARE_DELETE 0x04 |
51 |
|
|
52 |
#define FILE_BASIC_INFORMATION 0x04 |
#define FILE_BASIC_INFORMATION 0x04 |
53 |
#define FILE_STANDARD_INFORMATION 0x05 |
#define FILE_STANDARD_INFORMATION 0x05 |
54 |
|
|
231 |
break; |
break; |
232 |
} |
} |
233 |
|
|
234 |
/* the sad part is that we can't trust this flag */ |
//printf("Open: \"%s\" flags: %u, accessmask: %u sharemode: %u create disp: %u\n", path, flags_and_attributes, accessmask, sharemode, create_disposition); |
235 |
/* directories aren't always marked */ |
|
236 |
if (flags_and_attributes ^ FILE_DIRECTORY_FILE) |
/* since we can't trust the FILE_DIRECTORY_FILE flag */ |
237 |
|
/* we need to double check that the file isn't a dir */ |
238 |
|
struct stat filestat; |
239 |
|
|
240 |
|
// Get information about file and set that flag ourselfs |
241 |
|
if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode))) |
242 |
|
flags_and_attributes |= FILE_DIRECTORY_FILE; |
243 |
|
|
244 |
|
if (flags_and_attributes & FILE_DIRECTORY_FILE) |
245 |
{ |
{ |
246 |
if (accessmask & GENERIC_ALL |
if (flags & O_CREAT) |
|
|| (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE)) |
|
|
{ |
|
|
flags |= O_RDWR; |
|
|
} |
|
|
else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ)) |
|
|
{ |
|
|
flags |= O_WRONLY; |
|
|
} |
|
|
else |
|
247 |
{ |
{ |
248 |
flags |= O_RDONLY; |
mkdir(path, mode); |
249 |
} |
} |
250 |
|
|
251 |
handle = open(path, flags, mode); |
dirp = opendir(path); |
252 |
if (handle == -1) |
if (!dirp) |
253 |
{ |
{ |
254 |
switch (errno) |
switch (errno) |
255 |
{ |
{ |
263 |
|
|
264 |
default: |
default: |
265 |
|
|
266 |
perror("open"); |
perror("opendir"); |
267 |
return STATUS_NO_SUCH_FILE; |
return STATUS_NO_SUCH_FILE; |
268 |
} |
} |
269 |
} |
} |
270 |
|
handle = DIRFD(dirp); |
|
/* all read and writes of files should be non blocking */ |
|
|
if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1) |
|
|
perror("fcntl"); |
|
271 |
} |
} |
272 |
|
else |
|
/* since we can't trust the FILE_DIRECTORY_FILE flag */ |
|
|
/* we need to double check that the file isn't a dir */ |
|
|
if (handle != 0) |
|
273 |
{ |
{ |
|
/* Must check if this file isn't actually a directory */ |
|
|
struct stat filestat; |
|
274 |
|
|
275 |
// Get information about file and set that flag ourselfs |
if (accessmask & GENERIC_ALL |
276 |
if ((fstat(handle, &filestat) == 0) && (S_ISDIR(filestat.st_mode))) |
|| (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE)) |
277 |
{ |
{ |
278 |
flags_and_attributes |= FILE_DIRECTORY_FILE; |
flags |= O_RDWR; |
|
close(handle); |
|
|
handle = 0; |
|
279 |
} |
} |
280 |
} |
else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ)) |
|
|
|
|
|
|
|
if (flags_and_attributes & FILE_DIRECTORY_FILE) |
|
|
{ |
|
|
if (flags & O_CREAT) |
|
281 |
{ |
{ |
282 |
mkdir(path, mode); |
flags |= O_WRONLY; |
283 |
|
} |
284 |
|
else |
285 |
|
{ |
286 |
|
flags |= O_RDONLY; |
287 |
} |
} |
288 |
|
|
289 |
dirp = opendir(path); |
handle = open(path, flags, mode); |
290 |
if (!dirp) |
if (handle == -1) |
291 |
{ |
{ |
292 |
switch (errno) |
switch (errno) |
293 |
{ |
{ |
298 |
case ENOENT: |
case ENOENT: |
299 |
|
|
300 |
return STATUS_NO_SUCH_FILE; |
return STATUS_NO_SUCH_FILE; |
|
|
|
301 |
default: |
default: |
302 |
|
|
303 |
perror("opendir"); |
perror("open"); |
304 |
return STATUS_NO_SUCH_FILE; |
return STATUS_NO_SUCH_FILE; |
305 |
} |
} |
306 |
} |
} |
307 |
handle = DIRFD(dirp); |
|
308 |
|
/* all read and writes of files should be non blocking */ |
309 |
|
if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1) |
310 |
|
perror("fcntl"); |
311 |
} |
} |
312 |
|
|
313 |
if (handle >= MAX_OPEN_FILES) |
if (handle >= MAX_OPEN_FILES) |
321 |
g_fileinfo[handle].pdir = dirp; |
g_fileinfo[handle].pdir = dirp; |
322 |
g_fileinfo[handle].device_id = device_id; |
g_fileinfo[handle].device_id = device_id; |
323 |
g_fileinfo[handle].flags_and_attributes = flags_and_attributes; |
g_fileinfo[handle].flags_and_attributes = flags_and_attributes; |
|
// printf("create: attrib: %u handle %u\n", g_fileinfo[handle].flags_and_attributes, handle ); |
|
324 |
strncpy(g_fileinfo[handle].path, path, 255); |
strncpy(g_fileinfo[handle].path, path, 255); |
325 |
|
|
326 |
*phandle = handle; |
*phandle = handle; |