ReactOS 0.4.17-dev-769-g1500a35
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 3429 of file obhandle.c.

3430{
3431 /* Call the internal API */
3433}
#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:1749

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 3437 of file obhandle.c.

3444{
3445 PEPROCESS SourceProcess, TargetProcess, Target;
3446 HANDLE hTarget;
3450 "%s - Duplicating handle: %p for %p into %p.\n",
3453 SourceProcessHandle,
3455
3456 /* Check if we have a target handle */
3457 if ((TargetHandle) && (PreviousMode != KernelMode))
3458 {
3459 /* Enter SEH */
3460 _SEH2_TRY
3461 {
3462 /* Probe the handle and assume failure */
3464 *TargetHandle = NULL;
3465 }
3467 {
3468 /* Return the exception code */
3470 }
3471 _SEH2_END;
3472 }
3473
3474 /* Now reference the input handle */
3475 Status = ObReferenceObjectByHandle(SourceProcessHandle,
3479 (PVOID*)&SourceProcess,
3480 NULL);
3481 if (!NT_SUCCESS(Status)) return Status;
3482
3483 /* Check if got a target handle */
3485 {
3486 /* Now reference the output handle */
3491 (PVOID*)&TargetProcess,
3492 NULL);
3493 if (NT_SUCCESS(Status))
3494 {
3495 /* Use this target process */
3496 Target = TargetProcess;
3497 }
3498 else
3499 {
3500 /* No target process */
3501 Target = NULL;
3502 }
3503 }
3504 else
3505 {
3506 /* No target process */
3508 Target = NULL;
3509 }
3510
3511 /* Call the internal routine */
3512 Status = ObDuplicateObject(SourceProcess,
3514 Target,
3515 &hTarget,
3518 Options,
3519 PreviousMode);
3520
3521 /* Check if the caller wanted the return handle */
3522 if (TargetHandle)
3523 {
3524 /* Protect the write to user mode */
3525 _SEH2_TRY
3526 {
3527 /* Write the new handle */
3528 *TargetHandle = hTarget;
3529 }
3531 {
3532 /* Otherwise, get the exception code */
3534 }
3535 _SEH2_END;
3536 }
3537
3538 /* Dereference the processes */
3540 "%s - Duplicated handle: %p into %p S %lx\n",
3542 hTarget,
3544 Status);
3546 ObDereferenceObject(SourceProcess);
3547 return Status;
3548}
_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:2226
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 2049 of file obhandle.c.

2050{
2054 BOOLEAN AttachedToProcess = FALSE;
2055
2056 ASSERT(Process);
2057
2058 /* Ensure the handle table doesn't go away while we use it */
2060 if (!HandleTable) return;
2061
2062 /* Attach to the current process if needed */
2064 {
2066 AttachedToProcess = TRUE;
2067 }
2068
2069 /* Enter a critical region */
2071
2072 /* Fill out the context */
2073 Context.AccessMode = UserMode;
2074 Context.HandleTable = HandleTable;
2075
2076 /* Sweep the handle table to close all handles */
2079 &Context);
2080
2081 /* Leave the critical region */
2083
2084 /* Detach if needed */
2085 if (AttachedToProcess)
2087
2088 /* Let the handle table go */
2090}
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:1946
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 3406 of file obhandle.c.

3408{
3409 /* Call the internal API */
3411}
_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(), IntCreateDesktopSwitchEvent(), IntCreateNewRegistryPath(), IntResolveDesktop(), IntSetupDeviceSettingsKey(), IntVideoPortInbvCleanup(), IntWinStaObjectDelete(), 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 2226 of file obhandle.c.

