X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fob%2Fobname.c;h=8d601eed77b28eba5d3a2a288c17fa034735e879;hp=a514af7b1950b7b08a478f84c6834990b68199ae;hb=753f07c723690b484ad19095c9009ccff183423f;hpb=d1e00dac5ccc209020221fbc759080e31ae5cacd diff --git a/ntoskrnl/ob/obname.c b/ntoskrnl/ob/obname.c index a514af7b195..8d601eed77b 100644 --- a/ntoskrnl/ob/obname.c +++ b/ntoskrnl/ob/obname.c @@ -113,24 +113,28 @@ VOID NTAPI ObDereferenceDeviceMap(IN PEPROCESS Process) { - //KIRQL OldIrql; - PDEVICE_MAP DeviceMap = Process->DeviceMap; + PDEVICE_MAP DeviceMap; - /* FIXME: We don't use Process Devicemaps yet */ + /* Get the pointer to this process devicemap and reset it + holding devicemap lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + DeviceMap = Process->DeviceMap; + Process->DeviceMap = NULL; + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + /* Continue only if there is a devicemap to dereference */ if (DeviceMap) { - /* FIXME: Acquire the DeviceMap Spinlock */ - // KeAcquireSpinLock(DeviceMap->Lock, &OldIrql); + KeAcquireGuardedMutex(&ObpDeviceMapLock); /* Delete the device map link and dereference it */ - Process->DeviceMap = NULL; if (--DeviceMap->ReferenceCount) { /* Nobody is referencing it anymore, unlink the DOS directory */ DeviceMap->DosDevicesDirectory->DeviceMap = NULL; - /* FIXME: Release the DeviceMap Spinlock */ - // KeReleasepinLock(DeviceMap->Lock, OldIrql); + /* Release the devicemap lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); /* Dereference the DOS Devices Directory and free the Device Map */ ObDereferenceObject(DeviceMap->DosDevicesDirectory); @@ -138,8 +142,8 @@ ObDereferenceDeviceMap(IN PEPROCESS Process) } else { - /* FIXME: Release the DeviceMap Spinlock */ - // KeReleasepinLock(DeviceMap->Lock, OldIrql); + /* Release the devicemap lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); } } } @@ -540,7 +544,7 @@ ParseFromRoot: } /* Reparse */ - while (Reparse) + while (Reparse && MaxReparse) { /* Get the name */ RemainingName = *ObjectName; @@ -690,7 +694,7 @@ ParseFromRoot: ObjectHeader))) { /* Either couldn't allocate the name, or insert failed */ - if (NewName) ExFreePool(NewName); + if (NewName) ExFreePoolWithTag(NewName, OB_NAME_TAG); /* Fail due to memory reasons */ Status = STATUS_INSUFFICIENT_RESOURCES; @@ -791,6 +795,7 @@ ReparseObject: { /* Reparse again */ Reparse = TRUE; + --MaxReparse; /* Start over from root if we got sent back there */ if ((Status == STATUS_REPARSE_OBJECT) || @@ -981,6 +986,7 @@ ObQueryNameString(IN PVOID Object, ULONG NameSize; PWCH ObjectName; BOOLEAN ObjectIsNamed; + NTSTATUS Status = STATUS_SUCCESS; /* Get the Kernel Meta-Structures */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); @@ -989,28 +995,57 @@ ObQueryNameString(IN PVOID Object, /* Check if a Query Name Procedure is available */ if (ObjectHeader->Type->TypeInfo.QueryNameProcedure) { - /* Call the procedure */ + /* Call the procedure inside SEH */ ObjectIsNamed = ((LocalInfo) && (LocalInfo->Name.Length > 0)); - return ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object, + + _SEH2_TRY + { + Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object, ObjectIsNamed, ObjectNameInfo, Length, ReturnLength, KernelMode); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + return Status; } /* Check if the object doesn't even have a name */ if (!(LocalInfo) || !(LocalInfo->Name.Buffer)) { - /* We're returning the name structure */ - *ReturnLength = sizeof(OBJECT_NAME_INFORMATION); + Status = STATUS_SUCCESS; - /* Check if we were given enough space */ - if (*ReturnLength > Length) return STATUS_INFO_LENGTH_MISMATCH; + _SEH2_TRY + { + /* We're returning the name structure */ + *ReturnLength = sizeof(OBJECT_NAME_INFORMATION); - /* Return an empty buffer */ - RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0); - return STATUS_SUCCESS; + /* Check if we were given enough space */ + if (*ReturnLength > Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + /* Return an empty buffer */ + RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0); + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + return Status; } /* @@ -1020,123 +1055,136 @@ ObQueryNameString(IN PVOID Object, * enough right at the beginning, not work our way through * and find out at the end */ - if (Object == ObpRootDirectoryObject) - { - /* Size of the '\' string */ - NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR); - } - else + _SEH2_TRY { - /* Get the Object Directory and add name of Object */ - ParentDirectory = LocalInfo->Directory; - NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length; - - /* Loop inside the directory to get the top-most one (meaning root) */ - while ((ParentDirectory != ObpRootDirectoryObject) && (ParentDirectory)) + if (Object == ObpRootDirectoryObject) + { + /* Size of the '\' string */ + NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR); + } + else { - /* Get the Name Information */ - LocalInfo = OBJECT_HEADER_TO_NAME_INFO( - OBJECT_TO_OBJECT_HEADER(ParentDirectory)); + /* Get the Object Directory and add name of Object */ + ParentDirectory = LocalInfo->Directory; + NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length; - /* Add the size of the Directory Name */ - if (LocalInfo && LocalInfo->Directory) + /* Loop inside the directory to get the top-most one (meaning root) */ + while ((ParentDirectory != ObpRootDirectoryObject) && (ParentDirectory)) { - /* Size of the '\' string + Directory Name */ - NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + - LocalInfo->Name.Length; + /* Get the Name Information */ + LocalInfo = OBJECT_HEADER_TO_NAME_INFO( + OBJECT_TO_OBJECT_HEADER(ParentDirectory)); - /* Move to next parent Directory */ - ParentDirectory = LocalInfo->Directory; - } - else - { - /* Directory with no name. We append "...\" */ - NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR); - break; + /* Add the size of the Directory Name */ + if (LocalInfo && LocalInfo->Directory) + { + /* Size of the '\' string + Directory Name */ + NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + + LocalInfo->Name.Length; + + /* Move to next parent Directory */ + ParentDirectory = LocalInfo->Directory; + } + else + { + /* Directory with no name. We append "...\" */ + NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR); + break; + } } } - } - /* Finally, add the name of the structure and the null char */ - *ReturnLength = NameSize + - sizeof(OBJECT_NAME_INFORMATION) + - sizeof(UNICODE_NULL); - - /* Check if we were given enough space */ - if (*ReturnLength > Length) return STATUS_INFO_LENGTH_MISMATCH; - - /* - * Now we will actually create the name. We work backwards because - * it's easier to start off from the Name we have and walk up the - * parent directories. We use the same logic as Name Length calculation. - */ - LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); - ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength); - *--ObjectName = UNICODE_NULL; + /* Finally, add the name of the structure and the null char */ + *ReturnLength = NameSize + + sizeof(OBJECT_NAME_INFORMATION) + + sizeof(UNICODE_NULL); - /* Check if the object is actually the Root directory */ - if (Object == ObpRootDirectoryObject) - { - /* This is already the Root Directory, return "\\" */ - *--ObjectName = OBJ_NAME_PATH_SEPARATOR; - ObjectNameInfo->Name.Length = (USHORT)NameSize; - ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + - sizeof(UNICODE_NULL)); - ObjectNameInfo->Name.Buffer = ObjectName; - return STATUS_SUCCESS; - } - else - { - /* Start by adding the Object's Name */ - ObjectName = (PWCH)((ULONG_PTR)ObjectName - - LocalInfo->Name.Length); - RtlCopyMemory(ObjectName, - LocalInfo->Name.Buffer, - LocalInfo->Name.Length); - - /* Now parse the Parent directories until we reach the top */ - ParentDirectory = LocalInfo->Directory; - while ((ParentDirectory != ObpRootDirectoryObject) && (ParentDirectory)) + /* Check if we were given enough space */ + if (*ReturnLength > Length) _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH); + + /* + * Now we will actually create the name. We work backwards because + * it's easier to start off from the Name we have and walk up the + * parent directories. We use the same logic as Name Length calculation. + */ + LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); + ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength); + *--ObjectName = UNICODE_NULL; + + /* Check if the object is actually the Root directory */ + if (Object == ObpRootDirectoryObject) { - /* Get the name information */ - LocalInfo = OBJECT_HEADER_TO_NAME_INFO( - OBJECT_TO_OBJECT_HEADER(ParentDirectory)); + /* This is already the Root Directory, return "\\" */ + *--ObjectName = OBJ_NAME_PATH_SEPARATOR; + ObjectNameInfo->Name.Length = (USHORT)NameSize; + ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + + sizeof(UNICODE_NULL)); + ObjectNameInfo->Name.Buffer = ObjectName; + _SEH2_YIELD(return STATUS_SUCCESS); + } + else + { + /* Start by adding the Object's Name */ + ObjectName = (PWCH)((ULONG_PTR)ObjectName - + LocalInfo->Name.Length); + RtlCopyMemory(ObjectName, + LocalInfo->Name.Buffer, + LocalInfo->Name.Length); + + /* Now parse the Parent directories until we reach the top */ + ParentDirectory = LocalInfo->Directory; + while ((ParentDirectory != ObpRootDirectoryObject) && (ParentDirectory)) + { + /* Get the name information */ + LocalInfo = OBJECT_HEADER_TO_NAME_INFO( + OBJECT_TO_OBJECT_HEADER(ParentDirectory)); - /* Add the "\" */ - *(--ObjectName) = OBJ_NAME_PATH_SEPARATOR; + /* Add the "\" */ + *(--ObjectName) = OBJ_NAME_PATH_SEPARATOR; - /* Add the Parent Directory's Name */ - if (LocalInfo && LocalInfo->Name.Buffer) - { - /* Add the name */ - ObjectName = (PWCH)((ULONG_PTR)ObjectName - - LocalInfo->Name.Length); - RtlCopyMemory(ObjectName, - LocalInfo->Name.Buffer, - LocalInfo->Name.Length); - - /* Move to next parent */ - ParentDirectory = LocalInfo->Directory; - } - else - { - /* Directory without a name, we add "..." */ - ObjectName -= sizeof(L"..."); - ObjectName = L"..."; - break; + /* Add the Parent Directory's Name */ + if (LocalInfo && LocalInfo->Name.Buffer) + { + /* Add the name */ + ObjectName = (PWCH)((ULONG_PTR)ObjectName - + LocalInfo->Name.Length); + RtlCopyMemory(ObjectName, + LocalInfo->Name.Buffer, + LocalInfo->Name.Length); + + /* Move to next parent */ + ParentDirectory = LocalInfo->Directory; + } + else + { + /* Directory without a name, we add "..." */ + ObjectName = (PWCH)((ULONG_PTR)ObjectName - + sizeof(L"...") + + sizeof(UNICODE_NULL)); + RtlCopyMemory(ObjectName, + L"...", + sizeof(L"...") + sizeof(UNICODE_NULL)); + break; + } } - } - /* Add Root Directory Name */ - *(--ObjectName) = OBJ_NAME_PATH_SEPARATOR; - ObjectNameInfo->Name.Length = (USHORT)NameSize; - ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + - sizeof(UNICODE_NULL)); - ObjectNameInfo->Name.Buffer = ObjectName; + /* Add Root Directory Name */ + *(--ObjectName) = OBJ_NAME_PATH_SEPARATOR; + ObjectNameInfo->Name.Length = (USHORT)NameSize; + ObjectNameInfo->Name.MaximumLength = + (USHORT)(NameSize + sizeof(UNICODE_NULL)); + ObjectNameInfo->Name.Buffer = ObjectName; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + Status = _SEH2_GetExceptionCode(); } + _SEH2_END; /* Return success */ - return STATUS_SUCCESS; + return Status; } VOID @@ -1144,15 +1192,12 @@ NTAPI ObQueryDeviceMapInformation(IN PEPROCESS Process, IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo) { - //KIRQL OldIrql ; - /* * FIXME: This is an ugly hack for now, to always return the System Device Map * instead of returning the Process Device Map. Not important yet since we don't use it */ - /* FIXME: Acquire the DeviceMap Spinlock */ - // KeAcquireSpinLock(DeviceMap->Lock, &OldIrql); + KeAcquireGuardedMutex(&ObpDeviceMapLock); /* Make a copy */ DeviceMapInfo->Query.DriveMap = ObSystemDeviceMap->DriveMap; @@ -1160,8 +1205,33 @@ ObQueryDeviceMapInformation(IN PEPROCESS Process, ObSystemDeviceMap->DriveType, sizeof(ObSystemDeviceMap->DriveType)); - /* FIXME: Release the DeviceMap Spinlock */ - // KeReleasepinLock(DeviceMap->Lock, OldIrql); + KeReleaseGuardedMutex(&ObpDeviceMapLock); +} + +NTSTATUS +NTAPI +ObIsDosDeviceLocallyMapped( + IN ULONG Index, + OUT PUCHAR DosDeviceState) +{ + /* check parameters */ + if (Index < 1 || Index > 26) + { + /* invalid index */ + return STATUS_INVALID_PARAMETER; + } + + /* acquire lock */ + KeAcquireGuardedMutex(&ObpDeviceMapLock); + + /* get drive mapping status */ + *DosDeviceState = (ObSystemDeviceMap->DriveMap & (1 << Index)) != 0; + + /* release lock */ + KeReleaseGuardedMutex(&ObpDeviceMapLock); + + /* done */ + return STATUS_SUCCESS; } /* EOF */