diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index 5e303647d5c..c7bf4686acd 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -84,14 +84,17 @@ ObCreateHandleTable( NTSTATUS NTAPI ObFindObject( - POBJECT_CREATE_INFORMATION ObjectCreateInfo, - PUNICODE_STRING ObjectName, - PVOID* ReturnedObject, - PUNICODE_STRING RemainingPath, - POBJECT_TYPE ObjectType, - POBP_LOOKUP_CONTEXT Context, + 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 PVOID ParseContext + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN PVOID ParseContext, + IN PVOID Insert ); NTSTATUS diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index a8d7415e05c..b7127bcc806 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -754,7 +754,6 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN OUT PVOID ParseContext, OUT PHANDLE Handle) { - UNICODE_STRING RemainingPath; PVOID Object = NULL; UNICODE_STRING ObjectName; OBJECT_CREATE_INFORMATION ObjectCreateInfo; @@ -797,26 +796,19 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, } /* Now do the lookup */ - Status = ObFindObject(&ObjectCreateInfo, + Status = ObFindObject(ObjectCreateInfo.RootDirectory, &ObjectName, + ObjectCreateInfo.Attributes, + AccessMode, &Object, - &RemainingPath, ObjectType, - &Context, // Temporary Hack + &Context, PassedAccessState, - ParseContext); + ObjectCreateInfo.SecurityQos, + ParseContext, + NULL); if (!NT_SUCCESS(Status)) goto Cleanup; - /* ROS Hack */ - if (RemainingPath.Buffer != NULL) - { - if (wcschr(RemainingPath.Buffer + 1, L'\\') == NULL) - Status = STATUS_OBJECT_NAME_NOT_FOUND; - else - Status =STATUS_OBJECT_PATH_NOT_FOUND; - goto Cleanup; - } - /* Create the actual handle now */ Status = ObpCreateHandle(Object, DesiredAccess, @@ -827,9 +819,6 @@ Cleanup: /* Dereference the object */ if (Object) ObDereferenceObject(Object); - /* ROS Hacl: Free the remaining path */ - RtlFreeUnicodeString(&RemainingPath); - /* Delete the access state */ if (PassedAccessState == &AccessState) { @@ -923,15 +912,13 @@ ObInsertObject(IN PVOID Object, { POBJECT_CREATE_INFORMATION ObjectCreateInfo; POBJECT_HEADER Header; - POBJECT_HEADER_NAME_INFO ObjectNameInfo; PVOID FoundObject = NULL; POBJECT_HEADER FoundHeader = NULL; NTSTATUS Status = STATUS_SUCCESS; - UNICODE_STRING RemainingPath; - BOOLEAN ObjectAttached = FALSE; PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL; SECURITY_SUBJECT_CONTEXT SubjectContext; OBP_LOOKUP_CONTEXT Context; + POBJECT_HEADER_NAME_INFO ObjectNameInfo; PAGED_CODE(); /* Get the Header and Create Info */ @@ -942,111 +929,69 @@ ObInsertObject(IN PVOID Object, /* First try to find the Object */ if (ObjectNameInfo && ObjectNameInfo->Name.Buffer) { - DPRINT("Object has a name. Trying to find it: %wZ.\n", &ObjectNameInfo->Name); - Status = ObFindObject(ObjectCreateInfo, + Status = ObFindObject(ObjectCreateInfo->RootDirectory, &ObjectNameInfo->Name, + ObjectCreateInfo->Attributes, + KernelMode, &FoundObject, - &RemainingPath, - NULL, + Header->Type, &Context, NULL, - NULL); - DPRINT("FoundObject: %x, Path: %wZ\n", FoundObject, &RemainingPath); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ObFindObject() failed! (Status 0x%x)\n", Status); - return Status; - } + ObjectCreateInfo->SecurityQos, + NULL, + Object); + if (!NT_SUCCESS(Status)) return Status; if (FoundObject) { DPRINT("Getting header: %x\n", FoundObject); FoundHeader = OBJECT_TO_OBJECT_HEADER(FoundObject); } - - if (FoundHeader && RemainingPath.Buffer == NULL) - { - DPRINT("Object exists\n"); - ObDereferenceObject(FoundObject); - return STATUS_OBJECT_NAME_COLLISION; - } } else { - DPRINT("No name, empty remaining path\n"); - RtlInitUnicodeString(&RemainingPath, NULL); - } - - if (FoundHeader && FoundHeader->Type == ObDirectoryType && - RemainingPath.Buffer) - { - /* The name was changed so let's update it */ - /* FIXME: TEMPORARY HACK This will go in ObFindObject in the next commit */ - PVOID NewName; - PWSTR BufferPos = RemainingPath.Buffer; - ULONG Delta = 0; - - ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(Header); - - if (BufferPos[0] == L'\\') + /* + * OK, if we got here then that means we don't have a name, + * so RemainingPath.Buffer/RemainingPath would've been NULL + * under the old implemetantation, so just use NULL. + * If remaining path wouldn't have been NULL, then we would've + * called ObFindObject which already has this code. + * We basically kill 3-4 hacks and add 2 new ones. + */ + if ((Header->Type == IoFileObjectType) || + (Header->Type->TypeInfo.OpenProcedure != NULL)) { - BufferPos++; - Delta = sizeof(WCHAR); - } - NewName = ExAllocatePool(NonPagedPool, RemainingPath.MaximumLength - Delta); - RtlMoveMemory(NewName, BufferPos, RemainingPath.MaximumLength - Delta); - if (ObjectNameInfo->Name.Buffer) ExFreePool(ObjectNameInfo->Name.Buffer); - ObjectNameInfo->Name.Buffer = NewName; - ObjectNameInfo->Name.Length = RemainingPath.Length - Delta; - ObjectNameInfo->Name.MaximumLength = RemainingPath.MaximumLength - Delta; - ObpInsertEntryDirectory(FoundObject, &Context, Header); - ObjectAttached = TRUE; - } - - if ((Header->Type == IoFileObjectType) || - (Header->Type->TypeInfo.OpenProcedure != NULL)) - { - DPRINT("About to call Open Routine\n"); - if (Header->Type == IoFileObjectType) - { - /* TEMPORARY HACK. DO NOT TOUCH -- Alex */ - DPRINT("Calling IopCreateFile: %x\n", FoundObject); - Status = IopCreateFile(&Header->Body, - FoundObject, - RemainingPath.Buffer, - ObjectCreateInfo); - DPRINT("Called IopCreateFile: %x\n", Status); - - } - else if (Header->Type->TypeInfo.OpenProcedure != NULL) - { - DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure); - Status = Header->Type->TypeInfo.OpenProcedure(ObCreateHandle, - NULL, - &Header->Body, - 0, - 0); - } - - if (!NT_SUCCESS(Status)) - { - DPRINT("Create Failed\n"); - if (ObjectAttached == TRUE) + DPRINT("About to call Open Routine\n"); + if (Header->Type == IoFileObjectType) { - ObpDeleteEntryDirectory(&Context); + /* TEMPORARY HACK. DO NOT TOUCH -- Alex */ + DPRINT("Calling IopCreateFile: %x\n", FoundObject); + Status = IopCreateFile(&Header->Body, + FoundObject, + NULL, + NULL); + DPRINT("Called IopCreateFile: %x\n", Status); } - if (FoundObject) + else if (Header->Type->TypeInfo.OpenProcedure) { - ObDereferenceObject(FoundObject); + DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure); + Status = Header->Type->TypeInfo.OpenProcedure(ObCreateHandle, + NULL, + &Header->Body, + 0, + 0); + } + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Create Failed\n"); + if (FoundObject) ObDereferenceObject(FoundObject); + return Status; } - RtlFreeUnicodeString(&RemainingPath); - return Status; } } - RtlFreeUnicodeString(&RemainingPath); - - DPRINT("Security Assignment in progress\n"); + DPRINT("Security Assignment in progress\n"); SeCaptureSubjectContext(&SubjectContext); /* Build the new security descriptor */ diff --git a/reactos/ntoskrnl/ob/obname.c b/reactos/ntoskrnl/ob/obname.c index 5fa8c44eab4..4fef72bf7f5 100644 --- a/reactos/ntoskrnl/ob/obname.c +++ b/reactos/ntoskrnl/ob/obname.c @@ -22,24 +22,28 @@ POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL; NTSTATUS NTAPI -ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, - PUNICODE_STRING ObjectName, - PVOID* ReturnedObject, - PUNICODE_STRING RemainingPath, - POBJECT_TYPE ObjectType, - POBP_LOOKUP_CONTEXT Context, +ObFindObject(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 PVOID ParseContext) + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN PVOID ParseContext, + IN PVOID Insert) { PVOID NextObject; PVOID CurrentObject; PVOID RootObject; POBJECT_HEADER CurrentHeader; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PWSTR current; UNICODE_STRING PathString; - ULONG Attributes; UNICODE_STRING CurrentUs; + UNICODE_STRING Path; + PUNICODE_STRING RemainingPath = &Path; PAGED_CODE(); @@ -48,20 +52,20 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, RtlInitUnicodeString (RemainingPath, NULL); - if (ObjectCreateInfo->RootDirectory == NULL) + if (RootHandle == NULL) { ObReferenceObjectByPointer(NameSpaceRoot, DIRECTORY_TRAVERSE, NULL, - ObjectCreateInfo->ProbeMode); + PreviousMode); CurrentObject = NameSpaceRoot; } else { - Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory, + Status = ObReferenceObjectByHandle(RootHandle, 0, NULL, - ObjectCreateInfo->ProbeMode, + PreviousMode, &CurrentObject, NULL); if (!NT_SUCCESS(Status)) @@ -77,7 +81,7 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, return STATUS_SUCCESS; } - if (ObjectCreateInfo->RootDirectory == NULL && + if (RootHandle == NULL && ObjectName->Buffer[0] != L'\\') { ObDereferenceObject (CurrentObject); @@ -104,7 +108,6 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, current = PathString.Buffer; RootObject = CurrentObject; - Attributes = ObjectCreateInfo->Attributes; if (ObjectType == ObSymbolicLinkType) Attributes |= OBJ_OPENLINK; @@ -194,7 +197,7 @@ Next: ObReferenceObjectByPointer(NextObject, DIRECTORY_TRAVERSE, NULL, - ObjectCreateInfo->ProbeMode); + PreviousMode); } @@ -214,7 +217,114 @@ Next: RtlFreeUnicodeString (&PathString); *ReturnedObject = CurrentObject; - return STATUS_SUCCESS; + /* + * Icky hack: put the code that was in ObInsertObject here so that + * we can get rid of the "RemainingPath" stuff, which shouldn't + * be exposed outside of here. + * Also makes the interface closer to NT parsing, and will make the + * eventual changes easier to deal with + */ + if (Insert) + { + PVOID FoundObject = NULL; + POBJECT_HEADER Header = OBJECT_TO_OBJECT_HEADER(Insert); + POBJECT_HEADER FoundHeader = NULL; + BOOLEAN ObjectAttached = FALSE; + FoundObject = *ReturnedObject; + if (FoundObject) + { + FoundHeader = OBJECT_TO_OBJECT_HEADER(FoundObject); + } + + if (FoundHeader && RemainingPath->Buffer == NULL) + { + DPRINT("Object exists\n"); + ObDereferenceObject(FoundObject); + return STATUS_OBJECT_NAME_COLLISION; + } + + if (FoundHeader && FoundHeader->Type == ObDirectoryType && + RemainingPath->Buffer) + { + /* The name was changed so let's update it */ + PVOID NewName; + PWSTR BufferPos = RemainingPath->Buffer; + ULONG Delta = 0; + POBJECT_HEADER_NAME_INFO ObjectNameInfo; + + ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(Header); + + if (BufferPos[0] == L'\\') + { + BufferPos++; + Delta = sizeof(WCHAR); + } + NewName = ExAllocatePool(NonPagedPool, RemainingPath->MaximumLength - Delta); + RtlMoveMemory(NewName, BufferPos, RemainingPath->MaximumLength - Delta); + if (ObjectNameInfo->Name.Buffer) ExFreePool(ObjectNameInfo->Name.Buffer); + ObjectNameInfo->Name.Buffer = NewName; + ObjectNameInfo->Name.Length = RemainingPath->Length - Delta; + ObjectNameInfo->Name.MaximumLength = RemainingPath->MaximumLength - Delta; + ObpInsertEntryDirectory(FoundObject, Context, Header); + ObjectAttached = TRUE; + } + + if ((Header->Type == IoFileObjectType) || + (Header->Type->TypeInfo.OpenProcedure != NULL)) + { + DPRINT("About to call Open Routine\n"); + if (Header->Type == IoFileObjectType) + { + /* TEMPORARY HACK. DO NOT TOUCH -- Alex */ + DPRINT("Calling IopCreateFile: %x\n", FoundObject); + Status = IopCreateFile(&Header->Body, + FoundObject, + RemainingPath->Buffer, + NULL); + DPRINT("Called IopCreateFile: %x\n", Status); + + } + else if (Header->Type->TypeInfo.OpenProcedure != NULL) + { + DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure); + Status = Header->Type->TypeInfo.OpenProcedure(ObCreateHandle, + NULL, + &Header->Body, + 0, + 0); + } + + if (!NT_SUCCESS(Status)) + { + DPRINT("Create Failed\n"); + if (ObjectAttached == TRUE) + { + ObpDeleteEntryDirectory(Context); + } + if (FoundObject) + { + ObDereferenceObject(FoundObject); + } + RtlFreeUnicodeString(RemainingPath); + return Status; + } + } + RtlFreeUnicodeString(RemainingPath); + } + else + { + /* ROS Hack */ + DPRINT("REmaining path: %wZ\n", RemainingPath); + if (RemainingPath->Buffer != NULL) + { + if (wcschr(RemainingPath->Buffer + 1, L'\\') == NULL) + Status = STATUS_OBJECT_NAME_NOT_FOUND; + else + Status =STATUS_OBJECT_PATH_NOT_FOUND; + } + } + + return Status; } /* PUBLIC FUNCTIONS *********************************************************/ diff --git a/reactos/ntoskrnl/ob/obref.c b/reactos/ntoskrnl/ob/obref.c index a0a33b2253e..7537ee6e0dd 100644 --- a/reactos/ntoskrnl/ob/obref.c +++ b/reactos/ntoskrnl/ob/obref.c @@ -200,9 +200,7 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath, PVOID* ObjectPtr) { PVOID Object = NULL; - UNICODE_STRING RemainingPath; UNICODE_STRING ObjectName; - OBJECT_CREATE_INFORMATION ObjectCreateInfo; NTSTATUS Status; OBP_LOOKUP_CONTEXT Context; AUX_DATA AuxData; @@ -224,27 +222,24 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath, if (!NT_SUCCESS(Status)) goto Quickie; } - /* - * Create a fake ObjectCreateInfo structure. Note that my upcoming - * ObFindObject refactoring will remove the need for this hack. - */ - ObjectCreateInfo.RootDirectory = NULL; - ObjectCreateInfo.Attributes = Attributes; - Status = ObFindObject(&ObjectCreateInfo, + /* Find the object */ + Status = ObFindObject(NULL, &ObjectName, + Attributes, + AccessMode, &Object, - &RemainingPath, ObjectType, &Context, PassedAccessState, - ParseContext); + NULL, + ParseContext, + NULL); if (!NT_SUCCESS(Status)) goto Quickie; /* ROS Hack */ - if (RemainingPath.Buffer != NULL || Object == NULL) + if (Object == NULL) { *ObjectPtr = NULL; - RtlFreeUnicodeString (&RemainingPath); Status = STATUS_OBJECT_NAME_NOT_FOUND; goto Quickie; } @@ -252,9 +247,6 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath, /* Return the object */ *ObjectPtr = Object; - /* ROS Hack: Free the remaining path */ - RtlFreeUnicodeString(&RemainingPath); - /* Free the access state */ if (PassedAccessState == &AccessState) { diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index a0dc58bbd9c..976a60d7dad 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -150,7 +150,7 @@ IntDesktopObjectParse(IN PVOID ParseObject, Status = ObCreateObject(KernelMode, ExDesktopObjectType, &ObjectAttributes, - UserMode, + KernelMode, NULL, sizeof(DESKTOP_OBJECT), 0,