2234{
2235 HANDLE_TABLE_ENTRY NewHandleEntry;
2236 BOOLEAN AttachedToProcess = FALSE;
2237 PVOID SourceObject;
2238 POBJECT_HEADER ObjectHeader;
2240 HANDLE NewHandle;
2243 ACCESS_MASK TargetAccess, SourceAccess;
2246 AUX_ACCESS_DATA AuxData;
2249 ULONG AuditMask;
2251
2252 PAGED_CODE();
2254 "%s - Duplicating handle: %p for %p into %p\n",
2257 SourceProcess,
2258 TargetProcess);
2259
2260 /* Assume failure */
2262
2263 /* Check if we're not duplicating the same access */
2265 {
2266 /* Validate the desired access */
2267 Status = STATUS_SUCCESS; //ObpValidateDesiredAccess(DesiredAccess);
2268 if (!NT_SUCCESS(Status)) return Status;
2269 }
2270
2271 /* Reference the object table */
2274
2275 /* Reference the process object */
2277 SourceProcess,
2280 &SourceObject,
2282 &AuditMask);
2283 if (!NT_SUCCESS(Status))
2284 {
2285 /* Fail */
2286 ObDereferenceProcessHandleTable(SourceProcess);
2287 return Status;
2288 }
2289 else
2290 {
2291 /* Check if we have to don't have to audit object close */
2292 if (!(HandleInformation.HandleAttributes & OBJ_AUDIT_OBJECT_CLOSE))
2293 {
2294 /* Then there is no audit mask */
2295 AuditMask = 0;
2296 }
2297 }
2298
2299 /* Check if there's no target process */
2300 if (!TargetProcess)
2301 {
2302 /* Check if the caller wanted actual duplication */
2304 {
2305 /* Invalid request */
2307 }
2308 else
2309 {
2310 /* Otherwise, do the attach */
2311 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2312
2313 /* Close the handle and detach */
2316 }
2317
2318 /* Return */
2319 ObDereferenceProcessHandleTable(SourceProcess);
2320 ObDereferenceObject(SourceObject);
2321 return Status;
2322 }
2323
2324 /* Create a kernel handle if asked, but only in the system process */
2325 if (PreviousMode == KernelMode &&
2327 TargetProcess == PsInitialSystemProcess)
2328 {
2330 }
2331
2332 /* Get the target handle table */
2334 if (!HandleTable)
2335 {
2336 /* Check if the caller wanted us to close the handle */
2338 {
2339 /* Do the attach */
2340 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2341
2342 /* Close the handle and detach */
2345 }
2346
2347 /* Return */
2348 ObDereferenceProcessHandleTable(SourceProcess);
2349 ObDereferenceObject(SourceObject);
2351 }
2352
2353 /* Get the source access */
2354 SourceAccess = HandleInformation.GrantedAccess;
2355
2356 /* Check if we're not in the target process */
2357 if (TargetProcess != PsGetCurrentProcess())
2358 {
2359 /* Attach to it */
2360 KeStackAttachProcess(&TargetProcess->Pcb, &ApcState);
2361 AttachedToProcess = TRUE;
2362 }
2363
2364 /* Check if we're duplicating the attributes */
2366 {
2367 /* Duplicate them */
2368 HandleAttributes = HandleInformation.HandleAttributes;
2369 }
2370 else
2371 {
2372 /* Don't allow caller to bypass auditing */
2373 HandleAttributes |= HandleInformation.HandleAttributes &
2375 }
2376
2377 /* Check if we're duplicating the access */
2378 if (Options & DUPLICATE_SAME_ACCESS) DesiredAccess = SourceAccess;
2379
2380 /* Get object data */
2381 ObjectHeader = OBJECT_TO_OBJECT_HEADER(SourceObject);
2382 ObjectType = ObjectHeader->Type;
2383
2384 /* Fill out the entry */
2385 RtlZeroMemory(&NewHandleEntry, sizeof(HANDLE_TABLE_ENTRY));
2386 NewHandleEntry.Object = ObjectHeader;
2388
2389 /* Check if we're using a generic mask */
2391 {
2392 /* Map it */
2394 &ObjectType->TypeInfo.GenericMapping);
2395 }
2396
2397 /* Set the target access, always propagate ACCESS_SYSTEM_SECURITY */
2398 TargetAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
2400 NewHandleEntry.GrantedAccess = TargetAccess;
2401
2402 /* Check if we're asking for new access */
2403 if (TargetAccess & ~SourceAccess)
2404 {
2405 /* We are. We need the security procedure to validate this */
2406 if (ObjectType->TypeInfo.SecurityProcedure == SeDefaultObjectMethod)
2407 {
2408 /* Use our built-in access state */
2411 &AuxData,
2412 TargetAccess,
2413 &ObjectType->TypeInfo.GenericMapping);
2414 }
2415 else
2416 {
2417 /* Otherwise we can't allow this privilege elevation */
2419 }
2420 }
2421 else
2422 {
2423 /* We don't need an access state */
2425 }
2426
2427 /* Make sure the access state was created OK */
2428 if (NT_SUCCESS(Status))
2429 {
2430 /* Add a new handle */
2431 Status = ObpIncrementHandleCount(SourceObject,
2437 }
2438
2439 /* Check if we were attached */
2440 if (AttachedToProcess)
2441 {
2442 /* We can safely detach now */
2444 AttachedToProcess = FALSE;
2445 }
2446
2447 /* Check if we have to close the source handle */
2449 {
2450 /* Attach and close */
2451 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2454 }
2455
2456 /* Check if we had an access state */
2458
2459 /* Now check if incrementing actually failed */
2460 if (!NT_SUCCESS(Status))
2461 {
2462 /* Dereference handle tables */
2463 ObDereferenceProcessHandleTable(SourceProcess);
2464 ObDereferenceProcessHandleTable(TargetProcess);
2465
2466 /* Dereference the source object */
2467 ObDereferenceObject(SourceObject);
2468 return Status;
2469 }
2470
2471 if (NewHandleEntry.ObAttributes & OBJ_PROTECT_CLOSE)
2472 {
2473 NewHandleEntry.ObAttributes &= ~OBJ_PROTECT_CLOSE;
2474 NewHandleEntry.GrantedAccess |= ObpAccessProtectCloseBit;
2475 }
2476
2477 /* Now create the handle */
2478 NewHandle = ExCreateHandle(HandleTable, &NewHandleEntry);
2479 if (!NewHandle)
2480 {
2481 /* Undo the increment */
2482 ObpDecrementHandleCount(SourceObject,
2483 TargetProcess,
2484 TargetAccess,
2485 ObjectType);
2486
2487 /* Deference the object and set failure status */
2488 ObDereferenceObject(SourceObject);
2490 }
2491
2492 /* Mark it as a kernel handle if requested */
2493 if (KernelHandle)
2494 {
2495 NewHandle = ObMarkHandleAsKernelHandle(NewHandle);
2496 }
2497
2498 /* Return the handle */
2499 if (TargetHandle) *TargetHandle = NewHandle;
2500
2501 /* Dereference handle tables */
2502 ObDereferenceProcessHandleTable(SourceProcess);
2503 ObDereferenceProcessHandleTable(TargetProcess);
2504
2505 /* Return status */
2507 "%s - Duplicated handle: %p for %p into %p. Source: %p HC PC %lx %lx\n",
2509 NewHandle,
2510 SourceProcess,
2511 TargetProcess,
2512 SourceObject,
2513 ObjectHeader->PointerCount,
2514 ObjectHeader->HandleCount);
2515 return Status;
2516}
#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:3429
#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 2878 of file obhandle.c.

2883{
2884 OBP_FIND_HANDLE_DATA FindData;
2886 PVOID ObjectTable;
2887
2888 /* Make sure we have an object table */
2890 if (ObjectTable)
2891 {
2892 /* Check if we have an object */
2893 if (Object)
2894 {
2895 /* Set its header */
2897 }
2898 else
2899 {
2900 /* Otherwise, no object to match*/
2901 FindData.ObjectHeader = NULL;
2902 }
2903
2904 /* Set other information */
2905 FindData.ObjectType = ObjectType;
2907
2908 /* Enumerate the handle table */
2909 if (ExEnumHandleTable(Process->ObjectTable,
2911 &FindData,
2912 Handle))
2913 {
2914 /* Set success */
2915 Result = TRUE;
2916 }
2917
2918 /* Let go of the table */
2920 }
2921
2922 /* Return the result */
2923 return Result;
2924}
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 2112 of file obhandle.c.

