[PATCH] [WinApi]: added a tool for server's protocol analysis
Eric Pouech
eric.pouech at wanadoo.fr
Sat Mar 25 03:49:06 CST 2006
- added winapi_server to monitor usage of server's call
across modules
A+
---
tools/winapi/server.api | 213 +++++++++++++++++++++++++++++++++++
tools/winapi/winapi_server | 268 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 481 insertions(+), 0 deletions(-)
diff --git a/tools/winapi/server.api b/tools/winapi/server.api
new file mode 100644
index 0000000..9a88e7b
--- /dev/null
+++ b/tools/winapi/server.api
@@ -0,0 +1,213 @@
+new_process ntdll process
+get_new_process_info ntdll process
+new_thread ntdll process
+get_startup_info ntdll process
+init_process_done ntdll process
+init_thread ntdll process
+terminate_process ntdll process
+terminate_thread ntdll process
+get_process_info ntdll process
+set_process_info ntdll process
+get_thread_info ntdll process
+set_thread_info ntdll process
+get_dll_info ntdll dll
+suspend_thread ntdll process
+resume_thread ntdll process
+load_dll ntdll dll
+unload_dll ntdll dll
+queue_apc ntdll ipc
+get_apc ntdll ipc
+close_handle ntdll ipc
+set_handle_info ntdll handle
+dup_handle ntdll handle
+open_process ntdll process
+open_thread ntdll process
+select ntdll ipc
+create_event ntdll ipc
+event_op ntdll ipc
+open_event ntdll ipc
+create_mutex ntdll ipc
+release_mutex ntdll ipc
+open_mutex ntdll ipc
+create_semaphore ntdll ipc
+release_semaphore ntdll ipc
+open_semaphore ntdll ipc
+create_file ntdll file
+alloc_file_handle ntdll file
+get_handle_fd ntdll handle
+flush_file ntdll file
+lock_file ntdll file
+unlock_file ntdll file
+unmount_device ntdll file
+create_socket ntdll socket
+accept_socket ntdll socket
+set_socket_event ntdll socket
+get_socket_event ntdll socket
+enable_socket_event ntdll socket
+set_socket_deferred ntdll socket
+create_mapping ntdll process
+open_mapping ntdll process
+get_mapping_info ntdll process
+create_snapshot ntdll process
+next_process ntdll process
+next_thread ntdll process
+next_module ntdll process
+wait_debug_event ntdll debug
+queue_exception_event ntdll debug
+get_exception_status ntdll debug
+output_debug_string ntdll debug
+continue_debug_event ntdll debug
+debug_process ntdll debug
+debug_break ntdll debug
+set_debugger_kill_on_exit ntdll debug
+read_process_memory ntdll process
+write_process_memory ntdll process
+create_key ntdll registry
+open_key ntdll registry
+delete_key ntdll registry
+flush_key ntdll registry
+enum_key ntdll registry
+set_key_value ntdll registry
+get_key_value ntdll registry
+enum_key_value ntdll registry
+delete_key_value ntdll registry
+load_registry ntdll registry
+unload_registry ntdll registry
+save_registry ntdll registry
+set_registry_notification ntdll registry
+create_timer ntdll misc
+open_timer ntdll misc
+set_timer ntdll misc
+cancel_timer ntdll misc
+get_timer_info ntdll misc
+get_thread_context ntdll process
+set_thread_context ntdll process
+get_selector_entry ntdll process
+add_atom ntdll misc
+delete_atom ntdll misc
+find_atom ntdll misc
+get_atom_information ntdll misc
+set_atom_information ntdll misc
+empty_atom_table ntdll misc
+init_atom_table ntdll misc
+get_serial_info ntdll serial
+set_serial_info ntdll serial
+register_async ntdll ipc
+cancel_async ntdll ipc
+create_named_pipe ntdll ipc
+open_named_pipe ntdll ipc
+connect_named_pipe ntdll ipc
+wait_named_pipe ntdll ipc
+disconnect_named_pipe ntdll ipc
+get_named_pipe_info ntdll ipc
+open_token ntdll token
+query_virtual_memory_info ntdll process
+adjust_token_privileges ntdll token
+get_token_privileges ntdll token
+check_token_privileges ntdll token
+duplicate_token ntdll token
+access_check ntdll token
+create_mailslot ntdll ipc
+open_mailslot ntdll ipc
+set_mailslot_info ntdll ipc
+get_token_user ntdll token
+set_handle_fd ntdll handle
+open_directory ntdll om
+create_directory ntdll om
+open_symlink ntdll om
+create_symlink ntdll om
+query_symlink ntdll om
+open_file_object ntdll om
+read_directory_changes ntdll file
+read_change ntdll file
+alloc_console wineconsole console
+free_console kernel console
+get_console_renderer_events wineconsole console
+open_console kernel,wineconsole console
+get_console_wait_event kernel console
+get_console_mode kernel console
+set_console_mode kernel console
+set_console_input_info kernel,wineconsole console
+get_console_input_info kernel,wineconsole console
+append_console_input_history kernel console
+get_console_input_history kernel console
+create_console_output kernel,wineconsole console
+set_console_output_info kernel,wineconsole console
+get_console_output_info kernel,wineconsole console
+write_console_input kernel console
+read_console_input kernel console
+write_console_output kernel console
+fill_console_output kernel console
+read_console_output kernel,wineconsole console
+move_console_output kernel console
+send_console_signal kernel console
+get_msg_queue user message
+set_queue_mask user message
+get_queue_status user message
+wait_input_idle user message
+send_message user,x11drv message
+get_message user message
+reply_message user message
+accept_hardware_message user message
+get_message_reply user message
+set_win_timer user message
+kill_win_timer user message
+create_window user window
+destroy_window user window
+set_window_owner user window
+get_window_info user window
+set_window_info user window
+set_parent user,x11drv window
+get_window_parents user window
+get_window_children user window
+get_window_children_from_point user window
+get_window_tree user window
+set_window_pos x11drv window
+get_window_rectangles user window
+get_window_text user window
+set_window_text user window
+get_windows_offset user window
+get_visible_region x11drv window
+get_window_region user window
+set_window_region user window
+get_update_region user window
+update_window_zorder x11drv window
+redraw_window user window
+set_window_property user window
+remove_window_property user window
+get_window_property user window
+get_window_properties user window
+create_winstation user window
+open_winstation user window
+close_winstation user window
+get_process_winstation user window
+set_process_winstation user window
+create_desktop user window
+open_desktop user window
+close_desktop user window
+get_thread_desktop user window
+set_thread_desktop user window
+set_user_object_info user window
+attach_thread_input user window
+get_thread_input user window
+get_last_input_time user window
+get_key_state user window
+set_key_state user window
+set_foreground_window user window
+set_focus_window user window
+set_active_window user window
+set_capture_window user,x11drv window
+set_caret_window user window
+set_caret_info user window
+set_hook user window
+remove_hook user window
+start_hook_chain user window
+finish_hook_chain user window
+get_next_hook user window
+create_class user window
+destroy_class user window
+set_class_info user window
+set_clipboard_info user,x11drv window
+set_global_windows user window
+get_desktop_window user window
+post_quit_message user window
diff --git a/tools/winapi/winapi_server b/tools/winapi/winapi_server
new file mode 100755
index 0000000..d8faba7
--- /dev/null
+++ b/tools/winapi/winapi_server
@@ -0,0 +1,268 @@
+#!/usr/bin/perl -w
+
+# Copyright 2005-2006 Eric Pouech
+#
+# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+use strict;
+
+my @files;
+
+my $data_file = 'server.api';
+
+sub is_in_list()
+{
+ my ($list, $name) = @_;
+
+ return 0 if (!defined($list));
+ # FIXME: this test is not so right... we should check the ,
+ # as we only get ntdll kernel user x11drv winsock as DLL names
+ # it should be just fine
+ return index($list, $name) != -1;
+}
+
+sub file_in_cmd_dir()
+{
+ my ($file) = @_;
+ my $idx = rindex($0, '/');
+ return $file if ($idx == -1);
+ return substr($0, 0, $idx + 1) . $file;
+}
+
+# grabs the list of source files (actually *.c) in Wine source tree
+sub browse_tree()
+{
+ my ($dlldir) = @_;
+
+ opendir(DIR, $dlldir) || die "can't opendir $dlldir: $!";
+ foreach my $sdir (sort readdir(DIR))
+ {
+ my $dir = "$dlldir/$sdir";
+
+ next if (! -d $dir);
+ opendir(SDIR, $dir) || die "can't opendir $dir: $!";
+ foreach my $file (sort readdir(SDIR))
+ {
+ push @files, "$dir/$file" if ($file =~ /^.*\.c$/);
+ }
+ closedir(SDIR);
+ }
+ closedir(DIR);
+}
+
+# list, for each server call, in which DLL this server call is used
+sub calls_by_dlls()
+{
+ my %out;
+ foreach my $file (@files)
+ {
+ open F, "<$file" || die "can't open $file: $!";
+ my ($dlldir, $sdir, $lfile) = split /\//, $file;
+ while (<F>)
+ {
+ if ($_ =~ /SERVER_START_REQ[ \t]*\([ \t]*([^ ^\t]*)[ \t]*\)/g)
+ {
+ if (!&is_in_list($out{$1}, $sdir))
+ {
+ $out{$1} .= ',' if (defined $out{$1});
+ $out{$1} .= $sdir;
+ }
+ }
+ }
+ close F;
+ }
+ foreach my $k (sort keys %out)
+ {
+ printf("%-30s -> $out{$k}\n", $k);
+ }
+ return 1;
+}
+
+# parse and return a hash of allowed DLL per server call
+sub load_api_data()
+{
+ my ($file) = @_;
+ my %data;
+
+ open F, "<$file" || die "can't open $file: $!";
+ while (<F>)
+ {
+ if ($_ =~ /([_a-z]+)[ \t]+(.*)[ \t]+(.*)/)
+ {
+ $data{$1} = $2;
+ }
+ else
+ {
+ die "wrong line $_";
+ }
+ }
+ close F;
+ return %data;
+}
+
+# prints out the count of calls (NT form and Kernel form) from
+# the files stored in global @files
+sub split_by_dlls()
+{
+ my ($opt) = @_;
+ my $last_sdir = '';
+ my $mode = 0;
+ my $count1 = 0;
+ my $count2 = 0;
+
+ $mode = 1 if (defined($opt) && $opt eq '--wiki');
+
+ $mode == 0 && printf "Call Krn NT\n";
+ $mode == 1 && printf "||||||<tablewidth=\"33%%\">||\n||<:>Call||<:>Kernel||<:>NT||\n";
+
+ foreach my $file (@files)
+ {
+ open F, "<$file" || die "can't open $file: $!";
+ my ($dlldir, $sdir, $lfile) = split /\//, $file;
+
+ if ($last_sdir ne $sdir)
+ {
+ if ($count1 != 0)
+ {
+ $mode == 0 && printf "%3d: %-3d %-3d $last_sdir\n", $count1, $count2, $count1 - $count2;
+ $mode == 1 && printf "||<:>$count1||<:>$count2||<:>%d||<:>$last_sdir||\n", $count1 - $count2;
+ $count1 = $count2 = 0;
+ }
+ $last_sdir = $sdir;
+ }
+ while (<F>)
+ {
+ $count1++ if (index($_, 'wine_server_call') != -1 && index($_, "\"wine_server_call\"") == -1);
+ $count2++ if (index($_, 'wine_server_call_err') != -1 && index($_, "\"wine_server_call_err\"") == -1);
+ }
+ close F;
+ }
+ if ($count1 != 0)
+ {
+ $mode == 0 && printf "%3d: %-3d %-3d $last_sdir\n", $count1, $count2, $count1 - $count2;
+ $mode == 1 && printf "||<:>$count1||<:>$count2||<:>%d||<:>$last_sdir||\n", $count1 - $count2;
+ }
+ return 1;
+}
+
+# validates that all server calls are actually made in the allowed
+# DLL. Requires a server.api file with the allowed mappings
+sub validate()
+{
+ my ($api) = @_;
+ my %data = &load_api_data(&file_in_cmd_dir($api));
+ my %notused = &load_api_data(&file_in_cmd_dir($api));
+ my $nw = 0;
+ my %used;
+ my %bydll;
+ my %warned;
+
+ foreach my $file (@files)
+ {
+ my $line = 0;
+ open F, "<$file" || die "can't open $file: $!";
+ my ($dlldir, $sdir, $lfile) = split /\//, $file;
+ while (<F>)
+ {
+ $line++;
+ if ($_ =~ /SERVER_START_REQ[ \t]*\([ \t]*([^ ^\t]*)[ \t]*\)/g)
+ {
+ $used{$1} = 1;
+ if (defined($data{$1}))
+ {
+ if (!&is_in_list($data{$1}, $sdir))
+ {
+ printf("$sdir/$lfile:$line: warning: server-call `$1' is not allowed in module $sdir\n");
+ $bydll{$sdir}++;
+ $nw++;
+ $warned{$1}++;
+ }
+ }
+ else
+ {
+ printf("$sdir/$lfile:$line: warning: server-call `$1' is not included in API list\n");
+ $nw++;
+ $warned{$1}++;
+ }
+ $notused{$1} =~ s/$sdir//;
+ }
+ }
+ close F;
+ }
+ foreach my $i (sort keys %data)
+ {
+ if (!defined($used{$i}))
+ {
+ printf("warning: server-call `$i' is never used\n");
+ $nw++;
+ $warned{$i}++;
+ }
+ }
+ foreach my $i (sort keys %notused)
+ {
+ if (defined($notused{$i}))
+ {
+ my $s = $notused{$i};
+ $s =~ s/[ \t]+//g;
+ if ($s ne '' && $s ne ',' && $s ne ',,' && !defined($warned{$i}))
+ {
+ printf("warning: dll '$s' remains for server call '$i'\n");
+ $nw++;
+ }
+ }
+ }
+ if ($nw != 0)
+ {
+ my $count = 0;
+ printf("$nw warnings (");
+ foreach my $i (keys %bydll)
+ {
+ printf(", ") if ($count++);
+ printf("%d in %s", $bydll{$i}, $i);
+ }
+ printf(")\n");
+ }
+ return 1;
+}
+
+sub usage()
+{
+ print
+"Usage: $0 [call|split|validate] [options]
+ + call: list per server call the DLLs where this call is used
+ + split: counts the number of calls per DLL
+ with --wiki option, use formatting for wiki inclusion
+ + validate: checks whether a call is allowed in a given DLL
+ (information is gotten from $data_file file)\n";
+}
+
+sub check_cur_dir()
+{
+ if (! -f 'README' || ! -f 'VERSION' || ! -f 'DEVELOPERS-HINTS' ||
+ ! -d 'dlls' || ! -d 'programs' || ! -d 'server')
+ {
+ print "$0 should be run from the top of Wine source tree\n";
+ exit;
+ }
+}
+
+&check_cur_dir();
+&usage() && exit if (!defined($ARGV[0]));
+&browse_tree('dlls');
+&browse_tree('programs');
+&calls_by_dlls() && exit if ($ARGV[0] eq 'call');
+&split_by_dlls($ARGV[1], $ARGV[2]) && exit if ($ARGV[0] eq 'split');
+&validate($data_file) && exit if ($ARGV[0] eq 'validate');
+&usage();
More information about the wine-patches
mailing list