Steven Wallace : ntdll: implemented ProcessDebugFlags in NtQueryInformationProcess.

Alexandre Julliard julliard at winehq.org
Wed Mar 30 13:15:41 CDT 2011


Module: wine
Branch: master
Commit: b3369e06c73f72ea8ff53223b22668854bfd9ac7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b3369e06c73f72ea8ff53223b22668854bfd9ac7

Author: Steven Wallace <swallace at wine-patches.sdwmail.homeunix.org>
Date:   Sun Mar 27 20:20:20 2011 -0700

ntdll: implemented ProcessDebugFlags in NtQueryInformationProcess.

---

 dlls/ntdll/process.c    |   25 +++++++++++++++-
 dlls/ntdll/tests/info.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+), 1 deletions(-)

diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index b9b81ca..eff3f58 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -141,7 +141,6 @@ NTSTATUS WINAPI NtQueryInformationProcess(
     UNIMPLEMENTED_INFO_CLASS(ProcessForegroundInformation);
     UNIMPLEMENTED_INFO_CLASS(ProcessLUIDDeviceMapsEnabled);
     UNIMPLEMENTED_INFO_CLASS(ProcessBreakOnTermination);
-    UNIMPLEMENTED_INFO_CLASS(ProcessDebugFlags);
     UNIMPLEMENTED_INFO_CLASS(ProcessHandleTracing);
 
     case ProcessBasicInformation:
@@ -314,6 +313,30 @@ NTSTATUS WINAPI NtQueryInformationProcess(
         else
             ret = STATUS_INFO_LENGTH_MISMATCH;
         break;
+    case ProcessDebugFlags:
+        len = sizeof(DWORD);
+        if (ProcessInformationLength == len)
+        {
+            if (!ProcessInformation)
+                ret = STATUS_ACCESS_VIOLATION;
+            else if (!ProcessHandle)
+                ret = STATUS_INVALID_HANDLE;
+            else
+            {
+                SERVER_START_REQ(get_process_info)
+                {
+                    req->handle = wine_server_obj_handle( ProcessHandle );
+                    if ((ret = wine_server_call( req )) == STATUS_SUCCESS)
+                    {
+                        *(DWORD *)ProcessInformation = !reply->debugger_present;
+                    }
+                }
+                SERVER_END_REQ;
+            }
+        }
+        else
+            ret = STATUS_INFO_LENGTH_MISMATCH;
+        break;
     case ProcessDefaultHardErrorMode:
         len = sizeof(process_error_mode);
         if (ProcessInformationLength == len)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 774e8a1..2d5c94f 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1028,6 +1028,78 @@ static void test_query_process_debug_object_handle(int argc, char **argv)
     ok(ret, "CloseHandle failed with last error %u\n", GetLastError());
 }
 
+static void test_query_process_debug_flags(int argc, char **argv)
+{
+    DWORD debug_flags = 0xdeadbeef;
+    char cmdline[MAX_PATH];
+    PROCESS_INFORMATION pi;
+    STARTUPINFO si = { 0 };
+    NTSTATUS status;
+    BOOL ret;
+
+    sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee");
+
+    si.cb = sizeof(si);
+    ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi);
+    ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError());
+    if (!ret) return;
+
+    status = pNtQueryInformationProcess(NULL, ProcessDebugFlags,
+            NULL, 0, NULL);
+    ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
+
+    status = pNtQueryInformationProcess(NULL, ProcessDebugFlags,
+            NULL, sizeof(debug_flags), NULL);
+    ok(status == STATUS_INVALID_HANDLE || status == STATUS_ACCESS_VIOLATION || broken(status == STATUS_INVALID_INFO_CLASS) /* W7PROX64 (32-bit) */,
+            "Expected STATUS_INVALID_HANDLE, got %#x.\n", status);
+
+    status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags,
+            NULL, sizeof(debug_flags), NULL);
+    ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status);
+
+    status = pNtQueryInformationProcess(NULL, ProcessDebugFlags,
+            &debug_flags, sizeof(debug_flags), NULL);
+    ok(status == STATUS_INVALID_HANDLE || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status);
+
+    status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags,
+            &debug_flags, sizeof(debug_flags) - 1, NULL);
+    ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
+
+    status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags,
+            &debug_flags, sizeof(debug_flags) + 1, NULL);
+    ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
+
+    status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags,
+            &debug_flags, sizeof(debug_flags), NULL);
+    ok(!status || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "NtQueryInformationProcess failed, status %#x.\n", status);
+    ok(debug_flags == TRUE|| broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected flag TRUE, got %x.\n", debug_flags);
+
+    status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags,
+            &debug_flags, sizeof(debug_flags), NULL);
+    ok(!status || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "NtQueryInformationProcess failed, status %#x.\n", status);
+    ok(debug_flags == FALSE || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected flag FALSE, got %x.\n", debug_flags);
+
+    for (;;)
+    {
+        DEBUG_EVENT ev;
+
+        ret = WaitForDebugEvent(&ev, INFINITE);
+        ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
+        if (!ret) break;
+
+        if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break;
+
+        ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
+        ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
+        if (!ret) break;
+    }
+
+    ret = CloseHandle(pi.hThread);
+    ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
+    ret = CloseHandle(pi.hProcess);
+    ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
+}
+
 static void test_readvirtualmemory(void)
 {
     HANDLE process;
@@ -1411,6 +1483,10 @@ START_TEST(info)
     trace("Starting test_query_process_debug_object_handle()\n");
     test_query_process_debug_object_handle(argc, argv);
 
+    /* 0x1F ProcessDebugFlags */
+    trace("Starting test_process_debug_flags()\n");
+    test_query_process_debug_flags(argc, argv);
+
     /* belongs into it's own file */
     trace("Starting test_readvirtualmemory()\n");
     test_readvirtualmemory();




More information about the wine-cvs mailing list