ReactOS 0.4.17-dev-650-gd0e71de
obhandle.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for obhandle.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

PHANDLE_TABLE NTAPI ObReferenceProcessHandleTable (IN PEPROCESS Process)
 
VOID NTAPI ObDereferenceProcessHandleTable (IN PEPROCESS Process)
 
ULONG NTAPI ObGetProcessHandleCount (IN PEPROCESS Process)
 
NTSTATUS NTAPI ObpReferenceProcessObjectByHandle (IN HANDLE Handle, IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation, OUT PACCESS_MASK AuditMask)
 
BOOLEAN NTAPI ObpEnumFindHandleProcedure (IN PHANDLE_TABLE_ENTRY HandleEntry, IN HANDLE Handle, IN PVOID Context)
 
POBJECT_HANDLE_COUNT_ENTRY NTAPI ObpInsertHandleCount (IN POBJECT_HEADER ObjectHeader)
 
NTSTATUS NTAPI ObpIncrementHandleDataBase (IN POBJECT_HEADER ObjectHeader, IN PEPROCESS Process, IN OUT PULONG NewProcessHandleCount)
 
NTSTATUS NTAPI ObpChargeQuotaForObject (IN POBJECT_HEADER ObjectHeader, IN POBJECT_TYPE ObjectType, OUT PBOOLEAN NewObject)
 
NTSTATUS NTAPI ObpValidateAccessMask (IN PACCESS_STATE AccessState)
 
VOID NTAPI ObpDecrementHandleCount (IN PVOID ObjectBody, IN PEPROCESS Process, IN ACCESS_MASK GrantedAccess, IN POBJECT_TYPE ObjectType)
 
NTSTATUS NTAPI ObpCloseHandleTableEntry (IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleEntry, IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN IgnoreHandleProtection)
 
NTSTATUS NTAPI ObpIncrementHandleCount (IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process, IN OB_OPEN_REASON OpenReason)
 
NTSTATUS NTAPI ObpIncrementUnnamedHandleCount (IN PVOID Object, IN PACCESS_MASK DesiredAccess, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process)
 
NTSTATUS NTAPI ObpCreateUnnamedHandle (IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN ULONG AdditionalReferences, IN ULONG HandleAttributes, IN KPROCESSOR_MODE AccessMode, OUT PVOID *ReturnedObject, OUT PHANDLE ReturnedHandle)
 
NTSTATUS NTAPI ObpCreateHandle (IN OB_OPEN_REASON OpenReason, IN PVOID Object, IN POBJECT_TYPE Type OPTIONAL, IN PACCESS_STATE AccessState, IN ULONG AdditionalReferences, IN ULONG HandleAttributes, IN POBP_LOOKUP_CONTEXT Context, IN KPROCESSOR_MODE AccessMode, OUT PVOID *ReturnedObject, OUT PHANDLE ReturnedHandle)
 