2114{
2115 PHANDLE_TABLE ParentTable, ObjectTable;
2116
2117 /* Check for a parent */
2118 if (Parent)
2119 {
2120 /* Reference the parent's table */
2122 if (!ParentTable) return STATUS_PROCESS_IS_TERMINATING;
2123
2124 /* Duplicate it */
2125 ObjectTable = ExDupHandleTable(Process,
2126 ParentTable,
2128 OBJ_INHERIT);
2129 }
2130 else
2131 {
2132 /* Otherwise just create a new table */
2133 ParentTable = NULL;
2134 ObjectTable = ExCreateHandleTable(Process);
2135 }
2136
2137 /* Make sure we have a table */
2138 if (ObjectTable)
2139 {
2140 /* Associate it */
2141 Process->ObjectTable = ObjectTable;
2142
2143 /* Check for auditing */
2145 {
2146 /* FIXME: TODO */
2147 DPRINT1("Need auditing!\n");
2148 }
2149
2150 /* Get rid of the old table now */
2151 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2152
2153 /* We are done */
2154 return STATUS_SUCCESS;
2155 }
2156 else
2157 {
2158 /* Fail */
2159 Process->ObjectTable = NULL;
2160 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2162 }
2163}
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:1982
#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 2957 of file obhandle.c.

