Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- The pattern which this function used consistently fails twice before returning success with the proposed replacement implementation in patch 2/4. While NtQueryInformationProcess() is arguably returning the wrong length, in practice applications should never depend on the list of system processes or threads (and hence its length) not changing between two successive calls, so I don't think it's worth working around.
dlls/kernel32/tests/toolhelp.c | 69 +++++++++++++++++----------------- 1 file changed, 34 insertions(+), 35 deletions(-)
diff --git a/dlls/kernel32/tests/toolhelp.c b/dlls/kernel32/tests/toolhelp.c index 7d27f221965..3bc07ec84f3 100644 --- a/dlls/kernel32/tests/toolhelp.c +++ b/dlls/kernel32/tests/toolhelp.c @@ -230,45 +230,44 @@ static DWORD WINAPI get_id_thread(void* curr_pid) ok(found == FALSE, "The thread order is not strictly consistent\n");
/* Determine the order by NtQuerySystemInformation function */ - pcs_buffer = NULL; - status = pNtQuerySystemInformation(SystemProcessInformation, pcs_buffer, buf_size, &buf_size); - ok(status == STATUS_INFO_LENGTH_MISMATCH, "Failed with %x\n", status); - if (status == STATUS_INFO_LENGTH_MISMATCH) + + while ((status = NtQuerySystemInformation(SystemProcessInformation, + pcs_buffer, buf_size, &buf_size)) == STATUS_INFO_LENGTH_MISMATCH) { - pcs_buffer = HeapAlloc(GetProcessHeap(), 0, buf_size); - ok(pcs_buffer != NULL, "Unable to allocate space\n"); - found = FALSE; - matched_idx = -1; - - status = NtQuerySystemInformation(SystemProcessInformation, pcs_buffer, buf_size, &buf_size); - do { - spi = (SYSTEM_PROCESS_INFORMATION*)&pcs_buffer[pcs_offset]; - if (spi->UniqueProcessId == curr_pid) - { - found = TRUE; - break; - } - pcs_offset += spi->NextEntryOffset; - } while (spi->NextEntryOffset != 0); + free(pcs_buffer); + pcs_buffer = malloc(buf_size); + } + ok(status == STATUS_SUCCESS, "got %#x\n", status); + found = FALSE; + matched_idx = -1;
- ok(found && spi, "No process found\n"); - for (i = 0; i < spi->dwThreadCount; i++) + do + { + spi = (SYSTEM_PROCESS_INFORMATION*)&pcs_buffer[pcs_offset]; + if (spi->UniqueProcessId == curr_pid) { - tid = HandleToULong(spi->ti[i].ClientId.UniqueThread); - if (matched_idx > 0) - { - thread_traversed[matched_idx++] = tid; - if (matched_idx >= NUM_THREADS) break; - } - else if (tid == thread_ids[0]) - { - matched_idx = 0; - thread_traversed[matched_idx++] = tid; - } + found = TRUE; + break; } - } - if (pcs_buffer) - HeapFree(GetProcessHeap(), 0, pcs_buffer); + pcs_offset += spi->NextEntryOffset; + } while (spi->NextEntryOffset != 0); + + ok(found && spi, "No process found\n"); + for (i = 0; i < spi->dwThreadCount; i++) + { + tid = HandleToULong(spi->ti[i].ClientId.UniqueThread); + if (matched_idx > 0) + { + thread_traversed[matched_idx++] = tid; + if (matched_idx >= NUM_THREADS) break; + } + else if (tid == thread_ids[0]) + { + matched_idx = 0; + thread_traversed[matched_idx++] = tid; + } + } + free(pcs_buffer);
ok(matched_idx > 0, "No thread id match found\n");
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v5: Fix a crash in kernel32:process.
dlls/ntdll/unix/system.c | 177 ++++++++++++++++----------------------- server/process.c | 68 +++++++++++++++ server/protocol.def | 30 +++++++ server/trace.c | 35 ++++++++ 4 files changed, 206 insertions(+), 104 deletions(-)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 7045bc1550b..91df9bdb5f5 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -2083,132 +2083,101 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
case SystemProcessInformation: { - SYSTEM_PROCESS_INFORMATION *spi = info; - SYSTEM_PROCESS_INFORMATION *last = NULL; - HANDLE handle = 0; - WCHAR procname[1024]; - WCHAR* exename; - DWORD wlen = 0; - DWORD procstructlen = 0; + unsigned int process_count, i, j; + char *buffer = NULL; + unsigned int pos = 0;
- SERVER_START_REQ( create_snapshot ) + if (size && !(buffer = RtlAllocateHeap( GetProcessHeap(), 0, size ))) { - req->flags = SNAP_PROCESS | SNAP_THREAD; - if (!(ret = wine_server_call( req ))) handle = wine_server_ptr_handle( reply->handle ); + ret = STATUS_NO_MEMORY; + break; } - SERVER_END_REQ;
- len = 0; - while (ret == STATUS_SUCCESS) + SERVER_START_REQ( list_processes ) { - int unix_pid = -1; - SERVER_START_REQ( next_process ) - { - req->handle = wine_server_obj_handle( handle ); - req->reset = (len == 0); - wine_server_set_reply( req, procname, sizeof(procname) - sizeof(WCHAR) ); - if (!(ret = wine_server_call( req ))) - { - unix_pid = reply->unix_pid; - - /* Make sure procname is 0 terminated */ - procname[wine_server_reply_size(reply) / sizeof(WCHAR)] = 0; - - /* Get only the executable name, not the path */ - if ((exename = wcsrchr(procname, '\')) != NULL) exename++; - else exename = procname; + wine_server_set_reply( req, buffer, size ); + ret = wine_server_call( req ); + len = reply->info_size; + process_count = reply->process_count; + } + SERVER_END_REQ;
- wlen = (wcslen(exename) + 1) * sizeof(WCHAR); - procstructlen = sizeof(*spi) + wlen + ((reply->threads - 1) * sizeof(SYSTEM_THREAD_INFORMATION)); + if (ret) + { + RtlFreeHeap( GetProcessHeap(), 0, buffer ); + break; + }
- if (size >= len + procstructlen) - { - /* ftCreationTime, ftUserTime, ftKernelTime; - * vmCounters, ioCounters - */ - memset(spi, 0, sizeof(*spi)); + len = 0;
- spi->NextEntryOffset = procstructlen - wlen; - spi->dwThreadCount = reply->threads; + for (i = 0; i < process_count; i++) + { + SYSTEM_PROCESS_INFORMATION *nt_process = (SYSTEM_PROCESS_INFORMATION *)((char *)info + len); + const struct process_info *server_process; + const WCHAR *server_name, *file_part; + ULONG proc_len; + ULONG name_len = 0;
- /* spi->pszProcessName will be set later on */ + pos = (pos + 7) & ~7; + server_process = (const struct process_info *)(buffer + pos); + pos += sizeof(*server_process);
- spi->dwBasePriority = reply->priority; - spi->UniqueProcessId = UlongToHandle(reply->pid); - spi->ParentProcessId = UlongToHandle(reply->ppid); - spi->HandleCount = reply->handles; + server_name = (const WCHAR *)(buffer + pos); + file_part = server_name + (server_process->name_len / sizeof(WCHAR)); + pos += server_process->name_len; + while (file_part > server_name && file_part[-1] != '\') + { + file_part--; + name_len++; + }
- /* spi->ti will be set later on */ + proc_len = sizeof(*nt_process) + server_process->thread_count * sizeof(SYSTEM_THREAD_INFORMATION) + + (name_len + 1) * sizeof(WCHAR); + len += proc_len;
- } - len += procstructlen; - } - } - SERVER_END_REQ; - if (ret != STATUS_SUCCESS) + if (len <= size) { - if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS; - break; + memset(nt_process, 0, sizeof(*nt_process)); + if (i < process_count - 1) + nt_process->NextEntryOffset = proc_len; + nt_process->dwThreadCount = server_process->thread_count; + nt_process->dwBasePriority = server_process->priority; + nt_process->UniqueProcessId = UlongToHandle(server_process->pid); + nt_process->ParentProcessId = UlongToHandle(server_process->parent_pid); + nt_process->HandleCount = server_process->handle_count; + get_thread_times( server_process->unix_pid, -1, &nt_process->KernelTime, &nt_process->UserTime ); }
- if (size >= len) + pos = (pos + 7) & ~7; + for (j = 0; j < server_process->thread_count; j++) { - int i, j; - - get_thread_times(unix_pid, -1, &spi->KernelTime, &spi->UserTime); + const struct thread_info *server_thread = (const struct thread_info *)(buffer + pos);
- /* set thread info */ - i = j = 0; - while (ret == STATUS_SUCCESS) + if (len <= size) { - int unix_tid, pid, tid, base_pri, delta_pri; - SERVER_START_REQ( next_thread ) - { - req->handle = wine_server_obj_handle( handle ); - req->reset = (j == 0); - if (!(ret = wine_server_call( req ))) - { - unix_tid = reply->unix_tid; - pid = reply->pid; - tid = reply->tid; - base_pri = reply->base_pri; - delta_pri = reply->delta_pri; - j++; - } - } - SERVER_END_REQ; - - if (!ret) - { - if (UlongToHandle(pid) == spi->UniqueProcessId) - { - memset(&spi->ti[i], 0, sizeof(spi->ti)); - - spi->ti[i].CreateTime.QuadPart = 0xdeadbeef; - spi->ti[i].ClientId.UniqueProcess = UlongToHandle(pid); - spi->ti[i].ClientId.UniqueThread = UlongToHandle(tid); - spi->ti[i].dwCurrentPriority = base_pri + delta_pri; - spi->ti[i].dwBasePriority = base_pri; - get_thread_times(unix_pid, unix_tid, &spi->ti[i].KernelTime, &spi->ti[i].UserTime); - i++; - } - } + nt_process->ti[j].CreateTime.QuadPart = 0xdeadbeef; + nt_process->ti[j].ClientId.UniqueProcess = UlongToHandle(server_process->pid); + nt_process->ti[j].ClientId.UniqueThread = UlongToHandle(server_thread->tid); + nt_process->ti[j].dwCurrentPriority = server_thread->current_priority; + nt_process->ti[j].dwBasePriority = server_thread->base_priority; + get_thread_times( server_process->unix_pid, server_thread->unix_tid, + &nt_process->ti[j].KernelTime, &nt_process->ti[j].UserTime ); } - if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS; - - /* now append process name */ - spi->ProcessName.Buffer = (WCHAR*)((char*)spi + spi->NextEntryOffset); - spi->ProcessName.Length = wlen - sizeof(WCHAR); - spi->ProcessName.MaximumLength = wlen; - memcpy( spi->ProcessName.Buffer, exename, wlen ); - spi->NextEntryOffset += wlen; - last = spi; - spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->NextEntryOffset); + + pos += sizeof(*server_thread); + } + + if (len <= size) + { + nt_process->ProcessName.Buffer = (WCHAR *)&nt_process->ti[server_process->thread_count]; + nt_process->ProcessName.Length = name_len * sizeof(WCHAR); + nt_process->ProcessName.MaximumLength = (name_len + 1) * sizeof(WCHAR); + memcpy(nt_process->ProcessName.Buffer, file_part, name_len * sizeof(WCHAR)); + nt_process->ProcessName.Buffer[name_len] = 0; } } - if (ret == STATUS_SUCCESS && last) last->NextEntryOffset = 0; + if (len > size) ret = STATUS_INFO_LENGTH_MISMATCH; - if (handle) NtClose( handle ); break; }
diff --git a/server/process.c b/server/process.c index 283edc09c5e..db92ad3499b 100644 --- a/server/process.c +++ b/server/process.c @@ -22,6 +22,7 @@ #include "wine/port.h"
#include <assert.h> +#include <errno.h> #include <limits.h> #include <signal.h> #include <string.h> @@ -1819,3 +1820,70 @@ DECL_HANDLER(resume_process) release_object( process ); } } + +/* Get a list of processes and threads currently running */ +DECL_HANDLER(list_processes) +{ + struct process *process; + struct thread *thread; + unsigned int pos = 0; + char *buffer; + + reply->process_count = 0; + reply->info_size = 0; + + LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry ) + { + struct process_dll *exe = get_process_exe_module( process ); + reply->info_size = (reply->info_size + 7) & ~7; + reply->info_size += sizeof(struct process_info); + if (exe) reply->info_size += exe->namelen; + reply->info_size = (reply->info_size + 7) & ~7; + reply->info_size += process->running_threads * sizeof(struct thread_info); + reply->process_count++; + } + + if (reply->info_size > get_reply_max_size()) + { + set_error( STATUS_INFO_LENGTH_MISMATCH ); + return; + } + + if (!(buffer = set_reply_data_size( reply->info_size ))) return; + + memset( buffer, 0, reply->info_size ); + LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry ) + { + struct process_info *process_info; + struct process_dll *exe = get_process_exe_module( process ); + + pos = (pos + 7) & ~7; + process_info = (struct process_info *)(buffer + pos); + process_info->name_len = exe ? exe->namelen : 0; + process_info->thread_count = process->running_threads; + process_info->priority = process->priority; + process_info->pid = process->id; + process_info->parent_pid = process->parent_id; + process_info->handle_count = get_handle_table_count(process); + process_info->unix_pid = process->unix_pid; + pos += sizeof(*process_info); + + if (exe) + { + memcpy( buffer + pos, exe->filename, exe->namelen ); + pos += exe->namelen; + } + + pos = (pos + 7) & ~7; + LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry ) + { + struct thread_info *thread_info = (struct thread_info *)(buffer + pos); + + thread_info->tid = thread->id; + thread_info->base_priority = thread->priority; + thread_info->current_priority = thread->priority; /* FIXME */ + thread_info->unix_tid = thread->unix_tid; + pos += sizeof(*thread_info); + } + } +} diff --git a/server/protocol.def b/server/protocol.def index 87ec4dbd482..28227ed82d4 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1909,6 +1909,36 @@ enum char_info_mode @END
+struct thread_info +{ + thread_id_t tid; + int base_priority; + int current_priority; + int unix_tid; +}; + +struct process_info +{ + data_size_t name_len; + unsigned int thread_count; + int priority; + process_id_t pid; + process_id_t parent_pid; + unsigned int handle_count; + int unix_pid; + /* VARARG(name,unicode_str,name_len); */ + /* VARARG(threads,struct thread_info,thread_count); */ +}; + +/* Get a list of processes and threads currently running */ +@REQ(list_processes) +@REPLY + data_size_t info_size; + unsigned int process_count; + VARARG(data,process_info,info_size); +@END + + /* Wait for a debug event */ @REQ(wait_debug_event) int get_handle; /* should we alloc a handle for waiting? */ diff --git a/server/trace.c b/server/trace.c index 5b3da34872e..388ae80134c 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1115,6 +1115,41 @@ static void dump_varargs_token_groups( const char *prefix, data_size_t size ) fputc( '}', stderr ); }
+static void dump_varargs_process_info( const char *prefix, data_size_t size ) +{ + data_size_t pos = 0; + unsigned int i; + + fprintf( stderr,"%s{", prefix ); + + while (size - pos >= sizeof(struct process_info)) + { + const struct process_info *process; + pos = (pos + 7) & ~7; + process = (const struct process_info *)((const char *)cur_data + pos); + fprintf( stderr, "[thread_count=%u,priority=%d,pid=%04x,parent_pid=%04x,handle_count=%08x,unix_pid=%d,", + process->thread_count, process->priority, process->pid, + process->parent_pid, process->handle_count, process->unix_pid ); + pos += sizeof(*process); + + pos = dump_inline_unicode_string( "name=L"", pos, process->name_len, size ); + + pos = (pos + 7) & ~7; + fprintf( stderr, "",threads={" ); + for (i = 0; i < process->thread_count; i++) + { + const struct thread_info *thread = (const struct thread_info *)((const char *)cur_data + pos); + if (size - pos < sizeof(*thread)) break; + fprintf( stderr, "[tid=%04x,base_priority=%d,current_priority=%d,unix_tid=%d],", + thread->tid, thread->base_priority, thread->current_priority, thread->unix_tid ); + pos += sizeof(*thread); + } + fprintf( stderr, "}," ); + } + + fputc( '}', stderr ); +} + static void dump_varargs_object_attributes( const char *prefix, data_size_t size ) { const struct object_attributes *objattr = cur_data;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/iphlpapi/ipstats.c | 85 ++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 36 deletions(-)
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 11d52d4d651..03e53abfb44 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -1887,56 +1887,69 @@ struct pid_map
static struct pid_map *get_pid_map( unsigned int *num_entries ) { - HANDLE snapshot = NULL; struct pid_map *map; - unsigned int i = 0, count = 16, size = count * sizeof(*map); + unsigned int i = 0, map_count = 16, buffer_len = 4096, process_count, pos = 0; NTSTATUS ret; + char *buffer = NULL, *new_buffer;
- if (!(map = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL; + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, buffer_len ))) return NULL;
- SERVER_START_REQ( create_snapshot ) + for (;;) + { + SERVER_START_REQ( list_processes ) + { + wine_server_set_reply( req, buffer, buffer_len ); + ret = wine_server_call( req ); + buffer_len = reply->info_size; + process_count = reply->process_count; + } + SERVER_END_REQ; + + if (ret != STATUS_INFO_LENGTH_MISMATCH) break; + + if (!(new_buffer = HeapReAlloc( GetProcessHeap(), 0, buffer, buffer_len ))) + { + HeapFree( GetProcessHeap(), 0, buffer ); + return NULL; + } + } + + if (!(map = HeapAlloc( GetProcessHeap(), 0, map_count * sizeof(*map) ))) { - req->flags = SNAP_PROCESS; - req->attributes = 0; - if (!(ret = wine_server_call( req ))) - snapshot = wine_server_ptr_handle( reply->handle ); + HeapFree( GetProcessHeap(), 0, buffer ); + return NULL; } - SERVER_END_REQ;
- *num_entries = 0; - while (ret == STATUS_SUCCESS) + for (i = 0; i < process_count; ++i) { - SERVER_START_REQ( next_process ) + const struct process_info *process; + + pos = (pos + 7) & ~7; + process = (const struct process_info *)(buffer + pos); + + if (i >= map_count) { - req->handle = wine_server_obj_handle( snapshot ); - req->reset = (i == 0); - if (!(ret = wine_server_call( req ))) + struct pid_map *new_map; + map_count *= 2; + if (!(new_map = HeapReAlloc( GetProcessHeap(), 0, map, map_count * sizeof(*map)))) { - if (i >= count) - { - struct pid_map *new_map; - count *= 2; - size = count * sizeof(*new_map); - - if (!(new_map = HeapReAlloc( GetProcessHeap(), 0, map, size ))) - { - HeapFree( GetProcessHeap(), 0, map ); - map = NULL; - goto done; - } - map = new_map; - } - map[i].pid = reply->pid; - map[i].unix_pid = reply->unix_pid; - (*num_entries)++; - i++; + HeapFree( GetProcessHeap(), 0, map ); + HeapFree( GetProcessHeap(), 0, buffer ); + return NULL; } + map = new_map; } - SERVER_END_REQ; + + map[i].pid = process->pid; + map[i].unix_pid = process->unix_pid; + + pos += sizeof(struct process_info) + process->name_len; + pos = (pos + 7) & ~7; + pos += process->thread_count * sizeof(struct thread_info); }
-done: - NtClose( snapshot ); + HeapFree( GetProcessHeap(), 0, buffer ); + *num_entries = process_count; return map; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- server/Makefile.in | 1 - server/process.c | 30 ------ server/process.h | 10 -- server/protocol.def | 41 -------- server/snapshot.c | 223 -------------------------------------------- server/thread.c | 24 ----- server/thread.h | 8 -- 7 files changed, 337 deletions(-) delete mode 100644 server/snapshot.c
diff --git a/server/Makefile.in b/server/Makefile.in index 3f3761faab6..e90c5d1336c 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -33,7 +33,6 @@ C_SRCS = \ semaphore.c \ serial.c \ signal.c \ - snapshot.c \ sock.c \ symlink.c \ thread.c \ diff --git a/server/process.c b/server/process.c index db92ad3499b..9482da98be5 100644 --- a/server/process.c +++ b/server/process.c @@ -1086,36 +1086,6 @@ int set_process_debug_flag( struct process *process, int flag ) return write_process_memory( process, process->peb + 2, 1, &data ); }
-/* take a snapshot of currently running processes */ -struct process_snapshot *process_snap( int *count ) -{ - struct process_snapshot *snapshot, *ptr; - struct process *process; - - if (!running_processes) return NULL; - if (!(snapshot = mem_alloc( sizeof(*snapshot) * running_processes ))) - return NULL; - ptr = snapshot; - LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry ) - { - if (!process->running_threads) continue; - ptr->process = process; - ptr->threads = process->running_threads; - ptr->count = process->obj.refcount; - ptr->priority = process->priority; - ptr->handles = get_handle_table_count(process); - grab_object( process ); - ptr++; - } - - if (!(*count = ptr - snapshot)) - { - free( snapshot ); - snapshot = NULL; - } - return snapshot; -} - /* create a new process */ DECL_HANDLER(new_process) { diff --git a/server/process.h b/server/process.h index 5b83e111a6f..fb29f21cb12 100644 --- a/server/process.h +++ b/server/process.h @@ -100,15 +100,6 @@ struct process struct list kernel_object; /* list of kernel object pointers */ };
-struct process_snapshot -{ - struct process *process; /* process ptr */ - int count; /* process refcount */ - int threads; /* number of threads */ - int priority; /* priority class */ - int handles; /* number of handles */ -}; - #define CPU_FLAG(cpu) (1 << (cpu)) #define CPU_64BIT_MASK (CPU_FLAG(CPU_x86_64) | CPU_FLAG(CPU_ARM64))
@@ -137,7 +128,6 @@ extern void kill_process( struct process *process, int violent_death ); extern void kill_console_processes( struct thread *renderer, int exit_code ); extern void kill_debugged_processes( struct thread *debugger, int exit_code ); extern void detach_debugged_processes( struct thread *debugger ); -extern struct process_snapshot *process_snap( int *count ); extern void enum_processes( int (*cb)(struct process*, void*), void *user);
/* console functions */ diff --git a/server/protocol.def b/server/protocol.def index 28227ed82d4..18e4db27b4d 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1868,47 +1868,6 @@ enum char_info_mode @END
-#define SNAP_PROCESS 0x00000001 -#define SNAP_THREAD 0x00000002 -/* Create a snapshot */ -@REQ(create_snapshot) - unsigned int attributes; /* object attributes */ - unsigned int flags; /* snapshot flags (SNAP_*) */ -@REPLY - obj_handle_t handle; /* handle to the snapshot */ -@END - - -/* Get the next process from a snapshot */ -@REQ(next_process) - obj_handle_t handle; /* handle to the snapshot */ - int reset; /* reset snapshot position? */ -@REPLY - int count; /* process usage count */ - process_id_t pid; /* process id */ - process_id_t ppid; /* parent process id */ - int threads; /* number of threads */ - int priority; /* process priority */ - int handles; /* number of handles */ - int unix_pid; /* Unix pid */ - VARARG(filename,unicode_str); /* file name of main exe */ -@END - - -/* Get the next thread from a snapshot */ -@REQ(next_thread) - obj_handle_t handle; /* handle to the snapshot */ - int reset; /* reset snapshot position? */ -@REPLY - int count; /* thread usage count */ - process_id_t pid; /* process id */ - thread_id_t tid; /* thread id */ - int base_pri; /* base priority */ - int delta_pri; /* delta priority */ - int unix_tid; /* thread native pid */ -@END - - struct thread_info { thread_id_t tid; diff --git a/server/snapshot.c b/server/snapshot.c deleted file mode 100644 index bdceaef5302..00000000000 --- a/server/snapshot.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Server-side snapshots - * - * Copyright (C) 1999 Alexandre Julliard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * FIXME: heap snapshots not implemented - */ - -#include "config.h" -#include "wine/port.h" - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> - -#include "ntstatus.h" -#define WIN32_NO_STATUS -#include "windef.h" -#include "winternl.h" - -#include "handle.h" -#include "process.h" -#include "thread.h" -#include "request.h" - - -struct snapshot -{ - struct object obj; /* object header */ - struct process_snapshot *processes; /* processes snapshot */ - int process_count; /* count of processes */ - int process_pos; /* current position in proc snapshot */ - struct thread_snapshot *threads; /* threads snapshot */ - int thread_count; /* count of threads */ - int thread_pos; /* current position in thread snapshot */ -}; - -static void snapshot_dump( struct object *obj, int verbose ); -static void snapshot_destroy( struct object *obj ); - -static const struct object_ops snapshot_ops = -{ - sizeof(struct snapshot), /* size */ - snapshot_dump, /* dump */ - no_get_type, /* get_type */ - no_add_queue, /* add_queue */ - NULL, /* remove_queue */ - NULL, /* signaled */ - NULL, /* satisfied */ - no_signal, /* signal */ - no_get_fd, /* get_fd */ - no_map_access, /* map_access */ - default_get_sd, /* get_sd */ - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ - no_link_name, /* link_name */ - NULL, /* unlink_name */ - no_open_file, /* open_file */ - no_kernel_obj_list, /* get_kernel_obj_list */ - no_close_handle, /* close_handle */ - snapshot_destroy /* destroy */ -}; - - -/* create a new snapshot */ -static struct snapshot *create_snapshot( unsigned int flags ) -{ - struct snapshot *snapshot; - - if (!(snapshot = alloc_object( &snapshot_ops ))) return NULL; - - snapshot->process_pos = 0; - snapshot->process_count = 0; - if (flags & SNAP_PROCESS) - snapshot->processes = process_snap( &snapshot->process_count ); - - snapshot->thread_pos = 0; - snapshot->thread_count = 0; - if (flags & SNAP_THREAD) - snapshot->threads = thread_snap( &snapshot->thread_count ); - - return snapshot; -} - -/* get the next process in the snapshot */ -static int snapshot_next_process( struct snapshot *snapshot, struct next_process_reply *reply ) -{ - struct process_snapshot *ptr; - struct process_dll *exe_module; - - if (!snapshot->process_count) - { - set_error( STATUS_INVALID_PARAMETER ); /* FIXME */ - return 0; - } - if (snapshot->process_pos >= snapshot->process_count) - { - set_error( STATUS_NO_MORE_FILES ); - return 0; - } - ptr = &snapshot->processes[snapshot->process_pos++]; - reply->count = ptr->count; - reply->pid = get_process_id( ptr->process ); - reply->ppid = ptr->process->parent_id; - reply->threads = ptr->threads; - reply->priority = ptr->priority; - reply->handles = ptr->handles; - reply->unix_pid = ptr->process->unix_pid; - if ((exe_module = get_process_exe_module( ptr->process )) && exe_module->filename) - { - data_size_t len = min( exe_module->namelen, get_reply_max_size() ); - set_reply_data( exe_module->filename, len ); - } - return 1; -} - -/* get the next thread in the snapshot */ -static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_reply *reply ) -{ - struct thread_snapshot *ptr; - - if (!snapshot->thread_count) - { - set_error( STATUS_INVALID_PARAMETER ); /* FIXME */ - return 0; - } - if (snapshot->thread_pos >= snapshot->thread_count) - { - set_error( STATUS_NO_MORE_FILES ); - return 0; - } - ptr = &snapshot->threads[snapshot->thread_pos++]; - reply->count = ptr->count; - reply->pid = get_process_id( ptr->thread->process ); - reply->tid = get_thread_id( ptr->thread ); - reply->base_pri = ptr->priority; - reply->delta_pri = 0; /* FIXME */ - reply->unix_tid = ptr->thread->unix_tid; - return 1; -} - -static void snapshot_dump( struct object *obj, int verbose ) -{ - struct snapshot *snapshot = (struct snapshot *)obj; - assert( obj->ops == &snapshot_ops ); - fprintf( stderr, "Snapshot: %d procs %d threads\n", - snapshot->process_count, snapshot->thread_count ); -} - -static void snapshot_destroy( struct object *obj ) -{ - int i; - struct snapshot *snapshot = (struct snapshot *)obj; - assert( obj->ops == &snapshot_ops ); - if (snapshot->process_count) - { - for (i = 0; i < snapshot->process_count; i++) - release_object( snapshot->processes[i].process ); - free( snapshot->processes ); - } - if (snapshot->thread_count) - { - for (i = 0; i < snapshot->thread_count; i++) - release_object( snapshot->threads[i].thread ); - free( snapshot->threads ); - } -} - -/* create a snapshot */ -DECL_HANDLER(create_snapshot) -{ - struct snapshot *snapshot; - - reply->handle = 0; - if ((snapshot = create_snapshot( req->flags ))) - { - reply->handle = alloc_handle( current->process, snapshot, 0, req->attributes ); - release_object( snapshot ); - } -} - -/* get the next process from a snapshot */ -DECL_HANDLER(next_process) -{ - struct snapshot *snapshot; - - if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle, - 0, &snapshot_ops ))) - { - if (req->reset) snapshot->process_pos = 0; - snapshot_next_process( snapshot, reply ); - release_object( snapshot ); - } -} - -/* get the next thread from a snapshot */ -DECL_HANDLER(next_thread) -{ - struct snapshot *snapshot; - - if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle, - 0, &snapshot_ops ))) - { - if (req->reset) snapshot->thread_pos = 0; - snapshot_next_thread( snapshot, reply ); - release_object( snapshot ); - } -} diff --git a/server/thread.c b/server/thread.c index d55af204bda..9b14174578e 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1299,30 +1299,6 @@ static unsigned int get_context_system_regs( enum cpu_type cpu ) return 0; }
-/* take a snapshot of currently running threads */ -struct thread_snapshot *thread_snap( int *count ) -{ - struct thread_snapshot *snapshot, *ptr; - struct thread *thread; - int total = 0; - - LIST_FOR_EACH_ENTRY( thread, &thread_list, struct thread, entry ) - if (thread->state != TERMINATED) total++; - if (!total || !(snapshot = mem_alloc( sizeof(*snapshot) * total ))) return NULL; - ptr = snapshot; - LIST_FOR_EACH_ENTRY( thread, &thread_list, struct thread, entry ) - { - if (thread->state == TERMINATED) continue; - ptr->thread = thread; - ptr->count = thread->obj.refcount; - ptr->priority = thread->priority; - grab_object( thread ); - ptr++; - } - *count = total; - return snapshot; -} - /* gets the current impersonation token */ struct token *thread_get_impersonation_token( struct thread *thread ) { diff --git a/server/thread.h b/server/thread.h index 183f6baa0f2..650bc44628d 100644 --- a/server/thread.h +++ b/server/thread.h @@ -93,13 +93,6 @@ struct thread WCHAR *desc; /* thread description string */ };
-struct thread_snapshot -{ - struct thread *thread; /* thread ptr */ - int count; /* thread refcount */ - int priority; /* priority class */ -}; - extern struct thread *current;
/* thread functions */ @@ -125,7 +118,6 @@ extern int thread_queue_apc( struct process *process, struct thread *thread, str extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_type type ); extern int thread_add_inflight_fd( struct thread *thread, int client, int server ); extern int thread_get_inflight_fd( struct thread *thread, int client ); -extern struct thread_snapshot *thread_snap( int *count ); extern struct token *thread_get_impersonation_token( struct thread *thread ); extern int set_thread_affinity( struct thread *thread, affinity_t affinity ); extern int is_cpu_supported( enum cpu_type cpu );