NTSTATUS NTAPI ObpCloseHandle (IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
 
static BOOLEAN NTAPI ObpSetHandleAttributes (_Inout_ PHANDLE_TABLE_ENTRY HandleTableEntry, _In_ ULONG_PTR Context)
 Internal callback used by ObSetHandleAttributes(). Updates the attributes of a handle given by its handle table entry.
 
BOOLEAN NTAPI ObpCloseHandleCallback (IN PHANDLE_TABLE_ENTRY HandleTableEntry, IN HANDLE Handle, IN PVOID Context)
 
BOOLEAN NTAPI ObpDuplicateHandleCallback (IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY OldEntry, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
 
VOID NTAPI ObClearProcessHandleTable (IN PEPROCESS Process)
 
NTSTATUS NTAPI ObInitProcess (IN PEPROCESS Parent OPTIONAL, IN PEPROCESS Process)
 
VOID NTAPI ObKillProcess (IN PEPROCESS Process)
 
NTSTATUS NTAPI ObDuplicateObject (IN PEPROCESS SourceProcess, IN HANDLE SourceHandle, IN PEPROCESS TargetProcess OPTIONAL, IN PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options, IN KPROCESSOR_MODE PreviousMode)
 
NTSTATUS NTAPI ObOpenObjectByName (IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
 
NTSTATUS NTAPI ObOpenObjectByPointer (IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
 
BOOLEAN NTAPI ObFindHandleForObject (IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType, IN POBJECT_HANDLE_INFORMATION HandleInformation, OUT PHANDLE Handle)
 
NTSTATUS NTAPI ObInsertObject (IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
 
NTSTATUS NTAPI ObSetHandleAttributes (_In_ HANDLE Handle, _In_ POBJECT_HANDLE_FLAG_INFORMATION HandleFlags, _In_ KPROCESSOR_MODE PreviousMode)
 Sets the attributes (inheritable and protect-from-close) of an existing object handle.
 
NTSTATUS NTAPI ObCloseHandle (IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
 
NTSTATUS NTAPI NtClose (IN HANDLE Handle)
 
NTSTATUS NTAPI NtDuplicateObject (IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
 
BOOLEAN NTAPI ObIsKernelHandle (IN HANDLE Handle)
 

Variables

PHANDLE_TABLE ObpKernelHandleTable = NULL
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file obhandle.c.

Function Documentation

◆ NtClose()

NTSTATUS NTAPI NtClose ( IN HANDLE  Handle)

Definition at line 3419 of file obhandle.c.

3420{
3421 /* Call the internal API */
3423}
#define ExGetPreviousMode
Definition: ex.h:143
ULONG Handle
Definition: gdb_input.c:15
NTSTATUS NTAPI ObpCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:1739

Referenced by _At_(), _main(), _tmain(), AccessCheckEmptyMappingTest(), AccessGrantedMultipleObjectsTests(), AccessGrantedNoDaclTests(), AccessGrantedTests(), AccpCloseObjectHandle(), add_boot_rename_entry(), AddCodepageToRegistry(), AddFontsSettingsToRegistry(), AddHotkeySettings(), AddKbLayoutsToRegistry(), AddVolumeToList(), AfdBind(), AfdConnect(), AfdGetInformation(), AfdSend(), AfdSendTo(), AfdSetInformation(), alloc_console(), AllocConsole(), AssignDriveLetter(), AssignNextDriveLetter(), BaseComputeProcessDllPath(), BaseGetNamedObjectDirectory(), BaseInitializeStaticServerData(), BasepCopyFileExW(), BasepIsProcessAllowed(), BasepMapFile(), BasepMoveFileDelayed(), BasepNotifyTrackingService(), BasepOpenFileForMove(), BasepSxsCloseHandles(), BaseSrvCleanupVDMResources(), BaseSrvCreatePairWaitHandles(), BaseSrvDestroyConsoleRecord(), BaseSrvDestroyPairWaitHandles(), BaseSrvIsVdmAllowed(), Beep(), CabinetExtractFile(), CallApphelpWithImage(), CallCacheControl(), check_boot_options(), CheckForGlobalDriveLetter(), CheckTokenMembership(), clean_main(), ClientThread(), CloseCabinet(), CloseDefaultKeys(), CloseDevice(), CloseHandle(), CloseIniBootLoaderStore(), closeTcpFile(), CmGetSystemDriverList(), CmInitSystem1(), CmpCreateControlSet(), CmpCreateHardwareProfile(), CmpInitializeHardwareConfiguration(), CmpInitializeMachineDependentConfiguration(), CmpInitializeRegistryNode(), CmpSetSystemValues(), CmpSetupConfigurationTree(), CmpSetVersionData(), CommandDumpSector(), CommandPartInfo(), CON_API(), ConCfgOpenUserSettings(), ConDrvDeinitInputBuffer(), ConnectConsole(), ConnectRegistry(), ConSrvDeleteConsole(), ConSrvInitConsole(), ConvertNtPathToWin32Path(), create_classes_root_hkey(), create_key(), create_pseudo_console(), create_registry_key(), create_special_root_hkey(), CreateBaseAcls(), CreateContext(), CreateDirectoryExW(), CreateDirectoryW(), CreateDisk(), CreateHardLinkW(), CreateIoCompletionPort(), CreateKeyTest(), CreateNestedKey(), CreatePartitionList(), CreatePipe(), CreateProcessAsUserCommon(), CreateProcessInternalW(), CreatePseudoConsole(), CreateRegistryFile(), CreateRemoteThread(), CreateRemoteThreadEx(), CreateSymbolicLinkW(), CreateSymLinkKey(), CreateWindowStationW(), CSR_API(), CsrApiPortInitialize(), CsrCreateRemoteThread(), CsrGetProcessLuid(), CsrpCheckRequestThreads(), CsrpConnectToServer(), CsrProcessRefcountZero(), CsrSbApiRequestThread(), CsrSetProcessSecurity(), CsrSrvCreateSharedSection(), CsrThreadRefcountZero(), DbgUiIssueRemoteBreakin(), DebugActiveProcess(), DebugActiveProcessStop(), DefineDosDeviceW(), DeleteDriveLetter(), DeleteFileW(), DeleteKeyTest(), DeleteSymLinkKey(), DeleteValueTest(), DenyAccessTests(), DestroyProtoHive(), DisablePredefinedHandleTableInternal(), DismountVolume(), do_enumeratekey(), DoesPathExist_UStr(), DumpDisk(), DumpPartition(), DumpRegistryData(), enum_modules64(), EnumerateKeyTest(), EnumerateValueTest(), ExpandSymbolicLink(), ExpCreateSystemRootLink(), ExpInitializeCallbacks(), Ext2CloseDevice(), FindClose(), FindFirstChangeNotificationW(), FindFirstFileExW(), FindFirstStreamW(), FindNTOSInstallations(), FormatEx2(), FreeConsole(), get_file_id(), get_manifest_in_associated_manifest(), get_manifest_in_manifest_file(), get_manifest_in_pe_file(), get_perflib_key(), get_proc_address64(), get_registry_locale_info(), get_system_root(), GetAutomountState(), GetCallerLuid(), GetCompressedFileSizeW(), GetComputerIdentifier(), GetComputerNameFromRegistry(), GetConsoleIMECommandLine(), GetCPFileNameFromRegistry(), GetDeviceInfo_UStr(), GetDiskFreeSpaceExW(), GetDiskFreeSpaceW(), GetDisplayIdentifier(), GetDllList(), GetDosDevicesProtection(), GetDriveTypeW(), GetFileSecurityW(), GetFileSystem(), GetFileSystemName_UStr(), GetLogicalDrives(), GetNTObjectSymbolicLinkTarget(), GetRegInt(), GetSocketInformation(), GetSourcePaths(), GetTempFileNameW(), GetTimeouts(), GetToken(), GetTokenProcess(), GetUserGeoID(), GetVolumeInformationW(), GetVolumeNameForRoot(), GetVolumePathNameW(), GrantedAccessTests(), GRAPHICS_BUFFER_Destroy(), GRAPHICS_BUFFER_Initialize(), GuiApplyUserSettings(), GuiConsoleShowConsoleProperties(), GuiDeinitFrontEnd(), GuiInit(), GuiInitFrontEnd(), IcmpCloseHandle(), ImpersonateLoggedOnUser(), InferFileSystem(), InfOpenFile(), InfWriteFile(), IniCacheLoad(), IniCacheSave(), InitFunctionPtrs(), InitializeFmIfsOnce(), InitializeUserModePnpManager(), InitLogPort(), InitVolumeDeviceName(), InstallBootCodeToDisk(), InstallBootCodeToFile(), InstallBootManagerAndBootEntries(), InstallDevice(), InstallDriver(), InstallSetupInfFile(), IntAllocConsole(), IntAttachConsole(), IntGetCodePageEntry(), IntIsLogOnSession(), IopCreateRootDirectories(), IopInitializePlugPlayServices(), IopMarkBootPartition(), is_mounted_multi_device(), IsAcpiComputer(), IsShimInfrastructureDisabled(), IsThisARootDirectory(), IsValidLanguageGroup(), IsValidNTOSInstallation(), JapaneseEra_IsFirstYearGannen(), JapaneseEra_Load(), keyed_event_thread(), KsecOpenDevice(), LdrOpenImageFileOptionsKey(), LdrpCheckForKnownDll(), LdrpCheckForLoadedDll(), LdrpCreateDllSection(), LdrpDisableProcessCompatGuidDetection(), LdrpInitializeProcess(), LdrpMapDll(), LdrQueryImageFileExecutionOptionsEx(), LdrVerifyImageMatchesChecksum(), ListDirectory(), LoadModule(), LoadSymbolsRoutine(), LOCALE_InitRegistry(), LogfBackupFile(), LogfClose(), LogfCreate(), lookup_assembly(), lookup_winsxs(), LsaConnectUntrusted(), LsapAddNotification(), LsapCheckLogonProcess(), LsapCloseDbObject(), LsapCloseLsaPort(), LsapCreateDatabaseKeys(), LsapCreateDbObject(), LsapDeleteDbObject(), LsapDeregisterLogonProcess(), LsapEnumLogonSessions(), LsapGetLogonSessionData(), LsapGetObjectAttribute(), LsapIsDatabaseInstalled(), LsapIsTrustedClient(), LsapLogonUser(), LsapOpenDbObject(), LsapRegCloseKey(), LsapRegDeleteSubKey(), LsapRemoveNotification(), LsapSetObjectAttribute(), LsarSetSecurityObject(), main(), MapFile(), MountVolume(), MoveFileWithProgressW(), MsafdUpdateConnectionContext(), MyDeleteFile(), NetpGetClientLogonId(), NetUserChangePassword(), NLS_EnumLanguageGroupLocales(), NLS_EnumSystemLanguageGroups(), NlsInit(), NlsUninit(), NtQueryOpenSubKeys(), ObDuplicateObject(), ObInitSystem(), ObpCreateDosDevicesDirectory(), open_cross_process_connection(), open_key(), open_subkey(), open_wow6432node_parent(), OpenAndMapFile(), OpenBootStore_UStr(), OpenFile(), OpenIniBootLoaderStore(), OpenWindowStationW(), nt_handle::operator=(), ParamsValidationTests(), ParamValidationNoObjsList(), parse_file(), Phase1InitializationDiscard(), PipGetDriverTagPriority(), PortThreadRoutine(), PrintProcess(), PrintThreads(), PrivMoveFileIdentityW(), ProcessDisplayRegistry(), ProcessIdToSessionId(), ProcessLocaleRegistry(), ProfileLoopFunction(), QueryDeviceInformation(), QueryDosDeviceW(), QueryDosVolumeNameForNtDeviceName(), QueryTokenImpersonationTests(), QueryTokenIsSandboxInert(), QueryTokenPrivilegesAndGroupsTests(), QueryTokenRestrictedSidsTest(), read_nt_symlink(), ReadBlock(), ReadBootCodeFromFile(), RegCleanupRegistry(), RegCloseKey(), RegCopyTreeW(), RegDeleteKeyExW(), RegInitializeRegistry(), RegisterUncProvider(), registry_callback(), RegOverridePredefKey(), RegpCopyTree(), RegReplaceKeyW(), RegRestoreKeyW(), RegSaveKeyW(), RegSetKeyValueA(), RegSetKeyValueW(), RemapPredefinedHandleInternal(), RemoveDirectoryW(), ReplaceFileW(), resolve_symlink(), ResolveArcNameNtSymLink(), RSetServiceObjectSecurity(), RtlCreateActivationContext(), RtlCreateTimerQueue(), RtlCreateUserSecurityObject(), RtlCreateUserThread(), RtlDefaultNpAcl(), RtlDeleteCriticalSection(), RtlDeleteResource(), RtlDeleteTimer(), RtlDeleteTimerQueueEx(), RtlDeregisterWaitEx(), RtlImpersonateSelf(), RtlInitializeRXact(), RtlNewSecurityGrantedAccess(), RtlpCloseKeyedEvent(), RtlpExecuteIoWorkItem(), RtlpExecuteWorkItem(), RtlpIoWorkerThreadProc(), RtlpIsIoPending(), RtlpStartWorkerThread(), RtlQueryRegistryValues(), RtlQueueWorkItem(), RtlRegisterWait(), RtlReleaseRelativeName(), RtlSetCurrentDirectory_U(), RtlSetIoCompletionCallback(), RXactpCommit(), SampRegCloseKey(), SampRegDeleteKey(), SamrSetSecurityObject(), SaveBootSector(), ScmCheckDriver(), ScmConvertToBootPathName(), ScmGetDriverStatus(), ScrubAutomount(), SdbCloseDatabase(), SdbDeletePermLayerKeys(), SdbpCloseMemMappedFile(), SdbpGetPermLayersInternal(), SdbpOpenMemMappedFile(), SdbRegisterDatabaseEx(), SdbSetPermLayerKeys(), SdbUnregisterDatabase(), ServerThread(), SetActiveComputerNameToRegistry(), SetAutomountState(), SetComputerNameToRegistry(), SetDefaultPagefile(), SetFileAttributesW(), SetFileSecurityW(), SetGeoID(), SetLocaleInfoW(), SetMountedDeviceValue(), SetRosSpecificInfo(), SetSocketInformation(), SetupCopyFile(), SetupCreateSingleDirectory(), SetupDeleteFile(), SetupMoveFile(), SetUserGeoID(), SetValueTest1(), SetValueTest2(), SetVolumeLabelW(), SmExecPgm(), SmExecuteProgram(), SmLookupSubsystem(), SmpAcquirePrivilege(), SmpConfigureObjectDirectories(), SmpCreateDynamicEnvironmentVariables(), SmpCreateVolumeDescriptors(), SmpDeletePagingFile(), SmpDereferenceSubsystem(), SmpExecPgm(), SmpExecuteImage(), SmpExecuteInitialCommand(), SmpGetPagingFileSize(), SmpGetVolumeFreeSpace(), SmpHandleConnectionRequest(), SmpInit(), SmpInitializeDosDevices(), SmpInitializeKnownDllsInternal(), SmpLoadDataFromRegistry(), SmpLoadSubSystem(), SmpProcessFileRenames(), SmpReleasePrivilege(), SmpSbCreateSession(), SmpStartCsr(), SmpTranslateSystemPartitionInformation(), SockCreateOrReferenceAsyncThread(), SpeakerCleanup(), start_debugger(), START_TEST(), StartAuthenticationPort(), subtest_empty_name_pipe_operations(), subtest_pipe_name(), subtest_query_process_debug_port_custom_dacl(), TerminateUserModePnpManager(), test1(), test2(), test3(), test5(), test6(), test7(), test9(), Test_ApphelpCheckRunApp(), test_completion_port_scheduling(), test_debuggee_dbgport(), Test_Device_StorDeviceNumber(), Test_EmptyFile(), test_exception_dispatcher(), test_image_mappings(), Test_ImageSection(), test_init_block(), test_keyed_events(), Test_KeyFullInformation(), Test_KeyNameInformation(), test_mutant(), test_notifications(), test_nt_names(), test_nt_wow64(), test_NtAllocateReserveObject(), test_NtMapViewOfSection(), test_NtMapViewOfSectionEx(), test_NtOpenKey(), test_object_permanence(), Test_Other(), Test_PageFileSection(), test_perflib_key(), test_query_image_information(), test_query_process(), test_query_process_debug_object_handle(), test_query_region_information(), Test_RawSize(), Test_recv(), Test_SectionBasicInformation(), Test_SectionContents(), test_semaphore(), test_syscalls(), Test_ThreadHideFromDebuggerClass(), Test_ThreadNameInformation(), test_tp_multi_wait(), TestCreateOpen_(), TestSend(), TestSendTo(), TestTcp(), TestUdp(), TH32CreateSnapshotSectionInitialize(), timer_queue_thread_proc(), tp_ioqueue_lock(), tp_new_worker_thread(), tp_timerqueue_lock(), tp_waitqueue_lock(), UnhandledExceptionFilter(), UnMapFile(), UserpFormatMessages(), VfatFormat(), VfatxFormat(), wait_pipe(), Wait_thread_proc(), WaitNamedPipeW(), waitqueue_thread_proc(), WinExec(), WriteGptPartitions(), WriteMbrPartitions(), WritePartitions(), WSPAccept(), WSPBind(), WSPCloseSocket(), WSPConnect(), WSPDuplicateSocket(), WSPEnumNetworkEvents(), WSPEventSelect(), WSPGetPeerName(), WSPGetSockName(), WSPListen(), WSPRecv(), WSPRecvFrom(), WSPSelect(), WSPSend(), WSPSendTo(), WSPShutdown(), WSPSocket(), CEnumNTDirectory::~CEnumNTDirectory(), mountmgr::~mountmgr(), and nt_handle::~nt_handle().

◆ NtDuplicateObject()

NTSTATUS NTAPI NtDuplicateObject ( IN HANDLE  SourceProcessHandle,
IN HANDLE  SourceHandle,
IN HANDLE TargetProcessHandle  OPTIONAL,
OUT PHANDLE TargetHandle  OPTIONAL,
IN ACCESS_MASK  DesiredAccess,
IN ULONG  HandleAttributes,
IN ULONG  Options 
)

Definition at line 3427 of file obhandle.c.

3434{
3435 PEPROCESS SourceProcess, TargetProcess, Target;
3436 HANDLE hTarget;
3440 "%s - Duplicating handle: %p for %p into %p.\n",
3443 SourceProcessHandle,
3445
3446 /* Check if we have a target handle */
3447 if ((TargetHandle) && (PreviousMode != KernelMode))
3448 {
3449 /* Enter SEH */
3450 _SEH2_TRY
3451 {
3452 /* Probe the handle and assume failure */
3454 *TargetHandle = NULL;
3455 }
3457 {
3458 /* Return the exception code */
3460 }
3461 _SEH2_END;
3462 }
3463
3464 /* Now reference the input handle */
3465 Status = ObReferenceObjectByHandle(SourceProcessHandle,
3469 (PVOID*)&SourceProcess,
3470 NULL);
3471 if (!NT_SUCCESS(Status)) return Status;
3472
3473 /* Check if got a target handle */
3475 {
3476 /* Now reference the output handle */
3481 (PVOID*)&TargetProcess,
3482 NULL);
3483 if (NT_SUCCESS(Status))
3484 {
3485 /* Use this target process */
3486 Target = TargetProcess;
3487 }
3488 else
3489 {
3490 /* No target process */
3491 Target = NULL;
3492 }
3493 }
3494 else
3495 {
3496 /* No target process */
3498 Target = NULL;
3499 }
3500
3501 /* Call the internal routine */
3502 Status = ObDuplicateObject(SourceProcess,
3504 Target,
3505 &hTarget,
3508 Options,
3509 PreviousMode);
3510
3511 /* Check if the caller wanted the return handle */
3512 if (TargetHandle)
3513 {
3514 /* Protect the write to user mode */
3515 _SEH2_TRY
3516 {
3517 /* Write the new handle */
3518 *TargetHandle = hTarget;
3519 }
3521 {
3522 /* Otherwise, get the exception code */
3524 }
3525 _SEH2_END;
3526 }
3527
3528 /* Dereference the processes */
3530 "%s - Duplicated handle: %p into %p S %lx\n",
3532 hTarget,
3534 Status);
3536 ObDereferenceObject(SourceProcess);
3537 return Status;
3538}
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define __FUNCTION__
Definition: types.h:116
Status
Definition: gdiplustypes.h:24
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define PROCESS_DUP_HANDLE
#define KernelMode
Definition: asm.h:38
_In_ HANDLE SourceHandle
Definition: obfuncs.h:438
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:440
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:442
_In_ HANDLE _In_opt_ HANDLE TargetProcessHandle
Definition: obfuncs.h:439
POBJECT_TYPE PsProcessType
Definition: process.c:20
#define OBTRACE(x, fmt,...)
Definition: ob.h:34
#define OB_HANDLE_DEBUG
Definition: ob.h:17
NTSTATUS NTAPI ObDuplicateObject(IN PEPROCESS SourceProcess, IN HANDLE SourceHandle, IN PEPROCESS TargetProcess OPTIONAL, IN PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options, IN KPROCESSOR_MODE PreviousMode)
Definition: obhandle.c:2216
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:493
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3540
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by BaseSrvCreatePairWaitHandles(), BaseSrvDestroyPairWaitHandles(), ConSrvAllocateConsole(), ConSrvInheritConsole(), CSR_API(), CsrCreateRemoteThread(), DuplicateHandle(), GRAPHICS_BUFFER_Destroy(), GRAPHICS_BUFFER_Initialize(), GuiApplyUserSettings(), GuiConsoleShowConsoleProperties(), GuiInit(), LsapAddNotification(), LsapLogonUser(), RemapPredefinedHandleInternal(), RtlpIoWorkerThreadProc(), RtlpIsIoPending(), SmpExecPgm(), SmpExecuteInitialCommand(), SmpLoadSubSystem(), SmpSbCreateSession(), START_TEST(), and StuffStdHandle().

◆ ObClearProcessHandleTable()

VOID NTAPI ObClearProcessHandleTable ( IN PEPROCESS  Process)

Definition at line 2039 of file obhandle.c.

2040{
2044 BOOLEAN AttachedToProcess = FALSE;
2045
2046 ASSERT(Process);
2047
2048 /* Ensure the handle table doesn't go away while we use it */
2050 if (!HandleTable) return;
2051
2052 /* Attach to the current process if needed */
2054 {
2056 AttachedToProcess = TRUE;
2057 }
2058
2059 /* Enter a critical region */
2061
2062 /* Fill out the context */
2063 Context.AccessMode = UserMode;
2064 Context.HandleTable = HandleTable;
2065
2066 /* Sweep the handle table to close all handles */
2069 &Context);
2070
2071 /* Leave the critical region */
2073
2074 /* Detach if needed */
2075 if (AttachedToProcess)
2077
2078 /* Let the handle table go */
2080}
unsigned char BOOLEAN
Definition: actypes.h:127
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define ASSERT(a)
Definition: mode.c:44
#define UserMode
Definition: asm.h:39
VOID NTAPI ExSweepHandleTable(IN PHANDLE_TABLE HandleTable, IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, IN PVOID Context)
Definition: handle.c:1232
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1769
VOID NTAPI ObDereferenceProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:48
BOOLEAN NTAPI ObpCloseHandleCallback(IN PHANDLE_TABLE_ENTRY HandleTableEntry, IN HANDLE Handle, IN PVOID Context)
Definition: obhandle.c:1936
PHANDLE_TABLE NTAPI ObReferenceProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:26
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
_In_ PVOID Context
Definition: storport.h:2269
KAPC_STATE
Definition: ketypes.h:1727
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by NtTerminateProcess(), and PspTerminateProcess().

◆ ObCloseHandle()

NTSTATUS NTAPI ObCloseHandle ( IN HANDLE  Handle,
IN KPROCESSOR_MODE  AccessMode 
)

Definition at line 3396 of file obhandle.c.

3398{
3399 /* Call the internal API */
3401}
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396

Referenced by _IRQL_requires_max_(), CheckDirectorySecurity__(), CheckKeySecurity__(), CmpAddToHiveFileList(), CmpLinkKeyToHive(), CmpRemoveFromHiveFileList(), DbgkCreateThread(), DbgkMapViewOfSection(), DbgkpFreeDebugEvent(), DbgkpOpenHandles(), DbgkpPostFakeModuleMessages(), DbgkpPostFakeThreadMessages(), DisplayBootBitmap(), ExitThreadCallback(), ExpCreateSystemRootLink(), ExpCreateWorkerThread(), ExpInitializeWorkerThreads(), ExpInitNls(), InitThreadCallback(), IntCopyRegistryKey(), IntCreateDesktop(), IntCreateNewRegistryPath(), IntResolveDesktop(), IntSetupDeviceSettingsKey(), IntVideoPortInbvCleanup(), IoCreateController(), IoCreateDevice(), IoCreateStreamFileObjectEx(), IopDetectResourceConflict(), IopOpenLinkOrRenameTarget(), IopReassignSystemRoot(), IopStoreSystemPartitionInformation(), KernelModeTest(), KmtStartThread(), LpcpCreatePort(), MmCreatePhysicalMemorySection(), NotificationCallback(), NtLoadKeyEx(), NtQueryInformationProcess(), NtSaveKeyEx(), NtSaveMergedKeys(), NtSecureConnectPort(), NtSetDefaultLocale(), NtSetInformationFile(), NtUnloadKey2(), NtUserCloseDesktop(), NtUserCloseWindowStation(), NtUserResolveDesktop(), PnpRootCreateDevice(), PspCreateProcess(), PspCreateThread(), PspExitThread(), PspInitPhase0(), RawInputThreadMain(), RunTest(), ScrInbvCleanup(), SepOpenThreadToken(), SepRmCommandServerThread(), SepRmCommandServerThreadInit(), SeRmInitPhase1(), START_TEST(), TestAllInformation(), TestConnect(), TestCreateNamedPipe(), TestDuplicate(), TestIoCreateFile(), TestObRootSecurity(), TestPhysicalMemorySection(), TestReadWrite(), TestRelativeNames(), TestSharedCacheMap(), UserModeTest(), and UserSetProcessWindowStation().

◆ ObDereferenceProcessHandleTable()

VOID NTAPI ObDereferenceProcessHandleTable ( IN PEPROCESS  Process)

Definition at line 48 of file obhandle.c.

49{
50 /* Release the process lock */
51 ExReleaseRundownProtection(&Process->RundownProtect);
52}
#define ExReleaseRundownProtection
Definition: ex.h:139

Referenced by ObClearProcessHandleTable(), ObDuplicateObject(), ObFindHandleForObject(), ObGetProcessHandleCount(), and ObInitProcess().

◆ ObDuplicateObject()

NTSTATUS NTAPI ObDuplicateObject ( IN PEPROCESS  SourceProcess,
IN HANDLE  SourceHandle,
IN PEPROCESS TargetProcess  OPTIONAL,
IN PHANDLE TargetHandle  OPTIONAL,
IN ACCESS_MASK  DesiredAccess,
IN ULONG  HandleAttributes,
IN ULONG  Options,
IN KPROCESSOR_MODE  PreviousMode 
)

Definition at line 2216 of file obhandle.c.

2224{
2225 HANDLE_TABLE_ENTRY NewHandleEntry;
2226 BOOLEAN AttachedToProcess = FALSE;
2227 PVOID SourceObject;
2228 POBJECT_HEADER ObjectHeader;
2230 HANDLE NewHandle;
2233 ACCESS_MASK TargetAccess, SourceAccess;
2236 AUX_ACCESS_DATA AuxData;
2239 ULONG AuditMask;
2241
2242 PAGED_CODE();
2244 "%s - Duplicating handle: %p for %p into %p\n",
2247 SourceProcess,
2248 TargetProcess);
2249
2250 /* Assume failure */
2252
2253 /* Check if we're not duplicating the same access */
2255 {
2256 /* Validate the desired access */
2257 Status = STATUS_SUCCESS; //ObpValidateDesiredAccess(DesiredAccess);
2258 if (!NT_SUCCESS(Status)) return Status;
2259 }
2260
2261 /* Reference the object table */
2264
2265 /* Reference the process object */
2267 SourceProcess,
2270 &SourceObject,
2272 &AuditMask);
2273 if (!NT_SUCCESS(Status))
2274 {
2275 /* Fail */
2276 ObDereferenceProcessHandleTable(SourceProcess);
2277 return Status;
2278 }
2279 else
2280 {
2281 /* Check if we have to don't have to audit object close */
2282 if (!(HandleInformation.HandleAttributes & OBJ_AUDIT_OBJECT_CLOSE))
2283 {
2284 /* Then there is no audit mask */
2285 AuditMask = 0;
2286 }
2287 }
2288
2289 /* Check if there's no target process */
2290 if (!TargetProcess)
2291 {
2292 /* Check if the caller wanted actual duplication */
2294 {
2295 /* Invalid request */
2297 }
2298 else
2299 {
2300 /* Otherwise, do the attach */
2301 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2302
2303 /* Close the handle and detach */
2306 }
2307
2308 /* Return */
2309 ObDereferenceProcessHandleTable(SourceProcess);
2310 ObDereferenceObject(SourceObject);
2311 return Status;
2312 }
2313
2314 /* Create a kernel handle if asked, but only in the system process */
2315 if (PreviousMode == KernelMode &&
2317 TargetProcess == PsInitialSystemProcess)
2318 {
2320 }
2321
2322 /* Get the target handle table */
2324 if (!HandleTable)
2325 {
2326 /* Check if the caller wanted us to close the handle */
2328 {
2329 /* Do the attach */
2330 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2331
2332 /* Close the handle and detach */
2335 }
2336
2337 /* Return */
2338 ObDereferenceProcessHandleTable(SourceProcess);
2339 ObDereferenceObject(SourceObject);
2341 }
2342
2343 /* Get the source access */
2344 SourceAccess = HandleInformation.GrantedAccess;
2345
2346 /* Check if we're not in the target process */
2347 if (TargetProcess != PsGetCurrentProcess())
2348 {
2349 /* Attach to it */
2350 KeStackAttachProcess(&TargetProcess->Pcb, &ApcState);
2351 AttachedToProcess = TRUE;
2352 }
2353
2354 /* Check if we're duplicating the attributes */
2356 {
2357 /* Duplicate them */
2358 HandleAttributes = HandleInformation.HandleAttributes;
2359 }
2360 else
2361 {
2362 /* Don't allow caller to bypass auditing */
2363 HandleAttributes |= HandleInformation.HandleAttributes &
2365 }
2366
2367 /* Check if we're duplicating the access */
2368 if (Options & DUPLICATE_SAME_ACCESS) DesiredAccess = SourceAccess;
2369
2370 /* Get object data */
2371 ObjectHeader = OBJECT_TO_OBJECT_HEADER(SourceObject);
2372 ObjectType = ObjectHeader->Type;
2373
2374 /* Fill out the entry */
2375 RtlZeroMemory(&NewHandleEntry, sizeof(HANDLE_TABLE_ENTRY));
2376 NewHandleEntry.Object = ObjectHeader;
2378
2379 /* Check if we're using a generic mask */
2381 {
2382 /* Map it */
2384 &ObjectType->TypeInfo.GenericMapping);
2385 }
2386
2387 /* Set the target access, always propagate ACCESS_SYSTEM_SECURITY */
2388 TargetAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
2390 NewHandleEntry.GrantedAccess = TargetAccess;
2391
2392 /* Check if we're asking for new access */
2393 if (TargetAccess & ~SourceAccess)
2394 {
2395 /* We are. We need the security procedure to validate this */
2396 if (ObjectType->TypeInfo.SecurityProcedure == SeDefaultObjectMethod)
2397 {
2398 /* Use our built-in access state */
2401 &AuxData,
2402 TargetAccess,
2403 &ObjectType->TypeInfo.GenericMapping);
2404 }
2405 else
2406 {
2407 /* Otherwise we can't allow this privilege elevation */
2409 }
2410 }
2411 else
2412 {
2413 /* We don't need an access state */
2415 }
2416
2417 /* Make sure the access state was created OK */
2418 if (NT_SUCCESS(Status))
2419 {
2420 /* Add a new handle */
2421 Status = ObpIncrementHandleCount(SourceObject,
2427 }
2428
2429 /* Check if we were attached */
2430 if (AttachedToProcess)
2431 {
2432 /* We can safely detach now */
2434 AttachedToProcess = FALSE;
2435 }
2436
2437 /* Check if we have to close the source handle */
2439 {
2440 /* Attach and close */
2441 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2444 }
2445
2446 /* Check if we had an access state */
2448
2449 /* Now check if incrementing actually failed */
2450 if (!NT_SUCCESS(Status))
2451 {
2452 /* Dereference handle tables */
2453 ObDereferenceProcessHandleTable(SourceProcess);
2454 ObDereferenceProcessHandleTable(TargetProcess);
2455
2456 /* Dereference the source object */
2457 ObDereferenceObject(SourceObject);
2458 return Status;
2459 }
2460
2461 if (NewHandleEntry.ObAttributes & OBJ_PROTECT_CLOSE)
2462 {
2463 NewHandleEntry.ObAttributes &= ~OBJ_PROTECT_CLOSE;
2464 NewHandleEntry.GrantedAccess |= ObpAccessProtectCloseBit;
2465 }
2466
2467 /* Now create the handle */
2468 NewHandle = ExCreateHandle(HandleTable, &NewHandleEntry);
2469 if (!NewHandle)
2470 {
2471 /* Undo the increment */
2472 ObpDecrementHandleCount(SourceObject,
2473 TargetProcess,
2474 TargetAccess,
2475 ObjectType);
2476
2477 /* Deference the object and set failure status */
2478 ObDereferenceObject(SourceObject);
2480 }
2481
2482 /* Mark it as a kernel handle if requested */
2483 if (KernelHandle)
2484 {
2485 NewHandle = ObMarkHandleAsKernelHandle(NewHandle);
2486 }
2487
2488 /* Return the handle */
2489 if (TargetHandle) *TargetHandle = NewHandle;
2490
2491 /* Dereference handle tables */
2492 ObDereferenceProcessHandleTable(SourceProcess);
2493 ObDereferenceProcessHandleTable(TargetProcess);
2494
2495 /* Return status */
2497 "%s - Duplicated handle: %p for %p into %p. Source: %p HC PC %lx %lx\n",
2499 NewHandle,
2500 SourceProcess,
2501 TargetProcess,
2502 SourceObject,
2503 ObjectHeader->PointerCount,
2504 ObjectHeader->HandleCount);
2505 return Status;
2506}
#define PAGED_CODE()
#define OBJ_PROTECT_CLOSE
#define GENERIC_ACCESS
Definition: security.c:35
HANDLE KernelHandle
Definition: legacy.c:24
ObjectType
Definition: metafile.c:88
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:127
@ ObDuplicateHandle
Definition: obtypes.h:163
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:97
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
ULONG ACCESS_MASK
Definition: nt_native.h:40
HANDLE NTAPI ExCreateHandle(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:827
NTSTATUS NTAPI SeDefaultObjectMethod(_In_ PVOID Object, _In_ SECURITY_OPERATION_CODE OperationType, _In_ PSECURITY_INFORMATION SecurityInformation, _Inout_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_opt_ PULONG ReturnLength, _Inout_opt_ PSECURITY_DESCRIPTOR *OldSecurityDescriptor, _In_ POOL_TYPE PoolType, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode)
VOID NTAPI SeDeleteAccessState(_In_ PACCESS_STATE AccessState)
Deletes an allocated access state from the memory.
Definition: access.c:150
NTSTATUS NTAPI SeCreateAccessState(_Out_ PACCESS_STATE AccessState, _Out_ __drv_aliasesMem PAUX_ACCESS_DATA AuxData, _In_ ACCESS_MASK Access, _In_ PGENERIC_MAPPING GenericMapping)
Creates an access state.
Definition: access.c:121
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:596
#define OBJ_HANDLE_ATTRIBUTES
Definition: ob.h:52
#define ObpAccessProtectCloseBit
Definition: ob.h:59
#define ObMarkHandleAsKernelHandle(Handle)
Definition: ob.h:85
#define OBJ_AUDIT_OBJECT_CLOSE
Definition: ob.h:51
VOID NTAPI ObpDecrementHandleCount(IN PVOID ObjectBody, IN PEPROCESS Process, IN ACCESS_MASK GrantedAccess, IN POBJECT_TYPE ObjectType)
Definition: obhandle.c:530
NTSTATUS NTAPI ObpReferenceProcessObjectByHandle(IN HANDLE Handle, IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation, OUT PACCESS_MASK AuditMask)
Definition: obhandle.c:85
NTSTATUS NTAPI ObpIncrementHandleCount(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process, IN OB_OPEN_REASON OpenReason)
Definition: obhandle.c:811
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3419
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
Definition: extypes.h:767
PVOID Object
Definition: extypes.h:770
ULONG GrantedAccess
Definition: extypes.h:777
ULONG_PTR ObAttributes
Definition: extypes.h:771
LONG_PTR HandleCount
Definition: obtypes.h:511
LONG_PTR PointerCount
Definition: obtypes.h:508
POBJECT_TYPE Type
Definition: obtypes.h:514
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ACCESS_MASK _In_opt_ POBJECT_TYPE _In_ KPROCESSOR_MODE _Out_ PVOID _Out_opt_ POBJECT_HANDLE_INFORMATION HandleInformation
Definition: obfuncs.h:44
_Inout_opt_ PACCESS_STATE PassedAccessState
Definition: obfuncs.h:71
#define DUPLICATE_SAME_ACCESS
#define DUPLICATE_CLOSE_SOURCE
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417

Referenced by DbgkpOpenHandles(), and NtDuplicateObject().

◆ ObFindHandleForObject()

BOOLEAN NTAPI ObFindHandleForObject ( IN PEPROCESS  Process,
IN PVOID  Object,
IN POBJECT_TYPE  ObjectType,
IN POBJECT_HANDLE_INFORMATION  HandleInformation,
OUT PHANDLE  Handle 
)

Definition at line 2868 of file obhandle.c.

2873{
2874 OBP_FIND_HANDLE_DATA FindData;
2876 PVOID ObjectTable;
2877
2878 /* Make sure we have an object table */
2880 if (ObjectTable)
2881 {
2882 /* Check if we have an object */
2883 if (Object)
2884 {
2885 /* Set its header */
2887 }
2888 else
2889 {
2890 /* Otherwise, no object to match*/
2891 FindData.ObjectHeader = NULL;
2892 }
2893
2894 /* Set other information */
2895 FindData.ObjectType = ObjectType;
2897
2898 /* Enumerate the handle table */
2899 if (ExEnumHandleTable(Process->ObjectTable,
2901 &FindData,
2902 Handle))
2903 {
2904 /* Set success */
2905 Result = TRUE;
2906 }
2907
2908 /* Let go of the table */
2910 }
2911
2912 /* Return the result */
2913 return Result;
2914}
BOOLEAN NTAPI ExEnumHandleTable(IN PHANDLE_TABLE HandleTable, IN PEX_ENUM_HANDLE_CALLBACK EnumHandleProcedure, IN OUT PVOID Context, OUT PHANDLE EnumHandle OPTIONAL)
Definition: handle.c:1271
BOOLEAN NTAPI ObpEnumFindHandleProcedure(IN PHANDLE_TABLE_ENTRY HandleEntry, IN HANDLE Handle, IN PVOID Context)
Definition: obhandle.c:211
POBJECT_HANDLE_INFORMATION HandleInformation
Definition: ob.h:125
POBJECT_TYPE ObjectType
Definition: ob.h:124
POBJECT_HEADER ObjectHeader
Definition: ob.h:123
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by IntGetDesktopObjectHandle(), and IntResolveDesktop().

◆ ObGetProcessHandleCount()

ULONG NTAPI ObGetProcessHandleCount ( IN PEPROCESS  Process)

Definition at line 56 of file obhandle.c.

57{
60
62
63 /* Ensure the handle table doesn't go away while we use it */
65
66 if (HandleTable != NULL)
67 {
68 /* Count the number of handles the process has */
69 HandleCount = HandleTable->HandleCount;
70
71 /* Let the handle table go */
73 }
74 else
75 {
76 /* No handle table, no handles */
77 HandleCount = 0;
78 }
79
80 return HandleCount;
81}
static ULONG HandleCount
Definition: uefidisk.c:67

Referenced by ExpQuerySystemProcessInformation(), and NtQueryInformationProcess().

◆ ObInitProcess()

NTSTATUS NTAPI ObInitProcess ( IN PEPROCESS Parent  OPTIONAL,
IN PEPROCESS  Process 
)

Definition at line 2102 of file obhandle.c.

2104{
2105 PHANDLE_TABLE ParentTable, ObjectTable;
2106
2107 /* Check for a parent */
2108 if (Parent)
2109 {
2110 /* Reference the parent's table */
2112 if (!ParentTable) return STATUS_PROCESS_IS_TERMINATING;
2113
2114 /* Duplicate it */
2115 ObjectTable = ExDupHandleTable(Process,
2116 ParentTable,
2118 OBJ_INHERIT);
2119 }
2120 else
2121 {
2122 /* Otherwise just create a new table */
2123 ParentTable = NULL;
2124 ObjectTable = ExCreateHandleTable(Process);
2125 }
2126
2127 /* Make sure we have a table */
2128 if (ObjectTable)
2129 {
2130 /* Associate it */
2131 Process->ObjectTable = ObjectTable;
2132
2133 /* Check for auditing */
2135 {
2136 /* FIXME: TODO */
2137 DPRINT1("Need auditing!\n");
2138 }
2139
2140 /* Get rid of the old table now */
2141 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2142
2143 /* We are done */
2144 return STATUS_SUCCESS;
2145 }
2146 else
2147 {
2148 /* Fail */
2149 Process->ObjectTable = NULL;
2150 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2152 }
2153}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
#define DPRINT1
Definition: precomp.h:8
PHANDLE_TABLE NTAPI ExCreateHandleTable(IN PEPROCESS Process OPTIONAL)
Definition: handle.c:801
PHANDLE_TABLE NTAPI ExDupHandleTable(IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, IN ULONG_PTR Mask)
Definition: handle.c:1072
BOOLEAN NTAPI SeDetailedAuditingWithToken(_In_ PTOKEN Token)
Peforms a detailed security auditing with an access token.
Definition: audit.c:34
BOOLEAN NTAPI ObpDuplicateHandleCallback(IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY OldEntry, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: obhandle.c:1972
#define OBJ_INHERIT
Definition: winternl.h:225

Referenced by PspCreateProcess().

◆ ObInsertObject()

NTSTATUS NTAPI ObInsertObject ( IN PVOID  Object,
IN PACCESS_STATE AccessState  OPTIONAL,
IN ACCESS_MASK  DesiredAccess,
IN ULONG  ObjectPointerBias,
OUT PVOID *NewObject  OPTIONAL,
OUT PHANDLE  Handle 
)

Definition at line 2947 of file obhandle.c.

2953{
2954 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
2955 POBJECT_HEADER ObjectHeader;
2958 PVOID InsertObject;
2959 PSECURITY_DESCRIPTOR ParentDescriptor = NULL;
2960 BOOLEAN SdAllocated = FALSE;
2961 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
2963 ACCESS_STATE LocalAccessState;
2964 AUX_ACCESS_DATA AuxData;
2965 OB_OPEN_REASON OpenReason;
2967 NTSTATUS Status = STATUS_SUCCESS, RealStatus;
2968 BOOLEAN IsNewObject;
2969 PAGED_CODE();
2970
2971 /* Get the Header */
2972 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2973
2974 /* Detect invalid insert */
2975 if (!(ObjectHeader->Flags & OB_FLAG_CREATE_INFO))
2976 {
2977 /* Display warning and break into debugger */
2978 DPRINT1("OB: Attempting to insert existing object %p\n", Object);
2979 DbgBreakPoint();
2980
2981 /* Allow debugger to continue */
2984 }
2985
2986 /* Get the create and name info, as well as the object type */
2987 ObjectCreateInfo = ObjectHeader->ObjectCreateInfo;
2988 ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
2989 ObjectType = ObjectHeader->Type;
2990 ObjectName = NULL;
2991
2992 /* Check if this is an named object */
2993 if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer))
2994 {
2995 /* Get the object name */
2996 ObjectName = &ObjectNameInfo->Name;
2997 }
2998
2999 /* Sanity check */
3000 ASSERT((Handle) ||
3001 ((ObjectPointerBias == 0) &&
3002 (ObjectName == NULL) &&
3003 (ObjectType->TypeInfo.SecurityRequired) &&
3004 (NewObject == NULL)));
3005
3006 /* Check if the object is unnamed and also doesn't have security */
3008 if (!(ObjectType->TypeInfo.SecurityRequired) && !(ObjectName))
3009 {
3010 /* Assume failure */
3011 *Handle = NULL;
3012 ObjectHeader->ObjectCreateInfo = NULL;
3013
3014 /* Create the handle */
3018 ObjectCreateInfo->Attributes,
3020 NewObject,
3021 Handle);
3022
3023 /* Free the create information */
3024 ObpFreeObjectCreateInformation(ObjectCreateInfo);
3025
3026 /* Release the object name information */
3027 ObpDereferenceNameInfo(ObjectNameInfo);
3028
3029 /* Remove the extra keep-alive reference */
3031
3032 /* Return */
3034 "%s - returning Object with PC S: %lx %lx\n",
3036 ObjectHeader->PointerCount,
3037 Status);
3038 return Status;
3039 }
3040
3041 /* Check if we didn't get an access state */
3042 if (!AccessState)
3043 {
3044 /* Use our built-in access state */
3045 AccessState = &LocalAccessState;
3046 Status = SeCreateAccessState(&LocalAccessState,
3047 &AuxData,
3049 &ObjectType->TypeInfo.GenericMapping);
3050 if (!NT_SUCCESS(Status))
3051 {
3052 /* Fail */
3053 ObpDereferenceNameInfo(ObjectNameInfo);
3055 return Status;
3056 }
3057 }
3058
3059 /* Save the security descriptor */
3060 AccessState->SecurityDescriptor = ObjectCreateInfo->SecurityDescriptor;
3061
3062 /* Validate the access mask */
3064 if (!NT_SUCCESS(Status))
3065 {
3066 /* Fail */
3067 ObpDereferenceNameInfo(ObjectNameInfo);
3069 return Status;
3070 }
3071
3072 /* Setup a lookup context */
3074 InsertObject = Object;
3075 OpenReason = ObCreateHandle;
3076
3077 /* Check if the object is named */
3078 if (ObjectName)
3079 {
3080 /* Look it up */
3081 Status = ObpLookupObjectName(ObjectCreateInfo->RootDirectory,
3082 ObjectName,
3083 ObjectCreateInfo->Attributes,
3084 ObjectType,
3085 (ObjectHeader->Flags & OB_FLAG_KERNEL_MODE) ?
3087 ObjectCreateInfo->ParseContext,
3088 ObjectCreateInfo->SecurityQos,
3089 Object,
3091 &Context,
3092 &InsertObject);
3093
3094 /* Check if we found an object that doesn't match the one requested */
3095 if ((NT_SUCCESS(Status)) && (InsertObject) && (Object != InsertObject))
3096 {
3097 /* This means we're opening an object, not creating a new one */
3098 OpenReason = ObOpenHandle;
3099
3100 /* Make sure the caller said it's OK to do this */
3101 if (ObjectCreateInfo->Attributes & OBJ_OPENIF)
3102 {
3103 /* He did, but did he want this type? */
3104 if (ObjectType != OBJECT_TO_OBJECT_HEADER(InsertObject)->Type)
3105 {
3106 /* Wrong type, so fail */
3108 }
3109 else
3110 {
3111 /* Right type, so warn */
3113 }
3114 }
3115 else
3116 {
3117 /* Check if this was a symbolic link */
3118 if (OBJECT_TO_OBJECT_HEADER(InsertObject)->Type ==
3120 {
3121 /* Dereference it */
3122 ObDereferenceObject(InsertObject);
3123 }
3124
3125 /* Caller wanted to create a new object, fail */
3127 }
3128 }
3129
3130 /* Check if anything until now failed */
3131 if (!NT_SUCCESS(Status))
3132 {
3133 /* Cleanup after lookup */
3135
3136 /* Remove query reference that we added */
3137 ObpDereferenceNameInfo(ObjectNameInfo);
3138
3139 /* Dereference the object and delete the access state */
3141 if (AccessState == &LocalAccessState)
3142 {
3143 /* We used a local one; delete it */
3145 }
3146
3147 /* Return failure code */
3148 return Status;
3149 }
3150 else
3151 {
3152 /* Check if this is a symbolic link */
3154 {
3155 /* Create the internal name */
3157 }
3158 }
3159 }
3160
3161 /* Now check if this object is being created */
3162 if (InsertObject == Object)
3163 {
3164 /* Check if it's named or forces security */
3165 if ((ObjectName) || (ObjectType->TypeInfo.SecurityRequired))
3166 {
3167 /* Make sure it's inserted into an object directory */
3168 if ((ObjectNameInfo) && (ObjectNameInfo->Directory))
3169 {
3170 /* Get the current descriptor */
3171 ObGetObjectSecurity(ObjectNameInfo->Directory,
3172 &ParentDescriptor,
3173 &SdAllocated);
3174 }
3175
3176 /* Now assign it */
3178 ParentDescriptor,
3179 Object,
3180 ObjectType);
3181
3182 /* Check if we captured one */
3183 if (ParentDescriptor)
3184 {
3185 /* We did, release it */
3186 ObReleaseObjectSecurity(ParentDescriptor, SdAllocated);
3187 }
3188 else if (NT_SUCCESS(Status))
3189 {
3190 /* Other we didn't, but we were able to use the current SD */
3192 ObjectCreateInfo->ProbeMode,
3193 TRUE);
3194
3195 /* Clear the current one */
3196 AccessState->SecurityDescriptor =
3197 ObjectCreateInfo->SecurityDescriptor = NULL;
3198 }
3199 }
3200
3201 /* Check if anything until now failed */
3202 if (!NT_SUCCESS(Status))
3203 {
3204 /* Check if the directory was added */
3205 if (Context.DirectoryLocked)
3206 {
3207 /* Weird case where we need to do a manual delete */
3208 DPRINT1("Unhandled path\n");
3209 ASSERT(FALSE);
3210 }
3211
3212 /* Cleanup the lookup */
3214
3215 /* Remove query reference that we added */
3216 ObpDereferenceNameInfo(ObjectNameInfo);
3217
3218 /* Dereference the object and delete the access state */
3220 if (AccessState == &LocalAccessState)
3221 {
3222 /* We used a local one; delete it */
3224 }
3225
3226 /* Return failure code */
3227 ASSERT(FALSE);
3228 return Status;
3229 }
3230 }
3231
3232 /* Save the actual status until here */
3233 RealStatus = Status;
3234
3235 /* Check if caller wants us to create a handle */
3236 ObjectHeader->ObjectCreateInfo = NULL;
3237 if (Handle)
3238 {
3239 /* Create the handle */
3240 Status = ObpCreateHandle(OpenReason,
3241 InsertObject,
3242 NULL,
3245 ObjectCreateInfo->Attributes,
3246 &Context,
3248 NewObject,
3249 Handle);
3250 if (!NT_SUCCESS(Status))
3251 {
3252 /* If the object had a name, backout everything */
3254
3255 /* Return the status of the failure */
3256 *Handle = NULL;
3257 RealStatus = Status;
3258 }
3259
3260 /* Remove a query reference */
3261 ObpDereferenceNameInfo(ObjectNameInfo);
3262
3263 /* Remove the extra keep-alive reference */
3265 }
3266 else
3267 {
3268 /* Otherwise, lock the object */
3269 ObpAcquireObjectLock(ObjectHeader);
3270
3271 /* And charge quota for the process to make it appear as used */
3272 RealStatus = ObpChargeQuotaForObject(ObjectHeader,
3273 ObjectType,
3274 &IsNewObject);
3275
3276 /* Release the lock */
3277 ObpReleaseObjectLock(ObjectHeader);
3278
3279 /* Check if we failed and dereference the object if so */
3280 if (!NT_SUCCESS(RealStatus)) ObDereferenceObject(Object);
3281 }
3282
3283 /* We can delete the Create Info now */
3284 ObpFreeObjectCreateInformation(ObjectCreateInfo);
3285
3286 /* Check if we created our own access state and delete it if so */
3287 if (AccessState == &LocalAccessState) SeDeleteAccessState(AccessState);
3288
3289 /* Return status code */
3291 "%s - returning Object with PC RS/S: %lx %lx %lx\n",
3293 OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
3294 RealStatus, Status);
3295 return RealStatus;
3296}
#define ObpSymbolicLinkObjectType
Definition: ObTypes.cpp:171
Type
Definition: Type.h:7
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define OB_FLAG_CREATE_INFO
Definition: obtypes.h:83
#define OB_FLAG_KERNEL_MODE
Definition: obtypes.h:84
@ ObOpenHandle
Definition: obtypes.h:162
@ ObCreateHandle
Definition: obtypes.h:161
enum _OB_OPEN_REASON OB_OPEN_REASON
NTSTATUS NTAPI SeReleaseSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
Releases a captured security descriptor buffer.
Definition: sd.c:760
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:189
VOID NTAPI ObpCreateSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
Definition: oblink.c:334
VOID NTAPI ObpDeleteNameCheck(IN PVOID Object)
Definition: obname.c:301
NTSTATUS NTAPI ObpLookupObjectName(IN HANDLE RootHandle OPTIONAL, IN OUT PUNICODE_STRING ObjectName, IN ULONG Attributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, IN PVOID InsertObject OPTIONAL, IN OUT PACCESS_STATE AccessState, OUT POBP_LOOKUP_CONTEXT LookupContext, OUT PVOID *FoundObject)
Definition: obname.c:446
FORCEINLINE VOID ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:48
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Initializes a new object directory lookup context. Used for lookup operations (insertions/deletions) ...
Definition: ob_x.h:258
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
FORCEINLINE VOID ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
Definition: ob_x.h:143
FORCEINLINE VOID ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Releases an initialized object directory lookup context. Unlocks it if necessary, and dereferences th...
Definition: ob_x.h:323
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
FORCEINLINE VOID ObpFreeObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:460
NTSTATUS NTAPI ObpCreateHandle(IN OB_OPEN_REASON OpenReason, IN PVOID Object, IN POBJECT_TYPE Type OPTIONAL, IN PACCESS_STATE AccessState, IN ULONG AdditionalReferences, IN ULONG HandleAttributes, IN POBP_LOOKUP_CONTEXT Context, IN KPROCESSOR_MODE AccessMode, OUT PVOID *ReturnedObject, OUT PHANDLE ReturnedHandle)
Definition: obhandle.c:1506
NTSTATUS NTAPI ObpChargeQuotaForObject(IN POBJECT_HEADER ObjectHeader, IN POBJECT_TYPE ObjectType, OUT PBOOLEAN NewObject)
Definition: obhandle.c:431
NTSTATUS NTAPI ObpCreateUnnamedHandle(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN ULONG AdditionalReferences, IN ULONG HandleAttributes, IN KPROCESSOR_MODE AccessMode, OUT PVOID *ReturnedObject, OUT PHANDLE ReturnedHandle)
Definition: obhandle.c:1321
NTSTATUS NTAPI ObpValidateAccessMask(IN PACCESS_STATE AccessState)
Definition: obhandle.c:488
NTSTATUS NTAPI ObGetObjectSecurity(IN PVOID Object, OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, OUT PBOOLEAN MemoryAllocated)
Definition: obsecure.c:612
VOID NTAPI ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN MemoryAllocated)
Definition: obsecure.c:712
NTSTATUS NTAPI ObAssignSecurity(IN PACCESS_STATE AccessState, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PVOID Object, IN POBJECT_TYPE Type)
Definition: obsecure.c:550
#define OBJ_OPENIF
Definition: winternl.h:229
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:365
KPROCESSOR_MODE ProbeMode
Definition: obtypes.h:361
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: obtypes.h:366
POBJECT_DIRECTORY Directory
Definition: obtypes.h:453
UNICODE_STRING Name
Definition: obtypes.h:454
UCHAR Flags
Definition: obtypes.h:518
POBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: obtypes.h:521
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
NTSYSAPI void WINAPI DbgBreakPoint(void)
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
_Inout_opt_ PACCESS_STATE _In_opt_ ACCESS_MASK _In_ ULONG ObjectPointerBias
Definition: obfuncs.h:73
_Inout_opt_ PACCESS_STATE _In_opt_ ACCESS_MASK _In_ ULONG _Out_opt_ PVOID * NewObject
Definition: obfuncs.h:74

