From: Zebediah Figura Subject: [PATCH 2/3] iphlpapi: Reimplement get_pid_map() using the list_processes request. Message-Id: <20200702031814.1078606-2-zfigura@codeweavers.com> Date: Wed, 1 Jul 2020 22:18:13 -0500 In-Reply-To: <20200702031814.1078606-1-zfigura@codeweavers.com> References: <20200702031814.1078606-1-zfigura@codeweavers.com> Signed-off-by: Zebediah Figura --- dlls/iphlpapi/ipstats.c | 81 +++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 11d52d4d651..e858c1ace24 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -1887,56 +1887,65 @@ 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; NTSTATUS ret; + void *buffer = NULL, *new_buffer; + const struct process_info *process; - 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->user_len; + 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) + process = buffer; + for (i = 0; i < process_count; ++i) { - SERVER_START_REQ( next_process ) + 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; + + process = (const struct process_info *)((char *)(process + 1) + process->name_len + + process->thread_count * sizeof(struct thread_info)); } -done: - NtClose( snapshot ); + HeapFree( GetProcessHeap(), 0, buffer ); + *num_entries = process_count; return map; } -- 2.27.0