in the last days, i wrote a little program called "Handle Manager". It is based on many undocumented stuctures, definitions and API calls, so there might be still some bugs inside it.
What is the sense of the program?
Handle Manager shows you all used Handles from all Processes in the System. So you can for example see which registry keys are opened, or which files are used by a programm. You can also kill the handle by double clicking on it.
Why should i use the program?
Did you ever had the problem, that you want delete a file, but you get the error message "The file is used by a process, you cannot delete it" ? Then this program is your solution. Just click on "Enumerate Handles" and after this on search and enter the filename. After you have found the file, just make a double click on it and you can delete the file.
This is also useful, if you want to unmount a disk/ usb stick.
What should i know before i use the program?
I coded it for 32 bit, so it can have unpredictable results on 64 bit!
[All 32 bit NT OS:]
It can be dangerous to kill handles from other processes. Normaly a process does not check everytime if the handle is valid and this can cause a crash. So NEVER kill a Handle from a System process unless you know what you a doing!
[XP:]
SOLVED XP PROBLEM!
I think it is possible to write many intressting programs based on this code, so you can use the source code for what ever you want, just mention somewhere in the source code (for open source projects) or in the documentation/about dialog (for closed source projects): "This program uses NT Handle code by DarkPlayer"
Here is the code:
Code: Select all
;Written by DarkPlayer
Global FILE_TYPE.i
Global Process_TYPE.i
Global Thread_TYPE.i
Structure TypeList
Name.s
Enabled.i
Checkbox.i
EndStructure
Structure TypeListArray
Count.i
Element.TypeList[0]
EndStructure
Global *Types.TypeListArray
Select OSVersion()
Case #PB_OS_Windows_NT_4
FILE_TYPE = 23
Case #PB_OS_Windows_2000
FILE_TYPE = 26
Case #PB_OS_Windows_XP, #PB_OS_Windows_Server_2003
FILE_TYPE = 28
Case #PB_OS_Windows_Vista
FILE_TYPE = 25
EndSelect
Enumeration
#WIN_MAIN = 1
#WIN_OPTIONS
#GT_ENUM
#GT_SEARCH
#GT_OPTIONS
#GT_PROGRESS
#GT_LISTICON
#OPT_ENABLE_ALL
#OPT_DISABLE_ALL
EndEnumeration
#STATUS_INFO_LENGTH_MISMATCH = $C0000004
#STATUS_INVALID_DEVICE_REQUEST = $C0000010
#FILE_DEVICE_NAMED_PIPE = $00000011
#ProcessBasicInformation = 0
#ProcessDebugPort = 7
#ProcessWow64Information = 26
#ProcessImageFileName = 27
Structure PROCESS_BASIC_INFORMATION
Reserved1.i;
*PebBaseAddress;
Reserved2.i[2];
UniqueProcessId.i;
Reserved3.i
EndStructure
Structure UNICODE_STRING
Length.w
MaxiumLength.w
*Buffer
EndStructure
Structure OBJECT_TYPE_INFORMATION
TypeName.UNICODE_STRING
TotalNumberOfObjects.l
TotalNumberOfHandles.l
TotalPagedPoolUsage.l
TotalNonPagedPoolUsage.l
TotalNamePoolUsage.l
TotalHandleTableUsage.l
HighWaterNumberOfObjects.l
HighWaterNumberOfHandles.l
HighWaterPagedPoolUsage.l
HighWaterNonPagedPoolUsage.l
HighWaterNamePoolUsage.l
HighWaterHandleTableUsage.l
InvalidAttributes.l
GenericMapping.GENERIC_MAPPING
ValidAccessMask.l
SecurityRequired.w
MaintainHandleCount.w
PoolType.l
DefaultPagedPoolCharge.l
DefaultNonPagedPoolCharge.l
EndStructure
Enumeration
#SystemBasicInformation
#SystemProcessorInformation
#SystemPerformanceInformation
#SystemTimeOfDayInformation
#SystemNotImplemented1
#SystemProcessesAndThreadsInformation
#SystemCallCounts
#SystemConfigurationInformation
#SystemProcessorTimes
#SystemGlobalFlag
#SystemNotImplemented2
#SystemModuleInformation
#SystemLockInformation
#SystemNotImplemented3
#SystemNotImplemented4
#SystemNotImplemented5
#SystemHandleInformation
;// there are more available, but we do not need them here
EndEnumeration
;The Definition from SysInternals Forum
; Enumeration
; #ObjectBasicInformation
; #ObjectNameInformation
; #ObjectTypeInformation
; #ObjectAllInformation
; #ObjectDataInformation
; EndEnumeration
;From http://rongchaua.net/blog/c-get-object-type-number-in-windows-64-bits/
Enumeration
#ObjectBasicInformation = 0
#ObjectNameInformation = 1
#ObjectTypeInformation = 2
#ObjectAllTypesInformation = 3
#ObjectHandleInformation = 4
EndEnumeration
; Definition form ReactOS
; Enumeration ;almost all of them are not even documented on "The Undocumented Functions by NTinternals"
; #ObjectBasicInformation = 0
; #ObjectNameInformation = 1
; #ObjectTypeInformation = 2
; #ObjectTypesInformation = 3
; #ObjectHandleFlagInformation = 4
; #ObjectSessionInformation = 5
; #MaxObjectInfoClass = 6
; EndEnumeration
Enumeration
#FileDirectoryInformation=1
#FileFullDirectoryInformation
#FileBothDirectoryInformation
#FileBasicInformation
#FileStandardInformation
#FileInternalInformation
#FileEaInformation
#FileAccessInformation
#FileNameInformation
#FileRenameInformation
#FileLinkInformation
#FileNamesInformation
#FileDispositionInformation
#FilePositionInformation
#FileFullEaInformation
#FileModeInformation
#FileAlignmentInformation
#FileAllInformation
#FileAllocationInformation
#FileEndOfFileInformation
#FileAlternateNameInformation
#FileStreamInformation
#FilePipeInformation
#FilePipeLocalInformation
#FilePipeRemoteInformation
#FileMailslotQueryInformation
#FileMailslotSetInformation
#FileCompressionInformation
#FileCopyOnWriteInformation
#FileCompletionInformation
#FileMoveClusterInformation
#FileQuotaInformation
#FileReparsePointInformation
#FileNetworkOpenInformation
#FileObjectIdInformation
#FileTrackingInformation
#FileOleDirectoryInformation
#FileContentIndexInformation
#FileInheritContentIndexInformation
#FileOleInformation
#FileMaximumInformation
EndEnumeration
Structure CLIENT_ID
UniqueProcess.i;
UniqueThread.i;
EndStructure
Structure THREAD_BASIC_INFORMATION
ExitStatus.l;
TebBaseAddress.i;
ClientId.CLIENT_ID;
AffinityMask.l;
Priority.l;
BasePriority.l;
EndStructure
Enumeration
#ThreadBasicInformation
#ThreadTimes
#ThreadPriority
#ThreadBasePriority
#ThreadAffinityMask
#ThreadImpersonationToken
#ThreadDescriptorTableEntry
#ThreadEnableAlignmentFaultFixup
#ThreadEventPair
#ThreadQuerySetWin32StartAddress
#ThreadZeroTlsCell
#ThreadPerformanceCount
#ThreadAmILastThread
#ThreadIdealProcessor
#ThreadPriorityBoost
#ThreadSetTlsArrayAddress
#ThreadIsIoPending
#ThreadHideFromDebugger
#ThreadBreakOnTermination
#ThreadSwitchLegacyState
#ThreadIsTerminated
#ThreadLastSystemCall
#ThreadIoPriority
#ThreadCycleTime
#ThreadPagePriority
#ThreadActualBasePriority
#ThreadTebInformation
#ThreadCSwitchMon
EndEnumeration
Prototype.i GetVolumePathNameW(lpszFileName.p-unicode, *lpszVolumePathName, cchBufferLength.i)
Prototype.i GetVolumePathNameA(lpszFileName.p-ascii, *lpszVolumePathName, cchBufferLength.i)
CompilerIf #PB_Compiler_Unicode
Global GetVolumePathName.GetVolumePathNameW
CompilerElse
Global GetVolumePathName.GetVolumePathNameA
CompilerEndIf
Structure SYSTEM_HANDLE_TABLE_ENTRY_INFO
ProcessId.l
ObjectTypeNumber.a
Flags.a
Handle.w
*Object
GrantedAccess.l
EndStructure
Structure SYSTEM_HANDLE_INFORMATION
HandleCount.l
Handles.SYSTEM_HANDLE_TABLE_ENTRY_INFO[0]
EndStructure
Structure FILE_NAME_INFORMATION
FileNameLength.l;
FileName.w[512];
EndStructure
Macro WaitNTThread()
If WaitThread(Thread,100) = 0
KillThread(Thread)
Query\ReturnV = 1
Debug "Killed"
EndIf
EndMacro
Macro QueryThreadID()
Protected Info.THREAD_BASIC_INFORMATION
If NtQueryInformationThread_(Query\Handle,#ThreadBasicInformation, @Info, SizeOf(Info),0) = 0
CName = "ThreadID: " + StrU(Info\ClientId\UniqueThread) + " PID: " + StrU(Info\ClientId\UniqueProcess)
EndIf
EndMacro
; Macro QueryFileName()
;
; *FILE.FILE_NAME_INFORMATION = AllocateMemory(SizeOf(FILE_NAME_INFORMATION))
;
; Query\ObjectName = *FILE
;
; If *File
; Thread = CreateThread(@QueryFileThread(),@Query)
; If Thread
; WaitNTThread()
;
; If Query\ReturnV = 0 And *File\FileNameLength
; CName = PeekS(@*File\FileName[0],*File\FileNameLength,#PB_Unicode)
; EndIf
;
;
; EndIf
; FreeMemory(*File)
;
; EndIf
;
; EndMacro
Macro QueryProcessName()
Protected *MemoryStr.UNICODE_STRING
*MemoryStr = AllocateMemory(2*#MAX_PATH)
If *MemoryStr
If ZwQueryInformationProcess_(DupHandle ,#ProcessImageFileName,*MemoryStr,2*#MAX_PATH,0) = 0 And *MemoryStr\Buffer And *MemoryStr\Length
Protected ExePath.s = PeekS(*MemoryStr\Buffer,*MemoryStr\Length,#PB_Unicode)
CName = StringField(ExePath,CountString(ExePath,"\")+1,"\")
EndIf
EndIf
EndMacro
Macro QueryNTObject()
Query\ObjectName = *ObjectName
Thread = CreateThread(@QueryThread(),@Query)
If Thread
WaitNTThread()
If Query\ReturnV = 0 And *ObjectName\Buffer
CName = PeekS(*ObjectName\Buffer,*ObjectName\Length,#PB_Unicode)
EndIf
EndIf
EndMacro
Declare ProcEvents()
Procedure XPTestThread(Handle.i)
GetFileType_(Handle)
EndProcedure
Procedure AdjustToken()
Protected Token.i
If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ALL_ACCESS, @Token)
Protected LUID.q
Protected TokensAdj.TOKEN_PRIVILEGES
TokensAdj\PrivilegeCount = 1
If LookupPrivilegeValue_(0,"SeDebugPrivilege",@TokensAdj\Privileges[0]\Luid)
TokensAdj\Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
If AdjustTokenPrivileges_(Token, #False, @TokensAdj, SizeOf(TOKEN_PRIVILEGES), 0, 0)
If GetLastError_() = 0
ProcedureReturn #True
EndIf
EndIf
EndIf
EndIf
EndProcedure
Prototype EnumCallBack(PID.i, Type.s, Handle.i, Name.s, CouldAcces.i,User.i)
Structure QueryTH
Handle.i
*ObjectName.i
ReturnV.i
EndStructure
Procedure QueryThread(*Query.QueryTH) ;We need this because NtQueryObject() freezes randomly...
*Query\ReturnV = NtQueryObject_(*Query\Handle, #ObjectNameInformation, *Query\ObjectName, 255, 0)
EndProcedure
; Procedure QueryFileThread(*Query.QueryTH) ;We need this because ZwQueryInformationFile() freezes randomly...
; Protected Status.q
; *Query\ReturnV = ZwQueryInformationFile_(*Query\Handle, @STATUS, *Query\ObjectName, SizeOf(FILE_NAME_INFORMATION), #FileNameInformation)
; EndProcedure
Procedure.s ResolveObjectNumber(Obj.i)
If *Types
If Obj>0 And Obj <= *Types\Count
ProcedureReturn *Types\Element[Obj]\Name
EndIf
EndIf
ProcedureReturn Str(Obj)
EndProcedure
Procedure IsObjectEnabled(Obj.i)
If *Types
If Obj>0 And Obj <= *Types\Count
ProcedureReturn *Types\Element[Obj]\Enabled
EndIf
EndIf
ProcedureReturn #True
EndProcedure
Procedure FindStringIndex(Text.s, FindString.s, Index.i)
Protected Position = 0
Protected i.i
For i = 1 To Index
Position = FindString(Text, FindString,Position+1)
If Position = 0
ProcedureReturn 0
EndIf
Next
ProcedureReturn Position
EndProcedure
Procedure EnumerateAllHandles(Call.EnumCallBack, User)
Protected Length.i = 50
Protected *Memory.SYSTEM_HANDLE_INFORMATION = AllocateMemory(Length)
Protected PID.i
Protected i.i
Protected HTempProcess.i
Protected DupHandle.i
Protected *ObjectName.UNICODE_STRING
If *Memory
*ObjectName.UNICODE_STRING = AllocateMemory(512)
*ObjectName\MaxiumLength = 254
If *ObjectName
Repeat
Length * 2 ;There is a bug in the Windows API, Windows does not return the right size, so you have to do it that way
*Memory = ReAllocateMemory(*Memory,Length)
If *Memory
Result = NtQuerySystemInformation_(#SystemHandleInformation, *Memory, Length, 0)
EndIf
Until Result <> #STATUS_INFO_LENGTH_MISMATCH Or *Memory = 0
If Result = 0 And *Memory <> 0
SetGadgetAttribute(#GT_PROGRESS, #PB_ProgressBar_Maximum, *Memory\HandleCount) ;Remove this, if you want to use it as include
For i = 0 To *Memory\HandleCount -1
If IsObjectEnabled(*Memory\Handles[i]\ObjectTypeNumber)
If *Memory\Handles[i]\ProcessId = GetCurrentProcessId_()
DupHandle = *Memory\Handles[i]\Handle
Else
HTempProcess = OpenProcess_(#PROCESS_DUP_HANDLE,0,*Memory\Handles[i]\ProcessId)
DupHandle = 0
If HTempProcess
If DuplicateHandle_(HTempProcess, *Memory\Handles[i]\Handle, GetCurrentProcess_(), @DupHandle,0, 0, #DUPLICATE_SAME_ACCESS) = 0
DupHandle = 0
EndIf
EndIf
EndIf
Protected CName.s = ""
Protected Access.i = #True
If DupHandle
Protected Query.QueryTH
Query\Handle = DupHandle
XPError.i = #False
Protected Thread.i
If *Memory\Handles[i]\ObjectTypeNumber = FILE_TYPE
;This is somehow a crazy trick
;NtQueryObject_(*Query\Handle, #ObjectNameInformation,...) would cause a Thread freeze in the kernel
;GetFileType_() also freezes, but it is still possible to kill the thread (not like when you call NTQueryObject)
;If GetFileType_() freezes, NtQueryObject would freeze too, so just dont call it and we will not get zombie Threads
If OSVersion() = #PB_OS_Windows_XP
Thread = CreateThread(@XPTestThread(),DupHandle)
If Thread
If WaitThread(Thread,100) = 0
KillThread(Thread)
XPError = #True
EndIf
EndIf
EndIf
If XPError = #False
QueryNTObject()
If CName <> "" And GetFileType_(DupHandle) = #FILE_TYPE_DISK
Protected Position
Position = FindStringIndex(CName,"\",3)
If Position
Protected DeviceString.s = Space(128)
If GetVolumePathName(CName,@DeviceString,128)
CName = DeviceString + Mid(CName,Position+1)
EndIf
EndIf
EndIf
EndIf
ElseIf Process_TYPE And *Memory\Handles[i]\ObjectTypeNumber = Process_TYPE
QueryProcessName()
ElseIf Thread_TYPE And *Memory\Handles[i]\ObjectTypeNumber = Thread_TYPE
QueryThreadID()
Else
QueryNTObject()
EndIf
Else
CName = "Not enough rights to access this process"
Access = #False
EndIf
Call(*Memory\Handles[i]\ProcessId,ResolveObjectNumber(*Memory\Handles[i]\ObjectTypeNumber), *Memory\Handles[i]\Handle, Cname, Access,User)
If *Memory\Handles[i]\ProcessId <> GetCurrentProcessId_()
If HTempProcess
CloseHandle_(HTempProcess)
If DupHandle
CloseHandle_(DupHandle)
EndIf
EndIf
EndIf
SetGadgetState(#GT_PROGRESS, i+1) ;Remove this, if you want to use it as include
ProcEvents() ;Remove this, if you want to use it as include
EndIf
Next
MessageRequester("Ready", "Enumerated " + Str(*Memory\HandleCount) + " Handles") ;Remove this, if you want to use it as include
EndIf
FreeMemory(*ObjectName)
EndIf
FreeMemory(*Memory)
EndIf
EndProcedure
Procedure EnumerateSystemTypes()
Protected *Memory
*Memory = AllocateMemory(1024*10) ;A bug in Windows, the function does not return the needed size, so we take 10kb, should be enough
If *Memory
Protected Length.i
If ZwQueryObject_(0, #ObjectAllTypesInformation, *Memory, 10214, 0) = 0
If *Types
FreeMemory(*Types)
EndIf
If OSVersion() = #PB_OS_Windows_7
*Types = AllocateMemory(SizeOf(TypeListArray) + (PeekI(*Memory)+2) * SizeOf(TypeList))
Else
*Types = AllocateMemory(SizeOf(TypeListArray) + (PeekI(*Memory)+1) * SizeOf(TypeList))
EndIf
If *Types
*Types\Count = PeekI(*Memory)
Protected Offset = *Memory + SizeOf(Integer)
For i = 0 To PeekI(*Memory) - 1
*Item.OBJECT_TYPE_INFORMATION = Offset
If OSVersion() = #PB_OS_Windows_7 ;Not really sure about it, but i have read it and can not test ist
*Types\Element[i+2]\Name = PeekS(*Item\TypeName\Buffer,*Item\TypeName\Length,#PB_Unicode)
*Types\Element[i+2]\Enabled = #True
Else
*Types\Element[i+1]\Name = PeekS(*Item\TypeName\Buffer,*Item\TypeName\Length,#PB_Unicode)
*Types\Element[i+1]\Enabled = #True
EndIf
Offset = *Item\TypeName\Buffer + *Item\TypeName\MaxiumLength
If *Item\TypeName\MaxiumLength % 4 <> 0
OffSet + (4-*Item\TypeName\MaxiumLength % 4)
EndIf
Next
EndIf
EndIf
FreeMemory(*Memory)
EndIf
EndProcedure
Procedure.s GetPathFromPID(PID.i)
Protected HProcess.i
Protected *Memory.UNICODE_STRING
Protected Name.s = ""
Protected Size.s
Protected Position.i
Protected Library.i
If PID = 4 : ProcedureReturn "SYSTEM" : EndIf
*Memory = AllocateMemory(2*#MAX_PATH)
If *Memory
HProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION,0,PID)
If HProcess
If ZwQueryInformationProcess_(HProcess ,#ProcessImageFileName,*Memory,2*#MAX_PATH,0) = 0
Name = PeekS(*Memory\Buffer,*Memory\Length,#PB_Unicode)
Position = FindStringIndex(Name,"\",3)
If Position
Protected DeviceString.s = Space(128)
If GetVolumePathName(Name,@DeviceString,128)
Name = DeviceString + Mid(Name,Position+1)
EndIf
EndIf
EndIf
CloseHandle_(HProcess)
EndIf
FreeMemory(*Memory)
EndIf
ProcedureReturn Name
EndProcedure
Procedure KillHandle(PID.i, Handle.i)
Protected HTempProcess.i
Protected Result.i = #False
Debug PID
Debug Handle
HTempProcess = OpenProcess_(#PROCESS_DUP_HANDLE,0,PID)
If HTempProcess
If DuplicateHandle_(HTempProcess, Handle, GetCurrentProcess_(), 0,0, 0, #DUPLICATE_CLOSE_SOURCE)
MessageRequester("Information", "Killed... this time you don't have to go to jail")
Result = #True
Else
MessageRequester("Information", "Could not kill the handle, maybe try an axe?")
EndIf
CloseHandle_(HTempProcess)
EndIf
ProcedureReturn Result
EndProcedure
;- GUI Code
Procedure Enum(PID.i, Type.s, Handle.i, Name.s, CouldAcces.i,User.i)
Protected Path.s
Protected EXE.s
Path = GetPathFromPID(PID)
If Path
EXE = StringField(Path,CountString(Path,"\")+1,"\")
EndIf
AddGadgetItem(#GT_LISTICON,-1, Str(PID) + Chr(10)+ EXE +Chr(10)+ Type +Chr(10) + Str(Handle) + Chr(10) + Name)
If CouldAcces = #False
;SetGadgetItemColor(#GT_LISTICON, CountGadgetItems(#GT_LISTICON)-1,#PB_Gadget_BackColor, $BABBFF,-1)
EndIf
EndProcedure
Procedure ProcEvents()
Protected Event.i
Protected Gadget.i
Protected i.i
Protected Find.s
Protected Name.s
Event = WindowEvent()
If EventWindow() = #WIN_MAIN
If Event = #PB_Event_CloseWindow
End
ElseIf Event = #PB_Event_Gadget
Gadget = EventGadget()
If Gadget = #GT_ENUM
DisableGadget(#GT_ENUM, #True)
DisableGadget(#GT_SEARCH,#False)
ClearGadgetItems(#GT_LISTICON)
EnumerateAllHandles(@Enum(),0)
DisableGadget(#GT_ENUM, #False)
ElseIf Gadget = #GT_SEARCH
Find.s = LCase(InputRequester("Search", "What do you search?",""))
For i = 0 To CountGadgetItems(#GT_LISTICON) -1
Name = LCase(GetGadgetItemText(#GT_LISTICON,i,4))
If FindString(Name,Find,1)
SetGadgetState(#GT_LISTICON,i)
Debug "Found " + Str(i)
Break
EndIf
Next
ElseIf Gadget = #GT_LISTICON
If EventType() = #PB_EventType_LeftDoubleClick And GetGadgetState(#GT_LISTICON) <> -1
Protected Item.i = GetGadgetState(#GT_LISTICON)
Protected MSGText.s
Protected Flag.i
If Val(GetGadgetItemText(#GT_LISTICON, Item,0)) = 4
MSGText.s = "WARNING! Do you really want to kill a SYSTEM handle? This can cause a BSOD!"
Flag = #MB_ICONSTOP
Else
MSGText.s = "Do you really want to kill this handle?"
Flag = #MB_ICONWARNING
EndIf
If MessageRequester("Warning", MSGText ,#PB_MessageRequester_YesNo|Flag) = #PB_MessageRequester_Yes
If KillHandle(Val(GetGadgetItemText(#GT_LISTICON, Item,0)),Val(GetGadgetItemText(#GT_LISTICON, Item,3)))
RemoveGadgetItem(#GT_LISTICON, Item)
EndIf
EndIf
EndIf
ElseIf Gadget = #GT_OPTIONS
If IsWindow(#WIN_OPTIONS)
SetActiveWindow(#WIN_OPTIONS)
Else
If *Types
#CheckBox_Width = 150
Protected Width.i = (*Types\Count / 10) * (#CheckBox_Width+5) + 10
If *Types\Count % 10 <> 0
Width + #CheckBox_Width + 5
EndIf
OpenWindow(#WIN_OPTIONS,0,0,Width,300,"Options",#PB_Window_ScreenCentered |#PB_Window_SystemMenu)
ButtonGadget(#OPT_ENABLE_ALL, 5, 260, 100,30,"Enable All")
ButtonGadget(#OPT_DISABLE_ALL, 110, 260, 100,30,"Disable All")
For i = 1 To *Types\Count
*Types\Element[i]\Checkbox = CheckBoxGadget(#PB_Any, ((i -1) / 10) * #CheckBox_Width + 5, ((i -1) % 10) * 25 + 5, #CheckBox_Width, 25, *Types\Element[i]\Name)
SetGadgetState(*Types\Element[i]\Checkbox, *Types\Element[i]\Enabled)
Next
EndIf
EndIf
EndIf
EndIf
Else
If Event = #PB_Event_CloseWindow
CloseWindow(#WIN_OPTIONS)
ElseIf Event = #PB_Event_Gadget
Gadget = EventGadget()
If Gadget = #OPT_ENABLE_ALL
For i = 1 To *Types\Count
*Types\Element[i]\Enabled = #True
SetGadgetState(*Types\Element[i]\Checkbox,#True)
Next
ElseIf Gadget = #OPT_DISABLE_ALL
For i = 1 To *Types\Count
*Types\Element[i]\Enabled = #False
SetGadgetState(*Types\Element[i]\Checkbox,#False)
Next
Else
If *Types
For i = 1 To *Types\Count
If *Types\Element[i]\Checkbox = Gadget
*Types\Element[i]\Enabled = GetGadgetState(*Types\Element[i]\Checkbox)
EndIf
Next
EndIf
EndIf
EndIf
EndIf
EndProcedure
If IsUserAnAdmin_()
AdjustToken()
Else
MessageRequester("Warning", "You should run this program as Administrator to get access to all Handles!" ,#MB_ICONWARNING)
EndIf
EnumerateSystemTypes()
;Overwrite FILE_TYPE if we could get a better one frome the System:
If *Types
Define i.i
For i = 0 To *Types\Count - 1
If *Types\Element[i]\Name = "File"
FILE_TYPE = i
ElseIf *Types\Element[i]\Name = "Process"
Process_TYPE = i
ElseIf *Types\Element[i]\Name = "Thread"
Thread_TYPE = i
EndIf
Next
EndIf
Library = OpenLibrary(#PB_Any,"kernel32.dll")
If Library
CompilerIf #PB_Compiler_Unicode
Global GetVolumePathName.GetVolumePathNameW = GetFunction(Library,"GetVolumePathNameW")
CompilerElse
Global GetVolumePathName.GetVolumePathNameA = GetFunction(Library,"GetVolumePathNameA")
CompilerEndIf
Else
MessageRequester("Warning", "Can not load Kernel32.dll! Stopping Program" ,#MB_ICONWARNING)
End
EndIf
InitNetwork()
OpenWindow(#WIN_MAIN,0,0,640,505,"Handle Manager",#PB_Window_ScreenCentered |#PB_Window_SystemMenu)
ButtonGadget(#GT_ENUM,5,5, 630, 20, "Enumerate Handles")
ButtonGadget(#GT_SEARCH,5,30, 630, 20, "Search for Name")
DisableGadget(#GT_SEARCH,#True)
ButtonGadget(#GT_OPTIONS,5,55, 630, 20, "Options")
ProgressBarGadget(#GT_PROGRESS, 5,80, 630, 20, 0 , 100, #PB_ProgressBar_Smooth)
ListIconGadget(#GT_LISTICON, 5, 105, 630, 400, "PID",40, #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines | #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(#GT_LISTICON, 1, "PNAME", 80)
AddGadgetColumn(#GT_LISTICON, 2, "TYPE", 60)
AddGadgetColumn(#GT_LISTICON, 3, "HANDLE", 60)
AddGadgetColumn(#GT_LISTICON, 4, "NAME", 350)
Repeat
Delay(1)
ProcEvents()
ForEver