symlink: open downcall passes symlink target
on last_error == ERROR_REPARSE, the daemon converts args->path back to wchar and passes it down to the driver Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
374e7ad083
commit
45a14a17ff
2 changed files with 29 additions and 2 deletions
|
|
@ -328,6 +328,23 @@ int marshall_open(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
status = safe_write(&buffer, length, &args->mode, sizeof(args->mode));
|
status = safe_write(&buffer, length, &args->mode, sizeof(args->mode));
|
||||||
if (status) goto out;
|
if (status) goto out;
|
||||||
status = safe_write(&buffer, length, &args->changeattr, sizeof(args->changeattr));
|
status = safe_write(&buffer, length, &args->changeattr, sizeof(args->changeattr));
|
||||||
|
if (status) goto out;
|
||||||
|
if (upcall->last_error == ERROR_REPARSE) {
|
||||||
|
/* convert args->path to wchar */
|
||||||
|
WCHAR wpath[NFS41_MAX_PATH_LEN];
|
||||||
|
unsigned short len = (unsigned short)MultiByteToWideChar(
|
||||||
|
CP_UTF8, 0, args->path.path, args->path.len, wpath, NFS41_MAX_PATH_LEN);
|
||||||
|
if (len == 0) {
|
||||||
|
status = ERROR_BUFFER_OVERFLOW;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
wpath[len++] = L'\0';
|
||||||
|
len *= sizeof(WCHAR);
|
||||||
|
dprintf(2, "ERROR_REPARSE -> '%S' [%u]\n", wpath, len);
|
||||||
|
status = safe_write(&buffer, length, &len, sizeof(len));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, wpath, len);
|
||||||
|
}
|
||||||
dprintf(2, "NFS41_OPEN: passing open_state=0x%p mode %o changeattr 0x%x\n",
|
dprintf(2, "NFS41_OPEN: passing open_state=0x%p mode %o changeattr 0x%x\n",
|
||||||
args->state, args->mode, args->changeattr);
|
args->state, args->mode, args->changeattr);
|
||||||
out:
|
out:
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ typedef struct _updowncall_entry {
|
||||||
HANDLE session;
|
HANDLE session;
|
||||||
HANDLE open_state;
|
HANDLE open_state;
|
||||||
PUNICODE_STRING filename;
|
PUNICODE_STRING filename;
|
||||||
|
UNICODE_STRING symlink;
|
||||||
ULONG access_mask;
|
ULONG access_mask;
|
||||||
ULONG access_mode;
|
ULONG access_mode;
|
||||||
ULONG attrs;
|
ULONG attrs;
|
||||||
|
|
@ -1344,8 +1345,16 @@ nfs41_downcall (
|
||||||
buf += sizeof(HANDLE);
|
buf += sizeof(HANDLE);
|
||||||
RtlCopyMemory(&cur->u.Open.mode, buf, sizeof(DWORD));
|
RtlCopyMemory(&cur->u.Open.mode, buf, sizeof(DWORD));
|
||||||
buf += sizeof(DWORD);
|
buf += sizeof(DWORD);
|
||||||
RtlCopyMemory(&cur->u.Open.changeattr, buf, sizeof(ULONG));
|
RtlCopyMemory(&cur->u.Open.changeattr, buf, sizeof(LONGLONG));
|
||||||
DbgP("[open] open_state 0x%x mode %o changeattr 0x%x\n",
|
buf += sizeof(LONGLONG);
|
||||||
|
if (tmp->errno == ERROR_REPARSE) {
|
||||||
|
RtlCopyMemory(&cur->u.Open.symlink.MaximumLength, buf, sizeof(USHORT));
|
||||||
|
buf += sizeof(USHORT);
|
||||||
|
cur->u.Open.symlink.Length = cur->u.Open.symlink.MaximumLength - sizeof(WCHAR);
|
||||||
|
cur->u.Open.symlink.Buffer = (PWCH)buf;
|
||||||
|
DbgP("[open] ERROR_REPARSE -> '%wZ'\n", &cur->u.Open.symlink);
|
||||||
|
}
|
||||||
|
DbgP("[open] open_state 0x%x mode %o changeattr 0x%x\n",
|
||||||
cur->u.Open.open_state, cur->u.Open.mode, cur->u.Open.changeattr);
|
cur->u.Open.open_state, cur->u.Open.mode, cur->u.Open.changeattr);
|
||||||
break;
|
break;
|
||||||
case NFS41_DIR_QUERY:
|
case NFS41_DIR_QUERY:
|
||||||
|
|
@ -2457,6 +2466,7 @@ static NTSTATUS map_open_errors(DWORD status, int len)
|
||||||
case ERROR_NETWORK_ACCESS_DENIED: return STATUS_NETWORK_ACCESS_DENIED;
|
case ERROR_NETWORK_ACCESS_DENIED: return STATUS_NETWORK_ACCESS_DENIED;
|
||||||
case ERROR_PATH_NOT_FOUND: return STATUS_OBJECT_PATH_NOT_FOUND;
|
case ERROR_PATH_NOT_FOUND: return STATUS_OBJECT_PATH_NOT_FOUND;
|
||||||
case ERROR_SHARING_VIOLATION: return STATUS_SHARING_VIOLATION;
|
case ERROR_SHARING_VIOLATION: return STATUS_SHARING_VIOLATION;
|
||||||
|
case ERROR_REPARSE: return STATUS_REPARSE;
|
||||||
default:
|
default:
|
||||||
DbgP("[ERROR] nfs41_Create: upcall returned %d returning "
|
DbgP("[ERROR] nfs41_Create: upcall returned %d returning "
|
||||||
"STATUS_INSUFFICIENT_RESOURCES\n", status);
|
"STATUS_INSUFFICIENT_RESOURCES\n", status);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue