Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/tests/om.c | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index d3b932bec1d..6687b8b6767 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -73,6 +73,7 @@ static NTSTATUS (WINAPI *pNtQuerySystemTime)( LARGE_INTEGER * ); static NTSTATUS (WINAPI *pRtlWaitOnAddress)( const void *, const void *, SIZE_T, const LARGE_INTEGER * ); static void (WINAPI *pRtlWakeAddressAll)( const void * ); static void (WINAPI *pRtlWakeAddressSingle)( const void * ); +static NTSTATUS (WINAPI *pNtOpenProcess)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, const CLIENT_ID * );
#define KEYEDEVENT_WAIT 0x0001 #define KEYEDEVENT_WAKE 0x0002 @@ -2034,6 +2035,56 @@ static void test_wait_on_address(void) ok(address == 0, "got %s\n", wine_dbgstr_longlong(address)); }
+static void test_process(void) +{ + OBJECT_ATTRIBUTES attr; + CLIENT_ID cid; + NTSTATUS status; + HANDLE process; + + if (!pNtOpenProcess) + { + win_skip( "NtOpenProcess not supported, skipping test\n" ); + return; + } + + InitializeObjectAttributes( &attr, NULL, 0, 0, NULL ); + + cid.UniqueProcess = 0; + cid.UniqueThread = 0; + status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, NULL, &cid ); + todo_wine ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcess returned %x\n", status ); + status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, NULL ); + todo_wine ok( status == STATUS_INVALID_PARAMETER_MIX, "NtOpenProcess returned %x\n", status ); + + cid.UniqueProcess = 0; + cid.UniqueThread = 0; + status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid ); + todo_wine ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %x\n", status ); + + cid.UniqueProcess = ULongToHandle( 0xdeadbeef ); + cid.UniqueThread = ULongToHandle( 0xdeadbeef ); + status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid ); + todo_wine ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %x\n", status ); + + cid.UniqueProcess = ULongToHandle( GetCurrentThreadId() ); + cid.UniqueThread = 0; + status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid ); + todo_wine ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %x\n", status ); + + cid.UniqueProcess = ULongToHandle( GetCurrentProcessId() ); + cid.UniqueThread = 0; + status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid ); + ok( !status, "NtOpenProcess returned %x\n", status ); + pNtClose( process ); + + cid.UniqueProcess = ULongToHandle( GetCurrentProcessId() ); + cid.UniqueThread = ULongToHandle( GetCurrentThreadId() ); + status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid ); + ok( !status, "NtOpenProcess returned %x\n", status ); + pNtClose( process ); +} + START_TEST(om) { HMODULE hntdll = GetModuleHandleA("ntdll.dll"); @@ -2082,6 +2133,7 @@ START_TEST(om) pRtlWaitOnAddress = (void *)GetProcAddress(hntdll, "RtlWaitOnAddress"); pRtlWakeAddressAll = (void *)GetProcAddress(hntdll, "RtlWakeAddressAll"); pRtlWakeAddressSingle = (void *)GetProcAddress(hntdll, "RtlWakeAddressSingle"); + pNtOpenProcess = (void *)GetProcAddress(hntdll, "NtOpenProcess");
test_case_sensitive(); test_namespace_pipe(); @@ -2096,4 +2148,5 @@ START_TEST(om) test_keyed_events(); test_null_device(); test_wait_on_address(); + test_process(); }
When appropriate, instead of STATUS_INVALID_PARAMETER.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/tests/om.c | 6 +++--- server/process.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index 6687b8b6767..4f711f6b6b8 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -2060,17 +2060,17 @@ static void test_process(void) cid.UniqueProcess = 0; cid.UniqueThread = 0; status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid ); - todo_wine ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %x\n", status ); + ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %x\n", status );
cid.UniqueProcess = ULongToHandle( 0xdeadbeef ); cid.UniqueThread = ULongToHandle( 0xdeadbeef ); status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid ); - todo_wine ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %x\n", status ); + ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %x\n", status );
cid.UniqueProcess = ULongToHandle( GetCurrentThreadId() ); cid.UniqueThread = 0; status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid ); - todo_wine ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %x\n", status ); + ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %x\n", status );
cid.UniqueProcess = ULongToHandle( GetCurrentProcessId() ); cid.UniqueThread = 0; diff --git a/server/process.c b/server/process.c index d5b9a2548cf..5b3e29e5dfd 100644 --- a/server/process.c +++ b/server/process.c @@ -778,7 +778,7 @@ struct process *get_process_from_id( process_id_t id ) struct object *obj = get_ptid_entry( id );
if (obj && obj->ops == &process_ops) return (struct process *)grab_object( obj ); - set_error( STATUS_INVALID_PARAMETER ); + set_error( STATUS_INVALID_CID ); return NULL; }
When PID is invalid, some DRMs call it with GetCurrentThreadId().
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
They don't seem to mind about the result though, and they don't seem to do anything meaningful with the buffer either. What is supposed to be exposed in it, isn't very clear anyway. Our structures definitions may be incorrect or outdated, or this API is broken on Windows too.
dlls/ntdll/debugbuffer.c | 13 +++++++++++-- dlls/ntdll/tests/rtl.c | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/debugbuffer.c b/dlls/ntdll/debugbuffer.c index 3ac765d454e..e6b16bbb880 100644 --- a/dlls/ntdll/debugbuffer.c +++ b/dlls/ntdll/debugbuffer.c @@ -114,7 +114,16 @@ NTSTATUS WINAPI RtlDestroyQueryDebugBuffer(IN PDEBUG_BUFFER iBuf)
NTSTATUS WINAPI RtlQueryProcessDebugInformation(IN ULONG iProcessId, IN ULONG iDebugInfoMask, IN OUT PDEBUG_BUFFER iBuf) { - NTSTATUS nts = STATUS_SUCCESS; + CLIENT_ID cid; + NTSTATUS status; + HANDLE process; + + cid.UniqueProcess = ULongToHandle( iProcessId ); + cid.UniqueThread = 0; + + if (FAILED(status = NtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, NULL, &cid ))) return status; + NtClose( process ); + FIXME("(%d, %x, %p): stub\n", iProcessId, iDebugInfoMask, iBuf); iBuf->InfoClassMask = iDebugInfoMask;
@@ -139,5 +148,5 @@ NTSTATUS WINAPI RtlQueryProcessDebugInformation(IN ULONG iProcessId, IN ULONG iD } TRACE("returns:%p\n", iBuf); dump_DEBUG_BUFFER(iBuf); - return nts; + return status; } diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 897be4fcd12..28dd02fd118 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -132,6 +132,24 @@ static void InitFunctionPtrs(void) ok(strlen(src) == 15, "Source must be 16 bytes long!\n"); }
+static void test_RtlQueryProcessDebugInformation(void) +{ + DEBUG_BUFFER *buffer; + NTSTATUS status; + + buffer = RtlCreateQueryDebugBuffer( 0, 0 ); + ok( buffer != NULL, "RtlCreateQueryDebugBuffer returned NULL" ); + + status = RtlQueryProcessDebugInformation( GetCurrentThreadId(), PDI_HEAPS | PDI_HEAP_BLOCKS, buffer ); + ok( status == STATUS_INVALID_CID, "RtlQueryProcessDebugInformation returned %x\n", status ); + + status = RtlQueryProcessDebugInformation( GetCurrentProcessId(), PDI_HEAPS | PDI_HEAP_BLOCKS, buffer ); + ok( !status, "RtlQueryProcessDebugInformation returned %x\n", status ); + + status = RtlDestroyQueryDebugBuffer( buffer ); + ok( !status, "RtlDestroyQueryDebugBuffer returned %x\n", status ); +} + #define COMP(str1,str2,cmplen,len) size = RtlCompareMemory(str1, str2, cmplen); \ ok(size == len, "Expected %ld, got %ld\n", size, (SIZE_T)len)
@@ -3668,6 +3686,7 @@ START_TEST(rtl) { InitFunctionPtrs();
+ test_RtlQueryProcessDebugInformation(); test_RtlCompareMemory(); test_RtlCompareMemoryUlong(); test_RtlMoveMemory();
Rémi Bernon rbernon@codeweavers.com wrote:
- if (FAILED(status = NtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, NULL, &cid ))) return status;
FAILED() is supposed to be used for something else than NTSTATUS codes.
On 11/26/20 11:00 AM, Dmitry Timoshkov wrote:
Rémi Bernon rbernon@codeweavers.com wrote:
- if (FAILED(status = NtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, NULL, &cid ))) return status;
FAILED() is supposed to be used for something else than NTSTATUS codes.
Ah right, thanks.
Some DRM call it with GetCurrentThreadId(), although they don't seem to mind about the result.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v2: Don't use FAILED for NTSTATUS. Supersedes: 196573
dlls/ntdll/debugbuffer.c | 13 +++++++++++-- dlls/ntdll/tests/rtl.c | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/debugbuffer.c b/dlls/ntdll/debugbuffer.c index 3ac765d454e..9f5d214aacb 100644 --- a/dlls/ntdll/debugbuffer.c +++ b/dlls/ntdll/debugbuffer.c @@ -114,7 +114,16 @@ NTSTATUS WINAPI RtlDestroyQueryDebugBuffer(IN PDEBUG_BUFFER iBuf)
NTSTATUS WINAPI RtlQueryProcessDebugInformation(IN ULONG iProcessId, IN ULONG iDebugInfoMask, IN OUT PDEBUG_BUFFER iBuf) { - NTSTATUS nts = STATUS_SUCCESS; + CLIENT_ID cid; + NTSTATUS status; + HANDLE process; + + cid.UniqueProcess = ULongToHandle( iProcessId ); + cid.UniqueThread = 0; + + if ((status = NtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, NULL, &cid ))) return status; + NtClose( process ); + FIXME("(%d, %x, %p): stub\n", iProcessId, iDebugInfoMask, iBuf); iBuf->InfoClassMask = iDebugInfoMask;
@@ -139,5 +148,5 @@ NTSTATUS WINAPI RtlQueryProcessDebugInformation(IN ULONG iProcessId, IN ULONG iD } TRACE("returns:%p\n", iBuf); dump_DEBUG_BUFFER(iBuf); - return nts; + return status; } diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 897be4fcd12..28dd02fd118 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -132,6 +132,24 @@ static void InitFunctionPtrs(void) ok(strlen(src) == 15, "Source must be 16 bytes long!\n"); }
+static void test_RtlQueryProcessDebugInformation(void) +{ + DEBUG_BUFFER *buffer; + NTSTATUS status; + + buffer = RtlCreateQueryDebugBuffer( 0, 0 ); + ok( buffer != NULL, "RtlCreateQueryDebugBuffer returned NULL" ); + + status = RtlQueryProcessDebugInformation( GetCurrentThreadId(), PDI_HEAPS | PDI_HEAP_BLOCKS, buffer ); + ok( status == STATUS_INVALID_CID, "RtlQueryProcessDebugInformation returned %x\n", status ); + + status = RtlQueryProcessDebugInformation( GetCurrentProcessId(), PDI_HEAPS | PDI_HEAP_BLOCKS, buffer ); + ok( !status, "RtlQueryProcessDebugInformation returned %x\n", status ); + + status = RtlDestroyQueryDebugBuffer( buffer ); + ok( !status, "RtlDestroyQueryDebugBuffer returned %x\n", status ); +} + #define COMP(str1,str2,cmplen,len) size = RtlCompareMemory(str1, str2, cmplen); \ ok(size == len, "Expected %ld, got %ld\n", size, (SIZE_T)len)
@@ -3668,6 +3686,7 @@ START_TEST(rtl) { InitFunctionPtrs();
+ test_RtlQueryProcessDebugInformation(); test_RtlCompareMemory(); test_RtlCompareMemoryUlong(); test_RtlMoveMemory();