Referenced by _IRQL_requires_max_(), CmpCreateRegistryRoot(), CreateClientPort(), ExCreateCallback(), HalpDmaAllocateChildAdapter(), IntCreateWindowStation(), IoCreateController(), IoCreateDevice(), IoCreateDriver(), IoCreateStreamFileObjectEx(), IopInitializeDriverModule(), LpcpCreatePort(), MmCreatePhysicalMemorySection(), NtCreateDebugObject(), NtCreateDirectoryObject(), NtCreateEvent(), NtCreateEventPair(), NtCreateIoCompletion(), NtCreateJobObject(), NtCreateMutant(), NtCreateProfile(), NtCreateSection(), NtCreateSemaphore(), NtCreateSymbolicLinkObject(), NtCreateTimer(), NtDuplicateToken(), NtFilterToken(), NtSecureConnectPort(), ObtCreateObjects(), PspCreateProcess(), PspCreateThread(), SeFilterToken(), SepCreateToken(), SepInitializationPhase1(), SepOpenThreadToken(), and SeSubProcessToken().

◆ ObIsKernelHandle()

BOOLEAN NTAPI ObIsKernelHandle ( IN HANDLE  Handle)

Definition at line 3542 of file obhandle.c.

3543{
3544 /* Use the inlined version. We know we are in kernel mode. */
3546}
#define ObpIsKernelHandle(Handle, ProcessorMode)
Definition: ob.h:74