2963{
2964 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
2965 POBJECT_HEADER ObjectHeader;
2968 PVOID InsertObject;
2969 PSECURITY_DESCRIPTOR ParentDescriptor = NULL;
2970 BOOLEAN SdAllocated = FALSE;
2971 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
2973 ACCESS_STATE LocalAccessState;
2974 AUX_ACCESS_DATA AuxData;
2975 OB_OPEN_REASON OpenReason;
2977 NTSTATUS Status = STATUS_SUCCESS, RealStatus;
2978 BOOLEAN IsNewObject;
2979 PAGED_CODE();
2980
2981 /* Get the Header */
2982 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2983
2984 /* Detect invalid insert */
2985 if (!(ObjectHeader->Flags & OB_FLAG_CREATE_INFO))
2986 {
2987 /* Display warning and break into debugger */
2988 DPRINT1("OB: Attempting to insert existing object %p\n", Object);
2989 DbgBreakPoint();
2990
2991 /* Allow debugger to continue */
2994 }
2995
2996 /* Get the create and name info, as well as the object type */
2997 ObjectCreateInfo = ObjectHeader->ObjectCreateInfo;
2998 ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
2999 ObjectType = ObjectHeader->Type;
3000 ObjectName = NULL;
3001
3002 /* Check if this is an named object */
3003 if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer))
3004 {
3005 /* Get the object name */
3006 ObjectName = &ObjectNameInfo->Name;
3007 }
3008
3009 /* Sanity check */
3010 ASSERT((Handle) ||
3011 ((ObjectPointerBias == 0) &&
3012 (ObjectName == NULL) &&
3013 (ObjectType->TypeInfo.SecurityRequired) &&
3014 (NewObject == NULL)));
3015
3016 /* Check if the object is unnamed and also doesn't have security */
3018 if (!(ObjectType->TypeInfo.SecurityRequired) && !(ObjectName))
3019 {
3020 /* Assume failure */
3021 *Handle = NULL;
3022 ObjectHeader->ObjectCreateInfo = NULL;
3023
3024 /* Create the handle */
3028 ObjectCreateInfo->Attributes,
3030 NewObject,
3031 Handle);
3032
3033 /* Free the create information */
3034 ObpFreeObjectCreateInformation(ObjectCreateInfo);
3035
3036 /* Release the object name information */
3037 ObpDereferenceNameInfo(ObjectNameInfo);
3038
3039 /* Remove the extra keep-alive reference */
3041
3042 /* Return */
3044 "%s - returning Object with PC S: %lx %lx\n",
3046 ObjectHeader->PointerCount,
3047 Status);
3048 return Status;
3049 }
3050
3051 /* Check if we didn't get an access state */
3052 if (!AccessState)
3053 {
3054 /* Use our built-in access state */
3055 AccessState = &LocalAccessState;
3056 Status = SeCreateAccessState(&LocalAccessState,
3057 &AuxData,
3059 &ObjectType->TypeInfo.GenericMapping);
3060 if (!NT_SUCCESS(Status))
3061 {
3062 /* Fail */
3063 ObpDereferenceNameInfo(ObjectNameInfo);
3065 return Status;
3066 }
3067 }
3068
3069 /* Save the security descriptor */
3070 AccessState->SecurityDescriptor = ObjectCreateInfo->SecurityDescriptor;
3071
3072 /* Validate the access mask */
3074 if (!NT_SUCCESS(Status))
3075 {
3076 /* Fail */
3077 ObpDereferenceNameInfo(ObjectNameInfo);
3079 return Status;
3080 }
3081
3082 /* Setup a lookup context */
3084 InsertObject = Object;
3085 OpenReason = ObCreateHandle;
3086
3087 /* Check if the object is named */
3088 if (ObjectName)
3089 {
3090 /* Look it up */
3091 Status = ObpLookupObjectName(ObjectCreateInfo->RootDirectory,
3092 ObjectName,
3093 ObjectCreateInfo->Attributes,
3094 ObjectType,
3095 (ObjectHeader->Flags & OB_FLAG_KERNEL_MODE) ?
3097 ObjectCreateInfo->ParseContext,
3098 ObjectCreateInfo->SecurityQos,
3099 Object,
3101 &Context,
3102 &InsertObject);
3103
3104 /* Check if we found an object that doesn't match the one requested */
3105 if ((NT_SUCCESS(Status)) && (InsertObject) && (Object != InsertObject))
3106 {
3107 /* This means we're opening an object, not creating a new one */
3108 OpenReason = ObOpenHandle;
3109
3110 /* Make sure the caller said it's OK to do this */
3111 if (ObjectCreateInfo->Attributes & OBJ_OPENIF)
3112 {
3113 /* He did, but did he want this type? */
3114 if (ObjectType != OBJECT_TO_OBJECT_HEADER(InsertObject)->Type)
3115 {
3116 /* Wrong type, so fail */
3118 }
3119 else
3120 {
3121 /* Right type, so warn */
3123 }
3124 }
3125 else
3126 {
3127 /* Check if this was a symbolic link */
3128 if (OBJECT_TO_OBJECT_HEADER(InsertObject)->Type ==
3130 {
3131 /* Dereference it */
3132 ObDereferenceObject(InsertObject);
3133 }
3134
3135 /* Caller wanted to create a new object, fail */
3137 }
3138 }
3139
3140 /* Check if anything until now failed */
3141 if (!NT_SUCCESS(Status))
3142 {
3143 /* Cleanup after lookup */
3145
3146 /* Remove query reference that we added */
3147 ObpDereferenceNameInfo(ObjectNameInfo);
3148
3149 /* Dereference the object and delete the access state */
3151 if (AccessState == &LocalAccessState)
3152 {
3153 /* We used a local one; delete it */
3155 }
3156
3157 /* Return failure code */
3158 return Status;
3159 }
3160 else
3161 {
3162 /* Check if this is a symbolic link */
3164 {
3165 /* Create the internal name */
3167 }
3168 }
3169 }
3170
3171 /* Now check if this object is being created */
3172 if (InsertObject == Object)
3173 {
3174 /* Check if it's named or forces security */
3175 if ((ObjectName) || (ObjectType->TypeInfo.SecurityRequired))
3176 {
3177 /* Make sure it's inserted into an object directory */
3178 if ((ObjectNameInfo) && (ObjectNameInfo->Directory))
3179 {
3180 /* Get the current descriptor */
3181 ObGetObjectSecurity(ObjectNameInfo->Directory,
3182 &ParentDescriptor,
3183 &SdAllocated);
3184 }
3185
3186 /* Now assign it */
3188 ParentDescriptor,
3189 Object,
3190 ObjectType);
3191
3192 /* Check if we captured one */
3193 if (ParentDescriptor)
3194 {
3195 /* We did, release it */
3196 ObReleaseObjectSecurity(ParentDescriptor, SdAllocated);
3197 }
3198 else if (NT_SUCCESS(Status))
3199 {
3200 /* Other we didn't, but we were able to use the current SD */
3202 ObjectCreateInfo->ProbeMode,
3203 TRUE);
3204
3205 /* Clear the current one */
3206 AccessState->SecurityDescriptor =
3207 ObjectCreateInfo->SecurityDescriptor = NULL;
3208 }
3209 }
3210
3211 /* Check if anything until now failed */
3212 if (!NT_SUCCESS(Status))
3213 {
3214 /* Check if the directory was added */
3215 if (Context.DirectoryLocked)
3216 {
3217 /* Weird case where we need to do a manual delete */
3218 DPRINT1("Unhandled path\n");
3219 ASSERT(FALSE);
3220 }
3221
3222 /* Cleanup the lookup */
3224
3225 /* Remove query reference that we added */
3226 ObpDereferenceNameInfo(ObjectNameInfo);
3227
3228 /* Dereference the object and delete the access state */
3230 if (AccessState == &LocalAccessState)
3231 {
3232 /* We used a local one; delete it */
3234 }
3235
3236 /* Return failure code */
3237 ASSERT(FALSE);
3238 return Status;
3239 }
3240 }
3241
3242 /* Save the actual status until here */
3243 RealStatus = Status;
3244
3245 /* Check if caller wants us to create a handle */
3246 ObjectHeader->ObjectCreateInfo = NULL;
3247 if (Handle)
3248 {
3249 /* Create the handle */
3250 Status = ObpCreateHandle(OpenReason,
3251 InsertObject,
3252 NULL,
3255 ObjectCreateInfo->Attributes,
3256 &Context,
3258 NewObject,
3259 Handle);
3260 if (!NT_SUCCESS(Status))
3261 {
3262 /* If the object had a name, backout everything */
3264
3265 /* Return the status of the failure */
3266 *Handle = NULL;
3267 RealStatus = Status;
3268 }
3269
3270 /* Remove a query reference */
3271 ObpDereferenceNameInfo(ObjectNameInfo);
3272
3273 /* Remove the extra keep-alive reference */
3275 }
3276 else
3277 {
3278 /* Otherwise, lock the object */
3279 ObpAcquireObjectLock(ObjectHeader);
3280
3281 /* And charge quota for the process to make it appear as used */
3282 RealStatus = ObpChargeQuotaForObject(ObjectHeader,
3283 ObjectType,
3284 &IsNewObject);
3285
3286 /* Release the lock */
3287 ObpReleaseObjectLock(ObjectHeader);
3288
3289 /* Check if we failed and dereference the object if so */
3290 if (!NT_SUCCESS(RealStatus)) ObDereferenceObject(Object);
3291 }
3292
3293 /* We can delete the Create Info now */
3294 ObpFreeObjectCreateInformation(ObjectCreateInfo);
3295
3296 /* Check if we created our own access state and delete it if so */
3297 if (AccessState == &LocalAccessState) SeDeleteAccessState(AccessState);
3298
3299 /* Return status code */
3301 "%s - returning Object with PC RS/S: %lx %lx %lx\n",
3303 OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
3304 RealStatus, Status);
3305 return RealStatus;
3306}
#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:1516
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:1331
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 3552 of file obhandle.c.

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

◆ ObKillProcess()

VOID NTAPI ObKillProcess ( IN PEPROCESS  Process)

Definition at line 2182 of file obhandle.c.

2183{
2186 BOOLEAN HardErrors;
2187 PAGED_CODE();
2188
2189 /* Wait for process rundown and then complete it */
2191 ExRundownCompleted(&Process->RundownProtect);
2192
2193 /* Get the object table */
2194 HandleTable = Process->ObjectTable;
2195 if (!HandleTable) return;
2196
2197 /* Disable hard errors while we close handles */
2198 HardErrors = IoSetThreadHardErrorMode(FALSE);
2199
2200 /* Enter a critical region */
2202
2203 /* Fill out the context */
2204 Context.AccessMode = KernelMode;
2205 Context.HandleTable = HandleTable;
2206
2207 /* Sweep the handle table to close all handles */
2210 &Context);
2211 ASSERT(HandleTable->HandleCount == 0);
2212
2213 /* Leave the critical region */
2215
2216 /* Re-enable hard errors */
2217 IoSetThreadHardErrorMode(HardErrors);
2218
2219 /* Destroy the object table */
2220 Process->ObjectTable = NULL;
2222}
#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 2554 of file obhandle.c.

2561{
2562 PVOID Object = NULL;
2564 NTSTATUS Status, Status2;
2565 POBJECT_HEADER ObjectHeader;
2567 OB_OPEN_REASON OpenReason;
2568 POB_TEMP_BUFFER TempBuffer;
2569 PAGED_CODE();
2570
2571 /* Assume failure */
2572 *Handle = NULL;
2573
2574 /* Check if we didn't get any Object Attributes */
2575 if (!ObjectAttributes)
2576 {
2577 /* Fail with special status code */
2579 }
2580
2581 /* Allocate the temporary buffer */
2583 sizeof(OB_TEMP_BUFFER),
2585 if (!TempBuffer) return STATUS_INSUFFICIENT_RESOURCES;
2586
2587 /* Capture all the info */
2589 AccessMode,
2590 AccessMode,
2591 TRUE,
2592 &TempBuffer->ObjectCreateInfo,
2593 &ObjectName);
2594 if (!NT_SUCCESS(Status))
2595 {
2596 /* Fail */
2598 return Status;
2599 }
2600
2601 /* Check if we didn't get an access state */
2602 if (!PassedAccessState)
2603 {
2604 /* Try to get the generic mapping if we can */
2605 if (ObjectType) GenericMapping = &ObjectType->TypeInfo.GenericMapping;
2606
2607 /* Use our built-in access state */
2608 PassedAccessState = &TempBuffer->LocalAccessState;
2610 &TempBuffer->AuxData,
2613 if (!NT_SUCCESS(Status)) goto Quickie;
2614 }
2615
2616 /* Get the security descriptor */
2617 if (TempBuffer->ObjectCreateInfo.SecurityDescriptor)
2618 {
2619 /* Save it in the access state */
2622 }
2623
2624 /* Validate the access mask */
2626 if (!NT_SUCCESS(Status))
2627 {
2628 /* Cleanup after lookup */
2630 goto Cleanup;
2631 }
2632
2633 /* Now do the lookup */
2635 &ObjectName,
2636 TempBuffer->ObjectCreateInfo.Attributes,
2637 ObjectType,
2638 AccessMode,
2639 ParseContext,
2640 TempBuffer->ObjectCreateInfo.SecurityQos,
2641 NULL,
2643 &TempBuffer->LookupContext,
2644 &Object);
2645 if (!NT_SUCCESS(Status))
2646 {
2647 /* Cleanup after lookup */
2649 goto Cleanup;
2650 }
2651
2652 /* Check if this object has create information */
2653 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
2654 if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO)
2655 {
2656 /* Then we are creating a new handle */
2657 OpenReason = ObCreateHandle;
2658
2659 /* Check if we still have create info */
2660 if (ObjectHeader->ObjectCreateInfo)
2661 {
2662 /* Free it */
2663 ObpFreeObjectCreateInformation(ObjectHeader->
2664 ObjectCreateInfo);
2665 ObjectHeader->ObjectCreateInfo = NULL;
2666 }
2667 }
2668 else
2669 {
2670 /* Otherwise, we are merely opening it */
2671 OpenReason = ObOpenHandle;
2672 }
2673
2674 /* Check if we have invalid object attributes */
2675 if (ObjectHeader->Type->TypeInfo.InvalidAttributes &
2676 TempBuffer->ObjectCreateInfo.Attributes)
2677 {
2678 /* Set failure code */
2680
2681 /* Cleanup after lookup */
2683
2684 /* Dereference the object */
2686 }
2687 else
2688 {
2689 /* Create the actual handle now */
2690 Status2 = ObpCreateHandle(OpenReason,
2691 Object,
2692 ObjectType,
2694 0,
2695 TempBuffer->ObjectCreateInfo.Attributes,
2696 &TempBuffer->LookupContext,
2697 AccessMode,
2698 NULL,
2699 Handle);
2700 if (!NT_SUCCESS(Status2))
2701 {
2703 Status = Status2;
2704 }
2705 }
2706
2707Cleanup:
2708 /* Delete the access state */
2709 if (PassedAccessState == &TempBuffer->LocalAccessState)
2710 {
2712 }
2713
2714Quickie:
2715 /* Release the object attributes and temporary buffer */
2719
2720 /* Return status */
2722 "%s - returning Object %p with PC S: %lx %lx\n",
2724 Object,
2725 Object ? OBJECT_TO_OBJECT_HEADER(Object)->PointerCount : -1,
2726 Status);
2727 return Status;
2728}
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 2764 of file obhandle.c.

2771{
2775 AUX_ACCESS_DATA AuxData;
2776 PAGED_CODE();
2777
2778 /* Assume failure */
2779 *Handle = NULL;
2780
2781 /* Reference the object */
2783 0,
2784 ObjectType,
2785 AccessMode);
2786 if (!NT_SUCCESS(Status)) return Status;
2787
2788 /* Get the Header Info */
2790
2791 /* Check if we didn't get an access state */
2792 if (!PassedAccessState)
2793 {
2794 /* Use our built-in access state */
2797 &AuxData,
2799 &Header->Type->TypeInfo.GenericMapping);
2800 if (!NT_SUCCESS(Status))
2801 {
2802 /* Fail */
2804 return Status;
2805 }
2806 }
2807
2808 /* Check if we have invalid object attributes */
2809 if (Header->Type->TypeInfo.InvalidAttributes & HandleAttributes)
2810 {
2811 /* Delete the access state */
2813 {
2815 }
2816
2817 /* Dereference the object */
2820 }
2821
2822 /* Create the handle */
2824 Object,
2825 ObjectType,
2827 0,
2829 NULL,
2830 AccessMode,
2831 NULL,
2832 Handle);
2834
2835 /* Delete the access state */
2837 {
2839 }
2840
2841 /* Return */
2843 "%s - returning Object with PC S: %lx %lx\n",
2845 OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
2846 Status);
2847 return Status;
2848}
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 1749 of file obhandle.c.

1751{
1753 BOOLEAN AttachedToProcess = FALSE;
1755 PHANDLE_TABLE_ENTRY HandleTableEntry;
1758 PAGED_CODE();
1760 "%s - Closing handle: %p\n", __FUNCTION__, Handle);
1761
1762 if (AccessMode == KernelMode && Handle == (HANDLE)-1)
1763 return STATUS_INVALID_HANDLE;
1764
1765 /* Check if we're dealing with a kernel handle */
1767 {
1768 /* Use the kernel table and convert the handle */
1771
1772 /* Check if we're not in the system process */
1774 {
1775 /* Attach to the system process */
1777 AttachedToProcess = TRUE;
1778 }
1779 }
1780 else
1781 {
1782 /* Use the process's handle table */
1783 HandleTable = Process->ObjectTable;
1784 }
1785
1786 /* Enter a critical region to protect handle access */
1788
1789 /* Get the handle entry */
1790 HandleTableEntry = ExMapHandleToPointer(HandleTable, Handle);
1791 if (HandleTableEntry)
1792 {
1793 /* Now close the entry */
1795 HandleTableEntry,
1796 Handle,
1797 AccessMode,
1798 FALSE);
1799
1800 /* We can quit the critical region now */
1802
1803 /* Detach and return success */
1804 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1805 }
1806 else
1807 {
1808 /* We failed, quit the critical region */
1810
1811 /* Detach */
1812 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1813
1814 /* Check if we have a valid handle that's not the process or thread */
1815 if ((Handle) &&
1816 (Handle != NtCurrentProcess()) &&
1817 (Handle != NtCurrentThread()))
1818 {
1819 /* Check if we came from user mode */
1820 if (AccessMode != KernelMode)
1821 {
1822 /* Check if we have no debug port */
1823 if (Process->DebugPort)
1824 {
1825 /* Make sure we're not attached */
1826 if (!KeIsAttachedProcess())
1827 {
1828 /* Raise an exception */
1830 }
1831 }
1832 }
1833 else
1834 {
1835 /* This is kernel mode. Check if we're exiting */
1837 (Process->Peb))
1838 {
1839 /* Check if the debugger is enabled */
1841 {
1842 /* Bugcheck */
1843 KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 1, 0, 0);
1844 }
1845 }
1846 }
1847 }
1848
1849 /* Set invalid status */
1851 }
1852
1853 /* Return status */
1855 "%s - Closed handle: %p S: %lx\n",
1857 return Status;
1858}
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:1399
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 1946 of file obhandle.c.

1949{
1951
1952 /* Simply decrement the handle count */
1954 HandleTableEntry,
1955 Handle,
1956 CloseContext->AccessMode,
1957 TRUE);
1958 return TRUE;
1959}
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 1516 of file obhandle.c.

1526{
1527 HANDLE_TABLE_ENTRY NewEntry;
1528 POBJECT_HEADER ObjectHeader;
1529 HANDLE Handle;
1531 BOOLEAN AttachedToProcess = FALSE, KernelHandle = FALSE;
1536 PAUX_ACCESS_DATA AuxData;
1537 PAGED_CODE();
1538
1539 /* Get the object header and type */
1540 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1541 ObjectType = ObjectHeader->Type;
1543 "%s - Creating handle for: %p. Reason: %lx. HC PC %lx %lx\n",
1545 Object,
1546 OpenReason,
1547 ObjectHeader->HandleCount,
1548 ObjectHeader->PointerCount);
1549
1550 /* Check if the types match */
1551 if ((Type) && (ObjectType != Type))
1552 {
1553 /* They don't, cleanup */
1556 }
1557
1558 /* Save the object header */
1559 NewEntry.Object = ObjectHeader;
1560
1561 /* Check if this is a kernel handle */
1563 {
1564 /* Set the handle table */
1567
1568 /* Check if we're not in the system process */
1570 {
1571 /* Attach to the system process */
1573 AttachedToProcess = TRUE;
1574 }
1575 }
1576 else
1577 {
1578 /* Get the current handle table */
1579 HandleTable = PsGetCurrentProcess()->ObjectTable;
1580 }
1581
1582 /* Increment the handle count */
1585 AccessMode,
1588 OpenReason);
1589 if (!NT_SUCCESS(Status))
1590 {
1591 /*
1592 * We failed (meaning security failure, according to NT Internals)
1593 * detach and return
1594 */
1596 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1597 return Status;
1598 }
1599
1600 /* Check if we are doing audits on close */
1601 if (AccessState->GenerateOnClose)
1602 {
1603 /* Force the attribute on */
1605 }
1606
1607 /* Mask out the internal attributes */
1609
1610 /* Get the original desired access */
1611 DesiredAccess = AccessState->RemainingDesiredAccess |
1612 AccessState->PreviouslyGrantedAccess;
1613
1614 /* Remove what's not in the valid access mask */
1615 GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
1617
1618 /* Update the value in the access state */
1619 AccessState->PreviouslyGrantedAccess = GrantedAccess;
1620
1621 /* Get the auxiliary data */
1622 AuxData = AccessState->AuxData;
1623
1624 /* Handle extra references */
1625 if (AdditionalReferences)
1626 {
1627 /* Add them to the header */
1629 AdditionalReferences);
1630 }
1631
1632 /* Now we can release the object */
1634
1635 /* Save the access mask */
1636 NewEntry.GrantedAccess = GrantedAccess;
1637
1638 /*
1639 * Create the actual handle. We'll need to do this *after* calling
1640 * ObpIncrementHandleCount to make sure that Object Security is valid
1641 * (specified in Gl00my documentation on Ob)
1642 */
1644 "%s - Handle Properties: [%p-%lx-%lx]\n",
1646 NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
1647 Handle = ExCreateHandle(HandleTable, &NewEntry);
1648
1649 /* Make sure we got a handle */
1650 if (Handle)
1651 {
1652 /* Check if this was a kernel handle */
1654
1655 /* Return it */
1656 *ReturnedHandle = Handle;
1657
1658 /* Check if we need to generate on audit */
1659 if (AccessState->GenerateAudit)
1660 {
1661 /* Audit the handle creation */
1662 //SeAuditHandleCreation(AccessState, Handle);
1663 }
1664
1665 /* Check if this was a create */
1666 if (OpenReason == ObCreateHandle)
1667 {
1668 /* Check if we need to audit the privileges */
1669 if ((AuxData->PrivilegesUsed) &&
1670 (AuxData->PrivilegesUsed->PrivilegeCount))
1671 {
1672 /* Do the audit */
1673#if 0
1675 &AccessState->
1678 AuxData->PrivilegesUsed,
1679 TRUE,
1681#endif
1682 }
1683 }
1684
1685 /* Return the new object only if caller wanted it biased */
1686 if ((AdditionalReferences) && (ReturnedObject))
1687 {
1688 /* Return it */
1689 *ReturnedObject = Object;
1690 }
1691
1692 /* Detach if needed */
1693 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1694
1695 /* Trace and return */
1697 "%s - Returning Handle: %p HC PC %lx %lx\n",
1699 Handle,
1700 ObjectHeader->HandleCount,
1701 ObjectHeader->PointerCount);
1702 return STATUS_SUCCESS;
1703 }
1704
1705 /* Decrement the handle count and detach */
1706 ObpDecrementHandleCount(&ObjectHeader->Body,
1709 ObjectType);
1710
1711 /* Handle extra references */
1712 if (AdditionalReferences)
1713 {
1714 /* Check how many extra references were added */
1715 if (AdditionalReferences > 1)
1716 {
1717 /* Dereference it many times */
1719 -(LONG)(AdditionalReferences - 1));
1720 }
1721
1722 /* Dereference the object one last time */
1724 }
1725
1726 /* Detach if necessary and fail */
1727 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1729}
#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 1331 of file obhandle.c.

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

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 1982 of file obhandle.c.

1986{
1987 POBJECT_HEADER ObjectHeader;
1988 BOOLEAN Ret = FALSE;
1991 PAGED_CODE();
1992
1993 /* Make sure that the handle is inheritable */
1994 Ret = (HandleTableEntry->ObAttributes & OBJ_INHERIT) != 0;
1995 if (Ret)
1996 {
1997 /* Get the object header */
1998 ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1999
2000 /* Increment the pointer count */
2002
2003 /* Release the handle lock */
2005
2006 /* Setup the access state */
2007 AccessState.PreviouslyGrantedAccess = HandleTableEntry->GrantedAccess;
2008
2009 /* Call the shared routine for incrementing handles */
2010 Status = ObpIncrementHandleCount(&ObjectHeader->Body,
2011 &AccessState,
2012 KernelMode,
2013 HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES,
2014 Process,
2016 if (!NT_SUCCESS(Status))
2017 {
2018 /* Return failure */
2019 ObDereferenceObject(&ObjectHeader->Body);
2020 Ret = FALSE;
2021 }
2022 }
2023 else
2024 {
2025 /* Release the handle lock */
2027 }
2028
2029 /* Return duplication result */
2030 return Ret;
2031}
#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 BOOLEAN ObjectLocked;
830 PAGED_CODE();
831
832 /* Get the object header and type */
833 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
834 ObjectType = ObjectHeader->Type;
836 "%s - Incrementing count for: %p. Reason: %lx. HC PC %lx %lx\n",
838 Object,
839 OpenReason,
840 ObjectHeader->HandleCount,
841 ObjectHeader->PointerCount);
842
843 /* Check if caller is forcing user mode */
845 {
846 /* Force it */
848 }
849 else
850 {
851 /* Keep original setting */
853 }
854
855 /* Lock the object */
856 ObpAcquireObjectLock(ObjectHeader);
857 ObjectLocked = TRUE;
858
859 /* Charge quota and remove the creator info flag */
861 if (!NT_SUCCESS(Status)) goto Quickie;
862
863 /* Check if the open is exclusive */
865 {
866 /* Check if the object allows this, or if the inherit flag was given */
868 !(ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
869 {
870 /* Incorrect attempt */
872 goto Quickie;
873 }
874
875 /* Check if we have access to it */
876 ExclusiveProcess = OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader);
877 if ((!(ExclusiveProcess) && (ObjectHeader->HandleCount)) ||
878 ((ExclusiveProcess) && (ExclusiveProcess != PsGetCurrentProcess())))
879 {
880 /* This isn't the right process */
882 goto Quickie;
883 }
884
885 /* Now you got exclusive access */
886 Exclusive = TRUE;
887 }
888 else if ((ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) &&
890 {
891 /* Caller didn't want exclusive access, but the object is exclusive */
893 goto Quickie;
894 }
895
896 /* Check for exclusive kernel object */
897 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
898 if ((NameInfo) && (NameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE) &&
900 {
901 /* Caller is not kernel, but the object is kernel exclusive */
903 goto Quickie;
904 }
905
906 /*
907 * Check if this is an object that went from 0 handles back to existence,
908 * but doesn't have an open procedure, only a close procedure. This means
909 * that it will never realize that the object is back alive, so we must
910 * fail the request.
911 */
912 if (!(ObjectHeader->HandleCount) &&
913 !(NewObject) &&
914 (ObjectType->TypeInfo.MaintainHandleCount) &&
915 !(ObjectType->TypeInfo.OpenProcedure) &&
916 (ObjectType->TypeInfo.CloseProcedure))
917 {
918 /* Fail */
920 goto Quickie;
921 }
922
923 /* Check if we're opening an existing handle */
924 if ((OpenReason == ObOpenHandle) ||
925 ((OpenReason == ObDuplicateHandle) && (AccessState)))
926 {
927 /* Validate the caller's access to this object */
930 TRUE,
931 ProbeMode,
932 &Status))
933 {
934 /* Access was denied, so fail */
935 goto Quickie;
936 }
937 }
938 else if (OpenReason == ObCreateHandle)
939 {
940 /* Convert MAXIMUM_ALLOWED to GENERIC_ALL */
941 if (AccessState->RemainingDesiredAccess & MAXIMUM_ALLOWED)
942 {
943 /* Mask out MAXIMUM_ALLOWED and stick GENERIC_ALL instead */
944 AccessState->RemainingDesiredAccess &= ~MAXIMUM_ALLOWED;
945 AccessState->RemainingDesiredAccess |= GENERIC_ALL;
946 }
947
948 /* Check if we have to map the GENERIC mask */
949 if (AccessState->RemainingDesiredAccess & GENERIC_ACCESS)
950 {
951 /* Map it to the correct access masks */
952 RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
953 &ObjectType->TypeInfo.GenericMapping);
954 }
955
956 /* Check if the caller is trying to access system security */
957 if (AccessState->RemainingDesiredAccess & ACCESS_SYSTEM_SECURITY)
958 {
959 /* Client must be warranted SeSecurityPrivilege to touch SACLs */
961 {
962 /* FIXME: Generate an audit alarm, security manager must be alerted */
964 goto Quickie;
965 }
966
967 /* Privilege held, grant it so the access state reflects reality */
968 AccessState->PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
969 AccessState->RemainingDesiredAccess &= ~ACCESS_SYSTEM_SECURITY;
970 }
971 }
972
973 /* Check if this is an exclusive handle */
974 if (Exclusive)
975 {
976 /* Save the owner process */
977 OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
978 }
979
980 /* Increase the handle count */
983
984 /* Check if we have a handle database */
985 if (ObjectType->TypeInfo.MaintainHandleCount)
986 {
987 /* Increment the handle database */
988 Status = ObpIncrementHandleDataBase(ObjectHeader,
989 Process,
991 if (!NT_SUCCESS(Status))
992 {
993 /* FIXME: This should never happen for now */
994 DPRINT1("Unhandled case\n");
995 ASSERT(FALSE);
996 goto Quickie;
997 }
998 }
999
1000 /* Release the lock */
1001 ObpReleaseObjectLock(ObjectHeader);
1002 ObjectLocked = FALSE;
1003
1004 /* Check if we have an open procedure */
1006 if (ObjectType->TypeInfo.OpenProcedure)
1007 {
1008 /* Call it */
1009 ObpCalloutStart(&CalloutIrql);
1010 ACCESS_MASK GrantedAccess = AccessState ? AccessState->PreviouslyGrantedAccess : 0;
1011 Status = ObjectType->TypeInfo.OpenProcedure(OpenReason,
1012 ProbeMode,
1013 Process,
1014 Object,
1017 ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
1018
1019 /* Check if the open procedure failed */
1020 if (!NT_SUCCESS(Status))
1021 {
1022 /* FIXME: This should never happen for now */
1023 DPRINT1("Unhandled case\n");
1024 ASSERT(FALSE);
1025 goto Quickie;
1026 }
1027 }
1028
1029 /* Check if this is a create operation */
1030 if (OpenReason == ObCreateHandle)
1031 {
1032 /* Check if we have creator info */
1033 CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
1034 if (CreatorInfo)
1035 {
1036 /* We do, acquire the lock */
1038
1039 /* Insert us on the list */
1040 InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
1041
1042 /* Release the lock */
1044 }
1045 }
1046
1047 /* Increase total number of handles */
1048 Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
1049 if (Total > ObjectType->HighWaterNumberOfHandles)
1050 {
1051 /* Fixup count */
1052 ObjectType->HighWaterNumberOfHandles = Total;
1053 }
1054
1055 /* Trace call and return */
1057 "%s - Incremented count for: %p. Reason: %lx HC PC %lx %lx\n",
1059 Object,
1060 OpenReason,
1061 ObjectHeader->HandleCount,
1062 ObjectHeader->PointerCount);
1063
1064Quickie:
1065 if (ObjectLocked)
1066 {
1067 ObpReleaseObjectLock(ObjectHeader);
1068 }
1069
1070 return Status;
1071}
#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 1103 of file obhandle.c.

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

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_ ULONG Attributes
Definition: dispmprt.h:1077
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653

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 1891 of file obhandle.c.

