From f727a1e4b489ac8ffe6d5fb2afeefc1a15796848 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Tue, 12 Oct 2010 10:04:06 -0400 Subject: [PATCH] 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 --- daemon/mount.c | 11 +++++------ daemon/nfs41.h | 2 +- daemon/open.c | 30 ++++++++++++++++++------------ daemon/readdir.c | 2 +- daemon/setattr.c | 13 ++++++------- daemon/upcall.h | 12 ++++++------ daemon/util.c | 42 +++++++++++------------------------------- daemon/util.h | 4 +--- 8 files changed, 49 insertions(+), 67 deletions(-) diff --git a/daemon/mount.c b/daemon/mount.c index 649ece6..737669e 100644 --- a/daemon/mount.c +++ b/daemon/mount.c @@ -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) { diff --git a/daemon/nfs41.h b/daemon/nfs41.h index c47fda0..29a0d1e 100644 --- a/daemon/nfs41.h +++ b/daemon/nfs41.h @@ -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); diff --git a/daemon/open.c b/daemon/open.c index 3fdd340..f1762b6 100644 --- a/daemon/open.c +++ b/daemon/open.c @@ -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; } diff --git a/daemon/readdir.c b/daemon/readdir.c index e0e3e02..f968c75 100644 --- a/daemon/readdir.c +++ b/daemon/readdir.c @@ -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; diff --git a/daemon/setattr.c b/daemon/setattr.c index 54dbe07..332aa2f 100644 --- a/daemon/setattr.c +++ b/daemon/setattr.c @@ -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; } diff --git a/daemon/upcall.h b/daemon/upcall.h index 45fb941..b7dee3f 100644 --- a/daemon/upcall.h +++ b/daemon/upcall.h @@ -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; diff --git a/daemon/util.c b/daemon/util.c index aae1b64..61b87ab 100644 --- a/daemon/util.c +++ b/daemon/util.c @@ -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) diff --git a/daemon/util.h b/daemon/util.h index 6229c4b..83319bd 100644 --- a/daemon/util.h +++ b/daemon/util.h @@ -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,