◆ ObKillProcess()

VOID NTAPI ObKillProcess ( IN PEPROCESS  Process)

Definition at line 2172 of file obhandle.c.

2173{
2176 BOOLEAN HardErrors;
2177 PAGED_CODE();
2178
2179 /* Wait for process rundown and then complete it */
2181 ExRundownCompleted(&Process->RundownProtect);
2182
2183 /* Get the object table */
2184 HandleTable = Process->ObjectTable;
2185 if (!HandleTable) return;
2186
2187 /* Disable hard errors while we close handles */
2188 HardErrors = IoSetThreadHardErrorMode(FALSE);
2189
2190 /* Enter a critical region */
2192
2193 /* Fill out the context */
2194 Context.AccessMode = KernelMode;
2195 Context.HandleTable = HandleTable;
2196
2197 /* Sweep the handle table to close all handles */
2200 &Context);
2201 ASSERT(HandleTable->HandleCount == 0);
2202
2203 /* Leave the critical region */
2205
2206 /* Re-enable hard errors */
2207 IoSetThreadHardErrorMode(HardErrors);
2208
2209 /* Destroy the object table */
2210 Process->ObjectTable = NULL;
2212}
#define ExWaitForRundownProtectionRelease
Definition: ex.h:141
#define ExRundownCompleted
Definition: ex.h:142
VOID NTAPI ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable, IN PVOID DestroyHandleProcedure OPTIONAL)
Definition: handle.c:963
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:726

Referenced by PspDeleteProcess(), and PspExitThread().

◆ ObOpenObjectByName()

NTSTATUS NTAPI ObOpenObjectByName ( IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN POBJECT_TYPE  ObjectType,
IN KPROCESSOR_MODE  AccessMode,
IN PACCESS_STATE  PassedAccessState,
IN ACCESS_MASK  DesiredAccess,
IN OUT PVOID  ParseContext,
OUT PHANDLE  Handle 
)

Definition at line 2544 of file obhandle.c.

