mirror of
https://github.com/reactos/reactos.git
synced 2024-09-30 22:47:28 +00:00
[RDBSS] Implement RxQueryNameInfo() and RxConjureOriginalName()
This commit is contained in:
parent
f5104a0042
commit
cc578af6df
|
@ -75,6 +75,22 @@ RxFindOrCreateConnections(
|
||||||
_In_ PRX_CONNECTION_ID RxConnectionId);
|
_In_ PRX_CONNECTION_ID RxConnectionId);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef enum _RX_NAME_CONJURING_METHODS
|
||||||
|
{
|
||||||
|
VNetRoot_As_Prefix,
|
||||||
|
VNetRoot_As_UNC_Name,
|
||||||
|
VNetRoot_As_DriveLetter
|
||||||
|
} RX_NAME_CONJURING_METHODS;
|
||||||
|
|
||||||
|
VOID
|
||||||
|
RxConjureOriginalName(
|
||||||
|
_Inout_ PFCB Fcb,
|
||||||
|
_Inout_ PFOBX Fobx,
|
||||||
|
_Out_ PULONG ActualNameLength,
|
||||||
|
_Out_writes_bytes_( *LengthRemaining) PWCHAR OriginalName,
|
||||||
|
_Inout_ PLONG LengthRemaining,
|
||||||
|
_In_ RX_NAME_CONJURING_METHODS NameConjuringMethod);
|
||||||
|
|
||||||
#if (_WIN32_WINNT >= 0x0600)
|
#if (_WIN32_WINNT >= 0x0600)
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
RxCompleteMdl(
|
RxCompleteMdl(
|
||||||
|
|
|
@ -4786,6 +4786,134 @@ RxCompleteMdl(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
RxConjureOriginalName(
|
||||||
|
PFCB Fcb,
|
||||||
|
PFOBX Fobx,
|
||||||
|
PULONG ActualNameLength,
|
||||||
|
PWCHAR OriginalName,
|
||||||
|
PLONG LengthRemaining,
|
||||||
|
RX_NAME_CONJURING_METHODS NameConjuringMethod)
|
||||||
|
{
|
||||||
|
PWSTR Prefix, Name;
|
||||||
|
PV_NET_ROOT VNetRoot;
|
||||||
|
USHORT PrefixLength, NameLength, ToCopy;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
VNetRoot = Fcb->VNetRoot;
|
||||||
|
/* We will use the prefix contained in NET_ROOT, if we don't have
|
||||||
|
* a V_NET_ROOT, or if it wasn't null deviced or if we already have
|
||||||
|
* a UNC path */
|
||||||
|
if (VNetRoot == NULL || VNetRoot->PrefixEntry.Prefix.Buffer[1] != L';' ||
|
||||||
|
BooleanFlagOn(Fobx->Flags, FOBX_FLAG_UNC_NAME))
|
||||||
|
{
|
||||||
|
Prefix = ((PNET_ROOT)Fcb->pNetRoot)->PrefixEntry.Prefix.Buffer;
|
||||||
|
PrefixLength = ((PNET_ROOT)Fcb->pNetRoot)->PrefixEntry.Prefix.Length;
|
||||||
|
NameLength = 0;
|
||||||
|
|
||||||
|
/* In that case, keep track that we will have a prefix as buffer */
|
||||||
|
NameConjuringMethod = VNetRoot_As_Prefix;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(NodeType(VNetRoot) == RDBSS_NTC_V_NETROOT);
|
||||||
|
|
||||||
|
/* Otherwise, return the prefix from our V_NET_ROOT */
|
||||||
|
Prefix = VNetRoot->PrefixEntry.Prefix.Buffer;
|
||||||
|
PrefixLength = VNetRoot->PrefixEntry.Prefix.Length;
|
||||||
|
NameLength = VNetRoot->NamePrefix.Length;
|
||||||
|
|
||||||
|
/* If we want a UNC path, skip potential device */
|
||||||
|
if (NameConjuringMethod == VNetRoot_As_UNC_Name)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
++Prefix;
|
||||||
|
PrefixLength -= sizeof(WCHAR);
|
||||||
|
} while (PrefixLength > 0 && Prefix[0] != L'\\');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we added an extra backslash, skip it */
|
||||||
|
if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_ADDEDBACKSLASH))
|
||||||
|
{
|
||||||
|
NameLength += sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we're asked for a drive letter, skip the prefix */
|
||||||
|
if (NameConjuringMethod == VNetRoot_As_DriveLetter)
|
||||||
|
{
|
||||||
|
PrefixLength = 0;
|
||||||
|
|
||||||
|
/* And make sure we arrive at a backslash */
|
||||||
|
if (Fcb->FcbTableEntry.Path.Length > NameLength &&
|
||||||
|
Fcb->FcbTableEntry.Path.Buffer[NameLength / sizeof(WCHAR)] != L'\\')
|
||||||
|
{
|
||||||
|
NameLength -= sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Prepare to copy the prefix, make sure not to overflow */
|
||||||
|
if (*LengthRemaining >= PrefixLength)
|
||||||
|
{
|
||||||
|
/* Copy everything */
|
||||||
|
ToCopy = PrefixLength;
|
||||||
|
*LengthRemaining = *LengthRemaining - PrefixLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Copy as much as we can */
|
||||||
|
ToCopy = *LengthRemaining;
|
||||||
|
/* And return failure */
|
||||||
|
*LengthRemaining = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the prefix */
|
||||||
|
RtlCopyMemory(OriginalName, Prefix, ToCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do we have a name to copy now? */
|
||||||
|
if (Fcb->FcbTableEntry.Path.Length > NameLength)
|
||||||
|
{
|
||||||
|
ToCopy = Fcb->FcbTableEntry.Path.Length - NameLength;
|
||||||
|
Name = Fcb->FcbTableEntry.Path.Buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Just use slash for now */
|
||||||
|
ToCopy = sizeof(WCHAR);
|
||||||
|
NameLength = 0;
|
||||||
|
Name = L"\\";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Total length we will have in the output buffer (if everything is alright) */
|
||||||
|
*ActualNameLength = ToCopy + PrefixLength;
|
||||||
|
/* If we still have room to write data */
|
||||||
|
if (*LengthRemaining != -1)
|
||||||
|
{
|
||||||
|
/* If we can copy everything, it's fine! */
|
||||||
|
if (*LengthRemaining > ToCopy)
|
||||||
|
{
|
||||||
|
*LengthRemaining = *LengthRemaining - ToCopy;
|
||||||
|
}
|
||||||
|
/* Otherwise, copy as much as possible, and return failure */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ToCopy = *LengthRemaining;
|
||||||
|
*LengthRemaining = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy name after the prefix */
|
||||||
|
RtlCopyMemory(Add2Ptr(OriginalName, PrefixLength),
|
||||||
|
Add2Ptr(Name, NameLength), ToCopy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -8012,13 +8140,46 @@ RxQueryInternalInfo(
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
RxQueryNameInfo(
|
RxQueryNameInfo(
|
||||||
PRX_CONTEXT RxContext,
|
PRX_CONTEXT RxContext,
|
||||||
PFILE_NAME_INFORMATION NameInfo)
|
PFILE_NAME_INFORMATION NameInfo)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PFCB Fcb;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PFOBX Fobx;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
DPRINT("RxQueryNameInfo(%p, %p)\n", RxContext, NameInfo);
|
||||||
|
|
||||||
|
/* Check we can at least copy name size */
|
||||||
|
if (RxContext->Info.LengthRemaining < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName))
|
||||||
|
{
|
||||||
|
DPRINT1("Buffer too small: %d\n", RxContext->Info.LengthRemaining);
|
||||||
|
RxContext->Info.Length = 0;
|
||||||
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fcb = (PFCB)RxContext->pFcb;
|
||||||
|
Fobx = (PFOBX)RxContext->pFobx;
|
||||||
|
/* Get the UNC name */
|
||||||
|
RxConjureOriginalName(Fcb, Fobx, &NameInfo->FileNameLength, &NameInfo->FileName[0],
|
||||||
|
&RxContext->Info.Length, VNetRoot_As_UNC_Name);
|
||||||
|
|
||||||
|
/* If RxConjureOriginalName returned a negative len (-1) then output buffer
|
||||||
|
* was too small, return the appropriate length & status.
|
||||||
|
*/
|
||||||
|
if (RxContext->Info.LengthRemaining < 0)
|
||||||
|
{
|
||||||
|
DPRINT1("Buffer too small!\n");
|
||||||
|
RxContext->Info.Length = 0;
|
||||||
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All correct */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
Loading…
Reference in a new issue