symlink: view symlinks in cygwin
handles the query for NfsSymlinkTargetName EA by making a symlink upcall. adds a trailing null for 'ls -l' in cygwin Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
0afc5ebb4d
commit
1a5f3cb3a1
1 changed files with 64 additions and 2 deletions
|
|
@ -4557,6 +4557,7 @@ NTSTATUS map_setea_error(
|
||||||
case ERROR_NETNAME_DELETED: return STATUS_NETWORK_NAME_DELETED;
|
case ERROR_NETNAME_DELETED: return STATUS_NETWORK_NAME_DELETED;
|
||||||
case ERROR_FILE_TOO_LARGE: return STATUS_EA_TOO_LARGE;
|
case ERROR_FILE_TOO_LARGE: return STATUS_EA_TOO_LARGE;
|
||||||
case ERROR_BUFFER_OVERFLOW: return STATUS_BUFFER_OVERFLOW;
|
case ERROR_BUFFER_OVERFLOW: return STATUS_BUFFER_OVERFLOW;
|
||||||
|
case STATUS_BUFFER_TOO_SMALL:
|
||||||
case ERROR_INSUFFICIENT_BUFFER: return STATUS_BUFFER_TOO_SMALL;
|
case ERROR_INSUFFICIENT_BUFFER: return STATUS_BUFFER_TOO_SMALL;
|
||||||
case ERROR_INVALID_EA_HANDLE: return STATUS_NONEXISTENT_EA_ENTRY;
|
case ERROR_INVALID_EA_HANDLE: return STATUS_NONEXISTENT_EA_ENTRY;
|
||||||
case ERROR_NO_MORE_FILES: return STATUS_NO_MORE_EAS;
|
case ERROR_NO_MORE_FILES: return STATUS_NO_MORE_EAS;
|
||||||
|
|
@ -4734,6 +4735,63 @@ out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS QueryCygwinSymlink(
|
||||||
|
IN OUT PRX_CONTEXT RxContext,
|
||||||
|
IN PFILE_GET_EA_INFORMATION query,
|
||||||
|
OUT PFILE_FULL_EA_INFORMATION info)
|
||||||
|
{
|
||||||
|
__notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
|
||||||
|
__notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
|
||||||
|
NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
|
||||||
|
__notnull PNFS41_NETROOT_EXTENSION NetRootContext =
|
||||||
|
NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
|
||||||
|
__notnull PNFS41_FOBX Fobx = NFS41GetFobxExtension(RxContext->pFobx);
|
||||||
|
nfs41_updowncall_entry *entry;
|
||||||
|
UNICODE_STRING TargetName;
|
||||||
|
const USHORT HeaderLen = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) +
|
||||||
|
query->EaNameLength + 1;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (RxContext->Info.LengthRemaining < HeaderLen) {
|
||||||
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
RxContext->InformationToReturn = HeaderLen;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetName.Buffer = (PWCH)(info->EaName + query->EaNameLength + 1);
|
||||||
|
TargetName.MaximumLength = (USHORT)min(RxContext->Info.LengthRemaining -
|
||||||
|
HeaderLen, 0xFFFF);
|
||||||
|
|
||||||
|
status = nfs41_UpcallCreate(NFS41_SYMLINK, &Fobx->sec_ctx,
|
||||||
|
VNetRootContext->session, Fobx->nfs41_open_state,
|
||||||
|
NetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
|
||||||
|
if (status) goto out;
|
||||||
|
|
||||||
|
entry->u.Symlink.filename = SrvOpen->pAlreadyPrefixedName;
|
||||||
|
entry->u.Symlink.target = &TargetName;
|
||||||
|
entry->u.Symlink.set = FALSE;
|
||||||
|
|
||||||
|
status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
|
||||||
|
if (status) goto out;
|
||||||
|
|
||||||
|
status = map_setea_error(entry->status);
|
||||||
|
if (status == STATUS_SUCCESS) {
|
||||||
|
info->NextEntryOffset = 0;
|
||||||
|
info->Flags = 0;
|
||||||
|
info->EaNameLength = query->EaNameLength;
|
||||||
|
info->EaValueLength = TargetName.Length - sizeof(UNICODE_NULL);
|
||||||
|
TargetName.Buffer[TargetName.Length/sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
RtlCopyMemory(info->EaName, query->EaName, query->EaNameLength);
|
||||||
|
RxContext->Info.LengthRemaining = HeaderLen + info->EaValueLength;
|
||||||
|
} else if (status == STATUS_BUFFER_TOO_SMALL) {
|
||||||
|
RxContext->InformationToReturn = HeaderLen +
|
||||||
|
entry->u.Symlink.target->Length;
|
||||||
|
}
|
||||||
|
RxFreePool(entry);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS QueryCygwinEA(
|
static NTSTATUS QueryCygwinEA(
|
||||||
IN OUT PRX_CONTEXT RxContext,
|
IN OUT PRX_CONTEXT RxContext,
|
||||||
IN PFILE_GET_EA_INFORMATION query,
|
IN PFILE_GET_EA_INFORMATION query,
|
||||||
|
|
@ -4744,6 +4802,11 @@ static NTSTATUS QueryCygwinEA(
|
||||||
if (query == NULL)
|
if (query == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (AnsiStrEq(&NfsSymlinkTargetName, query->EaName, query->EaNameLength)) {
|
||||||
|
status = QueryCygwinSymlink(RxContext, query, info);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (AnsiStrEq(&NfsV3Attributes, query->EaName, query->EaNameLength)) {
|
if (AnsiStrEq(&NfsV3Attributes, query->EaName, query->EaNameLength)) {
|
||||||
nfs3_attrs attrs;
|
nfs3_attrs attrs;
|
||||||
|
|
||||||
|
|
@ -4773,8 +4836,7 @@ static NTSTATUS QueryCygwinEA(
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AnsiStrEq(&NfsActOnLink, query->EaName, query->EaNameLength) ||
|
if (AnsiStrEq(&NfsActOnLink, query->EaName, query->EaNameLength)) {
|
||||||
AnsiStrEq(&NfsSymlinkTargetName, query->EaName, query->EaNameLength)) {
|
|
||||||
|
|
||||||
const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) +
|
const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) +
|
||||||
query->EaNameLength - sizeof(CHAR);
|
query->EaNameLength - sizeof(CHAR);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue