mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[NPFS]
- Implement NpInitializeAliases + NpTranslateAlias - Add a number of debug traces, disabled by default svn path=/trunk/; revision=61900
This commit is contained in:
parent
0973a225b9
commit
21c0eca870
5 changed files with 530 additions and 25 deletions
|
@ -59,12 +59,14 @@ NpOpenNamedPipeFileSystem(IN PFILE_OBJECT FileObject,
|
|||
{
|
||||
IO_STATUS_BLOCK Status;
|
||||
PAGED_CODE();
|
||||
TRACE("Entered\n");
|
||||
|
||||
NpSetFileObject(FileObject, NpVcb, NULL, FALSE);
|
||||
++NpVcb->ReferenceCount;
|
||||
|
||||
Status.Information = FILE_OPENED;
|
||||
Status.Status = STATUS_SUCCESS;
|
||||
TRACE("Leaving, Status.Status = %lx\n", Status.Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -78,6 +80,7 @@ NpOpenNamedPipeRootDirectory(IN PNP_DCB Dcb,
|
|||
IO_STATUS_BLOCK IoStatus;
|
||||
PNP_ROOT_DCB_FCB Ccb;
|
||||
PAGED_CODE();
|
||||
TRACE("Entered\n");
|
||||
|
||||
IoStatus.Status = NpCreateRootDcbCcb(&Ccb);
|
||||
if (NT_SUCCESS(IoStatus.Status))
|
||||
|
@ -93,6 +96,7 @@ NpOpenNamedPipeRootDirectory(IN PNP_DCB Dcb,
|
|||
IoStatus.Information = 0;
|
||||
}
|
||||
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
|
@ -116,6 +120,7 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
|
|||
USHORT NamedPipeConfiguration;
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
PNP_CCB Ccb = NULL;
|
||||
TRACE("Entered\n");
|
||||
|
||||
IoStatus.Status = STATUS_SUCCESS;
|
||||
IoStatus.Information = 0;
|
||||
|
@ -167,6 +172,7 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
|
|||
((GrantedAccess & FILE_WRITE_DATA) && (NamedPipeConfiguration == FILE_PIPE_OUTBOUND)))
|
||||
{
|
||||
IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
|
@ -185,6 +191,7 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
|
|||
if (NextEntry == ListHead)
|
||||
{
|
||||
IoStatus.Status = STATUS_PIPE_NOT_AVAILABLE;
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
|
@ -195,6 +202,7 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
|
|||
if (!NT_SUCCESS(IoStatus.Status))
|
||||
{
|
||||
NpUninitializeSecurity(Ccb);
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
|
@ -203,9 +211,151 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
|
|||
|
||||
IoStatus.Information = FILE_OPENED;
|
||||
IoStatus.Status = STATUS_SUCCESS;
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpTranslateAlias(
|
||||
PUNICODE_STRING PipeName)
|
||||
{
|
||||
WCHAR UpcaseBuffer[MAX_INDEXED_LENGTH + 1];
|
||||
UNICODE_STRING UpcaseString;
|
||||
ULONG Length;
|
||||
PNPFS_ALIAS CurrentAlias;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN BufferAllocated, BackSlash;
|
||||
LONG Result;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Get the pipe name length and check for empty string */
|
||||
Length = PipeName->Length;
|
||||
if (Length == 0)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Check if the name starts with a path separator */
|
||||
BackSlash = (PipeName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR);
|
||||
if (BackSlash)
|
||||
{
|
||||
/* We are only interested in the part after the backslash */
|
||||
Length -= sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* Check if the length is within our indexed list bounds */
|
||||
if ((Length >= MIN_INDEXED_LENGTH * sizeof(WCHAR)) &&
|
||||
(Length <= MAX_INDEXED_LENGTH * sizeof(WCHAR)))
|
||||
{
|
||||
/* Length is within bounds, use the list by length */
|
||||
CurrentAlias = NpAliasListByLength[(Length / sizeof(WCHAR)) - MIN_INDEXED_LENGTH];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We use the generic list, search for an entry of the right size */
|
||||
CurrentAlias = NpAliasList;
|
||||
while ((CurrentAlias != NULL) && (CurrentAlias->Name.Length != Length))
|
||||
{
|
||||
/* Check if we went past the desired length */
|
||||
if (CurrentAlias->Name.Length > Length)
|
||||
{
|
||||
/* In this case there is no matching alias, return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Go to the next alias in the list */
|
||||
CurrentAlias = CurrentAlias->Next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we find any alias? */
|
||||
if (CurrentAlias == NULL)
|
||||
{
|
||||
/* Nothing found, no matching alias */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Check whether we can use our stack buffer */
|
||||
if (Length <= MAX_INDEXED_LENGTH * sizeof(WCHAR))
|
||||
{
|
||||
/* Initialize the upcased string */
|
||||
UpcaseString.Buffer = UpcaseBuffer;
|
||||
UpcaseString.MaximumLength = sizeof(UpcaseBuffer);
|
||||
|
||||
/* Upcase the pipe name */
|
||||
Status = RtlUpcaseUnicodeString(&UpcaseString, PipeName, FALSE);
|
||||
NT_ASSERT(NT_SUCCESS(Status));
|
||||
BufferAllocated = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Upcase the pipe name, allocate the string buffer */
|
||||
Status = RtlUpcaseUnicodeString(&UpcaseString, PipeName, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
BufferAllocated = TRUE;
|
||||
}
|
||||
|
||||
/* Did the original name start with a backslash? */
|
||||
if (BackSlash)
|
||||
{
|
||||
/* Skip it for the comparison */
|
||||
UpcaseString.Buffer++;
|
||||
UpcaseString.Length -= sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* Make sure the length matches the "raw" length */
|
||||
NT_ASSERT(UpcaseString.Length == Length);
|
||||
NT_ASSERT(CurrentAlias->Name.Length == Length);
|
||||
|
||||
/* Loop while we have aliases */
|
||||
do
|
||||
{
|
||||
/* Compare the names and check if they match */
|
||||
Result = NpCompareAliasNames(&UpcaseString, &CurrentAlias->Name);
|
||||
if (Result == 0)
|
||||
{
|
||||
/* The names match, use the target name */
|
||||
*PipeName = *CurrentAlias->TargetName;
|
||||
|
||||
/* Did the original name start with a backslash? */
|
||||
if (!BackSlash)
|
||||
{
|
||||
/* It didn't, so skip it in the target name as well */
|
||||
PipeName->Buffer++;
|
||||
PipeName->Length -= sizeof(WCHAR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if we went past all string candidates */
|
||||
if (Result < 0)
|
||||
{
|
||||
/* Nothing found, we're done */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Go to the next alias */
|
||||
CurrentAlias = CurrentAlias->Next;
|
||||
|
||||
/* Keep looping while we have aliases of the right length */
|
||||
} while ((CurrentAlias != NULL) && (CurrentAlias->Name.Length == Length));
|
||||
|
||||
/* Did we allocate a buffer? */
|
||||
if (BufferAllocated)
|
||||
{
|
||||
/* Free the allocated buffer */
|
||||
ASSERT(UpcaseString.Buffer != UpcaseBuffer);
|
||||
RtlFreeUnicodeString(&UpcaseString);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -223,6 +373,8 @@ NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
|
|||
ACCESS_MASK DesiredAccess;
|
||||
LIST_ENTRY DeferredList;
|
||||
UNICODE_STRING Prefix;
|
||||
NTSTATUS Status;
|
||||
TRACE("Entered\n");
|
||||
|
||||
InitializeListHead(&DeferredList);
|
||||
IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
|
||||
|
@ -276,8 +428,9 @@ NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
|
|||
goto Quickie;
|
||||
}
|
||||
|
||||
// Status = NpTranslateAlias(&FileName);; // ignore this for now
|
||||
// if (!NT_SUCCESS(Status)) goto Quickie;
|
||||
Status = NpTranslateAlias(&FileName);
|
||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
||||
|
||||
if (RelatedFileObject)
|
||||
{
|
||||
if (Type == NPFS_NTC_ROOT_DCB)
|
||||
|
@ -355,6 +508,7 @@ Quickie:
|
|||
|
||||
Irp->IoStatus = IoStatus;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status);
|
||||
return IoStatus.Status;
|
||||
}
|
||||
|
||||
|
@ -380,6 +534,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
|||
USHORT NamedPipeConfiguration, CheckShareAccess;
|
||||
BOOLEAN AccessGranted;
|
||||
PAGED_CODE();
|
||||
TRACE("Entered\n");
|
||||
|
||||
Privileges = NULL;
|
||||
|
||||
|
@ -424,17 +579,23 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
|||
&AccessState->GenerateOnClose);
|
||||
|
||||
SeUnlockSubjectContext(SubjectSecurityContext);
|
||||
if (!AccessGranted) return IoStatus;
|
||||
if (!AccessGranted)
|
||||
{
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
|
||||
{
|
||||
IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
if (Disposition == FILE_CREATE)
|
||||
{
|
||||
IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
|
@ -455,6 +616,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
|||
if (CheckShareAccess != ShareAccess)
|
||||
{
|
||||
IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
|
@ -476,6 +638,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
|||
{
|
||||
--Ccb->Fcb->CurrentInstances;
|
||||
NpDeleteCcb(Ccb, List);
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
|
@ -485,6 +648,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
|
|||
|
||||
IoStatus.Status = STATUS_SUCCESS;
|
||||
IoStatus.Information = 1;
|
||||
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
|
||||
return IoStatus;
|
||||
}
|
||||
|
||||
|
@ -509,6 +673,7 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
|
|||
PNP_CCB Ccb;
|
||||
PNP_FCB Fcb;
|
||||
PAGED_CODE();
|
||||
TRACE("Entered\n");
|
||||
|
||||
if (!(Parameters->TimeoutSpecified) ||
|
||||
!(Parameters->MaximumInstances) ||
|
||||
|
@ -611,9 +776,11 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
|
|||
IoStatus->Status = STATUS_SUCCESS;
|
||||
IoStatus->Information = FILE_CREATED;
|
||||
|
||||
TRACE("Leaving, STATUS_SUCCESS\n");
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
Quickie:
|
||||
TRACE("Leaving, Status = %lx\n", Status);
|
||||
IoStatus->Information = 0;
|
||||
IoStatus->Status = Status;
|
||||
return Status;
|
||||
|
@ -635,6 +802,7 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
|
|||
UNICODE_STRING Prefix;
|
||||
PNAMED_PIPE_CREATE_PARAMETERS Parameters;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
TRACE("Entered\n");
|
||||
|
||||
InitializeListHead(&DeferredList);
|
||||
Process = IoGetRequestorProcess(Irp);
|
||||
|
@ -741,6 +909,7 @@ Quickie:
|
|||
NpCompleteDeferredIrps(&DeferredList);
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status);
|
||||
Irp->IoStatus = IoStatus;
|
||||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
return IoStatus.Status;
|
||||
|
|
|
@ -16,14 +16,292 @@
|
|||
/* GLOBALS ********************************************************************/
|
||||
|
||||
PDEVICE_OBJECT NpfsDeviceObject;
|
||||
PVOID NpAliases;
|
||||
PNPFS_ALIAS NpAliasList;
|
||||
PNPFS_ALIAS NpAliasListByLength[MAX_INDEXED_LENGTH + 1 - MIN_INDEXED_LENGTH];
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpReadAlias(
|
||||
PWSTR ValueName,
|
||||
ULONG ValueType,
|
||||
PVOID ValueData,
|
||||
ULONG ValueLength,
|
||||
PVOID Context,
|
||||
PVOID EntryContext)
|
||||
{
|
||||
PNPFS_QUERY_VALUE_CONTEXT QueryContext = Context;
|
||||
PWSTR CurrentString;
|
||||
USHORT Length;
|
||||
PNPFS_ALIAS CurrentAlias;
|
||||
UNICODE_STRING TempString;
|
||||
PUNICODE_STRING CurrentTargetName;
|
||||
|
||||
/* Check if we have the expected type */
|
||||
if (ValueType != REG_MULTI_SZ)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check if only the size is requested */
|
||||
if (QueryContext->SizeOnly)
|
||||
{
|
||||
/* Count this entry */
|
||||
QueryContext->NumberOfEntries++;
|
||||
|
||||
/* Get the length of the value name (i.e. the target name). */
|
||||
Length = wcslen(ValueName) * sizeof(WCHAR);
|
||||
|
||||
/* Add the size of the name plus a '\' and a UNICODE_STRING structure */
|
||||
QueryContext->FullSize += Length + sizeof(UNICODE_NULL) +
|
||||
sizeof(OBJ_NAME_PATH_SEPARATOR) +
|
||||
sizeof(UNICODE_STRING);
|
||||
|
||||
/* Loop while we have alias names */
|
||||
CurrentString = ValueData;
|
||||
while (*CurrentString != UNICODE_NULL)
|
||||
{
|
||||
/* Count this alias */
|
||||
QueryContext->NumberOfAliases++;
|
||||
|
||||
/* Get the length of the current string (i.e. the alias name) */
|
||||
Length = wcslen(CurrentString) * sizeof(WCHAR);
|
||||
|
||||
/* Count the length plus the size of an NPFS_ALIAS structure */
|
||||
QueryContext->FullSize += Length + sizeof(UNICODE_NULL) + sizeof(NPFS_ALIAS);
|
||||
|
||||
/* Go to the next string */
|
||||
CurrentString += (Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the next name string pointer */
|
||||
CurrentTargetName = QueryContext->CurrentTargetName++;
|
||||
|
||||
/* Get the length of the value name (i.e. the target name). */
|
||||
Length = wcslen(ValueName) * sizeof(WCHAR);
|
||||
|
||||
/* Initialize the current name string (one char more than the name) */
|
||||
CurrentTargetName->Buffer = QueryContext->CurrentStringPointer;
|
||||
CurrentTargetName->Length = Length + sizeof(OBJ_NAME_PATH_SEPARATOR);
|
||||
CurrentTargetName->MaximumLength = CurrentTargetName->Length + sizeof(UNICODE_NULL);
|
||||
|
||||
/* Update the current string pointer */
|
||||
QueryContext->CurrentStringPointer +=
|
||||
CurrentTargetName->MaximumLength / sizeof(WCHAR);
|
||||
|
||||
/* Prepend a '\' before the name */
|
||||
CurrentTargetName->Buffer[0] = OBJ_NAME_PATH_SEPARATOR;
|
||||
|
||||
/* Append the value name (including the NULL termination) */
|
||||
RtlCopyMemory(&CurrentTargetName->Buffer[1],
|
||||
ValueName,
|
||||
Length + sizeof(UNICODE_NULL));
|
||||
|
||||
/* Upcase the target name */
|
||||
RtlUpcaseUnicodeString(CurrentTargetName, CurrentTargetName, 0);
|
||||
|
||||
/* Loop while we have alias names */
|
||||
CurrentString = ValueData;
|
||||
while (*CurrentString != UNICODE_NULL)
|
||||
{
|
||||
/* Get the next alias pointer */
|
||||
CurrentAlias = QueryContext->CurrentAlias++;
|
||||
|
||||
/* Get the length of the current string (i.e. the alias name) */
|
||||
Length = wcslen(CurrentString) * sizeof(WCHAR);
|
||||
|
||||
/* Setup the alias structure */
|
||||
CurrentAlias->TargetName = CurrentTargetName;
|
||||
CurrentAlias->Name.Buffer = QueryContext->CurrentStringPointer;
|
||||
CurrentAlias->Name.Length = Length;
|
||||
CurrentAlias->Name.MaximumLength = Length + sizeof(UNICODE_NULL);
|
||||
|
||||
/* Upcase the alias name */
|
||||
TempString.Buffer = CurrentString;
|
||||
TempString.Length = Length;
|
||||
RtlUpcaseUnicodeString(&CurrentAlias->Name,
|
||||
&TempString,
|
||||
FALSE);
|
||||
|
||||
/* Update the current string pointer */
|
||||
QueryContext->CurrentStringPointer +=
|
||||
CurrentAlias->Name.MaximumLength / sizeof(WCHAR);
|
||||
|
||||
/* Go to the next string */
|
||||
CurrentString += (Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LONG
|
||||
NTAPI
|
||||
NpCompareAliasNames(
|
||||
_In_ PCUNICODE_STRING String1,
|
||||
_In_ PCUNICODE_STRING String2)
|
||||
{
|
||||
ULONG Count;
|
||||
PWCHAR P1, P2;
|
||||
|
||||
/* First check if the string sizes match */
|
||||
if (String1->Length != String2->Length)
|
||||
{
|
||||
/* They don't, return positive if the first is longer, negative otherwise */
|
||||
return String1->Length - String2->Length;
|
||||
}
|
||||
|
||||
/* Now loop all characters */
|
||||
Count = String1->Length / sizeof(WCHAR);
|
||||
P1 = String1->Buffer;
|
||||
P2 = String2->Buffer;
|
||||
while (Count)
|
||||
{
|
||||
/* Check if they don't match */
|
||||
if (*P1 != *P2)
|
||||
{
|
||||
/* Return positive if the first char is greater, negative otherwise */
|
||||
return *P1 - *P2;
|
||||
}
|
||||
|
||||
/* Go to the next buffer position */
|
||||
P1++;
|
||||
P2++;
|
||||
Count--;
|
||||
}
|
||||
|
||||
/* All characters matched, return 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpInitializeAliases(VOID)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
NPFS_QUERY_VALUE_CONTEXT Context;
|
||||
NTSTATUS Status;
|
||||
USHORT Length;
|
||||
ULONG i;
|
||||
PNPFS_ALIAS CurrentAlias, *AliasPointer;
|
||||
|
||||
/* Initialize the query table */
|
||||
QueryTable[0].QueryRoutine = NpReadAlias;
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_NOEXPAND;
|
||||
QueryTable[0].Name = NULL;
|
||||
QueryTable[0].EntryContext = NULL;
|
||||
QueryTable[0].DefaultType = REG_NONE;
|
||||
QueryTable[0].DefaultData = NULL;
|
||||
QueryTable[0].DefaultLength = 0;
|
||||
QueryTable[1].QueryRoutine = NULL;
|
||||
QueryTable[1].Flags = 0;
|
||||
QueryTable[1].Name = NULL;
|
||||
|
||||
/* Setup the query context */
|
||||
Context.SizeOnly = 1;
|
||||
Context.FullSize = 0;
|
||||
Context.NumberOfAliases = 0;
|
||||
Context.NumberOfEntries = 0;
|
||||
|
||||
/* Query the registry values (calculate length only) */
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES | RTL_REGISTRY_OPTIONAL,
|
||||
L"Npfs\\Aliases",
|
||||
QueryTable,
|
||||
&Context,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check if there is anything */
|
||||
if (Context.FullSize == 0)
|
||||
{
|
||||
/* Nothing to do, return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Allocate a structure large enough to hold all the data */
|
||||
NpAliases = ExAllocatePoolWithTag(NonPagedPool, Context.FullSize, 'sfpN');
|
||||
if (NpAliases == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Now setup the actual pointers in the context */
|
||||
Context.CurrentTargetName = NpAliases;
|
||||
CurrentAlias = (PNPFS_ALIAS)&Context.CurrentTargetName[Context.NumberOfEntries];
|
||||
Context.CurrentAlias = CurrentAlias;
|
||||
Context.CurrentStringPointer = (PWCHAR)&CurrentAlias[Context.NumberOfAliases];
|
||||
|
||||
/* This time query the real data */
|
||||
Context.SizeOnly = FALSE;
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES | RTL_REGISTRY_OPTIONAL,
|
||||
L"Npfs\\Aliases",
|
||||
QueryTable,
|
||||
&Context,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePoolWithTag(NpAliases, 0);
|
||||
NpAliases = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Make sure we didn't go past the end of the allocation! */
|
||||
NT_ASSERT((PUCHAR)Context.CurrentStringPointer <=
|
||||
((PUCHAR)NpAliases + Context.FullSize));
|
||||
|
||||
/* Loop all aliases we got */
|
||||
for (i = 0; i < Context.NumberOfAliases; i++)
|
||||
{
|
||||
/* Get the length and check what list to use */
|
||||
Length = CurrentAlias->Name.Length;
|
||||
if ((Length >= MIN_INDEXED_LENGTH * sizeof(WCHAR)) &&
|
||||
(Length <= MAX_INDEXED_LENGTH * sizeof(WCHAR)))
|
||||
{
|
||||
/* For this length range, we use an indexed list */
|
||||
AliasPointer = &NpAliasListByLength[(Length / sizeof(WCHAR)) - 5];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Length is outside of the range, use the default list */
|
||||
AliasPointer = &NpAliasList;
|
||||
}
|
||||
|
||||
/* Loop through all aliases already in the list until we find one that
|
||||
is greater than our current alias */
|
||||
while ((*AliasPointer != NULL) &&
|
||||
(NpCompareAliasNames(&CurrentAlias->Name,
|
||||
&(*AliasPointer)->Name) > 0))
|
||||
{
|
||||
/* Go to the next alias */
|
||||
AliasPointer = &(*AliasPointer)->Next;
|
||||
}
|
||||
|
||||
/* Insert the alias in the list */
|
||||
CurrentAlias->Next = *AliasPointer;
|
||||
*AliasPointer = CurrentAlias;
|
||||
|
||||
/* Go to the next alias in the array */
|
||||
CurrentAlias++;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
TRACE("Entered\n");
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
|
@ -45,6 +323,13 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
|||
|
||||
DPRINT1("Next-Generation NPFS-Lite\n");
|
||||
|
||||
Status = NpInitializeAliases();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to initialize aliases!\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = NpFsdCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = NpFsdCreateNamedPipe;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NpFsdClose;
|
||||
|
|
|
@ -14,8 +14,12 @@
|
|||
#include <ntifs.h>
|
||||
#include <ntndk.h>
|
||||
#include <pseh/pseh2.h>
|
||||
#define UNIMPLEMENTED
|
||||
#define DPRINT1 DbgPrint
|
||||
//#define UNIMPLEMENTED
|
||||
//#define DPRINT1 DbgPrint
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#define TRACE(...) /* DPRINT1("%s: ", __FUNCTION__); DbgPrint(__VA_ARGS__) */
|
||||
|
||||
//
|
||||
// Allow Microsoft Extensions
|
||||
|
@ -26,6 +30,9 @@
|
|||
#pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
#define MIN_INDEXED_LENGTH 5
|
||||
#define MAX_INDEXED_LENGTH 9
|
||||
|
||||
|
||||
/* TYPEDEFS & DEFINES *********************************************************/
|
||||
|
||||
|
@ -326,6 +333,32 @@ typedef struct _NP_VCB
|
|||
|
||||
extern PNP_VCB NpVcb;
|
||||
|
||||
//
|
||||
// Defines an alias
|
||||
//
|
||||
typedef struct _NPFS_ALIAS
|
||||
{
|
||||
struct _NPFS_ALIAS *Next;
|
||||
PUNICODE_STRING TargetName;
|
||||
UNICODE_STRING Name;
|
||||
} NPFS_ALIAS, *PNPFS_ALIAS;
|
||||
|
||||
//
|
||||
// Private structure used to enumerate the alias values
|
||||
//
|
||||
typedef struct _NPFS_QUERY_VALUE_CONTEXT
|
||||
{
|
||||
BOOLEAN SizeOnly;
|
||||
SIZE_T FullSize;
|
||||
ULONG NumberOfAliases;
|
||||
ULONG NumberOfEntries;
|
||||
PNPFS_ALIAS CurrentAlias;
|
||||
PUNICODE_STRING CurrentTargetName;
|
||||
PWCHAR CurrentStringPointer;
|
||||
} NPFS_QUERY_VALUE_CONTEXT, *PNPFS_QUERY_VALUE_CONTEXT;
|
||||
|
||||
extern PNPFS_ALIAS NpAliasList;
|
||||
extern PNPFS_ALIAS NpAliasListByLength[MAX_INDEXED_LENGTH + 1 - MIN_INDEXED_LENGTH];
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
|
@ -385,6 +418,12 @@ NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList)
|
|||
}
|
||||
}
|
||||
|
||||
LONG
|
||||
NTAPI
|
||||
NpCompareAliasNames(
|
||||
_In_ PCUNICODE_STRING String1,
|
||||
_In_ PCUNICODE_STRING String2);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
|
||||
|
@ -415,7 +454,7 @@ NTAPI
|
|||
NpAddDataQueueEntry(IN ULONG NamedPipeEnd,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PNP_DATA_QUEUE DataQueue,
|
||||
IN ULONG Who,
|
||||
IN ULONG Who,
|
||||
IN ULONG Type,
|
||||
IN ULONG DataSize,
|
||||
IN PIRP Irp,
|
||||
|
@ -510,20 +549,20 @@ NpSetConnectedPipeState(IN PNP_CCB Ccb,
|
|||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetListeningPipeState(IN PNP_CCB Ccb,
|
||||
IN PIRP Irp,
|
||||
IN PIRP Irp,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
|
||||
NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpSetClosingPipeState(IN PNP_CCB Ccb,
|
||||
IN PIRP Irp,
|
||||
IN ULONG NamedPipeEnd,
|
||||
IN PIRP Irp,
|
||||
IN ULONG NamedPipeEnd,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
VOID
|
||||
|
@ -594,7 +633,7 @@ NTSTATUS
|
|||
NTAPI
|
||||
NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
||||
IN LARGE_INTEGER WaitTime,
|
||||
IN PIRP Irp,
|
||||
IN PIRP Irp,
|
||||
IN PUNICODE_STRING AliasName);
|
||||
|
||||
NTSTATUS
|
||||
|
@ -607,27 +646,27 @@ NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
|
|||
|
||||
IO_STATUS_BLOCK
|
||||
NTAPI
|
||||
NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
||||
NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
|
||||
IN BOOLEAN Peek,
|
||||
IN BOOLEAN ReadOverflowOperation,
|
||||
IN PVOID Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN ULONG Mode,
|
||||
IN ULONG BufferSize,
|
||||
IN ULONG Mode,
|
||||
IN PNP_CCB Ccb,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
||||
IN ULONG Mode,
|
||||
IN PVOID OutBuffer,
|
||||
IN ULONG OutBufferSize,
|
||||
IN ULONG PipeType,
|
||||
OUT PULONG BytesWritten,
|
||||
IN PNP_CCB Ccb,
|
||||
IN ULONG NamedPipeEnd,
|
||||
IN PETHREAD Thread,
|
||||
IN ULONG Mode,
|
||||
IN PVOID OutBuffer,
|
||||
IN ULONG OutBufferSize,
|
||||
IN ULONG PipeType,
|
||||
OUT PULONG BytesWritten,
|
||||
IN PNP_CCB Ccb,
|
||||
IN ULONG NamedPipeEnd,
|
||||
IN PETHREAD Thread,
|
||||
IN PLIST_ENTRY List);
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
#define UNIMPLEMENTED
|
||||
|
||||
PWCHAR NpRootDCBName = L"\\";
|
||||
PNP_VCB NpVcb;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ NpQueryFsVolumeInfo(IN PVOID Buffer,
|
|||
PFILE_FS_VOLUME_INFORMATION InfoBuffer = Buffer;
|
||||
NTSTATUS Status;
|
||||
USHORT NameLength;
|
||||
TRACE("Entered\n");
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
|
@ -47,6 +48,7 @@ NpQueryFsVolumeInfo(IN PVOID Buffer,
|
|||
RtlCopyMemory(InfoBuffer->VolumeLabel, L"Named Pipe", NameLength);
|
||||
*Length -= NameLength;
|
||||
|
||||
TRACE("Leaving, Status = %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -56,6 +58,7 @@ NpQueryFsSizeInfo(IN PVOID Buffer,
|
|||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_FS_SIZE_INFORMATION InfoBuffer = Buffer;
|
||||
TRACE("Entered\n");
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
|
@ -64,6 +67,7 @@ NpQueryFsSizeInfo(IN PVOID Buffer,
|
|||
InfoBuffer->SectorsPerAllocationUnit = 1;
|
||||
InfoBuffer->BytesPerSector = 1;
|
||||
|
||||
TRACE("Leaving, Status = STATUS_SUCCESS\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -74,6 +78,7 @@ NpQueryFsDeviceInfo(IN PVOID Buffer,
|
|||
{
|
||||
PFILE_FS_DEVICE_INFORMATION InfoBuffer = Buffer;
|
||||
NTSTATUS Status;
|
||||
TRACE("Entered\n");
|
||||
|
||||
if (*Length >= sizeof(*InfoBuffer))
|
||||
{
|
||||
|
@ -87,6 +92,7 @@ NpQueryFsDeviceInfo(IN PVOID Buffer,
|
|||
{
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
TRACE("Leaving, Status = %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -98,6 +104,7 @@ NpQueryFsAttributeInfo(IN PVOID Buffer,
|
|||
PFILE_FS_ATTRIBUTE_INFORMATION InfoBuffer = Buffer;
|
||||
NTSTATUS Status;
|
||||
USHORT NameLength;
|
||||
TRACE("Entered\n");
|
||||
|
||||
NameLength = (USHORT)(*Length - 12);
|
||||
if (NameLength < 8)
|
||||
|
@ -117,6 +124,7 @@ NpQueryFsAttributeInfo(IN PVOID Buffer,
|
|||
InfoBuffer->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
|
||||
RtlCopyMemory(InfoBuffer->FileSystemName, L"NPFS", NameLength);
|
||||
|
||||
TRACE("Leaving, Status = %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -126,11 +134,13 @@ NpQueryFsFullSizeInfo(IN PVOID Buffer,
|
|||
IN OUT PULONG Length)
|
||||
{
|
||||
PFILE_FS_FULL_SIZE_INFORMATION InfoBuffer = Buffer;
|
||||
TRACE("Entered\n");
|
||||
|
||||
*Length -= sizeof(*InfoBuffer);
|
||||
|
||||
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
|
||||
|
||||
TRACE("Leaving, Status = STATUS_SUCCESS\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -145,6 +155,7 @@ NpCommonQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
PVOID Buffer;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
TRACE("Entered\n");
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
@ -174,6 +185,7 @@ NpCommonQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
Irp->IoStatus.Information = IoStack->Parameters.QueryVolume.Length - Length;
|
||||
TRACE("Leaving, Status = %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -184,6 +196,7 @@ NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
TRACE("Entered\n");
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
|
||||
|
@ -199,6 +212,7 @@ NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
|
|||
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
|
||||
}
|
||||
|
||||
TRACE("Leaving, Status = %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue