From: Hans Leidekker hans@codeweavers.com
--- dlls/wpcap/unixlib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/wpcap/unixlib.c b/dlls/wpcap/unixlib.c index 87a37af3f96..e0675537e2c 100644 --- a/dlls/wpcap/unixlib.c +++ b/dlls/wpcap/unixlib.c @@ -176,8 +176,9 @@ static NTSTATUS wrap_dump_close( void *args )
static NTSTATUS wrap_dump_open( void *args ) { - const struct dump_open_params *params = args; - *params->ret_handle = (ULONG_PTR)pcap_dump_open( (pcap_t *)(ULONG_PTR)params->handle, params->name ); + struct dump_open_params *params = args; + if (!(*params->ret_handle = (ULONG_PTR)pcap_dump_open( (pcap_t *)(ULONG_PTR)params->handle, params->name ))) + return STATUS_NO_MEMORY; return STATUS_SUCCESS; }
From: Hans Leidekker hans@codeweavers.com
--- dlls/wpcap/wpcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c index e8b6e4193f7..a3f00c65ac3 100644 --- a/dlls/wpcap/wpcap.c +++ b/dlls/wpcap/wpcap.c @@ -309,7 +309,7 @@ void CDECL pcap_dump_close( struct dumper *dumper )
if (!dumper) return; params.handle = dumper->handle; - PCAP_CALL( dump, ¶ms ); + PCAP_CALL( dump_close, ¶ms ); free( dumper ); }
From: Hans Leidekker hans@codeweavers.com
--- dlls/wpcap/wpcap.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c index a3f00c65ac3..26372cb9e87 100644 --- a/dlls/wpcap/wpcap.c +++ b/dlls/wpcap/wpcap.c @@ -345,8 +345,6 @@ struct dumper * CDECL pcap_dump_open( struct pcap *pcap, const char *filename ) return NULL; }
- TRACE( "unix_path %s\n", debugstr_a(params.name) ); - params.handle = pcap->handle; params.ret_handle = &dumper->handle; if (PCAP_CALL( dump_open, ¶ms ))
From: Hans Leidekker hans@codeweavers.com
--- dlls/wpcap/tests/wpcap.c | 4 ++-- dlls/wpcap/unixlib.c | 8 ++++---- dlls/wpcap/unixlib.h | 2 +- dlls/wpcap/wpcap.c | 18 ++++++++++++------ 4 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/dlls/wpcap/tests/wpcap.c b/dlls/wpcap/tests/wpcap.c index 717b640a4d2..a7abf8042f6 100644 --- a/dlls/wpcap/tests/wpcap.c +++ b/dlls/wpcap/tests/wpcap.c @@ -124,7 +124,7 @@ static const char * (CDECL *ppcap_tstamp_type_val_to_name)( int );
static void CDECL capture_callback( unsigned char *user, const struct pcap_pkthdr *hdr, const unsigned char *bytes ) { - trace( "user %p hdr %p byte %p\n", user, hdr, bytes ); + trace( "user %p hdr %p bytes %p\n", user, hdr, bytes ); }
static void test_capture( void ) @@ -314,7 +314,7 @@ static void test_dump( void ) dumper = ppcap_dump_open( pcap, filename ); ok( dumper != NULL, "got NULL\n" );
- ret = ppcap_dispatch( pcap, 1, dump_callback, NULL ); + ret = ppcap_dispatch( pcap, 2, dump_callback, (unsigned char *)dumper ); ok( ret >= 0, "got %d\n", ret );
ppcap_dump_close( dumper ); diff --git a/dlls/wpcap/unixlib.c b/dlls/wpcap/unixlib.c index e0675537e2c..3c3353ac7f7 100644 --- a/dlls/wpcap/unixlib.c +++ b/dlls/wpcap/unixlib.c @@ -153,7 +153,7 @@ static NTSTATUS wrap_dump( void *args ) hdr32.ts.tv_usec = params->hdr->ts.tv_usec; hdr32.caplen = params->hdr->caplen; hdr32.len = params->hdr->len; - pcap_dump( params->user, (const struct pcap_pkthdr *)&hdr32, params->packet ); + pcap_dump( (unsigned char *)(ULONG_PTR)params->handle, (const struct pcap_pkthdr *)&hdr32, params->packet ); } else { @@ -162,7 +162,7 @@ static NTSTATUS wrap_dump( void *args ) hdr64.ts.tv_usec = params->hdr->ts.tv_usec; hdr64.caplen = params->hdr->caplen; hdr64.len = params->hdr->len; - pcap_dump( params->user, &hdr64, params->packet ); + pcap_dump( (unsigned char *)(ULONG_PTR)params->handle, &hdr64, params->packet ); } return STATUS_SUCCESS; } @@ -634,14 +634,14 @@ static NTSTATUS wow64_dump( void *args ) { struct { - PTR32 user; + UINT64 handle; PTR32 hdr; PTR32 packet; } const *params32 = args;
struct dump_params params = { - ULongToPtr(params32->user), + params32->handle, ULongToPtr(params32->hdr), ULongToPtr(params32->packet) }; diff --git a/dlls/wpcap/unixlib.h b/dlls/wpcap/unixlib.h index f8d4b41dd1a..fa821085e4d 100644 --- a/dlls/wpcap/unixlib.h +++ b/dlls/wpcap/unixlib.h @@ -133,7 +133,7 @@ struct datalink_val_to_name_params
struct dump_params { - unsigned char *user; + UINT64 handle; const struct pcap_pkthdr_win32 *hdr; const unsigned char *packet; }; diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c index 26372cb9e87..96fe737476e 100644 --- a/dlls/wpcap/wpcap.c +++ b/dlls/wpcap/wpcap.c @@ -289,18 +289,24 @@ const char * CDECL pcap_datalink_val_to_name( int link ) return (datalinks[link].name = params.buf); }
+struct dumper +{ + UINT64 handle; +}; + void CDECL pcap_dump( unsigned char *user, const struct pcap_pkthdr_win32 *hdr, const unsigned char *packet ) { - struct dump_params params = { user, hdr, packet }; + struct dump_params params; + struct dumper *dumper = (struct dumper *)user; + TRACE( "%p, %p, %p\n", user, hdr, packet ); + + params.handle = dumper->handle; + params.hdr = hdr; + params.packet = packet; PCAP_CALL( dump, ¶ms ); }
-struct dumper -{ - UINT64 handle; -}; - void CDECL pcap_dump_close( struct dumper *dumper ) { struct dump_close_params params;
From: Hans Leidekker hans@codeweavers.com
--- dlls/wpcap/unixlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wpcap/unixlib.c b/dlls/wpcap/unixlib.c index 3c3353ac7f7..b2e2537647b 100644 --- a/dlls/wpcap/unixlib.c +++ b/dlls/wpcap/unixlib.c @@ -657,7 +657,7 @@ static NTSTATUS wow64_dump_open( void *args ) PTR32 ret_handle; } const *params32 = args;
- struct datalink_val_to_name_params params = + struct dump_open_params params = { params32->handle, ULongToPtr(params32->name),
From: Hans Leidekker hans@codeweavers.com
--- dlls/wpcap/unixlib.c | 59 ++++++++++++++++++++++++++++++++++++++++---- dlls/wpcap/unixlib.h | 5 +++- dlls/wpcap/wpcap.c | 21 ++++++++++++---- 3 files changed, 74 insertions(+), 11 deletions(-)
diff --git a/dlls/wpcap/unixlib.c b/dlls/wpcap/unixlib.c index b2e2537647b..338c3a1629a 100644 --- a/dlls/wpcap/unixlib.c +++ b/dlls/wpcap/unixlib.c @@ -40,6 +40,8 @@ #include "wine/debug.h" #include "unixlib.h"
+static ULONG_PTR zero_bits = 0; + WINE_DEFAULT_DEBUG_CHANNEL(wpcap);
static NTSTATUS wrap_activate( void *args ) @@ -318,7 +320,8 @@ static NTSTATUS wrap_next_ex( void *args ) if (sizeof(void *) == 4) { struct pcap_pkthdr_win32 *hdr32; - if ((ret = pcap_next_ex( (pcap_t *)(ULONG_PTR)params->handle, (struct pcap_pkthdr **)&hdr32, params->data )) == 1) + + if ((ret = pcap_next_ex( (pcap_t *)(ULONG_PTR)params->handle, (struct pcap_pkthdr **)&hdr32, ¶ms->data )) == 1) { params->hdr->ts.tv_sec = hdr32->ts.tv_sec; params->hdr->ts.tv_usec = hdr32->ts.tv_usec; @@ -329,13 +332,33 @@ static NTSTATUS wrap_next_ex( void *args ) else { struct pcap_pkthdr *hdr64; - if ((ret = pcap_next_ex( (pcap_t *)(ULONG_PTR)params->handle, &hdr64, params->data )) == 1) + const unsigned char *data; + + if ((ret = pcap_next_ex( (pcap_t *)(ULONG_PTR)params->handle, &hdr64, &data )) == 1) { + SIZE_T size; + if (hdr64->ts.tv_sec > INT_MAX || hdr64->ts.tv_usec > INT_MAX) WARN( "truncating timeval values(s)\n" ); params->hdr->ts.tv_sec = hdr64->ts.tv_sec; params->hdr->ts.tv_usec = hdr64->ts.tv_usec; params->hdr->caplen = hdr64->caplen; params->hdr->len = hdr64->len; + + if (zero_bits && (ULONG_PTR)data > zero_bits) + { + if (params->buf && params->bufsize < hdr64->caplen) + { + size = 0; + NtFreeVirtualMemory( GetCurrentProcess(), (void **)¶ms->buf, &size, MEM_RELEASE ); + } + size = hdr64->caplen; + if (NtAllocateVirtualMemory( GetCurrentProcess(), (void **)¶ms->buf, zero_bits, &size, + MEM_COMMIT, PAGE_READWRITE )) return PCAP_ERROR; + params->bufsize = size; + memcpy( params->buf, data, hdr64->caplen ); + params->data = params->buf; + } + else params->data = data; } } return ret; @@ -484,8 +507,22 @@ static NTSTATUS wrap_tstamp_type_val_to_name( void *args ) return STATUS_SUCCESS; }
+static NTSTATUS process_attach( void *args ) +{ +#ifdef _WIN64 + if (NtCurrentTeb()->WowTebOffset) + { + SYSTEM_BASIC_INFORMATION info; + NtQuerySystemInformation( SystemEmulationBasicInformation, &info, sizeof(info), NULL ); + zero_bits = (ULONG_PTR)info.HighestUserAddress | 0x7fffffff; + } +#endif + return STATUS_SUCCESS; +} + const unixlib_entry_t __wine_unix_call_funcs[] = { + process_attach, wrap_activate, wrap_breakloop, wrap_bufsize, @@ -806,20 +843,31 @@ static NTSTATUS wow64_lookupnet( void *args )
static NTSTATUS wow64_next_ex( void *args ) { + NTSTATUS ret; + struct { UINT64 handle; PTR32 hdr; PTR32 data; - } const *params32 = args; + PTR32 buf; + UINT32 bufsize; + } *params32 = args;
struct next_ex_params params = { params32->handle, ULongToPtr(params32->hdr), - ULongToPtr(params32->data) + ULongToPtr(params32->data), + ULongToPtr(params32->buf), + params32->bufsize }; - return wrap_next_ex( ¶ms ); + ret = wrap_next_ex( ¶ms ); + + params32->data = PtrToUlong( params.data ); + params32->buf = PtrToUlong( params.buf ); + params32->bufsize = params.bufsize; + return ret; }
static NTSTATUS wow64_open_live( void *args ) @@ -952,6 +1000,7 @@ static NTSTATUS wow64_tstamp_type_val_to_name( void *args )
const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { + process_attach, wrap_activate, wrap_breakloop, wrap_bufsize, diff --git a/dlls/wpcap/unixlib.h b/dlls/wpcap/unixlib.h index fa821085e4d..e618c1c090b 100644 --- a/dlls/wpcap/unixlib.h +++ b/dlls/wpcap/unixlib.h @@ -222,7 +222,9 @@ struct next_ex_params { UINT64 handle; struct pcap_pkthdr_win32 *hdr; - const unsigned char **data; + const unsigned char *data; + unsigned char *buf; + UINT32 bufsize; };
struct open_live_params @@ -342,6 +344,7 @@ struct tstamp_type_val_to_name_params
enum pcap_funcs { + unix_process_attach, unix_activate, unix_breakloop, unix_bufsize, diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c index 96fe737476e..4f9717d5e41 100644 --- a/dlls/wpcap/wpcap.c +++ b/dlls/wpcap/wpcap.c @@ -64,6 +64,8 @@ struct pcap { UINT64 handle; struct pcap_pkthdr_win32 hdr; + unsigned char *buf; + UINT32 bufsize; char errbuf[PCAP_ERRBUF_SIZE]; };
@@ -133,12 +135,14 @@ int CDECL pcap_can_set_rfmon( struct pcap *pcap ) void CDECL pcap_close( struct pcap *pcap ) { struct close_params params; + SIZE_T size = 0;
TRACE( "%p\n", pcap );
if (!pcap) return; params.handle = pcap->handle; PCAP_CALL( close, ¶ms ); + if (pcap->buf) NtFreeVirtualMemory( GetCurrentProcess(), (void **)&pcap->buf, &size, MEM_RELEASE ); free( pcap ); }
@@ -946,10 +950,17 @@ int CDECL pcap_next_ex( struct pcap *pcap, struct pcap_pkthdr_win32 **hdr, const TRACE( "%p, %p, %p\n", pcap, hdr, data );
if (!pcap) return PCAP_ERROR; - params.handle = pcap->handle; - params.hdr = &pcap->hdr; - params.data = data; - if ((ret = PCAP_CALL( next_ex, ¶ms )) == 1) *hdr = &pcap->hdr; + params.handle = pcap->handle; + params.hdr = &pcap->hdr; + params.buf = pcap->buf; + params.bufsize = pcap->bufsize; + if ((ret = PCAP_CALL( next_ex, ¶ms )) == 1) + { + *hdr = &pcap->hdr; + *data = params.data; + pcap->buf = params.buf; + pcap->bufsize = params.bufsize; + } return ret; }
@@ -1466,7 +1477,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, void *reserved ) { DisableThreadLibraryCalls( hinst ); if (__wine_init_unix_call()) ERR( "No pcap support, expect problems\n" ); - else + else if (!PCAP_CALL( process_attach, NULL )) { char errbuf[PCAP_ERRBUF_SIZE]; struct init_params params = { PCAP_CHAR_ENC_UTF_8, errbuf };