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=21…
==============================================================================
--- 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(a)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(a)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=219…
==============================================================================
--- 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(a)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(a)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=…
==============================================================================
--- 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(a)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=2…
==============================================================================
--- 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(a)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(a)relsoft.net)
+* David Welch (welch(a)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=2199…
==============================================================================
--- 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(a)relsoft.net)
- * David Welch (welch(a)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(a)relsoft.net)
+ * David Welch (welch(a)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;