Author: fireball Date: Fri Nov 23 23:32:38 2007 New Revision: 30705
URL: http://svn.reactos.org/svn/reactos?rev=30705&view=rev Log: - Cleanup NtCreateKey and NtOpenKey to make it simpler for the final steps of the rewirte. - Remove SEH and callbacks (yes this is "bad", but won't break anything, and it will be added back). - Try to make the code as similar as possible to isolate broken-Ob calls from proper Cm behavior.
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c trunk/reactos/ntoskrnl/cm/regobj.c
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=30... ============================================================================== --- trunk/reactos/ntoskrnl/cm/ntfunc.c (original) +++ trunk/reactos/ntoskrnl/cm/ntfunc.c Fri Nov 23 23:32:38 2007 @@ -23,107 +23,16 @@
/* GLOBALS ******************************************************************/
-extern POBJECT_TYPE CmpKeyObjectType; -static BOOLEAN CmiRegistryInitialized = FALSE; - -/* FUNCTIONS ****************************************************************/ - NTSTATUS NTAPI CmpCreateHandle(PVOID ObjectBody, ACCESS_MASK GrantedAccess, ULONG HandleAttributes, - PHANDLE HandleReturn) - /* - * FUNCTION: Add a handle referencing an object - * ARGUMENTS: - * obj = Object body that the handle should refer to - * RETURNS: The created handle - * NOTE: The handle is valid only in the context of the current process - */ -{ - HANDLE_TABLE_ENTRY NewEntry; - PEPROCESS CurrentProcess; - PVOID HandleTable; - POBJECT_HEADER ObjectHeader; - HANDLE Handle; - KAPC_STATE ApcState; - BOOLEAN AttachedToProcess = FALSE; - - PAGED_CODE(); - - DPRINT("CmpCreateHandle(obj %p)\n",ObjectBody); - - ASSERT(ObjectBody); - - CurrentProcess = PsGetCurrentProcess(); - - ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody); - - /* check that this is a valid kernel pointer */ - //ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED); - - if (GrantedAccess & MAXIMUM_ALLOWED) - { - GrantedAccess &= ~MAXIMUM_ALLOWED; - GrantedAccess |= GENERIC_ALL; - } - - if (GrantedAccess & GENERIC_ACCESS) - { - RtlMapGenericMask(&GrantedAccess, - &ObjectHeader->Type->TypeInfo.GenericMapping); - } - - NewEntry.Object = ObjectHeader; - if(HandleAttributes & OBJ_INHERIT) - NewEntry.ObAttributes |= OBJ_INHERIT; - else - NewEntry.ObAttributes &= ~OBJ_INHERIT; - NewEntry.GrantedAccess = GrantedAccess; - - if ((HandleAttributes & OBJ_KERNEL_HANDLE) && - ExGetPreviousMode() == KernelMode) - { - HandleTable = ObpKernelHandleTable; - if (PsGetCurrentProcess() != PsInitialSystemProcess) - { - KeStackAttachProcess(&PsInitialSystemProcess->Pcb, - &ApcState); - AttachedToProcess = TRUE; - } - } - else - { - HandleTable = PsGetCurrentProcess()->ObjectTable; - } - - Handle = ExCreateHandle(HandleTable, - &NewEntry); - - if (AttachedToProcess) - { - KeUnstackDetachProcess(&ApcState); - } - - if(Handle != NULL) - { - if (HandleAttributes & OBJ_KERNEL_HANDLE) - { - /* mark the handle value */ - Handle = ObMarkHandleAsKernelHandle(Handle); - } - - InterlockedIncrement(&ObjectHeader->HandleCount); - ObReferenceObject(ObjectBody); - - *HandleReturn = Handle; - - return STATUS_SUCCESS; - } - - return STATUS_UNSUCCESSFUL; -} + PHANDLE HandleReturn); + +static BOOLEAN CmiRegistryInitialized = FALSE; + +/* FUNCTIONS ****************************************************************/
NTSTATUS NTAPI @@ -137,228 +46,137 @@ { UNICODE_STRING RemainingPath = {0}, ReturnedPath = {0}; ULONG LocalDisposition; - PKEY_OBJECT KeyObject; + PKEY_OBJECT KeyObject, Parent; NTSTATUS Status = STATUS_SUCCESS; - PVOID Object = NULL; UNICODE_STRING ObjectName; OBJECT_CREATE_INFORMATION ObjectCreateInfo; - unsigned int i; - REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo; - REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo; - KPROCESSOR_MODE PreviousMode; - UNICODE_STRING CapturedClass = {0}; + ULONG i; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); HANDLE hKey; PCM_KEY_NODE Node, ParentNode; - PAGED_CODE();
- DPRINT("NtCreateKey(TI 0x%x, DA 0x%x, Class '%wZ', OA 0x%p, OA->ON '%wZ'\n", - TitleIndex, DesiredAccess, Class, ObjectAttributes, - ObjectAttributes ? ObjectAttributes->ObjectName : NULL); - - PreviousMode = ExGetPreviousMode(); - - if (PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeAndZeroHandle(KeyHandle); - if (Disposition != NULL) - { - ProbeForWriteUlong(Disposition); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if (!NT_SUCCESS(Status)) - { - return Status; - } - } - - if (Class != NULL) - { - Status = ProbeAndCaptureUnicodeString(&CapturedClass, - PreviousMode, - Class); - if (!NT_SUCCESS(Status)) - { - return Status; - } - } - /* Capture all the info */ - DPRINT("Capturing Create Info\n"); Status = ObpCaptureObjectAttributes(ObjectAttributes, PreviousMode, FALSE, &ObjectCreateInfo, &ObjectName); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status); - return Status; - } - - PostCreateKeyInfo.CompleteName = &ObjectName; - PreCreateKeyInfo.CompleteName = &ObjectName; - Status = CmiCallRegisteredCallbacks(RegNtPreCreateKey, &PreCreateKeyInfo); - if (!NT_SUCCESS(Status)) - { - PostCreateKeyInfo.Object = NULL; - PostCreateKeyInfo.Status = Status; - CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); - goto Cleanup; - } - + if (!NT_SUCCESS(Status)) return Status; + + /* Find the key object */ Status = CmFindObject(&ObjectCreateInfo, &ObjectName, - (PVOID*)&Object, + (PVOID*)&Parent, &ReturnedPath, CmpKeyObjectType, NULL, NULL); - if (!NT_SUCCESS(Status)) - { - PostCreateKeyInfo.Object = NULL; - PostCreateKeyInfo.Status = Status; - CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); - - DPRINT1("CmpFindObject failed, Status: 0x%x\n", Status); - goto Cleanup; - } - + if (!NT_SUCCESS(Status)) goto Cleanup; + + /* Check if we found the entire path */ RemainingPath = ReturnedPath; - DPRINT("RemainingPath (preparse) %wZ\n", &RemainingPath); - - if (RemainingPath.Length == 0) - { - /* Fail if the key has been deleted */ - if (((PKEY_OBJECT) Object)->KeyControlBlock->Delete) + if (!RemainingPath.Length) + { + /* Check if the parent has been deleted */ + if (Parent->KeyControlBlock->Delete) { - PostCreateKeyInfo.Object = NULL; - PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL; - CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); - + /* Fail */ DPRINT1("Object marked for delete!\n"); Status = STATUS_UNSUCCESSFUL; goto Cleanup; }
- Status = CmpCreateHandle(Object, + /* Create a new handle to the parent */ + Status = CmpCreateHandle(Parent, DesiredAccess, ObjectCreateInfo.Attributes, &hKey); - - if (!NT_SUCCESS(Status)) - DPRINT1("CmpCreateHandle failed Status 0x%x\n", Status); - - PostCreateKeyInfo.Object = NULL; - PostCreateKeyInfo.Status = Status; - CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); - + if (!NT_SUCCESS(Status)) goto Cleanup; + + /* Tell the caller we did this */ LocalDisposition = REG_OPENED_EXISTING_KEY; goto SuccessReturn; }
- /* If RemainingPath contains \ we must return error - because NtCreateKey doesn't create trees */ - while (RemainingPath.Length && *RemainingPath.Buffer == L'\') - { + /* Loop every leading slash */ + while ((RemainingPath.Length) && + (*RemainingPath.Buffer == OBJ_NAME_PATH_SEPARATOR)) + { + /* And remove it */ RemainingPath.Length -= sizeof(WCHAR); RemainingPath.MaximumLength -= sizeof(WCHAR); RemainingPath.Buffer++; }
- while (RemainingPath.Length && - RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] == L'\') - { + /* Loop every terminating slash */ + while ((RemainingPath.Length) && + (RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] == + OBJ_NAME_PATH_SEPARATOR)) + { + /* And remove it */ RemainingPath.Length -= sizeof(WCHAR); RemainingPath.MaximumLength -= sizeof(WCHAR); }
+ /* Now loop the entire path */ for (i = 0; i < RemainingPath.Length / sizeof(WCHAR); i++) { - if (L'\' == RemainingPath.Buffer[i]) + /* And check if we found slahes */ + if (RemainingPath.Buffer[i] == OBJ_NAME_PATH_SEPARATOR) { - DPRINT("NtCreateKey() doesn't create trees! (found '\' in remaining path: "%wZ"!)\n", &RemainingPath); - - PostCreateKeyInfo.Object = NULL; - PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND; - CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); - + /* We don't create trees -- parent key doesn't exist, so fail */ Status = STATUS_OBJECT_NAME_NOT_FOUND; goto Cleanup; } }
- DPRINT("RemainingPath %wZ ParentObject 0x%p\n", &RemainingPath, Object); - - // - if (RemainingPath.Length == 0 || RemainingPath.Buffer[0] == UNICODE_NULL) - { + /* Now check if we're left with no name by this point */ + if (!(RemainingPath.Length) || (RemainingPath.Buffer[0] == UNICODE_NULL)) + { + /* Then fail since we can't do anything */ Status = STATUS_OBJECT_NAME_NOT_FOUND; goto Cleanup; } - - - /* Acquire hive lock */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
/* Create the key */ - Status = CmpDoCreate(((PKEY_OBJECT)Object)->KeyControlBlock->KeyHive, - ((PKEY_OBJECT)Object)->KeyControlBlock->KeyCell, + Status = CmpDoCreate(Parent->KeyControlBlock->KeyHive, + Parent->KeyControlBlock->KeyCell, NULL, &RemainingPath, KernelMode, Class, CreateOptions, - ((PKEY_OBJECT)Object)->KeyControlBlock, + Parent->KeyControlBlock, NULL, (PVOID*)&KeyObject); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CmiAddSubKey() failed (Status %lx)\n", Status); - /* Release hive lock */ - ExReleaseResourceLite(&CmpRegistryLock); - KeLeaveCriticalRegion(); - - PostCreateKeyInfo.Object = NULL; - PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL; - CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); - - Status = STATUS_UNSUCCESSFUL; - goto Cleanup; - } - - RtlDuplicateUnicodeString - (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, - &RemainingPath, &KeyObject->Name); - DPRINT("Key Name: %wZ\n", &KeyObject->Name); + if (!NT_SUCCESS(Status)) goto Cleanup; + + /* If we got here, this is a new key */ + LocalDisposition = REG_CREATED_NEW_KEY; + + /* Now save the key name */ + RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, + &RemainingPath, + &KeyObject->Name); + + /* Get the parent node and the child node */
ParentNode = (PCM_KEY_NODE)HvGetCell(KeyObject->KeyControlBlock->ParentKcb->KeyHive, KeyObject->KeyControlBlock->ParentKcb->KeyCell); - Node = (PCM_KEY_NODE)HvGetCell(KeyObject->KeyControlBlock->KeyHive, KeyObject->KeyControlBlock->KeyCell); - + + /* Inherit some information */ Node->Parent = KeyObject->KeyControlBlock->ParentKcb->KeyCell; Node->Security = ParentNode->Security; - KeyObject->KeyControlBlock->ValueCache.ValueList = Node->ValueList.List; KeyObject->KeyControlBlock->ValueCache.Count = Node->ValueList.Count;
- DPRINT("RemainingPath: %wZ\n", &RemainingPath); - - CmiAddKeyToList(((PKEY_OBJECT)Object), KeyObject); - - VERIFY_KEY_OBJECT(KeyObject); - + /* Link child to parent */ + CmiAddKeyToList(Parent, KeyObject); + + /* Create the actual handle to the object */ Status = CmpCreateHandle(KeyObject, DesiredAccess, ObjectCreateInfo.Attributes, @@ -367,58 +185,25 @@ /* Free the create information */ ObpFreeAndReleaseCapturedAttributes(OBJECT_TO_OBJECT_HEADER(KeyObject)->ObjectCreateInfo); OBJECT_TO_OBJECT_HEADER(KeyObject)->ObjectCreateInfo = NULL; - - if (!NT_SUCCESS(Status)) - { - DPRINT1("ObInsertObject() failed!\n"); - - PostCreateKeyInfo.Object = NULL; - PostCreateKeyInfo.Status = Status; - CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); - - goto Cleanup; - } + if (!NT_SUCCESS(Status)) goto Cleanup;
/* Add the keep-alive reference */ ObReferenceObject(KeyObject); - /* Release hive lock */ - ExReleaseResourceLite(&CmpRegistryLock); - KeLeaveCriticalRegion(); - - PostCreateKeyInfo.Object = KeyObject; - PostCreateKeyInfo.Status = Status; - CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo); - + + /* Force a lazy flush */ CmpLazyFlush(); - - LocalDisposition = REG_CREATED_NEW_KEY;
SuccessReturn: - _SEH_TRY - { - *KeyHandle = hKey; - if (Disposition != NULL) - { - *Disposition = LocalDisposition; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; + /* Return data to user */ + *KeyHandle = hKey; + if (Disposition) *Disposition = LocalDisposition;
Cleanup: + /* Cleanup */ ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (Class != NULL) - { - ReleaseCapturedUnicodeString(&CapturedClass, - PreviousMode); - } if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); RtlFreeUnicodeString(&ReturnedPath); - if (Object != NULL) ObDereferenceObject(Object); - + if (Parent) ObDereferenceObject(Parent); return Status; }
@@ -428,88 +213,34 @@ IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes) { - UNICODE_STRING RemainingPath; - KPROCESSOR_MODE PreviousMode; - PVOID Object = NULL; + UNICODE_STRING RemainingPath = {0}; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PKEY_OBJECT Object = NULL; HANDLE hKey = NULL; NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING ObjectName; OBJECT_CREATE_INFORMATION ObjectCreateInfo; - REG_PRE_OPEN_KEY_INFORMATION PreOpenKeyInfo; - REG_POST_OPEN_KEY_INFORMATION PostOpenKeyInfo; - PAGED_CODE(); - - DPRINT("NtOpenKey(KH 0x%p DA %x OA 0x%p OA->ON '%wZ'\n", - KeyHandle, - DesiredAccess, - ObjectAttributes, - ObjectAttributes ? ObjectAttributes->ObjectName : NULL); - - /* Check place for result handle, if it's null - return immediately */ - if (KeyHandle == NULL) - return(STATUS_INVALID_PARAMETER); - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeAndZeroHandle(KeyHandle); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - return Status; - } - } - - /* WINE checks for the length also */ - /*if (ObjectAttributes->ObjectName->Length > MAX_NAME_LENGTH) - return(STATUS_BUFFER_OVERFLOW);*/ - + /* Capture all the info */ - DPRINT("Capturing Create Info\n"); Status = ObpCaptureObjectAttributes(ObjectAttributes, PreviousMode, FALSE, &ObjectCreateInfo, &ObjectName); - if (!NT_SUCCESS(Status)) - { - DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status); - return Status; - } - - if (ObjectName.Buffer && - ObjectName.Buffer[(ObjectName.Length / sizeof(WCHAR)) - 1] == '\') - { - ObjectName.Buffer[(ObjectName.Length / sizeof(WCHAR)) - 1] = UNICODE_NULL; + if (!NT_SUCCESS(Status)) return Status; + + /* Loop every terminating slash */ + while ((ObjectName.Length) && + (ObjectName.Buffer[(ObjectName.Length / sizeof(WCHAR)) - 1] == + OBJ_NAME_PATH_SEPARATOR)) + { + /* And remove it */ ObjectName.Length -= sizeof(WCHAR); ObjectName.MaximumLength -= sizeof(WCHAR); } - - PostOpenKeyInfo.CompleteName = &ObjectName; - PreOpenKeyInfo.CompleteName = &ObjectName; - Status = CmiCallRegisteredCallbacks(RegNtPreOpenKey, &PreOpenKeyInfo); - if (!NT_SUCCESS(Status)) - { - PostOpenKeyInfo.Object = NULL; - PostOpenKeyInfo.Status = Status; - CmiCallRegisteredCallbacks (RegNtPostOpenKey, &PostOpenKeyInfo); - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); - return Status; - } - - RemainingPath.Buffer = NULL; - + + /* Find the key */ Status = CmFindObject(&ObjectCreateInfo, &ObjectName, (PVOID*)&Object, @@ -517,64 +248,39 @@ CmpKeyObjectType, NULL, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("CmpFindObject() returned 0x%08lx\n", Status); - Status = STATUS_INVALID_HANDLE; /* Because ObFindObject returns STATUS_UNSUCCESSFUL */ - goto openkey_cleanup; - } - - VERIFY_KEY_OBJECT((PKEY_OBJECT) Object); - - DPRINT("RemainingPath '%wZ'\n", &RemainingPath); - - if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0)) - { - RtlFreeUnicodeString(&RemainingPath); + if (!NT_SUCCESS(Status)) goto openkey_cleanup; + + /* Make sure we don't have any remaining path */ + if ((RemainingPath.Buffer) && (RemainingPath.Buffer[0] != UNICODE_NULL)) + { + /* Fail */ Status = STATUS_OBJECT_NAME_NOT_FOUND; goto openkey_cleanup; }
- RtlFreeUnicodeString(&RemainingPath); - - /* Fail if the key has been deleted */ - if (((PKEY_OBJECT)Object)->KeyControlBlock->Delete) - { + /* Check if the key has been deleted */ + if (Object->KeyControlBlock->Delete) + { + /* Fail */ Status = STATUS_UNSUCCESSFUL; goto openkey_cleanup; }
+ /* Create the actual handle */ Status = CmpCreateHandle(Object, DesiredAccess, ObjectCreateInfo.Attributes, &hKey);
openkey_cleanup: - + /* Cleanup */ ObpReleaseCapturedAttributes(&ObjectCreateInfo); - PostOpenKeyInfo.Object = NT_SUCCESS(Status) ? (PVOID)Object : NULL; - PostOpenKeyInfo.Status = Status; - CmiCallRegisteredCallbacks (RegNtPostOpenKey, &PostOpenKeyInfo); if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); - - if (Object) - { - ObDereferenceObject(Object); - } - - if (NT_SUCCESS(Status)) - { - _SEH_TRY - { - *KeyHandle = hKey; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - + RtlFreeUnicodeString(&RemainingPath); + if (Object) ObDereferenceObject(Object); + + /* Return information and status to user */ + *KeyHandle = hKey; return Status; }
Modified: trunk/reactos/ntoskrnl/cm/regobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regobj.c?rev=30... ============================================================================== --- trunk/reactos/ntoskrnl/cm/regobj.c (original) +++ trunk/reactos/ntoskrnl/cm/regobj.c Fri Nov 23 23:32:38 2007 @@ -26,6 +26,103 @@ PUNICODE_STRING TargetPath);
/* FUNCTONS *****************************************************************/ + +NTSTATUS +NTAPI +CmpCreateHandle(PVOID ObjectBody, + ACCESS_MASK GrantedAccess, + ULONG HandleAttributes, + PHANDLE HandleReturn) +/* + * FUNCTION: Add a handle referencing an object + * ARGUMENTS: + * obj = Object body that the handle should refer to + * RETURNS: The created handle + * NOTE: The handle is valid only in the context of the current process + */ +{ + HANDLE_TABLE_ENTRY NewEntry; + PEPROCESS CurrentProcess; + PVOID HandleTable; + POBJECT_HEADER ObjectHeader; + HANDLE Handle; + KAPC_STATE ApcState; + BOOLEAN AttachedToProcess = FALSE; + + PAGED_CODE(); + + DPRINT("CmpCreateHandle(obj %p)\n",ObjectBody); + + ASSERT(ObjectBody); + + CurrentProcess = PsGetCurrentProcess(); + + ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody); + + /* check that this is a valid kernel pointer */ + //ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED); + + if (GrantedAccess & MAXIMUM_ALLOWED) + { + GrantedAccess &= ~MAXIMUM_ALLOWED; + GrantedAccess |= GENERIC_ALL; + } + + if (GrantedAccess & GENERIC_ACCESS) + { + RtlMapGenericMask(&GrantedAccess, + &ObjectHeader->Type->TypeInfo.GenericMapping); + } + + NewEntry.Object = ObjectHeader; + if(HandleAttributes & OBJ_INHERIT) + NewEntry.ObAttributes |= OBJ_INHERIT; + else + NewEntry.ObAttributes &= ~OBJ_INHERIT; + NewEntry.GrantedAccess = GrantedAccess; + + if ((HandleAttributes & OBJ_KERNEL_HANDLE) && + ExGetPreviousMode() == KernelMode) + { + HandleTable = ObpKernelHandleTable; + if (PsGetCurrentProcess() != PsInitialSystemProcess) + { + KeStackAttachProcess(&PsInitialSystemProcess->Pcb, + &ApcState); + AttachedToProcess = TRUE; + } + } + else + { + HandleTable = PsGetCurrentProcess()->ObjectTable; + } + + Handle = ExCreateHandle(HandleTable, + &NewEntry); + + if (AttachedToProcess) + { + KeUnstackDetachProcess(&ApcState); + } + + if(Handle != NULL) + { + if (HandleAttributes & OBJ_KERNEL_HANDLE) + { + /* mark the handle value */ + Handle = ObMarkHandleAsKernelHandle(Handle); + } + + InterlockedIncrement(&ObjectHeader->HandleCount); + ObReferenceObject(ObjectBody); + + *HandleReturn = Handle; + + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +}
PVOID NTAPI