--- sourceforge.net/trunk/rdesktop/disk.c 2004/02/03 14:02:59 595 +++ sourceforge.net/trunk/rdesktop/disk.c 2004/02/03 14:03:42 596 @@ -163,7 +163,7 @@ return count; } -/* Opens of creates a file or directory */ +/* Opens or creates a file or directory */ NTSTATUS disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition, uint32 flags_and_attributes, char *filename, HANDLE * phandle) @@ -181,7 +181,6 @@ if (filename[strlen(filename) - 1] == '/') filename[strlen(filename) - 1] = 0; sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename); - //printf("Open: %s\n", path); switch (create_disposition) { @@ -216,15 +215,26 @@ break; } - if (flags_and_attributes & FILE_DIRECTORY_FILE) + /* the sad part is that we can't trust this flag */ + /* directories aren't always marked */ + if (flags_and_attributes ^ FILE_DIRECTORY_FILE) { - if (flags & O_CREAT) + if (accessmask & GENERIC_ALL + || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE)) { - mkdir(path, mode); + flags |= O_RDWR; + } + else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ)) + { + flags |= O_WRONLY; + } + else + { + flags |= O_RDONLY; } - dirp = opendir(path); - if (!dirp) + handle = open(path, flags, mode); + if (handle == -1) { switch (errno) { @@ -238,30 +248,42 @@ default: - perror("opendir"); + perror("open"); return STATUS_NO_SUCH_FILE; } } - handle = DIRFD(dirp); + + /* all read and writes of files should be non blocking */ + if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1) + perror("fcntl"); } - 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) { - if (accessmask & GENERIC_ALL - || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE)) - { - flags |= O_RDWR; - } - else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ)) + /* Must check if this file isn't actually a directory */ + struct stat filestat; + + // Get information about file and set that flag ourselfs + if ((fstat(handle, &filestat) == 0) && (S_ISDIR(filestat.st_mode))) { - flags |= O_WRONLY; + flags_and_attributes |= FILE_DIRECTORY_FILE; + close(handle); + handle = 0; } - else + } + + + if (flags_and_attributes & FILE_DIRECTORY_FILE) + { + if (flags & O_CREAT) { - flags |= O_RDONLY; + mkdir(path, mode); } - handle = open(path, flags, mode); - if (handle == -1) + dirp = opendir(path); + if (!dirp) { switch (errno) { @@ -275,10 +297,11 @@ default: - perror("open"); + perror("opendir"); return STATUS_NO_SUCH_FILE; } } + handle = DIRFD(dirp); } if (handle >= MAX_OPEN_FILES) @@ -292,6 +315,7 @@ g_fileinfo[handle].pdir = dirp; g_fileinfo[handle].device_id = device_id; g_fileinfo[handle].flags_and_attributes = flags_and_attributes; +// printf("create: attrib: %u handle %u\n", g_fileinfo[handle].flags_and_attributes, handle ); strncpy(g_fileinfo[handle].path, path, 255); *phandle = handle; @@ -323,6 +347,14 @@ { int n; + /* browsing dir ???? */ + /* each request is 24 bytes */ + if (g_fileinfo[handle].flags_and_attributes & FILE_DIRECTORY_FILE) + { + *result = 0; + return STATUS_SUCCESS; + } + if (offset) lseek(handle, offset, SEEK_SET); n = read(handle, data, length); @@ -603,7 +635,7 @@ // Get information for directory entry sprintf(fullpath, "%s/%s", dirname, pdirent->d_name); - /* JIF + /* JIF printf("Stat: %s\n", fullpath); */ if (stat(fullpath, &fstat)) {