]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
regress: Add tool to list open handle on windows
authorEric Bollengier <eric@baculasystems.com>
Thu, 4 Jul 2024 11:00:05 +0000 (13:00 +0200)
committerEric Bollengier <eric@baculasystems.com>
Wed, 4 Dec 2024 08:14:26 +0000 (09:14 +0100)
bacula/src/win32/tools/handle-list.cpp [new file with mode: 0644]

diff --git a/bacula/src/win32/tools/handle-list.cpp b/bacula/src/win32/tools/handle-list.cpp
new file mode 100644 (file)
index 0000000..1c1c8e2
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2000-2023 Bacula Systems SA
+   All rights reserved.
+
+   The main author of Bacula is Kern Sibbald, with contributions from many
+   others, a complete list can be found in the file AUTHORS.
+
+   Licensees holding a valid Bacula Systems SA license may use this file
+   and others of this release in accordance with the proprietary license
+   agreement provided in the LICENSE file.  Redistribution of any part of
+   this release is not permitted.
+
+   Bacula® is a registered trademark of Kern Sibbald.
+*/
+
+/* Quick code to list open handler on windows */
+
+#include <windows.h>
+#include <winternl.h>
+#include <stdio.h>
+#include <ntstatus.h>
+
+// Define NtQuerySystemInformation and SYSTEM_HANDLE_INFORMATION structures
+typedef NTSTATUS(WINAPI* PNtQuerySystemInformation)(
+    SYSTEM_INFORMATION_CLASS SystemInformationClass,
+    PVOID SystemInformation,
+    ULONG SystemInformationLength,
+    PULONG ReturnLength);
+
+typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
+    USHORT UniqueProcessId;
+    USHORT HandleValue;
+    ULONG ObjectTypeIndex;
+    ULONG HandleAttributes;
+    ULONG Object;
+    ULONG GrantedAccess;
+} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
+
+typedef NTSTATUS(WINAPI* PNtQueryObject)(
+    HANDLE Handle,
+    OBJECT_INFORMATION_CLASS ObjectInformationClass,
+    PVOID ObjectInformation,
+    ULONG ObjectInformationLength,
+    PULONG ReturnLength);
+
+static PNtQueryObject pNtQueryObject;
+static PNtQuerySystemInformation pNtQuerySystemInformation;
+void init()
+{
+    HMODULE hNtdll = LoadLibraryA("ntdll.dll");
+    if (!hNtdll) {
+        printf("Failed to load ntdll.dll\n");
+        return;
+    }
+
+    pNtQueryObject = (PNtQueryObject)GetProcAddress(hNtdll, "NtQueryObject");
+    if (!pNtQueryObject) {
+        printf("Failed to get NtQueryObject address\n");
+    }
+
+    pNtQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress(hNtdll, "NtQuerySystemInformation");
+    if (pNtQuerySystemInformation == NULL) {
+        printf("Failed to get NtQuerySystemInformation address\n");
+    }
+    FreeLibrary(hNtdll);
+
+    if (!pNtQuerySystemInformation || !pNtQueryObject) {
+       exit(1);
+    }
+}
+
+
+void PrintHandleName(HANDLE handle) {
+
+    ULONG returnLength;
+    ULONG bufferSize = 0x1000;
+    POBJECT_NAME_INFORMATION objectNameInfo = (POBJECT_NAME_INFORMATION)malloc(bufferSize);
+
+    NTSTATUS status = pNtQueryObject(handle, (OBJECT_INFORMATION_CLASS)ObjectNameInformation, objectNameInfo, bufferSize, &returnLength);
+    if (status == STATUS_INFO_LENGTH_MISMATCH) {
+        objectNameInfo = (POBJECT_NAME_INFORMATION)realloc(objectNameInfo, returnLength);
+        status = pNtQueryObject(handle, (OBJECT_INFORMATION_CLASS)ObjectNameInformation, objectNameInfo, returnLength, &returnLength);
+    }
+
+    if (status == 0) {
+        printf("Handle Name: %S\n", objectNameInfo->Name.Buffer);
+    } else {
+        printf("NtQueryObject failed with status 0x%lX\n", status);
+    }
+
+    free(objectNameInfo);
+}
+
+int main() {
+   init();
+
+    ULONG handleInfoSize = 0x10000;
+    PSYSTEM_HANDLE_INFORMATION handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
+    NTSTATUS status;
+
+    while ((status = pNtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, &handleInfoSize)) == STATUS_INFO_LENGTH_MISMATCH) {
+        handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize);
+    }
+
+    if (status != 0) {
+        printf("NtQuerySystemInformation failed with status 0x%lX\n", status);
+        free(handleInfo);
+        return 1;
+    }
+
+    DWORD currentProcessId = GetCurrentProcessId();
+    printf("Open handles inherited by process %ld:\n", currentProcessId);
+
+    for (ULONG i = 0; i < handleInfo->Count; i++) {
+        if (handleInfo->Handle[i].OwnerPid == currentProcessId) {
+           HANDLE handle = (HANDLE)(ULONG_PTR)handleInfo->Handle[i].HandleValue;
+            printf("Handle: 0x%p\n", handle);
+           PrintHandleName(handle);
+        }
+    }
+
+    free(handleInfo);
+    return 0;
+}