symlink: open handles embedded symlinks
returns symlink_embedded=TRUE when the symlink isn't the last component, which gets passed to RxPrepareToReparseSymbolicLink() Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
a92fb8930e
commit
e27299d066
3 changed files with 22 additions and 4 deletions
|
|
@ -236,6 +236,17 @@ int handle_open(nfs41_upcall *upcall)
|
||||||
status = nfs41_lookup(args->root, nfs41_root_session(args->root),
|
status = nfs41_lookup(args->root, nfs41_root_session(args->root),
|
||||||
&state->path, &state->parent, &state->file, &info, &state->session);
|
&state->path, &state->parent, &state->file, &info, &state->session);
|
||||||
|
|
||||||
|
if (status == ERROR_REPARSE) {
|
||||||
|
/* one of the parent components was a symlink */
|
||||||
|
upcall->last_error = ERROR_REPARSE;
|
||||||
|
args->symlink_embedded = TRUE;
|
||||||
|
|
||||||
|
/* replace the path with the symlink target */
|
||||||
|
status = nfs41_symlink_follow(state->session,
|
||||||
|
&state->parent, &args->symlink);
|
||||||
|
goto out_free_state;
|
||||||
|
}
|
||||||
|
|
||||||
// now if file/dir exists, use type returned by lookup
|
// now if file/dir exists, use type returned by lookup
|
||||||
if (status == NO_ERROR) {
|
if (status == NO_ERROR) {
|
||||||
if (info.type == NF4DIR) {
|
if (info.type == NF4DIR) {
|
||||||
|
|
@ -263,10 +274,11 @@ int handle_open(nfs41_upcall *upcall)
|
||||||
} else {
|
} else {
|
||||||
/* tell the driver to call RxPrepareToReparseSymbolicLink() */
|
/* tell the driver to call RxPrepareToReparseSymbolicLink() */
|
||||||
upcall->last_error = ERROR_REPARSE;
|
upcall->last_error = ERROR_REPARSE;
|
||||||
|
args->symlink_embedded = FALSE;
|
||||||
|
|
||||||
/* replace the path with the symlink target */
|
/* replace the path with the symlink target */
|
||||||
status = nfs41_symlink_follow(state->session,
|
status = nfs41_symlink_follow(state->session,
|
||||||
&state->parent, &state->file, &args->symlink);
|
&state->file, &args->symlink);
|
||||||
goto out_free_state;
|
goto out_free_state;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
|
@ -375,6 +387,8 @@ int marshall_open(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
if (status) goto out;
|
if (status) goto out;
|
||||||
if (upcall->last_error == ERROR_REPARSE) {
|
if (upcall->last_error == ERROR_REPARSE) {
|
||||||
unsigned short len = (args->symlink.len + 1) * sizeof(WCHAR);
|
unsigned short len = (args->symlink.len + 1) * sizeof(WCHAR);
|
||||||
|
status = safe_write(&buffer, length, &args->symlink_embedded, sizeof(BOOLEAN));
|
||||||
|
if (status) goto out;
|
||||||
status = safe_write(&buffer, length, &len, sizeof(len));
|
status = safe_write(&buffer, length, &len, sizeof(len));
|
||||||
if (status) goto out;
|
if (status) goto out;
|
||||||
/* convert args->symlink to wchar */
|
/* convert args->symlink to wchar */
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ typedef struct __open_upcall_args {
|
||||||
DWORD mode;
|
DWORD mode;
|
||||||
LONGLONG changeattr;
|
LONGLONG changeattr;
|
||||||
BOOLEAN created;
|
BOOLEAN created;
|
||||||
|
BOOLEAN symlink_embedded;
|
||||||
} open_upcall_args;
|
} open_upcall_args;
|
||||||
|
|
||||||
typedef struct __close_upcall_args {
|
typedef struct __close_upcall_args {
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ typedef struct _updowncall_entry {
|
||||||
ULONG open_owner_id;
|
ULONG open_owner_id;
|
||||||
DWORD mode;
|
DWORD mode;
|
||||||
LONGLONG changeattr;
|
LONGLONG changeattr;
|
||||||
|
BOOLEAN symlink_embedded;
|
||||||
} Open;
|
} Open;
|
||||||
struct {
|
struct {
|
||||||
HANDLE open_state;
|
HANDLE open_state;
|
||||||
|
|
@ -1398,6 +1399,8 @@ nfs41_downcall (
|
||||||
RtlCopyMemory(&cur->u.Open.changeattr, buf, sizeof(LONGLONG));
|
RtlCopyMemory(&cur->u.Open.changeattr, buf, sizeof(LONGLONG));
|
||||||
buf += sizeof(LONGLONG);
|
buf += sizeof(LONGLONG);
|
||||||
if (tmp->errno == ERROR_REPARSE) {
|
if (tmp->errno == ERROR_REPARSE) {
|
||||||
|
RtlCopyMemory(&cur->u.Open.symlink_embedded, buf, sizeof(BOOLEAN));
|
||||||
|
buf += sizeof(BOOLEAN);
|
||||||
RtlCopyMemory(&cur->u.Open.symlink.MaximumLength, buf, sizeof(USHORT));
|
RtlCopyMemory(&cur->u.Open.symlink.MaximumLength, buf, sizeof(USHORT));
|
||||||
buf += sizeof(USHORT);
|
buf += sizeof(USHORT);
|
||||||
cur->u.Open.symlink.Length = cur->u.Open.symlink.MaximumLength - sizeof(WCHAR);
|
cur->u.Open.symlink.Length = cur->u.Open.symlink.MaximumLength - sizeof(WCHAR);
|
||||||
|
|
@ -2666,9 +2669,9 @@ NTSTATUS nfs41_Create(
|
||||||
RtlCopyMemory(buf, entry->u.Open.symlink.Buffer, entry->u.Open.symlink.Length);
|
RtlCopyMemory(buf, entry->u.Open.symlink.Buffer, entry->u.Open.symlink.Length);
|
||||||
|
|
||||||
status = RxPrepareToReparseSymbolicLink(RxContext,
|
status = RxPrepareToReparseSymbolicLink(RxContext,
|
||||||
FALSE, &AbsPath, TRUE, &ReparseRequired);
|
entry->u.Open.symlink_embedded, &AbsPath, TRUE, &ReparseRequired);
|
||||||
DbgP("RxPrepareToReparseSymbolicLink('%wZ') returned %08lX, "
|
DbgP("RxPrepareToReparseSymbolicLink(%u, '%wZ') returned %08lX, "
|
||||||
"FileName is '%wZ'\n",
|
"FileName is '%wZ'\n", entry->u.Open.symlink_embedded,
|
||||||
&AbsPath, status, &RxContext->CurrentIrpSp->FileObject->FileName);
|
&AbsPath, status, &RxContext->CurrentIrpSp->FileObject->FileName);
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
status = ReparseRequired ? STATUS_REPARSE :
|
status = ReparseRequired ? STATUS_REPARSE :
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue