max_path: get_name() avoids copying from upcall buffer
because we no longer have to convert strings from unicode, we can avoid copying them out of the upcall buffer Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
feb441ab4d
commit
f727a1e4b4
8 changed files with 49 additions and 67 deletions
|
|
@ -35,14 +35,13 @@ int parse_mount(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
|||
int status;
|
||||
mount_upcall_args *args = &upcall->args.mount;
|
||||
|
||||
status = get_name(&buffer, &length, args->srv_name);
|
||||
status = get_name(&buffer, &length, &args->hostname);
|
||||
if(status) goto out;
|
||||
ZeroMemory(&args->path, sizeof(nfs41_abs_path));
|
||||
status = get_abs_path(&buffer, &length, &args->path);
|
||||
status = get_name(&buffer, &length, &args->path);
|
||||
if(status) goto out;
|
||||
|
||||
dprintf(1, "parsing NFS14_MOUNT: srv_name=%s root=%s\n",
|
||||
args->srv_name, args->path.path);
|
||||
args->hostname, args->path);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
@ -57,13 +56,13 @@ int handle_mount(nfs41_upcall *upcall)
|
|||
nfs41_client *client;
|
||||
|
||||
// resolve hostname,port
|
||||
status = nfs41_server_resolve(args->srv_name, port, &addrs);
|
||||
status = nfs41_server_resolve(args->hostname, port, &addrs);
|
||||
if (status) {
|
||||
eprintf("nfs41_server_resolve() failed with %d\n", status);
|
||||
goto out;
|
||||
}
|
||||
// create root
|
||||
status = nfs41_root_create(args->srv_name, port, &args->path,
|
||||
status = nfs41_root_create(args->hostname, port, &args->path,
|
||||
NFS41_MAX_FILEIO_SIZE + WRITE_OVERHEAD,
|
||||
NFS41_MAX_FILEIO_SIZE + READ_OVERHEAD, &root);
|
||||
if (status) {
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ typedef struct __nfs41_root {
|
|||
int nfs41_root_create(
|
||||
IN const char *hostname,
|
||||
IN unsigned short port,
|
||||
IN const nfs41_abs_path *path,
|
||||
IN const char *path,
|
||||
IN uint32_t wsize,
|
||||
IN uint32_t rsize,
|
||||
OUT nfs41_root **root_out);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
|
||||
static int create_open_state(
|
||||
IN const nfs41_abs_path *path,
|
||||
IN const char *path,
|
||||
IN uint32_t open_owner_id,
|
||||
OUT nfs41_open_state **state_out)
|
||||
{
|
||||
|
|
@ -47,7 +47,11 @@ static int create_open_state(
|
|||
}
|
||||
|
||||
InitializeSRWLock(&state->path.lock);
|
||||
abs_path_copy(&state->path, path);
|
||||
if (FAILED(StringCchCopyA(state->path.path, NFS41_MAX_PATH_LEN, path))) {
|
||||
status = ERROR_BUFFER_OVERFLOW;
|
||||
goto out_free;
|
||||
}
|
||||
state->path.len = (unsigned short)strlen(state->path.path);
|
||||
path_fh_init(&state->file, &state->path);
|
||||
path_fh_init(&state->parent, &state->path);
|
||||
last_component(state->path.path, state->file.name.name,
|
||||
|
|
@ -62,6 +66,10 @@ static int create_open_state(
|
|||
status = NO_ERROR;
|
||||
out:
|
||||
return status;
|
||||
|
||||
out_free:
|
||||
free(state);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static void free_open_state(
|
||||
|
|
@ -78,8 +86,7 @@ int parse_open(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
|||
int status;
|
||||
open_upcall_args *args = &upcall->args.open;
|
||||
|
||||
ZeroMemory(&args->path, sizeof(nfs41_abs_path));
|
||||
status = get_abs_path(&buffer, &length, &args->path);
|
||||
status = get_name(&buffer, &length, &args->path);
|
||||
if (status) goto out;
|
||||
status = safe_read(&buffer, &length, &args->access_mask, sizeof(ULONG));
|
||||
if (status) goto out;
|
||||
|
|
@ -101,7 +108,7 @@ int parse_open(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
|||
dprintf(1, "parsing NFS41_OPEN: filename='%s' access mask=%d "
|
||||
"access mode=%d\n\tfile attrs=0x%x create attrs=0x%x "
|
||||
"(kernel) disposition=%d\n\tsession=%p open_owner_id=%d mode=%o\n",
|
||||
args->path.path, args->access_mask, args->access_mode, args->file_attrs,
|
||||
args->path, args->access_mask, args->access_mode, args->file_attrs,
|
||||
args->create_opts, args->disposition, args->root, args->open_owner_id,
|
||||
args->mode);
|
||||
print_disposition(2, args->disposition);
|
||||
|
|
@ -315,7 +322,7 @@ int handle_open(nfs41_upcall *upcall)
|
|||
nfs41_open_state *state;
|
||||
nfs41_file_info info;
|
||||
|
||||
status = create_open_state(&args->path, args->open_owner_id, &state);
|
||||
status = create_open_state(args->path, args->open_owner_id, &state);
|
||||
if (status) {
|
||||
eprintf("create_open_state(%u) failed with %d\n",
|
||||
args->open_owner_id, status);
|
||||
|
|
@ -338,7 +345,7 @@ int handle_open(nfs41_upcall *upcall)
|
|||
dprintf(2, "handle_nfs41_open: DIRECTORY\n");
|
||||
if (args->create_opts & FILE_NON_DIRECTORY_FILE) {
|
||||
eprintf("trying to open directory %s as a file\n",
|
||||
args->path.path);
|
||||
state->path.path);
|
||||
status = ERROR_ACCESS_DENIED;
|
||||
goto out_free_state;
|
||||
}
|
||||
|
|
@ -346,7 +353,7 @@ int handle_open(nfs41_upcall *upcall)
|
|||
dprintf(2, "handle nfs41_open: FILE\n");
|
||||
if (args->create_opts & FILE_DIRECTORY_FILE) {
|
||||
eprintf("trying to open file %s as a directory\n",
|
||||
args->path.path);
|
||||
state->path.path);
|
||||
#ifdef NOTEPAD_OPEN_FILE_AS_DIRFILE_FIXED
|
||||
status = ERROR_ACCESS_DENIED;
|
||||
goto out_free_state;
|
||||
|
|
@ -468,7 +475,7 @@ int cancel_open(IN nfs41_upcall *upcall)
|
|||
open_upcall_args *args = &upcall->args.open;
|
||||
nfs41_open_state *state = args->state;
|
||||
|
||||
dprintf(1, "--> cancel_open('%s')\n", args->path.path);
|
||||
dprintf(1, "--> cancel_open('%s')\n", args->path);
|
||||
|
||||
if (upcall->status)
|
||||
goto out; /* if handle_open() failed, the state was already freed */
|
||||
|
|
@ -507,8 +514,7 @@ int parse_close(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
|||
status = safe_read(&buffer, &length, &args->remove, sizeof(BOOLEAN));
|
||||
if (status) goto out;
|
||||
if (args->remove) {
|
||||
ZeroMemory(&args->path, sizeof(nfs41_abs_path));
|
||||
status = get_abs_path(&buffer, &length, &args->path);
|
||||
status = get_name(&buffer, &length, &args->path);
|
||||
if (status) goto out;
|
||||
status = safe_read(&buffer, &length, &args->renamed, sizeof(BOOLEAN));
|
||||
if (status) goto out;
|
||||
|
|
@ -517,7 +523,7 @@ int parse_close(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
|||
dprintf(1, "parsing NFS41_CLOSE: close root=0x%p "
|
||||
"open_state=0x%p remove=%d renamed=%d filename='%s'\n",
|
||||
args->root, args->state, args->remove, args->renamed,
|
||||
args->remove ? args->path.path : "");
|
||||
args->remove ? args->path : "");
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ int parse_readdir(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
|||
if (status) goto out;
|
||||
status = safe_read(&buffer, &length, &args->buf_len, sizeof(args->buf_len));
|
||||
if (status) goto out;
|
||||
status = get_name(&buffer, &length, args->filter);
|
||||
status = get_name(&buffer, &length, &args->filter);
|
||||
if (status) goto out;
|
||||
status = safe_read(&buffer, &length, &args->initial, sizeof(args->initial));
|
||||
if (status) goto out;
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ int parse_setattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
|||
int status;
|
||||
setattr_upcall_args *args = &upcall->args.setattr;
|
||||
|
||||
ZeroMemory(&args->path, sizeof(nfs41_abs_path));
|
||||
status = get_abs_path(&buffer, &length, &args->path);
|
||||
status = get_name(&buffer, &length, &args->path);
|
||||
if (status) goto out;
|
||||
status = safe_read(&buffer, &length, &args->set_class, sizeof(args->set_class));
|
||||
if (status) goto out;
|
||||
|
|
@ -65,7 +64,7 @@ int parse_setattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
|||
|
||||
dprintf(1, "parsing NFS41_FILE_SET: filename='%s' info_class=%d "
|
||||
"buf_len=%d root=%p open_state=%p\nopen_owner_id=%d "
|
||||
"access_mask=%x access_mode=%x\n", args->path.path, args->set_class,
|
||||
"access_mask=%x access_mode=%x\n", args->path, args->set_class,
|
||||
args->buf_len, args->root, args->state, args->open_owner_id,
|
||||
args->access_mask, args->access_mode);
|
||||
out:
|
||||
|
|
@ -213,13 +212,13 @@ static int handle_nfs41_rename(setattr_upcall_args *args)
|
|||
/* start from state->path instead of args->path, in case we got
|
||||
* the file from a referred server */
|
||||
AcquireSRWLockShared(&state->path.lock);
|
||||
abs_path_copy(&args->path, &state->path);
|
||||
abs_path_copy(&dst_path, &state->path);
|
||||
ReleaseSRWLockShared(&state->path.lock);
|
||||
|
||||
path_fh_init(&dst_dir, &args->path);
|
||||
path_fh_init(&dst_dir, &dst_path);
|
||||
fh_copy(&dst_dir.fh, &state->parent.fh);
|
||||
|
||||
create_silly_rename(&args->path, &state->file.fh, &dst_name);
|
||||
create_silly_rename(&dst_path, &state->file.fh, &dst_name);
|
||||
dprintf(1, "silly rename: %s -> %s\n", src_name->name, dst_name.name);
|
||||
|
||||
status = nfs41_rename(state->session,
|
||||
|
|
@ -231,7 +230,7 @@ static int handle_nfs41_rename(setattr_upcall_args *args)
|
|||
status = nfs_to_windows_error(status, ERROR_ACCESS_DENIED);
|
||||
} else {
|
||||
/* rename state->path on success */
|
||||
open_state_rename(state, &args->path);
|
||||
open_state_rename(state, &dst_path);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
/* structures for upcall arguments */
|
||||
typedef struct __mount_upcall_args {
|
||||
char srv_name[UPCALL_BUF_SIZE];
|
||||
nfs41_abs_path path;
|
||||
const char *hostname;
|
||||
const char *path;
|
||||
nfs41_root *root;
|
||||
} mount_upcall_args;
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ typedef struct __unmount_upcall_args {
|
|||
} unmount_upcall_args;
|
||||
|
||||
typedef struct __open_upcall_args {
|
||||
nfs41_abs_path path;
|
||||
const char *path;
|
||||
FILE_BASIC_INFO basic_info;
|
||||
FILE_STANDARD_INFO std_info;
|
||||
nfs41_root *root;
|
||||
|
|
@ -57,7 +57,7 @@ typedef struct __open_upcall_args {
|
|||
} open_upcall_args;
|
||||
|
||||
typedef struct __close_upcall_args {
|
||||
nfs41_abs_path path;
|
||||
const char *path;
|
||||
nfs41_root *root;
|
||||
nfs41_open_state *state;
|
||||
BOOLEAN remove;
|
||||
|
|
@ -102,7 +102,7 @@ typedef struct __getattr_upcall_args {
|
|||
} getattr_upcall_args;
|
||||
|
||||
typedef struct __setattr_upcall_args {
|
||||
nfs41_abs_path path;
|
||||
const char *path;
|
||||
nfs41_root *root;
|
||||
nfs41_open_state *state;
|
||||
unsigned char *buf;
|
||||
|
|
@ -120,7 +120,7 @@ typedef struct __setexattr_upcall_args {
|
|||
} setexattr_upcall_args;
|
||||
|
||||
typedef struct __readdir_upcall_args {
|
||||
char filter[UPCALL_BUF_SIZE];
|
||||
const char *filter;
|
||||
nfs41_readdir_cookie *cookie;
|
||||
nfs41_root *root;
|
||||
nfs41_open_state *state;
|
||||
|
|
|
|||
|
|
@ -53,44 +53,24 @@ int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src
|
|||
return 0;
|
||||
}
|
||||
|
||||
int wchar2asci(WCHAR *src, char **dest, int dest_len)
|
||||
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name)
|
||||
{
|
||||
int len = 0;
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
|
||||
if (*dest == NULL) {
|
||||
*dest = malloc(len + 1);
|
||||
if (*dest == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
} else if (len > dest_len)
|
||||
return ERROR_BUFFER_OVERFLOW;
|
||||
WideCharToMultiByte(CP_UTF8, 0, src, len, *dest, len + 1, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_name(unsigned char **pos, uint32_t *remaining, char *out_name)
|
||||
{
|
||||
WCHAR name[UPCALL_BUF_SIZE];
|
||||
int status, len = 0;
|
||||
|
||||
int status;
|
||||
USHORT len;
|
||||
|
||||
status = safe_read(pos, remaining, &len, sizeof(USHORT));
|
||||
if (status) goto out;
|
||||
status = safe_read(pos, remaining, name, len);
|
||||
if (status) goto out;
|
||||
|
||||
name[len/sizeof(WCHAR)] = L'\0';
|
||||
status = wchar2asci(name, &out_name, UPCALL_BUF_SIZE);
|
||||
if (*remaining < len) {
|
||||
status = ERROR_BUFFER_OVERFLOW;
|
||||
goto out;
|
||||
}
|
||||
*out_name = (const char*)*pos;
|
||||
*pos += len;
|
||||
*remaining -= len;
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
int get_abs_path(unsigned char **pos, uint32_t *remaining, nfs41_abs_path *path)
|
||||
{
|
||||
int status = get_name(pos, remaining, path->path);
|
||||
path->len = status ? 0 : (unsigned short)strlen(path->path);
|
||||
return status;
|
||||
}
|
||||
|
||||
const char* strip_path(
|
||||
IN const char *path,
|
||||
OUT uint32_t *len_out)
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@ enum stable_how4;
|
|||
|
||||
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len);
|
||||
int safe_write(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len);
|
||||
int get_name(unsigned char **pos, uint32_t *remaining, char *out_name);
|
||||
int get_abs_path(unsigned char **pos, uint32_t *remaining, nfs41_abs_path *path);
|
||||
int wchar2asci(WCHAR *src, char **dest, int dest_len);
|
||||
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name);
|
||||
|
||||
const char* strip_path(
|
||||
IN const char *path,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue