From 56261817357507908f755d0c565cfd3a47e70c02 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 07:46:17 +0000 Subject: [PATCH 01/30] - Implement ObCheckCreateObjectAccess, ObpCheckTraverseAccess, ObpCheckObjectReference. These APIs are not used yet but are all very similar to ObCheckObjectAccess. There are used at different places by Ob to make sure that the current token and access rights permits some privileged operations such as directory traversal, object referencing and object creation. svn path=/trunk/; revision=25368 --- reactos/ntoskrnl/ob/obsecure.c | 207 ++++++++++++++++++++++++++++++++- 1 file changed, 203 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/ob/obsecure.c b/reactos/ntoskrnl/ob/obsecure.c index 7faad13f83d..7bd90065e2b 100644 --- a/reactos/ntoskrnl/ob/obsecure.c +++ b/reactos/ntoskrnl/ob/obsecure.c @@ -11,10 +11,209 @@ #include #define NDEBUG -#include +#include /* PRIVATE FUNCTIONS *********************************************************/ +BOOLEAN +NTAPI +ObCheckCreateObjectAccess(IN PVOID Object, + IN ACCESS_MASK CreateAccess, + IN PACCESS_STATE AccessState, + IN PUNICODE_STRING ComponentName, + IN BOOLEAN LockHeld, + IN KPROCESSOR_MODE AccessMode, + OUT PNTSTATUS AccessStatus) +{ + POBJECT_HEADER ObjectHeader; + POBJECT_TYPE ObjectType; + PSECURITY_DESCRIPTOR SecurityDescriptor; + BOOLEAN SdAllocated; + BOOLEAN Result = TRUE; + ACCESS_MASK GrantedAccess = 0; + PPRIVILEGE_SET Privileges = NULL; + NTSTATUS Status; + PAGED_CODE(); + + /* Get the header and type */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); + ObjectType = ObjectHeader->Type; + + /* Get the security descriptor */ + Status = ObGetObjectSecurity(Object, &SecurityDescriptor, &SdAllocated); + if (!NT_SUCCESS(Status)) + { + /* We failed */ + *AccessStatus = Status; + return FALSE; + } + + /* Lock the security context */ + SeLockSubjectContext(&AccessState->SubjectSecurityContext); + + /* Check if we have an SD */ + if (SecurityDescriptor) + { + /* Now do the entire access check */ + Result = SeAccessCheck(SecurityDescriptor, + &AccessState->SubjectSecurityContext, + TRUE, + CreateAccess, + 0, + &Privileges, + &ObjectType->TypeInfo.GenericMapping, + AccessMode, + &GrantedAccess, + AccessStatus); + if (Privileges) + { + /* We got privileges, append them to the access state and free them */ + Status = SeAppendPrivileges(AccessState, Privileges); + SeFreePrivileges(Privileges); + } + } + + /* We're done, unlock the context and release security */ + SeUnlockSubjectContext(&AccessState->SubjectSecurityContext); + ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated); + return Result; +} + +BOOLEAN +NTAPI +ObpCheckTraverseAccess(IN PVOID Object, + IN ACCESS_MASK TraverseAccess, + IN PACCESS_STATE AccessState OPTIONAL, + IN BOOLEAN LockHeld, + IN KPROCESSOR_MODE AccessMode, + OUT PNTSTATUS AccessStatus) +{ + POBJECT_HEADER ObjectHeader; + POBJECT_TYPE ObjectType; + PSECURITY_DESCRIPTOR SecurityDescriptor; + BOOLEAN SdAllocated; + BOOLEAN Result; + ACCESS_MASK GrantedAccess = 0; + PPRIVILEGE_SET Privileges = NULL; + NTSTATUS Status; + PAGED_CODE(); + + /* Get the header and type */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); + ObjectType = ObjectHeader->Type; + + /* Get the security descriptor */ + Status = ObGetObjectSecurity(Object, &SecurityDescriptor, &SdAllocated); + if (!NT_SUCCESS(Status)) + { + /* We failed */ + *AccessStatus = Status; + return FALSE; + } + + /* Lock the security context */ + SeLockSubjectContext(&AccessState->SubjectSecurityContext); + + /* Now do the entire access check */ + Result = SeAccessCheck(SecurityDescriptor, + &AccessState->SubjectSecurityContext, + TRUE, + TraverseAccess, + 0, + &Privileges, + &ObjectType->TypeInfo.GenericMapping, + AccessMode, + &GrantedAccess, + AccessStatus); + if (Privileges) + { + /* We got privileges, append them to the access state and free them */ + Status = SeAppendPrivileges(AccessState, Privileges); + SeFreePrivileges(Privileges); + } + + /* We're done, unlock the context and release security */ + SeUnlockSubjectContext(&AccessState->SubjectSecurityContext); + ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated); + return Result; +} + +BOOLEAN +NTAPI +ObpCheckObjectReference(IN PVOID Object, + IN OUT PACCESS_STATE AccessState, + IN BOOLEAN LockHeld, + IN KPROCESSOR_MODE AccessMode, + OUT PNTSTATUS AccessStatus) +{ + POBJECT_HEADER ObjectHeader; + POBJECT_TYPE ObjectType; + PSECURITY_DESCRIPTOR SecurityDescriptor; + BOOLEAN SdAllocated; + BOOLEAN Result; + ACCESS_MASK GrantedAccess = 0; + PPRIVILEGE_SET Privileges = NULL; + NTSTATUS Status; + PAGED_CODE(); + + /* Get the header and type */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); + ObjectType = ObjectHeader->Type; + + /* Get the security descriptor */ + Status = ObGetObjectSecurity(Object, &SecurityDescriptor, &SdAllocated); + if (!NT_SUCCESS(Status)) + { + /* We failed */ + *AccessStatus = Status; + return FALSE; + } + + /* Lock the security context */ + SeLockSubjectContext(&AccessState->SubjectSecurityContext); + + /* Now do the entire access check */ + Result = SeAccessCheck(SecurityDescriptor, + &AccessState->SubjectSecurityContext, + TRUE, + AccessState->RemainingDesiredAccess, + AccessState->PreviouslyGrantedAccess, + &Privileges, + &ObjectType->TypeInfo.GenericMapping, + AccessMode, + &GrantedAccess, + AccessStatus); + if (Result) + { + /* Update the access state */ + AccessState->RemainingDesiredAccess &= ~GrantedAccess; + AccessState->PreviouslyGrantedAccess |= GrantedAccess; + } + + /* Check if we have an SD */ + if (SecurityDescriptor) + { + /* Do audit alarm */ +#if 0 + SeObjectReferenceAuditAlarm(&AccessState->OperationID, + Object, + SecurityDescriptor, + &AccessState->SubjectSecurityContext, + AccessState->RemainingDesiredAccess | + AccessState->PreviouslyGrantedAccess, + ((PAUX_DATA)(AccessState->AuxData))-> + PrivilegeSet, + Result, + AccessMode); +#endif + } + + /* We're done, unlock the context and release security */ + SeUnlockSubjectContext(&AccessState->SubjectSecurityContext); + ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated); + return Result; +} + /*++ * @name ObCheckObjectAccess * @@ -26,7 +225,7 @@ * @param AccessState * * -* @param Unknown +* @param LockHeld * * * @param AccessMode @@ -44,7 +243,7 @@ BOOLEAN NTAPI ObCheckObjectAccess(IN PVOID Object, IN OUT PACCESS_STATE AccessState, - IN BOOLEAN Unknown, + IN BOOLEAN LockHeld, IN KPROCESSOR_MODE AccessMode, OUT PNTSTATUS ReturnedStatus) { @@ -93,7 +292,7 @@ ObCheckObjectAccess(IN PVOID Object, ReturnedStatus); if (Privileges) { - /* We got privileges, append them to teh access state and free them */ + /* We got privileges, append them to the access state and free them */ Status = SeAppendPrivileges(AccessState, Privileges); SeFreePrivileges(Privileges); } From d107f7d0f4f6e010ae30ef3135131230f52da2f6 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 07:51:07 +0000 Subject: [PATCH 02/30] - Set an invalid pointer as the object header's type when freeing it, to detect invalid usage. - Optimize type mutex acquisition in ObpDeleteObject. Also optimize freeing of the unicode_String containing the name. Also add callout checks/protection during the security and delete procedure callouts. - Acquire object type mutex during modification of the OB_FLAG_PERMANENT flag in ObpSetPermanentObject. - Initialize default QueryReferences field to 1 during object allocation. - Support undocumented 0x10000 object attribute flag used in Windows 2003 SP1 and higher to protect objects from user-mode access (such as PhysicalMemory). - Use InterlockedIncrements for ObjectType accounting outside the type lock. - Clear the lookup context's object pointer for future use. svn path=/trunk/; revision=25369 --- reactos/ntoskrnl/ob/oblife.c | 77 +++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 19 deletions(-) diff --git a/reactos/ntoskrnl/ob/oblife.c b/reactos/ntoskrnl/ob/oblife.c index 72ef1c16471..54be69e9aa3 100644 --- a/reactos/ntoskrnl/ob/oblife.c +++ b/reactos/ntoskrnl/ob/oblife.c @@ -107,9 +107,6 @@ ObpDeallocateObject(IN PVOID Object) /* Add the SD charge too */ if (Header->Flags & OB_FLAG_SECURITY) PagedPoolCharge += 2048; } - - /* FIXME: Should be returning quota */ - DPRINT("Quotas: %lx %lx\n", PagedPoolCharge, NonPagedPoolCharge); } } @@ -129,6 +126,9 @@ ObpDeallocateObject(IN PVOID Object) NameInfo->Name.Buffer = NULL; } + /* Catch invalid access */ + Header->Type = (POBJECT_TYPE)0xBAADB0B0; + /* Free the object using the same allocation tag */ ExFreePoolWithTag(HeaderLocation, ObjectType->Key); } @@ -142,6 +142,7 @@ ObpDeleteObject(IN PVOID Object, POBJECT_TYPE ObjectType; POBJECT_HEADER_NAME_INFO NameInfo; POBJECT_HEADER_CREATOR_INFO CreatorInfo; + KIRQL CalloutIrql; PAGED_CODE(); /* Get the header and type */ @@ -152,33 +153,32 @@ ObpDeleteObject(IN PVOID Object, NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header); CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(Header); - /* Lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); - /* Check if the object is on a type list */ if ((CreatorInfo) && !(IsListEmpty(&CreatorInfo->TypeList))) { + /* Lock the object type */ + ObpEnterObjectTypeMutex(ObjectType); + /* Remove the object from the type list */ RemoveEntryList(&CreatorInfo->TypeList); - } - /* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + /* Release the lock */ + ObpLeaveObjectTypeMutex(ObjectType); + } /* Check if we have a name */ if ((NameInfo) && (NameInfo->Name.Buffer)) { /* Free it */ ExFreePool(NameInfo->Name.Buffer); - - /* Clean up the string so we don't try this again */ - RtlInitUnicodeString(&NameInfo->Name, NULL); + RtlInitEmptyUnicodeString(&NameInfo->Name, NULL, 0); } /* Check if we have a security descriptor */ if (Header->SecurityDescriptor) { /* Call the security procedure to delete it */ + ObpCalloutStart(&CalloutIrql); ObjectType->TypeInfo.SecurityProcedure(Object, DeleteSecurityDescriptor, 0, @@ -187,13 +187,16 @@ ObpDeleteObject(IN PVOID Object, &Header->SecurityDescriptor, 0, NULL); + ObpCalloutEnd(CalloutIrql, "Security", ObjectType, Object); } /* Check if we have a delete procedure */ if (ObjectType->TypeInfo.DeleteProcedure) { /* Call it */ + ObpCalloutStart(&CalloutIrql); ObjectType->TypeInfo.DeleteProcedure(Object); + ObpCalloutEnd(CalloutIrql, "Delete", ObjectType, Object); } /* Now de-allocate all object members */ @@ -256,16 +259,27 @@ ObpSetPermanentObject(IN PVOID ObjectBody, /* Get the header */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody); + + /* Acquire object type lock */ + ObpEnterObjectTypeMutex(ObjectHeader->Type); + + /* Check what we're doing to it */ if (Permanent) { /* Set it to permanent */ ObjectHeader->Flags |= OB_FLAG_PERMANENT; + + /* Release the lock */ + ObpLeaveObjectTypeMutex(ObjectHeader->Type); } else { /* Remove the flag */ ObjectHeader->Flags &= ~OB_FLAG_PERMANENT; + /* Release the lock */ + ObpLeaveObjectTypeMutex(ObjectHeader->Type); + /* Check if we should delete the object now */ ObpDeleteNameCheck(ObjectBody); } @@ -623,9 +637,10 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, Header = ExAllocatePoolWithTag(PoolType, FinalSize + ObjectSize, Tag); if (!Header) return STATUS_INSUFFICIENT_RESOURCES; - /* Initialize quota info */ + /* Check if we have a quota header */ if (QuotaSize) { + /* Initialize quota info */ QuotaInfo = (POBJECT_HEADER_QUOTA_INFO)Header; QuotaInfo->PagedPoolCharge = ObjectCreateInfo->PagedPoolCharge; QuotaInfo->NonPagedPoolCharge = ObjectCreateInfo->NonPagedPoolCharge; @@ -634,26 +649,41 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, Header = (POBJECT_HEADER)(QuotaInfo + 1); } - /* Initialize Handle Info */ + /* Check if we have a handle database header */ if (HandleSize) { + /* Initialize Handle Info */ HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header; HandleInfo->SingleEntry.HandleCount = 0; Header = (POBJECT_HEADER)(HandleInfo + 1); } - /* Initialize the Object Name Info */ + /* Check if we have a name header */ if (NameSize) { + /* Initialize the Object Name Info */ NameInfo = (POBJECT_HEADER_NAME_INFO)Header; NameInfo->Name = *ObjectName; NameInfo->Directory = NULL; + NameInfo->QueryReferences = 1; + + /* Check if this is a call with the special protection flag */ + if ((PreviousMode == KernelMode) && + (ObjectCreateInfo) && + (ObjectCreateInfo->Attributes & 0x10000)) + { + /* Set flag which will make the object protected from user-mode */ + NameInfo->QueryReferences |= 0x40000000; + } + + /* Set the header pointer */ Header = (POBJECT_HEADER)(NameInfo + 1); } - /* Initialize Creator Info */ + /* Check if we have a creator header */ if (CreatorSize) { + /* Initialize Creator Info */ CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header; CreatorInfo->CreatorBackTraceIndex = 0; CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcessId(); @@ -739,7 +769,7 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, if (ObjectType) { /* Increase the number of objects of this type */ - ObjectType->TotalNumberOfObjects++; + InterlockedIncrement(&ObjectType->TotalNumberOfObjects); /* Update the high water */ ObjectType->HighWaterNumberOfObjects = max(ObjectType-> @@ -774,8 +804,6 @@ ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, POBJECT_CREATE_INFORMATION ObjectCreateInfo; UNICODE_STRING ObjectName; POBJECT_HEADER Header; - DPRINT("ObCreateObject(Type %p ObjectAttributes %p, Object %p)\n", - Type, ObjectAttributes, Object); /* Allocate a capture buffer */ ObjectCreateInfo = ObpAllocateCapturedAttributes(LookasideCreateInfoList); @@ -898,6 +926,8 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, if (*p++ == OBJ_NAME_PATH_SEPARATOR) return STATUS_OBJECT_NAME_INVALID; } + Context.Object = NULL; + /* Check if we've already created the directory of types */ if (ObpTypeDirectoryObject) { @@ -911,6 +941,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, &Context)) { /* We have already created it, so fail */ + Context.Object = NULL; return STATUS_OBJECT_NAME_COLLISION; } } @@ -922,6 +953,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, if (!ObjectName.Buffer) { /* Out of memory, fail */ + Context.Object = NULL; return STATUS_INSUFFICIENT_RESOURCES; } @@ -938,6 +970,8 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, (POBJECT_HEADER*)&Header); if (!NT_SUCCESS(Status)) { + Context.Object = NULL; + /* Free the name and fail */ ExFreePool(ObjectName.Buffer); return Status; @@ -1067,12 +1101,15 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, ObReferenceObject(ObpTypeDirectoryObject); } + Context.Object = NULL; + /* Return the object type and success */ *ObjectType = LocalObjectType; return STATUS_SUCCESS; } /* If we got here, then we failed */ + Context.Object = NULL; return STATUS_INSUFFICIENT_RESOURCES; } @@ -1094,6 +1131,8 @@ VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody) { + PAGED_CODE(); + /* Call the internal API */ ObpSetPermanentObject(ObjectBody, FALSE); } From 569e9458d6e74075d9b7fab94f6473ddf713bc3a Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 07:53:50 +0000 Subject: [PATCH 03/30] - Validate lookup context in ObpInsertEntryDirectory. - Read actual ObpLUIDDeviceMapsEnable variable do determine if shadow-searching is enabled in ObpLookupEntryDirectory. - Currently disable all directory locking code (it was never used anyways) in ObpLookupEntryDirectory. - Update ObpLookupEntryDirectory with placeholder code/branches for future patch implementing directory locks. svn path=/trunk/; revision=25370 --- reactos/ntoskrnl/ob/obdir.c | 78 ++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 18 deletions(-) diff --git a/reactos/ntoskrnl/ob/obdir.c b/reactos/ntoskrnl/ob/obdir.c index a0cfdda2bba..5cb37be6df5 100644 --- a/reactos/ntoskrnl/ob/obdir.c +++ b/reactos/ntoskrnl/ob/obdir.c @@ -13,11 +13,11 @@ /* INCLUDES ***************************************************************/ -#define NTDDI_VERSION NTDDI_WS03 #include #define NDEBUG -#include +#include +BOOLEAN ObpLUIDDeviceMapsEnabled; POBJECT_TYPE ObDirectoryType = NULL; /* PRIVATE FUNCTIONS ******************************************************/ @@ -54,6 +54,18 @@ ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, /* Make sure we have a name */ ASSERT(ObjectHeader->NameInfoOffset != 0); + /* Validate the context */ + if ((Context->Object) || + !(Context->DirectoryLocked) || + (Parent != Context->Directory)) + { + /* Invalid context */ + DPRINT1("OB: ObpInsertEntryDirectory - invalid context %p %ld\n", + Context, Context->DirectoryLocked); + KEBUGCHECK(0); + return FALSE; + } + /* Allocate a new Directory Entry */ NewEntry = ExAllocatePoolWithTag(PagedPool, sizeof(OBJECT_DIRECTORY_ENTRY), @@ -116,6 +128,7 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, { BOOLEAN CaseInsensitive = FALSE; POBJECT_HEADER_NAME_INFO HeaderNameInfo; + POBJECT_HEADER ObjectHeader; ULONG HashValue; ULONG HashIndex; LONG TotalChars; @@ -127,8 +140,8 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, PWSTR Buffer; PAGED_CODE(); - /* Always disable this until we have DOS Device Maps */ - SearchShadow = FALSE; + /* Check if we should search the shadow directory */ + if (!ObpLUIDDeviceMapsEnabled) SearchShadow = FALSE; /* Fail if we don't have a directory or name */ if (!(Directory) || !(Name)) goto Quickie; @@ -137,12 +150,12 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, TotalChars = Name->Length / sizeof(WCHAR); Buffer = Name->Buffer; - /* Fail if the name is empty */ - if (!(Buffer) || !(TotalChars)) goto Quickie; - /* Set up case-sensitivity */ if (Attributes & OBJ_CASE_INSENSITIVE) CaseInsensitive = TRUE; + /* Fail if the name is empty */ + if (!(Buffer) || !(TotalChars)) goto Quickie; + /* Create the Hash */ for (HashValue = 0; TotalChars; TotalChars--) { @@ -172,9 +185,7 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, /* Check if the directory is already locked */ if (!Context->DirectoryLocked) { - /* Lock it */ - KeEnterCriticalRegion(); - ExAcquireResourceSharedLite(&Directory->Lock, TRUE); + } /* Start looping */ @@ -184,10 +195,11 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, if (CurrentEntry->HashValue == HashValue) { /* Make sure that it has a name */ - ASSERT(OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object)->NameInfoOffset != 0); + ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object); /* Get the name information */ - HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object)); + ASSERT(ObjectHeader->NameInfoOffset != 0); + HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); /* Do the names match? */ if ((Name->Length == HeaderNameInfo->Name.Length) && @@ -207,6 +219,11 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, /* Set this entry as the first, to speed up incoming insertion */ if (AllocatedEntry != LookupBucket) { + /* Check if the directory was locked */ + if (!Context->DirectoryLocked) + { + } + /* Set the Current Entry */ *AllocatedEntry = CurrentEntry->ChainLink; @@ -220,17 +237,42 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, /* Save the found object */ FoundObject = CurrentEntry->Object; if (!FoundObject) goto Quickie; - } - /* Check if the directory was unlocked (which means we locked it) */ - if (!Context->DirectoryLocked) + /* Get the object name information */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(FoundObject); + HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); + + /* Reference the object being looked up */ + //ObReferenceObject(FoundObject); + + /* Check if the directory was locked */ + if (!Context->DirectoryLocked) + { + } + } + else { - /* Lock it */ - ExReleaseResourceLite(&Directory->Lock); - KeLeaveCriticalRegion(); + /* Check if the directory was locked */ + if (!Context->DirectoryLocked) + { + } + + /* Check if we should scan the shadow directory */ + if ((SearchShadow) && (Directory->DeviceMap)) + { + /* FIXME: We don't support this yet */ + KEBUGCHECK(0); + } } Quickie: + /* Check if we found an object already */ + if (Context->Object) + { + /* We already did a lookup, so remove this object's query reference */ + //ObpRemoveQueryReference(Context->Object); + } + /* Return the object we found */ Context->Object = FoundObject; return FoundObject; From 956ae8b6f1c5193502b51f8227974498c3783ebd Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 07:54:57 +0000 Subject: [PATCH 04/30] - Changes to lookup context set-up as place-holder and compatibility for future patch. Only configure the lookup context once, outside the initial loop, instead of configuring it with the same settings at each iteration. svn path=/trunk/; revision=25371 --- reactos/ntoskrnl/ob/obinit.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/reactos/ntoskrnl/ob/obinit.c b/reactos/ntoskrnl/ob/obinit.c index 978888ad0ea..f34fcfd33ff 100644 --- a/reactos/ntoskrnl/ob/obinit.c +++ b/reactos/ntoskrnl/ob/obinit.c @@ -12,11 +12,9 @@ #include #define NDEBUG -#include +#include -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, ObInit) -#endif +/* GLOBALS *******************************************************************/ GENERIC_MAPPING ObpTypeMapping = { @@ -280,6 +278,10 @@ ObPostPhase0: Status = NtClose(Handle); if (!NT_SUCCESS(Status)) return FALSE; + Context.Object = NULL; + Context.Directory = ObpTypeDirectoryObject; + Context.DirectoryLocked = TRUE; + /* Loop the object types */ ListHead = &ObTypeObjectType->TypeList; NextEntry = ListHead->Flink; @@ -297,10 +299,6 @@ ObPostPhase0: /* Make sure we have a name, and aren't inserted yet */ if ((NameInfo) && !(NameInfo->Directory)) { - /* Set up the context for the insert */ - Context.Directory = ObpTypeDirectoryObject; - Context.DirectoryLocked = TRUE; - /* Do the initial lookup to setup the context */ if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject, &NameInfo->Name, @@ -319,6 +317,8 @@ ObPostPhase0: NextEntry = NextEntry->Flink; } + Context.Object = NULL; + /* Initialize DOS Devices Directory and related Symbolic Links */ Status = ObpCreateDosDevicesDirectory(); if (!NT_SUCCESS(Status)) return FALSE; From 74332efe6339ddea22da872ff5e389172e77bf82 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 08:03:47 +0000 Subject: [PATCH 05/30] - Fix ObReferenceObjectByName to do proper name validation checks. - Fix ObReferenceObjectByName to call ObpCheckObjectReference before allowing the caller to obtain the reference. - Rename ObFindObject to ObpLookupObjectName and shuffle parameters around and add some placeholder code that resets the object pointer of the lookup context. - Modify ObpChargeQuotaForObject to also return if this is a new object. - Modify ObpDecrementHandleCount to detect when objects with a handle database are being used. Also protect close callout with checks. Protect ObpCloseHAndleTableEntry's callouts with checks as well. - Update logic of ObpIncrementHandleCount and ObpIncrementUnnamedHandleCount to handle currently exclusive objects as well as new handles with OBJ_EXCLUSIVE. Also detect objects that require handle databases and protect callouts. - Support CreatorInfo and the TypeList in ObpIncrementHandleCount. Also update the TotalNumberOfHandles in the object type properly. - Fixup object type lock usage in these routines. - Do proper invalid attributes check in ObOpenObjectByName, and also use a buffer from the pool instead of the stack. - Make ObInsertObject detect invalid object insertions and change some parameter names and checks. - Add stub code to validate the access mask in ObInsertObject. Proper initailize some lookup variables before starting lookup. - Add detection for symbolic link inserts which require some handling code later on. - Free the create information at the right moment isntead of too late. - Add some missing Ob functions, flags and types to the NDK. Fix OBJECT_DIRECTORY structure to use EX_PUSH_LOCK for locks, not ERESOURCE. svn path=/trunk/; revision=25372 --- reactos/include/ndk/iotypes.h | 4 +- reactos/include/ndk/obtypes.h | 22 +- reactos/ntoskrnl/include/internal/ob.h | 70 ++- reactos/ntoskrnl/ob/obhandle.c | 608 +++++++++++++++++++------ reactos/ntoskrnl/ob/obname.c | 37 +- reactos/ntoskrnl/ob/obref.c | 63 ++- 6 files changed, 597 insertions(+), 207 deletions(-) diff --git a/reactos/include/ndk/iotypes.h b/reactos/include/ndk/iotypes.h index d0fe92cda55..5217162f463 100644 --- a/reactos/include/ndk/iotypes.h +++ b/reactos/include/ndk/iotypes.h @@ -23,9 +23,7 @@ Author: // Dependencies // #include -#if !defined(_NTIFS_) -typedef PVOID PFS_FILTER_CALLBACKS; -#endif +#include // // I/O Completion Access Rights diff --git a/reactos/include/ndk/obtypes.h b/reactos/include/ndk/obtypes.h index 72d50affa6b..a794077f47b 100644 --- a/reactos/include/ndk/obtypes.h +++ b/reactos/include/ndk/obtypes.h @@ -23,16 +23,14 @@ Author: // Dependencies // #include - -// -// If the IFS wasn't included, define this here -// -#ifndef EX_PUSH_LOCK -#define EX_PUSH_LOCK ULONG_PTR +#ifndef NTOS_MODE_USER +#include #endif -#ifdef NTOS_MODE_USER +#undef NTDDI_VERSION +#define NTDDI_VERSION NTDDI_WS03SP1 +#ifdef NTOS_MODE_USER // // Definitions for Object Creation // @@ -86,6 +84,7 @@ Author: #define OB_FLAG_PERMANENT 0x10 #define OB_FLAG_SECURITY 0x20 #define OB_FLAG_SINGLE_PROCESS 0x40 +#define OB_FLAG_DEFER_DELETE 0x80 #define OBJECT_TO_OBJECT_HEADER(o) \ CONTAINING_RECORD((o), OBJECT_HEADER, Body) @@ -107,6 +106,11 @@ Author: OB_FLAG_CREATOR_INFO) ? NULL: ((PCHAR)(h) - \ sizeof(OBJECT_HEADER_CREATOR_INFO)))) +#define OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(h) \ + ((!((h)->Flags & OB_FLAG_EXCLUSIVE)) ? \ + NULL: (((POBJECT_HEADER_QUOTA_INFO)((PCHAR)(h) - \ + (h)->QuotaInfoOffset))->ExclusiveProcess)) + // // Reasons for Open Callback // @@ -359,8 +363,8 @@ typedef struct _OBJECT_DIRECTORY struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[NUMBER_HASH_BUCKETS]; #if (NTDDI_VERSION < NTDDI_WINXP) ERESOURCE Lock; -#elif (NTDDI_VERSION >= NTDDI_WINXP) - ERESOURCE Lock; // FIXME: HACKHACK, SHOULD BE EX_PUSH_LOCK +#else + EX_PUSH_LOCK Lock; #endif #if (NTDDI_VERSION < NTDDI_WINXP) BOOLEAN CurrentEntryValid; diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index 2762164fc79..f8a2f21ccc6 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -80,6 +80,18 @@ typedef struct _OBP_CLOSE_HANDLE_CONTEXT KPROCESSOR_MODE AccessMode; } OBP_CLOSE_HANDLE_CONTEXT, *POBP_CLOSE_HANDLE_CONTEXT; +// +// Private Temporary Buffer for Lookup Routines +// +#define TAG_OB_TEMP_STORAGE TAG('O', 'b', 'S', 't') +typedef struct _OB_TEMP_BUFFER +{ + ACCESS_STATE LocalAccessState; + OBJECT_CREATE_INFORMATION ObjectCreateInfo; + OBP_LOOKUP_CONTEXT LookupContext; + AUX_DATA AuxData; +} OB_TEMP_BUFFER, *POB_TEMP_BUFFER; + // // Directory Namespace Functions // @@ -152,18 +164,18 @@ ObKillProcess( // NTSTATUS NTAPI -ObFindObject( +ObpLookupObjectName( IN HANDLE RootHandle, IN PUNICODE_STRING ObjectName, IN ULONG Attributes, - IN KPROCESSOR_MODE PreviousMode, - IN PVOID *ReturnedObject, IN POBJECT_TYPE ObjectType, - IN POBP_LOOKUP_CONTEXT Context, - IN PACCESS_STATE AccessState, + IN KPROCESSOR_MODE AccessMode, + IN OUT PVOID ParseContext, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, - IN PVOID ParseContext, - IN PVOID Insert + IN PVOID InsertObject, + IN PACCESS_STATE AccessState, + IN POBP_LOOKUP_CONTEXT LookupContext, + OUT PVOID *FoundObject ); // @@ -267,6 +279,12 @@ ObDereferenceDeviceMap( IN PEPROCESS Process ); +VOID +FASTCALL +ObfDereferenceDeviceMap( + IN PVOID DeviceMap +); + VOID NTAPI ObInheritDeviceMap( @@ -314,16 +332,52 @@ ObpDereferenceCachedSecurityDescriptor( IN PSECURITY_DESCRIPTOR SecurityDescriptor ); +// +// Object Security Routines +// BOOLEAN NTAPI ObCheckObjectAccess( IN PVOID Object, IN OUT PACCESS_STATE AccessState, - IN BOOLEAN Unknown, + IN BOOLEAN LockHeld, IN KPROCESSOR_MODE AccessMode, OUT PNTSTATUS ReturnedStatus ); +BOOLEAN +NTAPI +ObCheckCreateObjectAccess( + IN PVOID Object, + IN ACCESS_MASK CreateAccess, + IN PACCESS_STATE AccessState, + IN PUNICODE_STRING ComponentName, + IN BOOLEAN LockHeld, + IN KPROCESSOR_MODE AccessMode, + OUT PNTSTATUS AccessStatus +); + +BOOLEAN +NTAPI +ObpCheckTraverseAccess( + IN PVOID Object, + IN ACCESS_MASK TraverseAccess, + IN PACCESS_STATE AccessState OPTIONAL, + IN BOOLEAN LockHeld, + IN KPROCESSOR_MODE AccessMode, + OUT PNTSTATUS AccessStatus +); + +BOOLEAN +NTAPI +ObpCheckObjectReference( + IN PVOID Object, + IN OUT PACCESS_STATE AccessState, + IN BOOLEAN LockHeld, + IN KPROCESSOR_MODE AccessMode, + OUT PNTSTATUS AccessStatus +); + // // Executive Fast Referencing Functions // diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index 85b0271c4eb..f4ea0dc6132 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -24,7 +24,8 @@ PHANDLE_TABLE ObpKernelHandleTable = NULL; NTSTATUS NTAPI ObpChargeQuotaForObject(IN POBJECT_HEADER ObjectHeader, - IN POBJECT_TYPE ObjectType) + IN POBJECT_TYPE ObjectType, + OUT PBOOLEAN NewObject) { POBJECT_HEADER_QUOTA_INFO ObjectQuota; ULONG PagedPoolCharge, NonPagedPoolCharge; @@ -32,10 +33,14 @@ ObpChargeQuotaForObject(IN POBJECT_HEADER ObjectHeader, /* Get quota information */ ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader); + *NewObject = FALSE; /* Check if this is a new object */ if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO) { + /* Set the flag */ + *NewObject = TRUE; + /* Remove the flag */ ObjectHeader->Flags &= ~ OB_FLAG_CREATE_INFO; if (ObjectQuota) @@ -95,6 +100,7 @@ ObpDecrementHandleCount(IN PVOID ObjectBody, LONG SystemHandleCount, ProcessHandleCount; LONG NewCount; POBJECT_HEADER_CREATOR_INFO CreatorInfo; + KIRQL CalloutIrql; /* Get the object type and header */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody); @@ -109,7 +115,7 @@ ObpDecrementHandleCount(IN PVOID ObjectBody, /* Lock the object type */ ObpEnterObjectTypeMutex(ObjectType); - /* FIXME: The process handle count should be in the Handle DB. Investigate */ + /* Set default counts */ SystemHandleCount = ObjectHeader->HandleCount; ProcessHandleCount = 0; @@ -129,6 +135,13 @@ ObpDecrementHandleCount(IN PVOID ObjectBody, } } + /* Is the object type keeping track of handles? */ + if (ObjectType->TypeInfo.MaintainHandleCount) + { + /* FIXME */ + DPRINT("Handle Database not yet implemented\n"); + } + /* Release the lock */ ObpLeaveObjectTypeMutex(ObjectType); @@ -136,11 +149,13 @@ ObpDecrementHandleCount(IN PVOID ObjectBody, if (ObjectType->TypeInfo.CloseProcedure) { /* Call it */ + ObpCalloutStart(&CalloutIrql); ObjectType->TypeInfo.CloseProcedure(Process, ObjectBody, GrantedAccess, ProcessHandleCount, SystemHandleCount); + ObpCalloutEnd(CalloutIrql, "Close", ObjectType, ObjectBody); } /* Check if we should delete the object */ @@ -193,6 +208,7 @@ ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable, POBJECT_TYPE ObjectType; POBJECT_HEADER ObjectHeader; ACCESS_MASK GrantedAccess; + KIRQL CalloutIrql; PAGED_CODE(); /* Get the object data */ @@ -212,15 +228,20 @@ ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable, if (ObjectType->TypeInfo.OkayToCloseProcedure) { /* Call it and check if it's not letting us close it */ + ObpCalloutStart(&CalloutIrql); if (!ObjectType->TypeInfo.OkayToCloseProcedure(PsGetCurrentProcess(), Body, Handle, AccessMode)) { /* Fail */ + ObpCalloutEnd(CalloutIrql, "NtClose", ObjectType, Body); ExUnlockHandleTableEntry(HandleTable, HandleEntry); return STATUS_HANDLE_NOT_CLOSABLE; } + + /* Success, validate callout retrn */ + ObpCalloutEnd(CalloutIrql, "NtClose", ObjectType, Body); } /* The callback allowed us to close it, but does the handle itself? */ @@ -241,7 +262,7 @@ ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable, } else { - /* Return the error isntead */ + /* Return the error instead */ return STATUS_HANDLE_NOT_CLOSABLE; } } @@ -258,9 +279,6 @@ ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable, ObpDecrementHandleCount(Body, PsGetCurrentProcess(), GrantedAccess); /* Dereference the object as well */ - ASSERT(ObjectHeader->Type); - ASSERT(ObjectHeader->PointerCount != 0xCCCCCCCC); - ObDereferenceObject(Body); /* Return to caller */ @@ -315,6 +333,10 @@ ObpIncrementHandleCount(IN PVOID Object, POBJECT_TYPE ObjectType; ULONG ProcessHandleCount; NTSTATUS Status; + PEPROCESS ExclusiveProcess; + BOOLEAN Exclusive = FALSE, NewObject; + POBJECT_HEADER_CREATOR_INFO CreatorInfo; + KIRQL CalloutIrql; /* Get the object header and type */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); @@ -331,9 +353,60 @@ ObpIncrementHandleCount(IN PVOID Object, ObpEnterObjectTypeMutex(ObjectType); /* Charge quota and remove the creator info flag */ - Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType); + Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType, &NewObject); if (!NT_SUCCESS(Status)) return Status; + /* Check if the open is exclusive */ + if (HandleAttributes & OBJ_EXCLUSIVE) + { + /* Check if the object allows this, or if the inherit flag was given */ + if ((HandleAttributes & OBJ_INHERIT) || + !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)) + { + /* Incorrect attempt */ + DPRINT1("Failing here\n"); + Status = STATUS_INVALID_PARAMETER; + goto Quickie; + } + + /* Check if we have access to it */ + ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader); + if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) || + ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess()))) + { + /* This isn't the right process */ + Status = STATUS_ACCESS_DENIED; + goto Quickie; + } + + /* Now you got exclusive access */ + Exclusive = TRUE; + } + else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) && + (OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader))) + { + /* Caller didn't want exclusive access, but the object is exclusive */ + Status = STATUS_ACCESS_DENIED; + goto Quickie; + } + + /* + * Check if this is an object that went from 0 handles back to existence, + * but doesn't have an open procedure, only a close procedure. This means + * that it will never realize that the object is back alive, so we must + * fail the request. + */ + if (!(ObjectHeader->HandleCount) && + !(NewObject) && + (ObjectType->TypeInfo.MaintainHandleCount) && + !(ObjectType->TypeInfo.OpenProcedure) && + (ObjectType->TypeInfo.CloseProcedure)) + { + /* Fail */ + Status = STATUS_UNSUCCESSFUL; + goto Quickie; + } + /* Check if we're opening an existing handle */ if (OpenReason == ObOpenHandle) { @@ -345,7 +418,7 @@ ObpIncrementHandleCount(IN PVOID Object, &Status)) { /* Access was denied, so fail */ - return Status; + goto Quickie; } } else if (OpenReason == ObCreateHandle) @@ -365,30 +438,82 @@ ObpIncrementHandleCount(IN PVOID Object, RtlMapGenericMask(&AccessState->RemainingDesiredAccess, &ObjectType->TypeInfo.GenericMapping); } + + /* Check if the caller is trying to access system security */ + if (AccessState->RemainingDesiredAccess & ACCESS_SYSTEM_SECURITY) + { + /* FIXME: TODO */ + DPRINT1("ACCESS_SYSTEM_SECURITY not validated!\n"); + } + } + + /* Check if this is an exclusive handle */ + if (Exclusive) + { + /* Save the owner process */ + OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process; } /* Increase the handle count */ InterlockedIncrement(&ObjectHeader->HandleCount); + ProcessHandleCount = 0; + + /* Check if we have a handle database */ + if (ObjectType->TypeInfo.MaintainHandleCount) + { + /* FIXME: TODO */ + DPRINT("Handle DB not yet supported\n"); + } /* Release the lock */ ObpLeaveObjectTypeMutex(ObjectType); - /* FIXME: Use the Handle Database */ - ProcessHandleCount = 0; - /* Check if we have an open procedure */ + Status = STATUS_SUCCESS; if (ObjectType->TypeInfo.OpenProcedure) { /* Call it */ - ObjectType->TypeInfo.OpenProcedure(OpenReason, - Process, - Object, - AccessState->PreviouslyGrantedAccess, - ProcessHandleCount); + ObpCalloutStart(&CalloutIrql); + Status = ObjectType->TypeInfo.OpenProcedure(OpenReason, + Process, + Object, + AccessState->PreviouslyGrantedAccess, + ProcessHandleCount); + ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object); + + /* Check if the open procedure failed */ + if (!NT_SUCCESS(Status)) + { + /* FIXME: This should never happen for now */ + DPRINT1("Unhandled case\n"); + KEBUGCHECK(0); + return Status; + } + } + + /* Check if we have creator info */ + CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader); + if (CreatorInfo) + { + /* We do, acquire the lock */ + ObpEnterObjectTypeMutex(ObjectType); + + /* Insert us on the list */ + InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList); + + /* Release the lock */ + ObpLeaveObjectTypeMutex(ObjectType); } /* Increase total number of handles */ InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles); + if (ObjectType->TotalNumberOfHandles > ObjectType->HighWaterNumberOfHandles) + { + /* Fixup count */ + ObjectType->HighWaterNumberOfHandles = ObjectType->TotalNumberOfHandles; + } + + /* Trace call and return */ OBTRACE(OB_HANDLE_DEBUG, "%s - Incremented count for: %p. Reason: %lx HC LC %lx %lx\n", __FUNCTION__, @@ -396,7 +521,12 @@ ObpIncrementHandleCount(IN PVOID Object, OpenReason, ObjectHeader->HandleCount, ObjectHeader->PointerCount); - return STATUS_SUCCESS; + return Status; + +Quickie: + /* Release lock and return */ + ObpLeaveObjectTypeMutex(ObjectType); + return Status; } /*++ @@ -439,6 +569,10 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object, POBJECT_TYPE ObjectType; ULONG ProcessHandleCount; NTSTATUS Status; + PEPROCESS ExclusiveProcess; + BOOLEAN Exclusive = FALSE, NewObject; + POBJECT_HEADER_CREATOR_INFO CreatorInfo; + KIRQL CalloutIrql; /* Get the object header and type */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); @@ -454,9 +588,60 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object, ObpEnterObjectTypeMutex(ObjectType); /* Charge quota and remove the creator info flag */ - Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType); + Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType, &NewObject); if (!NT_SUCCESS(Status)) return Status; + /* Check if the open is exclusive */ + if (HandleAttributes & OBJ_EXCLUSIVE) + { + /* Check if the object allows this, or if the inherit flag was given */ + if ((HandleAttributes & OBJ_INHERIT) || + !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)) + { + /* Incorrect attempt */ + DPRINT1("failing here\n"); + Status = STATUS_INVALID_PARAMETER; + goto Quickie; + } + + /* Check if we have access to it */ + ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader); + if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) || + ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess()))) + { + /* This isn't the right process */ + Status = STATUS_ACCESS_DENIED; + goto Quickie; + } + + /* Now you got exclusive access */ + Exclusive = TRUE; + } + else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) && + (OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader))) + { + /* Caller didn't want exclusive access, but the object is exclusive */ + Status = STATUS_ACCESS_DENIED; + goto Quickie; + } + + /* + * Check if this is an object that went from 0 handles back to existence, + * but doesn't have an open procedure, only a close procedure. This means + * that it will never realize that the object is back alive, so we must + * fail the request. + */ + if (!(ObjectHeader->HandleCount) && + !(NewObject) && + (ObjectType->TypeInfo.MaintainHandleCount) && + !(ObjectType->TypeInfo.OpenProcedure) && + (ObjectType->TypeInfo.CloseProcedure)) + { + /* Fail */ + Status = STATUS_UNSUCCESSFUL; + goto Quickie; + } + /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */ if (*DesiredAccess & MAXIMUM_ALLOWED) { @@ -473,35 +658,85 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object, &ObjectType->TypeInfo.GenericMapping); } + /* Check if this is an exclusive handle */ + if (Exclusive) + { + /* Save the owner process */ + OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process; + } + /* Increase the handle count */ InterlockedIncrement(&ObjectHeader->HandleCount); - - /* Release the object type */ - ObpLeaveObjectTypeMutex(ObjectType); - - /* FIXME: Use the Handle Database */ ProcessHandleCount = 0; + /* Check if we have a handle database */ + if (ObjectType->TypeInfo.MaintainHandleCount) + { + /* FIXME: TODO */ + DPRINT("Handle DB not yet supported\n"); + } + + /* Release the lock */ + ObpLeaveObjectTypeMutex(ObjectType); + /* Check if we have an open procedure */ + Status = STATUS_SUCCESS; if (ObjectType->TypeInfo.OpenProcedure) { /* Call it */ - ObjectType->TypeInfo.OpenProcedure(ObCreateHandle, - Process, - Object, - *DesiredAccess, - ProcessHandleCount); + ObpCalloutStart(&CalloutIrql); + Status = ObjectType->TypeInfo.OpenProcedure(ObCreateHandle, + Process, + Object, + *DesiredAccess, + ProcessHandleCount); + ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object); + + /* Check if the open procedure failed */ + if (!NT_SUCCESS(Status)) + { + /* FIXME: This should never happen for now */ + DPRINT1("Unhandled case\n"); + KEBUGCHECK(0); + return Status; + } + } + + /* Check if we have creator info */ + CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader); + if (CreatorInfo) + { + /* We do, acquire the lock */ + ObpEnterObjectTypeMutex(ObjectType); + + /* Insert us on the list */ + InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList); + + /* Release the lock */ + ObpLeaveObjectTypeMutex(ObjectType); } /* Increase total number of handles */ InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles); + if (ObjectType->TotalNumberOfHandles > ObjectType->HighWaterNumberOfHandles) + { + /* Fixup count */ + ObjectType->HighWaterNumberOfHandles = ObjectType->TotalNumberOfHandles; + } + + /* Trace call and return */ OBTRACE(OB_HANDLE_DEBUG, "%s - Incremented count for: %p. UNNAMED HC LC %lx %lx\n", __FUNCTION__, Object, ObjectHeader->HandleCount, ObjectHeader->PointerCount); - return STATUS_SUCCESS; + return Status; + +Quickie: + /* Release lock and return */ + ObpLeaveObjectTypeMutex(ObjectType); + return Status; } /*++ @@ -709,12 +944,7 @@ ObpCreateUnnamedHandle(IN PVOID Object, * * @return . * -* @remarks Gloomy says OpenReason is "enables Security" if == 1. -* since this function *has* to call ObpIncrementHandleCount, -* which needs to somehow know the OpenReason, and since -* ObOpenHandle == 1, I'm guessing this is actually the -* OpenReason. Also makes sense since this function is shared -* by Duplication, Creation and Opening.. +* @remarks Cleans up the Lookup Context on success. * *--*/ NTSTATUS @@ -725,6 +955,7 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason, IN PACCESS_STATE AccessState, IN ULONG AdditionalReferences, IN ULONG HandleAttributes, + IN POBP_LOOKUP_CONTEXT Context, IN KPROCESSOR_MODE AccessMode, OUT PVOID *ReturnedObject, OUT PHANDLE ReturnedHandle) @@ -1485,14 +1716,11 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, { PVOID Object = NULL; UNICODE_STRING ObjectName; - OBJECT_CREATE_INFORMATION ObjectCreateInfo; NTSTATUS Status; - OBP_LOOKUP_CONTEXT Context; POBJECT_HEADER ObjectHeader; - AUX_DATA AuxData; PGENERIC_MAPPING GenericMapping = NULL; - ACCESS_STATE AccessState; OB_OPEN_REASON OpenReason; + POB_TEMP_BUFFER TempBuffer; PAGED_CODE(); /* Check if we didn't get any Object Attributes */ @@ -1503,11 +1731,17 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, return STATUS_INVALID_PARAMETER; } + /* Allocate the temporary buffer */ + TempBuffer = ExAllocatePoolWithTag(NonPagedPool, + sizeof(OB_TEMP_BUFFER), + TAG_OB_TEMP_STORAGE); + if (!TempBuffer) return STATUS_INSUFFICIENT_RESOURCES; + /* Capture all the info */ Status = ObpCaptureObjectAttributes(ObjectAttributes, AccessMode, TRUE, - &ObjectCreateInfo, + &TempBuffer->ObjectCreateInfo, &ObjectName); if (!NT_SUCCESS(Status)) return Status; @@ -1518,35 +1752,40 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, if (ObjectType) GenericMapping = &ObjectType->TypeInfo.GenericMapping; /* Use our built-in access state */ - PassedAccessState = &AccessState; - Status = SeCreateAccessState(&AccessState, - &AuxData, + PassedAccessState = &TempBuffer->LocalAccessState; + Status = SeCreateAccessState(&TempBuffer->LocalAccessState, + &TempBuffer->AuxData, DesiredAccess, GenericMapping); if (!NT_SUCCESS(Status)) goto Quickie; } /* Get the security descriptor */ - if (ObjectCreateInfo.SecurityDescriptor) + if (TempBuffer->ObjectCreateInfo.SecurityDescriptor) { /* Save it in the access state */ PassedAccessState->SecurityDescriptor = - ObjectCreateInfo.SecurityDescriptor; + TempBuffer->ObjectCreateInfo.SecurityDescriptor; } /* Now do the lookup */ - Status = ObFindObject(ObjectCreateInfo.RootDirectory, - &ObjectName, - ObjectCreateInfo.Attributes, - AccessMode, - &Object, - ObjectType, - &Context, - PassedAccessState, - ObjectCreateInfo.SecurityQos, - ParseContext, - NULL); - if (!NT_SUCCESS(Status)) goto Cleanup; + Status = ObpLookupObjectName(TempBuffer->ObjectCreateInfo.RootDirectory, + &ObjectName, + TempBuffer->ObjectCreateInfo.Attributes, + ObjectType, + AccessMode, + ParseContext, + TempBuffer->ObjectCreateInfo.SecurityQos, + NULL, + PassedAccessState, + &TempBuffer->LookupContext, + &Object); + if (!NT_SUCCESS(Status)) + { + /* Cleanup after lookup */ + TempBuffer->LookupContext.Object = NULL; + goto Cleanup; + } /* Check if this object has create information */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); @@ -1570,29 +1809,44 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, OpenReason = ObOpenHandle; } - /* Create the actual handle now */ - Status = ObpCreateHandle(OpenReason, - Object, - ObjectType, - PassedAccessState, - 0, - ObjectCreateInfo.Attributes, - AccessMode, - NULL, - Handle); - if (!NT_SUCCESS(Status)) ObDereferenceObject(Object); + /* Check if we have invalid object attributes */ + if (ObjectHeader->Type->TypeInfo.InvalidAttributes & + TempBuffer->ObjectCreateInfo.Attributes) + { + /* Set failure code */ + Status = STATUS_INVALID_PARAMETER; + TempBuffer->LookupContext.Object = NULL; + } + else + { + /* Create the actual handle now */ + Status = ObpCreateHandle(OpenReason, + Object, + ObjectType, + PassedAccessState, + 0, + TempBuffer->ObjectCreateInfo.Attributes, + &TempBuffer->LookupContext, + AccessMode, + NULL, + Handle); + if (!NT_SUCCESS(Status)) ObDereferenceObject(Object); + } Cleanup: /* Delete the access state */ - if (PassedAccessState == &AccessState) + if (PassedAccessState == &TempBuffer->LocalAccessState) { SeDeleteAccessState(PassedAccessState); } - /* Release the object attributes and return status */ Quickie: - ObpReleaseCapturedAttributes(&ObjectCreateInfo); + /* Release the object attributes and temporary buffer */ + ObpReleaseCapturedAttributes(&TempBuffer->ObjectCreateInfo); if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName); + ExFreePool(TempBuffer); + + /* Return status */ OBTRACE(OB_HANDLE_DEBUG, "%s - returning Object %p with PC S: %lx %lx\n", __FUNCTION__, @@ -1684,6 +1938,7 @@ ObOpenObjectByPointer(IN PVOID Object, PassedAccessState, 0, HandleAttributes, + NULL, AccessMode, NULL, Handle); @@ -1747,39 +2002,70 @@ ObFindHandleForObject(IN PEPROCESS Process, NTSTATUS NTAPI ObInsertObject(IN PVOID Object, - IN PACCESS_STATE PassedAccessState OPTIONAL, + IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, - IN ULONG AdditionalReferences, - OUT PVOID *ReferencedObject OPTIONAL, + IN ULONG ObjectPointerBias, + OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle) { POBJECT_CREATE_INFORMATION ObjectCreateInfo; - POBJECT_HEADER Header; + POBJECT_HEADER ObjectHeader; POBJECT_TYPE ObjectType; - PVOID FoundObject = Object; - POBJECT_HEADER FoundHeader = NULL; - NTSTATUS Status = STATUS_SUCCESS, RealStatus; - PSECURITY_DESCRIPTOR DirectorySd = NULL; - BOOLEAN SdAllocated; - OBP_LOOKUP_CONTEXT Context; + PUNICODE_STRING ObjectName; + PVOID InsertObject; + PSECURITY_DESCRIPTOR ParentDescriptor = NULL; + BOOLEAN SdAllocated = FALSE; POBJECT_HEADER_NAME_INFO ObjectNameInfo; - ACCESS_STATE AccessState; + OBP_LOOKUP_CONTEXT Context; + ACCESS_STATE LocalAccessState; AUX_DATA AuxData; - BOOLEAN IsNamed = FALSE; - OB_OPEN_REASON OpenReason = ObCreateHandle; + OB_OPEN_REASON OpenReason; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS, RealStatus; PAGED_CODE(); - /* Get the Header and Create Info */ - Header = OBJECT_TO_OBJECT_HEADER(Object); - ObjectCreateInfo = Header->ObjectCreateInfo; - ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(Header); - ObjectType = Header->Type; + /* Get the Header */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); + + /* Detect invalid insert */ + if (!(ObjectHeader->Flags & OB_FLAG_CREATE_INFO)) + { + /* Display warning and break into debugger */ + DPRINT1("OB: Attempting to insert existing object %08x\n", Object); + KEBUGCHECK(0); + DbgBreakPoint(); + + /* Allow debugger to continue */ + ObDereferenceObject(Object); + return STATUS_INVALID_PARAMETER; + } + + /* Get the create and name info, as well as the object type */ + ObjectCreateInfo = ObjectHeader->ObjectCreateInfo; + ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); + ObjectType = ObjectHeader->Type; + /* Check if this is an named object */ - if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer)) IsNamed = TRUE; + ObjectName = NULL; + if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer)) + { + /* Get the object name */ + ObjectName = &ObjectNameInfo->Name; + } + + /* Sanity check, but broken on ROS due to Cm */ +#if 0 + ASSERT((Handle) || + ((ObjectPointerBias == 0) && + (ObjectName == NULL) && + (ObjectType->TypeInfo.SecurityRequired) && + (NewObject == NULL))); +#endif /* Check if the object is unnamed and also doesn't have security */ - if ((!ObjectType->TypeInfo.SecurityRequired) && !(IsNamed)) + PreviousMode = KeGetPreviousMode(); + if (!(ObjectType->TypeInfo.SecurityRequired) && !(ObjectName)) { /* ReactOS HACK */ if (Handle) @@ -1790,16 +2076,17 @@ ObInsertObject(IN PVOID Object, /* Create the handle */ Status = ObpCreateUnnamedHandle(Object, DesiredAccess, - AdditionalReferences + 1, + ObjectPointerBias + 1, ObjectCreateInfo->Attributes, - ExGetPreviousMode(), - ReferencedObject, + PreviousMode, + NewObject, Handle); } /* Free the create information */ ObpFreeAndReleaseCapturedAttributes(ObjectCreateInfo); - Header->ObjectCreateInfo = NULL; + ObjectHeader->ObjectCreateInfo = NULL; + /* Remove the extra keep-alive reference */ if (Handle) ObDereferenceObject(Object); @@ -1808,17 +2095,17 @@ ObInsertObject(IN PVOID Object, OBTRACE(OB_HANDLE_DEBUG, "%s - returning Object with PC S: %lx %lx\n", __FUNCTION__, - OBJECT_TO_OBJECT_HEADER(Object)->PointerCount, + ObjectHeader->PointerCount, Status); return Status; } /* Check if we didn't get an access state */ - if (!PassedAccessState) + if (!AccessState) { /* Use our built-in access state */ - PassedAccessState = &AccessState; - Status = SeCreateAccessState(&AccessState, + AccessState = &LocalAccessState; + Status = SeCreateAccessState(&LocalAccessState, &AuxData, DesiredAccess, &ObjectType->TypeInfo.GenericMapping); @@ -1831,37 +2118,50 @@ ObInsertObject(IN PVOID Object, } /* Save the security descriptor */ - PassedAccessState->SecurityDescriptor = - ObjectCreateInfo->SecurityDescriptor; + AccessState->SecurityDescriptor = ObjectCreateInfo->SecurityDescriptor; + + /* Validate the access mask */ + Status = STATUS_SUCCESS;//ObpValidateAccessMask(AccessState); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + ObDereferenceObject(Object); + return Status; + } + + /* Setup a lookup context */ + Context.Object = NULL; + InsertObject = Object; + OpenReason = ObCreateHandle; /* Check if the object is named */ - if (IsNamed) + if (ObjectName) { /* Look it up */ - Status = ObFindObject(ObjectCreateInfo->RootDirectory, - &ObjectNameInfo->Name, - ObjectCreateInfo->Attributes, - (Header->Flags & OB_FLAG_KERNEL_MODE) ? - KernelMode : UserMode, - &FoundObject, - ObjectType, - &Context, - PassedAccessState, - ObjectCreateInfo->SecurityQos, - ObjectCreateInfo->ParseContext, - Object); + Status = ObpLookupObjectName(ObjectCreateInfo->RootDirectory, + ObjectName, + ObjectCreateInfo->Attributes, + ObjectType, + (ObjectHeader->Flags & OB_FLAG_KERNEL_MODE) ? + KernelMode : UserMode, + ObjectCreateInfo->ParseContext, + ObjectCreateInfo->SecurityQos, + Object, + AccessState, + &Context, + &InsertObject); + /* Check if we found an object that doesn't match the one requested */ - if ((NT_SUCCESS(Status)) && (FoundObject) && (Object != FoundObject)) + if ((NT_SUCCESS(Status)) && (InsertObject) && (Object != InsertObject)) { /* This means we're opening an object, not creating a new one */ - FoundHeader = OBJECT_TO_OBJECT_HEADER(FoundObject); OpenReason = ObOpenHandle; /* Make sure the caller said it's OK to do this */ if (ObjectCreateInfo->Attributes & OBJ_OPENIF) { /* He did, but did he want this type? */ - if (ObjectType != FoundHeader->Type) + if (ObjectType != OBJECT_TO_OBJECT_HEADER(InsertObject)->Type) { /* Wrong type, so fail */ Status = STATUS_OBJECT_TYPE_MISMATCH; @@ -1884,43 +2184,53 @@ ObInsertObject(IN PVOID Object, { /* We failed, dereference the object and delete the access state */ ObDereferenceObject(Object); - if (PassedAccessState == &AccessState) + if (AccessState == &LocalAccessState) { /* We used a local one; delete it */ - SeDeleteAccessState(PassedAccessState); + SeDeleteAccessState(AccessState); } /* Return failure code */ return Status; } + else + { + /* Check if this is a symbolic link */ + if (ObjectType == ObSymbolicLinkType) + { + /* Create the internal name */ + DPRINT("FIXME: Created link!\n"); + //ObpCreateSymbolicLinkName(FoundObject); + } + } } /* Now check if this object is being created */ - if (FoundObject == Object) + if (InsertObject == Object) { /* Check if it's named or forces security */ - if ((IsNamed) || (ObjectType->TypeInfo.SecurityRequired)) + if ((ObjectName) || (ObjectType->TypeInfo.SecurityRequired)) { /* Make sure it's inserted into an object directory */ if ((ObjectNameInfo) && (ObjectNameInfo->Directory)) { /* Get the current descriptor */ ObGetObjectSecurity(ObjectNameInfo->Directory, - &DirectorySd, + &ParentDescriptor, &SdAllocated); } /* Now assign it */ - Status = ObAssignSecurity(PassedAccessState, - DirectorySd, + Status = ObAssignSecurity(AccessState, + ParentDescriptor, Object, ObjectType); /* Check if we captured one */ - if (DirectorySd) + if (ParentDescriptor) { /* We did, release it */ - ObReleaseObjectSecurity(DirectorySd, SdAllocated); + ObReleaseObjectSecurity(ParentDescriptor, SdAllocated); } else if (NT_SUCCESS(Status)) { @@ -1930,8 +2240,8 @@ ObInsertObject(IN PVOID Object, TRUE); /* Clear the current one */ - PassedAccessState->SecurityDescriptor = - ObjectCreateInfo->SecurityDescriptor = NULL; + AccessState->SecurityDescriptor = + ObjectCreateInfo->SecurityDescriptor = NULL; } } @@ -1941,10 +2251,10 @@ ObInsertObject(IN PVOID Object, /* We failed, dereference the object and delete the access state */ KEBUGCHECK(0); ObDereferenceObject(Object); - if (PassedAccessState == &AccessState) + if (AccessState == &LocalAccessState) { /* We used a local one; delete it */ - SeDeleteAccessState(PassedAccessState); + SeDeleteAccessState(AccessState); } /* Return failure code */ @@ -1961,34 +2271,29 @@ ObInsertObject(IN PVOID Object, * a handle if Handle is NULL when the Registry Code calls it, because * the registry code totally bastardizes the Ob and needs to be fixed */ + ObjectHeader->ObjectCreateInfo = NULL; if (Handle) { /* Create the handle */ Status = ObpCreateHandle(OpenReason, - FoundObject, + InsertObject, NULL, - PassedAccessState, - AdditionalReferences + 1, + AccessState, + ObjectPointerBias + 1, ObjectCreateInfo->Attributes, - ExGetPreviousMode(), - ReferencedObject, + &Context, + PreviousMode, + NewObject, Handle); } - /* We can delete the Create Info now */ - Header->ObjectCreateInfo = NULL; - ObpFreeAndReleaseCapturedAttributes(ObjectCreateInfo); - /* Check if creating the handle failed */ if (!NT_SUCCESS(Status)) { /* If the object had a name, backout everything */ - if (IsNamed) ObpDeleteNameCheck(Object); + if (ObjectName) ObpDeleteNameCheck(Object); } - /* Remove the extra keep-alive reference */ - if (Handle) ObDereferenceObject(Object); - /* Check our final status */ if (!NT_SUCCESS(Status)) { @@ -1997,12 +2302,17 @@ ObInsertObject(IN PVOID Object, RealStatus = Status; } - /* Check if we created our own access state */ - if (PassedAccessState == &AccessState) - { - /* We used a local one; delete it */ - SeDeleteAccessState(PassedAccessState); - } + + + + /* Remove the extra keep-alive reference */ + if (Handle) ObDereferenceObject(Object); + + /* We can delete the Create Info now */ + ObpFreeAndReleaseCapturedAttributes(ObjectCreateInfo); + + /* Check if we created our own access state and delete it if so */ + if (AccessState == &LocalAccessState) SeDeleteAccessState(AccessState); /* Return status code */ OBTRACE(OB_HANDLE_DEBUG, diff --git a/reactos/ntoskrnl/ob/obname.c b/reactos/ntoskrnl/ob/obname.c index aa3d9a8c754..ecbbbe72c21 100644 --- a/reactos/ntoskrnl/ob/obname.c +++ b/reactos/ntoskrnl/ob/obname.c @@ -14,8 +14,9 @@ #define NTDDI_VERSION NTDDI_WINXP #include #define NDEBUG -#include +#include +BOOLEAN ObpCaseInsensitive = TRUE; POBJECT_DIRECTORY NameSpaceRoot = NULL; POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL; @@ -181,6 +182,8 @@ ObpDeleteNameCheck(IN PVOID Object) (ObjectNameInfo->Name.Length) && !(ObjectHeader->Flags & OB_FLAG_PERMANENT)) { + Context.Object = NULL; + /* Make sure it's still inserted */ Context.Directory = ObjectNameInfo->Directory; Context.DirectoryLocked = TRUE; @@ -220,6 +223,8 @@ ObpDeleteNameCheck(IN PVOID Object) ExFreePool(ObjectNameInfo->Name.Buffer); RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0); + Context.Object = NULL; + /* Clear the current directory and de-reference it */ Directory = ObjectNameInfo->Directory; ObjectNameInfo->Directory = NULL; @@ -237,17 +242,17 @@ ObpDeleteNameCheck(IN PVOID Object) NTSTATUS NTAPI -ObFindObject(IN HANDLE RootHandle, - IN PUNICODE_STRING ObjectName, - IN ULONG Attributes, - IN KPROCESSOR_MODE AccessMode, - IN PVOID *ReturnedObject, - IN POBJECT_TYPE ObjectType, - IN POBP_LOOKUP_CONTEXT Context, - IN PACCESS_STATE AccessState, - IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, - IN OUT PVOID ParseContext, - OUT PVOID ExpectedObject) +ObpLookupObjectName(IN HANDLE RootHandle, + IN PUNICODE_STRING ObjectName, + IN ULONG Attributes, + IN POBJECT_TYPE ObjectType, + IN KPROCESSOR_MODE AccessMode, + IN OUT PVOID ParseContext, + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN PVOID ExpectedObject, + IN PACCESS_STATE AccessState, + IN POBP_LOOKUP_CONTEXT Context, + OUT PVOID *ReturnedObject) { PVOID RootDirectory; PVOID CurrentDirectory = NULL; @@ -500,7 +505,7 @@ ReparseNewDir: ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(CurrentHeader); /* Copy the Name */ - RtlCopyMemory(NewName, PartName.Buffer, PartName.MaximumLength); + RtlMoveMemory(NewName, PartName.Buffer, PartName.MaximumLength); /* Free old name */ if (ObjectNameInfo->Name.Buffer) ExFreePool(ObjectNameInfo->Name.Buffer); @@ -526,7 +531,7 @@ Reparse: /* We found it, so now get its header */ CurrentHeader = OBJECT_TO_OBJECT_HEADER(CurrentObject); - /* + /* * Check for a parse Procedure, but don't bother to parse for an insert * unless it's a Symbolic Link, in which case we MUST parse */ @@ -674,9 +679,9 @@ Reparse: NTSTATUS NTAPI -ObQueryNameString(IN PVOID Object, +ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, - IN ULONG Length, + IN ULONG Length, OUT PULONG ReturnLength) { POBJECT_HEADER_NAME_INFO LocalInfo; diff --git a/reactos/ntoskrnl/ob/obref.c b/reactos/ntoskrnl/ob/obref.c index 0432345edce..eeabc23e942 100644 --- a/reactos/ntoskrnl/ob/obref.c +++ b/reactos/ntoskrnl/ob/obref.c @@ -369,21 +369,21 @@ ObReferenceObjectByPointer(IN PVOID Object, return STATUS_OBJECT_TYPE_MISMATCH; } - /* Oncrement the reference count and return success */ + /* Increment the reference count and return success */ InterlockedIncrement(&Header->PointerCount); return STATUS_SUCCESS; } NTSTATUS NTAPI -ObReferenceObjectByName(PUNICODE_STRING ObjectPath, - ULONG Attributes, - PACCESS_STATE PassedAccessState, - ACCESS_MASK DesiredAccess, - POBJECT_TYPE ObjectType, - KPROCESSOR_MODE AccessMode, - PVOID ParseContext, - PVOID* ObjectPtr) +ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath, + IN ULONG Attributes, + IN PACCESS_STATE PassedAccessState, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_TYPE ObjectType, + IN KPROCESSOR_MODE AccessMode, + IN OUT PVOID ParseContext, + OUT PVOID* ObjectPtr) { PVOID Object = NULL; UNICODE_STRING ObjectName; @@ -391,11 +391,18 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath, OBP_LOOKUP_CONTEXT Context; AUX_DATA AuxData; ACCESS_STATE AccessState; + PAGED_CODE(); + + /* Fail quickly */ + if (!ObjectPath) return STATUS_OBJECT_NAME_INVALID; /* Capture the name */ Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode, TRUE); if (!NT_SUCCESS(Status)) return Status; + /* We also need a valid name after capture */ + if (!ObjectName.Length) return STATUS_OBJECT_NAME_INVALID; + /* Check if we didn't get an access state */ if (!PassedAccessState) { @@ -410,21 +417,33 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath, /* Find the object */ *ObjectPtr = NULL; - Status = ObFindObject(NULL, - &ObjectName, - Attributes, - AccessMode, - &Object, - ObjectType, - &Context, - PassedAccessState, - NULL, - ParseContext, - NULL); + Status = ObpLookupObjectName(NULL, + &ObjectName, + Attributes, + ObjectType, + AccessMode, + ParseContext, + NULL, + NULL, + PassedAccessState, + &Context, + &Object); + Context.Object = NULL; + + /* Check if the lookup succeeded */ if (NT_SUCCESS(Status)) { - /* Return the object */ - *ObjectPtr = Object; + /* Check if access is allowed */ + if (ObpCheckObjectReference(Object, + PassedAccessState, + FALSE, + AccessMode, + &Status)) + { + /* Return the object */ + Status = STATUS_SUCCESS; + *ObjectPtr = Object; + } } /* Free the access state */ From 7ce1744f9a9029aa0fe9bcd4035882f12e47b8fa Mon Sep 17 00:00:00 2001 From: Peter Ward Date: Mon, 8 Jan 2007 08:48:28 +0000 Subject: [PATCH 06/30] - Fix some annoying warnings in wrc. - Fixed a warning in winebuild. svn path=/trunk/; revision=25373 --- reactos/tools/winebuild/build.h | 2 ++ reactos/tools/wrc/dumpres.c | 30 +++++++++++++++--------------- reactos/tools/wrc/newstruc.c | 10 +++++----- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/reactos/tools/winebuild/build.h b/reactos/tools/winebuild/build.h index 7f66b5b8b42..c5c646bf2a0 100644 --- a/reactos/tools/winebuild/build.h +++ b/reactos/tools/winebuild/build.h @@ -220,6 +220,8 @@ extern void BuildPedllFile( FILE *outfile, DLLSPEC *spec ); extern int parse_spec_file( FILE *file, DLLSPEC *spec ); extern int parse_def_file( FILE *file, DLLSPEC *spec ); +extern int mkstemps(char *template, int suffix_len); + /* global variables */ extern int current_line; diff --git a/reactos/tools/wrc/dumpres.c b/reactos/tools/wrc/dumpres.c index 7af89e4d93b..a121189a8e3 100644 --- a/reactos/tools/wrc/dumpres.c +++ b/reactos/tools/wrc/dumpres.c @@ -203,12 +203,12 @@ static void dump_lvc(const lvc_t *l) printf("LANGUAGE \n"); if(l->version) - printf("VERSION %08lx\n", *(l->version)); + printf("VERSION %08x\n", *(l->version)); else printf("VERSION \n"); if(l->characts) - printf("CHARACTERISTICS %08lx\n", *(l->characts)); + printf("CHARACTERISTICS %08x\n", *(l->characts)); else printf("CHARACTERISTICS \n"); } @@ -537,16 +537,16 @@ static void dump_control(const control_t *ctrl) { assert(ctrl->style != NULL); assert(ctrl->style->and_mask == 0); - printf("\tStyle: %08lx\n", ctrl->style->or_mask); + printf("\tStyle: %08x\n", ctrl->style->or_mask); } if(ctrl->gotexstyle) { assert(ctrl->exstyle != NULL); assert(ctrl->exstyle->and_mask == 0); - printf("\tExStyle: %08lx\n", ctrl->exstyle->or_mask); + printf("\tExStyle: %08x\n", ctrl->exstyle->or_mask); } if(ctrl->gothelpid) - printf("\tHelpid: %ld\n", ctrl->helpid); + printf("\tHelpid: %u\n", ctrl->helpid); if(ctrl->extra) { printf("\t"); @@ -577,14 +577,14 @@ static void dump_dialog(const dialog_t *dlg) { assert(dlg->style != NULL); assert(dlg->style->and_mask == 0); - printf("Style: %08lx\n", dlg->style->or_mask); + printf("Style: %08x\n", dlg->style->or_mask); } if(dlg->gotexstyle) { assert(dlg->exstyle != NULL); assert(dlg->exstyle->and_mask == 0); - printf("ExStyle: %08lx\n", dlg->exstyle->or_mask); + printf("ExStyle: %08x\n", dlg->exstyle->or_mask); } printf("Menu: %s\n", get_nameid_str(dlg->menu)); printf("Class: %s\n", get_nameid_str(dlg->dlgclass)); @@ -627,16 +627,16 @@ static void dump_dialogex(const dialogex_t *dlgex) { assert(dlgex->style != NULL); assert(dlgex->style->and_mask == 0); - printf("Style: %08lx\n", dlgex->style->or_mask); + printf("Style: %08x\n", dlgex->style->or_mask); } if(dlgex->gotexstyle) { assert(dlgex->exstyle != NULL); assert(dlgex->exstyle->and_mask == 0); - printf("ExStyle: %08lx\n", dlgex->exstyle->or_mask); + printf("ExStyle: %08x\n", dlgex->exstyle->or_mask); } if(dlgex->gothelpid) - printf("Helpid: %ld\n", dlgex->helpid); + printf("Helpid: %u\n", dlgex->helpid); printf("Menu: %s\n", get_nameid_str(dlgex->menu)); printf("Class: %s\n", get_nameid_str(dlgex->dlgclass)); printf("Title: "); print_string(dlgex->title); printf("\n"); @@ -683,7 +683,7 @@ static void dump_menu_item(const menu_item_t *item) if(item->name) { print_string(item->name); - printf(", %d, %08lx", item->id, item->state); + printf(", %d, %08x", item->id, item->state); } else printf("SEPARATOR"); @@ -732,9 +732,9 @@ static void dump_menuex_item(const menuex_item_t *item) if(item->gotid) printf(", Id=%d", item->id); if(item->gottype) - printf(", Type=%ld", item->type); + printf(", Type=%u", item->type); if(item->gotstate) - printf(", State=%08lx", item->state); + printf(", State=%08x", item->state); if(item->gothelpid) printf(", HelpId=%d", item->helpid); printf("\n"); @@ -749,9 +749,9 @@ static void dump_menuex_item(const menuex_item_t *item) if(item->gotid) printf(", Id=%d", item->id); if(item->gottype) - printf(", Type=%ld", item->type); + printf(", Type=%u", item->type); if(item->gotstate) - printf(", State=%08lx", item->state); + printf(", State=%08x", item->state); if(item->gothelpid) printf(", HelpId=%d", item->helpid); } diff --git a/reactos/tools/wrc/newstruc.c b/reactos/tools/wrc/newstruc.c index 5d3ce95cb0b..8589b3c008c 100644 --- a/reactos/tools/wrc/newstruc.c +++ b/reactos/tools/wrc/newstruc.c @@ -328,7 +328,7 @@ static int convert_bitmap(char *data, int size) else { fprintf(stderr, "bisizel %d bosizel %d b4sizel %d\n", bisizel, bosizel, b4sizel); - yyerror("Invalid bitmap format, bih->biSize = %ld", bih->biSize); + yyerror("Invalid bitmap format, bih->biSize = %u", bih->biSize); } switch(type) @@ -1045,7 +1045,7 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt) for(id = mbp[i].idlo; id <= mbp[i].idhi; id++) { if(MSGTAB_BAD_PTR(mep, rd->data, rd->size, mep->length)) - yyerror("Messagetable's data for block %d, ID 0x%08lx is outside of defined data", (int)i, id); + yyerror("Messagetable's data for block %d, ID 0x%08x is outside of defined data", (int)i, id); if(mep->flags == 1) /* Docu says 'flags == 0x0001' for unicode */ { WORD *wp = (WORD *)&mep[1]; @@ -1053,7 +1053,7 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt) int n; if(mep->length & 1) - yyerror("Message 0x%08lx is unicode (block %d), but has odd length (%d)", id, (int)i, mep->length); + yyerror("Message 0x%08x is unicode (block %d), but has odd length (%d)", id, (int)i, mep->length); for(n = 0; n < l; n++) wp[n] = BYTESWAP_WORD(wp[n]); @@ -1098,7 +1098,7 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt) mep->flags = BYTESWAP_WORD(mep->flags); if(MSGTAB_BAD_PTR(mep, rd->data, rd->size, mep->length)) - yyerror("Messagetable's data for block %d, ID 0x%08lx is outside of defined data", (int)i, id); + yyerror("Messagetable's data for block %d, ID 0x%08x is outside of defined data", (int)i, id); if(mep->flags == 1) /* Docu says 'flags == 0x0001' for unicode */ { WORD *wp = (WORD *)&mep[1]; @@ -1106,7 +1106,7 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt) int n; if(mep->length & 1) - yyerror("Message 0x%08lx is unicode (block %d), but has odd length (%d)", id, (int)i, mep->length); + yyerror("Message 0x%08x is unicode (block %d), but has odd length (%d)", id, (int)i, mep->length); for(n = 0; n < l; n++) wp[n] = BYTESWAP_WORD(wp[n]); From cbd8c787307da6e9f6be9414f4f7f9f8267064bd Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 16:51:06 +0000 Subject: [PATCH 07/30] =?UTF-8?q?-=20Delete=20/fs=20directory.=20-=20Add?= =?UTF-8?q?=20/fsrtl=20directory=20with=20new=20file=20structure=20and=20r?= =?UTF-8?q?emove=20all=20the=20code=20except=20for=20some=20smaller=20"kno?= =?UTF-8?q?wn-working"=20functions.=20-=20Reason=20for=20this=20is=20that?= =?UTF-8?q?=20FsRtl=20now=20has=20a=20new=20owner=20(Dominique=20Cot=C3=A9?= =?UTF-8?q?)=20and=20he=20will=20be=20implementing=20and=20testing=20prope?= =?UTF-8?q?r=20versions=20of=20the=20routines.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=25379 --- reactos/include/ndk/cctypes.h | 2 + reactos/ntoskrnl/fs/context.c | 83 -- reactos/ntoskrnl/fs/fastio.c | 578 -------- reactos/ntoskrnl/fs/filelock.c | 1127 --------------- reactos/ntoskrnl/fs/name.c | 655 --------- reactos/ntoskrnl/fs/notify.c | 1214 ----------------- reactos/ntoskrnl/fs/pool.c | 173 --- reactos/ntoskrnl/fs/util.c | 305 ----- reactos/ntoskrnl/fsrtl/dbcsname.c | 182 +++ reactos/ntoskrnl/fsrtl/fastio.c | 268 ++++ reactos/ntoskrnl/fsrtl/faulttol.c | 94 ++ reactos/ntoskrnl/fsrtl/filelock.c | 367 +++++ reactos/ntoskrnl/fsrtl/filter.c | 246 ++++ reactos/ntoskrnl/fsrtl/filtrctx.c | 124 ++ reactos/ntoskrnl/fsrtl/fsfilter.c | 75 + reactos/ntoskrnl/fsrtl/fsrtlpc.c | 208 +++ .../ntoskrnl/{fs/mcb.c => fsrtl/largemcb.c} | 741 +++++----- reactos/ntoskrnl/fsrtl/name.c | 277 ++++ reactos/ntoskrnl/fsrtl/notify.c | 398 ++++++ reactos/ntoskrnl/{fs => fsrtl}/oplock.c | 351 ++--- reactos/ntoskrnl/fsrtl/pnp.c | 42 + reactos/ntoskrnl/fsrtl/stackovf.c | 69 + reactos/ntoskrnl/{fs => fsrtl}/tunnel.c | 358 ++--- reactos/ntoskrnl/{fs => fsrtl}/unc.c | 139 +- reactos/ntoskrnl/include/internal/fsrtl.h | 149 +- reactos/ntoskrnl/ntoskrnl.def | 204 +-- reactos/ntoskrnl/ntoskrnl.rbuild | 15 +- 27 files changed, 3301 insertions(+), 5143 deletions(-) delete mode 100644 reactos/ntoskrnl/fs/context.c delete mode 100644 reactos/ntoskrnl/fs/fastio.c delete mode 100644 reactos/ntoskrnl/fs/filelock.c delete mode 100644 reactos/ntoskrnl/fs/name.c delete mode 100644 reactos/ntoskrnl/fs/notify.c delete mode 100644 reactos/ntoskrnl/fs/pool.c delete mode 100644 reactos/ntoskrnl/fs/util.c create mode 100644 reactos/ntoskrnl/fsrtl/dbcsname.c create mode 100644 reactos/ntoskrnl/fsrtl/fastio.c create mode 100644 reactos/ntoskrnl/fsrtl/faulttol.c create mode 100644 reactos/ntoskrnl/fsrtl/filelock.c create mode 100644 reactos/ntoskrnl/fsrtl/filter.c create mode 100644 reactos/ntoskrnl/fsrtl/filtrctx.c create mode 100644 reactos/ntoskrnl/fsrtl/fsfilter.c create mode 100644 reactos/ntoskrnl/fsrtl/fsrtlpc.c rename reactos/ntoskrnl/{fs/mcb.c => fsrtl/largemcb.c} (62%) create mode 100644 reactos/ntoskrnl/fsrtl/name.c create mode 100644 reactos/ntoskrnl/fsrtl/notify.c rename reactos/ntoskrnl/{fs => fsrtl}/oplock.c (75%) create mode 100644 reactos/ntoskrnl/fsrtl/pnp.c create mode 100644 reactos/ntoskrnl/fsrtl/stackovf.c rename reactos/ntoskrnl/{fs => fsrtl}/tunnel.c (57%) rename reactos/ntoskrnl/{fs => fsrtl}/unc.c (66%) diff --git a/reactos/include/ndk/cctypes.h b/reactos/include/ndk/cctypes.h index 2e04cdb9d6e..3b45ecca33b 100644 --- a/reactos/include/ndk/cctypes.h +++ b/reactos/include/ndk/cctypes.h @@ -31,6 +31,8 @@ Author: // extern ULONG NTSYSAPI CcFastReadNotPossible; extern ULONG NTSYSAPI CcFastReadWait; +extern ULONG NTSYSAPI CcFastReadResourceMiss; +extern ULONG NTSYSAPI CcFastReadNoWait; #endif #endif // _CCTYPES_H diff --git a/reactos/ntoskrnl/fs/context.c b/reactos/ntoskrnl/fs/context.c deleted file mode 100644 index f1b2ba6e714..00000000000 --- a/reactos/ntoskrnl/fs/context.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/context.c - * PURPOSE: File and Stream Context Functions - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES *****************************************************************/ - -#include - -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -/* PRIVATE FUNCTIONS**********************************************************/ - -/* FUNCTIONS *****************************************************************/ - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -FsRtlInsertPerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER PerStreamContext, - IN PFSRTL_PER_STREAM_CONTEXT Ptr) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @unimplemented - */ -PFSRTL_PER_STREAM_CONTEXT -NTAPI -FsRtlRemovePerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, - IN PVOID OwnerId OPTIONAL, - IN PVOID InstanceId OPTIONAL) -{ - UNIMPLEMENTED; - return NULL; -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -FsRtlInsertPerFileObjectContext(IN PFILE_OBJECT FileObject, - IN PFSRTL_PER_FILEOBJECT_CONTEXT Ptr) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @unimplemented - */ -PFSRTL_PER_FILEOBJECT_CONTEXT -NTAPI -FsRtlRemovePerFileObjectContext(IN PFILE_OBJECT PerFileObjectContext, - IN PVOID OwnerId OPTIONAL, - IN PVOID InstanceId OPTIONAL) -{ - UNIMPLEMENTED; - return NULL; -} - -/* - * @unimplemented - */ -VOID -NTAPI -FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvancedHeader) -{ - UNIMPLEMENTED; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/fs/fastio.c b/reactos/ntoskrnl/fs/fastio.c deleted file mode 100644 index 8943b8d8d6d..00000000000 --- a/reactos/ntoskrnl/fs/fastio.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/fastio.c - * PURPOSE: File System Routines which support Fast I/O or Cc Access. - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) -*/ - -/* INCLUDES ******************************************************************/ - -#include -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -extern ULONG CcFastReadNotPossible; -extern ULONG CcFastReadResourceMiss; -extern ULONG CcFastReadWait; -extern ULONG CcFastReadNoWait; -ULONG CcFastMdlReadNotPossible; - -/* FUNCTIONS *****************************************************************/ - -/* - * @implemented - */ -VOID -NTAPI -FsRtlIncrementCcFastReadResourceMiss(VOID) -{ - CcFastReadResourceMiss++; -} - -/* - * @implemented - */ -VOID -NTAPI -FsRtlIncrementCcFastReadNotPossible(VOID) -{ - CcFastReadNotPossible++; -} - -/* - * @implemented - */ -VOID -NTAPI -FsRtlIncrementCcFastReadWait(VOID) -{ - CcFastReadWait++; -} - -/* - * @implemented - */ -VOID -NTAPI -FsRtlIncrementCcFastReadNoWait(VOID) -{ - CcFastReadNoWait++; -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -FsRtlCopyRead(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - OUT PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -FsRtlCopyWrite(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - OUT PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -FsRtlGetFileSize(IN PFILE_OBJECT FileObject, - IN OUT PLARGE_INTEGER FileSize) -{ - FILE_STANDARD_INFORMATION Info; - NTSTATUS Status; - IO_STATUS_BLOCK IoStatusBlock; - ULONG Length; - PDEVICE_OBJECT DeviceObject; - PFAST_IO_DISPATCH FastDispatch; - - /* Get Device Object and Fast Calls */ - DeviceObject = IoGetRelatedDeviceObject(FileObject); - FastDispatch = DeviceObject->DriverObject->FastIoDispatch; - - /* Check if we support Fast Calls, and check this one */ - if (FastDispatch && FastDispatch->FastIoQueryStandardInfo) - { - /* Fast Path */ - FastDispatch->FastIoQueryStandardInfo(FileObject, - TRUE, - &Info, - &IoStatusBlock, - DeviceObject); - Status = IoStatusBlock.Status; - } - else - { - /* Slow Path */ - Status = IoQueryFileInformation(FileObject, - FileStandardInformation, - sizeof(Info), - &Info, - &Length); - } - - /* Check success */ - if (NT_SUCCESS(Status)) - { - *FileSize = Info.EndOfFile; - } - - /* Return status */ - return Status; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlMdlRead(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - OUT PMDL *MdlChain, - OUT PIO_STATUS_BLOCK IoStatus) -{ - PDEVICE_OBJECT DeviceObject, BaseDeviceObject; - PFAST_IO_DISPATCH FastDispatch; - - /* Get Device Object and Fast Calls */ - DeviceObject = IoGetRelatedDeviceObject(FileObject); - FastDispatch = DeviceObject->DriverObject->FastIoDispatch; - - /* Check if we support Fast Calls, and check this one */ - if (FastDispatch && FastDispatch->MdlRead) - { - /* Use the fast path */ - return FastDispatch->MdlRead(FileObject, - FileOffset, - Length, - LockKey, - MdlChain, - IoStatus, - DeviceObject); - } - - /* Get the Base File System (Volume) and Fast Calls */ - BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject); - FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch; - - /* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->MdlRead && - BaseDeviceObject != DeviceObject) - { - return FALSE; - } - - /* No fast path, use slow path */ - return FsRtlMdlReadDev(FileObject, - FileOffset, - Length, - LockKey, - MdlChain, - IoStatus, - DeviceObject); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject, - IN OUT PMDL MdlChain) -{ - PDEVICE_OBJECT DeviceObject, BaseDeviceObject; - PFAST_IO_DISPATCH FastDispatch; - - /* Get Device Object and Fast Calls */ - DeviceObject = IoGetRelatedDeviceObject(FileObject); - FastDispatch = DeviceObject->DriverObject->FastIoDispatch; - - /* Check if we support Fast Calls, and check this one */ - if (FastDispatch && FastDispatch->MdlReadComplete) - { - /* Use the fast path */ - return FastDispatch->MdlReadComplete(FileObject, - MdlChain, - DeviceObject); - } - - /* Get the Base File System (Volume) and Fast Calls */ - BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject); - FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch; - - /* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->MdlReadComplete && - BaseDeviceObject != DeviceObject) - { - return FALSE; - } - - /* No fast path, use slow path */ - return FsRtlMdlReadCompleteDev(FileObject, MdlChain, DeviceObject); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, - IN PMDL MdlChain, - IN PDEVICE_OBJECT DeviceObject) -{ - /* Call the Cache Manager */ - CcMdlReadCompleteDev(MdlChain, FileObject); - return TRUE; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlMdlReadDev(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - OUT PMDL *MdlChain, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - PFSRTL_COMMON_FCB_HEADER FcbHeader; - BOOLEAN Result = TRUE; - LARGE_INTEGER Offset; - PFAST_IO_DISPATCH FastIoDispatch; - PDEVICE_OBJECT Device; - PAGED_CODE(); - - /* No actual read */ - if (!Length) - { - /* Return success */ - IoStatus->Status = STATUS_SUCCESS; - IoStatus->Information = 0; - return TRUE; - } - - /* Sanity check */ - ASSERT(MAXLONGLONG - FileOffset->QuadPart >= (LONGLONG)Length); - - /* Get the offset and FCB header */ - Offset.QuadPart = FileOffset->QuadPart + Length; - FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; - - /* Enter the FS */ - FsRtlEnterFileSystem(); - CcFastMdlReadWait++; - - /* Lock the FCB */ - ExAcquireResourceShared(FcbHeader->Resource, TRUE); - - /* Check if this is a fast I/O cached file */ - if (!(FileObject->PrivateCacheMap) || - (FcbHeader->IsFastIoPossible == FastIoIsNotPossible)) - { - /* It's not, so fail */ - CcFastMdlReadNotPossible += 1; - Result = FALSE; - goto Cleanup; - } - - /* Check if we need to find out if fast I/O is available */ - if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) - { - /* Sanity check */ - ASSERT(!KeIsExecutingDpc()); - - /* Get the Fast I/O table */ - Device = IoGetRelatedDeviceObject(FileObject); - FastIoDispatch = Device->DriverObject->FastIoDispatch; - - /* Sanity check */ - ASSERT(FastIoDispatch != NULL); - ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); - - /* Ask the driver if we can do it */ - if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, - FileOffset, - Length, - TRUE, - LockKey, - TRUE, - IoStatus, - Device)) - { - /* It's not, fail */ - CcFastMdlReadNotPossible += 1; - Result = FALSE; - goto Cleanup; - } - } - - /* Check if we read too much */ - if (Offset.QuadPart > FcbHeader->FileSize.QuadPart) - { - /* We did, check if the file offset is past the end */ - if (FileOffset->QuadPart >= FcbHeader->FileSize.QuadPart) - { - /* Set end of file */ - IoStatus->Status = STATUS_END_OF_FILE; - IoStatus->Information = 0; - goto Cleanup; - } - - /* Otherwise, just normalize the length */ - Length = (ULONG)(FcbHeader->FileSize.QuadPart - FileOffset->QuadPart); - } - - /* Set this as top-level IRP */ - PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; - - /* Attempt a read */ - CcMdlRead(FileObject, FileOffset, Length, MdlChain, IoStatus); - FileObject->Flags |= FO_FILE_FAST_IO_READ; - - /* Remove the top-level IRP flag */ - PsGetCurrentThread()->TopLevelIrp = 0; - - /* Return to caller */ -Cleanup: - ExReleaseResourceLite(FcbHeader->Resource); - FsRtlExitFileSystem(); - return Result; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlMdlWriteComplete(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PMDL MdlChain) -{ - PDEVICE_OBJECT DeviceObject, BaseDeviceObject; - PFAST_IO_DISPATCH FastDispatch; - - /* Get Device Object and Fast Calls */ - DeviceObject = IoGetRelatedDeviceObject(FileObject); - FastDispatch = DeviceObject->DriverObject->FastIoDispatch; - - /* Check if we support Fast Calls, and check this one */ - if (FastDispatch && FastDispatch->MdlWriteComplete) - { - /* Use the fast path */ - return FastDispatch->MdlWriteComplete(FileObject, - FileOffset, - MdlChain, - DeviceObject); - } - - /* Get the Base File System (Volume) and Fast Calls */ - BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject); - FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch; - - /* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->MdlWriteComplete && - BaseDeviceObject != DeviceObject) - { - return FALSE; - } - - /* No fast path, use slow path */ - return FsRtlMdlWriteCompleteDev(FileObject, - FileOffset, - MdlChain, - DeviceObject); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlMdlWriteCompleteDev(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PMDL MdlChain, - IN PDEVICE_OBJECT DeviceObject) -{ - /* Call the Cache Manager */ - CcMdlWriteCompleteDev(FileOffset, MdlChain, FileObject); - return TRUE; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlPrepareMdlWrite(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - OUT PMDL *MdlChain, - OUT PIO_STATUS_BLOCK IoStatus) -{ - PDEVICE_OBJECT DeviceObject, BaseDeviceObject; - PFAST_IO_DISPATCH FastDispatch; - - /* Get Device Object and Fast Calls */ - DeviceObject = IoGetRelatedDeviceObject(FileObject); - FastDispatch = DeviceObject->DriverObject->FastIoDispatch; - - /* Check if we support Fast Calls, and check this one */ - if (FastDispatch && FastDispatch->PrepareMdlWrite) - { - /* Use the fast path */ - return FastDispatch->PrepareMdlWrite(FileObject, - FileOffset, - Length, - LockKey, - MdlChain, - IoStatus, - DeviceObject); - } - - /* Get the Base File System (Volume) and Fast Calls */ - BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject); - FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch; - - /* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->PrepareMdlWrite && - BaseDeviceObject != DeviceObject) - { - return FALSE; - } - - /* No fast path, use slow path */ - return FsRtlPrepareMdlWriteDev(FileObject, - FileOffset, - Length, - LockKey, - MdlChain, - IoStatus, - DeviceObject); -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG LockKey, - OUT PMDL *MdlChain, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* -* @implemented -*/ -VOID -NTAPI -FsRtlAcquireFileExclusive(IN PFILE_OBJECT FileObject) -{ - PFAST_IO_DISPATCH FastDispatch; - PDEVICE_OBJECT DeviceObject; - PFSRTL_COMMON_FCB_HEADER FcbHeader; - - /* Get the Device Object and fast dispatch */ - DeviceObject = IoGetBaseFileSystemDeviceObject(FileObject); - FastDispatch = DeviceObject->DriverObject->FastIoDispatch; - - /* Check if we have to do a Fast I/O Dispatch */ - if ((FastDispatch) && (FastDispatch->AcquireFileForNtCreateSection)) - { - /* Enter the file system and call it */ - FsRtlEnterFileSystem(); - FastDispatch->AcquireFileForNtCreateSection(FileObject); - return; - } - - /* Get the FCB Header */ - FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; - if (FcbHeader->Resource) - { - /* Use a Resource Acquire */ - FsRtlEnterFileSystem(); - ExAcquireResourceExclusive(FcbHeader->Resource, TRUE); - } - - /* All done, return */ - return; -} - -/* -* @implemented -*/ -VOID -NTAPI -FsRtlReleaseFile(IN PFILE_OBJECT FileObject) -{ - PFAST_IO_DISPATCH FastDispatch; - PDEVICE_OBJECT DeviceObject; - PFSRTL_COMMON_FCB_HEADER FcbHeader; - - /* Get the Device Object */ - DeviceObject = IoGetBaseFileSystemDeviceObject(FileObject); - - FastDispatch = DeviceObject->DriverObject->FastIoDispatch; - - /* Check if we have to do a Fast I/O Dispatch */ - if ((FastDispatch) && (FastDispatch->ReleaseFileForNtCreateSection)) - { - /* Call the release function and exit the file system */ - FastDispatch->ReleaseFileForNtCreateSection(FileObject); - FsRtlExitFileSystem(); - return; - } - - /* Get the FCB Header */ - FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; - if (FcbHeader->Resource) - { - /* Use a Resource release */ - ExReleaseResourceLite(FcbHeader->Resource); - FsRtlExitFileSystem(); - } - - /* All done, return */ - return; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/fs/filelock.c b/reactos/ntoskrnl/fs/filelock.c deleted file mode 100644 index 1bd4fe52e77..00000000000 --- a/reactos/ntoskrnl/fs/filelock.c +++ /dev/null @@ -1,1127 +0,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/fs/filelock.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: No programmer listed. - */ - -#include -#define NDEBUG -#include - -/* -NOTE: -I'm not using resource syncronization here, since FsRtlFastCheckLockForRead/Write -are allowed to be called at DISPATCH_LEVEL. Must therefore use nonpaged memory for -the lists. -UPDATE: I'm not sure about this! -Gunnar -*/ - -FAST_MUTEX LockTocMutex; -NPAGED_LOOKASIDE_LIST GrantedLookaside; -NPAGED_LOOKASIDE_LIST LockTocLookaside; -PAGED_LOOKASIDE_LIST LockLookaside; - -__inline BOOLEAN -IsOverlappingLock(PFILE_LOCK_INFO Lock, - PLARGE_INTEGER StartOffset, - PLARGE_INTEGER EndOffset) -{ - if ((ULONGLONG)StartOffset->QuadPart > (ULONGLONG)Lock->EndingByte.QuadPart) - { - return FALSE; - } - - if ((ULONGLONG)EndOffset->QuadPart < (ULONGLONG)Lock->StartingByte.QuadPart) - { - return FALSE; - } - - return TRUE; -} - -__inline BOOLEAN -IsSurroundingLock(PFILE_LOCK_INFO Lock, - PLARGE_INTEGER StartOffset, - PLARGE_INTEGER EndOffset) -{ - if ((ULONGLONG)StartOffset->QuadPart >= (ULONGLONG)Lock->StartingByte.QuadPart && - (ULONGLONG)EndOffset->QuadPart <= (ULONGLONG)Lock->EndingByte.QuadPart) - { - return TRUE; - } - - return FALSE; -} - -VOID -NTAPI -FsRtlInitSystem(VOID) -{ - /* Initialize the list for all lock information structures */ - ExInitializeNPagedLookasideList(&LockTocLookaside, - NULL, - NULL, - 0, - sizeof(FILE_LOCK_TOC), - IFS_POOL_TAG, - 0); - - /* Initialize the list for granted locks */ - ExInitializeNPagedLookasideList(&GrantedLookaside, - NULL, - NULL, - 0, - sizeof(FILE_LOCK_GRANTED), - IFS_POOL_TAG, - 0); - - /* Initialize the list for lock allocations */ - ExInitializePagedLookasideList(&LockLookaside, - NULL, - NULL, - 0, - sizeof(FILE_LOCK), - IFS_POOL_TAG, - 0); - - /* Initialize the lock information mutex */ - ExInitializeFastMutex(&LockTocMutex); -} - -VOID -NTAPI -FsRtlCompleteLockIrpReal(IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteRoutine, - IN PVOID Context, - IN PIRP Irp, - IN NTSTATUS Status, - OUT PNTSTATUS NewStatus, - IN PFILE_OBJECT FileObject OPTIONAL) -{ - /* Check if we have a complete routine */ - if (CompleteRoutine) - { - /* Check if we have a file object */ - if (FileObject) FileObject->LastLock = NULL; - - /* Set the I/O Status and do completion */ - Irp->IoStatus.Status = Status; - *NewStatus = CompleteRoutine(Context, Irp); - } - else - { - /* Otherwise do a normal I/O complete request */ - FsRtlCompleteRequest(Irp, Status); - *NewStatus = Status; - } -} - -VOID -STDCALL -FsRtlpFileLockCancelRoutine(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - KIRQL oldIrql; - PKSPIN_LOCK SpinLock; - - //don't need this since we have our own sync. protecting irp cancellation - IoReleaseCancelSpinLock(Irp->CancelIrql); - - SpinLock = Irp->Tail.Overlay.DriverContext[3]; - - KeAcquireSpinLock(SpinLock, &oldIrql); - - RemoveEntryList(&Irp->Tail.Overlay.ListEntry); - - KeReleaseSpinLock(SpinLock, oldIrql); - - Irp->IoStatus.Status = STATUS_CANCELLED; - Irp->IoStatus.Information = 0; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); -} - -BOOLEAN -FASTCALL -FsRtlpCheckLockForReadOrWriteAccess(IN PFILE_LOCK FileLock, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN ULONG Key, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process, - IN BOOLEAN Read) -{ - KIRQL oldirql; - PFILE_LOCK_TOC LockToc; - PFILE_LOCK_GRANTED Granted; - LARGE_INTEGER EndOffset; - - ASSERT(FileLock); - - LockToc = FileLock->LockInformation; - - if (LockToc == NULL || Length->QuadPart == 0) - { - return TRUE; - } - - EndOffset.QuadPart = FileOffset->QuadPart + Length->QuadPart - 1; - - KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); - - LIST_FOR_EACH(Granted, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry) - { - //if overlapping - if(IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset)) - { - //No read conflict if (shared lock) OR (exclusive + our lock) - //No write conflict if exclusive lock AND our lock - if ((Read && !Granted->Lock.ExclusiveLock) || - (Granted->Lock.ExclusiveLock && - Granted->Lock.ProcessId == Process && - Granted->Lock.FileObject == FileObject && - Granted->Lock.Key == Key ) ) - { - //AND if lock surround request region, stop searching and grant - if (IsSurroundingLock(&Granted->Lock, FileOffset, &EndOffset) ) - { - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - return TRUE; - } - - //else continue searching for conflicts - continue; - } - - //found conflict - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - return FALSE; - } - - } - - //no conflict - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - return TRUE; -} - -NTSTATUS -FASTCALL -FsRtlpFastUnlockAllByKey(IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process, - IN ULONG Key, - IN BOOLEAN UseKey, - IN PVOID Context OPTIONAL) -{ - KIRQL oldirql; - PFILE_LOCK_TOC LockToc; - PFILE_LOCK_GRANTED Granted, tmp; - BOOLEAN Unlock = FALSE; - //must make local copy since FILE_LOCK struct is allowed to be paged - BOOLEAN GotUnlockRoutine; - LIST_ENTRY UnlockedListHead; - PLIST_ENTRY EnumEntry; - - ASSERT(FileLock); - LockToc = FileLock->LockInformation; - - if (LockToc == NULL) - { - return STATUS_RANGE_NOT_LOCKED; - } - - InitializeListHead(&UnlockedListHead); - GotUnlockRoutine = FileLock->UnlockRoutine != NULL; - KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); - - LIST_FOR_EACH_SAFE(Granted, tmp, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry) - { - - if (Granted->Lock.ProcessId == Process && - Granted->Lock.FileObject == FileObject && - (!UseKey || (UseKey && Granted->Lock.Key == Key)) ) - { - RemoveEntryList(&Granted->ListEntry); - Unlock = TRUE; - - if (GotUnlockRoutine) - { - /* - Put on unlocked list and call unlock routine for them afterwards. - This way we don't have to restart enum after each call - */ - InsertHeadList(&UnlockedListHead,&Granted->ListEntry); - } - else - { - ExFreeToNPagedLookasideList(&GrantedLookaside,Granted); - } - } - } - - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - - if (Unlock) - { - //call unlock routine for each unlocked lock (if any) - while (!IsListEmpty(&UnlockedListHead)) - { - EnumEntry = RemoveTailList(&UnlockedListHead); - Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry); - - FileLock->UnlockRoutine(Granted->UnlockContext, &Granted->Lock); - ExFreeToNPagedLookasideList(&GrantedLookaside,Granted); - } - - //NOTE: holding spinlock while calling this - KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); - FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql, Context); - - if (IsListEmpty(&LockToc->GrantedListHead)) - { - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - FsRtlAreThereCurrentFileLocks(FileLock) = FALSE; - } - else - { - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - } - - return STATUS_SUCCESS; - } - - return STATUS_RANGE_NOT_LOCKED; -} - -BOOLEAN -FASTCALL -FsRtlpAddLock(IN PFILE_LOCK_TOC LockToc, - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN PEPROCESS Process, - IN ULONG Key, - IN BOOLEAN ExclusiveLock, - IN PVOID Context) -{ - PFILE_LOCK_GRANTED Granted; - LARGE_INTEGER EndOffset; - - EndOffset.QuadPart = FileOffset->QuadPart + Length->QuadPart - 1; - - //loop and try to find conflicking locks - LIST_FOR_EACH(Granted, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry) - { - if (IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset)) - { - //we found a locks that overlap with the new lock - - //if both locks are shared, we might have a fast path outa here... - if (!Granted->Lock.ExclusiveLock && !ExclusiveLock) - { - //if existing lock surround new lock, we know that no other exclusive lock - //may overlap with our new lock;-D - if (IsSurroundingLock(&Granted->Lock, FileOffset, &EndOffset)) - { - break; - } - - //else keep locking for conflicts - continue; - } - - //we found a conflict: - //we want shared access to an excl. lock OR exlc. access to a shared lock - return FALSE; - } - } - - Granted = ExAllocateFromNPagedLookasideList(&GrantedLookaside); - - //starting offset - Granted->Lock.StartingByte = *FileOffset; - Granted->Lock.Length = *Length; - Granted->Lock.ExclusiveLock = ExclusiveLock; - Granted->Lock.Key = Key; - Granted->Lock.FileObject = FileObject; - Granted->Lock.ProcessId = Process; - //ending offset - Granted->Lock.EndingByte = EndOffset; - Granted->UnlockContext = Context; - - InsertHeadList(&LockToc->GrantedListHead,&Granted->ListEntry); - return TRUE; -} - -VOID -FASTCALL -FsRtlpCompletePendingLocks(IN PFILE_LOCK FileLock, - IN PFILE_LOCK_TOC LockToc, - IN OUT PKIRQL oldirql, - IN PVOID Context) -{ - //walk pending list, FIFO order, try 2 complete locks - PLIST_ENTRY EnumEntry; - PIRP Irp, tmp; - PIO_STACK_LOCATION Stack; - LIST_ENTRY CompletedListHead; - - InitializeListHead(&CompletedListHead); - - LIST_FOR_EACH_SAFE(Irp, tmp, &LockToc->PendingListHead, IRP, Tail.Overlay.ListEntry) - { - Stack = IoGetCurrentIrpStackLocation(Irp); - if (FsRtlpAddLock(LockToc, - Stack->FileObject, - &Stack->Parameters.LockControl.ByteOffset, - Stack->Parameters.LockControl.Length, - IoGetRequestorProcess(Irp), - Stack->Parameters.LockControl.Key, - Stack->Flags & SL_EXCLUSIVE_LOCK, - Irp->Tail.Overlay.DriverContext[2] //Context - ) ) - { - RemoveEntryList(&Irp->Tail.Overlay.ListEntry); - - if (!IoSetCancelRoutine(Irp, NULL)) - { - //irp is canceled and cancelroutine will run when we release the lock - InitializeListHead(&Irp->Tail.Overlay.ListEntry); - continue; - } - - /* - Put on completed list and complete them all afterwards. - This way we don't have to restart enum after each completion. - */ - InsertHeadList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry); - } - } - - KeReleaseSpinLock(&LockToc->SpinLock, *oldirql); - - //complete irp's (if any) - while (!IsListEmpty(&CompletedListHead)) - { - EnumEntry = RemoveTailList(&CompletedListHead); - - Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - - if (FileLock->CompleteLockIrpRoutine) - { - if (FileLock->CompleteLockIrpRoutine(Context, Irp)!=STATUS_SUCCESS) - { - Stack = IoGetCurrentIrpStackLocation(Irp); - - //revert - FsRtlpUnlockSingle ( FileLock, - Stack->FileObject, - &Stack->Parameters.LockControl.ByteOffset, - Stack->Parameters.LockControl.Length, - IoGetRequestorProcess(Irp), - Stack->Parameters.LockControl.Key, - NULL, /* unused context */ - FALSE /* don't call unlock copletion rout.*/ - ); - } - } - else - { - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - - } - - KeAcquireSpinLock(&LockToc->SpinLock, oldirql); -} - -NTSTATUS -FASTCALL -FsRtlpUnlockSingle(IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN PEPROCESS Process, - IN ULONG Key, - IN PVOID Context OPTIONAL, - IN BOOLEAN CallUnlockRoutine) -{ - KIRQL oldirql; - PFILE_LOCK_TOC LockToc; - PFILE_LOCK_GRANTED Granted, tmp; - - ASSERT(FileLock); - LockToc = FileLock->LockInformation; - - if (LockToc == NULL) - { - return STATUS_RANGE_NOT_LOCKED; - } - - KeAcquireSpinLock(&LockToc->SpinLock, &oldirql ); - - LIST_FOR_EACH_SAFE(Granted, tmp, &LockToc->GrantedListHead, FILE_LOCK_GRANTED,ListEntry) - { - - //must be exact match - if (FileOffset->QuadPart == Granted->Lock.StartingByte.QuadPart && - Length->QuadPart == Granted->Lock.Length.QuadPart && - Granted->Lock.ProcessId == Process && - Granted->Lock.FileObject == FileObject && - Granted->Lock.Key == Key) - { - RemoveEntryList(&Granted->ListEntry); - FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql, Context); - - if (IsListEmpty(&LockToc->GrantedListHead)) - { - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - - FsRtlAreThereCurrentFileLocks(FileLock) = FALSE; //paged data - } - else - { - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - } - - if (FileLock->UnlockRoutine && CallUnlockRoutine) - { - FileLock->UnlockRoutine(Granted->UnlockContext, &Granted->Lock); - } - - ExFreeToNPagedLookasideList(&GrantedLookaside, Granted); - - return STATUS_SUCCESS; - } - } - - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - - return STATUS_RANGE_NOT_LOCKED; - -} - -/* PUBLIC FUNCTIONS **********************************************************/ - -/* - * @implemented - */ -PFILE_LOCK_INFO -NTAPI -FsRtlGetNextFileLock(IN PFILE_LOCK FileLock, - IN BOOLEAN Restart) -{ - /* - Messy enumeration of granted locks. - What our last ptr. in LastReturnedLock points at, might have been freed between - calls, so we have to scan thru the list every time, searching for our last lock. - If it's not there anymore, restart the enumeration... - */ - KIRQL oldirql; - PLIST_ENTRY EnumEntry; - PFILE_LOCK_GRANTED Granted; - PFILE_LOCK_TOC LockToc; - BOOLEAN FoundPrevious = FALSE; - //must make local copy since FILE_LOCK struct is allowed to be in paged mem - FILE_LOCK_INFO LocalLastReturnedLockInfo; - PVOID LocalLastReturnedLock; - - ASSERT(FileLock); - LockToc = FileLock->LockInformation; - if (LockToc == NULL) - { - return NULL; - } - - LocalLastReturnedLock = FileLock->LastReturnedLock; - - KeAcquireSpinLock(&LockToc->SpinLock,&oldirql); - -restart:; - - EnumEntry = LockToc->GrantedListHead.Flink; - - if (Restart) - { - if (EnumEntry != &LockToc->GrantedListHead) - { - Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED,ListEntry); - LocalLastReturnedLockInfo = Granted->Lock; - KeReleaseSpinLock(&LockToc->SpinLock,oldirql); - - FileLock->LastReturnedLockInfo = LocalLastReturnedLockInfo; - FileLock->LastReturnedLock = EnumEntry; - return &FileLock->LastReturnedLockInfo; - } - else - { - KeReleaseSpinLock(&LockToc->SpinLock,oldirql); - return NULL; - } - } - - //else: continue enum - while (EnumEntry != &LockToc->GrantedListHead) - { - //found previous lock? - if (EnumEntry == LocalLastReturnedLock) - { - FoundPrevious = TRUE; - //get next - EnumEntry = EnumEntry->Flink; - if (EnumEntry != &LockToc->GrantedListHead) - { - Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED,ListEntry); - LocalLastReturnedLockInfo = Granted->Lock; - KeReleaseSpinLock(&LockToc->SpinLock,oldirql); - - FileLock->LastReturnedLockInfo = LocalLastReturnedLockInfo; - FileLock->LastReturnedLock = EnumEntry; - return &FileLock->LastReturnedLockInfo; - } - break; - } - EnumEntry = EnumEntry->Flink; - } - - if (!FoundPrevious) - { - //got here? uh no, didn't find our last lock..must have been freed...restart - Restart = TRUE; - goto restart; - } - - KeReleaseSpinLock(&LockToc->SpinLock,oldirql); - - return NULL;//no (more) locks -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlPrivateLock(IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN PEPROCESS Process, - IN ULONG Key, - IN BOOLEAN FailImmediately, //seems meaningless for fast io - IN BOOLEAN ExclusiveLock, - OUT PIO_STATUS_BLOCK IoStatus, - IN PIRP Irp OPTIONAL, - IN PVOID Context OPTIONAL, - IN BOOLEAN AlreadySynchronized) -{ - PFILE_LOCK_TOC LockToc; - KIRQL oldirql; - - ASSERT(FileLock); - if (FileLock->LockInformation == NULL) - { - ExAcquireFastMutex(&LockTocMutex); - //still NULL? - if (FileLock->LockInformation == NULL) - { - FileLock->LockInformation = ExAllocateFromNPagedLookasideList(&LockTocLookaside); - LockToc = FileLock->LockInformation; - KeInitializeSpinLock(&LockToc->SpinLock); - InitializeListHead(&LockToc->GrantedListHead); - InitializeListHead(&LockToc->PendingListHead); - } - ExReleaseFastMutex(&LockTocMutex); - } - - LockToc = FileLock->LockInformation; - KeAcquireSpinLock(&LockToc->SpinLock, &oldirql); - - //try add new lock (while holding spin lock) - if (FsRtlpAddLock(LockToc, - FileObject, - FileOffset, - Length, - Process, - Key, - ExclusiveLock, - Context - ) ) - { - IoStatus->Status = STATUS_SUCCESS; - } - else if (Irp && !FailImmediately) - { - //failed + irp + no fail = make. pending - - Irp->Tail.Overlay.DriverContext[3] = &LockToc->SpinLock; - Irp->Tail.Overlay.DriverContext[2] = Context; - - (void)IoSetCancelRoutine(Irp, FsRtlpFileLockCancelRoutine); - if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL)) - { - //irp was canceled - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); - - Irp->IoStatus.Status = STATUS_CANCELLED; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return TRUE; - } - - IoMarkIrpPending(Irp); - Irp->IoStatus.Status = IoStatus->Status = STATUS_PENDING; - Irp->IoStatus.Information = 0; - InsertHeadList(&LockToc->PendingListHead,&Irp->Tail.Overlay.ListEntry); - - } - else - { - IoStatus->Status = STATUS_LOCK_NOT_GRANTED; - } - - KeReleaseSpinLock(&LockToc->SpinLock, oldirql); //fires cancel routine - - //never pending if no irp;-) - ASSERT(!(IoStatus->Status == STATUS_PENDING && !Irp)); - - if (IoStatus->Status != STATUS_PENDING) - { - if (IoStatus->Status == STATUS_SUCCESS) - { - FsRtlAreThereCurrentFileLocks(FileLock) = TRUE; - } - - if (Irp) - { - Irp->IoStatus.Status = IoStatus->Status; - Irp->IoStatus.Information = 0; - if (FileLock->CompleteLockIrpRoutine) - { - if (FileLock->CompleteLockIrpRoutine(Context,Irp)!=STATUS_SUCCESS) - { - //CompleteLockIrpRoutine complain: revert changes - FsRtlpUnlockSingle( FileLock, - FileObject, - FileOffset, - Length, - Process, - Key, - NULL, /* context */ - FALSE /* don't call unlock copletion routine */ - ); - } - } - else - { - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - } - } - - //NOTE: only fast io seems to care about this return value - return (IoStatus->Status == STATUS_SUCCESS || FailImmediately); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - LARGE_INTEGER LocalLength; - - /* Get the I/O Stack location and length */ - Stack = IoGetCurrentIrpStackLocation(Irp); - LocalLength.QuadPart = Stack->Parameters.Read.Length; - - /* Call the internal API */ - return FsRtlpCheckLockForReadOrWriteAccess(FileLock, - &Stack->Parameters. - Read.ByteOffset, - &LocalLength, - Stack->Parameters.Read.Key, - Stack->FileObject, - IoGetRequestorProcess(Irp), - TRUE); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - LARGE_INTEGER LocalLength; - - /* Get the I/O Stack location and length */ - Stack = IoGetCurrentIrpStackLocation(Irp); - LocalLength.QuadPart = Stack->Parameters.Read.Length; - - /* Call the internal API */ - return FsRtlpCheckLockForReadOrWriteAccess(FileLock, - &Stack->Parameters. - Read.ByteOffset, - &LocalLength, - Stack->Parameters.Read.Key, - Stack->FileObject, - IoGetRequestorProcess(Irp), - FALSE); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlFastCheckLockForRead(IN PFILE_LOCK FileLock, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN ULONG Key, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process) -{ - /* Call the internal API */ - return FsRtlpCheckLockForReadOrWriteAccess(FileLock, - FileOffset, - Length, - Key, - FileObject, - Process, - TRUE); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN ULONG Key, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process) -{ - /* Call the internal API */ - return FsRtlpCheckLockForReadOrWriteAccess(FileLock, - FileOffset, - Length, - Key, - FileObject, - Process, - FALSE); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN PEPROCESS Process, - IN ULONG Key, - IN PVOID Context OPTIONAL, - IN BOOLEAN AlreadySynchronized) -{ - /* Call the internal API */ - return FsRtlpUnlockSingle(FileLock, - FileObject, - FileOffset, - Length, - Process, - Key, - Context, - TRUE); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process, - IN PVOID Context OPTIONAL) -{ - /* Call the generic function by process */ - return FsRtlpFastUnlockAllByKey(FileLock, - FileObject, - Process, - 0, - FALSE, - Context); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -FsRtlFastUnlockAllByKey(IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process, - IN ULONG Key, - IN PVOID Context OPTIONAL) -{ - /* Call the generic function by key */ - return FsRtlpFastUnlockAllByKey(FileLock, - FileObject, - Process, - Key, - TRUE, - Context); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -FsRtlProcessFileLock(IN PFILE_LOCK FileLock, - IN PIRP Irp, - IN PVOID Context OPTIONAL) -{ - PIO_STACK_LOCATION IoStackLocation; - NTSTATUS Status; - IO_STATUS_BLOCK IoStatusBlock; - - /* Get the I/O Stack location */ - IoStackLocation = IoGetCurrentIrpStackLocation(Irp); - ASSERT(IoStackLocation->MajorFunction == IRP_MJ_LOCK_CONTROL); - - /* Clear the I/O status block and check what function this is */ - IoStatusBlock.Information = 0; - switch(IoStackLocation->MinorFunction) - { - /* A lock */ - case IRP_MN_LOCK: - - /* Call the private lock routine */ - FsRtlPrivateLock(FileLock, - IoStackLocation->FileObject, - &IoStackLocation-> - Parameters.LockControl.ByteOffset, - IoStackLocation->Parameters.LockControl.Length, - IoGetRequestorProcess(Irp), - IoStackLocation->Parameters.LockControl.Key, - IoStackLocation->Flags & SL_FAIL_IMMEDIATELY, - IoStackLocation->Flags & SL_EXCLUSIVE_LOCK, - &IoStatusBlock, - Irp, - Context, - FALSE); - break; - - /* A single unlock */ - case IRP_MN_UNLOCK_SINGLE: - - /* Call fast unlock */ - IoStatusBlock.Status = - FsRtlFastUnlockSingle(FileLock, - IoStackLocation->FileObject, - &IoStackLocation->Parameters.LockControl. - ByteOffset, - IoStackLocation->Parameters.LockControl. - Length, - IoGetRequestorProcess(Irp), - IoStackLocation->Parameters.LockControl. - Key, - Context, - FALSE); - - /* Complete the IRP */ - FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, - Context, - Irp, - IoStatusBlock.Status, - &Status, - NULL); - break; - - /* Total unlock */ - case IRP_MN_UNLOCK_ALL: - - /* Do a fast unlock */ - IoStatusBlock.Status = FsRtlFastUnlockAll(FileLock, - IoStackLocation-> - FileObject, - IoGetRequestorProcess(Irp), - Context); - - /* Complete the IRP */ - FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, - Context, - Irp, - IoStatusBlock.Status, - &Status, - NULL); - break; - - /* Unlock by key */ - case IRP_MN_UNLOCK_ALL_BY_KEY: - - /* Do it */ - IoStatusBlock.Status = - FsRtlFastUnlockAllByKey(FileLock, - IoStackLocation->FileObject, - IoGetRequestorProcess(Irp), - IoStackLocation->Parameters. - LockControl.Key, - Context); - - /* Complete the IRP */ - FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, - Context, - Irp, - IoStatusBlock.Status, - &Status, - NULL); - break; - - /* Invalid request */ - default: - - /* Complete it */ - FsRtlCompleteRequest(Irp, STATUS_INVALID_DEVICE_REQUEST); - IoStatusBlock.Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - - /* Return the status */ - return IoStatusBlock.Status; -} - -/* - * @implemented - */ -VOID -NTAPI -FsRtlInitializeFileLock (IN PFILE_LOCK FileLock, - IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, - IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL) -{ - /* Setup the lock */ - FileLock->FastIoIsQuestionable = FALSE; - FileLock->CompleteLockIrpRoutine = CompleteLockIrpRoutine; - FileLock->UnlockRoutine = UnlockRoutine; - FileLock->LockInformation = NULL; -} - -/* - * @implemented - */ -VOID -NTAPI -FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock) -{ - PFILE_LOCK_TOC LockToc; - PIRP Irp; - PFILE_LOCK_GRANTED Granted; - PLIST_ENTRY EnumEntry; - KIRQL OldIrql; - - /* Get the lock information */ - LockToc = FileLock->LockInformation; - if (!FileLock->LockInformation) return; - - /* Acquire the lock queue */ - KeAcquireSpinLock(&LockToc->SpinLock, &OldIrql); - - /* Loop the lock tree */ - while (!IsListEmpty(&LockToc->GrantedListHead)) - { - /* Get the entry */ - EnumEntry = RemoveTailList(&LockToc->GrantedListHead); - - /* Get the granted lock and free it */ - Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED, ListEntry); - ExFreeToNPagedLookasideList(&GrantedLookaside, Granted); - } - - /* Loop the waiting locks */ - while (!IsListEmpty(&LockToc->PendingListHead)) - { - /* Get the entry and IRP */ - EnumEntry = RemoveTailList(&LockToc->PendingListHead); - Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry); - - /* Release the lock */ - KeReleaseSpinLock(&LockToc->SpinLock, OldIrql); - - /* Acquire cancel spinlock and clear the cancel routine */ - IoAcquireCancelSpinLock(&Irp->CancelIrql); - (void)IoSetCancelRoutine(Irp, NULL); - IoReleaseCancelSpinLock(Irp->CancelIrql); - - /* Complete the IRP */ - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_RANGE_NOT_LOCKED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - /* Acquire the lock again */ - KeAcquireSpinLock(&LockToc->SpinLock, &OldIrql); - } - - /* Release the lock and free it */ - KeReleaseSpinLock(&LockToc->SpinLock, OldIrql); - ExFreeToNPagedLookasideList(&LockTocLookaside, LockToc); - - /* Remove the lock information pointer */ - FileLock->LockInformation = NULL; -} - -/* - * @implemented - */ -PFILE_LOCK -NTAPI -FsRtlAllocateFileLock(IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, - IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL) -{ - PFILE_LOCK FileLock; - - /* Try to allocate it */ - FileLock = ExAllocateFromPagedLookasideList(&LockLookaside); - if (FileLock) - { - /* Initialize it */ - FsRtlInitializeFileLock(FileLock, - CompleteLockIrpRoutine, - UnlockRoutine); - } - - /* Return the lock */ - return FileLock; -} - -/* - * @implemented - */ -VOID -NTAPI -FsRtlFreeFileLock(IN PFILE_LOCK FileLock) -{ - /* Uninitialize and free the lock */ - FsRtlUninitializeFileLock(FileLock); - ExFreeToPagedLookasideList(&LockLookaside, FileLock); -} - -/* EOF */ diff --git a/reactos/ntoskrnl/fs/name.c b/reactos/ntoskrnl/fs/name.c deleted file mode 100644 index 2e9f09ddb75..00000000000 --- a/reactos/ntoskrnl/fs/name.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/name.c - * PURPOSE: Name and DBCS Name Validation and Dissection Functions. - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * Eric Kohl - * Filip Navara - */ - -/* INCLUDES ****************************************************************/ - -#include - -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -static UCHAR LegalAnsiCharacterArray[] = -{ - 0, /* CTRL+@, 0x00 */ - 0, /* CTRL+A, 0x01 */ - 0, /* CTRL+B, 0x02 */ - 0, /* CTRL+C, 0x03 */ - 0, /* CTRL+D, 0x04 */ - 0, /* CTRL+E, 0x05 */ - 0, /* CTRL+F, 0x06 */ - 0, /* CTRL+G, 0x07 */ - 0, /* CTRL+H, 0x08 */ - 0, /* CTRL+I, 0x09 */ - 0, /* CTRL+J, 0x0a */ - 0, /* CTRL+K, 0x0b */ - 0, /* CTRL+L, 0x0c */ - 0, /* CTRL+M, 0x0d */ - 0, /* CTRL+N, 0x0e */ - 0, /* CTRL+O, 0x0f */ - 0, /* CTRL+P, 0x10 */ - 0, /* CTRL+Q, 0x11 */ - 0, /* CTRL+R, 0x12 */ - 0, /* CTRL+S, 0x13 */ - 0, /* CTRL+T, 0x14 */ - 0, /* CTRL+U, 0x15 */ - 0, /* CTRL+V, 0x16 */ - 0, /* CTRL+W, 0x17 */ - 0, /* CTRL+X, 0x18 */ - 0, /* CTRL+Y, 0x19 */ - 0, /* CTRL+Z, 0x1a */ - 0, /* CTRL+[, 0x1b */ - 0, /* CTRL+\, 0x1c */ - 0, /* CTRL+], 0x1d */ - 0, /* CTRL+^, 0x1e */ - 0, /* CTRL+_, 0x1f */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* ` ', 0x20 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `!', 0x21 */ - FSRTL_WILD_CHARACTER, /* `"', 0x22 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `#', 0x23 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `$', 0x24 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `%', 0x25 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `&', 0x26 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `'', 0x27 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `(', 0x28 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `)', 0x29 */ - FSRTL_WILD_CHARACTER, /* `*', 0x2a */ - FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `+', 0x2b */ - FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `,', 0x2c */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `-', 0x2d */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `.', 0x2e */ - 0, /* `/', 0x2f */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `0', 0x30 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `1', 0x31 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `2', 0x32 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `3', 0x33 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `4', 0x34 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `5', 0x35 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `6', 0x36 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `7', 0x37 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `8', 0x38 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `9', 0x39 */ - FSRTL_NTFS_LEGAL, /* `:', 0x3a */ - FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `;', 0x3b */ - FSRTL_WILD_CHARACTER, /* `<', 0x3c */ - FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `=', 0x3d */ - FSRTL_WILD_CHARACTER, /* `>', 0x3e */ - FSRTL_WILD_CHARACTER, /* `?', 0x3f */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `@', 0x40 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `A', 0x41 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `B', 0x42 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `C', 0x43 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `D', 0x44 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `E', 0x45 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `F', 0x46 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `G', 0x47 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `H', 0x48 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `I', 0x49 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `J', 0x4a */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `K', 0x4b */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `L', 0x4c */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `M', 0x4d */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `N', 0x4e */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `O', 0x4f */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `P', 0x50 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `Q', 0x51 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `R', 0x52 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `S', 0x53 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `T', 0x54 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `U', 0x55 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `V', 0x56 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `W', 0x57 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `X', 0x58 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `Y', 0x59 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `Z', 0x5a */ - FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `[', 0x5b */ - 0, /* `\', 0x5c */ - FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `]', 0x5d */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `^', 0x5e */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `_', 0x5f */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* ``', 0x60 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `a', 0x61 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `b', 0x62 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `c', 0x63 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `d', 0x64 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `e', 0x65 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `f', 0x66 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `g', 0x67 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `h', 0x68 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `i', 0x69 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `j', 0x6a */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `k', 0x6b */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `l', 0x6c */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `m', 0x6d */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `n', 0x6e */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `o', 0x6f */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `p', 0x70 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `q', 0x71 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `r', 0x72 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `s', 0x73 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `t', 0x74 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `u', 0x75 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `v', 0x76 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `w', 0x77 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `x', 0x78 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `y', 0x79 */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `z', 0x7a */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `{', 0x7b */ - 0, /* `|', 0x7c */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `}', 0x7d */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `~', 0x7e */ - FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL /* 0x7f */ -}; - -PUCHAR FsRtlLegalAnsiCharacterArray = LegalAnsiCharacterArray; - -/* FUNCTIONS *****************************************************************/ - -/*++ - * @name FsRtlAreNamesEqual - * @implemented - * - * FILLME - * - * @param Name1 - * FILLME - * - * @param Name2 - * FILLME - * - * @param IgnoreCase - * FILLME - * - * @param UpcaseTable - * FILLME - * - * @return None - * - * @remarks From Bo Branten's ntifs.h v25. - * - *--*/ -BOOLEAN -NTAPI -FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, - IN PCUNICODE_STRING Name2, - IN BOOLEAN IgnoreCase, - IN PCWCH UpcaseTable OPTIONAL) -{ - UNICODE_STRING UpcaseName1; - UNICODE_STRING UpcaseName2; - BOOLEAN StringsAreEqual; - - /* Well, first check their size */ - if (Name1->Length != Name2->Length) { - /* Not equal! */ - return FALSE; - } - - /* Turn them into Upcase if we don't have a table */ - if (IgnoreCase && !UpcaseTable) { - RtlUpcaseUnicodeString(&UpcaseName1, Name1, TRUE); - RtlUpcaseUnicodeString(&UpcaseName2, Name2, TRUE); - Name1 = &UpcaseName1; - Name2 = &UpcaseName2; - - goto ManualCase; - } - - /* Do a case-sensitive search */ - if (!IgnoreCase) { - -ManualCase: - /* Use a raw memory compare */ - StringsAreEqual = RtlEqualMemory(Name1->Buffer, - Name2->Buffer, - Name1->Length); - - /* Clear the strings if we need to */ - if (IgnoreCase) { - RtlFreeUnicodeString(&UpcaseName1); - RtlFreeUnicodeString(&UpcaseName2); - } - - /* Return the equality */ - return StringsAreEqual; - - } else { - - /* Case in-sensitive search */ - - LONG i; - - for (i = Name1->Length / sizeof(WCHAR) - 1; i >= 0; i--) { - - if (UpcaseTable[Name1->Buffer[i]] != UpcaseTable[Name2->Buffer[i]]) { - - /* Non-match found! */ - return FALSE; - } - } - - /* We finished the loop so we are equal */ - return TRUE; - } -} - -/*++ - * @name FsRtlDissectDbcs - * @implemented - * - * Dissects a given path name into first and remaining part. - * - * @param Name - * ANSI string to dissect. - * - * @param FirstPart - * Pointer to user supplied ANSI_STRING, that will later point - * to the first part of the original name. - * - * @param RemainingPart - * Pointer to user supplied ANSI_STRING, that will later point - * to the remaining part of the original name. - * - * @return None - * - * @remarks Example: - * Name: \test1\test2\test3 - * FirstPart: test1 - * RemainingPart: test2\test3 - * - *--*/ -VOID -NTAPI -FsRtlDissectDbcs(IN ANSI_STRING Name, - OUT PANSI_STRING FirstPart, - OUT PANSI_STRING RemainingPart) -{ - ULONG i; - ULONG FirstLoop; - - /* Initialize the Outputs */ - RtlZeroMemory(&FirstPart, sizeof(ANSI_STRING)); - RtlZeroMemory(&RemainingPart, sizeof(ANSI_STRING)); - - /* Bail out if empty */ - if (!Name.Length) return; - - /* Ignore backslash */ - if (Name.Buffer[0] == '\\') { - i = 1; - } else { - i = 0; - } - - /* Loop until we find a backslash */ - for (FirstLoop = i;i < Name.Length;i++) { - if (Name.Buffer[i] != '\\') break; - if (FsRtlIsLeadDbcsCharacter(Name.Buffer[i])) i++; - } - - /* Now we have the First Part */ - FirstPart->Length = (USHORT)(i - FirstLoop); - FirstPart->MaximumLength = FirstPart->Length; /* +2?? */ - FirstPart->Buffer = &Name.Buffer[FirstLoop]; - - /* Make the second part if something is still left */ - if (iLength = (USHORT)(Name.Length - (i+1)); - RemainingPart->MaximumLength = RemainingPart->Length; /* +2?? */ - RemainingPart->Buffer = &Name.Buffer[i+1]; - } - - return; -} - -/*++ - * @name FsRtlDissectName - * @implemented - * - * Dissects a given path name into first and remaining part. - * - * @param Name - * Unicode string to dissect. - * - * @param FirstPart - * Pointer to user supplied UNICODE_STRING, that will later point - * to the first part of the original name. - * - * @param RemainingPart - * Pointer to user supplied UNICODE_STRING, that will later point - * to the remaining part of the original name. - * - * @return None - * - * @remarks Example: - * Name: \test1\test2\test3 - * FirstPart: test1 - * RemainingPart: test2\test3 - * - *--*/ -VOID -NTAPI -FsRtlDissectName(IN UNICODE_STRING Name, - OUT PUNICODE_STRING FirstPart, - OUT PUNICODE_STRING RemainingPart) -{ - USHORT NameOffset = 0; - USHORT NameLength = 0; - USHORT Length; - - FirstPart->Length = 0; - FirstPart->MaximumLength = 0; - FirstPart->Buffer = NULL; - - RemainingPart->Length = 0; - RemainingPart->MaximumLength = 0; - RemainingPart->Buffer = NULL; - - if (Name.Length == 0) - return; - - /* Skip leading backslash */ - if (Name.Buffer[0] == L'\\') - NameOffset++; - - Length = Name.Length / sizeof(WCHAR); - - /* Search for next backslash or end-of-string */ - while ((NameOffset + NameLength < Length) && - (Name.Buffer[NameOffset + NameLength] != L'\\')) - { - NameLength++; - } - - FirstPart->Length = - FirstPart->MaximumLength = NameLength * sizeof(WCHAR); - FirstPart->Buffer = &Name.Buffer[NameOffset]; - - NameOffset += NameLength + 1; - if (NameOffset < Length) - { - RemainingPart->Length = (Length - NameOffset) * sizeof(WCHAR); - RemainingPart->MaximumLength = (Length - NameOffset) * sizeof(WCHAR); - RemainingPart->Buffer = &Name.Buffer[NameOffset]; - } -} - -/*++ - * @name FsRtlDoesDbcsContainWildCards - * @implemented - * - * FILLME - * - * @param Name - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -BOOLEAN -NTAPI -FsRtlDoesDbcsContainWildCards(IN PANSI_STRING Name) -{ - ULONG i; - - /* Check every character */ - for (i=0;i < Name->Length;i++) { - - /* First make sure it's not the Lead DBCS */ - if (FsRtlIsLeadDbcsCharacter(Name->Buffer[i])) { - i++; - } else if (FsRtlIsAnsiCharacterWild(Name->Buffer[i])) { - /* Now return if it has a Wilcard */ - return TRUE; - } - } - - /* We didn't return above...so none found */ - return FALSE; -} - -/*++ - * @name FsRtlDoesNameContainWildCards - * @implemented - * - * FILLME - * - * @param Name - * Pointer to a UNICODE_STRING containing Name to examine - * - * @return TRUE if Name contains wildcards, FALSE otherwise - * - * @remarks From Bo Branten's ntifs.h v12. - * - *--*/ -BOOLEAN -NTAPI -FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name) -{ - PWCHAR Ptr; - - /* Loop through every character */ - if (Name->Length) { - for (Ptr = Name->Buffer + (Name->Length / sizeof(WCHAR))-1; - Ptr >= Name->Buffer && *Ptr != L'\\';Ptr--) { - - /* Check for Wildcard */ - if (FsRtlIsUnicodeCharacterWild(*Ptr)) { - return TRUE; - } - } - } - - /* Nothing Found */ - return FALSE; -} - -/*++ - * @name FsRtlIsDbcsInExpression - * @unimplemented - * - * FILLME - * - * @param Expression - * FILLME - * - * @param Name - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -BOOLEAN -NTAPI -FsRtlIsDbcsInExpression(IN PANSI_STRING Expression, - IN PANSI_STRING Name) -{ - UNIMPLEMENTED; - return FALSE; -} - -/*++ - * @name FsRtlIsFatDbcsLegal - * @unimplemented - * - * FILLME - * - * @param DbcsName - * FILLME - * - * @param WildCardsPermissible - * FILLME - * - * @param PathNamePermissible - * FILLME - * - * @param LeadingBackslashPermissible - * FILLME - * - * @return TRUE if the DbcsName is legal, FALSE otherwise - * - * @remarks None - * - *--*/ -BOOLEAN -NTAPI -FsRtlIsFatDbcsLegal(IN ANSI_STRING DbcsName, - IN BOOLEAN WildCardsPermissible, - IN BOOLEAN PathNamePermissible, - IN BOOLEAN LeadingBackslashPermissible) -{ - UNIMPLEMENTED; - return FALSE; -} - -/*++ - * @name FsRtlIsHpfsDbcsLegal - * @unimplemented - * - * FILLME - * - * @param DbcsName - * FILLME - * - * @param WildCardsPermissible - * FILLME - * - * @param PathNamePermissible - * FILLME - * - * @param LeadingBackslashPermissible - * FILLME - * - * @return TRUE if the DbcsName is legal, FALSE otherwise - * - * @remarks None - * - *--*/ -BOOLEAN -STDCALL -FsRtlIsHpfsDbcsLegal(IN ANSI_STRING DbcsName, - IN BOOLEAN WildCardsPermissible, - IN BOOLEAN PathNamePermissible, - IN BOOLEAN LeadingBackslashPermissible) -{ - UNIMPLEMENTED; - return FALSE; -} - -/*++ - * @name FsRtlIsNameInExpression - * @implemented - * - * FILLME - * - * @param DeviceObject - * FILLME - * - * @param Irp - * FILLME - * - * @return TRUE if Name is in Expression, FALSE otherwise - * - * @remarks From Bo Branten's ntifs.h v12. This function should be - * rewritten to avoid recursion and better wildcard handling - * should be implemented (see FsRtlDoesNameContainWildCards). - * - *--*/ -BOOLEAN -NTAPI -FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, - IN PUNICODE_STRING Name, - IN BOOLEAN IgnoreCase, - IN PWCHAR UpcaseTable OPTIONAL) -{ - USHORT ExpressionPosition, NamePosition; - UNICODE_STRING TempExpression, TempName; - - ExpressionPosition = 0; - NamePosition = 0; - while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) && - NamePosition < (Name->Length / sizeof(WCHAR))) - { - if (Expression->Buffer[ExpressionPosition] == L'*') - { - ExpressionPosition++; - if (ExpressionPosition == (Expression->Length / sizeof(WCHAR))) - { - return TRUE; - } - while (NamePosition < (Name->Length / sizeof(WCHAR))) - { - TempExpression.Length = - TempExpression.MaximumLength = - Expression->Length - (ExpressionPosition * sizeof(WCHAR)); - TempExpression.Buffer = Expression->Buffer + ExpressionPosition; - TempName.Length = - TempName.MaximumLength = - Name->Length - (NamePosition * sizeof(WCHAR)); - TempName.Buffer = Name->Buffer + NamePosition; - /* FIXME: Rewrite to get rid of recursion */ - if (FsRtlIsNameInExpression(&TempExpression, &TempName, - IgnoreCase, UpcaseTable)) - { - return TRUE; - } - NamePosition++; - } - } - else - { - /* FIXME: Take UpcaseTable into account! */ - if (Expression->Buffer[ExpressionPosition] == L'?' || - (IgnoreCase && - RtlUpcaseUnicodeChar(Expression->Buffer[ExpressionPosition]) == - RtlUpcaseUnicodeChar(Name->Buffer[NamePosition])) || - (!IgnoreCase && - Expression->Buffer[ExpressionPosition] == - Name->Buffer[NamePosition])) - { - NamePosition++; - ExpressionPosition++; - } - else - { - return FALSE; - } - } - } - - /* Handle matching of "f0_*.*" expression to "f0_000" file name. */ - if (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) && - Expression->Buffer[ExpressionPosition] == L'.') - { - while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) && - (Expression->Buffer[ExpressionPosition] == L'.' || - Expression->Buffer[ExpressionPosition] == L'*' || - Expression->Buffer[ExpressionPosition] == L'?')) - { - ExpressionPosition++; - } - } - - if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)) && - NamePosition == (Name->Length / sizeof(WCHAR))) - { - return TRUE; - } - - return FALSE; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/fs/notify.c b/reactos/ntoskrnl/fs/notify.c deleted file mode 100644 index 759f0e7013c..00000000000 --- a/reactos/ntoskrnl/fs/notify.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* $Id$ - * - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/notify.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: Gunnar Dalsnes - */ - -/* INCLUDES *****************************************************************/ -#include - -#define NDEBUG -#include - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, FsRtlpInitNotifyImplementation) -#endif - -/* GLOBALS *******************************************************************/ - -PAGED_LOOKASIDE_LIST NotifyEntryLookaside; - -typedef struct _NOTIFY_ENTRY -{ - LIST_ENTRY ListEntry; - PSTRING FullDirectoryName; - BOOLEAN WatchTree; - BOOLEAN PendingChanges; - ULONG CompletionFilter; - LIST_ENTRY IrpQueue; - PVOID Fcb; - PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback; - PSECURITY_SUBJECT_CONTEXT SubjectContext; - PVOID FsContext; - BOOLEAN Unicode; - BOOLEAN BufferExhausted; - PVOID Buffer; /* Buffer == NULL equals IgnoreBuffer == TRUE */ - ULONG BufferSize; - ULONG NextEntryOffset; - PFILE_NOTIFY_INFORMATION PrevEntry; -} NOTIFY_ENTRY, *PNOTIFY_ENTRY; - -/* FUNCTIONS *****************************************************************/ - -/*++ - * @name FsRtlpInitNotifyImplementation - * @unimplemented - * - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI INIT_FUNCTION -FsRtlpInitNotifyImplementation(VOID) -{ - ExInitializePagedLookasideList(&NotifyEntryLookaside, - NULL, - NULL, - 0, - sizeof(NOTIFY_ENTRY), - FSRTL_NOTIFY_TAG, - 0); -} - -/*++ - * @name FsRtlpIsUnicodePath - * - * FILLME - * - * @param Path - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -static -__inline -BOOLEAN -FsRtlpIsUnicodePath(PSTRING Path) -{ - ASSERT(Path->Length); - - if (Path->Length == 1) - return FALSE; - - if (*(WCHAR*)Path->Buffer == '\\') - return TRUE; - - return FALSE; -} - -/*++ - * @name FsRtlpNotifyCancelRoutine - * - * FILLME - * - * @param DeviceObject - * FILLME - * - * @param Irp - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -static -VOID -NTAPI -FsRtlpNotifyCancelRoutine(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PFAST_MUTEX Lock; - - //don't need this since we have our own sync. protecting irp cancellation - IoReleaseCancelSpinLock(Irp->CancelIrql); - - Lock = (PFAST_MUTEX)Irp->Tail.Overlay.DriverContext[3]; - - ExAcquireFastMutex(Lock ); - - RemoveEntryList(&Irp->Tail.Overlay.ListEntry); - - ExReleaseFastMutex(Lock); - - Irp->IoStatus.Status = STATUS_CANCELLED; - Irp->IoStatus.Information = 0; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - -} - -/*++ - * @name FsRtlpFindNotifyEntry - * - * FILLME - * - * @param NotifyList - * FILLME - * - * @param FsContext - * FILLME - * - * @return FILLME - * - * @remarks None - * - *--*/ -static -PNOTIFY_ENTRY -FASTCALL -FsRtlpFindNotifyEntry(PLIST_ENTRY NotifyList, - PVOID FsContext) -{ - PNOTIFY_ENTRY NotifyEntry; - - LIST_FOR_EACH(NotifyEntry, NotifyList, NOTIFY_ENTRY, ListEntry) - { - if (NotifyEntry->FsContext == FsContext) - { - return NotifyEntry; - } - } - - return NULL; -} - -/*++ - * @name FsRtlNotifyChangeDirectory - * @implemented - * - * FILLME - * - * @param NotifySync - * FILLME - * - * @param FsContext - * FILLME - * - * @param FullDirectoryName - * FILLME - * - * @param NotifyList - * FILLME - * - * @param WatchTree - * FILLME - * - * @param CompletionFilter - * FILLME - * - * @param NotifyIrp - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlNotifyChangeDirectory(IN PNOTIFY_SYNC NotifySync, - IN PVOID FsContext, - IN PSTRING FullDirectoryName, - IN PLIST_ENTRY NotifyList, - IN BOOLEAN WatchTree, - IN ULONG CompletionFilter, - IN PIRP NotifyIrp) -{ - FsRtlNotifyFullChangeDirectory(NotifySync, - NotifyList, - FsContext, - FullDirectoryName, - WatchTree, - TRUE, /* IgnoreBuffer */ - CompletionFilter, - NotifyIrp, - NULL, - NULL); -} - -/*++ - * @name FsRtlNotifyCleanup - * @unimplemented - * - * Called by FSD when all handles to FileObject (identified by FsContext) are closed - * - * @param NotifySync - * FILLME - * - * @param NotifyList - * FILLME - * - * @param FsContext - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlNotifyCleanup(IN PNOTIFY_SYNC NotifySync, - IN PLIST_ENTRY NotifyList, - IN PVOID FsContext) -{ - PNOTIFY_ENTRY NotifyEntry; - LIST_ENTRY CompletedListHead; - PLIST_ENTRY TmpEntry; - PIRP Irp; - - InitializeListHead(&CompletedListHead); - - ExAcquireFastMutex((PFAST_MUTEX)NotifySync); - - NotifyEntry = FsRtlpFindNotifyEntry(NotifyList, FsContext); - - if (NotifyEntry) - { - /* free buffered changes */ - if (NotifyEntry->Buffer) - { - ExFreePool(NotifyEntry->Buffer); - } - - /* cancel(?) pending irps */ - while (!IsListEmpty(&NotifyEntry->IrpQueue)) - { - TmpEntry = RemoveHeadList(&NotifyEntry->IrpQueue); - Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry); - - /* irp cancelation bolilerplate */ - if (!IoSetCancelRoutine(Irp, NULL)) - { - //The cancel routine will be called. When we release the lock it will complete the irp. - InitializeListHead(&Irp->Tail.Overlay.ListEntry); - continue; - } - - Irp->IoStatus.Status = STATUS_NOTIFY_CLEANUP; /* FIXME: correct status? */ - Irp->IoStatus.Information = 0; - - /* avoid holding lock while completing irp */ - InsertTailList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry); - } - - /* Unlink and free the NotifyStruct */ - RemoveEntryList(&NotifyEntry->ListEntry); - ExFreeToPagedLookasideList(&NotifyEntryLookaside, NotifyEntry); - } - - ExReleaseFastMutex((PFAST_MUTEX)NotifySync); - - /* complete defered irps */ - while (!IsListEmpty(&CompletedListHead)) - { - TmpEntry = RemoveHeadList(&CompletedListHead); - Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } -} - -/*++ - * @name FsRtlNotifyFilterChangeDirectory - * @unimplemented - * - * FILLME - * - * @param NotifySync - * FILLME - * - * @param NotifyList - * FILLME - * - * @param FsContext - * FILLME - * - * @param FullDirectoryName - * FILLME - * - * @param WatchTree - * FILLME - * - * @param IgnoreBuffer - * FILLME - * - * @param CompletionFilter - * FILLME - * - * @param NotifyIrp - * FILLME - * - * @param TraverseCallback - * FILLME - * - * @param SubjectContext - * FILLME - * - * @param FilterCallback - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlNotifyFilterChangeDirectory(IN PNOTIFY_SYNC NotifySync, - IN PLIST_ENTRY NotifyList, - IN PVOID FsContext, - IN PSTRING FullDirectoryName, - IN BOOLEAN WatchTree, - IN BOOLEAN IgnoreBuffer, - IN ULONG CompletionFilter, - IN PIRP NotifyIrp, - IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, - IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL, - IN PFILTER_REPORT_CHANGE FilterCallback OPTIONAL) -{ - UNIMPLEMENTED; -} - -/*++ - * @name FsRtlNotifyFilterReportChange - * @unimplemented - * - * FILLME - * - * @param NotifySync - * FILLME - * - * @param NotifyList - * FILLME - * - * @param FullTargetName - * FILLME - * - * @param TargetNameOffset - * FILLME - * - * @param StreamName - * FILLME - * - * @param NormalizedParentName - * FILLME - * - * @param FilterMatch - * FILLME - * - * @param Action - * FILLME - * - * @param TargetContext - * FILLME - * - * @param FilterContext - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlNotifyFilterReportChange(IN PNOTIFY_SYNC NotifySync, - IN PLIST_ENTRY NotifyList, - IN PSTRING FullTargetName, - IN USHORT TargetNameOffset, - IN PSTRING StreamName OPTIONAL, - IN PSTRING NormalizedParentName OPTIONAL, - IN ULONG FilterMatch, - IN ULONG Action, - IN PVOID TargetContext, - IN PVOID FilterContext) -{ - UNIMPLEMENTED; -} - -/*++ - * @name FsRtlpWatchedDirectoryWasDeleted - * - * FILLME - * - * @param NotifySync - * FILLME - * - * @param NotifyList - * FILLME - * - * @param Fcb - * FILLME - * - * @return None - * - * @remarks Private function - * - *--*/ -static -VOID -FASTCALL -FsRtlpWatchedDirectoryWasDeleted(IN PNOTIFY_SYNC NotifySync, - IN PLIST_ENTRY NotifyList, - IN PVOID Fcb) -{ - LIST_ENTRY CompletedListHead; - PLIST_ENTRY TmpEntry; - PNOTIFY_ENTRY NotifyEntry, tmp; - PIRP Irp; - - InitializeListHead(&CompletedListHead); - - ExAcquireFastMutex((PFAST_MUTEX)NotifySync); - - LIST_FOR_EACH_SAFE(NotifyEntry, tmp, NotifyList, NOTIFY_ENTRY, ListEntry ) - { - if (NotifyEntry->Fcb == Fcb) - { - RemoveEntryList(&NotifyEntry->ListEntry); - - /* free buffered changes */ - if (NotifyEntry->Buffer) - { - ExFreePool(NotifyEntry->Buffer); - } - - /* cleanup pending irps */ - while (!IsListEmpty(&NotifyEntry->IrpQueue)) - { - TmpEntry = RemoveHeadList(&NotifyEntry->IrpQueue); - Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry); - - /* irp cancelation bolilerplate */ - if (!IoSetCancelRoutine(Irp, NULL)) - { - //The cancel routine will be called. When we release the lock it will complete the irp. - InitializeListHead(&Irp->Tail.Overlay.ListEntry); - continue; - } - - Irp->IoStatus.Status = STATUS_DELETE_PENDING; - Irp->IoStatus.Information = 0; - - /* avoid holding lock while completing irp */ - InsertTailList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry); - } - } - } - - ExReleaseFastMutex((PFAST_MUTEX)NotifySync); - - /* complete defered irps */ - while (!IsListEmpty(&CompletedListHead)) - { - TmpEntry = RemoveHeadList(&CompletedListHead); - Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } -} - -/*++ - * @name FsRtlNotifyFullChangeDirectory - * @unimplemented - * - * FILLME - * - * @param NotifySync - * FILLME - * - * @param NotifyList - * FILLME - * - * @param FsContext - * FILLME - * - * @param FullDirectoryName - * FILLME - * - * @param WatchTree - * FILLME - * - * @param IgnoreBuffer - * FILLME - * - * @param CompletionFilter - * FILLME - * - * @param Irp - * FILLME - * - * @param TraverseCallback - * FILLME - * - * @param SubjectContext - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlNotifyFullChangeDirectory(IN PNOTIFY_SYNC NotifySync, - IN PLIST_ENTRY NotifyList, - IN PVOID FsContext, - IN PSTRING FullDirectoryName, - IN BOOLEAN WatchTree, - IN BOOLEAN IgnoreBuffer, - IN ULONG CompletionFilter, - IN PIRP Irp, - IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, - IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL) -{ - PIO_STACK_LOCATION IrpStack; - PNOTIFY_ENTRY NotifyEntry; - ULONG IrpBuffLen; - - if (!Irp) - { - /* all other params are ignored if NotifyIrp == NULL */ - FsRtlpWatchedDirectoryWasDeleted(NotifySync, NotifyList, FsContext); - return; - } - - DPRINT("FullDirectoryName: %wZ\n", FullDirectoryName); - - ExAcquireFastMutex((PFAST_MUTEX)NotifySync); - - IrpStack = IoGetCurrentIrpStackLocation(Irp); - if (IrpStack->FileObject->Flags & FO_CLEANUP_COMPLETE) - { - ExReleaseFastMutex((PFAST_MUTEX)NotifySync); - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_NOTIFY_CLEANUP; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return; - } - - IrpBuffLen = IrpStack->Parameters.NotifyDirectory.Length; - - NotifyEntry = FsRtlpFindNotifyEntry(NotifyList, FsContext); - - if (!NotifyEntry) - { - /* No NotifyStruct for this FileObject existed */ - - /* The first request for this FileObject set the standards. - * For subsequent requests, these params will be ignored. - * Ref: Windows NT File System Internals page 516 - */ - - NotifyEntry = ExAllocateFromPagedLookasideList(&NotifyEntryLookaside); - - RtlZeroMemory(NotifyEntry, sizeof(NOTIFY_ENTRY)); - - NotifyEntry->FsContext = FsContext; - NotifyEntry->FullDirectoryName = FullDirectoryName; - NotifyEntry->WatchTree = WatchTree; - NotifyEntry->CompletionFilter = CompletionFilter; - NotifyEntry->TraverseCallback = TraverseCallback; - NotifyEntry->SubjectContext = SubjectContext; - NotifyEntry->Fcb = IrpStack->FileObject->FsContext; - NotifyEntry->Unicode = FsRtlpIsUnicodePath(FullDirectoryName); - - /* Init. buffer */ - if (IrpBuffLen && !IgnoreBuffer) - { - _SEH_TRY - { - NotifyEntry->Buffer = ExAllocatePoolWithQuotaTag( - PagedPool, - IrpBuffLen, - FSRTL_NOTIFY_TAG - ); - - NotifyEntry->BufferSize = IrpBuffLen; - } - _SEH_HANDLE - { - /* ExAllocatePoolWithQuotaTag raised exception but we dont care. - The impl. doesnt require a buffer, so well continue as usual. - */ - } - _SEH_END; - } - - InitializeListHead(&NotifyEntry->IrpQueue); - - InsertTailList(NotifyList, &NotifyEntry->ListEntry); - } - - - if (!NotifyEntry->PendingChanges) - { - /* No changes are pending. Queue the irp */ - - /* Irp cancelation boilerplate */ - - /* save NotifySych for use in the cancel routine */ - Irp->Tail.Overlay.DriverContext[3] = NotifySync; - - (void)IoSetCancelRoutine(Irp, FsRtlpNotifyCancelRoutine); - if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL)) - { - //irp was canceled - ExReleaseFastMutex((PFAST_MUTEX)NotifySync); - - Irp->IoStatus.Status = STATUS_CANCELLED; - Irp->IoStatus.Information = 0; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return; - } - - IoMarkIrpPending(Irp); - - //FIXME: any point in setting irp status/information before queueing? - Irp->IoStatus.Status = STATUS_PENDING; - - InsertTailList(&NotifyEntry->IrpQueue, &Irp->Tail.Overlay.ListEntry); - - ExReleaseFastMutex((PFAST_MUTEX)NotifySync); - return; - } - - - /* Pending changes exist */ - - if (NotifyEntry->Buffer == NULL || - NotifyEntry->BufferExhausted || - IrpBuffLen < NotifyEntry->NextEntryOffset) - { - /* - Can't return detailed changes to user cause: - -No buffer exist, OR - -Buffer were overflowed, OR - -Current irp buff was not large enough - */ - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_NOTIFY_ENUM_DIR; - - } - else - { - PVOID Adr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority); - - if (Adr) - { - memcpy(Adr, NotifyEntry->Buffer, NotifyEntry->NextEntryOffset); - Irp->IoStatus.Information = NotifyEntry->NextEntryOffset; - } - else - { - Irp->IoStatus.Information = 0; - } - - Irp->IoStatus.Status = STATUS_SUCCESS; - } - - /* reset buffer */ - NotifyEntry->PrevEntry = NULL; - NotifyEntry->NextEntryOffset = 0; - NotifyEntry->BufferExhausted = FALSE; - - NotifyEntry->PendingChanges = FALSE; - - ExReleaseFastMutex((PFAST_MUTEX)NotifySync); - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - /* caller must return STATUS_PENDING */ -} - -/*++ - * @name FsRtlpGetNextIrp - * - * FILLME - * - * @param NotifyEntry - * FILLME - * - * @return FILLME - * - * @remarks Private function - * - *--*/ -static -PIRP -FASTCALL -FsRtlpGetNextIrp(PNOTIFY_ENTRY NotifyEntry) -{ - PIRP Irp; - PLIST_ENTRY TmpEntry; - - /* Loop to get a non-canceled irp */ - while (!IsListEmpty(&NotifyEntry->IrpQueue)) - { - /* If we have queued irp(s) we can't possibly have pending changes too */ - ASSERT(!NotifyEntry->PendingChanges); - - TmpEntry = RemoveHeadList(&NotifyEntry->IrpQueue); - Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry); - - /* irp cancelation bolilerplate */ - if (!IoSetCancelRoutine(Irp, NULL)) - { - //The cancel routine will be called. When we release the lock it will complete the irp. - InitializeListHead(&Irp->Tail.Overlay.ListEntry); - continue; - } - - /* Finally we got a non-canceled irp */ - return Irp; - } - - return NULL; -} - -/*++ - * @name FsRtlpCopyName - * - * FILLME - * - * @param CurrentEntry - * FILLME - * - * @param Unicode - * FILLME - * - * @param RelativeName - * FILLME - * - * @param StreamName - * FILLME - * - * @return None - * - * @remarks Private function - * - *--*/ -static -__inline -VOID -FsRtlpCopyName(PFILE_NOTIFY_INFORMATION CurrentEntry, - BOOLEAN Unicode, - PSTRING RelativeName, - PSTRING StreamName) -{ - /* Buffer size is allready probed, so just copy the data */ - - if (Unicode) - { - memcpy(CurrentEntry->FileName, RelativeName->Buffer, RelativeName->Length); - if (StreamName) - { - CurrentEntry->FileName[RelativeName->Length/sizeof(WCHAR)] = ':'; - memcpy(&CurrentEntry->FileName[(RelativeName->Length/sizeof(WCHAR))+1], - StreamName->Buffer, - StreamName->Length); - } - } - else - { - //FIXME: convert to unicode etc. - DPRINT1("FIXME: ansi strings in notify impl. not supported yet\n"); - } -} - -/*++ - * @name FsRtlNotifyFullReportChange - * @unimplemented - * - * FILLME - * - * @param NotifySync - * FILLME - * - * @param NotifyList - * FILLME - * - * @param FullTargetName - * FILLME - * - * @param TargetNameOffset - * FILLME - * - * @param StreamName - * FILLME - * - * @param NormalizedParentName - * FILLME - * - * @param FilterMatch - * FILLME - * - * @param Action - * FILLME - * - * @param TargetContext - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlNotifyFullReportChange(IN PNOTIFY_SYNC NotifySync, - IN PLIST_ENTRY NotifyList, - IN PSTRING FullTargetName, /* can include short names! */ - IN USHORT TargetNameOffset, /* in bytes */ - IN PSTRING StreamName OPTIONAL, - IN PSTRING NormalizedParentName OPTIONAL, /* same as FullTargetName, but with long names */ - IN ULONG FilterMatch, - IN ULONG Action, - IN PVOID TargetContext) -{ - USHORT FullDirLen; - STRING RelativeName; - PNOTIFY_ENTRY NotifyEntry, tmp; - PLIST_ENTRY EnumEntry; - PIRP Irp; - LIST_ENTRY CompletedListHead; - USHORT NameLenU; - ULONG RecordLen; - PFILE_NOTIFY_INFORMATION CurrentEntry; - - InitializeListHead(&CompletedListHead); - - DPRINT("FullTargetName: %wZ\n", FullTargetName); - - /* - I think FullTargetName can include/be a short file name! What the heck do i do with this? - Dont think this apply to FsRtlNotifyFullChangeDirectory's FullDirectoryName. - */ - - ExAcquireFastMutex((PFAST_MUTEX)NotifySync); - - LIST_FOR_EACH_SAFE(NotifyEntry, tmp, NotifyList, NOTIFY_ENTRY, ListEntry ) - { - ASSERT(NotifyEntry->Unicode == FsRtlpIsUnicodePath(FullTargetName)); - - /* rule out some easy cases */ - /* FIXME: short vs. long names??? lower case/upper case/mixed case? */ - if (!(FilterMatch & NotifyEntry->CompletionFilter)) continue; - - FullDirLen = TargetNameOffset - (NotifyEntry->Unicode ? sizeof(WCHAR) : sizeof(char)); - if (FullDirLen == 0) - { - /* special case for root dir */ - FullDirLen = (NotifyEntry->Unicode ? sizeof(WCHAR) : sizeof(char)); - } - - if (FullDirLen < NotifyEntry->FullDirectoryName->Length) continue; - - if (!NotifyEntry->WatchTree && FullDirLen != NotifyEntry->FullDirectoryName->Length) continue; - - DPRINT("NotifyEntry->FullDirectoryName: %wZ\n", NotifyEntry->FullDirectoryName); - - /* FIXME: short vs. long names??? lower case/upper case/mixed case? */ - if (memcmp(NotifyEntry->FullDirectoryName->Buffer, - FullTargetName->Buffer, - NotifyEntry->FullDirectoryName->Length) != 0) continue; - - - if (NotifyEntry->WatchTree && - NotifyEntry->TraverseCallback && - FullDirLen != NotifyEntry->FullDirectoryName->Length) - { - /* change happend in a subdir. ask caller if we are allowed in here */ - NTSTATUS Status = NotifyEntry->TraverseCallback(NotifyEntry->FsContext, - TargetContext, - NotifyEntry->SubjectContext); - - if (!NT_SUCCESS(Status)) continue; - - /* - FIXME: notify-dir impl. should release and free the SubjectContext - */ - } - - DPRINT("Found match\n"); - - /* Found a valid change */ - - RelativeName.Buffer = FullTargetName->Buffer + TargetNameOffset; - RelativeName.MaximumLength = - RelativeName.Length = - FullTargetName->Length - TargetNameOffset; - - DPRINT("RelativeName: %wZ\n",&RelativeName); - - /* calculate unicode bytes of relative-name + stream-name */ - if (NotifyEntry->Unicode) - { - NameLenU = RelativeName.Length + (StreamName ? (StreamName->Length + sizeof(WCHAR)) : 0); - } - else - { - NameLenU = RelativeName.Length * sizeof(WCHAR) + - (StreamName ? ((StreamName->Length * sizeof(WCHAR)) + sizeof(WCHAR)) : 0); - } - - RecordLen = FIELD_OFFSET(FILE_NOTIFY_INFORMATION, FileName) + NameLenU; - - if ((Irp = FsRtlpGetNextIrp(NotifyEntry))) - { - PIO_STACK_LOCATION IrpStack; - ULONG IrpBuffLen; - - IrpStack = IoGetCurrentIrpStackLocation(Irp); - IrpBuffLen = IrpStack->Parameters.NotifyDirectory.Length; - - DPRINT("Got pending irp\n"); - - ASSERT(!NotifyEntry->PendingChanges); - - if (NotifyEntry->Buffer == NULL || /* aka. IgnoreBuffer */ - RecordLen > IrpBuffLen) - { - /* ignore buffer / buffer not large enough */ - Irp->IoStatus.Status = STATUS_NOTIFY_ENUM_DIR; - Irp->IoStatus.Information = 0; - } - else - { - CurrentEntry = (PFILE_NOTIFY_INFORMATION) - MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority); - - if (CurrentEntry) - { - CurrentEntry->Action = Action; - CurrentEntry->FileNameLength = NameLenU; - CurrentEntry->NextEntryOffset = 0; - - FsRtlpCopyName( - CurrentEntry, - NotifyEntry->Unicode, - &RelativeName, - StreamName - ); - - Irp->IoStatus.Information = RecordLen; - } - else - { - Irp->IoStatus.Information = 0; - } - - - Irp->IoStatus.Status = STATUS_SUCCESS; - } - - /* avoid holding lock while completing irp */ - InsertTailList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry); - } - else - { - DPRINT("No irp\n"); - - NotifyEntry->PendingChanges = TRUE; - - if (NotifyEntry->Buffer == NULL || NotifyEntry->BufferExhausted) continue; - - if (RecordLen > NotifyEntry->BufferSize - NotifyEntry->NextEntryOffset) - { - /* overflow. drop these changes and stop buffering any other changes too */ - NotifyEntry->BufferExhausted = TRUE; - continue; - } - - /* The buffer has enough room for the changes. - * Copy data to buffer. - */ - - CurrentEntry = (PFILE_NOTIFY_INFORMATION)NotifyEntry->Buffer; - - CurrentEntry->Action = Action; - CurrentEntry->FileNameLength = NameLenU; - CurrentEntry->NextEntryOffset = 0; - - FsRtlpCopyName(CurrentEntry, - NotifyEntry->Unicode, - &RelativeName, - StreamName - ); - - if (NotifyEntry->PrevEntry) - { - NotifyEntry->PrevEntry->NextEntryOffset = (char*)CurrentEntry - (char*)NotifyEntry->PrevEntry; - } - NotifyEntry->PrevEntry = CurrentEntry; - NotifyEntry->NextEntryOffset += RecordLen; - - // { - // UNICODE_STRING TmpStr; - // TmpStr.Buffer = BufferedChange->RelativeName; - // TmpStr.MaximumLength = TmpStr.Length = BufferedChange->NameLen; - // DPRINT("BufferedChange->RelativeName: %wZ\n", &TmpStr); - // } - - } - } - - ExReleaseFastMutex((PFAST_MUTEX)NotifySync); - - /* complete defered irps */ - while (!IsListEmpty(&CompletedListHead)) - { - EnumEntry = RemoveHeadList(&CompletedListHead); - Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry); - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } -} - -/*++ - * @name FsRtlNotifyInitializeSync - * @unimplemented - * - * FILLME - * - * @param NotifySync - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlNotifyInitializeSync(IN PNOTIFY_SYNC *NotifySync) -{ - *NotifySync = ExAllocatePoolWithTag(NonPagedPool, sizeof(FAST_MUTEX), FSRTL_NOTIFY_TAG ); - ExInitializeFastMutex((PFAST_MUTEX)*NotifySync); -} - -/*++ - * @name FsRtlNotifyReportChange - * @unimplemented - * - * FILLME - * - * @param NotifySync - * FILLME - * - * @param NotifyList - * FILLME - * - * @param FullTargetName - * FILLME - * - * @param FileNamePartLength - * FILLME - * - * @param FilterMatch - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlNotifyReportChange(IN PNOTIFY_SYNC NotifySync, - IN PLIST_ENTRY NotifyList, - IN PSTRING FullTargetName, - IN PUSHORT FileNamePartLength, - IN ULONG FilterMatch) -{ - FsRtlNotifyFullReportChange( - NotifySync, - NotifyList, - FullTargetName, - (FullTargetName->Length - *FileNamePartLength), - NULL, - NULL, - FilterMatch, - 0, - NULL - ); -} - -/*++ - * @name FsRtlCurrentBatchOplock - * @implemented - * - * Uninitialize a NOTIFY_SYNC object - * - * @param NotifySync - * Address of a pointer to a PNOTIFY_SYNC object previously - * initialized by FsRtlNotifyInitializeSync() - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync) -{ - ExFreePool(*NotifySync); -} - -/*++ - * @name FsRtlNotifyVolumeEvent - * @unimplemented - * - * FILLME - * - * @param FileObject - * FILLME - * - * @param EventCode - * FILLME - * - * @return None - * - * @remarks Only present in NT 5+. - * - *--*/ -NTSTATUS -NTAPI -FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject, - IN ULONG EventCode) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/*++ - * @name FsRtlRegisterFileSystemFilterCallbacks - * @unimplemented - * - * FILLME - * - * @param FilterDriverObject - * FILLME - * - * @param Callbacks - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -NTSTATUS -NTAPI -FsRtlRegisterFileSystemFilterCallbacks(IN PDRIVER_OBJECT FilterDriverObject, - IN PFS_FILTER_CALLBACKS Callbacks) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} -/* EOF */ diff --git a/reactos/ntoskrnl/fs/pool.c b/reactos/ntoskrnl/fs/pool.c deleted file mode 100644 index ffaf43ee7ed..00000000000 --- a/reactos/ntoskrnl/fs/pool.c +++ /dev/null @@ -1,173 +0,0 @@ -/* $Id$ - * - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/pool.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: No programmer listed. - */ - -/* INCLUDES *****************************************************************/ - -#include - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/*++ - * @name FsRtlAllocatePool - * @implemented - * - * FILLME - * - * @param PoolType - * FILLME - * - * @param NumberOfBytes - * FILLME - * - * @return None - * - * @remarks IFS_POOL_TAG is "FSrt" in mem view. - * - *--*/ -PVOID -NTAPI -FsRtlAllocatePool(IN POOL_TYPE PoolType, - IN ULONG NumberOfBytes) -{ - PVOID Address; - - Address = ExAllocatePoolWithTag(PoolType, - NumberOfBytes, - IFS_POOL_TAG); - - if (NULL == Address) - { - ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); - } - - return Address; -} - -/*++ - * @name FsRtlAllocatePoolWithQuota - * @implemented - * - * FILLME - * - * @param PoolType - * FILLME - * - * @param NumberOfBytes - * FILLME - * - * @return None - * - * @remarks IFS_POOL_TAG is "FSrt" in mem view. - * - *--*/ -PVOID -NTAPI -FsRtlAllocatePoolWithQuota(IN POOL_TYPE PoolType, - IN ULONG NumberOfBytes) -{ - PVOID Address; - - Address = ExAllocatePoolWithQuotaTag(PoolType, - NumberOfBytes, - IFS_POOL_TAG); - if (NULL == Address) - { - ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); - } - return Address; -} - -/*++ - * @name FsRtlAllocatePoolWithQuotaTag - * @implemented - * - * FILLME - * - * @param PoolType - * FILLME - * - * @param NumberOfBytes - * FILLME - * - * @param Tag - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -#undef FsRtlAllocatePoolWithQuotaTag -PVOID -NTAPI -FsRtlAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, - IN ULONG NumberOfBytes, - IN ULONG Tag) -{ - PVOID Address; - - Address = ExAllocatePoolWithQuotaTag(PoolType, - NumberOfBytes, - Tag); - - if (NULL == Address) - { - ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); - } - - return Address; -} - -/*++ - * @name FsRtlAllocatePoolWithTag - * @implemented - * - * FILLME - * - * @param PoolType - * FILLME - * - * @param NumberOfBytes - * FILLME - * - * @param Tag - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -#undef FsRtlAllocatePoolWithTag -PVOID -NTAPI -FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, - IN ULONG NumberOfBytes, - IN ULONG Tag) -{ - PVOID Address; - - Address = ExAllocatePoolWithTag(PoolType, - NumberOfBytes, - Tag); - - if (NULL == Address) - { - ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); - } - - return Address; -} - - -/* EOF */ diff --git a/reactos/ntoskrnl/fs/util.c b/reactos/ntoskrnl/fs/util.c deleted file mode 100644 index 58853bef3c5..00000000000 --- a/reactos/ntoskrnl/fs/util.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/util.c - * PURPOSE: Misc Utility Functions for File System Drivers - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Emanuele Aliberti - */ - -/* INCLUDES *****************************************************************/ - -#include - -#define NDEBUG -#include - -#define FSRTL_MAX_RESOURCES 16 - -#define FTTYPE ((ULONG)'f') -#define FT_BALANCED_READ_MODE \ - CTL_CODE(FTTYPE, 6, METHOD_NEITHER, FILE_ANY_ACCESS) - -/* GLOBALS *******************************************************************/ - -BOOLEAN STDCALL MmIsFileAPagingFile(PFILE_OBJECT FileObject); -VOID NTAPI INIT_FUNCTION RtlpInitializeResources(VOID); -static ULONG FsRtlpAllocatedResources = 0; -static PERESOURCE FsRtlpResources; - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, RtlpInitializeResources) -#endif - -/* PRIVATE FUNCTIONS**********************************************************/ - -VOID -NTAPI -INIT_FUNCTION -RtlpInitializeResources(VOID) -{ - ULONG i; - - /* Allocate the Resource Buffer */ - FsRtlpResources = FsRtlAllocatePoolWithTag(NonPagedPool, - FSRTL_MAX_RESOURCES * - sizeof(ERESOURCE), - TAG('F', 's', 'R', 'e')); - - /* Initialize the Resources */ - for (i = 0; i < FSRTL_MAX_RESOURCES; i++) - { - ExInitializeResource(&FsRtlpResources[i]); - } -} - -/* FUNCTIONS *****************************************************************/ - -/*++ - * @name FsRtlIsTotalDeviceFailure - * @implemented NT 4.0 - * - * The FsRtlIsTotalDeviceFailure routine checks if an NTSTATUS error code - * represents a disk hardware failure. - * - * @param NtStatus - * The NTSTATUS Code to Test - * - * @return TRUE in case of Hardware Failure, FALSE otherwise. - * - * @remarks None. - * - *--*/ -BOOLEAN -NTAPI -FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus) -{ - return((NT_SUCCESS(NtStatus)) || - (STATUS_CRC_ERROR == NtStatus) || - (STATUS_DEVICE_DATA_ERROR == NtStatus) ? FALSE : TRUE); -} - -/*++ - * @name FsRtlIsNtstatusExpected - * @implemented NT 4.0 - * - * The FsRtlIsNtstatusExpected routine checks if an NTSTATUS error code - * is expected by the File System Support Library. - * - * @param NtStatus - * The NTSTATUS Code to Test - * - * @return TRUE if the Value is Expected, FALSE otherwise. - * - * @remarks None. - * - *--*/ -BOOLEAN -NTAPI -FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus) -{ - return((STATUS_DATATYPE_MISALIGNMENT == NtStatus) || - (STATUS_ACCESS_VIOLATION == NtStatus) || - (STATUS_ILLEGAL_INSTRUCTION == NtStatus) || - (STATUS_INSTRUCTION_MISALIGNMENT == NtStatus)) ? FALSE : TRUE; -} - -/*++ - * @name FsRtlIsPagingFile - * @implemented NT 4.0 - * - * The FsRtlIsPagingFile routine checks if the FileObject is a Paging File. - * - * @param FileObject - * A pointer to the File Object to be tested. - * - * @return TRUE if the File is a Paging File, FALSE otherwise. - * - * @remarks None. - * - *--*/ -LOGICAL -NTAPI -FsRtlIsPagingFile(IN PFILE_OBJECT FileObject) -{ - return MmIsFileAPagingFile(FileObject); -} - -/*++ - * @name FsRtlNormalizeNtstatus - * @implemented NT 4.0 - * - * The FsRtlNormalizeNtstatus routine normalizes an NTSTATUS error code. - * - * @param NtStatusToNormalize - * The NTSTATUS error code to Normalize. - * - * @param NormalizedNtStatus - * The NTSTATUS error code to return if the NtStatusToNormalize is not - * a proper expected error code by the File System Library. - * - * @return NtStatusToNormalize if it is an expected value, otherwise - * NormalizedNtStatus. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -FsRtlNormalizeNtstatus(IN NTSTATUS NtStatusToNormalize, - IN NTSTATUS NormalizedNtStatus) -{ - return(TRUE == FsRtlIsNtstatusExpected(NtStatusToNormalize)) ? - NtStatusToNormalize : NormalizedNtStatus; -} - -/*++ - * @name FsRtlAllocateResource - * @implemented NT 4.0 - * - * The FsRtlAllocateResource routine returns a pre-initialized ERESOURCE - * for use by a File System Driver. - * - * @return A Pointer to a pre-initialized ERESOURCE. - * - * @remarks The File System Library only provides up to 16 Resources. - * - *--*/ -PERESOURCE -NTAPI -FsRtlAllocateResource(VOID) -{ - /* Return a pre-allocated ERESOURCE */ - return &FsRtlpResources[FsRtlpAllocatedResources++ & FSRTL_MAX_RESOURCES]; -} - -/*++ - * @name FsRtlBalanceReads - * @implemented NT 4.0 - * - * The FsRtlBalanceReads routine sends an IRP to an FTDISK Driver - * requesting the driver to balance read requests across a mirror set. - * - * @param TargetDevice - * A pointer to an FTDISK Device Object. - * - * @return The NTSTATUS error code returned by the FTDISK Driver. - * - * @remarks FTDISK is a Software RAID Implementation. - * - *--*/ -NTSTATUS -NTAPI -FsRtlBalanceReads(PDEVICE_OBJECT TargetDevice) -{ - PIRP Irp; - KEVENT Event; - IO_STATUS_BLOCK IoStatusBlock; - NTSTATUS Status; - - /* Initialize the Local Event */ - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - /* Build the special IOCTL */ - Irp = IoBuildDeviceIoControlRequest(FT_BALANCED_READ_MODE, - TargetDevice, - NULL, - 0, - NULL, - 0, - FALSE, - &Event, - &IoStatusBlock); - - /* Send it */ - Status = IoCallDriver(TargetDevice, Irp); - - /* Wait if needed */ - if (Status == STATUS_PENDING) - { - Status = KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); - /* Return Status */ - Status = IoStatusBlock.Status; - } - - return Status; -} - -/*++ - * @name FsRtlPostPagingFileStackOverflow - * @unimplemented NT 4.0 - * - * The FsRtlPostPagingFileStackOverflow routine - * - * @param Context - * - * @param Event - * - * @param StackOverflowRoutine - * - * @return - * - * @remarks None. - * - *--*/ -VOID -NTAPI -FsRtlPostPagingFileStackOverflow(IN PVOID Context, - IN PKEVENT Event, - IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine) -{ - UNIMPLEMENTED; -} - -/*++ - * @name FsRtlPostStackOverflow - * @unimplemented NT 4.0 - * - * The FsRtlPostStackOverflow routine - * - * @param Context - * - * @param Event - * - * @param StackOverflowRoutine - * - * @return - * - * @remarks None. - * - *--*/ -VOID -NTAPI -FsRtlPostStackOverflow(IN PVOID Context, - IN PKEVENT Event, - IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine) -{ - UNIMPLEMENTED; -} - -/*++ - * @name FsRtlSyncVolumes - * @implemented NT 4.0 - * - * The FsRtlSyncVolumes routine is deprecated. - * - * @return Always returns STATUS_SUCCESS. - * - * @remarks Deprecated. - * - *--*/ -NTSTATUS -NTAPI -FsRtlSyncVolumes(ULONG Unknown0, - ULONG Unknown1, - ULONG Unknown2) -{ - return STATUS_SUCCESS; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/fsrtl/dbcsname.c b/reactos/ntoskrnl/fsrtl/dbcsname.c new file mode 100644 index 00000000000..34d016cd9c1 --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/dbcsname.c @@ -0,0 +1,182 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/name.c + * PURPOSE: Provides DBCS parsing and other support routines for FSDs + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlDissectDbcs + * @implemented + * + * Dissects a given path name into first and remaining part. + * + * @param Name + * ANSI string to dissect. + * + * @param FirstPart + * Pointer to user supplied ANSI_STRING, that will later point + * to the first part of the original name. + * + * @param RemainingPart + * Pointer to user supplied ANSI_STRING, that will later point + * to the remaining part of the original name. + * + * @return None + * + * @remarks Example: + * Name: \test1\test2\test3 + * FirstPart: test1 + * RemainingPart: test2\test3 + * + *--*/ +VOID +NTAPI +FsRtlDissectDbcs(IN ANSI_STRING Name, + OUT PANSI_STRING FirstPart, + OUT PANSI_STRING RemainingPart) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlDoesDbcsContainWildCards + * @implemented + * + * FILLME + * + * @param Name + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +BOOLEAN +NTAPI +FsRtlDoesDbcsContainWildCards(IN PANSI_STRING Name) +{ + ULONG i; + + /* Check every character */ + for (i = 0; i < Name->Length; i++) + { + /* First make sure it's not the Lead DBCS */ + if (FsRtlIsLeadDbcsCharacter(Name->Buffer[i])) + { + i++; + } + else if (FsRtlIsAnsiCharacterWild(Name->Buffer[i])) + { + /* Now return if it has a wildcard */ + return TRUE; + } + } + + /* We didn't return above...so none found */ + return FALSE; +} + +/*++ + * @name FsRtlIsDbcsInExpression + * @unimplemented + * + * FILLME + * + * @param Expression + * FILLME + * + * @param Name + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +BOOLEAN +NTAPI +FsRtlIsDbcsInExpression(IN PANSI_STRING Expression, + IN PANSI_STRING Name) +{ + KEBUGCHECK(0); + return FALSE; +} + +/*++ + * @name FsRtlIsFatDbcsLegal + * @unimplemented + * + * FILLME + * + * @param DbcsName + * FILLME + * + * @param WildCardsPermissible + * FILLME + * + * @param PathNamePermissible + * FILLME + * + * @param LeadingBackslashPermissible + * FILLME + * + * @return TRUE if the DbcsName is legal, FALSE otherwise + * + * @remarks None + * + *--*/ +BOOLEAN +NTAPI +FsRtlIsFatDbcsLegal(IN ANSI_STRING DbcsName, + IN BOOLEAN WildCardsPermissible, + IN BOOLEAN PathNamePermissible, + IN BOOLEAN LeadingBackslashPermissible) +{ + KEBUGCHECK(0); + return FALSE; +} + +/*++ + * @name FsRtlIsHpfsDbcsLegal + * @unimplemented + * + * FILLME + * + * @param DbcsName + * FILLME + * + * @param WildCardsPermissible + * FILLME + * + * @param PathNamePermissible + * FILLME + * + * @param LeadingBackslashPermissible + * FILLME + * + * @return TRUE if the DbcsName is legal, FALSE otherwise + * + * @remarks None + * + *--*/ +BOOLEAN +STDCALL +FsRtlIsHpfsDbcsLegal(IN ANSI_STRING DbcsName, + IN BOOLEAN WildCardsPermissible, + IN BOOLEAN PathNamePermissible, + IN BOOLEAN LeadingBackslashPermissible) +{ + KEBUGCHECK(0); + return FALSE; +} diff --git a/reactos/ntoskrnl/fsrtl/fastio.c b/reactos/ntoskrnl/fsrtl/fastio.c new file mode 100644 index 00000000000..a4b2dfabd93 --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/fastio.c @@ -0,0 +1,268 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/fastio.c + * PURPOSE: Provides Fast I/O entrypoints to the Cache Manager + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +VOID +NTAPI +FsRtlIncrementCcFastReadResourceMiss(VOID) +{ + CcFastReadResourceMiss++; +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlIncrementCcFastReadNotPossible(VOID) +{ + CcFastReadNotPossible++; +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlIncrementCcFastReadWait(VOID) +{ + CcFastReadWait++; +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlIncrementCcFastReadNoWait(VOID) +{ + CcFastReadNoWait++; +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +FsRtlCopyRead(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +FsRtlCopyWrite(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +FsRtlGetFileSize(IN PFILE_OBJECT FileObject, + IN OUT PLARGE_INTEGER FileSize) +{ + KEBUGCHECK(0); + return STATUS_UNSUCCESSFUL; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlMdlRead(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject, + IN OUT PMDL MdlChain) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, + IN PMDL MdlChain, + IN PDEVICE_OBJECT DeviceObject) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlMdlReadDev(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlMdlWriteComplete(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlMdlWriteCompleteDev(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain, + IN PDEVICE_OBJECT DeviceObject) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlPrepareMdlWrite(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* +* @implemented +*/ +VOID +NTAPI +FsRtlAcquireFileExclusive(IN PFILE_OBJECT FileObject) +{ + KEBUGCHECK(0); +} + +/* +* @implemented +*/ +VOID +NTAPI +FsRtlReleaseFile(IN PFILE_OBJECT FileObject) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlRegisterFileSystemFilterCallbacks + * @unimplemented + * + * FILLME + * + * @param FilterDriverObject + * FILLME + * + * @param Callbacks + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +NTSTATUS +NTAPI +FsRtlRegisterFileSystemFilterCallbacks(IN PDRIVER_OBJECT FilterDriverObject, + IN PFS_FILTER_CALLBACKS Callbacks) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + diff --git a/reactos/ntoskrnl/fsrtl/faulttol.c b/reactos/ntoskrnl/fsrtl/faulttol.c new file mode 100644 index 00000000000..0aceba8c869 --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/faulttol.c @@ -0,0 +1,94 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/faulttol.c + * PURPOSE: Provides Fault Tolerance support for File System Drivers + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#include "ntddft.h" +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlBalanceReads + * @implemented NT 4.0 + * + * The FsRtlBalanceReads routine sends an IRP to an FTDISK Driver + * requesting the driver to balance read requests across a mirror set. + * + * @param TargetDevice + * A pointer to an FTDISK Device Object. + * + * @return The NTSTATUS error code returned by the FTDISK Driver. + * + * @remarks FTDISK is a Software RAID Implementation. + * + *--*/ +NTSTATUS +NTAPI +FsRtlBalanceReads(PDEVICE_OBJECT TargetDevice) +{ + PIRP Irp; + KEVENT Event; + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; + + /* Initialize the Local Event */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + /* Build the special IOCTL */ + Irp = IoBuildDeviceIoControlRequest(FT_BALANCED_READ_MODE, + TargetDevice, + NULL, + 0, + NULL, + 0, + FALSE, + &Event, + &IoStatusBlock); + + /* Send it */ + Status = IoCallDriver(TargetDevice, Irp); + + /* Wait if needed */ + if (Status == STATUS_PENDING) + { + Status = KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + /* Return Status */ + Status = IoStatusBlock.Status; + } + + /* Return the status */ + return Status; +} + +/*++ + * @name FsRtlSyncVolumes + * @implemented NT 4.0 + * + * The FsRtlSyncVolumes routine is deprecated. + * + * @return Always returns STATUS_SUCCESS. + * + * @remarks Deprecated. + * + *--*/ +NTSTATUS +NTAPI +FsRtlSyncVolumes(ULONG Unknown0, + ULONG Unknown1, + ULONG Unknown2) +{ + /* Always return success */ + return STATUS_SUCCESS; +} diff --git a/reactos/ntoskrnl/fsrtl/filelock.c b/reactos/ntoskrnl/fsrtl/filelock.c new file mode 100644 index 00000000000..71360cc0b46 --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/filelock.c @@ -0,0 +1,367 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/filelock.c + * PURPOSE: File Locking implementation for File System Drivers + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +PAGED_LOOKASIDE_LIST FsRtlFileLockLookasideList; + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +FsRtlCompleteLockIrpReal(IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteRoutine, + IN PVOID Context, + IN PIRP Irp, + IN NTSTATUS Status, + OUT PNTSTATUS NewStatus, + IN PFILE_OBJECT FileObject OPTIONAL) +{ + /* Check if we have a complete routine */ + if (CompleteRoutine) + { + /* Check if we have a file object */ + if (FileObject) FileObject->LastLock = NULL; + + /* Set the I/O Status and do completion */ + Irp->IoStatus.Status = Status; + *NewStatus = CompleteRoutine(Context, Irp); + } + else + { + /* Otherwise do a normal I/O complete request */ + FsRtlCompleteRequest(Irp, Status); + *NewStatus = Status; + } +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +PFILE_LOCK_INFO +NTAPI +FsRtlGetNextFileLock(IN PFILE_LOCK FileLock, + IN BOOLEAN Restart) +{ + KEBUGCHECK(0); + return NULL; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlPrivateLock(IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS Process, + IN ULONG Key, + IN BOOLEAN FailImmediately, + IN BOOLEAN ExclusiveLock, + OUT PIO_STATUS_BLOCK IoStatus, + IN PIRP Irp OPTIONAL, + IN PVOID Context OPTIONAL, + IN BOOLEAN AlreadySynchronized) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, + IN PIRP Irp) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, + IN PIRP Irp) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlFastCheckLockForRead(IN PFILE_LOCK FileLock, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN ULONG Key, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN ULONG Key, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS Process, + IN ULONG Key, + IN PVOID Context OPTIONAL, + IN BOOLEAN AlreadySynchronized) +{ + KEBUGCHECK(0); + return STATUS_UNSUCCESSFUL; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process, + IN PVOID Context OPTIONAL) +{ + KEBUGCHECK(0); + return STATUS_UNSUCCESSFUL; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +FsRtlFastUnlockAllByKey(IN PFILE_LOCK FileLock, + IN PFILE_OBJECT FileObject, + IN PEPROCESS Process, + IN ULONG Key, + IN PVOID Context OPTIONAL) +{ + KEBUGCHECK(0); + return STATUS_UNSUCCESSFUL; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +FsRtlProcessFileLock(IN PFILE_LOCK FileLock, + IN PIRP Irp, + IN PVOID Context OPTIONAL) +{ + PIO_STACK_LOCATION IoStackLocation; + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + + /* Get the I/O Stack location */ + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + ASSERT(IoStackLocation->MajorFunction == IRP_MJ_LOCK_CONTROL); + + /* Clear the I/O status block and check what function this is */ + IoStatusBlock.Information = 0; + switch(IoStackLocation->MinorFunction) + { + /* A lock */ + case IRP_MN_LOCK: + + /* Call the private lock routine */ + FsRtlPrivateLock(FileLock, + IoStackLocation->FileObject, + &IoStackLocation-> + Parameters.LockControl.ByteOffset, + IoStackLocation->Parameters.LockControl.Length, + IoGetRequestorProcess(Irp), + IoStackLocation->Parameters.LockControl.Key, + IoStackLocation->Flags & SL_FAIL_IMMEDIATELY, + IoStackLocation->Flags & SL_EXCLUSIVE_LOCK, + &IoStatusBlock, + Irp, + Context, + FALSE); + break; + + /* A single unlock */ + case IRP_MN_UNLOCK_SINGLE: + + /* Call fast unlock */ + IoStatusBlock.Status = + FsRtlFastUnlockSingle(FileLock, + IoStackLocation->FileObject, + &IoStackLocation->Parameters.LockControl. + ByteOffset, + IoStackLocation->Parameters.LockControl. + Length, + IoGetRequestorProcess(Irp), + IoStackLocation->Parameters.LockControl. + Key, + Context, + FALSE); + + /* Complete the IRP */ + FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, + Context, + Irp, + IoStatusBlock.Status, + &Status, + NULL); + break; + + /* Total unlock */ + case IRP_MN_UNLOCK_ALL: + + /* Do a fast unlock */ + IoStatusBlock.Status = FsRtlFastUnlockAll(FileLock, + IoStackLocation-> + FileObject, + IoGetRequestorProcess(Irp), + Context); + + /* Complete the IRP */ + FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, + Context, + Irp, + IoStatusBlock.Status, + &Status, + NULL); + break; + + /* Unlock by key */ + case IRP_MN_UNLOCK_ALL_BY_KEY: + + /* Do it */ + IoStatusBlock.Status = + FsRtlFastUnlockAllByKey(FileLock, + IoStackLocation->FileObject, + IoGetRequestorProcess(Irp), + IoStackLocation->Parameters. + LockControl.Key, + Context); + + /* Complete the IRP */ + FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, + Context, + Irp, + IoStatusBlock.Status, + &Status, + NULL); + break; + + /* Invalid request */ + default: + + /* Complete it */ + FsRtlCompleteRequest(Irp, STATUS_INVALID_DEVICE_REQUEST); + IoStatusBlock.Status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + /* Return the status */ + return IoStatusBlock.Status; +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlInitializeFileLock (IN PFILE_LOCK FileLock, + IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, + IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL) +{ + /* Setup the lock */ + FileLock->FastIoIsQuestionable = FALSE; + FileLock->CompleteLockIrpRoutine = CompleteLockIrpRoutine; + FileLock->UnlockRoutine = UnlockRoutine; + FileLock->LockInformation = NULL; +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock) +{ + return; +} + +/* + * @implemented + */ +PFILE_LOCK +NTAPI +FsRtlAllocateFileLock(IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, + IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL) +{ + PFILE_LOCK FileLock; + + /* Try to allocate it */ + FileLock = ExAllocateFromPagedLookasideList(&FsRtlFileLockLookasideList); + if (FileLock) + { + /* Initialize it */ + FsRtlInitializeFileLock(FileLock, + CompleteLockIrpRoutine, + UnlockRoutine); + } + + /* Return the lock */ + return FileLock; +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlFreeFileLock(IN PFILE_LOCK FileLock) +{ + /* Uninitialize and free the lock */ + FsRtlUninitializeFileLock(FileLock); + ExFreeToPagedLookasideList(&FsRtlFileLockLookasideList, FileLock); +} + diff --git a/reactos/ntoskrnl/fsrtl/filter.c b/reactos/ntoskrnl/fsrtl/filter.c new file mode 100644 index 00000000000..9d8ca0df49c --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/filter.c @@ -0,0 +1,246 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/filter.c + * PURPOSE: Provides support for usage of SEH inside File System Drivers + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +#undef FsRtlAllocatePoolWithQuotaTag +#undef FsRtlAllocatePoolWithTag + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlIsTotalDeviceFailure + * @implemented NT 4.0 + * + * The FsRtlIsTotalDeviceFailure routine checks if an NTSTATUS error code + * represents a disk hardware failure. + * + * @param NtStatus + * The NTSTATUS Code to Test + * + * @return TRUE in case of Hardware Failure, FALSE otherwise. + * + * @remarks None. + * + *--*/ +BOOLEAN +NTAPI +FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus) +{ + return((NT_SUCCESS(NtStatus)) || + (STATUS_CRC_ERROR == NtStatus) || + (STATUS_DEVICE_DATA_ERROR == NtStatus) ? FALSE : TRUE); +} + +/*++ + * @name FsRtlIsNtstatusExpected + * @implemented NT 4.0 + * + * The FsRtlIsNtstatusExpected routine checks if an NTSTATUS error code + * is expected by the File System Support Library. + * + * @param NtStatus + * The NTSTATUS Code to Test + * + * @return TRUE if the Value is Expected, FALSE otherwise. + * + * @remarks None. + * + *--*/ +BOOLEAN +NTAPI +FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus) +{ + return((STATUS_DATATYPE_MISALIGNMENT == NtStatus) || + (STATUS_ACCESS_VIOLATION == NtStatus) || + (STATUS_ILLEGAL_INSTRUCTION == NtStatus) || + (STATUS_INSTRUCTION_MISALIGNMENT == NtStatus)) ? FALSE : TRUE; +} + +/*++ + * @name FsRtlNormalizeNtstatus + * @implemented NT 4.0 + * + * The FsRtlNormalizeNtstatus routine normalizes an NTSTATUS error code. + * + * @param NtStatusToNormalize + * The NTSTATUS error code to Normalize. + * + * @param NormalizedNtStatus + * The NTSTATUS error code to return if the NtStatusToNormalize is not + * a proper expected error code by the File System Library. + * + * @return NtStatusToNormalize if it is an expected value, otherwise + * NormalizedNtStatus. + * + * @remarks None. + * + *--*/ +NTSTATUS +NTAPI +FsRtlNormalizeNtstatus(IN NTSTATUS NtStatusToNormalize, + IN NTSTATUS NormalizedNtStatus) +{ + return(TRUE == FsRtlIsNtstatusExpected(NtStatusToNormalize)) ? + NtStatusToNormalize : NormalizedNtStatus; +} + +/*++ + * @name FsRtlAllocatePool + * @implemented + * + * FILLME + * + * @param PoolType + * FILLME + * + * @param NumberOfBytes + * FILLME + * + * @return None + * + * @remarks The pool tag used is "FSrt". + * + *--*/ +PVOID +NTAPI +FsRtlAllocatePool(IN POOL_TYPE PoolType, + IN ULONG NumberOfBytes) +{ + PVOID Address; + + Address = ExAllocatePoolWithTag(PoolType, + NumberOfBytes, + IFS_POOL_TAG); + + if (NULL == Address) + { + ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); + } + + return Address; +} + +/*++ + * @name FsRtlAllocatePoolWithQuota + * @implemented + * + * FILLME + * + * @param PoolType + * FILLME + * + * @param NumberOfBytes + * FILLME + * + * @return None + * + * @remarks The pool tag used is "FSrt". + * + *--*/ +PVOID +NTAPI +FsRtlAllocatePoolWithQuota(IN POOL_TYPE PoolType, + IN ULONG NumberOfBytes) +{ + PVOID Address; + + Address = ExAllocatePoolWithQuotaTag(PoolType, + NumberOfBytes, + IFS_POOL_TAG); + if (NULL == Address) + { + ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); + } + return Address; +} + +/*++ + * @name FsRtlAllocatePoolWithQuotaTag + * @implemented + * + * FILLME + * + * @param PoolType + * FILLME + * + * @param NumberOfBytes + * FILLME + * + * @param Tag + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +PVOID +NTAPI +FsRtlAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, + IN ULONG NumberOfBytes, + IN ULONG Tag) +{ + PVOID Address; + + Address = ExAllocatePoolWithQuotaTag(PoolType, + NumberOfBytes, + Tag); + + if (NULL == Address) + { + ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); + } + + return Address; +} + +/*++ + * @name FsRtlAllocatePoolWithTag + * @implemented + * + * FILLME + * + * @param PoolType + * FILLME + * + * @param NumberOfBytes + * FILLME + * + * @param Tag + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +PVOID +NTAPI +FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, + IN ULONG NumberOfBytes, + IN ULONG Tag) +{ + PVOID Address; + + Address = ExAllocatePoolWithTag(PoolType, + NumberOfBytes, + Tag); + + if (NULL == Address) + { + ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); + } + + return Address; +} + diff --git a/reactos/ntoskrnl/fsrtl/filtrctx.c b/reactos/ntoskrnl/fsrtl/filtrctx.c new file mode 100644 index 00000000000..7ce96f4fafd --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/filtrctx.c @@ -0,0 +1,124 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/filtrctx.c + * PURPOSE: File Stream Filter Context support for File System Drivers + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlIsPagingFile + * @implemented NT 4.0 + * + * The FsRtlIsPagingFile routine checks if the FileObject is a Paging File. + * + * @param FileObject + * A pointer to the File Object to be tested. + * + * @return TRUE if the File is a Paging File, FALSE otherwise. + * + * @remarks None. + * + *--*/ +LOGICAL +NTAPI +FsRtlIsPagingFile(IN PFILE_OBJECT FileObject) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @unimplemented + */ +PFSRTL_PER_STREAM_CONTEXT +NTAPI +FsRtlLookupPerStreamContextInternal(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, + IN PVOID OwnerId OPTIONAL, + IN PVOID InstanceId OPTIONAL) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @unimplemented + */ +PFSRTL_PER_FILEOBJECT_CONTEXT +NTAPI +FsRtlLookupPerFileObjectContext(IN PFILE_OBJECT FileObject, + IN PVOID OwnerId OPTIONAL, + IN PVOID InstanceId OPTIONAL) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +FsRtlInsertPerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER PerStreamContext, + IN PFSRTL_PER_STREAM_CONTEXT Ptr) +{ + KEBUGCHECK(0); + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +PFSRTL_PER_STREAM_CONTEXT +NTAPI +FsRtlRemovePerStreamContext(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, + IN PVOID OwnerId OPTIONAL, + IN PVOID InstanceId OPTIONAL) +{ + KEBUGCHECK(0); + return NULL; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +FsRtlInsertPerFileObjectContext(IN PFILE_OBJECT FileObject, + IN PFSRTL_PER_FILEOBJECT_CONTEXT Ptr) +{ + KEBUGCHECK(0); + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +PFSRTL_PER_FILEOBJECT_CONTEXT +NTAPI +FsRtlRemovePerFileObjectContext(IN PFILE_OBJECT PerFileObjectContext, + IN PVOID OwnerId OPTIONAL, + IN PVOID InstanceId OPTIONAL) +{ + KEBUGCHECK(0); + return NULL; +} + +/* + * @unimplemented + */ +VOID +NTAPI +FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvancedHeader) +{ + KEBUGCHECK(0); +} + diff --git a/reactos/ntoskrnl/fsrtl/fsfilter.c b/reactos/ntoskrnl/fsrtl/fsfilter.c new file mode 100644 index 00000000000..378c816fa8e --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/fsfilter.c @@ -0,0 +1,75 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/fsfilter.c + * PURPOSE: Provides support for the Filter Manager + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlCreateSectionForDataScan + * @unimplemented + * + * FILLME + * + * @param SectionHandle + * FILLME + * + * @param SectionObject + * FILLME + * + * @param SectionFileSize + * FILLME + * + * @param FileObject + * FILLME + * + * @param DesiredAccess + * FILLME + * + * @param ObjectAttributes + * FILLME + * + * @param MaximumSize + * FILLME + * + * @param SectionPageProtection + * FILLME + * + * @param AllocationAttributes + * FILLME + * + * @param Flags + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +NTSTATUS +NTAPI +FsRtlCreateSectionForDataScan(OUT PHANDLE SectionHandle, + OUT PVOID *SectionObject, + OUT PLARGE_INTEGER SectionFileSize OPTIONAL, + IN PFILE_OBJECT FileObject, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLARGE_INTEGER MaximumSize OPTIONAL, + IN ULONG SectionPageProtection, + IN ULONG AllocationAttributes, + IN ULONG Flags) +{ + /* Unimplemented */ + KEBUGCHECK(0); + return STATUS_NOT_IMPLEMENTED; +} + diff --git a/reactos/ntoskrnl/fsrtl/fsrtlpc.c b/reactos/ntoskrnl/fsrtl/fsrtlpc.c new file mode 100644 index 00000000000..1fdd15aadc5 --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/fsrtlpc.c @@ -0,0 +1,208 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/fsrtlpc.c + * PURPOSE: Contains initialization and support code for the FsRtl + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +PERESOURCE FsRtlPagingIoResources; +ULONG FsRtlPagingIoResourceSelector; + +static UCHAR LegalAnsiCharacterArray[] = +{ + 0, /* CTRL+@, 0x00 */ + 0, /* CTRL+A, 0x01 */ + 0, /* CTRL+B, 0x02 */ + 0, /* CTRL+C, 0x03 */ + 0, /* CTRL+D, 0x04 */ + 0, /* CTRL+E, 0x05 */ + 0, /* CTRL+F, 0x06 */ + 0, /* CTRL+G, 0x07 */ + 0, /* CTRL+H, 0x08 */ + 0, /* CTRL+I, 0x09 */ + 0, /* CTRL+J, 0x0a */ + 0, /* CTRL+K, 0x0b */ + 0, /* CTRL+L, 0x0c */ + 0, /* CTRL+M, 0x0d */ + 0, /* CTRL+N, 0x0e */ + 0, /* CTRL+O, 0x0f */ + 0, /* CTRL+P, 0x10 */ + 0, /* CTRL+Q, 0x11 */ + 0, /* CTRL+R, 0x12 */ + 0, /* CTRL+S, 0x13 */ + 0, /* CTRL+T, 0x14 */ + 0, /* CTRL+U, 0x15 */ + 0, /* CTRL+V, 0x16 */ + 0, /* CTRL+W, 0x17 */ + 0, /* CTRL+X, 0x18 */ + 0, /* CTRL+Y, 0x19 */ + 0, /* CTRL+Z, 0x1a */ + 0, /* CTRL+[, 0x1b */ + 0, /* CTRL+\, 0x1c */ + 0, /* CTRL+], 0x1d */ + 0, /* CTRL+^, 0x1e */ + 0, /* CTRL+_, 0x1f */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* ` ', 0x20 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `!', 0x21 */ + FSRTL_WILD_CHARACTER, /* `"', 0x22 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `#', 0x23 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `$', 0x24 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `%', 0x25 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `&', 0x26 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `'', 0x27 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `(', 0x28 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `)', 0x29 */ + FSRTL_WILD_CHARACTER, /* `*', 0x2a */ + FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `+', 0x2b */ + FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `,', 0x2c */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `-', 0x2d */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `.', 0x2e */ + 0, /* `/', 0x2f */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `0', 0x30 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `1', 0x31 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `2', 0x32 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `3', 0x33 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `4', 0x34 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `5', 0x35 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `6', 0x36 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `7', 0x37 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `8', 0x38 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `9', 0x39 */ + FSRTL_NTFS_LEGAL, /* `:', 0x3a */ + FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `;', 0x3b */ + FSRTL_WILD_CHARACTER, /* `<', 0x3c */ + FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `=', 0x3d */ + FSRTL_WILD_CHARACTER, /* `>', 0x3e */ + FSRTL_WILD_CHARACTER, /* `?', 0x3f */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `@', 0x40 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `A', 0x41 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `B', 0x42 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `C', 0x43 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `D', 0x44 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `E', 0x45 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `F', 0x46 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `G', 0x47 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `H', 0x48 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `I', 0x49 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `J', 0x4a */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `K', 0x4b */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `L', 0x4c */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `M', 0x4d */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `N', 0x4e */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `O', 0x4f */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `P', 0x50 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `Q', 0x51 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `R', 0x52 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `S', 0x53 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `T', 0x54 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `U', 0x55 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `V', 0x56 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `W', 0x57 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `X', 0x58 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `Y', 0x59 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `Z', 0x5a */ + FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `[', 0x5b */ + 0, /* `\', 0x5c */ + FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `]', 0x5d */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `^', 0x5e */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `_', 0x5f */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* ``', 0x60 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `a', 0x61 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `b', 0x62 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `c', 0x63 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `d', 0x64 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `e', 0x65 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `f', 0x66 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `g', 0x67 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `h', 0x68 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `i', 0x69 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `j', 0x6a */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `k', 0x6b */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `l', 0x6c */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `m', 0x6d */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `n', 0x6e */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `o', 0x6f */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `p', 0x70 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `q', 0x71 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `r', 0x72 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `s', 0x73 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `t', 0x74 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `u', 0x75 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `v', 0x76 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `w', 0x77 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `x', 0x78 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `y', 0x79 */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `z', 0x7a */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `{', 0x7b */ + 0, /* `|', 0x7c */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `}', 0x7d */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL, /* `~', 0x7e */ + FSRTL_FAT_LEGAL | FSRTL_HPFS_LEGAL | FSRTL_NTFS_LEGAL /* 0x7f */ +}; + +PUCHAR FsRtlLegalAnsiCharacterArray = LegalAnsiCharacterArray; + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +FsRtlInitSystem(VOID) +{ + ULONG i; + + /* Initialize the list for granted locks */ + ExInitializePagedLookasideList(&FsRtlFileLockLookasideList, + NULL, + NULL, + 0, + sizeof(FILE_LOCK), + IFS_POOL_TAG, + 0); + + /* Allocate the Resource Buffer */ + FsRtlPagingIoResources = FsRtlAllocatePoolWithTag(NonPagedPool, + FSRTL_MAX_RESOURCES * + sizeof(ERESOURCE), + TAG('F', 's', 'R', 'e')); + + /* Initialize the Resources */ + for (i = 0; i < FSRTL_MAX_RESOURCES; i++) + { + ExInitializeResource(&FsRtlPagingIoResources[i]); + } +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlAllocateResource + * @implemented NT 4.0 + * + * The FsRtlAllocateResource routine returns a pre-initialized ERESOURCE + * for use by a File System Driver. + * + * @return A Pointer to a pre-initialized ERESOURCE. + * + * @remarks The File System Library only provides up to 16 Resources. + * + *--*/ +PERESOURCE +NTAPI +FsRtlAllocateResource(VOID) +{ + PAGED_CODE(); + + /* Return a preallocated ERESOURCE */ + return &FsRtlPagingIoResources[FsRtlPagingIoResourceSelector++ % + FSRTL_MAX_RESOURCES]; +} + diff --git a/reactos/ntoskrnl/fs/mcb.c b/reactos/ntoskrnl/fsrtl/largemcb.c similarity index 62% rename from reactos/ntoskrnl/fs/mcb.c rename to reactos/ntoskrnl/fsrtl/largemcb.c index ce8fdbf90c1..6a1b4b37b4f 100644 --- a/reactos/ntoskrnl/fs/mcb.c +++ b/reactos/ntoskrnl/fsrtl/largemcb.c @@ -1,391 +1,350 @@ -/* $Id$ - * - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/mcb.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: No programmer listed. - */ - -/* INCLUDES ****************************************************************/ - -#include - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/********************************************************************** - * NAME EXPORTED - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * NOTES - * - * @unimplemented - */ -BOOLEAN -NTAPI -FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, - IN LONGLONG Vbn, - IN LONGLONG Lbn, - IN LONGLONG SectorCount) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * FsRtlAddMcbEntry: Obsolete - * - * @implemented - */ -BOOLEAN -NTAPI -FsRtlAddMcbEntry(IN PMCB Mcb, - IN VBN Vbn, - IN LBN Lbn, - IN ULONG SectorCount) -{ - return FsRtlAddLargeMcbEntry(&Mcb->DummyFieldThatSizesThisStructureCorrectly, - (LONGLONG)Vbn, - (LONGLONG)Lbn, - (LONGLONG)SectorCount); -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, - IN ULONG RunIndex, - OUT PLONGLONG Vbn, - OUT PLONGLONG Lbn, - OUT PLONGLONG SectorCount) -{ - UNIMPLEMENTED; - return FALSE; -} - - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlGetNextMcbEntry(IN PMCB Mcb, - IN ULONG RunIndex, - OUT PVBN Vbn, - OUT PLBN Lbn, - OUT PULONG SectorCount) -{ - BOOLEAN Return = FALSE; - LONGLONG llVbn; - LONGLONG llLbn; - LONGLONG llSectorCount; - - /* Call the Large version */ - Return = FsRtlGetNextLargeMcbEntry(&Mcb->DummyFieldThatSizesThisStructureCorrectly, - RunIndex, - &llVbn, - &llLbn, - &llSectorCount); - - /* Return everything typecasted */ - *Vbn = (ULONG)llVbn; - *Lbn = (ULONG)llLbn; - *SectorCount = (ULONG)llSectorCount; - - /* And return the original value */ - return(Return); -} - - -/* - * @unimplemented - */ -VOID -NTAPI -FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, - IN POOL_TYPE PoolType) -{ - UNIMPLEMENTED; - Mcb->BaseMcb.PoolType = PoolType; -} - -/* - * FsRtlInitializeMcb: Obsolete - * @implemented - */ -VOID -NTAPI -FsRtlInitializeMcb (IN PMCB Mcb, - IN POOL_TYPE PoolType) -{ - FsRtlInitializeLargeMcb(& Mcb->DummyFieldThatSizesThisStructureCorrectly, PoolType); -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb, - IN LONGLONG Vbn, - OUT PLONGLONG Lbn OPTIONAL, - OUT PLONGLONG SectorCountFromLbn OPTIONAL, - OUT PLONGLONG StartingLbn OPTIONAL, - OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL, - OUT PULONG Index OPTIONAL) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -FsRtlLookupLastLargeMcbEntryAndIndex(IN PLARGE_MCB OpaqueMcb, - OUT PLONGLONG LargeVbn, - OUT PLONGLONG LargeLbn, - OUT PULONG Index) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -PFSRTL_PER_STREAM_CONTEXT -NTAPI -FsRtlLookupPerStreamContextInternal(IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, - IN PVOID OwnerId OPTIONAL, - IN PVOID InstanceId OPTIONAL) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -PFSRTL_PER_FILEOBJECT_CONTEXT -NTAPI -FsRtlLookupPerFileObjectContext(IN PFILE_OBJECT FileObject, - IN PVOID OwnerId OPTIONAL, - IN PVOID InstanceId OPTIONAL) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, - OUT PLONGLONG Vbn, - OUT PLONGLONG Lbn) -{ - UNIMPLEMENTED; - return(FALSE); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlLookupLastMcbEntry(IN PMCB Mcb, - OUT PVBN Vbn, - OUT PLBN Lbn) -{ - BOOLEAN Return = FALSE; - LONGLONG llVbn; - LONGLONG llLbn; - - /* Call the Large version */ - Return = FsRtlLookupLastLargeMcbEntry(&Mcb->DummyFieldThatSizesThisStructureCorrectly, - &llVbn, - &llLbn); - - /* Return everything typecasted */ - *Vbn = (ULONG)llVbn; - *Lbn = (ULONG)llLbn; - - /* And return the original value */ - return(Return); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -FsRtlLookupMcbEntry(IN PMCB Mcb, - IN VBN Vbn, - OUT PLBN Lbn, - OUT PULONG SectorCount OPTIONAL, - OUT PULONG Index) -{ - BOOLEAN Return = FALSE; - LONGLONG llLbn; - LONGLONG llSectorCount; - - /* Call the Large version */ - Return = FsRtlLookupLargeMcbEntry(&Mcb->DummyFieldThatSizesThisStructureCorrectly, - (LONGLONG)Vbn, - &llLbn, - &llSectorCount, - NULL, - NULL, - Index); - - /* Return everything typecasted */ - *Lbn = (ULONG)llLbn; - if (SectorCount) *SectorCount = (ULONG)llSectorCount; - - /* And return the original value */ - return(Return); -} - -/* - * @implemented - */ -ULONG -NTAPI -FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb) -{ - ULONG NumberOfRuns; - - KeAcquireGuardedMutex(Mcb->GuardedMutex); - NumberOfRuns = Mcb->BaseMcb.PairCount; - KeReleaseGuardedMutex(Mcb->GuardedMutex); - - return NumberOfRuns; -} - - -/* - * FsRtlNumberOfRunsInMcb: Obsolete - * - * @implemented - */ -ULONG -NTAPI -FsRtlNumberOfRunsInMcb (IN PMCB Mcb) -{ - return FsRtlNumberOfRunsInLargeMcb(&Mcb->DummyFieldThatSizesThisStructureCorrectly); -} - - -/* - * @unimplemented - */ -VOID -NTAPI -FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, - IN LONGLONG Vbn, - IN LONGLONG SectorCount) -{ - UNIMPLEMENTED; -} - -/* - * @implemented - */ -VOID -NTAPI -FsRtlRemoveMcbEntry(IN PMCB Mcb, - IN VBN Vbn, - IN ULONG SectorCount) -{ - /* Call the large function */ - FsRtlRemoveLargeMcbEntry(&Mcb->DummyFieldThatSizesThisStructureCorrectly, - (LONGLONG)Vbn, - (LONGLONG)SectorCount); -} - - -/* - * @unimplemented - */ -VOID -NTAPI -FsRtlResetLargeMcb(IN PLARGE_MCB Mcb, - IN BOOLEAN SelfSynchronized) -{ - UNIMPLEMENTED; -} - -/* - * @unimplemented - */ -BOOLEAN -NTAPI -FsRtlSplitLargeMcb(IN PLARGE_MCB Mcb, - IN LONGLONG Vbn, - IN LONGLONG Amount) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ -VOID -NTAPI -FsRtlTruncateLargeMcb(IN PLARGE_MCB Mcb, - IN LONGLONG Vbn) -{ - UNIMPLEMENTED; -} - -/* - * FsRtlTruncateMcb: Obsolete - * - * @implemented - */ -VOID -NTAPI -FsRtlTruncateMcb (IN PMCB Mcb, - IN VBN Vbn) -{ - FsRtlTruncateLargeMcb(&Mcb->DummyFieldThatSizesThisStructureCorrectly, (LONGLONG)Vbn); -} - -/* - * @unimplemented - */ -VOID -NTAPI -FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb) -{ - UNIMPLEMENTED; -} - -/* - * FsRtlUninitializeMcb: Obsolete - * - * @implemented - */ -VOID -NTAPI -FsRtlUninitializeMcb(IN PMCB Mcb) -{ - FsRtlUninitializeLargeMcb(& Mcb->DummyFieldThatSizesThisStructureCorrectly); -} - -/* EOF */ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/largemcb.c + * PURPOSE: Mapping Control Block (MCB) support for File System Drivers + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, + IN LONGLONG Vbn, + IN LONGLONG Lbn, + IN LONGLONG SectorCount) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlAddMcbEntry(IN PMCB Mcb, + IN VBN Vbn, + IN LBN Lbn, + IN ULONG SectorCount) +{ + /* Call the newer function */ + return FsRtlAddLargeMcbEntry(&Mcb-> + DummyFieldThatSizesThisStructureCorrectly, + (LONGLONG)Vbn, + (LONGLONG)Lbn, + (LONGLONG)SectorCount); +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, + IN ULONG RunIndex, + OUT PLONGLONG Vbn, + OUT PLONGLONG Lbn, + OUT PLONGLONG SectorCount) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlGetNextMcbEntry(IN PMCB Mcb, + IN ULONG RunIndex, + OUT PVBN Vbn, + OUT PLBN Lbn, + OUT PULONG SectorCount) +{ + BOOLEAN Return = FALSE; + LONGLONG llVbn; + LONGLONG llLbn; + LONGLONG llSectorCount; + + /* Call the Large version */ + Return = FsRtlGetNextLargeMcbEntry( + &Mcb->DummyFieldThatSizesThisStructureCorrectly, + RunIndex, + &llVbn, + &llLbn, + &llSectorCount); + + /* Return the lower 32 bits */ + *Vbn = (ULONG)llVbn; + *Lbn = (ULONG)llLbn; + *SectorCount = (ULONG)llSectorCount; + + /* And return the original value */ + return Return; +} + +/* + * @unimplemented + */ +VOID +NTAPI +FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, + IN POOL_TYPE PoolType) +{ + KEBUGCHECK(0); +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlInitializeMcb(IN PMCB Mcb, + IN POOL_TYPE PoolType) +{ + /* Call the newer function */ + FsRtlInitializeLargeMcb(&Mcb->DummyFieldThatSizesThisStructureCorrectly, + PoolType); +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb, + IN LONGLONG Vbn, + OUT PLONGLONG Lbn OPTIONAL, + OUT PLONGLONG SectorCountFromLbn OPTIONAL, + OUT PLONGLONG StartingLbn OPTIONAL, + OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL, + OUT PULONG Index OPTIONAL) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +FsRtlLookupLastLargeMcbEntryAndIndex(IN PLARGE_MCB OpaqueMcb, + OUT PLONGLONG LargeVbn, + OUT PLONGLONG LargeLbn, + OUT PULONG Index) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, + OUT PLONGLONG Vbn, + OUT PLONGLONG Lbn) +{ + KEBUGCHECK(0); + return(FALSE); +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlLookupLastMcbEntry(IN PMCB Mcb, + OUT PVBN Vbn, + OUT PLBN Lbn) +{ + BOOLEAN Return = FALSE; + LONGLONG llVbn; + LONGLONG llLbn; + + /* Call the Large version */ + Return = FsRtlLookupLastLargeMcbEntry( + &Mcb->DummyFieldThatSizesThisStructureCorrectly, + &llVbn, + &llLbn); + + /* Return the lower 32-bits */ + *Vbn = (ULONG)llVbn; + *Lbn = (ULONG)llLbn; + + /* And return the original value */ + return Return; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +FsRtlLookupMcbEntry(IN PMCB Mcb, + IN VBN Vbn, + OUT PLBN Lbn, + OUT PULONG SectorCount OPTIONAL, + OUT PULONG Index) +{ + BOOLEAN Return = FALSE; + LONGLONG llLbn; + LONGLONG llSectorCount; + + /* Call the Large version */ + Return = FsRtlLookupLargeMcbEntry(&Mcb-> + DummyFieldThatSizesThisStructureCorrectly, + (LONGLONG)Vbn, + &llLbn, + &llSectorCount, + NULL, + NULL, + Index); + + /* Return the lower 32-bits */ + *Lbn = (ULONG)llLbn; + if (SectorCount) *SectorCount = (ULONG)llSectorCount; + + /* And return the original value */ + return Return; +} + +/* + * @implemented + */ +ULONG +NTAPI +FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb) +{ + ULONG NumberOfRuns; + + /* Read the number of runs while holding the MCB lock */ + KeAcquireGuardedMutex(Mcb->GuardedMutex); + NumberOfRuns = Mcb->BaseMcb.PairCount; + KeReleaseGuardedMutex(Mcb->GuardedMutex); + + /* Return the count */ + return NumberOfRuns; +} + +/* + * @implemented + */ +ULONG +NTAPI +FsRtlNumberOfRunsInMcb (IN PMCB Mcb) +{ + /* Call the newer function */ + return FsRtlNumberOfRunsInLargeMcb( + &Mcb->DummyFieldThatSizesThisStructureCorrectly); +} + +/* + * @unimplemented + */ +VOID +NTAPI +FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, + IN LONGLONG Vbn, + IN LONGLONG SectorCount) +{ + KEBUGCHECK(0); +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlRemoveMcbEntry(IN PMCB Mcb, + IN VBN Vbn, + IN ULONG SectorCount) +{ + /* Call the large function */ + FsRtlRemoveLargeMcbEntry(&Mcb->DummyFieldThatSizesThisStructureCorrectly, + (LONGLONG)Vbn, + (LONGLONG)SectorCount); +} + +/* + * @unimplemented + */ +VOID +NTAPI +FsRtlResetLargeMcb(IN PLARGE_MCB Mcb, + IN BOOLEAN SelfSynchronized) +{ + KEBUGCHECK(0); +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +FsRtlSplitLargeMcb(IN PLARGE_MCB Mcb, + IN LONGLONG Vbn, + IN LONGLONG Amount) +{ + KEBUGCHECK(0); + return FALSE; +} + +/* + * @unimplemented + */ +VOID +NTAPI +FsRtlTruncateLargeMcb(IN PLARGE_MCB Mcb, + IN LONGLONG Vbn) +{ + KEBUGCHECK(0); +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlTruncateMcb (IN PMCB Mcb, + IN VBN Vbn) +{ + /* Call the newer function */ + FsRtlTruncateLargeMcb(&Mcb->DummyFieldThatSizesThisStructureCorrectly, + (LONGLONG)Vbn); +} + +/* + * @unimplemented + */ +VOID +NTAPI +FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb) +{ + KEBUGCHECK(0); +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlUninitializeMcb(IN PMCB Mcb) +{ + /* Call the newer function */ + FsRtlUninitializeLargeMcb(&Mcb->DummyFieldThatSizesThisStructureCorrectly); +} + diff --git a/reactos/ntoskrnl/fsrtl/name.c b/reactos/ntoskrnl/fsrtl/name.c new file mode 100644 index 00000000000..1a63945694b --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/name.c @@ -0,0 +1,277 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/name.c + * PURPOSE: Provides name parsing and other support routines for FSDs + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlAreNamesEqual + * @implemented + * + * FILLME + * + * @param Name1 + * FILLME + * + * @param Name2 + * FILLME + * + * @param IgnoreCase + * FILLME + * + * @param UpcaseTable + * FILLME + * + * @return None + * + * @remarks From Bo Branten's ntifs.h v25. + * + *--*/ +BOOLEAN +NTAPI +FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, + IN PCUNICODE_STRING Name2, + IN BOOLEAN IgnoreCase, + IN PCWCH UpcaseTable OPTIONAL) +{ + UNICODE_STRING UpcaseName1; + UNICODE_STRING UpcaseName2; + BOOLEAN StringsAreEqual; + + /* Well, first check their size */ + if (Name1->Length != Name2->Length) { + /* Not equal! */ + return FALSE; + } + + /* Turn them into Upcase if we don't have a table */ + if (IgnoreCase && !UpcaseTable) { + RtlUpcaseUnicodeString(&UpcaseName1, Name1, TRUE); + RtlUpcaseUnicodeString(&UpcaseName2, Name2, TRUE); + Name1 = &UpcaseName1; + Name2 = &UpcaseName2; + + goto ManualCase; + } + + /* Do a case-sensitive search */ + if (!IgnoreCase) { + +ManualCase: + /* Use a raw memory compare */ + StringsAreEqual = RtlEqualMemory(Name1->Buffer, + Name2->Buffer, + Name1->Length); + + /* Clear the strings if we need to */ + if (IgnoreCase) { + RtlFreeUnicodeString(&UpcaseName1); + RtlFreeUnicodeString(&UpcaseName2); + } + + /* Return the equality */ + return StringsAreEqual; + + } else { + + /* Case in-sensitive search */ + + LONG i; + + for (i = Name1->Length / sizeof(WCHAR) - 1; i >= 0; i--) { + + if (UpcaseTable[Name1->Buffer[i]] != UpcaseTable[Name2->Buffer[i]]) { + + /* Non-match found! */ + return FALSE; + } + } + + /* We finished the loop so we are equal */ + return TRUE; + } +} + +/*++ + * @name FsRtlDissectName + * @implemented + * + * Dissects a given path name into first and remaining part. + * + * @param Name + * Unicode string to dissect. + * + * @param FirstPart + * Pointer to user supplied UNICODE_STRING, that will later point + * to the first part of the original name. + * + * @param RemainingPart + * Pointer to user supplied UNICODE_STRING, that will later point + * to the remaining part of the original name. + * + * @return None + * + * @remarks Example: + * Name: \test1\test2\test3 + * FirstPart: test1 + * RemainingPart: test2\test3 + * + *--*/ +VOID +NTAPI +FsRtlDissectName(IN UNICODE_STRING Name, + OUT PUNICODE_STRING FirstPart, + OUT PUNICODE_STRING RemainingPart) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlDoesNameContainWildCards + * @implemented + * + * FILLME + * + * @param Name + * Pointer to a UNICODE_STRING containing Name to examine + * + * @return TRUE if Name contains wildcards, FALSE otherwise + * + * @remarks From Bo Branten's ntifs.h v12. + * + *--*/ +BOOLEAN +NTAPI +FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name) +{ + PWCHAR Ptr; + + /* Loop through every character */ + if (Name->Length) + { + Ptr = Name->Buffer + (Name->Length / sizeof(WCHAR)) - 1; + while ((Ptr >= Name->Buffer) && (*Ptr != L'\\')) + { + /* Check for Wildcard */ + if (FsRtlIsUnicodeCharacterWild(*Ptr)) return TRUE; + Ptr--; + } + } + + /* Nothing Found */ + return FALSE; +} + +/*++ + * @name FsRtlIsNameInExpression + * @implemented + * + * FILLME + * + * @param DeviceObject + * FILLME + * + * @param Irp + * FILLME + * + * @return TRUE if Name is in Expression, FALSE otherwise + * + * @remarks From Bo Branten's ntifs.h v12. This function should be + * rewritten to avoid recursion and better wildcard handling + * should be implemented (see FsRtlDoesNameContainWildCards). + * + *--*/ +BOOLEAN +NTAPI +FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, + IN PUNICODE_STRING Name, + IN BOOLEAN IgnoreCase, + IN PWCHAR UpcaseTable OPTIONAL) +{ + USHORT ExpressionPosition, NamePosition; + UNICODE_STRING TempExpression, TempName; + + ExpressionPosition = 0; + NamePosition = 0; + while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) && + NamePosition < (Name->Length / sizeof(WCHAR))) + { + if (Expression->Buffer[ExpressionPosition] == L'*') + { + ExpressionPosition++; + if (ExpressionPosition == (Expression->Length / sizeof(WCHAR))) + { + return TRUE; + } + while (NamePosition < (Name->Length / sizeof(WCHAR))) + { + TempExpression.Length = + TempExpression.MaximumLength = + Expression->Length - (ExpressionPosition * sizeof(WCHAR)); + TempExpression.Buffer = Expression->Buffer + ExpressionPosition; + TempName.Length = + TempName.MaximumLength = + Name->Length - (NamePosition * sizeof(WCHAR)); + TempName.Buffer = Name->Buffer + NamePosition; + /* FIXME: Rewrite to get rid of recursion */ + if (FsRtlIsNameInExpression(&TempExpression, &TempName, + IgnoreCase, UpcaseTable)) + { + return TRUE; + } + NamePosition++; + } + } + else + { + /* FIXME: Take UpcaseTable into account! */ + if (Expression->Buffer[ExpressionPosition] == L'?' || + (IgnoreCase && + RtlUpcaseUnicodeChar(Expression->Buffer[ExpressionPosition]) == + RtlUpcaseUnicodeChar(Name->Buffer[NamePosition])) || + (!IgnoreCase && + Expression->Buffer[ExpressionPosition] == + Name->Buffer[NamePosition])) + { + NamePosition++; + ExpressionPosition++; + } + else + { + return FALSE; + } + } + } + + /* Handle matching of "f0_*.*" expression to "f0_000" file name. */ + if (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) && + Expression->Buffer[ExpressionPosition] == L'.') + { + while (ExpressionPosition < (Expression->Length / sizeof(WCHAR)) && + (Expression->Buffer[ExpressionPosition] == L'.' || + Expression->Buffer[ExpressionPosition] == L'*' || + Expression->Buffer[ExpressionPosition] == L'?')) + { + ExpressionPosition++; + } + } + + if (ExpressionPosition == (Expression->Length / sizeof(WCHAR)) && + NamePosition == (Name->Length / sizeof(WCHAR))) + { + return TRUE; + } + + return FALSE; +} + diff --git a/reactos/ntoskrnl/fsrtl/notify.c b/reactos/ntoskrnl/fsrtl/notify.c new file mode 100644 index 00000000000..f33a4af7881 --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/notify.c @@ -0,0 +1,398 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/notify.c + * PURPOSE: Change Notifications and Sync for File System Drivers + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlNotifyChangeDirectory + * @implemented + * + * FILLME + * + * @param NotifySync + * FILLME + * + * @param FsContext + * FILLME + * + * @param FullDirectoryName + * FILLME + * + * @param NotifyList + * FILLME + * + * @param WatchTree + * FILLME + * + * @param CompletionFilter + * FILLME + * + * @param NotifyIrp + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlNotifyChangeDirectory(IN PNOTIFY_SYNC NotifySync, + IN PVOID FsContext, + IN PSTRING FullDirectoryName, + IN PLIST_ENTRY NotifyList, + IN BOOLEAN WatchTree, + IN ULONG CompletionFilter, + IN PIRP NotifyIrp) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlNotifyCleanup + * @unimplemented + * + * Called by FSD when all handles to FileObject (identified by FsContext) are closed + * + * @param NotifySync + * FILLME + * + * @param NotifyList + * FILLME + * + * @param FsContext + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlNotifyCleanup(IN PNOTIFY_SYNC NotifySync, + IN PLIST_ENTRY NotifyList, + IN PVOID FsContext) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlNotifyFilterChangeDirectory + * @unimplemented + * + * FILLME + * + * @param NotifySync + * FILLME + * + * @param NotifyList + * FILLME + * + * @param FsContext + * FILLME + * + * @param FullDirectoryName + * FILLME + * + * @param WatchTree + * FILLME + * + * @param IgnoreBuffer + * FILLME + * + * @param CompletionFilter + * FILLME + * + * @param NotifyIrp + * FILLME + * + * @param TraverseCallback + * FILLME + * + * @param SubjectContext + * FILLME + * + * @param FilterCallback + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlNotifyFilterChangeDirectory(IN PNOTIFY_SYNC NotifySync, + IN PLIST_ENTRY NotifyList, + IN PVOID FsContext, + IN PSTRING FullDirectoryName, + IN BOOLEAN WatchTree, + IN BOOLEAN IgnoreBuffer, + IN ULONG CompletionFilter, + IN PIRP NotifyIrp, + IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, + IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL, + IN PFILTER_REPORT_CHANGE FilterCallback OPTIONAL) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlNotifyFilterReportChange + * @unimplemented + * + * FILLME + * + * @param NotifySync + * FILLME + * + * @param NotifyList + * FILLME + * + * @param FullTargetName + * FILLME + * + * @param TargetNameOffset + * FILLME + * + * @param StreamName + * FILLME + * + * @param NormalizedParentName + * FILLME + * + * @param FilterMatch + * FILLME + * + * @param Action + * FILLME + * + * @param TargetContext + * FILLME + * + * @param FilterContext + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlNotifyFilterReportChange(IN PNOTIFY_SYNC NotifySync, + IN PLIST_ENTRY NotifyList, + IN PSTRING FullTargetName, + IN USHORT TargetNameOffset, + IN PSTRING StreamName OPTIONAL, + IN PSTRING NormalizedParentName OPTIONAL, + IN ULONG FilterMatch, + IN ULONG Action, + IN PVOID TargetContext, + IN PVOID FilterContext) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlNotifyFullChangeDirectory + * @unimplemented + * + * FILLME + * + * @param NotifySync + * FILLME + * + * @param NotifyList + * FILLME + * + * @param FsContext + * FILLME + * + * @param FullDirectoryName + * FILLME + * + * @param WatchTree + * FILLME + * + * @param IgnoreBuffer + * FILLME + * + * @param CompletionFilter + * FILLME + * + * @param Irp + * FILLME + * + * @param TraverseCallback + * FILLME + * + * @param SubjectContext + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlNotifyFullChangeDirectory(IN PNOTIFY_SYNC NotifySync, + IN PLIST_ENTRY NotifyList, + IN PVOID FsContext, + IN PSTRING FullDirectoryName, + IN BOOLEAN WatchTree, + IN BOOLEAN IgnoreBuffer, + IN ULONG CompletionFilter, + IN PIRP Irp, + IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, + IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlNotifyFullReportChange + * @unimplemented + * + * FILLME + * + * @param NotifySync + * FILLME + * + * @param NotifyList + * FILLME + * + * @param FullTargetName + * FILLME + * + * @param TargetNameOffset + * FILLME + * + * @param StreamName + * FILLME + * + * @param NormalizedParentName + * FILLME + * + * @param FilterMatch + * FILLME + * + * @param Action + * FILLME + * + * @param TargetContext + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlNotifyFullReportChange(IN PNOTIFY_SYNC NotifySync, + IN PLIST_ENTRY NotifyList, + IN PSTRING FullTargetName, + IN USHORT TargetNameOffset, + IN PSTRING StreamName OPTIONAL, + IN PSTRING NormalizedParentName OPTIONAL, + IN ULONG FilterMatch, + IN ULONG Action, + IN PVOID TargetContext) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlNotifyInitializeSync + * @unimplemented + * + * FILLME + * + * @param NotifySync + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlNotifyInitializeSync(IN PNOTIFY_SYNC *NotifySync) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlNotifyReportChange + * @unimplemented + * + * FILLME + * + * @param NotifySync + * FILLME + * + * @param NotifyList + * FILLME + * + * @param FullTargetName + * FILLME + * + * @param FileNamePartLength + * FILLME + * + * @param FilterMatch + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlNotifyReportChange(IN PNOTIFY_SYNC NotifySync, + IN PLIST_ENTRY NotifyList, + IN PSTRING FullTargetName, + IN PUSHORT FileNamePartLength, + IN ULONG FilterMatch) +{ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlCurrentBatchOplock + * @implemented + * + * Uninitialize a NOTIFY_SYNC object + * + * @param NotifySync + * Address of a pointer to a PNOTIFY_SYNC object previously + * initialized by FsRtlNotifyInitializeSync() + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync) +{ + KEBUGCHECK(0); +} + diff --git a/reactos/ntoskrnl/fs/oplock.c b/reactos/ntoskrnl/fsrtl/oplock.c similarity index 75% rename from reactos/ntoskrnl/fs/oplock.c rename to reactos/ntoskrnl/fsrtl/oplock.c index c83d437bae8..d92643ed418 100644 --- a/reactos/ntoskrnl/fs/oplock.c +++ b/reactos/ntoskrnl/fsrtl/oplock.c @@ -1,175 +1,176 @@ -/* $Id$ - * - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/oplock.c - * PURPOSE: Oplock-functions - * - * PROGRAMMERS: Emanuele Aliberti - * Eric Kohl - */ - -/* INCLUDES *****************************************************************/ - -#include - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/*++ - * @name FsRtlCheckOplock - * @unimplemented - * - * FILLME - * - * @param Oplock - * FILLME - * - * @param Irp - * FILLME - * - * @param Context - * FILLME - * - * @param CompletionRoutine - * FILLME - * - * @param PostIrpRoutine - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -NTSTATUS -NTAPI -FsRtlCheckOplock(IN POPLOCK Oplock, - IN PIRP Irp, - IN PVOID Context, - IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, - IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/*++ - * @name FsRtlCurrentBatchOplock - * @unimplemented - * - * FILLME - * - * @param Oplock - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -BOOLEAN -NTAPI -FsRtlCurrentBatchOplock(IN POPLOCK Oplock) -{ - UNIMPLEMENTED; - return FALSE; -} - -/*++ - * @name FsRtlInitializeOplock - * @unimplemented - * - * FILLME - * - * @param Oplock - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlInitializeOplock(IN OUT POPLOCK Oplock) -{ - UNIMPLEMENTED; -} - -/*++ - * @name FsRtlOplockFsctrl - * @unimplemented - * - * FILLME - * - * @param Oplock - * FILLME - * - * @param Irp - * FILLME - * - * @param OpenCount - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -NTSTATUS -NTAPI -FsRtlOplockFsctrl(IN POPLOCK Oplock, - IN PIRP Irp, - IN ULONG OpenCount) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/*++ - * @name FsRtlOplockIsFastIoPossible - * @unimplemented - * - * FILLME - * - * @param Oplock - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -BOOLEAN -NTAPI -FsRtlOplockIsFastIoPossible(IN POPLOCK Oplock) -{ - UNIMPLEMENTED; - return FALSE; -} - -/*++ - * @name FsRtlUninitializeOplock - * @unimplemented - * - * FILLME - * - * @param Oplock - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlUninitializeOplock(IN POPLOCK Oplock) -{ - UNIMPLEMENTED; -} - -/* EOF */ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/oplock.c + * PURPOSE: Provides an Opportunistic Lock for file system drivers. + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlCheckOplock + * @unimplemented + * + * FILLME + * + * @param Oplock + * FILLME + * + * @param Irp + * FILLME + * + * @param Context + * FILLME + * + * @param CompletionRoutine + * FILLME + * + * @param PostIrpRoutine + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +NTSTATUS +NTAPI +FsRtlCheckOplock(IN POPLOCK Oplock, + IN PIRP Irp, + IN PVOID Context, + IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, + IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL) +{ + /* Unimplemented */ + KEBUGCHECK(0); + return STATUS_NOT_IMPLEMENTED; +} + +/*++ + * @name FsRtlCurrentBatchOplock + * @unimplemented + * + * FILLME + * + * @param Oplock + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +BOOLEAN +NTAPI +FsRtlCurrentBatchOplock(IN POPLOCK Oplock) +{ + /* Unimplemented */ + KEBUGCHECK(0); + return FALSE; +} + +/*++ + * @name FsRtlInitializeOplock + * @unimplemented + * + * FILLME + * + * @param Oplock + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlInitializeOplock(IN OUT POPLOCK Oplock) +{ + /* Unimplemented */ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlOplockFsctrl + * @unimplemented + * + * FILLME + * + * @param Oplock + * FILLME + * + * @param Irp + * FILLME + * + * @param OpenCount + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +NTSTATUS +NTAPI +FsRtlOplockFsctrl(IN POPLOCK Oplock, + IN PIRP Irp, + IN ULONG OpenCount) +{ + /* Unimplemented */ + KEBUGCHECK(0); + return STATUS_NOT_IMPLEMENTED; +} + +/*++ + * @name FsRtlOplockIsFastIoPossible + * @unimplemented + * + * FILLME + * + * @param Oplock + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +BOOLEAN +NTAPI +FsRtlOplockIsFastIoPossible(IN POPLOCK Oplock) +{ + /* Unimplemented */ + KEBUGCHECK(0); + return FALSE; +} + +/*++ + * @name FsRtlUninitializeOplock + * @unimplemented + * + * FILLME + * + * @param Oplock + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlUninitializeOplock(IN POPLOCK Oplock) +{ + /* Unimplemented */ + KEBUGCHECK(0); +} + diff --git a/reactos/ntoskrnl/fsrtl/pnp.c b/reactos/ntoskrnl/fsrtl/pnp.c new file mode 100644 index 00000000000..f0b23f310ca --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/pnp.c @@ -0,0 +1,42 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/pnp.c + * PURPOSE: Manages PnP support routines for file system drivers. + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlNotifyVolumeEvent + * @unimplemented + * + * FILLME + * + * @param FileObject + * FILLME + * + * @param EventCode + * FILLME + * + * @return None + * + * @remarks Only present in NT 5+. + * + *--*/ +NTSTATUS +NTAPI +FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject, + IN ULONG EventCode) +{ + /* Unimplemented */ + KEBUGCHECK(0); + return STATUS_NOT_IMPLEMENTED; +} diff --git a/reactos/ntoskrnl/fsrtl/stackovf.c b/reactos/ntoskrnl/fsrtl/stackovf.c new file mode 100644 index 00000000000..af6cd579c3a --- /dev/null +++ b/reactos/ntoskrnl/fsrtl/stackovf.c @@ -0,0 +1,69 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/stackovf.c + * PURPOSE: Provides Stack Overflow support for File System Drivers + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlPostPagingFileStackOverflow + * @unimplemented NT 4.0 + * + * The FsRtlPostPagingFileStackOverflow routine + * + * @param Context + * + * @param Event + * + * @param StackOverflowRoutine + * + * @return + * + * @remarks None. + * + *--*/ +VOID +NTAPI +FsRtlPostPagingFileStackOverflow(IN PVOID Context, + IN PKEVENT Event, + IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine) +{ + UNIMPLEMENTED; +} + +/*++ + * @name FsRtlPostStackOverflow + * @unimplemented NT 4.0 + * + * The FsRtlPostStackOverflow routine + * + * @param Context + * + * @param Event + * + * @param StackOverflowRoutine + * + * @return + * + * @remarks None. + * + *--*/ +VOID +NTAPI +FsRtlPostStackOverflow(IN PVOID Context, + IN PKEVENT Event, + IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine) +{ + KEBUGCHECK(0); +} + +/* EOF */ diff --git a/reactos/ntoskrnl/fs/tunnel.c b/reactos/ntoskrnl/fsrtl/tunnel.c similarity index 57% rename from reactos/ntoskrnl/fs/tunnel.c rename to reactos/ntoskrnl/fsrtl/tunnel.c index 4922ea2d2fb..6347126994e 100644 --- a/reactos/ntoskrnl/fs/tunnel.c +++ b/reactos/ntoskrnl/fsrtl/tunnel.c @@ -1,178 +1,180 @@ -/* $Id$ - * - * PROJECT: ReactOS kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/tunnel.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: Emanuele Aliberti - */ - -/* INCLUDES ******************************************************************/ - -#include - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/*++ - * @name FsRtlAddToTunnelCache - * @unimplemented - * - * FILLME - * - * @param Cache - * FILLME - * - * @param DirectoryKey - * FILLME - * - * @param ShortName - * FILLME - * - * @param LongName - * FILLME - * - * @param KeyByShortName - * FILLME - * - * @param DataLength - * FILLME - * - * @param Data - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlAddToTunnelCache(IN PTUNNEL Cache, - IN ULONGLONG DirectoryKey, - IN PUNICODE_STRING ShortName, - IN PUNICODE_STRING LongName, - IN BOOLEAN KeyByShortName, - IN ULONG DataLength, - IN PVOID Data) -{ - UNIMPLEMENTED; -} - -/*++ - * @name FsRtlDeleteKeyFromTunnelCache - * @unimplemented - * - * FILLME - * - * @param Cache - * FILLME - * - * @param DirectoryKey - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlDeleteKeyFromTunnelCache(IN PTUNNEL Cache, - IN ULONGLONG DirectoryKey) -{ - UNIMPLEMENTED; -} - -/*++ - * @name FsRtlDeleteTunnelCache - * @unimplemented - * - * FILLME - * - * @param Cache - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlDeleteTunnelCache(IN PTUNNEL Cache) -{ - UNIMPLEMENTED; -} - -/*++ - * @name FsRtlFindInTunnelCache - * @unimplemented - * - * FILLME - * - * @param Cache - * FILLME - * - * @param DirectoryKey - * FILLME - * - * @param ShortName - * FILLME - * - * @param LongName - * FILLME - * - * @param KeyByShortName - * FILLME - * - * @param DataLength - * FILLME - * - * @param Data - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -BOOLEAN -NTAPI -FsRtlFindInTunnelCache(IN PTUNNEL Cache, - IN ULONGLONG DirectoryKey, - IN PUNICODE_STRING Name, - OUT PUNICODE_STRING ShortName, - OUT PUNICODE_STRING LongName, - IN OUT PULONG DataLength, - OUT PVOID Data) -{ - UNIMPLEMENTED; - return FALSE; -} - -/*++ - * @name FsRtlDeleteTunnelCache - * @unimplemented - * - * FILLME - * - * @param Cache - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlInitializeTunnelCache(IN PTUNNEL Cache) -{ - UNIMPLEMENTED; -} - -/* EOF */ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/tunnel.c + * PURPOSE: Provides the Tunnel Cache implementation for file system drivers. + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlAddToTunnelCache + * @unimplemented + * + * FILLME + * + * @param Cache + * FILLME + * + * @param DirectoryKey + * FILLME + * + * @param ShortName + * FILLME + * + * @param LongName + * FILLME + * + * @param KeyByShortName + * FILLME + * + * @param DataLength + * FILLME + * + * @param Data + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlAddToTunnelCache(IN PTUNNEL Cache, + IN ULONGLONG DirectoryKey, + IN PUNICODE_STRING ShortName, + IN PUNICODE_STRING LongName, + IN BOOLEAN KeyByShortName, + IN ULONG DataLength, + IN PVOID Data) +{ + /* Unimplemented */ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlDeleteKeyFromTunnelCache + * @unimplemented + * + * FILLME + * + * @param Cache + * FILLME + * + * @param DirectoryKey + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlDeleteKeyFromTunnelCache(IN PTUNNEL Cache, + IN ULONGLONG DirectoryKey) +{ + /* Unimplemented */ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlDeleteTunnelCache + * @unimplemented + * + * FILLME + * + * @param Cache + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlDeleteTunnelCache(IN PTUNNEL Cache) +{ + /* Unimplemented */ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlFindInTunnelCache + * @unimplemented + * + * FILLME + * + * @param Cache + * FILLME + * + * @param DirectoryKey + * FILLME + * + * @param ShortName + * FILLME + * + * @param LongName + * FILLME + * + * @param KeyByShortName + * FILLME + * + * @param DataLength + * FILLME + * + * @param Data + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +BOOLEAN +NTAPI +FsRtlFindInTunnelCache(IN PTUNNEL Cache, + IN ULONGLONG DirectoryKey, + IN PUNICODE_STRING Name, + OUT PUNICODE_STRING ShortName, + OUT PUNICODE_STRING LongName, + IN OUT PULONG DataLength, + OUT PVOID Data) +{ + /* Unimplemented */ + KEBUGCHECK(0); + return FALSE; +} + +/*++ + * @name FsRtlDeleteTunnelCache + * @unimplemented + * + * FILLME + * + * @param Cache + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlInitializeTunnelCache(IN PTUNNEL Cache) +{ + /* Unimplemented */ + KEBUGCHECK(0); +} + +/* EOF */ diff --git a/reactos/ntoskrnl/fs/unc.c b/reactos/ntoskrnl/fsrtl/unc.c similarity index 66% rename from reactos/ntoskrnl/fs/unc.c rename to reactos/ntoskrnl/fsrtl/unc.c index 2c3d9244e41..8738a97ee1c 100644 --- a/reactos/ntoskrnl/fs/unc.c +++ b/reactos/ntoskrnl/fsrtl/unc.c @@ -1,72 +1,67 @@ -/* $Id$ - * - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/fs/unc.c - * PURPOSE: Functions to work with UNC providers - * - * PROGRAMMERS: Emanuele Aliberti - * Eric Kohl - */ - -/* INCLUDES *****************************************************************/ - -#include - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/*++ - * @name FsRtlDeregisterUncProvider - * @unimplemented - * - * FILLME - * - * @param Handle - * FILLME - * - * @return None - * - * @remarks None - * - *--*/ -VOID -NTAPI -FsRtlDeregisterUncProvider(IN HANDLE Handle) -{ - UNIMPLEMENTED; -} - -/*++ - * @name FsRtlRegisterUncProvider - * @unimplemented - * - * FILLME - * - * @param Handle - * FILLME - * - * @param RedirectorDeviceName - * FILLME - * - * @param MailslotsSupported - * - * @return None - * - * @remarks None - * - *--*/ -NTSTATUS -NTAPI -FsRtlRegisterUncProvider(IN OUT PHANDLE Handle, - IN PUNICODE_STRING RedirectorDeviceName, - IN BOOLEAN MailslotsSupported) -{ - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); -} - - -/* EOF */ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/fsrtl/unc.c + * PURPOSE: Manages UNC support routines for file system drivers. + * PROGRAMMERS: None. + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ + * @name FsRtlDeregisterUncProvider + * @unimplemented + * + * FILLME + * + * @param Handle + * FILLME + * + * @return None + * + * @remarks None + * + *--*/ +VOID +NTAPI +FsRtlDeregisterUncProvider(IN HANDLE Handle) +{ + /* Unimplemented */ + KEBUGCHECK(0); +} + +/*++ + * @name FsRtlRegisterUncProvider + * @unimplemented + * + * FILLME + * + * @param Handle + * FILLME + * + * @param RedirectorDeviceName + * FILLME + * + * @param MailslotsSupported + * + * @return None + * + * @remarks None + * + *--*/ +NTSTATUS +NTAPI +FsRtlRegisterUncProvider(IN OUT PHANDLE Handle, + IN PUNICODE_STRING RedirectorDeviceName, + IN BOOLEAN MailslotsSupported) +{ + /* Unimplemented */ + KEBUGCHECK(0); + return STATUS_NOT_IMPLEMENTED; +} diff --git a/reactos/ntoskrnl/include/internal/fsrtl.h b/reactos/ntoskrnl/include/internal/fsrtl.h index 5387da975f7..8b4da207f60 100644 --- a/reactos/ntoskrnl/include/internal/fsrtl.h +++ b/reactos/ntoskrnl/include/internal/fsrtl.h @@ -1,96 +1,61 @@ -#ifndef __INCLUDE_INTERNAL_IFS_H -#define __INCLUDE_INTERNAL_IFS_H +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/include/fsrtl.h + * PURPOSE: Internal header for the File System Runtime Library + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ -typedef struct _FILE_LOCK_GRANTED -{ - LIST_ENTRY ListEntry; - FILE_LOCK_INFO Lock; - PVOID UnlockContext; -} FILE_LOCK_GRANTED, *PFILE_LOCK_GRANTED; +// +// Define this if you want debugging support +// +#define _FSRTL_DEBUG_ 0x00 -typedef struct _FILE_LOCK_TOC -{ - KSPIN_LOCK SpinLock; - LIST_ENTRY GrantedListHead; - LIST_ENTRY PendingListHead; -} FILE_LOCK_TOC, *PFILE_LOCK_TOC; - -VOID -INIT_FUNCTION -NTAPI -FsRtlpInitNotifyImplementation(VOID); - -VOID -NTAPI -FsRtlInitSystem(VOID); - -VOID -NTAPI -FsRtlpFileLockCancelRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -BOOLEAN -FASTCALL -FsRtlpCheckLockForReadOrWriteAccess( - IN PFILE_LOCK FileLock, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN ULONG Key, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process, - IN BOOLEAN Read -); - -NTSTATUS -FASTCALL -FsRtlpFastUnlockAllByKey( - IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PEPROCESS Process, - IN ULONG Key, - IN BOOLEAN UseKey, - IN PVOID Context OPTIONAL -); - -BOOLEAN -FASTCALL -FsRtlpAddLock( - IN PFILE_LOCK_TOC LockToc, - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN PEPROCESS Process, - IN ULONG Key, - IN BOOLEAN ExclusiveLock, - IN PVOID UnlockContext -); - -VOID -FASTCALL -FsRtlpCompletePendingLocks( - IN PFILE_LOCK FileLock, - IN PFILE_LOCK_TOC LockToc, - IN OUT PKIRQL oldirql, - IN PVOID Context -); - -NTSTATUS -FASTCALL -FsRtlpUnlockSingle( - IN PFILE_LOCK FileLock, - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - IN PEPROCESS Process, - IN ULONG Key, - IN PVOID Context OPTIONAL, - IN BOOLEAN CallUnlockRoutine -); - -VOID -FASTCALL -FsRtlpDumpFileLocks(IN PFILE_LOCK FileLock); +// +// These define the Debug Masks Supported +// +#define FSRTL_FASTIO_DEBUG 0x01 +#define FSRTL_OPLOCK_DEBUG 0x02 +#define FSRTL_TUNNEL_DEBUG 0x04 +#define FSRTL_MCB_DEBUG 0x08 +#define FSRTL_NAME_DEBUG 0x10 +#define FSRTL_NOTIFY_DEBUG 0x20 +#define FSRTL_FILELOCK_DEBUG 0x40 +#define FSRTL_UNC_DEBUG 0x80 +#define FSRTL_FILTER_DEBUG 0x100 +#define FSRTL_CONTEXT_DEBUG 0x200 +// +// Debug/Tracing support +// +#if _FSRTL_DEBUG_ +#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented +#define FSTRACE DbgPrintEx +#else +#define FSTRACE(x, ...) \ + if (x & FsRtlpTraceLevel) DbgPrint(__VA_ARGS__) #endif +#else +#define FSTRACE(x, ...) DPRINT(__VA_ARGS__) +#endif + +// +// Number of internal ERESOURCE structures allocated for callers to request +// +#define FSRTL_MAX_RESOURCES 16 + +// +// Initialization Routines +// +VOID +NTAPI +FsRtlInitSystem( + VOID +); + +// +// Global data inside the File System Runtime Library +// +extern PERESOURCE FsRtlPagingIoResources; +extern PUCHAR _FsRtlLegalAnsiCharacterArray; +extern PAGED_LOOKASIDE_LIST FsRtlFileLockLookasideList; diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 7293fadd4c4..05beae70a8b 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -176,111 +176,125 @@ ExWindowStationObjectType DATA Exi386InterlockedDecrementLong@4 Exi386InterlockedExchangeUlong@12 Exi386InterlockedIncrementLong@4 -FsRtlAcquireFileExclusive@4 -FsRtlAddLargeMcbEntry@28 -FsRtlAddMcbEntry@16 -FsRtlAddToTunnelCache@32 -FsRtlAllocateFileLock@8 -FsRtlAllocatePool@8 -FsRtlAllocatePoolWithQuota@8 -FsRtlAllocatePoolWithQuotaTag@12 -FsRtlAllocatePoolWithTag@12 -FsRtlAllocateResource@0 +FsRtlAcquireFileExclusive +;FsRtlAddBaseMcbEntry +FsRtlAddLargeMcbEntry +FsRtlAddMcbEntry +FsRtlAddToTunnelCache +FsRtlAllocateFileLock +FsRtlAllocatePool +FsRtlAllocatePoolWithQuota +FsRtlAllocatePoolWithQuotaTag +FsRtlAllocatePoolWithTag +FsRtlAllocateResource FsRtlAreNamesEqual@16 -FsRtlBalanceReads@4 +FsRtlBalanceReads FsRtlCheckLockForReadAccess@8 FsRtlCheckLockForWriteAccess@8 -FsRtlCheckOplock@20 -FsRtlCopyRead@32 -FsRtlCopyWrite@32 -FsRtlCurrentBatchOplock@4 -FsRtlDeleteKeyFromTunnelCache@12 -FsRtlDeleteTunnelCache@4 -FsRtlDeregisterUncProvider@4 -FsRtlDissectDbcs@16 -FsRtlDissectName@16 -FsRtlDoesDbcsContainWildCards@4 +FsRtlCheckOplock +FsRtlCopyRead +FsRtlCopyWrite +;FsRtlCreateSectionForDataScan +FsRtlCurrentBatchOplock +FsRtlDeleteKeyFromTunnelCache +FsRtlDeleteTunnelCache +FsRtlDeregisterUncProvider +FsRtlDissectDbcs +FsRtlDissectName +FsRtlDoesDbcsContainWildCards FsRtlDoesNameContainWildCards@4 -FsRtlFastCheckLockForRead@24 -FsRtlFastCheckLockForWrite@24 +FsRtlFastCheckLockForRead +FsRtlFastCheckLockForWrite FsRtlFastUnlockAll@16 -FsRtlFastUnlockAllByKey@20 -FsRtlFastUnlockSingle@32 -FsRtlFindInTunnelCache@32 -FsRtlFreeFileLock@4 -FsRtlGetFileSize@8 -FsRtlGetNextFileLock@8 -FsRtlGetNextLargeMcbEntry@20 -FsRtlGetNextMcbEntry@20 -FsRtlIncrementCcFastReadNotPossible@0 -FsRtlIncrementCcFastReadNoWait@0 -FsRtlIncrementCcFastReadResourceMiss@0 -FsRtlIncrementCcFastReadWait@0 +FsRtlFastUnlockAllByKey +FsRtlFastUnlockSingle +FsRtlFindInTunnelCache +FsRtlFreeFileLock +FsRtlGetFileSize +;FsRtlGetNextBaseMcbEntry +FsRtlGetNextFileLock +FsRtlGetNextLargeMcbEntry +FsRtlGetNextMcbEntry +FsRtlIncrementCcFastReadNotPossible +FsRtlIncrementCcFastReadNoWait +FsRtlIncrementCcFastReadResourceMiss +FsRtlIncrementCcFastReadWait +;FsRtlInitializeBaseMcb FsRtlInitializeFileLock@12 -FsRtlInitializeLargeMcb@8 -FsRtlInitializeMcb@8 -FsRtlInitializeOplock@4 -FsRtlInitializeTunnelCache@4 -FsRtlInsertPerFileObjectContext@8 -FsRtlInsertPerStreamContext@8 -FsRtlIsDbcsInExpression@8 -FsRtlIsFatDbcsLegal@20 -FsRtlIsHpfsDbcsLegal@20 +FsRtlInitializeLargeMcb +FsRtlInitializeMcb +FsRtlInitializeOplock +FsRtlInitializeTunnelCache +FsRtlInsertPerFileObjectContext +FsRtlInsertPerStreamContext +FsRtlIsDbcsInExpression +FsRtlIsFatDbcsLegal +FsRtlIsHpfsDbcsLegal FsRtlIsNameInExpression@16 -FsRtlIsNtstatusExpected@4 -FsRtlIsPagingFile@4 -FsRtlIsTotalDeviceFailure@4 +FsRtlIsNtstatusExpected +FsRtlIsPagingFile +FsRtlIsTotalDeviceFailure FsRtlLegalAnsiCharacterArray=_FsRtlLegalAnsiCharacterArray -FsRtlLookupLargeMcbEntry@32 -FsRtlLookupLastLargeMcbEntry@12 -FsRtlLookupLastLargeMcbEntryAndIndex@16 -FsRtlLookupLastMcbEntry@12 -FsRtlLookupMcbEntry@20 -FsRtlLookupPerFileObjectContext@12 -FsRtlLookupPerStreamContextInternal@12 -FsRtlMdlRead@24 -FsRtlMdlReadComplete@8 -FsRtlMdlReadCompleteDev@12 -FsRtlMdlReadDev@28 -FsRtlMdlWriteComplete@12 -FsRtlMdlWriteCompleteDev@16 -FsRtlNormalizeNtstatus@8 -FsRtlNotifyChangeDirectory@28 -FsRtlNotifyCleanup@12 -FsRtlNotifyFilterChangeDirectory@44 -FsRtlNotifyFilterReportChange@40 -FsRtlNotifyFullChangeDirectory@40 -FsRtlNotifyFullReportChange@36 -FsRtlNotifyInitializeSync@4 -FsRtlNotifyReportChange@20 -FsRtlNotifyUninitializeSync@4 -FsRtlNotifyVolumeEvent@8 -FsRtlNumberOfRunsInLargeMcb@4 -FsRtlNumberOfRunsInMcb@4 -FsRtlOplockFsctrl@12 -FsRtlOplockIsFastIoPossible@4 -FsRtlPostPagingFileStackOverflow@12 -FsRtlPostStackOverflow@12 -FsRtlPrepareMdlWrite@24 -FsRtlPrepareMdlWriteDev@28 -FsRtlPrivateLock@48 +;FsRtlLookupBaseMcbEntry +FsRtlLookupLargeMcbEntry +;FsRtlLookupLastBaseMcbEntry +;FsRtlLookupLastBaseMcbEntryAndIndex +FsRtlLookupLastLargeMcbEntry +FsRtlLookupLastLargeMcbEntryAndIndex +FsRtlLookupLastMcbEntry +FsRtlLookupMcbEntry +FsRtlLookupPerFileObjectContext +FsRtlLookupPerStreamContextInternal +FsRtlMdlRead +FsRtlMdlReadComplete +FsRtlMdlReadCompleteDev +FsRtlMdlReadDev +FsRtlMdlWriteComplete +FsRtlMdlWriteCompleteDev +FsRtlNormalizeNtstatus +FsRtlNotifyChangeDirectory +FsRtlNotifyCleanup +FsRtlNotifyFilterChangeDirectory +FsRtlNotifyFilterReportChange +FsRtlNotifyFullChangeDirectory +FsRtlNotifyFullReportChange +FsRtlNotifyInitializeSync +FsRtlNotifyReportChange +FsRtlNotifyUninitializeSync +FsRtlNotifyVolumeEvent +;FsRtlNumberOfRunsInBaseMcb +FsRtlNumberOfRunsInLargeMcb +FsRtlNumberOfRunsInMcb +FsRtlOplockFsctrl +FsRtlOplockIsFastIoPossible +FsRtlPostPagingFileStackOverflow +FsRtlPostStackOverflow +FsRtlPrepareMdlWrite +FsRtlPrepareMdlWriteDev +FsRtlPrivateLock FsRtlProcessFileLock@12 -FsRtlRegisterUncProvider@12 -FsRtlReleaseFile@4 -FsRtlRemoveLargeMcbEntry@20 -FsRtlRemoveMcbEntry@12 -FsRtlRemovePerFileObjectContext@12 -FsRtlRemovePerStreamContext@12 -FsRtlResetLargeMcb@8 -FsRtlSplitLargeMcb@20 -FsRtlSyncVolumes@12 -FsRtlTeardownPerStreamContexts@4 -FsRtlTruncateLargeMcb@12 -FsRtlTruncateMcb@8 +FsRtlRegisterFileSystemFilterCallbacks +FsRtlRegisterUncProvider +FsRtlReleaseFile +;FsRtlRemoveBaseMcbEntry +FsRtlRemoveLargeMcbEntry +FsRtlRemoveMcbEntry +FsRtlRemovePerFileObjectContext +FsRtlRemovePerStreamContext +;FsRtlResetBaseMcb +FsRtlResetLargeMcb +;FsRtlSplitBaseMcb +FsRtlSplitLargeMcb +FsRtlSyncVolumes +FsRtlTeardownPerStreamContexts +;FsRtlTruncateBaseMcb +FsRtlTruncateLargeMcb +FsRtlTruncateMcb +;FsRtlUninitializeBaseMcb FsRtlUninitializeFileLock@4 -FsRtlUninitializeLargeMcb@4 -FsRtlUninitializeMcb@4 -FsRtlUninitializeOplock@4 +FsRtlUninitializeLargeMcb +FsRtlUninitializeMcb +FsRtlUninitializeOplock HalDispatchTable=_HalDispatchTable HalPrivateDispatchTable DATA @HalExamineMBR@16 diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 3f0ce54a4b3..10c6ed34404 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -154,18 +154,23 @@ zone.c zw.S - - context.c + + dbcsname.c fastio.c + faulttol.c filelock.c - mcb.c + filter.c + filtrctx.c + fsfilter.c + fsrtlpc.c + largemcb.c name.c notify.c oplock.c - pool.c + pnp.c + stackovf.c tunnel.c unc.c - util.c disksup.c From a22a4040cc7d9aeb0295dc1c94334edef15ba4b4 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 17:22:15 +0000 Subject: [PATCH 08/30] - Add authors' names. svn path=/trunk/; revision=25380 --- reactos/ntoskrnl/fsrtl/dbcsname.c | 2 +- reactos/ntoskrnl/fsrtl/faulttol.c | 2 +- reactos/ntoskrnl/fsrtl/filelock.c | 2 +- reactos/ntoskrnl/fsrtl/fsrtlpc.c | 2 +- reactos/ntoskrnl/fsrtl/largemcb.c | 2 +- reactos/ntoskrnl/fsrtl/name.c | 55 +++++++++++++++++-------------- 6 files changed, 35 insertions(+), 30 deletions(-) diff --git a/reactos/ntoskrnl/fsrtl/dbcsname.c b/reactos/ntoskrnl/fsrtl/dbcsname.c index 34d016cd9c1..f2535d3c6db 100644 --- a/reactos/ntoskrnl/fsrtl/dbcsname.c +++ b/reactos/ntoskrnl/fsrtl/dbcsname.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/fsrtl/name.c * PURPOSE: Provides DBCS parsing and other support routines for FSDs - * PROGRAMMERS: None. + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES ******************************************************************/ diff --git a/reactos/ntoskrnl/fsrtl/faulttol.c b/reactos/ntoskrnl/fsrtl/faulttol.c index 0aceba8c869..7e95a6e6419 100644 --- a/reactos/ntoskrnl/fsrtl/faulttol.c +++ b/reactos/ntoskrnl/fsrtl/faulttol.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/fsrtl/faulttol.c * PURPOSE: Provides Fault Tolerance support for File System Drivers - * PROGRAMMERS: None. + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES ******************************************************************/ diff --git a/reactos/ntoskrnl/fsrtl/filelock.c b/reactos/ntoskrnl/fsrtl/filelock.c index 71360cc0b46..2bbd0dac4ce 100644 --- a/reactos/ntoskrnl/fsrtl/filelock.c +++ b/reactos/ntoskrnl/fsrtl/filelock.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/fsrtl/filelock.c * PURPOSE: File Locking implementation for File System Drivers - * PROGRAMMERS: None. + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES ******************************************************************/ diff --git a/reactos/ntoskrnl/fsrtl/fsrtlpc.c b/reactos/ntoskrnl/fsrtl/fsrtlpc.c index 1fdd15aadc5..3e5f6a44ba1 100644 --- a/reactos/ntoskrnl/fsrtl/fsrtlpc.c +++ b/reactos/ntoskrnl/fsrtl/fsrtlpc.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/fsrtl/fsrtlpc.c * PURPOSE: Contains initialization and support code for the FsRtl - * PROGRAMMERS: None. + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES ******************************************************************/ diff --git a/reactos/ntoskrnl/fsrtl/largemcb.c b/reactos/ntoskrnl/fsrtl/largemcb.c index 6a1b4b37b4f..f0e4c8c1cac 100644 --- a/reactos/ntoskrnl/fsrtl/largemcb.c +++ b/reactos/ntoskrnl/fsrtl/largemcb.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/fsrtl/largemcb.c * PURPOSE: Mapping Control Block (MCB) support for File System Drivers - * PROGRAMMERS: None. + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES ******************************************************************/ diff --git a/reactos/ntoskrnl/fsrtl/name.c b/reactos/ntoskrnl/fsrtl/name.c index 1a63945694b..8fe40a1be44 100644 --- a/reactos/ntoskrnl/fsrtl/name.c +++ b/reactos/ntoskrnl/fsrtl/name.c @@ -3,7 +3,8 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/fsrtl/name.c * PURPOSE: Provides name parsing and other support routines for FSDs - * PROGRAMMERS: None. + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * Filip Navara (navaraf@reactos.org) */ /* INCLUDES ******************************************************************/ @@ -46,52 +47,56 @@ FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, { UNICODE_STRING UpcaseName1; UNICODE_STRING UpcaseName2; - BOOLEAN StringsAreEqual; + BOOLEAN StringsAreEqual, MemoryAllocated = FALSE; + ULONG i; /* Well, first check their size */ - if (Name1->Length != Name2->Length) { - /* Not equal! */ - return FALSE; - } + if (Name1->Length != Name2->Length) return FALSE; - /* Turn them into Upcase if we don't have a table */ - if (IgnoreCase && !UpcaseTable) { - RtlUpcaseUnicodeString(&UpcaseName1, Name1, TRUE); + /* Check if the caller didn't give an upcase table */ + if ((IgnoreCase) && !(UpcaseTable)) + { + /* Upcase the string ourselves */ + Status = RtlUpcaseUnicodeString(&UpcaseName1, Name1, TRUE); + if (!NT_SUCCESS(Status)) RtlRaiseStatus(Status); + + /* Upcase the second string too */ RtlUpcaseUnicodeString(&UpcaseName2, Name2, TRUE); Name1 = &UpcaseName1; Name2 = &UpcaseName2; - goto ManualCase; + /* Make sure we go through the path below, but free the strings */ + IgnoreCase = FALSE; + MemoryAllocated = TRUE; } /* Do a case-sensitive search */ - if (!IgnoreCase) { - -ManualCase: + if (!IgnoreCase) + { /* Use a raw memory compare */ StringsAreEqual = RtlEqualMemory(Name1->Buffer, Name2->Buffer, Name1->Length); - /* Clear the strings if we need to */ - if (IgnoreCase) { + /* Check if we allocated strings */ + if (MemoryAllocated) + { + /* Free them */ RtlFreeUnicodeString(&UpcaseName1); RtlFreeUnicodeString(&UpcaseName2); } /* Return the equality */ return StringsAreEqual; - - } else { - + } + else + { /* Case in-sensitive search */ - - LONG i; - - for (i = Name1->Length / sizeof(WCHAR) - 1; i >= 0; i--) { - - if (UpcaseTable[Name1->Buffer[i]] != UpcaseTable[Name2->Buffer[i]]) { - + for (i = 0; i < Name1->Length / sizeof(WCHAR); i++) + { + /* Check if the character matches */ + if (UpcaseTable[Name1->Buffer[i]] != UpcaseTable[Name2->Buffer[i]]) + { /* Non-match found! */ return FALSE; } From a9e4074bd0656365a49a18a124d39889bf723cf3 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 17:49:44 +0000 Subject: [PATCH 09/30] - Fix build. Sorry, forgot that the last commit also included changes to FsrtlAreNamesEqual to raise an exception if upcasing the strings failed. svn path=/trunk/; revision=25381 --- reactos/ntoskrnl/fsrtl/name.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/ntoskrnl/fsrtl/name.c b/reactos/ntoskrnl/fsrtl/name.c index 8fe40a1be44..f887d9fea49 100644 --- a/reactos/ntoskrnl/fsrtl/name.c +++ b/reactos/ntoskrnl/fsrtl/name.c @@ -49,6 +49,7 @@ FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, UNICODE_STRING UpcaseName2; BOOLEAN StringsAreEqual, MemoryAllocated = FALSE; ULONG i; + NTSTATUS Status; /* Well, first check their size */ if (Name1->Length != Name2->Length) return FALSE; From a9b16dfb0e0a38aa709c40f5b67002cc40b3d7b3 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 17:56:56 +0000 Subject: [PATCH 10/30] - Fix kmtest's inclusion of the NDK. - Implement support for the Handle Count Database. - Don't do anything in IopCloseFile if this isn't the last handle for the process. - Fix definition of OBJECT_HANDLE_COUNT_DATABASE. svn path=/trunk/; revision=25382 --- reactos/drivers/test/kmtest/ntos_ob.c | 7 +- reactos/include/ndk/obtypes.h | 2 +- reactos/ntoskrnl/io/iomgr/file.c | 3 + reactos/ntoskrnl/ob/obhandle.c | 249 +++++++++++++++++++++++++- 4 files changed, 248 insertions(+), 13 deletions(-) diff --git a/reactos/drivers/test/kmtest/ntos_ob.c b/reactos/drivers/test/kmtest/ntos_ob.c index b5495cb61cf..b5a140aa013 100644 --- a/reactos/drivers/test/kmtest/ntos_ob.c +++ b/reactos/drivers/test/kmtest/ntos_ob.c @@ -28,12 +28,7 @@ //#define NDEBUG #include "debug.h" -#include "ndk/obtypes.h" -#include "ndk/obfuncs.h" - -#include "ndk/ifssupp.h" -#include "ndk/setypes.h" -#include "ndk/sefuncs.h" +#include "ntndk.h" // I ment to make this test scalable, but for now // we work with two object types only diff --git a/reactos/include/ndk/obtypes.h b/reactos/include/ndk/obtypes.h index a794077f47b..50b9f2a83ac 100644 --- a/reactos/include/ndk/obtypes.h +++ b/reactos/include/ndk/obtypes.h @@ -399,7 +399,7 @@ typedef struct _OBJECT_HANDLE_COUNT_ENTRY typedef struct _OBJECT_HANDLE_COUNT_DATABASE { ULONG CountEntries; - POBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1]; + OBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1]; } OBJECT_HANDLE_COUNT_DATABASE, *POBJECT_HANDLE_COUNT_DATABASE; typedef struct _OBJECT_HEADER_HANDLE_INFO diff --git a/reactos/ntoskrnl/io/iomgr/file.c b/reactos/ntoskrnl/io/iomgr/file.c index b74e0aec9ac..6c0d4f52080 100644 --- a/reactos/ntoskrnl/io/iomgr/file.c +++ b/reactos/ntoskrnl/io/iomgr/file.c @@ -1396,6 +1396,9 @@ IopCloseFile(IN PEPROCESS Process OPTIONAL, KIRQL OldIrql; IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody); + /* If this isn't the last handle for the current process, quit */ + if (HandleCount != 1) return; + /* Check if the file is locked and has more then one handle opened */ if ((FileObject->LockOperation) && (SystemHandleCount != 1)) { diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index f4ea0dc6132..635d768c625 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -19,8 +19,178 @@ PHANDLE_TABLE ObpKernelHandleTable = NULL; +#define TAG_OB_HANDLE TAG('O', 'b', 'H', 'd') + /* PRIVATE FUNCTIONS *********************************************************/ +POBJECT_HANDLE_COUNT_ENTRY +NTAPI +ObpInsertHandleCount(IN POBJECT_HEADER ObjectHeader) +{ + POBJECT_HEADER_HANDLE_INFO HandleInfo; + POBJECT_HANDLE_COUNT_ENTRY FreeEntry; + POBJECT_HANDLE_COUNT_DATABASE HandleDatabase, OldHandleDatabase; + ULONG i; + ULONG Size, OldSize; + OBJECT_HANDLE_COUNT_DATABASE SingleDatabase; + PAGED_CODE(); + + /* Get the handle info */ + HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader); + if (!HandleInfo) return NULL; + + /* Check if we only have one entry */ + if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS) + { + /* Fill out the single entry */ + SingleDatabase.CountEntries = 1; + SingleDatabase.HandleCountEntries[0] = HandleInfo->SingleEntry; + + /* Use this as the old size */ + OldHandleDatabase = &SingleDatabase; + OldSize = sizeof(SingleDatabase); + + /* Now we'll have two entries, and an entire DB */ + i = 2; + Size = sizeof(OBJECT_HANDLE_COUNT_DATABASE) + + sizeof(OBJECT_HANDLE_COUNT_ENTRY); + } + else + { + /* We already have a DB, get the information from it */ + OldHandleDatabase = HandleInfo->HandleCountDatabase; + i = OldHandleDatabase->CountEntries; + OldSize = sizeof(OBJECT_HANDLE_COUNT_DATABASE) + + ((i - 1) * sizeof(OBJECT_HANDLE_COUNT_ENTRY)); + + /* Add 4 more entries */ + i += 4; + Size = OldSize += (4 * sizeof(OBJECT_HANDLE_COUNT_ENTRY)); + } + + /* Allocate the DB */ + HandleDatabase = ExAllocatePoolWithTag(PagedPool, Size, TAG_OB_HANDLE); + if (!HandleDatabase) return NULL; + + /* Copy the old database */ + RtlMoveMemory(HandleDatabase, OldHandleDatabase, OldSize); + + /* Check if we he had a single entry before */ + if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS) + { + /* Now we have more */ + ObjectHeader->Flags &= ~OB_FLAG_SINGLE_PROCESS; + } + else + { + /* Otherwise we had a DB, free it */ + ExFreePool(OldHandleDatabase); + } + + /* Find the end of the copy and zero out the new data */ + FreeEntry = (PVOID)((ULONG_PTR)HandleDatabase + OldSize); + RtlZeroMemory(FreeEntry, Size - OldSize); + + /* Set the new information and return the free entry */ + HandleDatabase->CountEntries = i; + HandleInfo->HandleCountDatabase = HandleDatabase; + return FreeEntry; +} + +NTSTATUS +NTAPI +ObpIncrementHandleDataBase(IN POBJECT_HEADER ObjectHeader, + IN PEPROCESS Process, + IN OUT PULONG NewProcessHandleCount) +{ + POBJECT_HEADER_HANDLE_INFO HandleInfo; + POBJECT_HANDLE_COUNT_ENTRY HandleEntry, FreeEntry = NULL; + POBJECT_HANDLE_COUNT_DATABASE HandleDatabase; + ULONG i; + PAGED_CODE(); + + /* Get the handle info and check if we only have one entry */ + HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader); + if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS) + { + /* Check if the entry is free */ + if (!HandleInfo->SingleEntry.HandleCount) + { + /* Add ours */ + HandleInfo->SingleEntry.HandleCount = 1; + HandleInfo->SingleEntry.Process = Process; + + /* Return success and 1 handle */ + *NewProcessHandleCount = 1; + return STATUS_SUCCESS; + } + else if (HandleInfo->SingleEntry.Process == Process) + { + /* Busy entry, but same process */ + *NewProcessHandleCount = ++HandleInfo->SingleEntry.HandleCount; + return STATUS_SUCCESS; + } + else + { + /* Insert a new entry */ + FreeEntry = ObpInsertHandleCount(ObjectHeader); + if (!FreeEntry) return STATUS_INSUFFICIENT_RESOURCES; + + /* Fill it out */ + FreeEntry->Process = Process; + FreeEntry->HandleCount = 1; + + /* Return success and 1 handle */ + *NewProcessHandleCount = 1; + return STATUS_SUCCESS; + } + } + + /* We have a database instead */ + HandleDatabase = HandleInfo->HandleCountDatabase; + if (HandleDatabase) + { + /* Get the entries and loop them */ + i = HandleDatabase->CountEntries; + HandleEntry = &HandleDatabase->HandleCountEntries[0]; + while (i) + { + /* Check if this is a match */ + if (HandleEntry->Process == Process) + { + /* Found it, get the process handle count */ + *NewProcessHandleCount = ++HandleEntry->HandleCount; + return STATUS_SUCCESS; + } + else if (!HandleEntry->HandleCount) + { + /* Found a free entry */ + FreeEntry = HandleEntry; + } + + /* Keep looping */ + HandleEntry++; + i--; + } + + /* Check if we couldn't find a free entry */ + if (!FreeEntry) + { + /* Allocate one */ + FreeEntry = ObpInsertHandleCount(ObjectHeader); + if (!FreeEntry) return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Fill out the entry */ + FreeEntry->Process = Process; + FreeEntry->HandleCount = 1; + *NewProcessHandleCount = 1; + } + + /* Return success if we got here */ + return STATUS_SUCCESS; +} + NTSTATUS NTAPI ObpChargeQuotaForObject(IN POBJECT_HEADER ObjectHeader, @@ -101,6 +271,10 @@ ObpDecrementHandleCount(IN PVOID ObjectBody, LONG NewCount; POBJECT_HEADER_CREATOR_INFO CreatorInfo; KIRQL CalloutIrql; + POBJECT_HEADER_HANDLE_INFO HandleInfo; + POBJECT_HANDLE_COUNT_ENTRY HandleEntry; + POBJECT_HANDLE_COUNT_DATABASE HandleDatabase; + ULONG i; /* Get the object type and header */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody); @@ -138,8 +312,53 @@ ObpDecrementHandleCount(IN PVOID ObjectBody, /* Is the object type keeping track of handles? */ if (ObjectType->TypeInfo.MaintainHandleCount) { - /* FIXME */ - DPRINT("Handle Database not yet implemented\n"); + /* Get handle information */ + HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader); + + /* Check if there's only a single entry */ + if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS) + { + /* It should be us */ + ASSERT(HandleInfo->SingleEntry.Process == Process); + ASSERT(HandleInfo->SingleEntry.HandleCount > 0); + + /* Get the handle counts */ + ProcessHandleCount = HandleInfo->SingleEntry.HandleCount--; + HandleEntry = &HandleInfo->SingleEntry; + } + else + { + /* Otherwise, get the database */ + HandleDatabase = HandleInfo->HandleCountDatabase; + if (HandleDatabase) + { + /* Get the entries and loop them */ + i = HandleDatabase->CountEntries; + HandleEntry = &HandleDatabase->HandleCountEntries[0]; + while (i) + { + /* Check if this is a match */ + if ((HandleEntry->HandleCount) && + (HandleEntry->Process == Process)) + { + /* Found it, get the process handle count */ + ProcessHandleCount = HandleEntry->HandleCount--; + } + + /* Keep looping */ + HandleEntry++; + i--; + } + } + } + + /* Check if this is the last handle */ + if (ProcessHandleCount == 1) + { + /* Then clear the entry */ + HandleEntry->Process = NULL; + HandleEntry->HandleCount = 0; + } } /* Release the lock */ @@ -461,8 +680,17 @@ ObpIncrementHandleCount(IN PVOID Object, /* Check if we have a handle database */ if (ObjectType->TypeInfo.MaintainHandleCount) { - /* FIXME: TODO */ - DPRINT("Handle DB not yet supported\n"); + /* Increment the handle database */ + Status = ObpIncrementHandleDataBase(ObjectHeader, + Process, + &ProcessHandleCount); + if (!NT_SUCCESS(Status)) + { + /* FIXME: This should never happen for now */ + DPRINT1("Unhandled case\n"); + KEBUGCHECK(0); + goto Quickie; + } } /* Release the lock */ @@ -672,8 +900,17 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object, /* Check if we have a handle database */ if (ObjectType->TypeInfo.MaintainHandleCount) { - /* FIXME: TODO */ - DPRINT("Handle DB not yet supported\n"); + /* Increment the handle database */ + Status = ObpIncrementHandleDataBase(ObjectHeader, + Process, + &ProcessHandleCount); + if (!NT_SUCCESS(Status)) + { + /* FIXME: This should never happen for now */ + DPRINT1("Unhandled case\n"); + KEBUGCHECK(0); + goto Quickie; + } } /* Release the lock */ From 30bc8d330ff16d34139f0d23f2a9b19053c93058 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 18:11:24 +0000 Subject: [PATCH 11/30] - Fix some NDK dependency problems. svn path=/trunk/; revision=25383 --- reactos/include/ndk/obfuncs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/include/ndk/obfuncs.h b/reactos/include/ndk/obfuncs.h index 070404c56ef..258033b1e37 100644 --- a/reactos/include/ndk/obfuncs.h +++ b/reactos/include/ndk/obfuncs.h @@ -23,6 +23,7 @@ Author: // Dependencies // #include +#include #include #ifndef NTOS_MODE_USER From 76de33fe36d62005e755b33c689fc5fce8d910e3 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 19:40:10 +0000 Subject: [PATCH 12/30] - Implement ObFindHandleForObject and add it to the NDK. However, it depends on ExEnumHandleTable which is still unimplemented. - Fix up prototype of the function (it returns TRUE/FALSE, not NTSTATUS) and fix callers to use it properly. - Also add ExEnumHandleTable to NDK. svn path=/trunk/; revision=25384 --- reactos/include/ndk/exfuncs.h | 13 +++ reactos/include/ndk/obfuncs.h | 2 +- reactos/ntoskrnl/ex/sysinfo.c | 17 ++-- reactos/ntoskrnl/include/internal/ob.h | 6 ++ reactos/ntoskrnl/ob/obhandle.c | 82 +++++++++++++++++-- .../subsystems/win32/win32k/ntuser/desktop.c | 38 ++++----- 6 files changed, 121 insertions(+), 37 deletions(-) diff --git a/reactos/include/ndk/exfuncs.h b/reactos/include/ndk/exfuncs.h index 0a404ed5790..ba795188133 100644 --- a/reactos/include/ndk/exfuncs.h +++ b/reactos/include/ndk/exfuncs.h @@ -103,6 +103,19 @@ ExTryToAcquireResourceExclusiveLite( IN PERESOURCE Resource ); +// +// Handle Table Functions +// +NTKERNELAPI +BOOLEAN +NTAPI +ExEnumHandleTable( + IN PHANDLE_TABLE HandleTable, + IN PVOID Callback, + IN OUT PVOID Param, + OUT PHANDLE Handle OPTIONAL +); + #endif // diff --git a/reactos/include/ndk/obfuncs.h b/reactos/include/ndk/obfuncs.h index 258033b1e37..6e86a599011 100644 --- a/reactos/include/ndk/obfuncs.h +++ b/reactos/include/ndk/obfuncs.h @@ -109,7 +109,7 @@ ObReferenceObjectByName( ); NTKERNELAPI -NTSTATUS +BOOLEAN NTAPI ObFindHandleForObject( IN PEPROCESS Process, diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index ee87bc6ef7b..8f91ef33575 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -41,16 +41,15 @@ ExGetPreviousMode (VOID) /* * @unimplemented */ -VOID -STDCALL -ExEnumHandleTable ( - PULONG HandleTable, - PVOID Callback, - PVOID Param, - PHANDLE Handle OPTIONAL - ) +BOOLEAN +NTAPI +ExEnumHandleTable(IN PHANDLE_TABLE HandleTable, + IN PVOID Callback, + IN OUT PVOID Param, + OUT PHANDLE Handle OPTIONAL) { - UNIMPLEMENTED; + UNIMPLEMENTED; + return FALSE; } /* diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index f8a2f21ccc6..a0ae504476d 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -79,6 +79,12 @@ typedef struct _OBP_CLOSE_HANDLE_CONTEXT PHANDLE_TABLE HandleTable; KPROCESSOR_MODE AccessMode; } OBP_CLOSE_HANDLE_CONTEXT, *POBP_CLOSE_HANDLE_CONTEXT; +typedef struct _OBP_FIND_HANDLE_DATA +{ + POBJECT_HEADER ObjectHeader; + POBJECT_TYPE ObjectType; + POBJECT_HANDLE_INFORMATION HandleInformation; +} OBP_FIND_HANDLE_DATA, *POBP_FIND_HANDLE_DATA; // // Private Temporary Buffer for Lookup Routines diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index 635d768c625..c88c59451b1 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -23,6 +23,18 @@ PHANDLE_TABLE ObpKernelHandleTable = NULL; /* PRIVATE FUNCTIONS *********************************************************/ +BOOLEAN +NTAPI +ObpEnumFindHandleProcedure(IN PHANDLE_TABLE_ENTRY HandleEntry, + IN HANDLE Handle, + IN PVOID Context) +{ + /* FIXME: TODO */ + DPRINT1("Not yet implemented!\n"); + KEBUGCHECK(0); + return FALSE; +} + POBJECT_HANDLE_COUNT_ENTRY NTAPI ObpInsertHandleCount(IN POBJECT_HEADER ObjectHeader) @@ -583,7 +595,6 @@ ObpIncrementHandleCount(IN PVOID Object, !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)) { /* Incorrect attempt */ - DPRINT1("Failing here\n"); Status = STATUS_INVALID_PARAMETER; goto Quickie; } @@ -827,7 +838,6 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object, !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)) { /* Incorrect attempt */ - DPRINT1("failing here\n"); Status = STATUS_INVALID_PARAMETER; goto Quickie; } @@ -2196,15 +2206,75 @@ ObOpenObjectByPointer(IN PVOID Object, return Status; } -NTSTATUS STDCALL +/*++ +* @name ObFindHandleForObject +* @implemented NT4 +* +* The ObFindHandleForObject routine +* +* @param Process +* . +* +* @param Object +* . +* +* @param ObjectType +* . +* +* @param HandleInformation +* . +* +* @param HandleReturn +* . +* +* @return . +* +* @remarks None. +* +*--*/ +BOOLEAN +NTAPI ObFindHandleForObject(IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType, IN POBJECT_HANDLE_INFORMATION HandleInformation, - OUT PHANDLE HandleReturn) + OUT PHANDLE Handle) { - DPRINT("ObFindHandleForObject is unimplemented!\n"); - return STATUS_UNSUCCESSFUL; + OBP_FIND_HANDLE_DATA FindData; + BOOLEAN Result = FALSE; + + /* Make sure we have an object table */ + if (Process->ObjectTable) + { + /* Check if we have an object */ + if (Object) + { + /* Set its header */ + FindData.ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); + } + else + { + /* Otherwise, no object to match*/ + FindData.ObjectHeader = NULL; + } + + /* Set other information */ + FindData.ObjectType = ObjectType; + FindData.HandleInformation = HandleInformation; + + /* Enumerate the handle table */ + if (ExEnumHandleTable(Process->ObjectTable, + ObpEnumFindHandleProcedure, + &FindData, + Handle)) + { + /* Set success */ + Result = TRUE; + } + } + + /* Return the result */ + return Result; } /*++ diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index 8ed84433508..ec23d919b0e 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -299,15 +299,14 @@ IntParseDesktopPath(PEPROCESS Process, { /* search the process handle table for (inherited) window station handles, use a more appropriate one than WinSta0 if possible. */ - Status = ObFindHandleForObject(Process, - NULL, - ExWindowStationObjectType, - NULL, - (PHANDLE)hWinSta); - if(!NT_SUCCESS(Status)) + if (!ObFindHandleForObject(Process, + NULL, + ExWindowStationObjectType, + NULL, + (PHANDLE)hWinSta)) { - /* we had no luck searching for opened handles, use WinSta0 now */ - RtlInitUnicodeString(&WinSta, L"WinSta0"); + /* we had no luck searching for opened handles, use WinSta0 now */ + RtlInitUnicodeString(&WinSta, L"WinSta0"); } } @@ -315,12 +314,11 @@ IntParseDesktopPath(PEPROCESS Process, { /* search the process handle table for (inherited) desktop handles, use a more appropriate one than Default if possible. */ - Status = ObFindHandleForObject(Process, - NULL, - ExDesktopObjectType, - NULL, - (PHANDLE)hDesktop); - if(!NT_SUCCESS(Status)) + if (!ObFindHandleForObject(Process, + NULL, + ExDesktopObjectType, + NULL, + (PHANDLE)hDesktop)) { /* we had no luck searching for opened handles, use Desktop now */ RtlInitUnicodeString(&Desktop, L"Default"); @@ -479,13 +477,11 @@ IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject) ASSERT(DesktopObject); - Status = ObFindHandleForObject(PsGetCurrentProcess(), - DesktopObject, - ExDesktopObjectType, - NULL, - (PHANDLE)&Ret); - - if(!NT_SUCCESS(Status)) + if (!ObFindHandleForObject(PsGetCurrentProcess(), + DesktopObject, + ExDesktopObjectType, + NULL, + (PHANDLE)&Ret)) { Status = ObOpenObjectByPointer(DesktopObject, 0, From 8c9205dfd57296db390283bda5a4e4f1b8b19d07 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 19:52:49 +0000 Subject: [PATCH 13/30] - Implement ObpCreateSymbolicLinkName and enable call to the function. It shouldn't do any work currently because we don't have DOS Device Maps. - Also stub ObpDeleteSymbolicLinkName since it'll probably be needed later. svn path=/trunk/; revision=25385 --- reactos/ntoskrnl/include/internal/ob.h | 12 ++++++++++ reactos/ntoskrnl/ob/obdir.c | 4 ---- reactos/ntoskrnl/ob/obhandle.c | 3 +-- reactos/ntoskrnl/ob/obname.c | 1 - reactos/ntoskrnl/ob/symlink.c | 33 ++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index a0ae504476d..211a05bb6b7 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -149,6 +149,18 @@ ObpParseSymbolicLink( OUT PVOID *NextObject ); +VOID +NTAPI +ObpCreateSymbolicLinkName( + IN POBJECT_SYMBOLIC_LINK SymbolicLink +); + +VOID +NTAPI +ObpDeleteSymbolicLinkName( + IN POBJECT_SYMBOLIC_LINK SymbolicLink +); + // // Process/Handle Table Init/Rundown // diff --git a/reactos/ntoskrnl/ob/obdir.c b/reactos/ntoskrnl/ob/obdir.c index 5cb37be6df5..b5b4929dca9 100644 --- a/reactos/ntoskrnl/ob/obdir.c +++ b/reactos/ntoskrnl/ob/obdir.c @@ -719,10 +719,6 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); - DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, " - "DesiredAccess %x, ObjectAttributes %x\n", - DirectoryHandle, DesiredAccess, ObjectAttributes); - /* Check if we need to do any probing */ if(PreviousMode != KernelMode) { diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index c88c59451b1..4adfe5a9a8e 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -2506,8 +2506,7 @@ ObInsertObject(IN PVOID Object, if (ObjectType == ObSymbolicLinkType) { /* Create the internal name */ - DPRINT("FIXME: Created link!\n"); - //ObpCreateSymbolicLinkName(FoundObject); + ObpCreateSymbolicLinkName(Object); } } } diff --git a/reactos/ntoskrnl/ob/obname.c b/reactos/ntoskrnl/ob/obname.c index ecbbbe72c21..c72bfe6a0fc 100644 --- a/reactos/ntoskrnl/ob/obname.c +++ b/reactos/ntoskrnl/ob/obname.c @@ -828,7 +828,6 @@ ObQueryNameString(IN PVOID Object, else { /* Directory without a name, we add "..." */ - DPRINT("Nameless Directory\n"); ObjectName -= sizeof(L"..."); ObjectName = L"..."; break; diff --git a/reactos/ntoskrnl/ob/symlink.c b/reactos/ntoskrnl/ob/symlink.c index 1f710720b20..4107998a8f8 100644 --- a/reactos/ntoskrnl/ob/symlink.c +++ b/reactos/ntoskrnl/ob/symlink.c @@ -19,6 +19,39 @@ POBJECT_TYPE ObSymbolicLinkType = NULL; /* PRIVATE FUNCTIONS *********************************************************/ +VOID +NTAPI +ObpDeleteSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink) +{ + /* FIXME: Device maps not supported yet */ + +} + +VOID +NTAPI +ObpCreateSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink) +{ + POBJECT_HEADER ObjectHeader; + POBJECT_HEADER_NAME_INFO ObjectNameInfo; + + /* Get header data */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(SymbolicLink); + ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); + + /* Check if we are not actually in a directory with a device map */ + if (!(ObjectNameInfo) || + !(ObjectNameInfo->Directory) || + !(ObjectNameInfo->Directory->DeviceMap)) + { + /* There's nothing to do, return */ + return; + } + + /* FIXME: We don't support device maps yet */ + DPRINT1("Unhandled path!\n"); + KEBUGCHECK(0); +} + /*++ * @name ObpDeleteSymbolicLink * From adf72c70d0cd5818b42489628f091c2294306d8c Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 8 Jan 2007 20:01:04 +0000 Subject: [PATCH 14/30] Clean up tabs / spaces mix (no code change) svn path=/trunk/; revision=25386 --- reactos/subsystems/win32/win32k/ntuser/misc.c | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/misc.c b/reactos/subsystems/win32/win32k/ntuser/misc.c index 63bc4d0803b..44c245d0916 100644 --- a/reactos/subsystems/win32/win32k/ntuser/misc.c +++ b/reactos/subsystems/win32/win32k/ntuser/misc.c @@ -957,14 +957,14 @@ IntSystemParametersInfo( case SPI_SETDOUBLECLICKTIME: case SPI_SETDESKWALLPAPER: case SPI_GETDESKWALLPAPER: - case SPI_GETWHEELSCROLLLINES: - case SPI_GETWHEELSCROLLCHARS: - case SPI_SETSCREENSAVERRUNNING: - case SPI_GETSCREENSAVERRUNNING: - case SPI_GETSCREENSAVETIMEOUT: - case SPI_SETSCREENSAVETIMEOUT: - case SPI_GETSCREENSAVEACTIVE: - case SPI_GETFLATMENU: + case SPI_GETWHEELSCROLLLINES: + case SPI_GETWHEELSCROLLCHARS: + case SPI_SETSCREENSAVERRUNNING: + case SPI_GETSCREENSAVERRUNNING: + case SPI_GETSCREENSAVETIMEOUT: + case SPI_SETSCREENSAVETIMEOUT: + case SPI_GETSCREENSAVEACTIVE: + case SPI_GETFLATMENU: case SPI_SETFLATMENU: { PSYSTEM_CURSORINFO CurInfo; @@ -981,43 +981,43 @@ IntSystemParametersInfo( switch(uiAction) { - case SPI_GETFLATMENU: - if (pvParam != NULL) *((UINT*)pvParam) = WinStaObject->FlatMenu; + case SPI_GETFLATMENU: + if (pvParam != NULL) *((UINT*)pvParam) = WinStaObject->FlatMenu; return TRUE; - break; + break; case SPI_SETFLATMENU: - WinStaObject->FlatMenu = uiParam; - break; - case SPI_GETSCREENSAVETIMEOUT: - if (pvParam != NULL) *((UINT*)pvParam) = WinStaObject->ScreenSaverTimeOut; - return TRUE; - break; - case SPI_SETSCREENSAVETIMEOUT: - WinStaObject->ScreenSaverTimeOut = uiParam; - break; - case SPI_GETSCREENSAVERRUNNING: - if (pvParam != NULL) *((BOOL*)pvParam) = WinStaObject->ScreenSaverRunning; + WinStaObject->FlatMenu = uiParam; + break; + case SPI_GETSCREENSAVETIMEOUT: + if (pvParam != NULL) *((UINT*)pvParam) = WinStaObject->ScreenSaverTimeOut; return TRUE; - break; - case SPI_SETSCREENSAVERRUNNING: - if (pvParam != NULL) *((BOOL*)pvParam) = WinStaObject->ScreenSaverRunning; - WinStaObject->ScreenSaverRunning = uiParam; - break; - case SPI_GETSCREENSAVEACTIVE: - /* FIXME: how to disable the screensaver? */ - if (pvParam != NULL) *((BOOL*)pvParam) = TRUE; - return TRUE; - break; - case SPI_GETWHEELSCROLLLINES: - CurInfo = IntGetSysCursorInfo(WinStaObject); - if (pvParam != NULL) *((UINT*)pvParam) = CurInfo->WheelScroLines; - /* FIXME add this value to scroll list as scroll value ?? */ + break; + case SPI_SETSCREENSAVETIMEOUT: + WinStaObject->ScreenSaverTimeOut = uiParam; + break; + case SPI_GETSCREENSAVERRUNNING: + if (pvParam != NULL) *((BOOL*)pvParam) = WinStaObject->ScreenSaverRunning; + return TRUE; + break; + case SPI_SETSCREENSAVERRUNNING: + if (pvParam != NULL) *((BOOL*)pvParam) = WinStaObject->ScreenSaverRunning; + WinStaObject->ScreenSaverRunning = uiParam; + break; + case SPI_GETSCREENSAVEACTIVE: + /* FIXME: how to disable the screensaver? */ + if (pvParam != NULL) *((BOOL*)pvParam) = TRUE; + return TRUE; + break; + case SPI_GETWHEELSCROLLLINES: + CurInfo = IntGetSysCursorInfo(WinStaObject); + if (pvParam != NULL) *((UINT*)pvParam) = CurInfo->WheelScroLines; + /* FIXME add this value to scroll list as scroll value ?? */ return TRUE; break; case SPI_GETWHEELSCROLLCHARS: - CurInfo = IntGetSysCursorInfo(WinStaObject); - if (pvParam != NULL) *((UINT*)pvParam) = CurInfo->WheelScroChars; - // FIXME add this value to scroll list as scroll value ?? + CurInfo = IntGetSysCursorInfo(WinStaObject); + if (pvParam != NULL) *((UINT*)pvParam) = CurInfo->WheelScroChars; + // FIXME add this value to scroll list as scroll value ?? return TRUE; break; case SPI_SETDOUBLECLKWIDTH: @@ -1396,14 +1396,14 @@ UserSystemParametersInfo( case SPI_GETGRADIENTCAPTIONS: case SPI_GETFOCUSBORDERHEIGHT: case SPI_GETFOCUSBORDERWIDTH: - case SPI_GETWHEELSCROLLLINES: + case SPI_GETWHEELSCROLLLINES: case SPI_GETWHEELSCROLLCHARS: - case SPI_GETSCREENSAVERRUNNING: - case SPI_SETSCREENSAVERRUNNING: - case SPI_GETSCREENSAVETIMEOUT: - case SPI_SETSCREENSAVETIMEOUT: - case SPI_GETSCREENSAVEACTIVE: - case SPI_GETFLATMENU: + case SPI_GETSCREENSAVERRUNNING: + case SPI_SETSCREENSAVERRUNNING: + case SPI_GETSCREENSAVETIMEOUT: + case SPI_SETSCREENSAVETIMEOUT: + case SPI_GETSCREENSAVEACTIVE: + case SPI_GETFLATMENU: case SPI_SETFLATMENU: { BOOL Ret; @@ -1529,10 +1529,10 @@ UserSystemParametersInfo( return( TRUE); } default : - { - DPRINT1("FIXME: UNIMPLEMENTED SPI Code: %lx \n",uiAction ); - break; - } + { + DPRINT1("FIXME: UNIMPLEMENTED SPI Code: %lx \n",uiAction ); + break; + } } return( FALSE); } From 27fda622882885cea6003d541b5265ff6c05958f Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 20:52:45 +0000 Subject: [PATCH 15/30] - "No files where added or changed, there is nothing to see here" <= Yeah, thanks a lot Tortoise. svn path=/trunk/; revision=25387 --- reactos/include/ddk/ntddft.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 reactos/include/ddk/ntddft.h diff --git a/reactos/include/ddk/ntddft.h b/reactos/include/ddk/ntddft.h new file mode 100644 index 00000000000..4966eb2e6f2 --- /dev/null +++ b/reactos/include/ddk/ntddft.h @@ -0,0 +1,21 @@ + +#ifndef _NTDDFT_ +#define _NTDDFT_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#define FTTYPE ((ULONG)'f') + +#define FT_SECONDARY_READ CTL_CODE(FTTYPE, 4, METHOD_OUT_DIRECT, FILE_READ_ACCESS) +#define FT_PRIMARY_READ CTL_CODE(FTTYPE, 5, METHOD_OUT_DIRECT, FILE_READ_ACCESS) +#define FT_BALANCED_READ_MODE CTL_CODE(FTTYPE, 6, METHOD_NEITHER, FILE_ANY_ACCESS) +#define FT_SYNC_REDUNDANT_COPY CTL_CODE(FTTYPE, 7, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#ifdef __cplusplus +} +#endif +#endif + From 00207351ecbc78b6b7c4cc1fcb0203dcc4abac5b Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 8 Jan 2007 20:55:47 +0000 Subject: [PATCH 16/30] - Add hit-testing to the preview control (almost complete). - Add selected item combobox. - Select item in the combobox upon clicking on an item in the preview window. svn path=/trunk/; revision=25388 --- reactos/dll/cpl/desk/Fr.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/It.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/Ja.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/Ru.rc | 25 ++++++++++++- reactos/dll/cpl/desk/Uk.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/appearance.c | 22 ++++++++++++ reactos/dll/cpl/desk/cz.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/de.rc | 27 ++++++++++++-- reactos/dll/cpl/desk/en.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/es.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/gr.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/hu.rc | 25 ++++++++++++- reactos/dll/cpl/desk/nl.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/pl.rc | 26 ++++++++++++-- reactos/dll/cpl/desk/preview.c | 58 +++++++++++++++++++++++++++++++ reactos/dll/cpl/desk/preview.h | 17 +++++++++ reactos/dll/cpl/desk/resource.h | 26 +++++++++++++- reactos/dll/cpl/desk/sv.rc | 26 ++++++++++++-- 18 files changed, 458 insertions(+), 28 deletions(-) diff --git a/reactos/dll/cpl/desk/Fr.rc b/reactos/dll/cpl/desk/Fr.rc index f81081fff5c..53196da600c 100644 --- a/reactos/dll/cpl/desk/Fr.rc +++ b/reactos/dll/cpl/desk/Fr.rc @@ -59,8 +59,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Vide pour l'instant....",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -139,3 +139,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/It.rc b/reactos/dll/cpl/desk/It.rc index c0e5f7c6116..d1c3134c885 100644 --- a/reactos/dll/cpl/desk/It.rc +++ b/reactos/dll/cpl/desk/It.rc @@ -53,8 +53,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Questo spazio č stato intenzionalmente lasciato in bianco.",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -133,3 +133,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/Ja.rc b/reactos/dll/cpl/desk/Ja.rc index ceed69362cc..23e7aba13dc 100644 --- a/reactos/dll/cpl/desk/Ja.rc +++ b/reactos/dll/cpl/desk/Ja.rc @@ -57,8 +57,8 @@ FONT 9, "MS UI Gothic" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "‚±‚±‚ÍÓ}“I‚ɋ󂯂˝‚܂܂ɂµ‚Ä‚ ‚č‚Ü‚·",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 228 @@ -137,3 +137,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/Ru.rc b/reactos/dll/cpl/desk/Ru.rc index 977e0c12017..4ba9a73a728 100644 --- a/reactos/dll/cpl/desk/Ru.rc +++ b/reactos/dll/cpl/desk/Ru.rc @@ -56,7 +56,8 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Íŕńňđîéęč âđĺěĺííî îňńóňńâóţň",IDC_STATIC,65,150,114,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX 0, 0, 246, 188 @@ -147,3 +148,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/Uk.rc b/reactos/dll/cpl/desk/Uk.rc index 672c8b05787..55549e325c9 100644 --- a/reactos/dll/cpl/desk/Uk.rc +++ b/reactos/dll/cpl/desk/Uk.rc @@ -61,8 +61,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Öĺ ěłńöĺ íŕâěčńíî çŕëčřĺíĺ ďóńňčě",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -141,3 +141,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/appearance.c b/reactos/dll/cpl/desk/appearance.c index 7b2fcad930c..18a4a63e98c 100644 --- a/reactos/dll/cpl/desk/appearance.c +++ b/reactos/dll/cpl/desk/appearance.c @@ -10,6 +10,23 @@ #include "desk.h" + +static VOID +OnInitDialog(HWND hwndDlg) +{ + TCHAR szBuffer[256]; + UINT i; + + for (i = IDS_ITEM_FIRST; i < IDS_ITEM_LAST; i++) + { + LoadString(hApplet, i, szBuffer, 256); + SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_UI_ITEM, CB_ADDSTRING, 0, (LPARAM)szBuffer); + } + + SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_UI_ITEM, CB_SETCURSEL, 2, 0); +} + + INT_PTR CALLBACK AppearancePageProc(HWND hwndDlg, UINT uMsg, @@ -23,10 +40,15 @@ AppearancePageProc(HWND hwndDlg, switch (uMsg) { case WM_INITDIALOG: + OnInitDialog(hwndDlg); break; case WM_COMMAND: break; + + case WM_USER: + SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_UI_ITEM, CB_SETCURSEL, lParam, 0); + break; } return FALSE; diff --git a/reactos/dll/cpl/desk/cz.rc b/reactos/dll/cpl/desk/cz.rc index 40199b3cd70..5acbe8c54c2 100644 --- a/reactos/dll/cpl/desk/cz.rc +++ b/reactos/dll/cpl/desk/cz.rc @@ -57,8 +57,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "This space is intentionally left blank",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -131,3 +131,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/de.rc b/reactos/dll/cpl/desk/de.rc index 186a3c44668..f2ae1edebbb 100644 --- a/reactos/dll/cpl/desk/de.rc +++ b/reactos/dll/cpl/desk/de.rc @@ -55,9 +55,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - - LTEXT "This space is intentionally left blank",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 228 @@ -135,3 +134,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D-Objekte" + IDS_ITEM_SCROLLBAR "Bildlaufleiste" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Dialogfeld" + IDS_ITEM_WINDOW "Fenster" + IDS_ITEM_APP_BACKGROUND "Hintergrund der Anwendung" + IDS_ITEM_SELECTED_ITEMS "Markierte Elemente" + IDS_ITEM_MENU "Menü" + IDS_ITEM_PALETTE_TITLE "Palettentitel" + IDS_ITEM_TOOLTIP "Quickinfo" + IDS_ITEM_INACTIVE_WINDOW "Rahmen der inaktiven Fenster" + IDS_ITEM_ACTIVE_WINDOW "Rahmen der aktiven Fenster" + IDS_ITEM_ICON "Symbol" + IDS_ITEM_ICON_SPACE_HORZ "Symbolabstand (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Symbolabstand (Vertikal)" + IDS_ITEM_INACTIVE_TITLE "Titelleiste des inaktiven Fensters" + IDS_ITEM_ACTIVE_TITLE "Titelleiste des aktiven Fensters" + IDS_ITEM_CAPTION_BUTTONS "Titelleistenschaltfläche" +END diff --git a/reactos/dll/cpl/desk/en.rc b/reactos/dll/cpl/desk/en.rc index 6c5585fe3b4..4b1c0ccbb33 100644 --- a/reactos/dll/cpl/desk/en.rc +++ b/reactos/dll/cpl/desk/en.rc @@ -53,8 +53,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "This space is intentionally left blank",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -133,3 +133,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/es.rc b/reactos/dll/cpl/desk/es.rc index 3d0a6ee0860..9961962dfbf 100644 --- a/reactos/dll/cpl/desk/es.rc +++ b/reactos/dll/cpl/desk/es.rc @@ -64,8 +64,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Este espacio se ha dejado en blanco intencionadamente",IDC_STATIC,33, - 150,181,10 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -138,3 +138,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/gr.rc b/reactos/dll/cpl/desk/gr.rc index db6eb7f8d8f..b9db77127dd 100644 --- a/reactos/dll/cpl/desk/gr.rc +++ b/reactos/dll/cpl/desk/gr.rc @@ -57,8 +57,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "This space is intentionally left blank",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -137,3 +137,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/hu.rc b/reactos/dll/cpl/desk/hu.rc index 98e7167c029..476b50d5638 100644 --- a/reactos/dll/cpl/desk/hu.rc +++ b/reactos/dll/cpl/desk/hu.rc @@ -49,7 +49,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Ez a terület szándékosan lett üresen hagyva",IDC_STATIC,66,150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -125,3 +126,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/nl.rc b/reactos/dll/cpl/desk/nl.rc index fe5d808381e..cd5cdb6d0c1 100644 --- a/reactos/dll/cpl/desk/nl.rc +++ b/reactos/dll/cpl/desk/nl.rc @@ -57,8 +57,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "This space is intentionally left blank",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -131,3 +131,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/pl.rc b/reactos/dll/cpl/desk/pl.rc index 629d932090e..c77aba79219 100644 --- a/reactos/dll/cpl/desk/pl.rc +++ b/reactos/dll/cpl/desk/pl.rc @@ -58,8 +58,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "To miejsce pozostało celowo puste",IDC_STATIC,66, - 150,112,8 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -132,3 +132,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END diff --git a/reactos/dll/cpl/desk/preview.c b/reactos/dll/cpl/desk/preview.c index 467e923c320..ae83c1b06b9 100644 --- a/reactos/dll/cpl/desk/preview.c +++ b/reactos/dll/cpl/desk/preview.c @@ -13,6 +13,8 @@ static const TCHAR szPreviewWndClass[] = TEXT("PreviewWndClass"); typedef struct _PREVIEW_DATA { + HWND hwndParent; + DWORD clrDesktop; HBRUSH hbrDesktop; @@ -39,6 +41,7 @@ typedef struct _PREVIEW_DATA RECT rcActiveFrame; RECT rcActiveCaption; RECT rcActiveMenuBar; + RECT rcSelectedMenuItem; RECT rcActiveClient; RECT rcActiveScroll; @@ -176,6 +179,9 @@ OnCreate(HWND hwnd, PPREVIEW_DATA pPreviewData) HiliteMenuItem(hwnd, pPreviewData->hMenu, ID_MENU_SELECTED, MF_BYCOMMAND | MF_HILITE); +// GetMenuItemRect(hwnd, pPreviewData->hMenu, +// ID_MENU_SELECTED, &pPreviewData->rcSelectedMenuItem); + AllocAndLoadString(&pPreviewData->lpInAct, hApplet, IDS_INACTWIN); AllocAndLoadString(&pPreviewData->lpAct, hApplet, IDS_ACTWIN); @@ -347,6 +353,54 @@ OnPaint(HWND hwnd, PPREVIEW_DATA pPreviewData) } +static VOID +OnLButtonDown(HWND hwnd, int xPos, int yPos, PPREVIEW_DATA pPreviewData) +{ + UINT type = IDX_DESKTOP; + POINT pt; + + pt.x = xPos; + pt.y = yPos; + + if (PtInRect(&pPreviewData->rcInactiveFrame, pt)) + type = IDX_INACTIVE_BORDER; + + if (PtInRect(&pPreviewData->rcInactiveCaption, pt)) + type = IDX_INACTIVE_CAPTION; + + + if (PtInRect(&pPreviewData->rcActiveFrame, pt)) + type = IDX_ACTIVE_BORDER; + + if (PtInRect(&pPreviewData->rcActiveCaption, pt)) + type = IDX_ACTIVE_CAPTION; + + if (PtInRect(&pPreviewData->rcActiveMenuBar, pt)) + type = IDX_MENU; + +// if (PtInRect(&pPreviewData->rcSelectedMenuItem, pt)) +// type = IDX_SELECTION; + + if (PtInRect(&pPreviewData->rcActiveClient, pt)) + type = IDX_WINDOW; + + if (PtInRect(&pPreviewData->rcActiveScroll, pt)) + type = IDX_SCROLLBAR; + + + if (PtInRect(&pPreviewData->rcDialogFrame, pt)) + type = IDX_DIALOG; + + if (PtInRect(&pPreviewData->rcDialogCaption, pt)) + type = IDX_ACTIVE_CAPTION; + + if (PtInRect(&pPreviewData->rcDialogButton, pt)) + type = IDX_3D_OBJECTS; + + SendMessage(GetParent(hwnd), WM_USER, 0, type); +} + + static VOID OnDestroy(PPREVIEW_DATA pPreviewData) { @@ -400,6 +454,10 @@ PreviewWndProc(HWND hwnd, OnPaint(hwnd, pPreviewData); break; + case WM_LBUTTONDOWN: + OnLButtonDown(hwnd, LOWORD(lParam), HIWORD(lParam), pPreviewData); + break; + case WM_DESTROY: OnDestroy(pPreviewData); HeapFree(GetProcessHeap(), 0, pPreviewData); diff --git a/reactos/dll/cpl/desk/preview.h b/reactos/dll/cpl/desk/preview.h index 5d4cbeef6f2..8b5852cad53 100644 --- a/reactos/dll/cpl/desk/preview.h +++ b/reactos/dll/cpl/desk/preview.h @@ -1,4 +1,21 @@ +#define IDX_3D_OBJECTS 0 +#define IDX_SCROLLBAR 1 +#define IDX_DESKTOP 2 +#define IDX_DIALOG 3 +#define IDX_WINDOW 4 +#define IDX_APPSPACE 5 +#define IDX_SELECTION 6 +#define IDX_MENU 7 + +#define IDX_QUICKINFO 9 +#define IDX_INACTIVE_BORDER 10 +#define IDX_ACTIVE_BORDER 11 + +#define IDX_INACTIVE_CAPTION 15 +#define IDX_ACTIVE_CAPTION 16 +#define IDX_CAPTION_BUTTON 17 + BOOL RegisterPreviewControl(IN HINSTANCE hInstance); VOID UnregisterPreviewControl(IN HINSTANCE hInstance); diff --git a/reactos/dll/cpl/desk/resource.h b/reactos/dll/cpl/desk/resource.h index f362b8895bf..f83d9cbd49f 100644 --- a/reactos/dll/cpl/desk/resource.h +++ b/reactos/dll/cpl/desk/resource.h @@ -84,7 +84,8 @@ /* Appearance Page */ -#define IDC_APPEARANCE_PREVIEW 1500 +#define IDC_APPEARANCE_PREVIEW 1500 +#define IDC_APPEARANCE_UI_ITEM 1501 #define IDS_INACTWIN 1510 #define IDS_ACTWIN 1511 @@ -93,6 +94,29 @@ #define IDS_MESSTEXT 1514 #define IDS_BUTTEXT 1515 +#define IDS_ITEM_3D_OBJECTS 1601 +#define IDS_ITEM_SCROLLBAR 1602 +#define IDS_ITEM_DESKTOP 1603 +#define IDS_ITEM_MESSAGE_BOX 1604 +#define IDS_ITEM_WINDOW 1605 +#define IDS_ITEM_APP_BACKGROUND 1606 +#define IDS_ITEM_SELECTED_ITEMS 1607 +#define IDS_ITEM_MENU 1608 +#define IDS_ITEM_PALETTE_TITLE 1609 +#define IDS_ITEM_TOOLTIP 1610 +#define IDS_ITEM_INACTIVE_WINDOW 1611 +#define IDS_ITEM_ACTIVE_WINDOW 1612 +#define IDS_ITEM_ICON 1613 +#define IDS_ITEM_ICON_SPACE_HORZ 1614 +#define IDS_ITEM_ICON_SPACE_VERT 1615 +#define IDS_ITEM_INACTIVE_TITLE 1616 +#define IDS_ITEM_ACTIVE_TITLE 1617 +#define IDS_ITEM_CAPTION_BUTTONS 1618 + +/* Update these IDs when you change the string id list */ +#define IDS_ITEM_FIRST (IDS_ITEM_3D_OBJECTS) +#define IDS_ITEM_LAST (IDS_ITEM_CAPTION_BUTTONS + 1) + #endif /* __CPL_DESK_RESOURCE_H__ */ diff --git a/reactos/dll/cpl/desk/sv.rc b/reactos/dll/cpl/desk/sv.rc index 96cd72d5216..a2b443ca3db 100644 --- a/reactos/dll/cpl/desk/sv.rc +++ b/reactos/dll/cpl/desk/sv.rc @@ -60,8 +60,8 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Det här utrymmet har avsiktligt\nlämnats tomt",IDC_STATIC,66, - 150,112,20 + LTEXT "Item:", IDC_STATIC, 7, 159, 26, 9 + COMBOBOX IDC_APPEARANCE_UI_ITEM, 7, 169, 120, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_SETTINGS DIALOGEX DISCARDABLE 0, 0, 246, 188 @@ -134,3 +134,25 @@ BEGIN IDS_MESSTEXT "Message Text" IDS_BUTTEXT "OK" END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ITEM_3D_OBJECTS "3D Objects" + IDS_ITEM_SCROLLBAR "Scrollbar" + IDS_ITEM_DESKTOP "Desktop" + IDS_ITEM_MESSAGE_BOX "Message Box" + IDS_ITEM_WINDOW "Window" + IDS_ITEM_APP_BACKGROUND "Application Background" + IDS_ITEM_SELECTED_ITEMS "Selected Items" + IDS_ITEM_MENU "Menu" + IDS_ITEM_PALETTE_TITLE "Palette Title" + IDS_ITEM_TOOLTIP "Tooltip" + IDS_ITEM_INACTIVE_WINDOW "Inactive Window Border" + IDS_ITEM_ACTIVE_WINDOW "Active Window Border" + IDS_ITEM_ICON "Icon" + IDS_ITEM_ICON_SPACE_HORZ "Icon Spacing (Horizontal)" + IDS_ITEM_ICON_SPACE_VERT "Icon Spacing (Vertical)" + IDS_ITEM_INACTIVE_TITLE "Inactive Title Bar" + IDS_ITEM_ACTIVE_TITLE "Active Title Bar" + IDS_ITEM_CAPTION_BUTTONS "Caption Buttons" +END From 9de4aee541e066caf6b4aa6b72246ca7b4c1fdd1 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 8 Jan 2007 21:02:22 +0000 Subject: [PATCH 17/30] - Make ObpReleaseCapturedName an actual function and rename it to ObpFreeObjectNameBuffer. Fix a bug in this function which was causing it to attempt freeing the UNICODE_STRING structure instead of the actual buffer. - Implement ObpAllocateObjectNameBuffer instead of inlined code in ObpCaptureObjectAttributes. Enable usage of the Name Buffer Lookaside List since the bug in ObpFreeObjectNameBuffer has now been fixed. This should result in significant speedup and less fragmentation of pool memory. - Allocate object names in the paged pool instead of non-paged pool, if we can't use the lookaside list. svn path=/trunk/; revision=25389 --- reactos/ntoskrnl/cm/ntfunc.c | 6 +- reactos/ntoskrnl/cm/registry.c | 2 +- reactos/ntoskrnl/include/internal/ob.h | 6 ++ reactos/ntoskrnl/include/internal/ob_x.h | 20 +---- reactos/ntoskrnl/ob/obhandle.c | 6 +- reactos/ntoskrnl/ob/oblife.c | 102 +++++++++++++++-------- reactos/ntoskrnl/ob/obref.c | 2 +- 7 files changed, 82 insertions(+), 62 deletions(-) diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 2e42400d0fc..9f1a5e6a74f 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -577,7 +577,7 @@ Cleanup: ReleaseCapturedUnicodeString(&CapturedClass, PreviousMode); } - if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName); + if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); if (FreeRemainingPath) RtlFreeUnicodeString(&RemainingPath); //if (Object != NULL) ObDereferenceObject(Object); @@ -1384,7 +1384,7 @@ NtOpenKey(OUT PHANDLE KeyHandle, PostOpenKeyInfo.Status = Status; CmiCallRegisteredCallbacks (RegNtPostOpenKey, &PostOpenKeyInfo); ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName); + if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); return Status; } @@ -1436,7 +1436,7 @@ openkey_cleanup: PostOpenKeyInfo.Object = NT_SUCCESS(Status) ? (PVOID)Object : NULL; PostOpenKeyInfo.Status = Status; CmiCallRegisteredCallbacks (RegNtPostOpenKey, &PostOpenKeyInfo); - if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName); + if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); if (Object) { diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index c2b14f2dfe6..3812583d8da 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -548,7 +548,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, /* Yields a new reference */ ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName); + if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); if (!NT_SUCCESS(Status)) { return Status; diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index 211a05bb6b7..0c845d2aa60 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -288,6 +288,12 @@ ObFreeObjectCreateInfoBuffer( IN POBJECT_CREATE_INFORMATION ObjectCreateInfo ); +VOID +NTAPI +ObpFreeObjectNameBuffer( + IN PUNICODE_STRING Name +); + // // DOS Devices Functions // diff --git a/reactos/ntoskrnl/include/internal/ob_x.h b/reactos/ntoskrnl/include/internal/ob_x.h index c09fb5ed5b0..12cb5e9735b 100644 --- a/reactos/ntoskrnl/include/internal/ob_x.h +++ b/reactos/ntoskrnl/include/internal/ob_x.h @@ -130,7 +130,7 @@ ObpAllocateCapturedAttributes(IN PP_NPAGED_LOOKASIDE_NUMBER Type) } VOID -static __inline +FORCEINLINE ObpFreeCapturedAttributes(IN PVOID Buffer, IN PP_NPAGED_LOOKASIDE_NUMBER Type) { @@ -168,23 +168,7 @@ ObpFreeCapturedAttributes(IN PVOID Buffer, } VOID -static __inline -ObpReleaseCapturedName(IN PUNICODE_STRING Name) -{ - /* We know this is a pool-allocation if the size doesn't match */ - if (Name->MaximumLength != 248) - { - ExFreePool(Name->Buffer); - } - else - { - /* Otherwise, free from the lookaside */ - ObpFreeCapturedAttributes(Name, LookasideNameBufferList); - } -} - -VOID -static __inline +FORCEINLINE ObpFreeAndReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo) { /* First release the attributes, then free them from the lookaside list */ diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index 4adfe5a9a8e..1746b437a11 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -2090,7 +2090,7 @@ Cleanup: Quickie: /* Release the object attributes and temporary buffer */ ObpReleaseCapturedAttributes(&TempBuffer->ObjectCreateInfo); - if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName); + if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); ExFreePool(TempBuffer); /* Return status */ @@ -2673,9 +2673,7 @@ NTSTATUS NTAPI NtClose(IN HANDLE Handle) { - // - // Call the internal API - // + /* Call the internal API */ return ObpCloseHandle(Handle, ExGetPreviousMode()); } diff --git a/reactos/ntoskrnl/ob/oblife.c b/reactos/ntoskrnl/ob/oblife.c index 54be69e9aa3..6384275e179 100644 --- a/reactos/ntoskrnl/ob/oblife.c +++ b/reactos/ntoskrnl/ob/oblife.c @@ -285,17 +285,70 @@ ObpSetPermanentObject(IN PVOID ObjectBody, } } +PWCHAR +NTAPI +ObpAllocateObjectNameBuffer(IN ULONG Length, + IN BOOLEAN UseLookaside, + IN OUT PUNICODE_STRING ObjectName) +{ + ULONG MaximumLength; + PVOID Buffer; + + /* Set the maximum length to the length plus the terminator */ + MaximumLength = Length + sizeof(UNICODE_NULL); + + /* Check if we should use the lookaside buffer */ + if (!(UseLookaside) || (MaximumLength > 248)) + { + /* Nope, allocate directly from pool */ + Buffer = ExAllocatePoolWithTag(PagedPool, + MaximumLength, + OB_NAME_TAG); + } + else + { + /* Allocate from the lookaside */ + //MaximumLength = 248; <= hack, we should actually set this...! + Buffer = ObpAllocateCapturedAttributes(LookasideNameBufferList); + } + + /* Setup the string */ + ObjectName->Length = (USHORT)Length; + ObjectName->MaximumLength = (USHORT)MaximumLength; + ObjectName->Buffer = Buffer; + return Buffer; +} + +VOID +NTAPI +ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name) +{ + PVOID Buffer = Name->Buffer; + + /* We know this is a pool-allocation if the size doesn't match */ + if (Name->MaximumLength != 248) + { + /* Free it from the pool */ + ExFreePool(Buffer); + } + else + { + /* Otherwise, free from the lookaside */ + ObpFreeCapturedAttributes(Buffer, LookasideNameBufferList); + } +} + NTSTATUS NTAPI ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName, IN PUNICODE_STRING ObjectName, IN KPROCESSOR_MODE AccessMode, - IN BOOLEAN AllocateFromLookaside) + IN BOOLEAN UseLookaside) { NTSTATUS Status = STATUS_SUCCESS; - ULONG StringLength, MaximumLength; + ULONG StringLength; PWCHAR StringBuffer = NULL; - UNICODE_STRING LocalName = {0}; /* <= GCC 4.0 + Optimizer */ + UNICODE_STRING LocalName; PAGED_CODE(); /* Initialize the Input String */ @@ -331,41 +384,20 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName, } else { - /* Set the maximum length to the length plus the terminator */ - MaximumLength = StringLength + sizeof(UNICODE_NULL); - - /* Check if we should use the lookaside buffer */ - //if (!(AllocateFromLookaside) || (MaximumLength > 248)) + /* Allocate the string buffer */ + StringBuffer = ObpAllocateObjectNameBuffer(StringLength, + UseLookaside, + CapturedName); + if (!StringBuffer) { - /* Nope, allocate directly from pool */ - StringBuffer = ExAllocatePoolWithTag(NonPagedPool, - MaximumLength, - OB_NAME_TAG); - } - //else - { - /* Allocate from the lookaside */ - // MaximumLength = 248; - // StringBuffer = - // ObpAllocateCapturedAttributes(LookasideNameBufferList); - } - - /* Setup the string */ - CapturedName->Length = (USHORT)StringLength; - CapturedName->MaximumLength = (USHORT)MaximumLength; - CapturedName->Buffer = StringBuffer; - - /* Make sure we have a buffer */ - if (StringBuffer) - { - /* Copy the string and null-terminate it */ - RtlMoveMemory(StringBuffer, LocalName.Buffer, StringLength); - StringBuffer[StringLength / sizeof(WCHAR)] = UNICODE_NULL; + /* Set failure code */ + Status = STATUS_INSUFFICIENT_RESOURCES; } else { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; + /* Copy the name */ + RtlMoveMemory(StringBuffer, LocalName.Buffer, StringLength); + StringBuffer[StringLength / sizeof(WCHAR)] = UNICODE_NULL; } } } @@ -875,7 +907,7 @@ ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, /* Release the Capture Info, we don't need it */ ObpReleaseCapturedAttributes(ObjectCreateInfo); - if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName); + if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); } /* We failed, so release the Buffer */ diff --git a/reactos/ntoskrnl/ob/obref.c b/reactos/ntoskrnl/ob/obref.c index eeabc23e942..d0f51d131ee 100644 --- a/reactos/ntoskrnl/ob/obref.c +++ b/reactos/ntoskrnl/ob/obref.c @@ -454,7 +454,7 @@ ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath, Quickie: /* Free the captured name if we had one, and return status */ - if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName); + ObpFreeObjectNameBuffer(&ObjectName); return Status; } From 5b83954756caf775c85183b0f3d3584572c37a94 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 9 Jan 2007 00:17:23 +0000 Subject: [PATCH 18/30] -don't create project files for the ISO targets -use the new extended_obj_names to prevent C::B from linking the wrong libs -change project file version to 1.6 -compile spec, S, asm and idl files -delete the temp rc files after building svn path=/trunk/; revision=25390 --- .../rbuild/backend/codeblocks/codeblocks.cpp | 75 +++++++++++++++++-- .../rbuild/backend/codeblocks/codeblocks.h | 1 + 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/reactos/tools/rbuild/backend/codeblocks/codeblocks.cpp b/reactos/tools/rbuild/backend/codeblocks/codeblocks.cpp index 9a57c8fcd26..7e29c1b42a2 100644 --- a/reactos/tools/rbuild/backend/codeblocks/codeblocks.cpp +++ b/reactos/tools/rbuild/backend/codeblocks/codeblocks.cpp @@ -342,6 +342,7 @@ CBBackend::_generate_cbproj ( const Module& module ) string CompilerVar; string baseaddr; string windres_defines; + string widl_options; string project_linker_flags = "-Wl,--enable-stdcall-fixup "; project_linker_flags += GenerateProjectLinkerFlags(); @@ -353,7 +354,20 @@ CBBackend::_generate_cbproj ( const Module& module ) vector source_files, resource_files, includes, libraries, libpaths; vector header_files, common_defines, compiler_flags; vector vars, values; - + + /* do not create project files for these targets + use virtual targets instead */ + switch (module.type) + { + case Iso: + case LiveIso: + case IsoRegTest: + case LiveIsoRegTest: + return; + default: + break; + } + compiler_flags.push_back ( "-Wall" ); // Always force disabling of sibling calls optimisation for GCC @@ -414,6 +428,7 @@ CBBackend::_generate_cbproj ( const Module& module ) module.GetBasePath() ); includes.push_back ( path ); + widl_options += "-I" + path + " "; } const vector& libs = data.libraries; for ( i = 0; i < libs.size(); i++ ) @@ -467,12 +482,13 @@ CBBackend::_generate_cbproj ( const Module& module ) fprintf ( OUT, "\r\n" ); fprintf ( OUT, "\r\n" ); - fprintf ( OUT, "\t\r\n" ); + fprintf ( OUT, "\t\r\n" ); fprintf ( OUT, "\t\r\n" ); fprintf ( OUT, "\t\t