http://bugs.winehq.org/show_bug.cgi?id=28898
Jerome Leclanche adys.wh@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #39480|0 |1 is obsolete| |
--- Comment #99 from Jerome Leclanche adys.wh@gmail.com 2012-05-14 15:44:02 CDT --- Comment on attachment 39480 --> http://bugs.winehq.org/attachment.cgi?id=39480 Patch with modified lsof parameters.
--- a/dlls/iphlpapi/iphlpapi_main.c +++ a/dlls/iphlpapi/iphlpapi_main.c @@ -1883,15 +1883,36 @@ DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder) DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, TCP_TABLE_CLASS TableClass, ULONG Reserved) {
- DWORD table_size;
- VOID *table;
- DWORD ret;
- TRACE("pTcpTable %p, pdwSize %p, bOrder %d, ulAf %u, TableClass %u, Reserved %u\n", pTcpTable, pdwSize, bOrder, ulAf, TableClass, Reserved);
- if (ulAf == AF_INET6 || TableClass != TCP_TABLE_BASIC_ALL)
- if (!pdwSize) return ERROR_INVALID_PARAMETER;
- if (ulAf == AF_INET6) {
FIXME("ulAf = %u, TableClass = %u not supportted\n", ulAf, TableClass);
}FIXME("AF_INET6 not supported\n"); return ERROR_NOT_SUPPORTED;
- return GetTcpTable(pTcpTable, pdwSize, bOrder);
- ret = tcp_build_table(GetProcessHeap(), 0, &table, &table_size, bOrder, TableClass);
- if (!ret) {
if (!pTcpTable || *pdwSize < table_size) {
*pdwSize = table_size;
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
*pdwSize = table_size;
memcpy(pTcpTable, table, table_size);
}
HeapFree(GetProcessHeap(), 0, table);
- }
- TRACE("returning %d\n", ret);
- return ret;
}
/****************************************************************** --- a/dlls/iphlpapi/ipstats.c +++ a/dlls/iphlpapi/ipstats.c @@ -1617,15 +1617,17 @@ DWORD WINAPI AllocateAndGetUdpTableFromStack(PMIB_UDPTABLE *ppUdpTable, BOOL bOr }
-static MIB_TCPTABLE *append_tcp_row( HANDLE heap, DWORD flags, MIB_TCPTABLE *table,
DWORD *count, const MIB_TCPROW *row )
+static VOID *append_tcp_row( HANDLE heap, DWORD flags, VOID *table, DWORD *count,
const VOID *row, DWORD row_size, DWORD table_struct_size )
{
- if (table->dwNumEntries >= *count)
- DWORD dwNumEntries = *(DWORD *)table;
- if (dwNumEntries >= *count) {
MIB_TCPTABLE *new_table;
DWORD new_count = table->dwNumEntries * 2;
VOID *new_table;
DWORD new_count = dwNumEntries * 2;
if (!(new_table = HeapReAlloc( heap, flags, table, FIELD_OFFSET(MIB_TCPTABLE, table[new_count] ))))
if (!(new_table = HeapReAlloc( heap, flags, table, table_struct_size + row_size*new_count ))) { HeapFree( heap, 0, table ); return NULL;
@@ -1633,7 +1635,8 @@ static MIB_TCPTABLE *append_tcp_row( HANDLE heap, DWORD flags, MIB_TCPTABLE *tab *count = new_count; table = new_table; }
- memcpy( &table->table[table->dwNumEntries++], row, sizeof(*row) );
- memcpy( (CHAR *)table + sizeof(DWORD) + dwNumEntries*row_size, row, row_size );
- *(DWORD *)table = dwNumEntries+1; return table;
}
@@ -1674,38 +1677,34 @@ static int compare_tcp_rows(const void *a, const void *b) }
-/******************************************************************
- AllocateAndGetTcpTableFromStack (IPHLPAPI.@)
- Get the TCP connection table.
- Like GetTcpTable(), but allocate the returned table from heap.
- PARAMS
- ppTcpTable [Out] pointer into which the MIB_TCPTABLE is
allocated and returned.
- bOrder [In] whether to sort the table
- heap [In] heap from which the table is allocated
- flags [In] flags to HeapAlloc
- RETURNS
- ERROR_INVALID_PARAMETER if ppTcpTable is NULL, whatever GetTcpTable()
- returns otherwise.
- */
-DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bOrder,
HANDLE heap, DWORD flags)
+#include "wine/server.h" +#define STATUS_SUCCESS 0 +DWORD tcp_build_table(HANDLE heap, DWORD flags, VOID **table, DWORD *table_size, BOOL bOrder,
TCP_TABLE_CLASS TableClass)
{
- MIB_TCPTABLE *table;
- MIB_TCPROW row;
- DWORD ret = NO_ERROR, count = 16;
- TRACE("table %p, bOrder %d, heap %p, flags 0x%08x\n", ppTcpTable, bOrder, heap, flags);
- DWORD ret = NO_ERROR, row_size, table_struct_size;
- MIB_TCPROW_OWNER_PID row;
- DWORD count = 16;
- if (!ppTcpTable) return ERROR_INVALID_PARAMETER;
- switch(TableClass)
- {
case TCP_TABLE_BASIC_ALL:
row_size = sizeof(MIB_TCPROW);
table_struct_size = sizeof(MIB_TCPTABLE)-row_size;
break;
case TCP_TABLE_OWNER_PID_ALL:
row_size = sizeof(MIB_TCPROW_OWNER_PID);
table_struct_size = sizeof(MIB_TCPTABLE_OWNER_PID)-row_size;
break;
default:
FIXME("TableClass = %u not supported\n", TableClass);
return ERROR_NOT_SUPPORTED;
- }
- if (!(table = HeapAlloc( heap, flags, FIELD_OFFSET(MIB_TCPTABLE, table[count] ))))
- if (!(*table = HeapAlloc( heap, flags, table_struct_size+row_size*count ))) return ERROR_OUTOFMEMORY;
- table->dwNumEntries = 0;
- *(DWORD *)*table = 0;
#ifdef __linux__ { @@ -1720,13 +1719,43 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bO ptr = fgets(buf, sizeof(buf), fp); while ((ptr = fgets(buf, sizeof(buf), fp))) {
if (sscanf( ptr, "%x: %x:%x %x:%x %x", &dummy, &row.dwLocalAddr, &row.dwLocalPort,
&row.dwRemoteAddr, &row.dwRemotePort, &row.u.dwState ) != 6)
int inode;
if (sscanf( ptr, "%x: %x:%x %x:%x %x %*s %*s %*s %*s %*s %d", &dummy, &row.dwLocalAddr, &row.dwLocalPort,
&row.dwRemoteAddr, &row.dwRemotePort, &row.dwState, &inode ) != 7) continue;
if (inode)
{
char cmd[200], ret[200];
FILE *handle;
size_t r = 0;
ret[0] = 0;
snprintf(cmd, sizeof(cmd), "lsof -n +c 0 -i :%d | grep '\\.exe' | grep ' %d ' | sed 's/[^ ]* *//' | sed 's/ .*//'", row.dwRemotePort, inode);
handle = popen(cmd, "r");
while(!feof(handle))
r = fread(ret, 1, sizeof(ret), handle);
if(r)
{
int unix_pid, status;
sscanf(ret, "%d", &unix_pid);
SERVER_START_REQ( find_process )
{
req->unix_pid = unix_pid;
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
row.dwOwningPid = reply->pid;
}
SERVER_END_REQ;
+FIXME("found pid %d\n", row.dwOwningPid);
}
pclose(handle);
} row.dwLocalPort = htons( row.dwLocalPort ); row.dwRemotePort = htons( row.dwRemotePort );
row.u.State = TCPStateToMIBState( row.u.dwState );
if (!(table = append_tcp_row( heap, flags, table, &count, &row )))
row.dwState = TCPStateToMIBState( row.dwState );
if (!(*table = append_tcp_row( heap, flags, *table, &count, &row, row_size, table_struct_size ))) break; } fclose( fp );
@@ -1749,8 +1778,8 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bO row.dwLocalPort = htons( entry->tcpConnLocalPort ); row.dwRemoteAddr = entry->tcpConnRemAddress; row.dwRemotePort = htons( entry->tcpConnRemPort );
row.u.dwState = entry->tcpConnState;
if (!(table = append_tcp_row( heap, flags, table, &count, &row ))) break;
row.dwState = entry->tcpConnState;
if (!(*table = append_tcp_row( heap, flags, *table, &count, &row, row_size, table_struct_size ))) break; } HeapFree( GetProcessHeap(), 0, data ); }
@@ -1828,8 +1857,8 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bO row.dwLocalPort = pINData->inp_lport; row.dwRemoteAddr = pINData->inp_faddr.s_addr; row.dwRemotePort = pINData->inp_fport;
row.u.State = TCPStateToMIBState (pTCPData->t_state);
if (!(table = append_tcp_row( heap, flags, table, &count, &row ))) break;
row.dwState = TCPStateToMIBState (pTCPData->t_state);
if (!(*table = append_tcp_row( heap, flags, *table, &count, &row, row_size, table_struct_size ))) break; }
done:
@@ -1840,14 +1869,51 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bO ret = ERROR_NOT_SUPPORTED; #endif
- if (!table) return ERROR_OUTOFMEMORY;
- if (!*table) return ERROR_OUTOFMEMORY; if (!ret) {
if (bOrder && table->dwNumEntries)
qsort( table->table, table->dwNumEntries, sizeof(row), compare_tcp_rows );
*ppTcpTable = table;
DWORD dwNumEntries = *(DWORD *)*table;
if (bOrder && dwNumEntries)
qsort( (CHAR*)(*table) + sizeof(DWORD), dwNumEntries, row_size, compare_tcp_rows );
if (table_size)
}*table_size = table_struct_size + row_size*dwNumEntries;
- else HeapFree( heap, flags, table );
- else HeapFree( heap, flags, *table );
- return ret;
+}
+/******************************************************************
- AllocateAndGetTcpTableFromStack (IPHLPAPI.@)
- Get the TCP connection table.
- Like GetTcpTable(), but allocate the returned table from heap.
- PARAMS
- ppTcpTable [Out] pointer into which the MIB_TCPTABLE is
allocated and returned.
- bOrder [In] whether to sort the table
- heap [In] heap from which the table is allocated
- flags [In] flags to HeapAlloc
- RETURNS
- ERROR_INVALID_PARAMETER if ppTcpTable is NULL, whatever GetTcpTable()
- returns otherwise.
- */
+DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bOrder,
HANDLE heap, DWORD flags)
+{
- MIB_TCPTABLE *table;
- DWORD ret;
- TRACE("table %p, bOrder %d, heap %p, flags 0x%08x\n", ppTcpTable, bOrder, heap, flags);
- if (!ppTcpTable) return ERROR_INVALID_PARAMETER;
- ret = tcp_build_table(heap, flags, (VOID **)&table, NULL, bOrder, TCP_TABLE_BASIC_ALL);
- if (ret == NO_ERROR)
*ppTcpTable = table;
- TRACE( "returning ret %u table %p\n", ret, table ); return ret;
} --- a/dlls/iphlpapi/ipstats.h +++ a/dlls/iphlpapi/ipstats.h @@ -27,6 +27,8 @@ #include "winbase.h" #include "iprtrmib.h"
+DWORD tcp_build_table(HANDLE heap, DWORD flags, VOID **table, DWORD *table_size, BOOL bOrder, TCP_TABLE_CLASS TableClass);
/* Fills in entry's interface stats, using name to find them.
- Returns ERROR_INVALID_PARAMETER if name or entry is NULL, NO_ERROR otherwise.
*/ --- a/dlls/ws2_32/socket.c +++ a/dlls/ws2_32/socket.c @@ -1700,7 +1700,7 @@ static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS sta if (status != STATUS_PENDING) goto finish;
- return STATUS_SUCCESS;
- return STATUS_ALERTED;
finish: iosb->u.Status = status; @@ -1708,8 +1708,6 @@ finish:
if (wsa->user_overlapped->hEvent) SetEvent(wsa->user_overlapped->hEvent);
if (wsa->cvalue)
WS_AddCompletion( HANDLE2SOCKET(wsa->listen_socket), wsa->cvalue, iosb->u.Status, iosb->Information );
*apc = ws2_async_accept_apc; return status;
@@ -2040,7 +2038,9 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW req->async.callback = wine_server_client_ptr( WS2_async_accept ); req->async.iosb = wine_server_client_ptr( overlapped ); req->async.arg = wine_server_client_ptr( wsa );
/* We don't set event or completion since we may also have to read */
req->async.cvalue = cvalue;
/* We don't set event since we may also have to read, completion returns STATUS_ALERTED
} SERVER_END_REQ;* to indicate that no completion should be queued. */ status = wine_server_call( req );
--- a/include/wine/server_protocol.h +++ a/include/wine/server_protocol.h @@ -716,6 +716,20 @@ struct init_thread_reply
+struct find_process_request +{
- struct request_header __header;
- int unix_pid;
+}; +struct find_process_reply +{
- struct reply_header __header;
- process_id_t pid;
- char __pad_12[4];
+};
struct terminate_process_request { struct request_header __header; @@ -4897,6 +4911,7 @@ enum request REQ_get_startup_info, REQ_init_process_done, REQ_init_thread,
- REQ_find_process, REQ_terminate_process, REQ_terminate_thread, REQ_get_process_info,
@@ -5151,6 +5166,7 @@ union generic_request struct get_startup_info_request get_startup_info_request; struct init_process_done_request init_process_done_request; struct init_thread_request init_thread_request;
- struct find_process_request find_process_request; struct terminate_process_request terminate_process_request; struct terminate_thread_request terminate_thread_request; struct get_process_info_request get_process_info_request;
@@ -5403,6 +5419,7 @@ union generic_reply struct get_startup_info_reply get_startup_info_reply; struct init_process_done_reply init_process_done_reply; struct init_thread_reply init_thread_reply;
- struct find_process_reply find_process_reply; struct terminate_process_reply terminate_process_reply; struct terminate_thread_reply terminate_thread_reply; struct get_process_info_reply get_process_info_reply;
@@ -5646,6 +5663,6 @@ union generic_reply struct set_suspend_context_reply set_suspend_context_reply; };
-#define SERVER_PROTOCOL_VERSION 431 +#define SERVER_PROTOCOL_VERSION 432
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ --- a/server/async.c +++ a/server/async.c @@ -256,10 +256,12 @@ void async_set_result( struct object *obj, unsigned int status, unsigned int tot else { if (async->timeout) remove_timeout_user( async->timeout );
if (async->completion && async->data.cvalue && status != STATUS_ALERTED)
add_completion( async->completion, async->comp_key, async->data.cvalue, status, total );
else if (async->completion && async->data.cvalue && status == STATUS_ALERTED)
status = STATUS_SUCCESS; async->timeout = NULL; async->status = status;
if (async->completion && async->data.cvalue)
add_completion( async->completion, async->comp_key, async->data.cvalue, status, total ); if (apc) { apc_call_t data;
--- a/server/process.c +++ a/server/process.c @@ -989,6 +989,24 @@ DECL_HANDLER(new_process) release_object( info ); }
+/* Find a process from the Unix pid */ +DECL_HANDLER(find_process) +{
- struct process *process;
- int i;
- for(i=0; i<used_ptid_entries; i++)
- {
process = (struct process *) ptid_entries[i].ptr;
if (process && process->unix_pid == req->unix_pid)
{
reply->pid = get_process_id( process );
return;
}
- }
- set_error( STATUS_INVALID_PARAMETER );
+}
/* Retrieve information about a newly started process */ DECL_HANDLER(get_new_process_info) { --- a/server/protocol.def +++ a/server/protocol.def @@ -695,6 +695,14 @@ typedef union @END
+/* Find a process from the Unix pid */ +@REQ(find_process)
- int unix_pid; /* Unix pid of the process */
+@REPLY
- process_id_t pid; /* Wine process id of the process */
+@END
/* Terminate a process */ @REQ(terminate_process) obj_handle_t handle; /* process handle to terminate */ --- a/server/request.h +++ a/server/request.h @@ -117,6 +117,7 @@ DECL_HANDLER(new_thread); DECL_HANDLER(get_startup_info); DECL_HANDLER(init_process_done); DECL_HANDLER(init_thread); +DECL_HANDLER(find_process); DECL_HANDLER(terminate_process); DECL_HANDLER(terminate_thread); DECL_HANDLER(get_process_info); @@ -370,6 +371,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_get_startup_info, (req_handler)req_init_process_done, (req_handler)req_init_thread,
- (req_handler)req_find_process, (req_handler)req_terminate_process, (req_handler)req_terminate_thread, (req_handler)req_get_process_info,
@@ -696,6 +698,10 @@ C_ASSERT( FIELD_OFFSET(struct init_thread_reply, info_size) == 24 ); C_ASSERT( FIELD_OFFSET(struct init_thread_reply, version) == 28 ); C_ASSERT( FIELD_OFFSET(struct init_thread_reply, all_cpus) == 32 ); C_ASSERT( sizeof(struct init_thread_reply) == 40 ); +C_ASSERT( FIELD_OFFSET(struct find_process_request, unix_pid) == 12 ); +C_ASSERT( sizeof(struct find_process_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct find_process_reply, pid) == 8 ); +C_ASSERT( sizeof(struct find_process_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct terminate_process_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct terminate_process_request, exit_code) == 16 ); C_ASSERT( sizeof(struct terminate_process_request) == 24 ); --- a/server/trace.c +++ a/server/trace.c @@ -1100,6 +1100,16 @@ static void dump_init_thread_reply( const struct init_thread_reply *req ) fprintf( stderr, ", all_cpus=%08x", req->all_cpus ); }
+static void dump_find_process_request( const struct find_process_request *req ) +{
- fprintf( stderr, " unix_pid=%d", req->unix_pid );
+}
+static void dump_find_process_reply( const struct find_process_reply *req ) +{
- fprintf( stderr, " pid=%04x", req->pid );
+}
static void dump_terminate_process_request( const struct terminate_process_request *req ) { fprintf( stderr, " handle=%04x", req->handle ); @@ -3920,6 +3930,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_startup_info_request, (dump_func)dump_init_process_done_request, (dump_func)dump_init_thread_request,
- (dump_func)dump_find_process_request, (dump_func)dump_terminate_process_request, (dump_func)dump_terminate_thread_request, (dump_func)dump_get_process_info_request,
@@ -4170,6 +4181,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_startup_info_reply, NULL, (dump_func)dump_init_thread_reply,
- (dump_func)dump_find_process_reply, (dump_func)dump_terminate_process_reply, (dump_func)dump_terminate_thread_reply, (dump_func)dump_get_process_info_reply,
@@ -4420,6 +4432,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "get_startup_info", "init_process_done", "init_thread",
- "find_process", "terminate_process", "terminate_thread", "get_process_info",