2551{
2552 PVOID Object = NULL;
2554 NTSTATUS Status, Status2;
2555 POBJECT_HEADER ObjectHeader;
2557 OB_OPEN_REASON OpenReason;
2558 POB_TEMP_BUFFER TempBuffer;
2559 PAGED_CODE();
2560
2561 /* Assume failure */
2562 *Handle = NULL;
2563
2564 /* Check if we didn't get any Object Attributes */
2565 if (!ObjectAttributes)
2566 {
2567 /* Fail with special status code */
2569 }
2570
2571 /* Allocate the temporary buffer */
2573 sizeof(OB_TEMP_BUFFER),
2575 if (!TempBuffer) return STATUS_INSUFFICIENT_RESOURCES;
2576
2577 /* Capture all the info */
2579 AccessMode,
2580 AccessMode,
2581 TRUE,
2582 &TempBuffer->ObjectCreateInfo,
2583 &ObjectName);
2584 if (!NT_SUCCESS(Status))
2585 {
2586 /* Fail */
2588 return Status;
2589 }
2590
2591 /* Check if we didn't get an access state */
2592 if (!PassedAccessState)
2593 {
2594 /* Try to get the generic mapping if we can */
2595 if (ObjectType) GenericMapping = &ObjectType->TypeInfo.GenericMapping;
2596
2597 /* Use our built-in access state */
2598 PassedAccessState = &TempBuffer->LocalAccessState;
2600 &TempBuffer->AuxData,
2603 if (!NT_SUCCESS(Status)) goto Quickie;
2604 }
2605
2606 /* Get the security descriptor */
2607 if (TempBuffer->ObjectCreateInfo.SecurityDescriptor)
2608 {
2609 /* Save it in the access state */
2612 }
2613
2614 /* Validate the access mask */
2616 if (!NT_SUCCESS(Status))
2617 {
2618 /* Cleanup after lookup */
2620 goto Cleanup;
2621 }
2622
2623 /* Now do the lookup */
2625 &ObjectName,
2626 TempBuffer->ObjectCreateInfo.Attributes,
2627 ObjectType,
2628 AccessMode,
2629 ParseContext,
2630 TempBuffer->ObjectCreateInfo.SecurityQos,
2631 NULL,
2633 &TempBuffer->LookupContext,
2634 &Object);
2635 if (!NT_SUCCESS(Status))
2636 {
2637 /* Cleanup after lookup */
2639 goto Cleanup;
2640 }
2641
2642 /* Check if this object has create information */
2643 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2644 if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO)
2645 {
2646 /* Then we are creating a new handle */
2647 OpenReason = ObCreateHandle;
2648
2649 /* Check if we still have create info */
2650 if (ObjectHeader->ObjectCreateInfo)
2651 {
2652 /* Free it */
2653 ObpFreeObjectCreateInformation(ObjectHeader->
2654 ObjectCreateInfo);
2655 ObjectHeader->ObjectCreateInfo = NULL;
2656 }
2657 }
2658 else
2659 {
2660 /* Otherwise, we are merely opening it */
2661 OpenReason = ObOpenHandle;
2662 }
2663
2664 /* Check if we have invalid object attributes */
2665 if (ObjectHeader->Type->TypeInfo.InvalidAttributes &
2666 TempBuffer->ObjectCreateInfo.Attributes)
2667 {
2668 /* Set failure code */
2670
2671 /* Cleanup after lookup */
2673
2674 /* Dereference the object */
2676 }
2677 else
2678 {
2679 /* Create the actual handle now */
2680 Status2 = ObpCreateHandle(OpenReason,
2681 Object,
2682 ObjectType,
2684 0,
2685 TempBuffer->ObjectCreateInfo.Attributes,
2686 &TempBuffer->LookupContext,
2687 AccessMode,
2688 NULL,
2689 Handle);
2690 if (!NT_SUCCESS(Status2))
2691 {
2693 Status = Status2;
2694 }
2695 }
2696
2697Cleanup:
2698 /* Delete the access state */
2699 if (PassedAccessState == &TempBuffer->LocalAccessState)
2700 {
2702 }
2703
2704Quickie:
2705 /* Release the object attributes and temporary buffer */
2709
2710 /* Return status */
2712 "%s - returning Object %p with PC S: %lx %lx\n",
2714 Object,
2715 Object ? OBJECT_TO_OBJECT_HEADER(Object)->PointerCount : -1,
2716 Status);
2717 return Status;
2718}
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
static const WCHAR Cleanup[]
Definition: register.c:80
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
NTSTATUS NTAPI ObpCaptureObjectCreateInformation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE CreatorMode, IN BOOLEAN AllocateFromLookaside, IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, OUT PUNICODE_STRING ObjectName)
Definition: oblife.c:456
#define TAG_OB_TEMP_STORAGE
Definition: ob.h:160
VOID NTAPI ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name)
Definition: oblife.c:347
FORCEINLINE VOID ObpReleaseObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:364
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: setypes.h:235
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:411
OBP_LOOKUP_CONTEXT LookupContext
Definition: ob.h:165
OBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: ob.h:164
AUX_ACCESS_DATA AuxData
Definition: ob.h:166
ACCESS_STATE LocalAccessState
Definition: ob.h:163

Referenced by CmLoadKey(), CmpLinkHiveToMaster(), CreateGreenFdo(), ExCreateCallback(), GetObjectType(), IntCreateDesktop(), IntCreateWindowStation(), IntResolveDesktop(), IoFastQueryNetworkAttributes(), IopCreateFile(), IopQueryAttributesFile(), NtCreateKey(), NtDeleteFile(), NtOpenDirectoryObject(), NtOpenEvent(), NtOpenEventPair(), NtOpenIoCompletion(), NtOpenJobObject(), NtOpenKey(), NtOpenMutant(), NtOpenProcess(), NtOpenSection(), NtOpenSemaphore(), NtOpenSymbolicLinkObject(), NtOpenThread(), NtOpenTimer(), NtQueryOpenSubKeys(), NtUnloadKey2(), NtUserOpenDesktop(), NtUserOpenWindowStation(), ObtCreateObjectTypes(), and START_TEST().

◆ ObOpenObjectByPointer()

NTSTATUS NTAPI ObOpenObjectByPointer ( IN PVOID  Object,
IN ULONG  HandleAttributes,
IN PACCESS_STATE  PassedAccessState,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_TYPE  ObjectType,
IN KPROCESSOR_MODE  AccessMode,
OUT PHANDLE  Handle 
)

Definition at line 2754 of file obhandle.c.

2761{
2765 AUX_ACCESS_DATA AuxData;
2766 PAGED_CODE();
2767
2768 /* Assume failure */
2769 *Handle = NULL;
2770
2771 /* Reference the object */
2773 0,
2774 ObjectType,
2775 AccessMode);
2776 if (!NT_SUCCESS(Status)) return Status;
2777
2778 /* Get the Header Info */
2780
2781 /* Check if we didn't get an access state */
2782 if (!PassedAccessState)
2783 {
2784 /* Use our built-in access state */
2787 &AuxData,
2789 &Header->Type->TypeInfo.GenericMapping);
2790 if (!NT_SUCCESS(Status))
2791 {
2792 /* Fail */
2794 return Status;
2795 }
2796 }
2797
2798 /* Check if we have invalid object attributes */
2799 if (Header->Type->TypeInfo.InvalidAttributes & HandleAttributes)
2800 {
2801 /* Delete the access state */
2803 {
2805 }
2806
2807 /* Dereference the object */
2810 }
2811
2812 /* Create the handle */
2814 Object,
2815 ObjectType,
2817 0,
2819 NULL,
2820 AccessMode,
2821 NULL,
2822 Handle);
2824
2825 /* Delete the access state */
2827 {
2829 }
2830
2831 /* Return */
2833 "%s - returning Object with PC S: %lx %lx\n",
2835 OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
2836 Status);
2837 return Status;
2838}
Definition: Header.h:9
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:380

Referenced by AfdBindSocket(), CheckSection_(), CmpConvertHandleToKernelHandle(), DbgkOpenProcessDebugPort(), DbgkpOpenHandles(), IntGetDesktopObjectHandle(), IntResolveDesktop(), NtOpenProcess(), NtOpenProcessTokenEx(), NtOpenThread(), RawInputThreadMain(), SepOpenThreadToken(), SerenumDetectLegacyDevice(), SerenumDetectPnpDevice(), SermouseDetectLegacyDevice(), START_TEST(), UserOpenInputDesktop(), and WmipOpenGuidObject().

◆ ObpChargeQuotaForObject()

NTSTATUS NTAPI ObpChargeQuotaForObject ( IN POBJECT_HEADER  ObjectHeader,
IN POBJECT_TYPE  ObjectType,
OUT PBOOLEAN  NewObject 
)

Definition at line 431 of file obhandle.c.

434{
435 POBJECT_HEADER_QUOTA_INFO ObjectQuota;
436 ULONG PagedPoolCharge, NonPagedPoolCharge;
437
438 /* Get quota information */
439 ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
440 *NewObject = FALSE;
441
442 /* Check if this is a new object */
443 if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO)
444 {
445 /* Remove the flag */
446 ObjectHeader->Flags &= ~ OB_FLAG_CREATE_INFO;
447 if (ObjectQuota)
448 {
449 /* We have a quota, get the charges */
450 PagedPoolCharge = ObjectQuota->PagedPoolCharge +
451 ObjectQuota->SecurityDescriptorCharge;
452 NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
453 }
454 else
455 {
456 /* Get it from the object type */
457 PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
458 NonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
459 }
460
461 /* Is this the system process? */
463 {
464 /* It is, don't do anything */
465 ObjectHeader->QuotaBlockCharged = OBP_SYSTEM_PROCESS_QUOTA;
466 }
467 else
468 {
469 /* Charge the quota */
470 ObjectHeader->QuotaBlockCharged = PsChargeSharedPoolQuota(PsGetCurrentProcess(),
471 PagedPoolCharge,
472 NonPagedPoolCharge);
473 }
474
475 /* Check if we don't have a quota block */
476 if (!ObjectHeader->QuotaBlockCharged) return STATUS_QUOTA_EXCEEDED;
477
478 /* Now set the flag */
479 *NewObject = TRUE;
480 }
481
482 /* Return success */
483 return STATUS_SUCCESS;
484}
#define OBJECT_HEADER_TO_QUOTA_INFO(h)
Definition: obtypes.h:108
#define STATUS_QUOTA_EXCEEDED
Definition: ntstatus.h:398
#define OBP_SYSTEM_PROCESS_QUOTA
Definition: ob.h:64
PEPROCESS_QUOTA_BLOCK NTAPI PsChargeSharedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T AmountToChargePaged, _In_ SIZE_T AmountToChargeNonPaged)
Charges the shared (paged and non paged) pool quotas. The function is used exclusively by the Object ...
Definition: quota.c:674

Referenced by ObInsertObject(), ObpIncrementHandleCount(), and ObpIncrementUnnamedHandleCount().

◆ ObpCloseHandle()

NTSTATUS NTAPI ObpCloseHandle ( IN HANDLE  Handle,
IN KPROCESSOR_MODE  AccessMode 
)

Definition at line 1739 of file obhandle.c.

1741{
1743 BOOLEAN AttachedToProcess = FALSE;
1745 PHANDLE_TABLE_ENTRY HandleTableEntry;
1748 PAGED_CODE();
1750 "%s - Closing handle: %p\n", __FUNCTION__, Handle);
1751
1752 if (AccessMode == KernelMode && Handle == (HANDLE)-1)
1753 return STATUS_INVALID_HANDLE;
1754
1755 /* Check if we're dealing with a kernel handle */
1757 {
1758 /* Use the kernel table and convert the handle */
1761
1762 /* Check if we're not in the system process */
1764 {
1765 /* Attach to the system process */
1767 AttachedToProcess = TRUE;
1768 }
1769 }
1770 else
1771 {
1772 /* Use the process's handle table */
1773 HandleTable = Process->ObjectTable;
1774 }
1775
1776 /* Enter a critical region to protect handle access */
1778
1779 /* Get the handle entry */
1780 HandleTableEntry = ExMapHandleToPointer(HandleTable, Handle);
1781 if (HandleTableEntry)
1782 {
1783 /* Now close the entry */
1785 HandleTableEntry,
1786 Handle,
1787 AccessMode,
1788 FALSE);
1789
1790 /* We can quit the critical region now */
1792
1793 /* Detach and return success */
1794 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1795 }
1796 else
1797 {
1798 /* We failed, quit the critical region */
1800
1801 /* Detach */
1802 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1803
1804 /* Check if we have a valid handle that's not the process or thread */
1805 if ((Handle) &&
1806 (Handle != NtCurrentProcess()) &&
1807 (Handle != NtCurrentThread()))
1808 {
1809 /* Check if we came from user mode */
1810 if (AccessMode != KernelMode)
1811 {
1812 /* Check if we have no debug port */
1813 if (Process->DebugPort)
1814 {
1815 /* Make sure we're not attached */
1816 if (!KeIsAttachedProcess())
1817 {
1818 /* Raise an exception */
1820 }
1821 }
1822 }
1823 else
1824 {
1825 /* This is kernel mode. Check if we're exiting */
1827 (Process->Peb))
1828 {
1829 /* Check if the debugger is enabled */
1831 {
1832 /* Bugcheck */
1833 KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 1, 0, 0);
1834 }
1835 }
1836 }
1837 }
1838
1839 /* Set invalid status */
1841 }
1842
1843 /* Return status */
1845 "%s - Closed handle: %p S: %lx\n",
1847 return Status;
1848}
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:82
#define NtCurrentProcess()
Definition: nt_native.h:1660
PHANDLE_TABLE_ENTRY NTAPI ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle)
Definition: handle.c:1046
NTSTATUS NTAPI KeRaiseUserException(IN NTSTATUS ExceptionCode)
Definition: except.c:413
BOOLEAN NTAPI PsIsThreadTerminating(IN PETHREAD Thread)
Definition: thread.c:868
#define ObKernelHandleToHandle(Handle)
Definition: ob.h:83
NTSTATUS NTAPI ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleEntry, IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN IgnoreHandleProtection)
Definition: obhandle.c:685
PHANDLE_TABLE ObpKernelHandleTable
Definition: obhandle.c:20
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
KPROCESS Pcb
Definition: pstypes.h:1369
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define NtCurrentThread()
Definition: winternl.h:5372

Referenced by NtClose(), and ObCloseHandle().

◆ ObpCloseHandleCallback()

BOOLEAN NTAPI ObpCloseHandleCallback ( IN PHANDLE_TABLE_ENTRY  HandleTableEntry,
IN HANDLE  Handle,
IN PVOID  Context 
)

Definition at line 1936 of file obhandle.c.

1939{
1941
1942 /* Simply decrement the handle count */
1944 HandleTableEntry,
1945 Handle,
1946 CloseContext->AccessMode,
1947 TRUE);
1948 return TRUE;
1949}
struct _OBP_CLOSE_HANDLE_CONTEXT * POBP_CLOSE_HANDLE_CONTEXT
PHANDLE_TABLE HandleTable
Definition: ob.h:117
KPROCESSOR_MODE AccessMode
Definition: ob.h:118

Referenced by ObClearProcessHandleTable(), and ObKillProcess().

◆ ObpCloseHandleTableEntry()

NTSTATUS NTAPI ObpCloseHandleTableEntry ( IN PHANDLE_TABLE  HandleTable,
IN PHANDLE_TABLE_ENTRY  HandleEntry,
IN HANDLE  Handle,
IN KPROCESSOR_MODE  AccessMode,
IN BOOLEAN  IgnoreHandleProtection 
)

Definition at line 685 of file obhandle.c.

690{
691 PVOID Body;
693 POBJECT_HEADER ObjectHeader;
695 KIRQL CalloutIrql;
696 PAGED_CODE();
697
698 /* Get the object data */
699 ObjectHeader = ObpGetHandleObject(HandleEntry);
700 ObjectType = ObjectHeader->Type;
701 Body = &ObjectHeader->Body;
702 GrantedAccess = HandleEntry->GrantedAccess;
704 "%s - Closing handle: %p for %p. HC PC %lx %lx\n",
706 Handle,
707 Body,
708 ObjectHeader->HandleCount,
709 ObjectHeader->PointerCount);
710
711 /* Check if the object has an Okay To Close procedure */
712 if (ObjectType->TypeInfo.OkayToCloseProcedure)
713 {
714 /* Call it and check if it's not letting us close it */
715 ObpCalloutStart(&CalloutIrql);
716 if (!ObjectType->TypeInfo.OkayToCloseProcedure(PsGetCurrentProcess(),
717 Body,
718 Handle,
719 AccessMode))
720 {
721 /* Fail */
722 ObpCalloutEnd(CalloutIrql, "NtClose", ObjectType, Body);
725 }
726
727 /* Success, validate callout return */
728 ObpCalloutEnd(CalloutIrql, "NtClose", ObjectType, Body);
729 }
730
731 /* The callback allowed us to close it, but does the handle itself? */
732 if ((HandleEntry->GrantedAccess & ObpAccessProtectCloseBit) &&
733 !(IgnoreHandleProtection))
734 {
735 /* It doesn't, are we from user mode? */
736 if (AccessMode != KernelMode)
737 {
738 /* We are! Unlock the entry */
740
741 /* Make sure we have a debug port */
742 if (PsGetCurrentProcess()->DebugPort)
743 {
744 /* Raise an exception */
746 }
747 else
748 {
749 /* Return the error instead */
751 }
752 }
753 else
754 {
755 /* Otherwise, bugcheck the OS */
756 KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 0, 0, 0);
757 }
758 }
759
760 /* Destroy and unlock the handle entry */
761 ExDestroyHandle(HandleTable, Handle, HandleEntry);
762
763 /* Now decrement the handle count */
767 ObjectType);
768
769 /* Dereference the object as well */
771
772 /* Return to caller */
774 "%s - Closed handle: %p for %p.\n",
776 Handle,
777 Body);
778 return STATUS_SUCCESS;
779}
UCHAR KIRQL
Definition: env_spec_w32.h:591
BOOLEAN NTAPI ExDestroyHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL)
Definition: handle.c:984
VOID NTAPI ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:923
#define STATUS_HANDLE_NOT_CLOSABLE
Definition: ntstatus.h:819
#define ObpGetHandleObject(x)
Definition: ob.h:91
FORCEINLINE VOID ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:497
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:505
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20

Referenced by ObpCloseHandle(), and ObpCloseHandleCallback().

◆ ObpCreateHandle()

NTSTATUS NTAPI ObpCreateHandle ( IN OB_OPEN_REASON  OpenReason,
IN PVOID  Object,
IN POBJECT_TYPE Type  OPTIONAL,
IN PACCESS_STATE  AccessState,
IN ULONG  AdditionalReferences,
IN ULONG  HandleAttributes,
IN POBP_LOOKUP_CONTEXT  Context,
IN KPROCESSOR_MODE  AccessMode,
OUT PVOID ReturnedObject,
OUT PHANDLE  ReturnedHandle 
)

Definition at line 1506 of file obhandle.c.

1516{
1517 HANDLE_TABLE_ENTRY NewEntry;
1518 POBJECT_HEADER ObjectHeader;
1519 HANDLE Handle;
1521 BOOLEAN AttachedToProcess = FALSE, KernelHandle = FALSE;
1526 PAUX_ACCESS_DATA AuxData;
1527 PAGED_CODE();
1528
1529 /* Get the object header and type */
1530 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1531 ObjectType = ObjectHeader->Type;
1533 "%s - Creating handle for: %p. Reason: %lx. HC PC %lx %lx\n",
1535 Object,
1536 OpenReason,
1537 ObjectHeader->HandleCount,
1538 ObjectHeader->PointerCount);
1539
1540 /* Check if the types match */
1541 if ((Type) && (ObjectType != Type))
1542 {
1543 /* They don't, cleanup */
1546 }
1547
1548 /* Save the object header */
1549 NewEntry.Object = ObjectHeader;
1550
1551 /* Check if this is a kernel handle */
1553 {
1554 /* Set the handle table */
1557
1558 /* Check if we're not in the system process */
1560 {
1561 /* Attach to the system process */
1563 AttachedToProcess = TRUE;
1564 }
1565 }
1566 else
1567 {
1568 /* Get the current handle table */
1569 HandleTable = PsGetCurrentProcess()->ObjectTable;
1570 }
1571
1572 /* Increment the handle count */
1575 AccessMode,
1578 OpenReason);
1579 if (!NT_SUCCESS(Status))
1580 {
1581 /*
1582 * We failed (meaning security failure, according to NT Internals)
1583 * detach and return
1584 */
1586 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1587 return Status;
1588 }
1589
1590 /* Check if we are doing audits on close */
1591 if (AccessState->GenerateOnClose)
1592 {
1593 /* Force the attribute on */
1595 }
1596
1597 /* Mask out the internal attributes */
1599
1600 /* Get the original desired access */
1601 DesiredAccess = AccessState->RemainingDesiredAccess |
1602 AccessState->PreviouslyGrantedAccess;
1603
1604 /* Remove what's not in the valid access mask */
1605 GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
1607
1608 /* Update the value in the access state */
1609 AccessState->PreviouslyGrantedAccess = GrantedAccess;
1610
1611 /* Get the auxiliary data */
1612 AuxData = AccessState->AuxData;
1613
1614 /* Handle extra references */
1615 if (AdditionalReferences)
1616 {
1617 /* Add them to the header */
1619 AdditionalReferences);
1620 }
1621
1622 /* Now we can release the object */
1624
1625 /* Save the access mask */
1626 NewEntry.GrantedAccess = GrantedAccess;
1627
1628 /*
1629 * Create the actual handle. We'll need to do this *after* calling
1630 * ObpIncrementHandleCount to make sure that Object Security is valid
1631 * (specified in Gl00my documentation on Ob)
1632 */
1634 "%s - Handle Properties: [%p-%lx-%lx]\n",
1636 NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
1637 Handle = ExCreateHandle(HandleTable, &NewEntry);
1638
1639 /* Make sure we got a handle */
1640 if (Handle)
1641 {
1642 /* Check if this was a kernel handle */
1644
1645 /* Return it */
1646 *ReturnedHandle = Handle;
1647
1648 /* Check if we need to generate on audit */
1649 if (AccessState->GenerateAudit)
1650 {
1651 /* Audit the handle creation */
1652 //SeAuditHandleCreation(AccessState, Handle);
1653 }
1654
1655 /* Check if this was a create */
1656 if (OpenReason == ObCreateHandle)
1657 {
1658 /* Check if we need to audit the privileges */
1659 if ((AuxData->PrivilegesUsed) &&
1660 (AuxData->PrivilegesUsed->PrivilegeCount))
1661 {
1662 /* Do the audit */
1663#if 0
1665 &AccessState->
1668 AuxData->PrivilegesUsed,
1669 TRUE,
1671#endif
1672 }
1673 }
1674
1675 /* Return the new object only if caller wanted it biased */
1676 if ((AdditionalReferences) && (ReturnedObject))
1677 {
1678 /* Return it */
1679 *ReturnedObject = Object;
1680 }
1681
1682 /* Detach if needed */
1683 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1684
1685 /* Trace and return */
1687 "%s - Returning Handle: %p HC PC %lx %lx\n",
1689 Handle,
1690 ObjectHeader->HandleCount,
1691 ObjectHeader->PointerCount);
1692 return STATUS_SUCCESS;
1693 }
1694
1695 /* Decrement the handle count and detach */
1696 ObpDecrementHandleCount(&ObjectHeader->Body,
1699 ObjectType);
1700
1701 /* Handle extra references */
1702 if (AdditionalReferences)
1703 {
1704 /* Check how many extra references were added */
1705 if (AdditionalReferences > 1)
1706 {
1707 /* Dereference it many times */
1709 -(LONG)(AdditionalReferences - 1));
1710 }
1711
1712 /* Dereference the object one last time */
1714 }
1715
1716 /* Detach if necessary and fail */
1717 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1719}
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:211
VOID NTAPI SePrivilegeObjectAuditAlarm(_In_ HANDLE Handle, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ ACCESS_MASK DesiredAccess, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted, _In_ KPROCESSOR_MODE CurrentMode)
Raises an audit with alarm notification message when an object tries to acquire this privilege.
Definition: audit.c:1321
long LONG
Definition: pedump.c:60
PPRIVILEGE_SET PrivilegesUsed
Definition: setypes.h:258
$ULONG PrivilegeCount
Definition: setypes.h:86
_In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: sefuncs.h:13

Referenced by ObInsertObject(), ObOpenObjectByName(), and ObOpenObjectByPointer().

◆ ObpCreateUnnamedHandle()

NTSTATUS NTAPI ObpCreateUnnamedHandle ( IN PVOID  Object,
IN ACCESS_MASK  DesiredAccess,
IN ULONG  AdditionalReferences,
IN ULONG  HandleAttributes,
IN KPROCESSOR_MODE  AccessMode,
OUT PVOID ReturnedObject,
OUT PHANDLE  ReturnedHandle 
)

Definition at line 1321 of file obhandle.c.

1328{
1329 HANDLE_TABLE_ENTRY NewEntry;
1330 POBJECT_HEADER ObjectHeader;
1331 HANDLE Handle;
1333 BOOLEAN AttachedToProcess = FALSE, KernelHandle = FALSE;
1338 PAGED_CODE();
1339
1340 /* Get the object header and type */
1341 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1342 ObjectType = ObjectHeader->Type;
1344 "%s - Creating handle for: %p. UNNAMED. HC PC %lx %lx\n",
1346 Object,
1347 ObjectHeader->HandleCount,
1348 ObjectHeader->PointerCount);
1349
1350 /* Save the object header */
1351 NewEntry.Object = ObjectHeader;
1352
1353 /* Mask out the internal attributes */
1355
1356 /* Check if this is a kernel handle */
1358 {
1359 /* Set the handle table */
1362
1363 /* Check if we're not in the system process */
1365 {
1366 /* Attach to the system process */
1368 AttachedToProcess = TRUE;
1369 }
1370 }
1371 else
1372 {
1373 /* Get the current handle table */
1374 HandleTable = PsGetCurrentProcess()->ObjectTable;
1375 }
1376
1377 /* Increment the handle count */
1380 AccessMode,
1383 if (!NT_SUCCESS(Status))
1384 {
1385 /*
1386 * We failed (meaning security failure, according to NT Internals)
1387 * detach and return
1388 */
1389 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1390 return Status;
1391 }
1392
1393 /* Remove what's not in the valid access mask */
1394 GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
1396
1397 /* Handle extra references */
1398 if (AdditionalReferences)
1399 {
1400 /* Add them to the header */
1402 AdditionalReferences);
1403 }
1404
1405 /* Save the access mask */
1406 NewEntry.GrantedAccess = GrantedAccess;
1407
1408 /*
1409 * Create the actual handle. We'll need to do this *after* calling
1410 * ObpIncrementHandleCount to make sure that Object Security is valid
1411 * (specified in Gl00my documentation on Ob)
1412 */
1414 "%s - Handle Properties: [%p-%lx-%lx]\n",
1416 NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
1417 Handle = ExCreateHandle(HandleTable, &NewEntry);
1418
1419 /* Make sure we got a handle */
1420 if (Handle)
1421 {
1422 /* Check if this was a kernel handle */
1424
1425 /* Return handle and object */
1426 *ReturnedHandle = Handle;
1427
1428 /* Return the new object only if caller wanted it biased */
1429 if ((AdditionalReferences) && (ReturnedObject))
1430 {
1431 /* Return it */
1432 *ReturnedObject = Object;
1433 }
1434
1435 /* Detach if needed */
1436 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1437
1438 /* Trace and return */
1440 "%s - Returning Handle: %p HC PC %lx %lx\n",
1442 Handle,
1443 ObjectHeader->HandleCount,
1444 ObjectHeader->PointerCount);
1445 return STATUS_SUCCESS;
1446 }
1447
1448 /* Handle extra references */
1449 if (AdditionalReferences)
1450 {
1451 /* Dereference it as many times as required */
1453 -(LONG)AdditionalReferences);
1454 }
1455
1456 /* Decrement the handle count and detach */
1457 ObpDecrementHandleCount(&ObjectHeader->Body,
1460 ObjectType);
1461
1462 /* Detach and fail */
1463 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1465}
NTSTATUS NTAPI ObpIncrementUnnamedHandleCount(IN PVOID Object, IN PACCESS_MASK DesiredAccess, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process)
Definition: obhandle.c:1098

Referenced by ObInsertObject().

◆ ObpDecrementHandleCount()

VOID NTAPI ObpDecrementHandleCount ( IN PVOID  ObjectBody,
IN PEPROCESS  Process,
IN ACCESS_MASK  GrantedAccess,
IN POBJECT_TYPE  ObjectType 
)

Definition at line 530 of file obhandle.c.

534{
535 POBJECT_HEADER ObjectHeader;
536 LONG SystemHandleCount, ProcessHandleCount;
537 LONG NewCount;
538 KIRQL CalloutIrql;
540 POBJECT_HANDLE_COUNT_ENTRY HandleEntry;
541 POBJECT_HANDLE_COUNT_DATABASE HandleDatabase;
542 ULONG i;
543 PAGED_CODE();
544
545 /* Get the object type and header */
546 ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
548 "%s - Decrementing count for: %p. HC PC %lx %lx\n",
550 ObjectBody,
551 ObjectHeader->HandleCount,
552 ObjectHeader->PointerCount);
553
554 /* Lock the object */
555 ObpAcquireObjectLock(ObjectHeader);
556
557 /* Set default counts */
558 SystemHandleCount = ObjectHeader->HandleCount;
560
561 /* Decrement the handle count */
562 NewCount = InterlockedDecrementSizeT(&ObjectHeader->HandleCount);
563
564 /* Check if we're out of handles and this was an exclusive object */
565 if (!(NewCount) && (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
566 {
567 /* Clear the exclusive flag */
568 OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = NULL;
569 }
570
571 /* Is the object type keeping track of handles? */
572 if (ObjectType->TypeInfo.MaintainHandleCount)
573 {
574 /* Get handle information */
575 HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
576
577 /* Check if there's only a single entry */
578 if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
579 {
580 /* It should be us */
581 ASSERT(HandleInfo->SingleEntry.Process == Process);
582 ASSERT(HandleInfo->SingleEntry.HandleCount > 0);
583
584 /* Get the handle counts */
586 HandleEntry = &HandleInfo->SingleEntry;
587 }
588 else
589 {
590 /* Otherwise, get the database */
591 HandleDatabase = HandleInfo->HandleCountDatabase;
592 if (HandleDatabase)
593 {
594 /* Get the entries and loop them */
595 i = HandleDatabase->CountEntries;
596 HandleEntry = &HandleDatabase->HandleCountEntries[0];
597 while (i)
598 {
599 /* Check if this is a match */
600 if ((HandleEntry->HandleCount) &&
601 (HandleEntry->Process == Process))
602 {
603 /* Found it, get the process handle count */
604 ProcessHandleCount = HandleEntry->HandleCount--;
605 break;
606 }
607
608 /* Keep looping */
609 HandleEntry++;
610 i--;
611 }
612 }
613 else
614 {
615 /* No database, so no entry */
616 HandleEntry = NULL;
617 }
618 }
619
620 /* Check if this is the last handle */
621 if (ProcessHandleCount == 1)
622 {
623 /* Then clear the entry */
624 HandleEntry->Process = NULL;
625 HandleEntry->HandleCount = 0;
626 }
627 }
628
629 /* Release the lock */
630 ObpReleaseObjectLock(ObjectHeader);
631
632 /* Check if we have a close procedure */
633 if (ObjectType->TypeInfo.CloseProcedure)
634 {
635 /* Call it */
636 ObpCalloutStart(&CalloutIrql);
637 ObjectType->TypeInfo.CloseProcedure(Process,
638 ObjectBody,
641 SystemHandleCount);
642 ObpCalloutEnd(CalloutIrql, "Close", ObjectType, ObjectBody);
643 }
644
645 /* Check if we should delete the object */
646 ObpDeleteNameCheck(ObjectBody);
647
648 /* Decrease the total number of handles for this type */
649 InterlockedDecrement((PLONG)&ObjectType->TotalNumberOfHandles);
651 "%s - Decremented count for: %p. HC PC %lx %lx\n",
653 ObjectBody,
654 ObjectHeader->HandleCount,
655 ObjectHeader->PointerCount);
656}
#define InterlockedDecrement
Definition: armddk.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define InterlockedDecrementSizeT(a)
Definition: interlocked.h:168
#define OBJECT_HEADER_TO_HANDLE_INFO(h)
Definition: obtypes.h:104
#define OB_FLAG_SINGLE_PROCESS
Definition: obtypes.h:89
#define OB_FLAG_EXCLUSIVE
Definition: obtypes.h:86
OBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1]
Definition: obtypes.h:472
Definition: obtypes.h:464
ULONG HandleCount
Definition: obtypes.h:466
struct _EPROCESS * Process
Definition: obtypes.h:465
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase
Definition: obtypes.h:479
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:480
int32_t * PLONG
Definition: typedefs.h:58
@ ProcessHandleCount
Definition: winternl.h:1902

Referenced by ObDuplicateObject(), ObpCloseHandleTableEntry(), ObpCreateHandle(), and ObpCreateUnnamedHandle().

◆ ObpDuplicateHandleCallback()

BOOLEAN NTAPI ObpDuplicateHandleCallback ( IN PEPROCESS  Process,
IN PHANDLE_TABLE  HandleTable,
IN PHANDLE_TABLE_ENTRY  OldEntry,
IN PHANDLE_TABLE_ENTRY  HandleTableEntry 
)

Definition at line 1972 of file obhandle.c.

1976{
1977 POBJECT_HEADER ObjectHeader;
1978 BOOLEAN Ret = FALSE;
1981 PAGED_CODE();
1982
1983 /* Make sure that the handle is inheritable */
1984 Ret = (HandleTableEntry->ObAttributes & OBJ_INHERIT) != 0;
1985 if (Ret)
1986 {
1987 /* Get the object header */
1988 ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1989
1990 /* Increment the pointer count */
1992
1993 /* Release the handle lock */
1995
1996 /* Setup the access state */
1997 AccessState.PreviouslyGrantedAccess = HandleTableEntry->GrantedAccess;
1998
1999 /* Call the shared routine for incrementing handles */
2000 Status = ObpIncrementHandleCount(&ObjectHeader->Body,
2001 &AccessState,
2002 KernelMode,
2003 HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES,
2004 Process,
2006 if (!NT_SUCCESS(Status))
2007 {
2008 /* Return failure */
2009 ObDereferenceObject(&ObjectHeader->Body);
2010 Ret = FALSE;
2011 }
2012 }
2013 else
2014 {
2015 /* Release the handle lock */
2017 }
2018
2019 /* Return duplication result */
2020 return Ret;
2021}
#define InterlockedIncrementSizeT(a)
Definition: interlocked.h:235
@ ObInheritHandle
Definition: obtypes.h:164

Referenced by ObInitProcess().

◆ ObpEnumFindHandleProcedure()

BOOLEAN NTAPI ObpEnumFindHandleProcedure ( IN PHANDLE_TABLE_ENTRY  HandleEntry,
IN HANDLE  Handle,
IN PVOID  Context 
)

Definition at line 211 of file obhandle.c.

214{
215 POBJECT_HEADER ObjectHeader;
219
220 /* Get the object header */
221 ObjectHeader = ObpGetHandleObject(HandleEntry);
222
223 /* Make sure it's valid and matching */
224 if ((FindData->ObjectHeader) && (FindData->ObjectHeader != ObjectHeader))
225 {
226 /* No match, fail */
227 return FALSE;
228 }
229
230 /* Now attempt to match the object type */
231 if ((FindData->ObjectType) && (FindData->ObjectType != ObjectHeader->Type))
232 {
233 /* No match, fail */
234 return FALSE;
235 }
236
237 /* Check if we have extra information */
238 if (FindData->HandleInformation)
239 {
240 /* Get the granted access and attributes */
241 GrantedAccess = HandleEntry->GrantedAccess;
242 HandleAttributes = HandleEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
243
244 /* Attempt to match them */
247 {
248 /* No match, fail */
249 return FALSE;
250 }
251 }
252
253 /* We have a match */
254 return TRUE;
255}
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181

Referenced by ObFindHandleForObject().

◆ ObpIncrementHandleCount()

NTSTATUS NTAPI ObpIncrementHandleCount ( IN PVOID  Object,
IN PACCESS_STATE AccessState  OPTIONAL,
IN KPROCESSOR_MODE  AccessMode,
IN ULONG  HandleAttributes,
IN PEPROCESS  Process,
IN OB_OPEN_REASON  OpenReason 
)

Definition at line 811 of file obhandle.c.

817{
818 POBJECT_HEADER ObjectHeader;
822 PEPROCESS ExclusiveProcess;
824 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
825 KIRQL CalloutIrql;
827 ULONG Total;
829 PAGED_CODE();
830
831 /* Get the object header and type */
832 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
833 ObjectType = ObjectHeader->Type;
835 "%s - Incrementing count for: %p. Reason: %lx. HC PC %lx %lx\n",
837 Object,
838 OpenReason,
839 ObjectHeader->HandleCount,
840 ObjectHeader->PointerCount);
841
842 /* Check if caller is forcing user mode */
844 {
845 /* Force it */
847 }
848 else
849 {
850 /* Keep original setting */
852 }
853
854 /* Lock the object */
855 ObpAcquireObjectLock(ObjectHeader);
856
857 /* Charge quota and remove the creator info flag */
859 if (!NT_SUCCESS(Status)) return Status;
860
861 /* Check if the open is exclusive */
863 {
864 /* Check if the object allows this, or if the inherit flag was given */
866 !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
867 {
868 /* Incorrect attempt */
870 goto Quickie;
871 }
872
873 /* Check if we have access to it */
874 ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader);
875 if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) ||
876 ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess())))
877 {
878 /* This isn't the right process */
880 goto Quickie;
881 }
882
883 /* Now you got exclusive access */
884 Exclusive = TRUE;
885 }
886 else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) &&
888 {
889 /* Caller didn't want exclusive access, but the object is exclusive */
891 goto Quickie;
892 }
893
894 /* Check for exclusive kernel object */
895 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
896 if ((NameInfo) && (NameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE) &&
898 {
899 /* Caller is not kernel, but the object is kernel exclusive */
901 goto Quickie;
902 }
903
904 /*
905 * Check if this is an object that went from 0 handles back to existence,
906 * but doesn't have an open procedure, only a close procedure. This means
907 * that it will never realize that the object is back alive, so we must
908 * fail the request.
909 */
910 if (!(ObjectHeader->HandleCount) &&
911 !(NewObject) &&
912 (ObjectType->TypeInfo.MaintainHandleCount) &&
913 !(ObjectType->TypeInfo.OpenProcedure) &&
914 (ObjectType->TypeInfo.CloseProcedure))
915 {
916 /* Fail */
918 goto Quickie;
919 }
920
921 /* Check if we're opening an existing handle */
922 if ((OpenReason == ObOpenHandle) ||
923 ((OpenReason == ObDuplicateHandle) && (AccessState)))
924 {
925 /* Validate the caller's access to this object */
928 TRUE,
929 ProbeMode,
930 &Status))
931 {
932 /* Access was denied, so fail */
933 goto Quickie;
934 }
935 }
936 else if (OpenReason == ObCreateHandle)
937 {
938 /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */
939 if (AccessState->RemainingDesiredAccess & MAXIMUM_ALLOWED)
940 {
941 /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */
942 AccessState->RemainingDesiredAccess &= ~MAXIMUM_ALLOWED;
943 AccessState->RemainingDesiredAccess |= GENERIC_ALL;
944 }
945
946 /* Check if we have to map the GENERIC mask */
947 if (AccessState->RemainingDesiredAccess & GENERIC_ACCESS)
948 {
949 /* Map it to the correct access masks */
950 RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
951 &ObjectType->TypeInfo.GenericMapping);
952 }
953
954 /* Check if the caller is trying to access system security */
955 if (AccessState->RemainingDesiredAccess & ACCESS_SYSTEM_SECURITY)
956 {
957 /* Client must be warranted SeSecurityPrivilege to touch SACLs */
959 {
960 /* FIXME: Generate an audit alarm, security manager must be alerted */
962 goto Quickie;
963 }
964
965 /* Privilege held, grant it so the access state reflects reality */
966 AccessState->PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
967 AccessState->RemainingDesiredAccess &= ~ACCESS_SYSTEM_SECURITY;
968 }
969 }
970
971 /* Check if this is an exclusive handle */
972 if (Exclusive)
973 {
974 /* Save the owner process */
975 OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
976 }
977
978 /* Increase the handle count */
981
982 /* Check if we have a handle database */
983 if (ObjectType->TypeInfo.MaintainHandleCount)
984 {
985 /* Increment the handle database */
986 Status = ObpIncrementHandleDataBase(ObjectHeader,
987 Process,
989 if (!NT_SUCCESS(Status))
990 {
991 /* FIXME: This should never happen for now */
992 DPRINT1("Unhandled case\n");
993 ASSERT(FALSE);
994 goto Quickie;
995 }
996 }
997
998 /* Release the lock */
999 ObpReleaseObjectLock(ObjectHeader);
1000
1001 /* Check if we have an open procedure */
1003 if (ObjectType->TypeInfo.OpenProcedure)
1004 {
1005 /* Call it */
1006 ObpCalloutStart(&CalloutIrql);
1007 ACCESS_MASK GrantedAccess = AccessState ? AccessState->PreviouslyGrantedAccess : 0;
1008 Status = ObjectType->TypeInfo.OpenProcedure(OpenReason,
1009 ProbeMode,
1010 Process,
1011 Object,
1014 ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
1015
1016 /* Check if the open procedure failed */
1017 if (!NT_SUCCESS(Status))
1018 {
1019 /* FIXME: This should never happen for now */
1020 DPRINT1("Unhandled case\n");
1021 ASSERT(FALSE);
1022 return Status;
1023 }
1024 }
1025
1026 /* Check if this is a create operation */
1027 if (OpenReason == ObCreateHandle)
1028 {
1029 /* Check if we have creator info */
1030 CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
1031 if (CreatorInfo)
1032 {
1033 /* We do, acquire the lock */
1035
1036 /* Insert us on the list */
1037 InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
1038
1039 /* Release the lock */
1041 }
1042 }
1043
1044 /* Increase total number of handles */
1045 Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
1046 if (Total > ObjectType->HighWaterNumberOfHandles)
1047 {
1048 /* Fixup count */
1049 ObjectType->HighWaterNumberOfHandles = Total;
1050 }
1051
1052 /* Trace call and return */
1054 "%s - Incremented count for: %p. Reason: %lx HC PC %lx %lx\n",
1056 Object,
1057 OpenReason,
1058 ObjectHeader->HandleCount,
1059 ObjectHeader->PointerCount);
1060 return Status;
1061
1062Quickie:
1063 /* Release lock and return */
1064 ObpReleaseObjectLock(ObjectHeader);
1065 return Status;
1066}
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define InterlockedIncrement
Definition: armddk.h:53
#define InsertTailList(ListHead, Entry)
__in PWDFDEVICE_INIT __in BOOLEAN Exclusive
#define OB_FLAG_KERNEL_EXCLUSIVE
Definition: obtypes.h:95
#define OBJECT_HEADER_TO_CREATOR_INFO(h)
Definition: obtypes.h:112
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:100
#define OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(h)
Definition: obtypes.h:117
#define GENERIC_ALL
Definition: nt_native.h:92
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
const LUID SeSecurityPrivilege
Definition: priv.c:27
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
BOOLEAN NTAPI ObCheckObjectAccess(IN PVOID Object, IN OUT PACCESS_STATE AccessState, IN BOOLEAN LockHeld, IN KPROCESSOR_MODE AccessMode, OUT PNTSTATUS ReturnedStatus)
Definition: obsecure.c:441
FORCEINLINE VOID ObpLeaveObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:352
FORCEINLINE VOID ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:340
NTSTATUS NTAPI ObpIncrementHandleDataBase(IN POBJECT_HEADER ObjectHeader, IN PEPROCESS Process, IN OUT PULONG NewProcessHandleCount)
Definition: obhandle.c:333
#define OBJ_FORCE_ACCESS_CHECK
Definition: winternl.h:232
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ _In_ ULONG ProbeMode
Definition: mmfuncs.h:561

Referenced by ObDuplicateObject(), ObpCreateHandle(), and ObpDuplicateHandleCallback().

◆ ObpIncrementHandleDataBase()

NTSTATUS NTAPI ObpIncrementHandleDataBase ( IN POBJECT_HEADER  ObjectHeader,
IN PEPROCESS  Process,
IN OUT PULONG  NewProcessHandleCount 
)

Definition at line 333 of file obhandle.c.

336{
338 POBJECT_HANDLE_COUNT_ENTRY HandleEntry, FreeEntry = NULL;
339 POBJECT_HANDLE_COUNT_DATABASE HandleDatabase;
340 ULONG i;
341 PAGED_CODE();
342
343 /* Get the handle info and check if we only have one entry */
344 HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
345 if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
346 {
347 /* Check if the entry is free */
348 if (!HandleInfo->SingleEntry.HandleCount)
349 {
350 /* Add ours */
351 HandleInfo->SingleEntry.HandleCount = 1;
352 HandleInfo->SingleEntry.Process = Process;
353
354 /* Return success and 1 handle */
355 *NewProcessHandleCount = 1;
356 return STATUS_SUCCESS;
357 }
358 else if (HandleInfo->SingleEntry.Process == Process)
359 {
360 /* Busy entry, but same process */
361 *NewProcessHandleCount = ++HandleInfo->SingleEntry.HandleCount;
362 return STATUS_SUCCESS;
363 }
364 else
365 {
366 /* Insert a new entry */
367 FreeEntry = ObpInsertHandleCount(ObjectHeader);
368 if (!FreeEntry) return STATUS_INSUFFICIENT_RESOURCES;
369 ASSERT(!FreeEntry->Process);
370 ASSERT(!FreeEntry->HandleCount);
371
372 /* Fill it out */
373 FreeEntry->Process = Process;
374 FreeEntry->HandleCount = 1;
375
376 /* Return success and 1 handle */
377 *NewProcessHandleCount = 1;
378 return STATUS_SUCCESS;
379 }
380 }
381
382 /* We have a database instead */
383 HandleDatabase = HandleInfo->HandleCountDatabase;
384 if (HandleDatabase)
385 {
386 /* Get the entries and loop them */
387 i = HandleDatabase->CountEntries;
388 HandleEntry = &HandleDatabase->HandleCountEntries[0];
389 while (i)
390 {
391 /* Check if this is a match */
392 if (HandleEntry->Process == Process)
393 {
394 /* Found it, get the process handle count */
395 *NewProcessHandleCount = ++HandleEntry->HandleCount;
396 return STATUS_SUCCESS;
397 }
398 else if (!HandleEntry->HandleCount)
399 {
400 /* Found a free entry */
401 FreeEntry = HandleEntry;
402 }
403
404 /* Keep looping */
405 HandleEntry++;
406 i--;
407 }
408
409 /* Check if we couldn't find a free entry */
410 if (!FreeEntry)
411 {
412 /* Allocate one */
413 FreeEntry = ObpInsertHandleCount(ObjectHeader);
414 if (!FreeEntry) return STATUS_INSUFFICIENT_RESOURCES;
415 ASSERT(!FreeEntry->Process);
416 ASSERT(!FreeEntry->HandleCount);
417 }
418
419 /* Fill out the entry */
420 FreeEntry->Process = Process;
421 FreeEntry->HandleCount = 1;
422 *NewProcessHandleCount = 1;
423 }
424
425 /* Return success if we got here */
426 return STATUS_SUCCESS;
427}
POBJECT_HANDLE_COUNT_ENTRY NTAPI ObpInsertHandleCount(IN POBJECT_HEADER ObjectHeader)
Definition: obhandle.c:259

Referenced by ObpIncrementHandleCount(), and ObpIncrementUnnamedHandleCount().

◆ ObpIncrementUnnamedHandleCount()

NTSTATUS NTAPI ObpIncrementUnnamedHandleCount ( IN PVOID  Object,
IN PACCESS_MASK  DesiredAccess,
IN KPROCESSOR_MODE  AccessMode,
IN ULONG  HandleAttributes,
IN PEPROCESS  Process 
)

Definition at line 1098 of file obhandle.c.

