- Implement NpInitializeAliases + NpTranslateAlias
- Add a number of debug traces, disabled by default

svn path=/trunk/; revision=61900
This commit is contained in:
Timo Kreuzer 2014-02-01 14:28:15 +00:00
parent 0973a225b9
commit 21c0eca870
5 changed files with 530 additions and 25 deletions

View file

@ -59,12 +59,14 @@ NpOpenNamedPipeFileSystem(IN PFILE_OBJECT FileObject,
{ {
IO_STATUS_BLOCK Status; IO_STATUS_BLOCK Status;
PAGED_CODE(); PAGED_CODE();
TRACE("Entered\n");
NpSetFileObject(FileObject, NpVcb, NULL, FALSE); NpSetFileObject(FileObject, NpVcb, NULL, FALSE);
++NpVcb->ReferenceCount; ++NpVcb->ReferenceCount;
Status.Information = FILE_OPENED; Status.Information = FILE_OPENED;
Status.Status = STATUS_SUCCESS; Status.Status = STATUS_SUCCESS;
TRACE("Leaving, Status.Status = %lx\n", Status.Status);
return Status; return Status;
} }
@ -78,6 +80,7 @@ NpOpenNamedPipeRootDirectory(IN PNP_DCB Dcb,
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
PNP_ROOT_DCB_FCB Ccb; PNP_ROOT_DCB_FCB Ccb;
PAGED_CODE(); PAGED_CODE();
TRACE("Entered\n");
IoStatus.Status = NpCreateRootDcbCcb(&Ccb); IoStatus.Status = NpCreateRootDcbCcb(&Ccb);
if (NT_SUCCESS(IoStatus.Status)) if (NT_SUCCESS(IoStatus.Status))
@ -93,6 +96,7 @@ NpOpenNamedPipeRootDirectory(IN PNP_DCB Dcb,
IoStatus.Information = 0; IoStatus.Information = 0;
} }
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus; return IoStatus;
} }
@ -116,6 +120,7 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
USHORT NamedPipeConfiguration; USHORT NamedPipeConfiguration;
PLIST_ENTRY NextEntry, ListHead; PLIST_ENTRY NextEntry, ListHead;
PNP_CCB Ccb = NULL; PNP_CCB Ccb = NULL;
TRACE("Entered\n");
IoStatus.Status = STATUS_SUCCESS; IoStatus.Status = STATUS_SUCCESS;
IoStatus.Information = 0; IoStatus.Information = 0;
@ -167,6 +172,7 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
((GrantedAccess & FILE_WRITE_DATA) && (NamedPipeConfiguration == FILE_PIPE_OUTBOUND))) ((GrantedAccess & FILE_WRITE_DATA) && (NamedPipeConfiguration == FILE_PIPE_OUTBOUND)))
{ {
IoStatus.Status = STATUS_ACCESS_DENIED; IoStatus.Status = STATUS_ACCESS_DENIED;
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus; return IoStatus;
} }
@ -185,6 +191,7 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
if (NextEntry == ListHead) if (NextEntry == ListHead)
{ {
IoStatus.Status = STATUS_PIPE_NOT_AVAILABLE; IoStatus.Status = STATUS_PIPE_NOT_AVAILABLE;
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus; return IoStatus;
} }
@ -195,6 +202,7 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
if (!NT_SUCCESS(IoStatus.Status)) if (!NT_SUCCESS(IoStatus.Status))
{ {
NpUninitializeSecurity(Ccb); NpUninitializeSecurity(Ccb);
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus; return IoStatus;
} }
@ -203,9 +211,151 @@ NpCreateClientEnd(IN PNP_FCB Fcb,
IoStatus.Information = FILE_OPENED; IoStatus.Information = FILE_OPENED;
IoStatus.Status = STATUS_SUCCESS; IoStatus.Status = STATUS_SUCCESS;
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return 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 NTSTATUS
NTAPI NTAPI
NpFsdCreate(IN PDEVICE_OBJECT DeviceObject, NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
@ -223,6 +373,8 @@ NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
ACCESS_MASK DesiredAccess; ACCESS_MASK DesiredAccess;
LIST_ENTRY DeferredList; LIST_ENTRY DeferredList;
UNICODE_STRING Prefix; UNICODE_STRING Prefix;
NTSTATUS Status;
TRACE("Entered\n");
InitializeListHead(&DeferredList); InitializeListHead(&DeferredList);
IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp); IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
@ -276,8 +428,9 @@ NpFsdCreate(IN PDEVICE_OBJECT DeviceObject,
goto Quickie; goto Quickie;
} }
// Status = NpTranslateAlias(&FileName);; // ignore this for now Status = NpTranslateAlias(&FileName);
// if (!NT_SUCCESS(Status)) goto Quickie; if (!NT_SUCCESS(Status)) goto Quickie;
if (RelatedFileObject) if (RelatedFileObject)
{ {
if (Type == NPFS_NTC_ROOT_DCB) if (Type == NPFS_NTC_ROOT_DCB)
@ -355,6 +508,7 @@ Quickie:
Irp->IoStatus = IoStatus; Irp->IoStatus = IoStatus;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status);
return IoStatus.Status; return IoStatus.Status;
} }
@ -380,6 +534,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
USHORT NamedPipeConfiguration, CheckShareAccess; USHORT NamedPipeConfiguration, CheckShareAccess;
BOOLEAN AccessGranted; BOOLEAN AccessGranted;
PAGED_CODE(); PAGED_CODE();
TRACE("Entered\n");
Privileges = NULL; Privileges = NULL;
@ -424,17 +579,23 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
&AccessState->GenerateOnClose); &AccessState->GenerateOnClose);
SeUnlockSubjectContext(SubjectSecurityContext); SeUnlockSubjectContext(SubjectSecurityContext);
if (!AccessGranted) return IoStatus; if (!AccessGranted)
{
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus;
}
if (Fcb->CurrentInstances >= Fcb->MaximumInstances) if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
{ {
IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE; IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus; return IoStatus;
} }
if (Disposition == FILE_CREATE) if (Disposition == FILE_CREATE)
{ {
IoStatus.Status = STATUS_ACCESS_DENIED; IoStatus.Status = STATUS_ACCESS_DENIED;
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus; return IoStatus;
} }
@ -455,6 +616,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
if (CheckShareAccess != ShareAccess) if (CheckShareAccess != ShareAccess)
{ {
IoStatus.Status = STATUS_ACCESS_DENIED; IoStatus.Status = STATUS_ACCESS_DENIED;
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus; return IoStatus;
} }
@ -476,6 +638,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
{ {
--Ccb->Fcb->CurrentInstances; --Ccb->Fcb->CurrentInstances;
NpDeleteCcb(Ccb, List); NpDeleteCcb(Ccb, List);
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus; return IoStatus;
} }
@ -485,6 +648,7 @@ NpCreateExistingNamedPipe(IN PNP_FCB Fcb,
IoStatus.Status = STATUS_SUCCESS; IoStatus.Status = STATUS_SUCCESS;
IoStatus.Information = 1; IoStatus.Information = 1;
TRACE("Leaving, IoStatus = %lx\n", IoStatus);
return IoStatus; return IoStatus;
} }
@ -509,6 +673,7 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
PNP_CCB Ccb; PNP_CCB Ccb;
PNP_FCB Fcb; PNP_FCB Fcb;
PAGED_CODE(); PAGED_CODE();
TRACE("Entered\n");
if (!(Parameters->TimeoutSpecified) || if (!(Parameters->TimeoutSpecified) ||
!(Parameters->MaximumInstances) || !(Parameters->MaximumInstances) ||
@ -611,9 +776,11 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
IoStatus->Status = STATUS_SUCCESS; IoStatus->Status = STATUS_SUCCESS;
IoStatus->Information = FILE_CREATED; IoStatus->Information = FILE_CREATED;
TRACE("Leaving, STATUS_SUCCESS\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
Quickie: Quickie:
TRACE("Leaving, Status = %lx\n", Status);
IoStatus->Information = 0; IoStatus->Information = 0;
IoStatus->Status = Status; IoStatus->Status = Status;
return Status; return Status;
@ -635,6 +802,7 @@ NpFsdCreateNamedPipe(IN PDEVICE_OBJECT DeviceObject,
UNICODE_STRING Prefix; UNICODE_STRING Prefix;
PNAMED_PIPE_CREATE_PARAMETERS Parameters; PNAMED_PIPE_CREATE_PARAMETERS Parameters;
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
TRACE("Entered\n");
InitializeListHead(&DeferredList); InitializeListHead(&DeferredList);
Process = IoGetRequestorProcess(Irp); Process = IoGetRequestorProcess(Irp);
@ -741,6 +909,7 @@ Quickie:
NpCompleteDeferredIrps(&DeferredList); NpCompleteDeferredIrps(&DeferredList);
FsRtlExitFileSystem(); FsRtlExitFileSystem();
TRACE("Leaving, IoStatus.Status = %lx\n", IoStatus.Status);
Irp->IoStatus = IoStatus; Irp->IoStatus = IoStatus;
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT); IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
return IoStatus.Status; return IoStatus.Status;

View file

@ -16,14 +16,292 @@
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
PDEVICE_OBJECT NpfsDeviceObject; PDEVICE_OBJECT NpfsDeviceObject;
PVOID NpAliases;
PNPFS_ALIAS NpAliasList;
PNPFS_ALIAS NpAliasListByLength[MAX_INDEXED_LENGTH + 1 - MIN_INDEXED_LENGTH];
/* FUNCTIONS ******************************************************************/ /* 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 NTSTATUS
NTAPI NTAPI
NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject, NpFsdDirectoryControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
TRACE("Entered\n");
UNIMPLEMENTED; UNIMPLEMENTED;
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
@ -45,6 +323,13 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
DPRINT1("Next-Generation NPFS-Lite\n"); 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] = NpFsdCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = NpFsdCreateNamedPipe; DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = NpFsdCreateNamedPipe;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NpFsdClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = NpFsdClose;

View file

@ -14,8 +14,12 @@
#include <ntifs.h> #include <ntifs.h>
#include <ntndk.h> #include <ntndk.h>
#include <pseh/pseh2.h> #include <pseh/pseh2.h>
#define UNIMPLEMENTED //#define UNIMPLEMENTED
#define DPRINT1 DbgPrint //#define DPRINT1 DbgPrint
#define NDEBUG
#include <debug.h>
#define TRACE(...) /* DPRINT1("%s: ", __FUNCTION__); DbgPrint(__VA_ARGS__) */
// //
// Allow Microsoft Extensions // Allow Microsoft Extensions
@ -26,6 +30,9 @@
#pragma warning(disable:4100) #pragma warning(disable:4100)
#endif #endif
#define MIN_INDEXED_LENGTH 5
#define MAX_INDEXED_LENGTH 9
/* TYPEDEFS & DEFINES *********************************************************/ /* TYPEDEFS & DEFINES *********************************************************/
@ -326,6 +333,32 @@ typedef struct _NP_VCB
extern PNP_VCB NpVcb; 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 ******************************************************************/ /* FUNCTIONS ******************************************************************/
@ -385,6 +418,12 @@ NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList)
} }
} }
LONG
NTAPI
NpCompareAliasNames(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2);
BOOLEAN BOOLEAN
NTAPI NTAPI
NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table, NpDeleteEventTableEntry(IN PRTL_GENERIC_TABLE Table,
@ -415,7 +454,7 @@ NTAPI
NpAddDataQueueEntry(IN ULONG NamedPipeEnd, NpAddDataQueueEntry(IN ULONG NamedPipeEnd,
IN PNP_CCB Ccb, IN PNP_CCB Ccb,
IN PNP_DATA_QUEUE DataQueue, IN PNP_DATA_QUEUE DataQueue,
IN ULONG Who, IN ULONG Who,
IN ULONG Type, IN ULONG Type,
IN ULONG DataSize, IN ULONG DataSize,
IN PIRP Irp, IN PIRP Irp,
@ -510,20 +549,20 @@ NpSetConnectedPipeState(IN PNP_CCB Ccb,
NTSTATUS NTSTATUS
NTAPI NTAPI
NpSetListeningPipeState(IN PNP_CCB Ccb, NpSetListeningPipeState(IN PNP_CCB Ccb,
IN PIRP Irp, IN PIRP Irp,
IN PLIST_ENTRY List); IN PLIST_ENTRY List);
NTSTATUS NTSTATUS
NTAPI NTAPI
NpSetDisconnectedPipeState(IN PNP_CCB Ccb, NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
IN PLIST_ENTRY List); IN PLIST_ENTRY List);
NTSTATUS NTSTATUS
NTAPI NTAPI
NpSetClosingPipeState(IN PNP_CCB Ccb, NpSetClosingPipeState(IN PNP_CCB Ccb,
IN PIRP Irp, IN PIRP Irp,
IN ULONG NamedPipeEnd, IN ULONG NamedPipeEnd,
IN PLIST_ENTRY List); IN PLIST_ENTRY List);
VOID VOID
@ -594,7 +633,7 @@ NTSTATUS
NTAPI NTAPI
NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue, NpAddWaiter(IN PNP_WAIT_QUEUE WaitQueue,
IN LARGE_INTEGER WaitTime, IN LARGE_INTEGER WaitTime,
IN PIRP Irp, IN PIRP Irp,
IN PUNICODE_STRING AliasName); IN PUNICODE_STRING AliasName);
NTSTATUS NTSTATUS
@ -607,27 +646,27 @@ NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
IO_STATUS_BLOCK IO_STATUS_BLOCK
NTAPI NTAPI
NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue, NpReadDataQueue(IN PNP_DATA_QUEUE DataQueue,
IN BOOLEAN Peek, IN BOOLEAN Peek,
IN BOOLEAN ReadOverflowOperation, IN BOOLEAN ReadOverflowOperation,
IN PVOID Buffer, IN PVOID Buffer,
IN ULONG BufferSize, IN ULONG BufferSize,
IN ULONG Mode, IN ULONG Mode,
IN PNP_CCB Ccb, IN PNP_CCB Ccb,
IN PLIST_ENTRY List); IN PLIST_ENTRY List);
NTSTATUS NTSTATUS
NTAPI NTAPI
NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue, NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
IN ULONG Mode, IN ULONG Mode,
IN PVOID OutBuffer, IN PVOID OutBuffer,
IN ULONG OutBufferSize, IN ULONG OutBufferSize,
IN ULONG PipeType, IN ULONG PipeType,
OUT PULONG BytesWritten, OUT PULONG BytesWritten,
IN PNP_CCB Ccb, IN PNP_CCB Ccb,
IN ULONG NamedPipeEnd, IN ULONG NamedPipeEnd,
IN PETHREAD Thread, IN PETHREAD Thread,
IN PLIST_ENTRY List); IN PLIST_ENTRY List);
NTSTATUS NTSTATUS

View file

@ -15,8 +15,6 @@
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
#define UNIMPLEMENTED
PWCHAR NpRootDCBName = L"\\"; PWCHAR NpRootDCBName = L"\\";
PNP_VCB NpVcb; PNP_VCB NpVcb;

View file

@ -23,6 +23,7 @@ NpQueryFsVolumeInfo(IN PVOID Buffer,
PFILE_FS_VOLUME_INFORMATION InfoBuffer = Buffer; PFILE_FS_VOLUME_INFORMATION InfoBuffer = Buffer;
NTSTATUS Status; NTSTATUS Status;
USHORT NameLength; USHORT NameLength;
TRACE("Entered\n");
*Length -= sizeof(*InfoBuffer); *Length -= sizeof(*InfoBuffer);
@ -47,6 +48,7 @@ NpQueryFsVolumeInfo(IN PVOID Buffer,
RtlCopyMemory(InfoBuffer->VolumeLabel, L"Named Pipe", NameLength); RtlCopyMemory(InfoBuffer->VolumeLabel, L"Named Pipe", NameLength);
*Length -= NameLength; *Length -= NameLength;
TRACE("Leaving, Status = %lx\n", Status);
return Status; return Status;
} }
@ -56,6 +58,7 @@ NpQueryFsSizeInfo(IN PVOID Buffer,
IN OUT PULONG Length) IN OUT PULONG Length)
{ {
PFILE_FS_SIZE_INFORMATION InfoBuffer = Buffer; PFILE_FS_SIZE_INFORMATION InfoBuffer = Buffer;
TRACE("Entered\n");
*Length -= sizeof(*InfoBuffer); *Length -= sizeof(*InfoBuffer);
@ -64,6 +67,7 @@ NpQueryFsSizeInfo(IN PVOID Buffer,
InfoBuffer->SectorsPerAllocationUnit = 1; InfoBuffer->SectorsPerAllocationUnit = 1;
InfoBuffer->BytesPerSector = 1; InfoBuffer->BytesPerSector = 1;
TRACE("Leaving, Status = STATUS_SUCCESS\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -74,6 +78,7 @@ NpQueryFsDeviceInfo(IN PVOID Buffer,
{ {
PFILE_FS_DEVICE_INFORMATION InfoBuffer = Buffer; PFILE_FS_DEVICE_INFORMATION InfoBuffer = Buffer;
NTSTATUS Status; NTSTATUS Status;
TRACE("Entered\n");
if (*Length >= sizeof(*InfoBuffer)) if (*Length >= sizeof(*InfoBuffer))
{ {
@ -87,6 +92,7 @@ NpQueryFsDeviceInfo(IN PVOID Buffer,
{ {
Status = STATUS_BUFFER_OVERFLOW; Status = STATUS_BUFFER_OVERFLOW;
} }
TRACE("Leaving, Status = %lx\n", Status);
return Status; return Status;
} }
@ -98,6 +104,7 @@ NpQueryFsAttributeInfo(IN PVOID Buffer,
PFILE_FS_ATTRIBUTE_INFORMATION InfoBuffer = Buffer; PFILE_FS_ATTRIBUTE_INFORMATION InfoBuffer = Buffer;
NTSTATUS Status; NTSTATUS Status;
USHORT NameLength; USHORT NameLength;
TRACE("Entered\n");
NameLength = (USHORT)(*Length - 12); NameLength = (USHORT)(*Length - 12);
if (NameLength < 8) if (NameLength < 8)
@ -117,6 +124,7 @@ NpQueryFsAttributeInfo(IN PVOID Buffer,
InfoBuffer->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES; InfoBuffer->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES;
RtlCopyMemory(InfoBuffer->FileSystemName, L"NPFS", NameLength); RtlCopyMemory(InfoBuffer->FileSystemName, L"NPFS", NameLength);
TRACE("Leaving, Status = %lx\n", Status);
return Status; return Status;
} }
@ -126,11 +134,13 @@ NpQueryFsFullSizeInfo(IN PVOID Buffer,
IN OUT PULONG Length) IN OUT PULONG Length)
{ {
PFILE_FS_FULL_SIZE_INFORMATION InfoBuffer = Buffer; PFILE_FS_FULL_SIZE_INFORMATION InfoBuffer = Buffer;
TRACE("Entered\n");
*Length -= sizeof(*InfoBuffer); *Length -= sizeof(*InfoBuffer);
RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer)); RtlZeroMemory(InfoBuffer, sizeof(*InfoBuffer));
TRACE("Leaving, Status = STATUS_SUCCESS\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -145,6 +155,7 @@ NpCommonQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
PVOID Buffer; PVOID Buffer;
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
TRACE("Entered\n");
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
Buffer = Irp->AssociatedIrp.SystemBuffer; Buffer = Irp->AssociatedIrp.SystemBuffer;
@ -174,6 +185,7 @@ NpCommonQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
} }
Irp->IoStatus.Information = IoStack->Parameters.QueryVolume.Length - Length; Irp->IoStatus.Information = IoStack->Parameters.QueryVolume.Length - Length;
TRACE("Leaving, Status = %lx\n", Status);
return Status; return Status;
} }
@ -184,6 +196,7 @@ NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
{ {
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
TRACE("Entered\n");
FsRtlEnterFileSystem(); FsRtlEnterFileSystem();
ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE); ExAcquireResourceSharedLite(&NpVcb->Lock, TRUE);
@ -199,6 +212,7 @@ NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject,
IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT); IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT);
} }
TRACE("Leaving, Status = %lx\n", Status);
return Status; return Status;
} }