diff --git a/Makefile b/Makefile index 33cafe3..4fae77a 100644 --- a/Makefile +++ b/Makefile @@ -93,7 +93,7 @@ ipxwrapper.dll: $(IPXWRAPPER_OBJS) $(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -shared -o $@ $^ version.o -liphlpapi -lversion -lole32 -loleaut32 src/ipxwrapper_stubs.s: src/ipxwrapper_stubs.txt - perl mkstubs.pl src/ipxwrapper_stubs.txt src/ipxwrapper_stubs.s + perl mkstubs.pl src/ipxwrapper_stubs.txt src/ipxwrapper_stubs.s ipxwrapper.dll # # WSOCK32.DLL @@ -103,7 +103,7 @@ wsock32.dll: src/stubdll.o src/wsock32_stubs.o src/log.o src/common.o src/config $(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -shared -o $@ $^ src/wsock32_stubs.s: src/wsock32_stubs.txt - perl mkstubs.pl src/wsock32_stubs.txt src/wsock32_stubs.s + perl mkstubs.pl src/wsock32_stubs.txt src/wsock32_stubs.s wsock32.dll # # MSWSOCK.DLL @@ -113,7 +113,7 @@ mswsock.dll: src/stubdll.o src/mswsock_stubs.o src/log.o src/common.o src/config $(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -shared -o $@ $^ src/mswsock_stubs.s: src/mswsock_stubs.txt - perl mkstubs.pl src/mswsock_stubs.txt src/mswsock_stubs.s + perl mkstubs.pl src/mswsock_stubs.txt src/mswsock_stubs.s mswsock.dll # # DPWSOCKX.DLL @@ -123,7 +123,7 @@ dpwsockx.dll: src/directplay.o src/log.o src/dpwsockx_stubs.o src/common.o src/c $(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -shared -o $@ $^ -lwsock32 src/dpwsockx_stubs.s: src/dpwsockx_stubs.txt - perl mkstubs.pl src/dpwsockx_stubs.txt src/dpwsockx_stubs.s + perl mkstubs.pl src/dpwsockx_stubs.txt src/dpwsockx_stubs.s dpwsockx.dll # # IPXCONFIG.EXE @@ -136,7 +136,7 @@ ipxconfig.exe: $(IPXCONFIG_OBJS) $(CXX) $(CXXFLAGS) -Wl,--enable-stdcall-fixup -static-libgcc -static-libstdc++ -mwindows -o $@ $^ -liphlpapi -lcomctl32 -lws2_32 src/ipxconfig_stubs.s: src/ipxwrapper_stubs.txt - perl mkstubs.pl src/ipxconfig_stubs.txt src/ipxconfig_stubs.s + perl mkstubs.pl src/ipxconfig_stubs.txt src/ipxconfig_stubs.s ipxconfig.exe # # SHARED TARGETS diff --git a/mkstubs.pl b/mkstubs.pl index e0a7b0d..c534411 100644 --- a/mkstubs.pl +++ b/mkstubs.pl @@ -17,8 +17,8 @@ use strict; use warnings; -if(@ARGV != 2) { - print STDERR "Usage: mkdll.pl \n"; +if(@ARGV != 3) { + print STDERR "Usage: mkdll.pl \n"; exit(1); } @@ -32,8 +32,7 @@ my %DLL_INDICES = ( "wpcap.dll" => 5, ); -my $stub_file = $ARGV[0]; -my $asm_file = $ARGV[1]; +my ($stub_file, $asm_file, $dll_name) = @ARGV; open(STUBS, "<$stub_file") or die("Cannot open $stub_file: $!"); open(CODE, ">$asm_file") or die("Cannot open $asm_file: $!"); @@ -96,6 +95,17 @@ foreach my $func(@stubs) END } +my $num_funcs = (scalar @stubs); + +print CODE <<"END"; +global _NUM_STUBS +_NUM_STUBS: dd $num_funcs + +DLL_NAME: db '$dll_name', 0 +global _STUBS_DLL_NAME +_STUBS_DLL_NAME: dd DLL_NAME +END + print CODE <<"END"; section .data END @@ -122,13 +132,6 @@ foreach my $func(@stubs) END } -my $num_funcs = (scalar @stubs); - -print CODE <<"END"; -global _num_stubs -_num_stubs: dd $num_funcs -END - print CODE <<"END"; section .text END diff --git a/src/common.h b/src/common.h index cadd157..a41c731 100644 --- a/src/common.h +++ b/src/common.h @@ -42,7 +42,8 @@ extern enum ipx_log_level min_log_level; /* Defined by stubs */ extern struct FuncStats stub_fstats[]; -extern unsigned int num_stubs; +extern const unsigned int NUM_STUBS; +extern const char *STUBS_DLL_NAME; const char *w32_error(DWORD errnum); diff --git a/src/directplay.c b/src/directplay.c index e7199ca..3cf2033 100644 --- a/src/directplay.c +++ b/src/directplay.c @@ -725,7 +725,7 @@ HRESULT WINAPI SPInit(LPSPINITDATA data) { BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if(fdwReason == DLL_PROCESS_ATTACH) { - fprof_init(stub_fstats, num_stubs); + fprof_init(stub_fstats, NUM_STUBS); log_open("ipxwrapper.log"); @@ -746,7 +746,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { unload_dlls(); log_close(); - fprof_cleanup(stub_fstats, num_stubs); + fprof_cleanup(stub_fstats, NUM_STUBS); } return TRUE; diff --git a/src/ipxwrapper.c b/src/ipxwrapper.c index e495203..db62f42 100644 --- a/src/ipxwrapper.c +++ b/src/ipxwrapper.c @@ -59,11 +59,26 @@ static void init_cs(CRITICAL_SECTION *cs) } } +static HANDLE prof_thread_handle = NULL; +static HANDLE prof_thread_exit = NULL; + +static DWORD WINAPI prof_thread_main(LPVOID lpParameter) +{ + static const int PROF_INTERVAL_MS = 10000; + + while(WaitForSingleObject(prof_thread_exit, PROF_INTERVAL_MS) == WAIT_TIMEOUT) + { + fprof_report(STUBS_DLL_NAME, stub_fstats, NUM_STUBS); + } + + return 0; +} + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if(fdwReason == DLL_PROCESS_ATTACH) { - fprof_init(stub_fstats, num_stubs); + fprof_init(stub_fstats, NUM_STUBS); log_open("ipxwrapper.log"); @@ -106,6 +121,30 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) } router_init(); + + prof_thread_exit = CreateEvent(NULL, FALSE, FALSE, NULL); + if(prof_thread_exit != NULL) + { + prof_thread_handle = CreateThread( + NULL, /* lpThreadAttributes */ + 0, /* dwStackSize */ + &prof_thread_main, /* lpStartAddress */ + NULL, /* lpParameter */ + 0, /* dwCreationFlags */ + NULL); /* lpThreadId */ + + if(prof_thread_handle == NULL) + { + log_printf(LOG_ERROR, + "Unable to create prof_thread_main thread: %s", + w32_error(GetLastError())); + } + } + else{ + log_printf(LOG_ERROR, + "Unable to create prof_thread_exit event object: %s", + w32_error(GetLastError())); + } } else if(fdwReason == DLL_PROCESS_DETACH) { @@ -119,6 +158,22 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } + if(prof_thread_exit != NULL) + { + SetEvent(prof_thread_exit); + + if(prof_thread_handle != NULL) + { + WaitForSingleObject(prof_thread_handle, INFINITE); + + CloseHandle(prof_thread_handle); + prof_thread_handle = NULL; + } + + CloseHandle(prof_thread_exit); + prof_thread_exit = NULL; + } + router_cleanup(); WSACleanup(); @@ -131,6 +186,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) unload_dlls(); + fprof_report(STUBS_DLL_NAME, stub_fstats, NUM_STUBS); + log_close(); if(kernel32) @@ -139,7 +196,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) kernel32 = NULL; } - fprof_cleanup(stub_fstats, num_stubs); + fprof_cleanup(stub_fstats, NUM_STUBS); } return TRUE; diff --git a/src/stubdll.c b/src/stubdll.c index 3450bef..a6f9f0d 100644 --- a/src/stubdll.c +++ b/src/stubdll.c @@ -23,14 +23,43 @@ #include "config.h" #include "funcprof.h" +static DWORD WINAPI prof_thread_main(LPVOID lpParameter); + +static HANDLE prof_thread_handle = NULL; +static HANDLE prof_thread_exit = NULL; + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if(fdwReason == DLL_PROCESS_ATTACH) { - fprof_init(stub_fstats, num_stubs); + fprof_init(stub_fstats, NUM_STUBS); log_open("ipxwrapper.log"); min_log_level = get_main_config().log_level; + + prof_thread_exit = CreateEvent(NULL, FALSE, FALSE, NULL); + if(prof_thread_exit != NULL) + { + prof_thread_handle = CreateThread( + NULL, /* lpThreadAttributes */ + 0, /* dwStackSize */ + &prof_thread_main, /* lpStartAddress */ + NULL, /* lpParameter */ + 0, /* dwCreationFlags */ + NULL); /* lpThreadId */ + + if(prof_thread_handle == NULL) + { + log_printf(LOG_ERROR, + "Unable to create prof_thread_main thread: %s", + w32_error(GetLastError())); + } + } + else{ + log_printf(LOG_ERROR, + "Unable to create prof_thread_exit event object: %s", + w32_error(GetLastError())); + } } else if(fdwReason == DLL_PROCESS_DETACH) { @@ -44,11 +73,42 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { return TRUE; } + if(prof_thread_exit != NULL) + { + SetEvent(prof_thread_exit); + + if(prof_thread_handle != NULL) + { + WaitForSingleObject(prof_thread_handle, INFINITE); + + CloseHandle(prof_thread_handle); + prof_thread_handle = NULL; + } + + CloseHandle(prof_thread_exit); + prof_thread_exit = NULL; + } + unload_dlls(); + + fprof_report(STUBS_DLL_NAME, stub_fstats, NUM_STUBS); + log_close(); - fprof_cleanup(stub_fstats, num_stubs); + fprof_cleanup(stub_fstats, NUM_STUBS); } return TRUE; } + +static DWORD WINAPI prof_thread_main(LPVOID lpParameter) +{ + static const int PROF_INTERVAL_MS = 10000; + + while(WaitForSingleObject(prof_thread_exit, PROF_INTERVAL_MS) == WAIT_TIMEOUT) + { + fprof_report(STUBS_DLL_NAME, stub_fstats, NUM_STUBS); + } + + return 0; +}