1103{
1104 POBJECT_HEADER ObjectHeader;
1108 PEPROCESS ExclusiveProcess;
1110 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1111 KIRQL CalloutIrql;
1112 ULONG Total;
1113
1114 /* Get the object header and type */
1115 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1116 ObjectType = ObjectHeader->Type;
1118 "%s - Incrementing count for: %p. UNNAMED. HC PC %lx %lx\n",
1120 Object,
1121 ObjectHeader->HandleCount,
1122 ObjectHeader->PointerCount);
1123
1124 /* Lock the object */
1125 ObpAcquireObjectLock(ObjectHeader);
1126
1127 /* Charge quota and remove the creator info flag */
1129 if (!NT_SUCCESS(Status)) return Status;
1130
1131 /* Check if the open is exclusive */
1133 {
1134 /* Check if the object allows this, or if the inherit flag was given */
1135 if ((HandleAttributes & OBJ_INHERIT) ||
1136 !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
1137 {
1138 /* Incorrect attempt */
1140 goto Quickie;
1141 }
1142
1143 /* Check if we have access to it */
1144 ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader);
1145 if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) ||
1146 ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess())))
1147 {
1148 /* This isn't the right process */
1150 goto Quickie;
1151 }
1152
1153 /* Now you got exclusive access */
1154 Exclusive = TRUE;
1155 }
1156 else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) &&
1157 (OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader)))
1158 {
1159 /* Caller didn't want exclusive access, but the object is exclusive */
1161 goto Quickie;
1162 }
1163
1164 /*
1165 * Check if this is an object that went from 0 handles back to existence,
1166 * but doesn't have an open procedure, only a close procedure. This means
1167 * that it will never realize that the object is back alive, so we must
1168 * fail the request.
1169 */
1170 if (!(ObjectHeader->HandleCount) &&
1171 !(NewObject) &&
1172 (ObjectType->TypeInfo.MaintainHandleCount) &&
1173 !(ObjectType->TypeInfo.OpenProcedure) &&
1174 (ObjectType->TypeInfo.CloseProcedure))
1175 {
1176 /* Fail */
1178 goto Quickie;
1179 }
1180
1181 /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */
1183 {
1184 /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */
1185 *DesiredAccess &= ~MAXIMUM_ALLOWED;
1187 }
1188
1189 /* Check if we have to map the GENERIC mask */
1191 {
1192 /* Map it to the correct access masks */
1194 &ObjectType->TypeInfo.GenericMapping);
1195 }
1196
1197 /* Check if this is an exclusive handle */
1198 if (Exclusive)
1199 {
1200 /* Save the owner process */
1201 OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
1202 }
1203
1204 /* Increase the handle count */
1205 InterlockedIncrementSizeT(&ObjectHeader->HandleCount);
1207
1208 /* Check if we have a handle database */
1209 if (ObjectType->TypeInfo.MaintainHandleCount)
1210 {
1211 /* Increment the handle database */
1212 Status = ObpIncrementHandleDataBase(ObjectHeader,
1213 Process,
1215 if (!NT_SUCCESS(Status))
1216 {
1217 /* FIXME: This should never happen for now */
1218 DPRINT1("Unhandled case\n");
1219 ASSERT(FALSE);
1220 goto Quickie;
1221 }
1222 }
1223
1224 /* Release the lock */
1225 ObpReleaseObjectLock(ObjectHeader);
1226
1227 /* Check if we have an open procedure */
1229 if (ObjectType->TypeInfo.OpenProcedure)
1230 {
1231 /* Call it */
1232 ObpCalloutStart(&CalloutIrql);
1233 Status = ObjectType->TypeInfo.OpenProcedure(ObCreateHandle,
1234 AccessMode,
1235 Process,
1236 Object,
1239 ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
1240
1241 /* Check if the open procedure failed */
1242 if (!NT_SUCCESS(Status))
1243 {
1244 /* FIXME: This should never happen for now */
1245 DPRINT1("Unhandled case\n");
1246 ASSERT(FALSE);
1247 return Status;
1248 }
1249 }
1250
1251 /* Check if we have creator info */
1252 CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
1253 if (CreatorInfo)
1254 {
1255 /* We do, acquire the lock */
1257
1258 /* Insert us on the list */
1259 InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
1260
1261 /* Release the lock */
1263 }
1264
1265 /* Increase total number of handles */
1266 Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
1267 if (Total > ObjectType->HighWaterNumberOfHandles)
1268 {
1269 /* Fixup count */
1270 ObjectType->HighWaterNumberOfHandles = Total;
1271 }
1272
1273 /* Trace call and return */
1275 "%s - Incremented count for: %p. UNNAMED HC PC %lx %lx\n",
1277 Object,
1278 ObjectHeader->HandleCount,
1279 ObjectHeader->PointerCount);
1280 return Status;
1281
1282Quickie:
1283 /* Release lock and return */
1284 ObpReleaseObjectLock(ObjectHeader);
1285 return Status;
1286}

Referenced by ObpCreateUnnamedHandle().

◆ ObpInsertHandleCount()

POBJECT_HANDLE_COUNT_ENTRY NTAPI ObpInsertHandleCount ( IN POBJECT_HEADER  ObjectHeader)

Definition at line 259 of file obhandle.c.

260{
263 POBJECT_HANDLE_COUNT_DATABASE HandleDatabase, OldHandleDatabase;
264 ULONG i;
265 ULONG Size, OldSize;
266 OBJECT_HANDLE_COUNT_DATABASE SingleDatabase;
267 PAGED_CODE();
268
269 /* Get the handle info */
270 HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
271 if (!HandleInfo) return NULL;
272
273 /* Check if we only have one entry */
274 if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
275 {
276 /* Fill out the single entry */
277 SingleDatabase.CountEntries = 1;
278 SingleDatabase.HandleCountEntries[0] = HandleInfo->SingleEntry;
279
280 /* Use this as the old size */
281 OldHandleDatabase = &SingleDatabase;
282 OldSize = sizeof(SingleDatabase);
283
284 /* Now we'll have two entries, and an entire DB */
285 i = 2;
287 ((i - 1) * sizeof(OBJECT_HANDLE_COUNT_ENTRY));
288 }
289 else
290 {
291 /* We already have a DB, get the information from it */
292 OldHandleDatabase = HandleInfo->HandleCountDatabase;
293 i = OldHandleDatabase->CountEntries;
294 OldSize = sizeof(OBJECT_HANDLE_COUNT_DATABASE) +
295 ((i - 1) * sizeof(OBJECT_HANDLE_COUNT_ENTRY));
296
297 /* Add 4 more entries */
298 i += 4;
299 Size = OldSize + (4 * sizeof(OBJECT_HANDLE_COUNT_ENTRY));
300 }
301
302 /* Allocate the DB */
304 if (!HandleDatabase) return NULL;
305
306 /* Copy the old database */
307 RtlCopyMemory(HandleDatabase, OldHandleDatabase, OldSize);
308
309 /* Check if we he had a single entry before */
310 if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
311 {
312 /* Now we have more */
313 ObjectHeader->Flags &= ~OB_FLAG_SINGLE_PROCESS;
314 }
315 else
316 {
317 /* Otherwise we had a DB, free it */
318 ExFreePoolWithTag(OldHandleDatabase, TAG_OB_HANDLE);
319 }
320
321 /* Find the end of the copy and zero out the new data */
322 FreeEntry = (PVOID)((ULONG_PTR)HandleDatabase + OldSize);
323 RtlZeroMemory(FreeEntry, Size - OldSize);
324
325 /* Set the new information and return the free entry */
326 HandleDatabase->CountEntries = i;
327 HandleInfo->HandleCountDatabase = HandleDatabase;
328 return FreeEntry;
329}
#define PagedPool
Definition: env_spec_w32.h:308
struct _OBJECT_HANDLE_COUNT_ENTRY OBJECT_HANDLE_COUNT_ENTRY
struct _OBJECT_HANDLE_COUNT_DATABASE OBJECT_HANDLE_COUNT_DATABASE
#define TAG_OB_HANDLE
Definition: tag.h:126
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by ObpIncrementHandleDataBase().

◆ ObpReferenceProcessObjectByHandle()

NTSTATUS NTAPI ObpReferenceProcessObjectByHandle ( IN HANDLE  Handle,
IN PEPROCESS  Process,
IN PHANDLE_TABLE  HandleTable,
IN KPROCESSOR_MODE  AccessMode,
OUT PVOID Object,
OUT POBJECT_HANDLE_INFORMATION  HandleInformation,
OUT PACCESS_MASK  AuditMask 
)

Definition at line 85 of file obhandle.c.

92{
93 PHANDLE_TABLE_ENTRY HandleEntry;
94 POBJECT_HEADER ObjectHeader;
99
100 /* Assume failure */
101 *Object = NULL;
102
103 /* Check if this is a special handle */
104 if (HandleToLong(Handle) < 0)
105 {
106 /* Check if the caller wants the current process */
107 if (Handle == NtCurrentProcess())
108 {
109 /* Return handle info */
110 HandleInformation->HandleAttributes = 0;
111 HandleInformation->GrantedAccess = Process->GrantedAccess;
112
113 /* No audit mask */
114 *AuditMask = 0;
115
116 /* Reference ourselves */
117 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Process);
119
120 /* Return the pointer */
121 *Object = Process;
122 ASSERT(*Object != NULL);
123 return STATUS_SUCCESS;
124 }
125
126 /* Check if the caller wants the current thread */
127 if (Handle == NtCurrentThread())
128 {
129 /* Return handle information */
130 HandleInformation->HandleAttributes = 0;
131 HandleInformation->GrantedAccess = Thread->GrantedAccess;
132
133 /* Reference ourselves */
134 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Thread);
136
137 /* No audit mask */
138 *AuditMask = 0;
139
140 /* Return the pointer */
141 *Object = Thread;
142 ASSERT(*Object != NULL);
143 return STATUS_SUCCESS;
144 }
145
146 /* This is a kernel handle... do we have access? */
147 if (AccessMode == KernelMode)
148 {
149 /* Use the kernel handle table and get the actual handle value */
152 }
153 else
154 {
155 /* This is an illegal attempt to access a kernel handle */
157 }
158 }
159
160 /* Enter a critical region while we touch the handle table */
163
164 /* Get the handle entry */
166 if (HandleEntry)
167 {
168 /* Get the object header and validate the type*/
169 ObjectHeader = ObpGetHandleObject(HandleEntry);
170
171 /* Get the granted access and validate it */
172 GrantedAccess = HandleEntry->GrantedAccess;
173
174 /* Mask out the internal attributes */
176
177 /* Fill out the information */
178 HandleInformation->HandleAttributes = Attributes;
179 HandleInformation->GrantedAccess = GrantedAccess;
180
181 /* No audit mask (FIXME!) */
182 *AuditMask = 0;
183
184 /* Return the pointer */
185 *Object = &ObjectHeader->Body;
186
187 /* Add a reference */
189
190 /* Unlock the handle */
193
194 /* Return success */
195 ASSERT(*Object != NULL);
196 return STATUS_SUCCESS;
197 }
198 else
199 {
200 /* Invalid handle */
202 }
203
204 /* Return failure status */
206 return Status;
207}
#define HandleToLong(h)
Definition: basetsd.h:74
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

Referenced by ObDuplicateObject().

◆ ObpSetHandleAttributes()

static BOOLEAN NTAPI ObpSetHandleAttributes ( _Inout_ PHANDLE_TABLE_ENTRY  HandleTableEntry,
_In_ ULONG_PTR  Context 
)
static

Internal callback used by ObSetHandleAttributes(). Updates the attributes of a handle given by its handle table entry.

This routine sets or clears the OBJ_INHERIT attribute and the internal close-protection bit corresponding to the protect-from-close handle attribute.

Parameters
[in,out]HandleTableEntryPointer to an entry in a process' handle table, representing the handle whose attributes are to be modified.
[in]ContextPointer-sized value to an OBP_SET_HANDLE_ATTRIBUTES_CONTEXT structure, that supplies the requested handle attribute values and the caller mode captured by ObSetHandleAttributes().
Returns
TRUE if the handle attributes are updated successfully, or FALSE if the requested change is not permitted.
Remarks
This routine is an internal callback for ExChangeHandle() (type: PEX_CHANGE_HANDLE_CALLBACK). It updates per-handle state rather than the underlying object. Requests to make a handle inheritable fail if the target object type does not permit the OBJ_INHERIT attribute.

Definition at line 1881 of file obhandle.c.

1884{
1886
1887 /* Define the handle inheritance, using the OBJ_INHERIT attribute */
1888 if (SetHandleInfo->Information.Inherit)
1889 {
1890 /* If inheritance is not supported for this object,
1891 * fail without changing anything */
1892 POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1893 if (ObjectHeader->Type->TypeInfo.InvalidAttributes & OBJ_INHERIT)
1894 return FALSE;
1895
1896 HandleTableEntry->ObAttributes |= OBJ_INHERIT;
1897 }
1898 else
1899 {
1900 HandleTableEntry->ObAttributes &= ~OBJ_INHERIT;
1901 }
1902
1903 /* Define the handle protection, using the protect-from-close bit */
1904 if (SetHandleInfo->Information.ProtectFromClose)
1905 HandleTableEntry->GrantedAccess |= ObpAccessProtectCloseBit;
1906 else
1907 HandleTableEntry->GrantedAccess &= ~ObpAccessProtectCloseBit;
1908
1909 return TRUE;
1910}
OBJECT_HANDLE_FLAG_INFORMATION Information
Definition: ob.h:112

Referenced by ObSetHandleAttributes().

◆ ObpValidateAccessMask()

NTSTATUS NTAPI ObpValidateAccessMask ( IN PACCESS_STATE  AccessState)

Definition at line 488 of file obhandle.c.

489{
491
492 /* We're only interested if the object for this access state has an SD */
493 SecurityDescriptor = AccessState->SecurityDescriptor;
495 {
496 /* Check if the SD has a system ACL but hasn't been granted access to get/set it */
497 if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
498 !(AccessState->PreviouslyGrantedAccess & ACCESS_SYSTEM_SECURITY))
499 {
500 /* We're gonna need access */
501 AccessState->RemainingDesiredAccess |= ACCESS_SYSTEM_SECURITY;
502 }
503 }
504
505 /* This can't fail */
506 return STATUS_SUCCESS;
507}
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
#define SE_SACL_PRESENT
Definition: setypes.h:835

Referenced by ObInsertObject(), and ObOpenObjectByName().

◆ ObReferenceProcessHandleTable()

PHANDLE_TABLE NTAPI ObReferenceProcessHandleTable ( IN PEPROCESS  Process)

Definition at line 26 of file obhandle.c.

27{
29
30 /* Lock the process */
31 if (ExAcquireRundownProtection(&Process->RundownProtect))
32 {
33 /* Get the handle table */
34 HandleTable = Process->ObjectTable;
35 if (!HandleTable)
36 {
37 /* No table, release the lock */
38 ExReleaseRundownProtection(&Process->RundownProtect);
39 }
40 }
41
42 /* Return the handle table */
43 return HandleTable;
44}
#define ExAcquireRundownProtection
Definition: ex.h:138

Referenced by ObClearProcessHandleTable(), ObDuplicateObject(), ObFindHandleForObject(), ObGetProcessHandleCount(), and ObInitProcess().

◆ ObSetHandleAttributes()

NTSTATUS NTAPI ObSetHandleAttributes ( _In_ HANDLE  Handle,
_In_ POBJECT_HANDLE_FLAG_INFORMATION  HandleFlags,
_In_ KPROCESSOR_MODE  PreviousMode 
)

Sets the attributes (inheritable and protect-from-close) of an existing object handle.

Parameters
[in]HandleHandle whose attributes are to be modified.
[in]HandleFlagsPointer to an OBJECT_HANDLE_FLAG_INFORMATION structure specifying the new values for the handle's inherit and protect-from-close attributes.
[in]PreviousModeProcessor mode of the original caller. This is used to determine whether Handle may refer to a kernel handle.
Returns
STATUS_SUCCESS on success, or STATUS_ACCESS_DENIED if the handle could not be located or its attributes could not be changed.
Remarks
This routine operates on per-handle state rather than on the underlying object itself. Requests to make a handle inheritable fail if the target object type does not permit the OBJ_INHERIT attribute.

Definition at line 3326 of file obhandle.c.

3330{
3331 OBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleAttributesContext;
3332 BOOLEAN Result, AttachedToProcess = FALSE;
3335
3336 PAGED_CODE();
3337
3338 /* Check if this is a kernel handle */
3340 {
3341 /* Use the kernel table and convert the handle */
3344
3345 /* Check if we're not in the system process */
3347 {
3348 /* Attach to the system process */
3350 AttachedToProcess = TRUE;
3351 }
3352 }
3353 else
3354 {
3355 /* Get the current process' handle table */
3356 HandleTable = PsGetCurrentProcess()->ObjectTable;
3357 }
3358
3359 /* Initialize the handle attribute context */
3360 SetHandleAttributesContext.PreviousMode = PreviousMode;
3361 SetHandleAttributesContext.Information = *HandleFlags;
3362
3363 /* Invoke the ObpSetHandleAttributes callback */
3365 Handle,
3367 (ULONG_PTR)&SetHandleAttributesContext);
3368
3369 /* Detach from the system process if needed */
3370 if (AttachedToProcess)
3372
3373 /* Return the result as an NTSTATUS value */
3375}
BOOLEAN NTAPI ExChangeHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, IN ULONG_PTR Context)
Definition: handle.c:1189
static BOOLEAN NTAPI ObpSetHandleAttributes(_Inout_ PHANDLE_TABLE_ENTRY HandleTableEntry, _In_ ULONG_PTR Context)
Internal callback used by ObSetHandleAttributes(). Updates the attributes of a handle given by its ha...
Definition: obhandle.c:1881
KPROCESSOR_MODE PreviousMode
Definition: ob.h:111

Referenced by NtSetInformationObject().

Variable Documentation

◆ ObpKernelHandleTable