enable aio of read/write files. workaround server bug where directory flag is not set on create
git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@595 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
a41bf5b907
commit
325121b29e
94
disk.c
94
disk.c
@ -163,7 +163,7 @@ disk_enum_devices(int *id, char *optarg)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opens of creates a file or directory */
|
/* Opens or creates a file or directory */
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,
|
disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,
|
||||||
uint32 flags_and_attributes, char *filename, HANDLE * phandle)
|
uint32 flags_and_attributes, char *filename, HANDLE * phandle)
|
||||||
@ -181,7 +181,6 @@ disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create
|
|||||||
if (filename[strlen(filename) - 1] == '/')
|
if (filename[strlen(filename) - 1] == '/')
|
||||||
filename[strlen(filename) - 1] = 0;
|
filename[strlen(filename) - 1] = 0;
|
||||||
sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);
|
sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);
|
||||||
//printf("Open: %s\n", path);
|
|
||||||
|
|
||||||
switch (create_disposition)
|
switch (create_disposition)
|
||||||
{
|
{
|
||||||
@ -216,35 +215,9 @@ disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create
|
|||||||
break;
|
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 & O_CREAT)
|
if (flags_and_attributes ^ FILE_DIRECTORY_FILE)
|
||||||
{
|
|
||||||
mkdir(path, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
dirp = opendir(path);
|
|
||||||
if (!dirp)
|
|
||||||
{
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
case EACCES:
|
|
||||||
|
|
||||||
return STATUS_ACCESS_DENIED;
|
|
||||||
|
|
||||||
case ENOENT:
|
|
||||||
|
|
||||||
return STATUS_NO_SUCH_FILE;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
perror("opendir");
|
|
||||||
return STATUS_NO_SUCH_FILE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handle = DIRFD(dirp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (accessmask & GENERIC_ALL
|
if (accessmask & GENERIC_ALL
|
||||||
|| (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE))
|
|| (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE))
|
||||||
@ -279,6 +252,56 @@ disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create
|
|||||||
return STATUS_NO_SUCH_FILE;
|
return STATUS_NO_SUCH_FILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* all read and writes of files should be non blocking */
|
||||||
|
if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1)
|
||||||
|
perror("fcntl");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
/* 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_and_attributes |= FILE_DIRECTORY_FILE;
|
||||||
|
close(handle);
|
||||||
|
handle = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (flags_and_attributes & FILE_DIRECTORY_FILE)
|
||||||
|
{
|
||||||
|
if (flags & O_CREAT)
|
||||||
|
{
|
||||||
|
mkdir(path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
dirp = opendir(path);
|
||||||
|
if (!dirp)
|
||||||
|
{
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
|
case EACCES:
|
||||||
|
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
|
case ENOENT:
|
||||||
|
|
||||||
|
return STATUS_NO_SUCH_FILE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
perror("opendir");
|
||||||
|
return STATUS_NO_SUCH_FILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handle = DIRFD(dirp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle >= MAX_OPEN_FILES)
|
if (handle >= MAX_OPEN_FILES)
|
||||||
@ -292,6 +315,7 @@ disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create
|
|||||||
g_fileinfo[handle].pdir = dirp;
|
g_fileinfo[handle].pdir = dirp;
|
||||||
g_fileinfo[handle].device_id = device_id;
|
g_fileinfo[handle].device_id = device_id;
|
||||||
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 );
|
||||||
strncpy(g_fileinfo[handle].path, path, 255);
|
strncpy(g_fileinfo[handle].path, path, 255);
|
||||||
|
|
||||||
*phandle = handle;
|
*phandle = handle;
|
||||||
@ -323,6 +347,14 @@ disk_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * re
|
|||||||
{
|
{
|
||||||
int n;
|
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)
|
if (offset)
|
||||||
lseek(handle, offset, SEEK_SET);
|
lseek(handle, offset, SEEK_SET);
|
||||||
n = read(handle, data, length);
|
n = read(handle, data, length);
|
||||||
|
Loading…
Reference in New Issue
Block a user