1894{
1896
1897 /* Define the handle inheritance, using the OBJ_INHERIT attribute */
1898 if (SetHandleInfo->Information.Inherit)
1899 {
1900 /* If inheritance is not supported for this object,
1901 * fail without changing anything */
1902 POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1903 if (ObjectHeader->Type->TypeInfo.InvalidAttributes & OBJ_INHERIT)
1904 return FALSE;
1905
1906 HandleTableEntry->ObAttributes |= OBJ_INHERIT;
1907 }
1908 else
1909 {
1910 HandleTableEntry->ObAttributes &= ~OBJ_INHERIT;
1911 }
1912
1913 /* Define the handle protection, using the protect-from-close bit */
1914 if (SetHandleInfo->Information.ProtectFromClose)
1915 HandleTableEntry->GrantedAccess |= ObpAccessProtectCloseBit;
1916 else
1917 HandleTableEntry->GrantedAccess &= ~ObpAccessProtectCloseBit;
1918
1919 return TRUE;
1920}
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 3336 of file obhandle.c.

3340{
3341 OBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleAttributesContext;
3342 BOOLEAN Result, AttachedToProcess = FALSE;
3345
3346 PAGED_CODE();
3347
3348 /* Check if this is a kernel handle */
3350 {
3351 /* Use the kernel table and convert the handle */
3354
3355 /* Check if we're not in the system process */
3357 {
3358 /* Attach to the system process */
3360 AttachedToProcess = TRUE;
3361 }
3362 }
3363 else
3364 {
3365 /* Get the current process' handle table */
3366 HandleTable = PsGetCurrentProcess()->ObjectTable;
3367 }
3368
3369 /* Initialize the handle attribute context */
3370 SetHandleAttributesContext.PreviousMode = PreviousMode;
3371 SetHandleAttributesContext.Information = *HandleFlags;
3372
3373 /* Invoke the ObpSetHandleAttributes callback */
3375 Handle,
3377 (ULONG_PTR)&SetHandleAttributesContext);
3378
3379 /* Detach from the system process if needed */
3380 if (AttachedToProcess)
3382
3383 /* Return the result as an NTSTATUS value */
3385}
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:1891
KPROCESSOR_MODE PreviousMode
Definition: ob.h:111

Referenced by NtSetInformationObject().

Variable Documentation

◆ ObpKernelHandleTable