Author: ion Date: Wed May 24 01:42:28 2006 New Revision: 21998
URL: http://svn.reactos.ru/svn/reactos?rev=21998&view=rev Log: - Cleanup the formatting, code and function headers of most of the Object Manager interfaces.
Modified: trunk/reactos/ntoskrnl/ob/dirobj.c trunk/reactos/ntoskrnl/ob/ntobj.c trunk/reactos/ntoskrnl/ob/security.c trunk/reactos/ntoskrnl/ob/symlink.c trunk/reactos/ntoskrnl/ob/wait.c
Modified: trunk/reactos/ntoskrnl/ob/dirobj.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/dirobj.c?rev=219... ============================================================================== --- trunk/reactos/ntoskrnl/ob/dirobj.c (original) +++ trunk/reactos/ntoskrnl/ob/dirobj.c Wed May 24 01:42:28 2006 @@ -1,11 +1,9 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ob/dirobj.c - * PURPOSE: Interface functions to directory object - * - * PROGRAMMERS: David Welch (welch@mcmail.com) +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ob/dirobj.c + * PURPOSE: Directory Object Implementation + * PROGRAMMER: David Welch (welch@mcmail.com) */
/* INCLUDES ***************************************************************/ @@ -14,490 +12,479 @@ #define NDEBUG #include <internal/debug.h>
- /* FUNCTIONS **************************************************************/
- -/********************************************************************** - * NAME EXPORTED - * NtOpenDirectoryObject - * - * DESCRIPTION - * Opens a namespace directory object. - * - * ARGUMENTS - * DirectoryHandle (OUT) - * Variable which receives the directory handle. - * - * DesiredAccess - * Desired access to the directory. - * - * ObjectAttributes - * Structure describing the directory. - * - * RETURN VALUE - * Status. - * - * NOTES - * Undocumented. - */ -NTSTATUS STDCALL +/*++ +* @name NtOpenDirectoryObject +* @implemented NT4 +* +* The NtOpenDirectoryObject opens a namespace directory object. +* +* @param DirectoryHandle +* Variable which receives the directory handle. +* +* @param DesiredAccess +* Desired access to the directory. +* +* @param ObjectAttributes +* Structure describing the directory. +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes) + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) { - HANDLE hDirectory; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWriteHandle(DirectoryHandle); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenDirectoryObject failed, Status: 0x%x\n", Status); - return Status; - } - } - - Status = ObOpenObjectByName(ObjectAttributes, - ObDirectoryType, - NULL, - PreviousMode, - DesiredAccess, - NULL, - &hDirectory); - if(NT_SUCCESS(Status)) - { - _SEH_TRY - { - *DirectoryHandle = hDirectory; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - - return Status; + HANDLE hDirectory; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWriteHandle(DirectoryHandle); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenDirectoryObject failed, Status: 0x%x\n", Status); + return Status; + } + } + + Status = ObOpenObjectByName(ObjectAttributes, + ObDirectoryType, + NULL, + PreviousMode, + DesiredAccess, + NULL, + &hDirectory); + if(NT_SUCCESS(Status)) + { + _SEH_TRY + { + *DirectoryHandle = hDirectory; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + + return Status; }
- -/********************************************************************** - * NAME EXPORTED - * NtQueryDirectoryObject - * - * DESCRIPTION - * Reads information from a directory in the system namespace. - * - * ARGUMENTS - * DirectoryHandle - * Handle, obtained with NtOpenDirectoryObject(), which - * must grant DIRECTORY_QUERY access to the directory - * object. - * - * Buffer (OUT) - * Buffer to hold the data read. - * - * BufferLength - * Size of the buffer in bytes. - * - * ReturnSingleEntry - * When TRUE, only 1 entry is written in DirObjInformation; - * otherwise as many as will fit in the buffer. - * - * RestartScan - * If TRUE start reading at index 0. - * If FALSE start reading at the index specified - * by object index *ObjectIndex. - * - * Context - * Zero based index into the directory, interpretation - * depends on RestartScan. - * - * ReturnLength (OUT) - * Caller supplied storage for the number of bytes - * written (or NULL). - * - * RETURN VALUE - * STATUS_SUCCESS - At least one (possibly more, depending on - * parameters and buffer size) dir entry is - * returned. - * STATUS_NO_MORE_ENTRIES - Directory is exhausted - * STATUS_BUFFER_TOO_SMALL - There isn't enough room in the - * buffer to return even 1 entry. - * ReturnLength will hold the required - * buffer size to return all remaining - * dir entries - * Other - Status code - * - * - * NOTES - * Although you can iterate over the directory by calling this - * function multiple times, the directory is unlocked between - * calls. This means that another thread can change the directory - * and so iterating doesn't guarantee a consistent picture of the - * directory. Best thing is to retrieve all directory entries in - * one call. - */ -NTSTATUS STDCALL -NtQueryDirectoryObject (IN HANDLE DirectoryHandle, - OUT PVOID Buffer, - IN ULONG BufferLength, - IN BOOLEAN ReturnSingleEntry, - IN BOOLEAN RestartScan, - IN OUT PULONG Context, - OUT PULONG ReturnLength OPTIONAL) +/*++ +* @name NtQueryDirectoryObject +* @implemented NT4 +* +* The NtQueryDirectoryObject Reads information from a directory in +* the system namespace. +* +* @param DirectoryHandle +* Handle obtained with NtOpenDirectoryObject which +* must grant DIRECTORY_QUERY access to the directory object. +* +* @param Buffer +* Buffer to hold the data read. +* +* @param BufferLength +* Size of the buffer in bytes. +* +* @param ReturnSingleEntry +* When TRUE, only 1 entry is written in DirObjInformation; +* otherwise as many as will fit in the buffer. +* +* @param RestartScan +* If TRUE start reading at index 0. +* If FALSE start reading at the index specified by *ObjectIndex. +* +* @param Context +* Zero based index into the directory, interpretation +* depends on RestartScan. +* +* @param ReturnLength +* Caller supplied storage for the number of bytes +* written (or NULL). +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks Although you can iterate over the directory by calling this +* function multiple times, the directory is unlocked between +* calls. This means that another thread can change the directory +* and so iterating doesn't guarantee a consistent picture of the +* directory. Best thing is to retrieve all directory entries in +* one call. +* +*--*/ +NTSTATUS +NTAPI +NtQueryDirectoryObject(IN HANDLE DirectoryHandle, + OUT PVOID Buffer, + IN ULONG BufferLength, + IN BOOLEAN ReturnSingleEntry, + IN BOOLEAN RestartScan, + IN OUT PULONG Context, + OUT PULONG ReturnLength OPTIONAL) { - PDIRECTORY_OBJECT Directory; - KPROCESSOR_MODE PreviousMode; - ULONG SkipEntries = 0; - ULONG NextEntry = 0; - ULONG CopyBytes = 0; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - /* a test showed that the Buffer pointer just has to be 16 bit aligned, - propably due to the fact that most information that needs to be copied - is unicode strings */ - ProbeForWrite(Buffer, - BufferLength, - sizeof(WCHAR)); - ProbeForWriteUlong(Context); - if(!RestartScan) - { + PDIRECTORY_OBJECT Directory; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + ULONG SkipEntries = 0; + ULONG NextEntry = 0; + ULONG CopyBytes = 0; + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + /* a test showed that the Buffer pointer just has to be 16 bit aligned, + propably due to the fact that most information that needs to be copied + is unicode strings */ + ProbeForWrite(Buffer, BufferLength, sizeof(WCHAR)); + ProbeForWriteUlong(Context); + if(!RestartScan) + { + SkipEntries = *Context; + } + if(ReturnLength != NULL) + { + ProbeForWriteUlong(ReturnLength); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryDirectoryObject failed, Status: 0x%x\n", Status); + return Status; + } + } + else if(!RestartScan) + { SkipEntries = *Context; - } - if(ReturnLength != NULL) - { - ProbeForWriteUlong(ReturnLength); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - DPRINT1("NtQueryDirectoryObject failed, Status: 0x%x\n", Status); - return Status; - } - } - else if(!RestartScan) - { - SkipEntries = *Context; - } - - Status = ObReferenceObjectByHandle(DirectoryHandle, - DIRECTORY_QUERY, - ObDirectoryType, - PreviousMode, - (PVOID*)&Directory, - NULL); - if(NT_SUCCESS(Status)) - { - PVOID TemporaryBuffer = ExAllocatePool(NonPagedPool, - BufferLength); - if(TemporaryBuffer != NULL) - { - PROS_OBJECT_HEADER EntryHeader; - PLIST_ENTRY ListEntry; - KIRQL OldLevel; - ULONG RequiredSize = sizeof(OBJECT_DIRECTORY_INFORMATION); - ULONG nDirectories = 0; - POBJECT_DIRECTORY_INFORMATION DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer; - - Status = STATUS_NO_MORE_ENTRIES; - - KeAcquireSpinLock(&Directory->Lock, &OldLevel); - - for(ListEntry = Directory->head.Flink; - ListEntry != &Directory->head; - ListEntry = ListEntry->Flink) - { - NextEntry++; - if(SkipEntries == 0) - { - PUNICODE_STRING Name, Type; - ULONG EntrySize; - - EntryHeader = CONTAINING_RECORD(ListEntry, ROS_OBJECT_HEADER, Entry); - - /* calculate the size of the required buffer space for this entry */ - Name = (HEADER_TO_OBJECT_NAME(EntryHeader)->Name.Length != 0 ? &HEADER_TO_OBJECT_NAME(EntryHeader)->Name : NULL); - Type = &EntryHeader->Type->Name; - EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) + - ((Name != NULL) ? ((ULONG)Name->Length + sizeof(WCHAR)) : 0) + - (ULONG)EntryHeader->Type->Name.Length + sizeof(WCHAR); - - if(RequiredSize + EntrySize <= BufferLength) - { - /* the buffer is large enough to receive this entry. It would've - been much easier if the strings were directly appended to the - OBJECT_DIRECTORY_INFORMATION structured written into the buffer */ - if(Name != NULL) - DirInfo->ObjectName = *Name; - else - { - DirInfo->ObjectName.Length = DirInfo->ObjectName.MaximumLength = 0; - DirInfo->ObjectName.Buffer = NULL; - } - DirInfo->ObjectTypeName = *Type; - - nDirectories++; - RequiredSize += EntrySize; - - Status = STATUS_SUCCESS; - - if(ReturnSingleEntry) - { - /* we're only supposed to query one entry, so bail and copy the - strings to the buffer */ - break; - } - DirInfo++; - } - else - { - if(ReturnSingleEntry) - { - /* the buffer is too small, so return the number of bytes that - would've been required for this query */ - RequiredSize += EntrySize; - Status = STATUS_BUFFER_TOO_SMALL; - } - - /* we couldn't query this entry, so leave the index that will be stored - in Context to this entry so the caller can query it the next time - he queries (hopefully with a buffer that is large enough then...) */ - NextEntry--; - - /* just copy the entries that fit into the buffer */ - break; - } + } + + Status = ObReferenceObjectByHandle(DirectoryHandle, + DIRECTORY_QUERY, + ObDirectoryType, + PreviousMode, + (PVOID*)&Directory, + NULL); + if(NT_SUCCESS(Status)) + { + PVOID TemporaryBuffer = ExAllocatePool(NonPagedPool, BufferLength); + if(TemporaryBuffer != NULL) + { + PROS_OBJECT_HEADER EntryHeader; + PLIST_ENTRY ListEntry; + KIRQL OldLevel; + ULONG RequiredSize = sizeof(OBJECT_DIRECTORY_INFORMATION); + ULONG nDirectories = 0; + POBJECT_DIRECTORY_INFORMATION DirInfo = + (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer; + + Status = STATUS_NO_MORE_ENTRIES; + + KeAcquireSpinLock(&Directory->Lock, &OldLevel); + + for(ListEntry = Directory->head.Flink; + ListEntry != &Directory->head; + ListEntry = ListEntry->Flink) + { + NextEntry++; + if(SkipEntries == 0) + { + PUNICODE_STRING Name, Type; + ULONG EntrySize; + + EntryHeader = CONTAINING_RECORD(ListEntry, + ROS_OBJECT_HEADER, + Entry); + + /* calculate the size of the required buffer space for this entry */ + Name = (HEADER_TO_OBJECT_NAME(EntryHeader)->Name.Length != 0 ? + &HEADER_TO_OBJECT_NAME(EntryHeader)->Name : NULL); + Type = &EntryHeader->Type->Name; + EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) + + ((Name != NULL) ? + ((ULONG)Name->Length + sizeof(WCHAR)) : 0) + + (ULONG)EntryHeader->Type->Name.Length + + sizeof(WCHAR); + + if(RequiredSize + EntrySize <= BufferLength) + { + /* the buffer is large enough to receive this entry. It would've + been much easier if the strings were directly appended to the + OBJECT_DIRECTORY_INFORMATION structured written into the buffer */ + if(Name != NULL) + DirInfo->ObjectName = *Name; + else + { + DirInfo->ObjectName.Length = + DirInfo->ObjectName.MaximumLength = 0; + DirInfo->ObjectName.Buffer = NULL; + } + DirInfo->ObjectTypeName = *Type; + + nDirectories++; + RequiredSize += EntrySize; + + Status = STATUS_SUCCESS; + + if(ReturnSingleEntry) + { + /* we're only supposed to query one entry, so bail and copy the + strings to the buffer */ + break; + } + DirInfo++; + } + else + { + if(ReturnSingleEntry) + { + /* the buffer is too small, so return the number of bytes that + would've been required for this query */ + RequiredSize += EntrySize; + Status = STATUS_BUFFER_TOO_SMALL; + } + + /* we couldn't query this entry, so leave the index that will be stored + in Context to this entry so the caller can query it the next time + he queries (hopefully with a buffer that is large enough then...) */ + NextEntry--; + + /* just copy the entries that fit into the buffer */ + break; + } + } + else + { + /* skip the entry */ + SkipEntries--; + } + } + + if(!ReturnSingleEntry && ListEntry != &Directory->head) + { + /* there are more entries to enumerate but the buffer is already full. + only tell this to the user if he queries multiple entries */ + Status = STATUS_MORE_ENTRIES; + } + + if(NT_SUCCESS(Status) && nDirectories > 0) + { + PWSTR strbuf = + (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + + nDirectories + 1); + PWSTR deststrbuf = + (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + + nDirectories + 1); + + memset((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + + nDirectories, + 0, + sizeof(OBJECT_DIRECTORY_INFORMATION)); + + CopyBytes = (nDirectories + 1) * + sizeof(OBJECT_DIRECTORY_INFORMATION); + + /* copy the names from the objects and append them to the list of the + objects. copy to the temporary buffer only because the directory + lock can't be released and the buffer might be pagable memory! */ + for(DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer; + nDirectories > 0; + nDirectories--, DirInfo++) + { + ULONG NameLength; + + if(DirInfo->ObjectName.Length > 0) + { + RtlCopyMemory(strbuf, + DirInfo->ObjectName.Buffer, + DirInfo->ObjectName.Length); + + /* change the buffer pointer to the buffer */ + DirInfo->ObjectName.Buffer = deststrbuf; + NameLength = DirInfo->ObjectName.Length / + sizeof(WCHAR); + + /* NULL-terminate the string */ + strbuf[NameLength] = L'\0'; + strbuf += NameLength + 1; + deststrbuf += NameLength + 1; + + CopyBytes += (NameLength + 1) * sizeof(WCHAR); + } + + RtlCopyMemory(strbuf, + DirInfo->ObjectTypeName.Buffer, + DirInfo->ObjectTypeName.Length); + + /* change the buffer pointer to the buffer */ + DirInfo->ObjectTypeName.Buffer = deststrbuf; + NameLength = DirInfo->ObjectTypeName.Length / + sizeof(WCHAR); + + /* NULL-terminate the string */ + strbuf[NameLength] = L'\0'; + strbuf += NameLength + 1; + deststrbuf += NameLength + 1; + + CopyBytes += (NameLength + 1) * sizeof(WCHAR); + } + } + + KeReleaseSpinLock(&Directory->Lock, OldLevel); + ObDereferenceObject(Directory); + + if(NT_SUCCESS(Status) || ReturnSingleEntry) + { + _SEH_TRY + { + if(CopyBytes != 0) + { + RtlCopyMemory(Buffer, TemporaryBuffer, CopyBytes); + } + + *Context = NextEntry; + + if(ReturnLength != NULL) + { + *ReturnLength = RequiredSize; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + + ExFreePool(TemporaryBuffer); } else { - /* skip the entry */ - SkipEntries--; - } - } - - if(!ReturnSingleEntry && ListEntry != &Directory->head) - { - /* there are more entries to enumerate but the buffer is already full. - only tell this to the user if he queries multiple entries */ - Status = STATUS_MORE_ENTRIES; - } - - if(NT_SUCCESS(Status) && nDirectories > 0) - { - PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories + 1); - PWSTR deststrbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories + 1); - memset((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories, 0, sizeof(OBJECT_DIRECTORY_INFORMATION)); - - CopyBytes = (nDirectories + 1) * sizeof(OBJECT_DIRECTORY_INFORMATION); - - /* copy the names from the objects and append them to the list of the - objects. copy to the temporary buffer only because the directory - lock can't be released and the buffer might be pagable memory! */ - for(DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer; - nDirectories > 0; - nDirectories--, DirInfo++) - { - ULONG NameLength; - - if(DirInfo->ObjectName.Length > 0) - { - RtlCopyMemory(strbuf, - DirInfo->ObjectName.Buffer, - DirInfo->ObjectName.Length); - /* change the buffer pointer to the buffer */ - DirInfo->ObjectName.Buffer = deststrbuf; - NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR); - /* NULL-terminate the string */ - strbuf[NameLength] = L'\0'; - strbuf += NameLength + 1; - deststrbuf += NameLength + 1; - - CopyBytes += (NameLength + 1) * sizeof(WCHAR); - } - - RtlCopyMemory(strbuf, - DirInfo->ObjectTypeName.Buffer, - DirInfo->ObjectTypeName.Length); - /* change the buffer pointer to the buffer */ - DirInfo->ObjectTypeName.Buffer = deststrbuf; - NameLength = DirInfo->ObjectTypeName.Length / sizeof(WCHAR); - /* NULL-terminate the string */ - strbuf[NameLength] = L'\0'; - strbuf += NameLength + 1; - deststrbuf += NameLength + 1; - - CopyBytes += (NameLength + 1) * sizeof(WCHAR); - } - } - - KeReleaseSpinLock(&Directory->Lock, OldLevel); - ObDereferenceObject(Directory); - - if(NT_SUCCESS(Status) || ReturnSingleEntry) - { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + + return Status; +} + +/*++ +* @name NtCreateDirectoryObject +* @implemented NT4 +* +* The NtOpenDirectoryObject creates or opens a directory object. +* +* @param DirectoryHandle +* Variable which receives the directory handle. +* +* @param DesiredAccess +* Desired access to the directory. +* +* @param ObjectAttributes +* Structure describing the directory. +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI +NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) +{ + PDIRECTORY_OBJECT Directory; + HANDLE hDirectory; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, " + "DesiredAccess %x, ObjectAttributes %x\n", + DirectoryHandle, DesiredAccess, ObjectAttributes); + + if(PreviousMode != KernelMode) + { _SEH_TRY { - if(CopyBytes != 0) - { - RtlCopyMemory(Buffer, - TemporaryBuffer, - CopyBytes); - } - *Context = NextEntry; - if(ReturnLength != NULL) - { - *ReturnLength = RequiredSize; - } + ProbeForWriteHandle(DirectoryHandle); } _SEH_HANDLE { - Status = _SEH_GetExceptionCode(); + Status = _SEH_GetExceptionCode(); } _SEH_END; - } - - ExFreePool(TemporaryBuffer); - } - else - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } - } - - return Status; + + if(!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateDirectoryObject failed, Status: 0x%x\n", Status); + return Status; + } + } + + Status = ObCreateObject(PreviousMode, + ObDirectoryType, + ObjectAttributes, + PreviousMode, + NULL, + sizeof(DIRECTORY_OBJECT), + 0, + 0, + (PVOID*)&Directory); + + if(NT_SUCCESS(Status)) + { + Status = ObInsertObject((PVOID)Directory, + NULL, + DesiredAccess, + 0, + NULL, + &hDirectory); + if (!NT_SUCCESS(Status)) + { + ObMakeTemporaryObject(Directory); + } + ObDereferenceObject(Directory); + + if(NT_SUCCESS(Status)) + { + _SEH_TRY + { + *DirectoryHandle = hDirectory; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + } + + return Status; }
- -/********************************************************************** - * NAME (EXPORTED as Zw) - * NtCreateDirectoryObject - * - * DESCRIPTION - * Creates or opens a directory object (a container for other - * objects). - * - * ARGUMENTS - * DirectoryHandle (OUT) - * Caller supplied storage for the handle of the - * directory. - * - * DesiredAccess - * Access desired to the directory. - * - * ObjectAttributes - * Object attributes initialized with - * InitializeObjectAttributes. - * - * RETURN VALUE - * Status. - */ -NTSTATUS STDCALL -NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes) -{ - PDIRECTORY_OBJECT Directory; - HANDLE hDirectory; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, " - "DesiredAccess %x, ObjectAttributes %x\n", - DirectoryHandle, DesiredAccess, ObjectAttributes); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWriteHandle(DirectoryHandle); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateDirectoryObject failed, Status: 0x%x\n", Status); - return Status; - } - } - - Status = ObCreateObject(PreviousMode, - ObDirectoryType, - ObjectAttributes, - PreviousMode, - NULL, - sizeof(DIRECTORY_OBJECT), - 0, - 0, - (PVOID*)&Directory); - - if(NT_SUCCESS(Status)) - { - Status = ObInsertObject((PVOID)Directory, - NULL, - DesiredAccess, - 0, - NULL, - &hDirectory); - if (!NT_SUCCESS(Status)) - { - ObMakeTemporaryObject(Directory); - } - ObDereferenceObject(Directory); - - if(NT_SUCCESS(Status)) - { - _SEH_TRY - { - *DirectoryHandle = hDirectory; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - } - - return Status; -} - /* EOF */
Modified: trunk/reactos/ntoskrnl/ob/ntobj.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/ntobj.c?rev=2199... ============================================================================== --- trunk/reactos/ntoskrnl/ob/ntobj.c (original) +++ trunk/reactos/ntoskrnl/ob/ntobj.c Wed May 24 01:42:28 2006 @@ -1,12 +1,10 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ob/ntobj.c - * PURPOSE: User mode interface to object manager - * - * PROGRAMMERS: David Welch (welch@cwcom.net) - */ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/ob/ntobj.c +* PURPOSE: Bunch of random functions that got stuck here without purpose. FIXME. +* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) +*/
/* INCLUDES *****************************************************************/
@@ -14,329 +12,327 @@ #define NDEBUG #include <internal/debug.h>
- -/* FUNCTIONS ************************************************************/ - -/********************************************************************** - * NAME EXPORTED - * NtSetInformationObject - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - */ -NTSTATUS STDCALL -NtSetInformationObject (IN HANDLE ObjectHandle, - IN OBJECT_INFORMATION_CLASS ObjectInformationClass, - IN PVOID ObjectInformation, - IN ULONG Length) -{ - PVOID Object; - NTSTATUS Status; - - PAGED_CODE(); - - if (ObjectInformationClass != ObjectHandleInformation) - return STATUS_INVALID_INFO_CLASS; - - if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) - return STATUS_INFO_LENGTH_MISMATCH; - - Status = ObReferenceObjectByHandle (ObjectHandle, - 0, - NULL, - (KPROCESSOR_MODE)KeGetPreviousMode (), - &Object, - NULL); - if (!NT_SUCCESS (Status)) +/* PRIVATE FUNCTIONS *********************************************************/ + +/*++ +* @name ObpSetPermanentObject +* +* The ObpSetPermanentObject routine <FILLMEIN> +* +* @param ObjectBody +* <FILLMEIN> +* +* @param Permanent +* <FILLMEIN> +* +* @return None. +* +* @remarks None. +* +*--*/ +VOID +FASTCALL +ObpSetPermanentObject(IN PVOID ObjectBody, + IN BOOLEAN Permanent) +{ + PROS_OBJECT_HEADER ObjectHeader; + + ObjectHeader = BODY_TO_HEADER(ObjectBody); + ASSERT (ObjectHeader->PointerCount > 0); + if (Permanent) { - return Status; + ObjectHeader->Flags |= OB_FLAG_PERMANENT; } - - Status = ObpSetHandleAttributes (ObjectHandle, - (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)ObjectInformation); - - ObDereferenceObject (Object); - - return Status; -} - - -/********************************************************************** - * NAME EXPORTED - * NtQueryObject - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - */ -NTSTATUS STDCALL -NtQueryObject (IN HANDLE ObjectHandle, - IN OBJECT_INFORMATION_CLASS ObjectInformationClass, - OUT PVOID ObjectInformation, - IN ULONG Length, - OUT PULONG ResultLength OPTIONAL) -{ - OBJECT_HANDLE_INFORMATION HandleInfo; - PROS_OBJECT_HEADER ObjectHeader; - ULONG InfoLength; - PVOID Object; - NTSTATUS Status; - - PAGED_CODE(); - - Status = ObReferenceObjectByHandle (ObjectHandle, - 0, - NULL, - (KPROCESSOR_MODE)KeGetPreviousMode(), - &Object, - &HandleInfo); - if (!NT_SUCCESS (Status)) + else { - return Status; + ObjectHeader->Flags &= ~OB_FLAG_PERMANENT; + if (ObjectHeader->HandleCount == 0 && + HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory) + { + /* Remove the object from the namespace */ + ObpRemoveEntryDirectory((PROS_OBJECT_HEADER)ObjectHeader); + } } - - ObjectHeader = BODY_TO_HEADER(Object); - - switch (ObjectInformationClass) +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ +* @name ObMakeTemporaryObject +* @implemented NT4 +* +* The ObMakeTemporaryObject routine <FILLMEIN> +* +* @param ObjectBody +* <FILLMEIN> +* +* @return None. +* +* @remarks None. +* +*--*/ +VOID +NTAPI +ObMakeTemporaryObject(IN PVOID ObjectBody) +{ + ObpSetPermanentObject (ObjectBody, FALSE); +} + +/*++ +* @name NtSetInformationObject +* @implemented NT4 +* +* The NtSetInformationObject routine <FILLMEIN> +* +* @param ObjectHandle +* <FILLMEIN> +* +* @param ObjectInformationClass +* <FILLMEIN> +* +* @param ObjectInformation +* <FILLMEIN> +* +* @param Length +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI +NtSetInformationObject(IN HANDLE ObjectHandle, + IN OBJECT_INFORMATION_CLASS ObjectInformationClass, + IN PVOID ObjectInformation, + IN ULONG Length) +{ + PVOID Object; + NTSTATUS Status; + PAGED_CODE(); + + if (ObjectInformationClass != ObjectHandleInformation) + return STATUS_INVALID_INFO_CLASS; + + if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) + return STATUS_INFO_LENGTH_MISMATCH; + + Status = ObReferenceObjectByHandle(ObjectHandle, + 0, + NULL, + KeGetPreviousMode(), + &Object, + NULL); + if (!NT_SUCCESS (Status)) return Status; + + Status = ObpSetHandleAttributes(ObjectHandle, + (POBJECT_HANDLE_ATTRIBUTE_INFORMATION) + ObjectInformation); + + ObDereferenceObject (Object); + return Status; +} + +/*++ +* @name NtQueryObject +* @implemented NT4 +* +* The NtQueryObject routine <FILLMEIN> +* +* @param ObjectHandle +* <FILLMEIN> +* +* @param ObjectInformationClass +* <FILLMEIN> +* +* @param ObjectInformation +* <FILLMEIN> +* +* @param Length +* <FILLMEIN> +* +* @param ResultLength +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI +NtQueryObject(IN HANDLE ObjectHandle, + IN OBJECT_INFORMATION_CLASS ObjectInformationClass, + OUT PVOID ObjectInformation, + IN ULONG Length, + OUT PULONG ResultLength OPTIONAL) +{ + OBJECT_HANDLE_INFORMATION HandleInfo; + PROS_OBJECT_HEADER ObjectHeader; + ULONG InfoLength; + PVOID Object; + NTSTATUS Status; + PAGED_CODE(); + + Status = ObReferenceObjectByHandle(ObjectHandle, + 0, + NULL, + KeGetPreviousMode(), + &Object, + &HandleInfo); + if (!NT_SUCCESS (Status)) return Status; + + ObjectHeader = BODY_TO_HEADER(Object); + + switch (ObjectInformationClass) { - case ObjectBasicInformation: - InfoLength = sizeof(OBJECT_BASIC_INFORMATION); - if (Length != sizeof(OBJECT_BASIC_INFORMATION)) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - else - { - POBJECT_BASIC_INFORMATION BasicInfo; - - BasicInfo = (POBJECT_BASIC_INFORMATION)ObjectInformation; - BasicInfo->Attributes = HandleInfo.HandleAttributes; - BasicInfo->GrantedAccess = HandleInfo.GrantedAccess; - BasicInfo->HandleCount = ObjectHeader->HandleCount; - BasicInfo->PointerCount = ObjectHeader->PointerCount; - BasicInfo->PagedPoolUsage = 0; /* FIXME*/ - BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/ - BasicInfo->NameInformationLength = 0; /* FIXME*/ - BasicInfo->TypeInformationLength = 0; /* FIXME*/ - BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/ - if (ObjectHeader->Type == ObSymbolicLinkType) - { - BasicInfo->CreateTime.QuadPart = - ((PSYMLINK_OBJECT)Object)->CreateTime.QuadPart; - } - else - { - BasicInfo->CreateTime.QuadPart = (ULONGLONG)0; - } - Status = STATUS_SUCCESS; - } - break; - - case ObjectNameInformation: - Status = ObQueryNameString (Object, - (POBJECT_NAME_INFORMATION)ObjectInformation, - Length, - &InfoLength); - break; - - case ObjectTypeInformation: -#if 0 -// InfoLength = - if (Length != sizeof(OBJECT_TYPE_INFORMATION)) - { - Status = STATUS_INVALID_BUFFER_SIZE; - } - else - { - POBJECT_TYPE_INFORMATION TypeInfo; - - TypeInfo = (POBJECT_TYPE_INFORMATION)ObjectInformation; - // FIXME: Is this supposed to only be the header's Name field? - // Can somebody check/verify this? - RtlCopyUnicodeString(&typeinfo->Name,&ObjectHeader->Name); - - if (Status != STATUS_SUCCESS) - { - break; - } - - RtlCopyUnicodeString(&typeinfo->Type,&ObjectHeader->Type->TypeName); - //This should be info from the object header, not the object type, right? - typeinfo->TotalHandles = ObjectHeader-> HandleCount; - typeinfo->ReferenceCount = ObjectHeader -> PointerCount; - } -#endif - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ObjectAllTypesInformation: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ObjectHandleInformation: - InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION); - if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - else - { - Status = ObpQueryHandleAttributes (ObjectHandle, - (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)ObjectInformation); - } - break; - - default: - Status = STATUS_INVALID_INFO_CLASS; - break; + case ObjectBasicInformation: + InfoLength = sizeof(OBJECT_BASIC_INFORMATION); + if (Length != sizeof(OBJECT_BASIC_INFORMATION)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + POBJECT_BASIC_INFORMATION BasicInfo; + + BasicInfo = (POBJECT_BASIC_INFORMATION)ObjectInformation; + BasicInfo->Attributes = HandleInfo.HandleAttributes; + BasicInfo->GrantedAccess = HandleInfo.GrantedAccess; + BasicInfo->HandleCount = ObjectHeader->HandleCount; + BasicInfo->PointerCount = ObjectHeader->PointerCount; + BasicInfo->PagedPoolUsage = 0; /* FIXME*/ + BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/ + BasicInfo->NameInformationLength = 0; /* FIXME*/ + BasicInfo->TypeInformationLength = 0; /* FIXME*/ + BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/ + if (ObjectHeader->Type == ObSymbolicLinkType) + { + BasicInfo->CreateTime.QuadPart = + ((PSYMLINK_OBJECT)Object)->CreateTime.QuadPart; + } + else + { + BasicInfo->CreateTime.QuadPart = (ULONGLONG)0; + } + Status = STATUS_SUCCESS; + } + break; + + case ObjectNameInformation: + Status = ObQueryNameString(Object, + (POBJECT_NAME_INFORMATION)ObjectInformation, + Length, + &InfoLength); + break; + + case ObjectTypeInformation: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case ObjectAllTypesInformation: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case ObjectHandleInformation: + InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION); + if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + Status = ObpQueryHandleAttributes( + ObjectHandle, + (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)ObjectInformation); + } + break; + + default: + Status = STATUS_INVALID_INFO_CLASS; + break; }
- ObDereferenceObject (Object); - - if (ResultLength != NULL) - *ResultLength = InfoLength; - - return Status; -} - - -/********************************************************************** - * NAME PRIVATE - * ObpSetPermanentObject/2 - * - * DESCRIPTION - * Fast general purpose routine to set an object's permanent - * attribute, given a pointer to the object's body. - */ -VOID FASTCALL -ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent) -{ - PROS_OBJECT_HEADER ObjectHeader; - - ObjectHeader = BODY_TO_HEADER(ObjectBody); - ASSERT (ObjectHeader->PointerCount > 0); - if (Permanent) - { - ObjectHeader->Flags |= OB_FLAG_PERMANENT; - } - else - { - ObjectHeader->Flags &= ~OB_FLAG_PERMANENT; - if (ObjectHeader->HandleCount == 0 && HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory) - { - /* Remove the object from the namespace */ - ObpRemoveEntryDirectory((PROS_OBJECT_HEADER)ObjectHeader); - } - } -} - -/********************************************************************** - * NAME EXPORTED - * ObMakeTemporaryObject/1 - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - * @implemented - */ -VOID STDCALL -ObMakeTemporaryObject(IN PVOID ObjectBody) -{ - ObpSetPermanentObject (ObjectBody, FALSE); -} - - -/********************************************************************** - * NAME EXPORTED - * NtMakeTemporaryObject - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - */ -NTSTATUS STDCALL + ObDereferenceObject (Object); + + if (ResultLength != NULL) *ResultLength = InfoLength; + + return Status; +} + +/*++ +* @name NtMakeTemporaryObject +* @implemented NT4 +* +* The NtMakeTemporaryObject routine <FILLMEIN> +* +* @param ObjectHandle +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI NtMakeTemporaryObject(IN HANDLE ObjectHandle) { - PVOID ObjectBody; - NTSTATUS Status; - - PAGED_CODE(); - - Status = ObReferenceObjectByHandle(ObjectHandle, - 0, - NULL, - (KPROCESSOR_MODE)KeGetPreviousMode(), - &ObjectBody, - NULL); - if (Status != STATUS_SUCCESS) - { - return Status; - } - - ObpSetPermanentObject (ObjectBody, FALSE); - - ObDereferenceObject(ObjectBody); - - return STATUS_SUCCESS; -} - - -/********************************************************************** - * NAME EXPORTED - * NtMakePermanentObject/1 - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - * @implemented - */ -NTSTATUS STDCALL + PVOID ObjectBody; + NTSTATUS Status; + PAGED_CODE(); + + Status = ObReferenceObjectByHandle(ObjectHandle, + 0, + NULL, + KeGetPreviousMode(), + &ObjectBody, + NULL); + if (Status != STATUS_SUCCESS) return Status; + + ObpSetPermanentObject (ObjectBody, FALSE); + + ObDereferenceObject(ObjectBody); + + return STATUS_SUCCESS; +} + +/*++ +* @name NtMakePermanentObject +* @implemented NT4 +* +* The NtMakePermanentObject routine <FILLMEIN> +* +* @param ObjectHandle +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI NtMakePermanentObject(IN HANDLE ObjectHandle) { - PVOID ObjectBody; - NTSTATUS Status; - - PAGED_CODE(); - - Status = ObReferenceObjectByHandle(ObjectHandle, - 0, - NULL, - (KPROCESSOR_MODE)KeGetPreviousMode(), - &ObjectBody, - NULL); - if (Status != STATUS_SUCCESS) - { - return Status; - } - - ObpSetPermanentObject (ObjectBody, TRUE); - - ObDereferenceObject(ObjectBody); - - return STATUS_SUCCESS; + PVOID ObjectBody; + NTSTATUS Status; + PAGED_CODE(); + + Status = ObReferenceObjectByHandle(ObjectHandle, + 0, + NULL, + KeGetPreviousMode(), + &ObjectBody, + NULL); + if (Status != STATUS_SUCCESS) return Status; + + ObpSetPermanentObject (ObjectBody, TRUE); + + ObDereferenceObject(ObjectBody); + + return STATUS_SUCCESS; }
/* EOF */
Modified: trunk/reactos/ntoskrnl/ob/security.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/security.c?rev=2... ============================================================================== --- trunk/reactos/ntoskrnl/ob/security.c (original) +++ trunk/reactos/ntoskrnl/ob/security.c Wed May 24 01:42:28 2006 @@ -1,12 +1,10 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ob/security.c - * PURPOSE: Security manager - * - * PROGRAMERS: No programmer listed. - */ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/ob/security.c +* PURPOSE: SRM Interface of the Object Manager +* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) +*/
/* INCLUDES *****************************************************************/
@@ -16,166 +14,232 @@
/* FUNCTIONS ***************************************************************/
-/* - * @implemented - */ -NTSTATUS STDCALL +/*++ +* @name ObAssignSecurity +* @implemented NT4 +* +* The ObAssignSecurity routine <FILLMEIN> +* +* @param AccessState +* <FILLMEIN> +* +* @param SecurityDescriptor +* <FILLMEIN> +* +* @param Object +* <FILLMEIN> +* +* @param Type +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI ObAssignSecurity(IN PACCESS_STATE AccessState, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PVOID Object, - IN POBJECT_TYPE Type) -{ - PSECURITY_DESCRIPTOR NewDescriptor; - NTSTATUS Status; - - PAGED_CODE(); - - /* Build the new security descriptor */ - Status = SeAssignSecurity(SecurityDescriptor, - AccessState->SecurityDescriptor, - &NewDescriptor, - (Type == ObDirectoryType), - &AccessState->SubjectSecurityContext, - &Type->TypeInfo.GenericMapping, - PagedPool); - if (!NT_SUCCESS(Status)) + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PVOID Object, + IN POBJECT_TYPE Type) +{ + PSECURITY_DESCRIPTOR NewDescriptor; + NTSTATUS Status; + PAGED_CODE(); + + /* Build the new security descriptor */ + Status = SeAssignSecurity(SecurityDescriptor, + AccessState->SecurityDescriptor, + &NewDescriptor, + (Type == ObDirectoryType), + &AccessState->SubjectSecurityContext, + &Type->TypeInfo.GenericMapping, + PagedPool); + if (!NT_SUCCESS(Status)) return Status; + + /* Call the security method */ + Status = Type->TypeInfo.SecurityProcedure(Object, + AssignSecurityDescriptor, + 0, + NewDescriptor, + NULL, + NULL, + NonPagedPool, + NULL); + + /* Release the new security descriptor */ + SeDeassignSecurity(&NewDescriptor); + return Status; - - /* Call the security method */ - Status = Type->TypeInfo.SecurityProcedure(Object, - AssignSecurityDescriptor, - 0, - NewDescriptor, - NULL, - NULL, - NonPagedPool, - NULL); - - /* Release the new security descriptor */ - SeDeassignSecurity(&NewDescriptor); - - return Status; -} - - -/* - * @implemented - */ -NTSTATUS STDCALL +} + +/*++ +* @name ObGetObjectSecurity +* @implemented NT4 +* +* The ObGetObjectSecurity routine <FILLMEIN> +* +* @param Object +* <FILLMEIN> +* +* @param SecurityDescriptor +* <FILLMEIN> +* +* @param MemoryAllocated +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI ObGetObjectSecurity(IN PVOID Object, - OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, - OUT PBOOLEAN MemoryAllocated) -{ - PROS_OBJECT_HEADER Header; - ULONG Length; - NTSTATUS Status; - - PAGED_CODE(); - - Header = BODY_TO_HEADER(Object); - if (Header->Type == NULL) - return STATUS_UNSUCCESSFUL; - - if (Header->Type->TypeInfo.SecurityProcedure == NULL) - { - ObpReferenceCachedSecurityDescriptor(Header->SecurityDescriptor); - *SecurityDescriptor = Header->SecurityDescriptor; - *MemoryAllocated = FALSE; - return STATUS_SUCCESS; - } - - /* Get the security descriptor size */ - Length = 0; - Status = Header->Type->TypeInfo.SecurityProcedure(Object, - QuerySecurityDescriptor, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, - NULL, - &Length, - NULL, - NonPagedPool, - NULL); - if (Status != STATUS_BUFFER_TOO_SMALL) - return Status; - - /* Allocate security descriptor */ - *SecurityDescriptor = ExAllocatePool(NonPagedPool, - Length); - if (*SecurityDescriptor == NULL) - return STATUS_INSUFFICIENT_RESOURCES; - - /* Query security descriptor */ - Status = Header->Type->TypeInfo.SecurityProcedure(Object, - QuerySecurityDescriptor, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, - *SecurityDescriptor, - &Length, - NULL, - NonPagedPool, - NULL); - if (!NT_SUCCESS(Status)) - { - ExFreePool(*SecurityDescriptor); - return Status; - } - - *MemoryAllocated = TRUE; - - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -VOID STDCALL + OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, + OUT PBOOLEAN MemoryAllocated) +{ + PROS_OBJECT_HEADER Header; + ULONG Length; + NTSTATUS Status; + PAGED_CODE(); + + Header = BODY_TO_HEADER(Object); + if (Header->Type == NULL) return STATUS_UNSUCCESSFUL; + + if (Header->Type->TypeInfo.SecurityProcedure == NULL) + { + ObpReferenceCachedSecurityDescriptor(Header->SecurityDescriptor); + *SecurityDescriptor = Header->SecurityDescriptor; + *MemoryAllocated = FALSE; + return STATUS_SUCCESS; + } + + /* Get the security descriptor size */ + Length = 0; + Status = Header->Type->TypeInfo.SecurityProcedure(Object, + QuerySecurityDescriptor, + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | + SACL_SECURITY_INFORMATION, + NULL, + &Length, + NULL, + NonPagedPool, + NULL); + if (Status != STATUS_BUFFER_TOO_SMALL) return Status; + + /* Allocate security descriptor */ + *SecurityDescriptor = ExAllocatePool(NonPagedPool, Length); + if (*SecurityDescriptor == NULL) return STATUS_INSUFFICIENT_RESOURCES; + + /* Query security descriptor */ + Status = Header->Type->TypeInfo.SecurityProcedure(Object, + QuerySecurityDescriptor, + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | + SACL_SECURITY_INFORMATION, + *SecurityDescriptor, + &Length, + NULL, + NonPagedPool, + NULL); + if (!NT_SUCCESS(Status)) + { + ExFreePool(*SecurityDescriptor); + return Status; + } + + *MemoryAllocated = TRUE; + + return STATUS_SUCCESS; +} + +/*++ +* @name ObReleaseObjectSecurity +* @implemented NT4 +* +* The ObReleaseObjectSecurity routine <FILLMEIN> +* +* @param SecurityDescriptor +* <FILLMEIN> +* +* @param MemoryAllocated +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +VOID +NTAPI ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN BOOLEAN MemoryAllocated) -{ - PAGED_CODE(); - - if (SecurityDescriptor == NULL) - return; - - if (MemoryAllocated) - { - ExFreePool(SecurityDescriptor); - } - else - { - ObpDereferenceCachedSecurityDescriptor(SecurityDescriptor); - } -} - - -/* - * @implemented - */ -NTSTATUS STDCALL + IN BOOLEAN MemoryAllocated) +{ + PAGED_CODE(); + + if (SecurityDescriptor == NULL) return; + + if (MemoryAllocated) + { + ExFreePool(SecurityDescriptor); + } + else + { + ObpDereferenceCachedSecurityDescriptor(SecurityDescriptor); + } +} + +/*++ +* @name NtQuerySecurityObject +* @implemented NT4 +* +* The NtQuerySecurityObject routine <FILLMEIN> +* +* @param Handle +* <FILLMEIN> +* +* @param SecurityInformation +* <FILLMEIN> +* +* @param SecurityDescriptor +* <FILLMEIN> +* +* @param Length +* <FILLMEIN> +* +* @param ResultLength +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI NtQuerySecurityObject(IN HANDLE Handle, - IN SECURITY_INFORMATION SecurityInformation, - OUT PSECURITY_DESCRIPTOR SecurityDescriptor, - IN ULONG Length, - OUT PULONG ResultLength) -{ - KPROCESSOR_MODE PreviousMode; + IN SECURITY_INFORMATION SecurityInformation, + OUT PSECURITY_DESCRIPTOR SecurityDescriptor, + IN ULONG Length, + OUT PULONG ResultLength) +{ + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); PVOID Object; PROS_OBJECT_HEADER Header; ACCESS_MASK DesiredAccess = (ACCESS_MASK)0; NTSTATUS Status = STATUS_SUCCESS; - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode();
if (PreviousMode != KernelMode) { _SEH_TRY { - ProbeForWrite(SecurityDescriptor, - Length, - sizeof(ULONG)); + ProbeForWrite(SecurityDescriptor, Length, sizeof(ULONG)); ProbeForWriteUlong(ResultLength); } _SEH_HANDLE @@ -203,14 +267,15 @@ Header = BODY_TO_HEADER(Object); ASSERT(Header->Type != NULL);
- Status = Header->Type->TypeInfo.SecurityProcedure(Object, - QuerySecurityDescriptor, - SecurityInformation, - SecurityDescriptor, - &Length, - &Header->SecurityDescriptor, - Header->Type->TypeInfo.PoolType, - &Header->Type->TypeInfo.GenericMapping); + Status = Header->Type->TypeInfo.SecurityProcedure( + Object, + QuerySecurityDescriptor, + SecurityInformation, + SecurityDescriptor, + &Length, + &Header->SecurityDescriptor, + Header->Type->TypeInfo.PoolType, + &Header->Type->TypeInfo.GenericMapping);
ObDereferenceObject(Object);
@@ -229,46 +294,60 @@ return Status; }
- -/* - * @implemented - */ -NTSTATUS STDCALL +/*++ +* @name NtSetSecurityObject +* @implemented NT4 +* +* The NtSetSecurityObject routine <FILLMEIN> +* +* @param Handle +* <FILLMEIN> +* +* @param SecurityInformation +* <FILLMEIN> +* +* @param SecurityDescriptor +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI NtSetSecurityObject(IN HANDLE Handle, - IN SECURITY_INFORMATION SecurityInformation, - IN PSECURITY_DESCRIPTOR SecurityDescriptor) -{ - KPROCESSOR_MODE PreviousMode; + IN SECURITY_INFORMATION SecurityInformation, + IN PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); PVOID Object; PROS_OBJECT_HEADER Header; SECURITY_DESCRIPTOR_RELATIVE *CapturedSecurityDescriptor; ACCESS_MASK DesiredAccess = (ACCESS_MASK)0; NTSTATUS Status; - PAGED_CODE();
/* make sure the caller doesn't pass a NULL security descriptor! */ - if (SecurityDescriptor == NULL) - { - return STATUS_ACCESS_DENIED; - } - - PreviousMode = ExGetPreviousMode(); + if (SecurityDescriptor == NULL) return STATUS_ACCESS_DENIED;
/* capture and make a copy of the security descriptor */ Status = SeCaptureSecurityDescriptor(SecurityDescriptor, PreviousMode, PagedPool, TRUE, - (PSECURITY_DESCRIPTOR*)&CapturedSecurityDescriptor); + (PSECURITY_DESCRIPTOR*) + &CapturedSecurityDescriptor); if (!NT_SUCCESS(Status)) { DPRINT1("Capturing the security descriptor failed! Status: 0x%lx\n", Status); return Status; }
- /* make sure the security descriptor passed by the caller - is valid for the operation we're about to perform */ + /* + * make sure the security descriptor passed by the caller + * is valid for the operation we're about to perform + */ if (((SecurityInformation & OWNER_SECURITY_INFORMATION) && (CapturedSecurityDescriptor->Owner == 0)) || ((SecurityInformation & GROUP_SECURITY_INFORMATION) && @@ -294,14 +373,15 @@ Header = BODY_TO_HEADER(Object); ASSERT(Header->Type != NULL);
- Status = Header->Type->TypeInfo.SecurityProcedure(Object, - SetSecurityDescriptor, - SecurityInformation, - (PSECURITY_DESCRIPTOR)SecurityDescriptor, - NULL, - &Header->SecurityDescriptor, - Header->Type->TypeInfo.PoolType, - &Header->Type->TypeInfo.GenericMapping); + Status = Header->Type->TypeInfo.SecurityProcedure( + Object, + SetSecurityDescriptor, + SecurityInformation, + (PSECURITY_DESCRIPTOR)SecurityDescriptor, + NULL, + &Header->SecurityDescriptor, + Header->Type->TypeInfo.PoolType, + &Header->Type->TypeInfo.GenericMapping);
ObDereferenceObject(Object); } @@ -315,18 +395,36 @@ return Status; }
- -/* - * @unimplemented - */ -NTSTATUS STDCALL +/*++ +* @name ObLogSecurityDescriptor +* @unimplemented NT5.2 +* +* The ObLogSecurityDescriptor routine <FILLMEIN> +* +* @param InputSecurityDescriptor +* <FILLMEIN> +* +* @param OutputSecurityDescriptor +* <FILLMEIN> +* +* @param RefBias +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI ObLogSecurityDescriptor(IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor, IN ULONG RefBias) { /* HACK: Return the same descriptor back */ PISECURITY_DESCRIPTOR SdCopy; - DPRINT1("ObLogSecurityDescriptor is not implemented!\n", InputSecurityDescriptor); + DPRINT1("ObLogSecurityDescriptor is not implemented!\n", + InputSecurityDescriptor);
SdCopy = ExAllocatePool(PagedPool, sizeof(*SdCopy)); RtlMoveMemory(SdCopy, InputSecurityDescriptor, sizeof(*SdCopy)); @@ -334,11 +432,25 @@ return STATUS_SUCCESS; }
- -/* - * @unimplemented - */ -VOID STDCALL +/*++ +* @name ObDereferenceSecurityDescriptor +* @unimplemented NT5.2 +* +* The ObDereferenceSecurityDescriptor routine <FILLMEIN> +* +* @param SecurityDescriptor +* <FILLMEIN> +* +* @param Count +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +VOID +NTAPI ObDereferenceSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Count) {
Modified: trunk/reactos/ntoskrnl/ob/symlink.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/symlink.c?rev=21... ============================================================================== --- trunk/reactos/ntoskrnl/ob/symlink.c (original) +++ trunk/reactos/ntoskrnl/ob/symlink.c Wed May 24 01:42:28 2006 @@ -1,12 +1,11 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ob/symlink.c - * PURPOSE: Implements symbolic links - * - * PROGRAMMERS: David Welch (welch@mcmail.com) - */ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/ob/symlink.c +* PURPOSE: Implements symbolic links +* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) +* David Welch (welch@mcmail.com) +*/
/* INCLUDES *****************************************************************/
@@ -18,436 +17,469 @@ #pragma alloc_text(INIT, ObInitSymbolicLinkImplementation) #endif
- /* GLOBALS ******************************************************************/
POBJECT_TYPE ObSymbolicLinkType = NULL;
-static GENERIC_MAPPING ObpSymbolicLinkMapping = { - STANDARD_RIGHTS_READ|SYMBOLIC_LINK_QUERY, - STANDARD_RIGHTS_WRITE, - STANDARD_RIGHTS_EXECUTE|SYMBOLIC_LINK_QUERY, - SYMBOLIC_LINK_ALL_ACCESS}; - -/* FUNCTIONS ****************************************************************/ - -/********************************************************************** - * NAME INTERNAL - * ObpDeleteSymbolicLink - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURNN VALUE - * Status. - * - * REVISIONS - */ -VOID STDCALL +static GENERIC_MAPPING ObpSymbolicLinkMapping = +{ + STANDARD_RIGHTS_READ | SYMBOLIC_LINK_QUERY, + STANDARD_RIGHTS_WRITE, + STANDARD_RIGHTS_EXECUTE | SYMBOLIC_LINK_QUERY, + SYMBOLIC_LINK_ALL_ACCESS +}; + +/* PRIVATE FUNCTIONS *********************************************************/ + +/*++ +* @name ObpDeleteSymbolicLink +* +* The ObpDeleteSymbolicLink routine <FILLMEIN> +* +* @param ObjectBody +* <FILLMEIN> +* +* @return None. +* +* @remarks None. +* +*--*/ +VOID +NTAPI ObpDeleteSymbolicLink(PVOID ObjectBody) { - PSYMLINK_OBJECT SymlinkObject = (PSYMLINK_OBJECT)ObjectBody; - - ExFreePool(SymlinkObject->TargetName.Buffer); -} - - -/********************************************************************** - * NAME INTERNAL - * ObpParseSymbolicLink - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - */ -NTSTATUS STDCALL + PSYMLINK_OBJECT SymlinkObject = (PSYMLINK_OBJECT)ObjectBody; + ExFreePool(SymlinkObject->TargetName.Buffer); +} + +/*++ +* @name ObpParseSymbolicLink +* +* The ObpParseSymbolicLink routine <FILLMEIN> +* +* @param Object +* <FILLMEIN> +* +* @param NextObject +* <FILLMEIN> +* +* @param FullPath +* <FILLMEIN> +* +* @param RemainingPath +* <FILLMEIN> +* +* @param Attributes +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI ObpParseSymbolicLink(PVOID Object, - PVOID * NextObject, - PUNICODE_STRING FullPath, - PWSTR * RemainingPath, - ULONG Attributes) -{ - PSYMLINK_OBJECT SymlinkObject = (PSYMLINK_OBJECT) Object; - UNICODE_STRING TargetPath; - - DPRINT("ObpParseSymbolicLink (RemainingPath %S)\n", *RemainingPath); - - /* - * Stop parsing if the entire path has been parsed and - * the desired object is a symbolic link object. - */ - if (((*RemainingPath == NULL) || (**RemainingPath == 0)) && - (Attributes & OBJ_OPENLINK)) - { - DPRINT("Parsing stopped!\n"); - *NextObject = NULL; - return(STATUS_SUCCESS); - } - - /* build the expanded path */ - TargetPath.MaximumLength = SymlinkObject->TargetName.Length + sizeof(WCHAR); - if (RemainingPath && *RemainingPath) - { - TargetPath.MaximumLength += (wcslen(*RemainingPath) * sizeof(WCHAR)); - } - TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR); - TargetPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, - TargetPath.MaximumLength, - TAG_SYMLINK_TTARGET); - wcscpy(TargetPath.Buffer, SymlinkObject->TargetName.Buffer); - if (RemainingPath && *RemainingPath) - { - wcscat(TargetPath.Buffer, *RemainingPath); - } - - /* transfer target path buffer into FullPath */ - ExFreePool(FullPath->Buffer); - FullPath->Length = TargetPath.Length; - FullPath->MaximumLength = TargetPath.MaximumLength; - FullPath->Buffer = TargetPath.Buffer; - - /* reinitialize RemainingPath for reparsing */ - *RemainingPath = FullPath->Buffer; - - *NextObject = NULL; - return STATUS_REPARSE; -} - - -/********************************************************************** - * NAME INTERNAL - * ObInitSymbolicLinkImplementation - * - * DESCRIPTION - * - * ARGUMENTS - * None. - * - * RETURNN VALUE - * None. - * - * REVISIONS - */ -VOID + PVOID * NextObject, + PUNICODE_STRING FullPath, + PWSTR * RemainingPath, + ULONG Attributes) +{ + PSYMLINK_OBJECT SymlinkObject = (PSYMLINK_OBJECT) Object; + UNICODE_STRING TargetPath; + + DPRINT("ObpParseSymbolicLink (RemainingPath %S)\n", *RemainingPath); + + /* + * Stop parsing if the entire path has been parsed and + * the desired object is a symbolic link object. + */ + if (((*RemainingPath == NULL) || (**RemainingPath == 0)) && + (Attributes & OBJ_OPENLINK)) + { + DPRINT("Parsing stopped!\n"); + *NextObject = NULL; + return(STATUS_SUCCESS); + } + + /* Build the expanded path */ + TargetPath.MaximumLength = SymlinkObject->TargetName.Length + + sizeof(WCHAR); + if (RemainingPath && *RemainingPath) + { + TargetPath.MaximumLength += (wcslen(*RemainingPath) * sizeof(WCHAR)); + } + TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR); + TargetPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, + TargetPath.MaximumLength, + TAG_SYMLINK_TTARGET); + wcscpy(TargetPath.Buffer, SymlinkObject->TargetName.Buffer); + if (RemainingPath && *RemainingPath) + { + wcscat(TargetPath.Buffer, *RemainingPath); + } + + /* Transfer target path buffer into FullPath */ + ExFreePool(FullPath->Buffer); + FullPath->Length = TargetPath.Length; + FullPath->MaximumLength = TargetPath.MaximumLength; + FullPath->Buffer = TargetPath.Buffer; + + /* Reinitialize RemainingPath for reparsing */ + *RemainingPath = FullPath->Buffer; + + *NextObject = NULL; + return STATUS_REPARSE; +} + +/*++ +* @name ObInitSymbolicLinkImplementation +* +* The ObInitSymbolicLinkImplementation routine <FILLMEIN> +* +* @param None. +* +* @return None. +* +* @remarks None. +* +*--*/ +VOID INIT_FUNCTION NTAPI -ObInitSymbolicLinkImplementation (VOID) -{ - UNICODE_STRING Name; - OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - - DPRINT("Creating SymLink Object Type\n"); - - /* Initialize the Directory type */ - RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); - RtlInitUnicodeString(&Name, L"SymbolicLink"); - ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); - ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(SYMLINK_OBJECT); - ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping; - ObjectTypeInitializer.PoolType = NonPagedPool; - ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS; - ObjectTypeInitializer.UseDefaultObject = TRUE; - ObjectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD)ObpParseSymbolicLink; - ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink; - ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObSymbolicLinkType); -} - - -/********************************************************************** - * NAME EXPORTED - * NtCreateSymbolicLinkObject - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - */ -NTSTATUS STDCALL +ObInitSymbolicLinkImplementation(VOID) +{ + UNICODE_STRING Name; + OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; + + DPRINT("Creating SymLink Object Type\n"); + + /* Initialize the Directory type */ + RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); + RtlInitUnicodeString(&Name, L"SymbolicLink"); + ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); + ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(SYMLINK_OBJECT); + ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping; + ObjectTypeInitializer.PoolType = NonPagedPool; + ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS; + ObjectTypeInitializer.UseDefaultObject = TRUE; + ObjectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD)ObpParseSymbolicLink; + ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink; + ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObSymbolicLinkType); +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/*++ +* @name NtCreateSymbolicLinkObject +* @implemented NT4 +* +* The NtCreateSymbolicLinkObject opens or creates a symbolic link object. +* +* @param LinkHandle +* Variable which receives the symlink handle. +* +* @param DesiredAccess +* Desired access to the symlink. +* +* @param ObjectAttributes +* Structure describing the symlink. +* +* @param LinkTarget +* Unicode string defining the symlink's target +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI NtCreateSymbolicLinkObject(OUT PHANDLE LinkHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PUNICODE_STRING LinkTarget) -{ - HANDLE hLink; - PSYMLINK_OBJECT SymbolicLink; - UNICODE_STRING CapturedLinkTarget; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWriteHandle(LinkHandle); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PUNICODE_STRING LinkTarget) +{ + HANDLE hLink; + PSYMLINK_OBJECT SymbolicLink; + UNICODE_STRING CapturedLinkTarget; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + DPRINT("NtCreateSymbolicLinkObject(LinkHandle %p, DesiredAccess %ul" + ", ObjectAttributes %p, LinkTarget %wZ)\n", + LinkHandle, + DesiredAccess, + ObjectAttributes, + LinkTarget); + + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWriteHandle(LinkHandle); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } + } + + Status = ProbeAndCaptureUnicodeString(&CapturedLinkTarget, + PreviousMode, + LinkTarget); if(!NT_SUCCESS(Status)) { - return Status; - } - } - - Status = ProbeAndCaptureUnicodeString(&CapturedLinkTarget, - PreviousMode, - LinkTarget); - if(!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateSymbolicLinkObject: Capturing the target link failed!\n"); + DPRINT1("NtCreateSymbolicLinkObject: Capturing the target link failed!\n"); + return Status; + } + + Status = ObCreateObject(PreviousMode, + ObSymbolicLinkType, + ObjectAttributes, + PreviousMode, + NULL, + sizeof(SYMLINK_OBJECT), + 0, + 0, + (PVOID*)&SymbolicLink); + if (NT_SUCCESS(Status)) + { + SymbolicLink->TargetName.Length = 0; + SymbolicLink->TargetName.MaximumLength = CapturedLinkTarget.Length + + sizeof(WCHAR); + SymbolicLink->TargetName.Buffer = + ExAllocatePoolWithTag(NonPagedPool, + SymbolicLink->TargetName.MaximumLength, + TAG_SYMLINK_TARGET); + + RtlCopyUnicodeString(&SymbolicLink->TargetName, &CapturedLinkTarget); + + DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer); + + ZwQuerySystemTime (&SymbolicLink->CreateTime); + + Status = ObInsertObject((PVOID)SymbolicLink, + NULL, + DesiredAccess, + 0, + NULL, + &hLink); + if (NT_SUCCESS(Status)) + { + _SEH_TRY + { + *LinkHandle = hLink; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + ObDereferenceObject(SymbolicLink); + } + + ReleaseCapturedUnicodeString(&CapturedLinkTarget, PreviousMode); return Status; - } - - DPRINT("NtCreateSymbolicLinkObject(LinkHandle %p, DesiredAccess %ul, ObjectAttributes %p, LinkTarget %wZ)\n", - LinkHandle, - DesiredAccess, - ObjectAttributes, - &CapturedLinkTarget); - - Status = ObCreateObject(ExGetPreviousMode(), - ObSymbolicLinkType, - ObjectAttributes, - PreviousMode, - NULL, - sizeof(SYMLINK_OBJECT), - 0, - 0, - (PVOID*)&SymbolicLink); - if (NT_SUCCESS(Status)) - { - SymbolicLink->TargetName.Length = 0; - SymbolicLink->TargetName.MaximumLength = - CapturedLinkTarget.Length + sizeof(WCHAR); - SymbolicLink->TargetName.Buffer = - ExAllocatePoolWithTag(NonPagedPool, - SymbolicLink->TargetName.MaximumLength, - TAG_SYMLINK_TARGET); - RtlCopyUnicodeString(&SymbolicLink->TargetName, - &CapturedLinkTarget); - - DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer); - - ZwQuerySystemTime (&SymbolicLink->CreateTime); - - Status = ObInsertObject ((PVOID)SymbolicLink, - NULL, - DesiredAccess, - 0, - NULL, - &hLink); +} + +/*++ +* @name NtOpenSymbolicLinkObject +* @implemented NT4 +* +* The NtOpenSymbolicLinkObject opens a symbolic link object. +* +* @param LinkHandle +* Variable which receives the symlink handle. +* +* @param DesiredAccess +* Desired access to the symlink. +* +* @param ObjectAttributes +* Structure describing the symlink. +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI +NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) +{ + HANDLE hLink; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + ProbeForWriteHandle(LinkHandle); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } + } + + DPRINT("NtOpenSymbolicLinkObject (Name %wZ)\n", + ObjectAttributes->ObjectName); + + Status = ObOpenObjectByName(ObjectAttributes, + ObSymbolicLinkType, + NULL, + PreviousMode, + DesiredAccess, + NULL, + &hLink); + if(NT_SUCCESS(Status)) + { + _SEH_TRY + { + *LinkHandle = hLink; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + + return Status; +} + +/*++ +* @name NtQuerySymbolicLinkObject +* @implemented NT4 +* +* The NtQuerySymbolicLinkObject queries a symbolic link object. +* +* @param LinkHandle +* Symlink handle to query +* +* @param LinkTarget +* Unicode string defining the symlink's target +* +* @param ResultLength +* Caller supplied storage for the number of bytes written (or NULL). +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ +NTSTATUS +NTAPI +NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, + OUT PUNICODE_STRING LinkTarget, + OUT PULONG ResultLength OPTIONAL) +{ + UNICODE_STRING SafeLinkTarget; + PSYMLINK_OBJECT SymlinkObject; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + ULONG LengthRequired; + PAGED_CODE(); + + if(PreviousMode != KernelMode) + { + _SEH_TRY + { + /* probe the unicode string and buffers supplied */ + ProbeForWrite(LinkTarget, sizeof(UNICODE_STRING), sizeof(ULONG)); + + SafeLinkTarget = *LinkTarget; + + ProbeForWrite(SafeLinkTarget.Buffer, + SafeLinkTarget.MaximumLength, + sizeof(WCHAR)); + + if(ResultLength != NULL) + { + ProbeForWriteUlong(ResultLength); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + return Status; + } + } + else + { + SafeLinkTarget = *LinkTarget; + } + + Status = ObReferenceObjectByHandle(LinkHandle, + SYMBOLIC_LINK_QUERY, + ObSymbolicLinkType, + PreviousMode, + (PVOID *)&SymlinkObject, + NULL); if (NT_SUCCESS(Status)) { - _SEH_TRY - { - *LinkHandle = hLink; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - ObDereferenceObject(SymbolicLink); - } - - ReleaseCapturedUnicodeString(&CapturedLinkTarget, - PreviousMode); - - return Status; -} - - -/********************************************************************** - * NAME EXPORTED - * NtOpenSymbolicLinkObject - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - */ -NTSTATUS STDCALL -NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes) -{ - HANDLE hLink; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWriteHandle(LinkHandle); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - return Status; - } - } - - DPRINT("NtOpenSymbolicLinkObject (Name %wZ)\n", - ObjectAttributes->ObjectName); - - Status = ObOpenObjectByName(ObjectAttributes, - ObSymbolicLinkType, - NULL, - PreviousMode, - DesiredAccess, - NULL, - &hLink); - if(NT_SUCCESS(Status)) - { - _SEH_TRY - { - *LinkHandle = hLink; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - - return Status; -} - - -/********************************************************************** - * NAME EXPORTED - * NtQuerySymbolicLinkObject - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - */ -NTSTATUS STDCALL -NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, - OUT PUNICODE_STRING LinkTarget, - OUT PULONG ResultLength OPTIONAL) -{ - UNICODE_STRING SafeLinkTarget; - PSYMLINK_OBJECT SymlinkObject; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - /* probe the unicode string and buffers supplied */ - ProbeForWrite(LinkTarget, - sizeof(UNICODE_STRING), - sizeof(ULONG)); - SafeLinkTarget = *LinkTarget; - ProbeForWrite(SafeLinkTarget.Buffer, - SafeLinkTarget.MaximumLength, - sizeof(WCHAR)); - - if(ResultLength != NULL) - { - ProbeForWriteUlong(ResultLength); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - return Status; - } - } - else - { - SafeLinkTarget = *LinkTarget; - } - - Status = ObReferenceObjectByHandle(LinkHandle, - SYMBOLIC_LINK_QUERY, - ObSymbolicLinkType, - PreviousMode, - (PVOID *)&SymlinkObject, - NULL); - if (NT_SUCCESS(Status)) - { - ULONG LengthRequired = SymlinkObject->TargetName.Length + sizeof(WCHAR); - - _SEH_TRY - { - if(SafeLinkTarget.MaximumLength >= LengthRequired) - { - /* don't pass TargetLink to RtlCopyUnicodeString here because the caller - might have modified the structure which could lead to a copy into - kernel memory! */ - RtlCopyUnicodeString(&SafeLinkTarget, - &SymlinkObject->TargetName); - SafeLinkTarget.Buffer[SafeLinkTarget.Length / sizeof(WCHAR)] = L'\0'; - /* copy back the new UNICODE_STRING structure */ - *LinkTarget = SafeLinkTarget; - } - else - { - Status = STATUS_BUFFER_TOO_SMALL; - } - - if(ResultLength != NULL) - { - *ResultLength = LengthRequired; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - ObDereferenceObject(SymlinkObject); - } - - return Status; + LengthRequired = SymlinkObject->TargetName.Length + sizeof(WCHAR); + + _SEH_TRY + { + if(SafeLinkTarget.MaximumLength >= LengthRequired) + { + /* + * Don't pass TargetLink to RtlCopyUnicodeString here because + * the caller might have modified the structure which could + * lead to a copy into kernel memory! + */ + RtlCopyUnicodeString(&SafeLinkTarget, + &SymlinkObject->TargetName); + SafeLinkTarget.Buffer[SafeLinkTarget.Length / + sizeof(WCHAR)] = UNICODE_NULL; + + /* Copy back the new UNICODE_STRING structure */ + *LinkTarget = SafeLinkTarget; + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if(ResultLength != NULL) + { + *ResultLength = LengthRequired; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + ObDereferenceObject(SymlinkObject); + } + + return Status; }
/* EOF */
Modified: trunk/reactos/ntoskrnl/ob/wait.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/wait.c?rev=21998... ============================================================================== --- trunk/reactos/ntoskrnl/ob/wait.c (original) +++ trunk/reactos/ntoskrnl/ob/wait.c Wed May 24 01:42:28 2006 @@ -1,11 +1,10 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ob/wait.c - * PURPOSE: Handles Waiting on Objects - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - * David Welch (welch@mcmail.com) + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ob/wait.c + * PURPOSE: Handles Waiting on Objects + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * David Welch (welch@mcmail.com) */
/* INCLUDES ******************************************************************/ @@ -18,13 +17,39 @@
/* FUNCTIONS *****************************************************************/
+/*++ +* @name NtWaitForMultipleObjects +* @implemented NT4 +* +* The NtWaitForMultipleObjects routine <FILLMEIN> +* +* @param ObjectCount +* <FILLMEIN> +* +* @param HandleArray +* <FILLMEIN> +* +* @param WaitType +* <FILLMEIN> +* +* @param Alertable +* <FILLMEIN> +* +* @param TimeOut +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ NTSTATUS -STDCALL +NTAPI NtWaitForMultipleObjects(IN ULONG ObjectCount, IN PHANDLE HandleArray, IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, - IN PLARGE_INTEGER TimeOut OPTIONAL) + IN PLARGE_INTEGER TimeOut OPTIONAL) { PKWAIT_BLOCK WaitBlockArray = NULL; HANDLE Handles[MAXIMUM_WAIT_OBJECTS]; @@ -41,8 +66,9 @@ PVOID DefaultObject; NTSTATUS Status = STATUS_SUCCESS;
- DPRINT("NtWaitForMultipleObjects(ObjectCount %lu HandleArray[] %x, Alertable %d, " - "TimeOut %x)\n", ObjectCount, HandleArray, Alertable, TimeOut); + DPRINT("NtWaitForMultipleObjects(ObjectCount %lu HandleArray[] %x," + " Alertable %d, TimeOut %x)\n", + ObjectCount, HandleArray, Alertable, TimeOut);
/* Enter a critical region since we'll play with handles */ LockInUse = TRUE; @@ -81,8 +107,8 @@ } }
- /* - * Make a copy so we don't have to guard with SEH later and keep + /* + * Make a copy so we don't have to guard with SEH later and keep * track of what objects we referenced if dereferencing pointers * suddenly fails */ @@ -231,7 +257,7 @@ { ReferencedObjects--; if (Objects[ReferencedObjects]) - { + { ObDereferenceObject(Objects[ReferencedObjects]); } } @@ -247,11 +273,28 @@ return Status; }
-/* - * @implemented - */ +/*++ +* @name NtWaitForSingleObject +* @implemented NT4 +* +* The NtWaitForSingleObject routine <FILLMEIN> +* +* @param ObjectHandle +* <FILLMEIN> +* +* @param Alertable +* <FILLMEIN> +* +* @param TimeOut +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ NTSTATUS -STDCALL +NTAPI NtWaitForSingleObject(IN HANDLE ObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL) @@ -325,12 +368,35 @@ return Status; }
+/*++ +* @name NtSignalAndWaitForSingleObject +* @implemented NT4 +* +* The NtSignalAndWaitForSingleObject routine <FILLMEIN> +* +* @param ObjectHandleToSignal +* <FILLMEIN> +* +* @param WaitableObjectHandle +* <FILLMEIN> +* +* @param Alertable +* <FILLMEIN> +* +* @param TimeOut +* <FILLMEIN> +* +* @return STATUS_SUCCESS or appropriate error value. +* +* @remarks None. +* +*--*/ NTSTATUS -STDCALL +NTAPI NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal, IN HANDLE WaitableObjectHandle, IN BOOLEAN Alertable, - IN PLARGE_INTEGER TimeOut OPTIONAL) + IN PLARGE_INTEGER TimeOut OPTIONAL) { KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); POBJECT_TYPE Type;