symlink: driver marshalls new SYMLINK upcall
new NFS41_SYMLINK upcall and associated data in nfs41_updowncall_entry.u.Symlink supports both setting and querying the symlink target. if Symlink.set is TRUE, Symlink.target is marshalled into the upcall. if Symlink.set is FALSE, Symlink.target is read from the downcall Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
b51bd2f9d1
commit
80d979ace6
3 changed files with 68 additions and 0 deletions
|
|
@ -198,6 +198,13 @@ typedef struct _updowncall_entry {
|
|||
HANDLE session;
|
||||
DWORD mode;
|
||||
} SetEa;
|
||||
struct {
|
||||
HANDLE open_state;
|
||||
HANDLE session;
|
||||
PUNICODE_STRING filename;
|
||||
PUNICODE_STRING target;
|
||||
BOOLEAN set;
|
||||
} Symlink;
|
||||
struct {
|
||||
HANDLE session;
|
||||
FS_INFORMATION_CLASS query;
|
||||
|
|
@ -968,6 +975,49 @@ out:
|
|||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS marshal_nfs41_symlink(nfs41_updowncall_entry *entry,
|
||||
unsigned char *buf,
|
||||
ULONG buf_len,
|
||||
ULONG *len)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
ULONG header_len = 0;
|
||||
unsigned char *tmp = buf;
|
||||
|
||||
DbgEn();
|
||||
status = marshal_nfs41_header(entry, tmp, buf_len, len);
|
||||
if (status == STATUS_INSUFFICIENT_RESOURCES)
|
||||
goto out;
|
||||
else
|
||||
tmp += *len;
|
||||
header_len = *len + 2 * sizeof(HANDLE) + sizeof(BOOLEAN) +
|
||||
length_as_ansi(entry->u.Symlink.filename);
|
||||
if (entry->u.Symlink.set)
|
||||
header_len += length_as_ansi(entry->u.Symlink.target);
|
||||
if (header_len > buf_len) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
RtlCopyMemory(tmp, &entry->u.Symlink.session, sizeof(HANDLE));
|
||||
tmp += sizeof(HANDLE);
|
||||
RtlCopyMemory(tmp, &entry->u.Symlink.open_state, sizeof(HANDLE));
|
||||
tmp += sizeof(HANDLE);
|
||||
marshall_unicode_as_ansi(&tmp, entry->u.Symlink.filename);
|
||||
RtlCopyMemory(tmp, &entry->u.Symlink.set, sizeof(BOOLEAN));
|
||||
tmp += sizeof(BOOLEAN);
|
||||
if (entry->u.Symlink.set)
|
||||
marshall_unicode_as_ansi(&tmp, entry->u.Symlink.target);
|
||||
|
||||
*len = header_len;
|
||||
|
||||
DbgP("session=0x%x open_state=0x%x set=0x%x\n",
|
||||
entry->u.SetEa.session, entry->u.SetEa.open_state, entry->u.SetEa.mode);
|
||||
out:
|
||||
DbgEx();
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS marshal_nfs41_volume(nfs41_updowncall_entry *entry,
|
||||
unsigned char *buf,
|
||||
ULONG buf_len,
|
||||
|
|
@ -1086,6 +1136,9 @@ handle_upcall(
|
|||
case NFS41_EA_SET:
|
||||
status = marshal_nfs41_easet(entry, pbOut, cbOut, len);
|
||||
break;
|
||||
case NFS41_SYMLINK:
|
||||
status = marshal_nfs41_symlink(entry, pbOut, cbOut, len);
|
||||
break;
|
||||
case NFS41_VOLUME_QUERY:
|
||||
status = marshal_nfs41_volume(entry, pbOut, cbOut, len);
|
||||
break;
|
||||
|
|
@ -1370,6 +1423,19 @@ nfs41_downcall (
|
|||
RtlCopyMemory(&cur->u.QueryFile.readdir_cookie, buf, sizeof(HANDLE));
|
||||
}
|
||||
break;
|
||||
case NFS41_SYMLINK:
|
||||
if (cur->u.Symlink.set)
|
||||
break;
|
||||
RtlCopyMemory(&cur->u.Symlink.target->Length, buf, sizeof(USHORT));
|
||||
buf += sizeof(USHORT);
|
||||
if (cur->u.Symlink.target->Length > cur->u.Symlink.target->MaximumLength) {
|
||||
cur->status = STATUS_BUFFER_TOO_SMALL;
|
||||
break;
|
||||
}
|
||||
RtlCopyMemory(cur->u.Symlink.target->Buffer, buf,
|
||||
cur->u.Symlink.target->Length);
|
||||
cur->u.Symlink.target->Length -= sizeof(UNICODE_NULL);
|
||||
break;
|
||||
case NFS41_VOLUME_QUERY:
|
||||
RtlCopyMemory(&tmp->u.Volume.buf_len, buf, sizeof(LONG));
|
||||
buf += sizeof(LONG);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue