- Fixed the long long problem.
- Added configure include consistancy checking.
- Added progress indicator.
- Began splitting up the win16api.dat and win32api.dat files.
- Added various minor checks.
- Minor fixes.

diff --git a/tools/winapi_check/nativeapi.pm b/tools/winapi_check/nativeapi.pm
index 136689d..b59da36 100644
--- a/tools/winapi_check/nativeapi.pm
+++ b/tools/winapi_check/nativeapi.pm
@@ -9,17 +9,59 @@
     bless ($self, $class);
 
     my $functions = \%{$self->{FUNCTIONS}};
+    my $conditionals = \%{$self->{CONDITIONALS}};
+    my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}};
 
-    my $file = shift;
+    my $api_file = shift;
+    my $configure_in_file = shift;
+    my $config_h_in_file = shift;
 
-    open(IN, "< $file");
+    open(IN, "< $api_file");
     $/ = "\n";
     while(<IN>) {
 	s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
 	s/^(.*?)\s*#.*$/$1/;  # remove comments
 	/^$/ && next;         # skip empty lines   
 	
-	$$functions{$_} = 1;
+	$$functions{$_}++;
+    }
+    close(IN);
+
+    my $again = 0;
+    open(IN, "< $configure_in_file");
+    local $/ = "\n";
+    while($again || (defined($_ = <IN>))) {
+	$again = 0;
+	chomp;
+	if(/(.*)\\$/) {
+	    my $line = <IN>;
+	    if(defined($line)) {
+		$_ = $1 . " " . $line;
+		$again = 1;
+		next;
+	    }
+	}
+	# remove leading and trailing whitespace
+	s/^\s*(.*?)\s*$/$1/;
+
+	if(/^AC_CHECK_HEADERS\(\s*(.*?)\)\s*$/) {
+	    my @arguments = split(/,/,$1);
+	    foreach my $header (split(/\s+/, $arguments[0])) {		
+		$$conditional_headers{$header}++;
+	    }
+	} elsif(/^AC_FUNC_ALLOCA/) {
+	    $$conditional_headers{"alloca.h"}++;
+	}
+
+    }
+    close(IN);
+
+    open(IN, "< $config_h_in_file");
+    local $/ = "\n";
+    while(<IN>) {
+	if(/^\#undef (\S+)$/) {
+	    $$conditionals{$1}++;
+	}
     }
     close(IN);
 
@@ -35,4 +77,22 @@
     return $$functions{$name};
 }
 
+sub is_conditional {
+    my $self = shift;
+    my $conditionals = \%{$self->{CONDITIONALS}};
+
+    my $name = shift;
+
+    return $$conditionals{$name};
+}
+
+sub is_conditional_header {
+    my $self = shift;
+    my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}};
+
+    my $name = shift;
+
+    return $$conditional_headers{$name};
+}
+
 1;
diff --git a/tools/winapi_check/output.pm b/tools/winapi_check/output.pm
new file mode 100644
index 0000000..0c0fb32
--- /dev/null
+++ b/tools/winapi_check/output.pm
@@ -0,0 +1,91 @@
+package output;
+
+use strict;
+
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+    my $self  = {};
+    bless ($self, $class);
+
+    my $progress = \${$self->{PROGRESS}};
+    my $last_progress = \${$self->{LAST_PROGRESS}};
+
+    $$progress = "";
+    $$last_progress = "";
+
+    return $self;
+}
+
+
+sub show_progress {
+    my $self = shift;
+    my $progress = \${$self->{PROGRESS}};
+    my $last_progress = \${$self->{LAST_PROGRESS}};
+
+    if($$progress) {
+	print STDERR $$progress;
+	$$last_progress = $$progress;
+    }
+}
+
+sub hide_progress  {
+    my $self = shift;
+    my $progress = \${$self->{PROGRESS}};
+    my $last_progress = \${$self->{LAST_PROGRESS}};
+
+    if($$last_progress) {
+	my $message;
+	for (1..length($$last_progress)) {
+	    $message .= " ";
+	}
+	print STDERR $message;
+	undef $$last_progress;
+    }
+}
+
+sub update_progress {
+    my $self = shift;
+    my $progress = \${$self->{PROGRESS}};
+    my $last_progress = \${$self->{LAST_PROGRESS}};
+    
+    my $prefix = "";
+    for (1..length($$last_progress)) {
+	$prefix .= "";
+    }
+
+    my $suffix = "";
+    my $diff = length($$last_progress)-length($$progress);
+    if($diff > 0) {
+	for (1..$diff) {
+	    $suffix .= " ";
+	}
+	for (1..$diff) {
+	    $suffix .= "";
+	}
+    }
+    print STDERR $prefix . $$progress . $suffix;
+    $$last_progress = $$progress;
+}
+
+sub progress {
+    my $self = shift;
+    my $progress = \${$self->{PROGRESS}};
+
+    $$progress = shift;
+
+    $self->update_progress;
+}
+
+sub write {
+    my $self = shift;
+    my $last_progress = \${$self->{LAST_PROGRESS}};
+
+    my $message = shift;
+     
+    $self->hide_progress;
+    print STDERR $message;
+    $self->show_progress;
+}
+
+1;
diff --git a/tools/winapi_check/preprocessor.pm b/tools/winapi_check/preprocessor.pm
new file mode 100644
index 0000000..dd9fbd4
--- /dev/null
+++ b/tools/winapi_check/preprocessor.pm
@@ -0,0 +1,175 @@
+package preprocessor;
+
+use strict;
+
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+    my $self  = {};
+    bless ($self, $class);
+
+    my $state = \%{$self->{STATE}};
+    my $stack = \@{$self->{STACK}};
+    my $include_found = \${$self->{INCLUDE_FOUND}};
+    my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
+  
+    $$include_found = shift;
+    $$conditional_found = shift;
+
+    return $self;
+}
+
+sub include {
+    my $self = shift;
+    my $include_found = \${$self->{INCLUDE_FOUND}};
+
+    my $argument = shift;
+
+    &$$include_found($argument);
+}
+
+sub define {
+    my $self = shift;
+    my $state = \%{$self->{STATE}};
+    my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
+
+    my $name = shift;
+
+    $$state{$name} = "def";
+
+    &$$conditional_found($name);
+}
+
+sub undefine {
+    my $self = shift;
+    my $state = \%{$self->{STATE}};
+    my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
+
+    my $name = shift;
+
+    $$state{$name} = "undef";
+
+    &$$conditional_found($name);
+}
+
+sub begin_if {
+    my $self = shift;
+    my $state = \%{$self->{STATE}};
+    my $stack = \@{$self->{STACK}};
+
+    my $directive = shift;
+    local $_ = shift;
+
+    while(!/^$/) {
+	if(/^0\s*\&\&/) {
+	    $_ = "0";
+	} elsif(/^1\s*\|\|/) {
+	    $_ = "1";
+	}
+
+	if(/^(!)?defined\s*\(\s*(.+?)\s*\)\s*((\&\&|\|\|)\s*)?/){
+	    $_ = $';
+	    if(defined($1) && $1 eq "!") {
+		$self->undefine($2);
+		push @$stack, $2;
+	    } else {
+		$self->define($2);
+		push @$stack, $2;
+	    }
+	} elsif(/^(\w+)\s*(<|<=|==|!=|>=|>)\s*(\w+)\s*((\&\&|\|\|)\s*)?/) {
+	    $_ = $';
+	} elsif(/^(\w+)\s*$/) {
+	    $_ = $';
+	} elsif(/^\(|\)/) {
+	    $_ = $';
+	} else {
+	    print "*** Can't parse '#$directive $_' ***\n";
+	    $_ = "";
+	}
+    }
+}
+
+sub else_if {
+    my $self = shift;
+    my $state = \%{$self->{STATE}};
+    my $stack = \@{$self->{STACK}};
+
+    my $argument = shift;
+
+    $self->end_if;
+
+    if(defined($argument)) {
+	$self->begin_if("elif", $argument);
+    }
+}
+
+sub end_if {
+    my $self = shift;
+    my $state = \%{$self->{STATE}};
+    my $stack = \@{$self->{STACK}};
+
+    my $macro = pop @$stack;
+    delete $$state{$macro} if defined($macro);
+}
+
+sub directive {
+    my $self = shift;
+    my $state = \%{$self->{STATE}};
+    my $stack = \@{$self->{STACK}};
+
+    my $directive = shift;
+    my $argument = shift;
+
+    local $_ = $directive;
+    if(/^if$/) {
+	$self->begin_if("if",$argument);
+    } elsif(/^ifdef$/) {
+	$self->begin_if("if", "defined($argument)");
+    } elsif(/^ifndef$/) {
+	$self->begin_if("if", "!defined($argument)");
+	push @$stack, $argument;
+    } elsif(/^elif$/) {
+	$self->else_if($argument);
+    } elsif(/^else$/) {
+	$self->else_if;
+    } elsif(/^endif$/) {
+	$self->end_if;
+    } elsif(/^include/) {
+	$self->include($argument);
+    }
+}
+
+sub is_def {
+    my $self = shift;
+    my $state = \%{$self->{STATE}};
+
+    my $name = shift;
+    
+    my $status = $$state{$name};
+
+    return defined($status) && $status eq "def";
+}
+
+sub is_undef {
+    my $self = shift;
+    my $state = \%{$self->{STATE}};
+
+    my $name = shift;
+    
+    my $status = $$state{$name};
+
+    return defined($status) && $status eq "undef";
+}
+
+sub is_unknown {
+    my $self = shift;
+    my $state = \%{$self->{STATE}};
+
+    my $name = shift;
+    
+    my $status = $$state{$name};
+
+    return !defined($status);
+}
+
+1;
diff --git a/tools/winapi_check/win16/display.api b/tools/winapi_check/win16/display.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/display.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16/gdi.api b/tools/winapi_check/win16/gdi.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/gdi.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16/olecli.api b/tools/winapi_check/win16/olecli.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/olecli.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16/user.api b/tools/winapi_check/win16/user.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/user.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16/wing.api b/tools/winapi_check/win16/wing.api
new file mode 100644
index 0000000..e184c7e
--- /dev/null
+++ b/tools/winapi_check/win16/wing.api
@@ -0,0 +1,3 @@
+%word
+
+HDC16
diff --git a/tools/winapi_check/win16api.dat b/tools/winapi_check/win16api.dat
index a9d299b..f946ee6 100644
--- a/tools/winapi_check/win16api.dat
+++ b/tools/winapi_check/win16api.dat
@@ -24,6 +24,7 @@
 %longlong
 
 LARGE_INTEGER
+ULARGE_INTEGER
 
 %ptr
 
@@ -157,6 +158,7 @@
 LPPALETTEENTRY
 LPPDEVICE
 LPPOINT16
+LPPRINTDLG16
 LPQUEUESTRUCT16 *
 LPRASTERIZER_STATUS
 LPRECT16
@@ -290,7 +292,6 @@
 HBITMAP16
 HBRUSH16
 HCURSOR16
-HDC16
 HDROP16
 HDRVR16
 HDWP16
@@ -330,7 +331,7 @@
 WORD
 WPARAM16
 
-%unknown --forbidden
+%unknown # --forbidden
 
 BOOL
 FARPROC
diff --git a/tools/winapi_check/win32/avifil32.api b/tools/winapi_check/win32/avifil32.api
new file mode 100644
index 0000000..6558fd2
--- /dev/null
+++ b/tools/winapi_check/win32/avifil32.api
@@ -0,0 +1,12 @@
+%ptr
+
+AVICOMPRESSOPTIONS *
+AVISTREAMINFOA *
+AVISTREAMINFOW *
+IAVIFile *
+LPAVIFILEINFOA
+LPAVIFILEINFOW
+PAVIFILE
+PAVIFILE *
+PAVISTREAM
+PAVISTREAM *
diff --git a/tools/winapi_check/win32/comctl32.api b/tools/winapi_check/win32/comctl32.api
new file mode 100644
index 0000000..18ff86f
--- /dev/null
+++ b/tools/winapi_check/win32/comctl32.api
@@ -0,0 +1,7 @@
+%long
+
+COLORREF
+HBITMAP
+HDC
+HICON
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/comdlg32.api b/tools/winapi_check/win32/comdlg32.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/comdlg32.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/gdi32.api b/tools/winapi_check/win32/gdi32.api
new file mode 100644
index 0000000..7454167
--- /dev/null
+++ b/tools/winapi_check/win32/gdi32.api
@@ -0,0 +1,22 @@
+%long
+
+COLORREF
+HBITMAP
+HBRUSH
+HCOLORSPACE
+HDC
+HENHMETAFILE
+HFONT
+HGDIOBJ
+HMETAFILE
+HPALETTE
+HPEN
+HRGN
+HWND
+
+%ptr
+
+BITMAP *
+BITMAPINFO *
+BITMAPINFOHEADER *
+
diff --git a/tools/winapi_check/win32/imm32.api b/tools/winapi_check/win32/imm32.api
new file mode 100644
index 0000000..3f41c3a
--- /dev/null
+++ b/tools/winapi_check/win32/imm32.api
@@ -0,0 +1,4 @@
+%long
+
+HWND
+HIMC
diff --git a/tools/winapi_check/win32/mpr.api b/tools/winapi_check/win32/mpr.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/mpr.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/msacm32.api b/tools/winapi_check/win32/msacm32.api
new file mode 100644
index 0000000..98fe080
--- /dev/null
+++ b/tools/winapi_check/win32/msacm32.api
@@ -0,0 +1,36 @@
+%long
+
+HACMDRIVER
+HACMDRIVERID
+HACMOBJ
+HACMSTREAM
+
+%ptr
+
+ACMDRIVERENUMCB
+ACMFILTERENUMCBA
+ACMFILTERENUMCBW
+ACMFILTERTAGENUMCBA
+ACMFILTERTAGENUMCBW
+ACMFORMATENUMCBA
+ACMFORMATENUMCBW
+ACMFORMATTAGENUMCBA
+ACMFORMATTAGENUMCBW
+PACMDRIVERDETAILSA
+PACMDRIVERDETAILSW
+PACMFILTERCHOOSEA
+PACMFILTERCHOOSEW
+PACMFILTERDETAILSA
+PACMFILTERDETAILSW
+PACMFILTERTAGDETAILSA
+PACMFILTERTAGDETAILSW
+PACMFORMATCHOOSEA
+PACMFORMATCHOOSEW
+PACMFORMATDETAILSA
+PACMFORMATDETAILSW
+PACMFORMATTAGDETAILSA
+PACMFORMATTAGDETAILSW
+PACMSTREAMHEADER
+PHACMDRIVER
+PHACMDRIVERID
+PHACMSTREAM
diff --git a/tools/winapi_check/win32/msvfw32.api b/tools/winapi_check/win32/msvfw32.api
new file mode 100644
index 0000000..05c8b15
--- /dev/null
+++ b/tools/winapi_check/win32/msvfw32.api
@@ -0,0 +1,7 @@
+%long
+
+HDC
+HIC
+HPALETTE
+HWND
+
diff --git a/tools/winapi_check/win32/ole32.api b/tools/winapi_check/win32/ole32.api
new file mode 100644
index 0000000..41888d9
--- /dev/null
+++ b/tools/winapi_check/win32/ole32.api
@@ -0,0 +1,10 @@
+%long
+
+CLIPFORMAT
+HACCEL
+HMENU
+HWND
+
+%ptr
+CLIPFORMAT *
+
diff --git a/tools/winapi_check/win32/oleaut32.api b/tools/winapi_check/win32/oleaut32.api
new file mode 100644
index 0000000..60895c7
--- /dev/null
+++ b/tools/winapi_check/win32/oleaut32.api
@@ -0,0 +1,7 @@
+%long
+
+HPALETTE
+
+%ptr
+
+COLORREF *
diff --git a/tools/winapi_check/win32/olecli32.api b/tools/winapi_check/win32/olecli32.api
new file mode 100644
index 0000000..8c76d1c
--- /dev/null
+++ b/tools/winapi_check/win32/olecli32.api
@@ -0,0 +1,3 @@
+%long
+
+HDC
\ No newline at end of file
diff --git a/tools/winapi_check/win32/oledlg.api b/tools/winapi_check/win32/oledlg.api
new file mode 100644
index 0000000..2a948b0
--- /dev/null
+++ b/tools/winapi_check/win32/oledlg.api
@@ -0,0 +1,4 @@
+%long
+
+HMENU
+HWND
diff --git a/tools/winapi_check/win32/shell32.api b/tools/winapi_check/win32/shell32.api
new file mode 100644
index 0000000..367c116
--- /dev/null
+++ b/tools/winapi_check/win32/shell32.api
@@ -0,0 +1,8 @@
+%long
+
+COLORREF
+HBITMAP
+HMENU
+HICON
+HWND
+
diff --git a/tools/winapi_check/win32/shlwapi.api b/tools/winapi_check/win32/shlwapi.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/shlwapi.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/tapi32.api b/tools/winapi_check/win32/tapi32.api
new file mode 100644
index 0000000..41c0866
--- /dev/null
+++ b/tools/winapi_check/win32/tapi32.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
diff --git a/tools/winapi_check/win32/user32.api b/tools/winapi_check/win32/user32.api
new file mode 100644
index 0000000..a392bb3
--- /dev/null
+++ b/tools/winapi_check/win32/user32.api
@@ -0,0 +1,19 @@
+%long
+
+COLORREF
+HACCEL
+HBITMAP
+HBRUSH
+HCURSOR
+HDC
+HDESK
+HFONT
+HICON
+HMENU
+HMONITOR
+HRGN
+HWND
+
+%ptr
+
+COLORREF *
diff --git a/tools/winapi_check/win32/winmm.api b/tools/winapi_check/win32/winmm.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/winmm.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/winspool.api b/tools/winapi_check/win32/winspool.api
new file mode 100644
index 0000000..c2835fa
--- /dev/null
+++ b/tools/winapi_check/win32/winspool.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
\ No newline at end of file
diff --git a/tools/winapi_check/win32/wsock32.api b/tools/winapi_check/win32/wsock32.api
new file mode 100644
index 0000000..41c0866
--- /dev/null
+++ b/tools/winapi_check/win32/wsock32.api
@@ -0,0 +1,3 @@
+%long
+
+HWND
diff --git a/tools/winapi_check/win32api.dat b/tools/winapi_check/win32api.dat
index 88d8673..4d1e0fa 100644
--- a/tools/winapi_check/win32api.dat
+++ b/tools/winapi_check/win32api.dat
@@ -13,8 +13,6 @@
 CALID
 CALTYPE
 CHAR
-CLIPFORMAT
-COLORREF
 COORD
 DATE
 DIGEST_HANDLE
@@ -25,44 +23,25 @@
 FOURCC
 FS_INFORMATION_CLASS
 GET_FILEEX_INFO_LEVELS
-HACCEL
-HACMDRIVER
-HACMDRIVERID
-HACMOBJ
-HACMSTREAM
 HANDLE
-HBITMAP
-HBRUSH
 HCALL
-HCOLORSPACE
 HCONV
 HCONVLIST
-HCURSOR
 HCRYPTKEY
-HDC
 HDDEDATA
-HDESK
 HDROP
 HDRVR
 HDSA
 HDWP
-HENHMETAFILE
 HFILE
-HFONT
-HGDIOBJ
 HGLOBAL
 HHOOK
-HIC
-HICON
-HIMC
 HINSTANCE
 HKEY
 HKL
 HLINE
 HLINEAPP
 HLOCAL
-HMENU
-HMETAFILE
 HMIDIIN
 HMIDIOUT
 HMIDISTRM
@@ -70,23 +49,18 @@
 HMIXEROBJ
 HMMIO
 HMODULE
-HMONITOR
 HOLEMENU
-HPALETTE
-HPEN
 HPHONE
 HPHONEAPP
 HPROPSHEETPAGE
 HPROVIDER
 HRESULT
-HRGN
 HRSRC
 HSZ
 HTASK
 HWAVEIN
 HWAVEOUT
 HWINSTA
-HWND
 INT
 KEY_INFORMATION_CLASS
 KEY_VALUE_INFORMATION_CLASS
@@ -106,7 +80,6 @@
 OLEOPT_RENDER
 OLESTATUS
 OLE_SERVER_USE
-OUT
 PHANDLE
 PHPROVIDER
 PIO_APC_ROUTINE
@@ -117,6 +90,7 @@
 PROCESSINFOCLASS
 PTIME_FIELDS
 PTOKEN_PRIVILEGES
+REGKIND
 REGSAM
 SC_HANDLE
 SECTION_INHERIT
@@ -150,37 +124,21 @@
 
 LARGE_INTEGER
 POINT
+ULARGE_INTEGER
 
 %ptr
 
 ABORTPROC
-ACMDRIVERENUMCB
-ACMFILTERENUMCBA
-ACMFILTERENUMCBW
-ACMFILTERTAGENUMCBA
-ACMFILTERTAGENUMCBW
-ACMFORMATENUMCBA
-ACMFORMATENUMCBW
-ACMFORMATTAGENUMCBA
-ACMFORMATTAGENUMCBW
-AVICOMPRESSOPTIONS *
-AVISTREAMINFOA *
-AVISTREAMINFOW *
-BITMAP *
-BITMAPINFO *
-BITMAPINFOHEADER *
 BOOL *
 BSTR *
 BYTE *
 BY_HANDLE_FILE_INFORMATION *
 CALINFO_ENUMPROCA
 CHAR *
-CLIPFORMAT *
 CLSID *
 CODEPAGE_ENUMPROCA
 CODEPAGE_ENUMPROCW
 COLORADJUSTMENT *
-COLORREF *
 CONST
 CONTEXT *
 COSERVERINFO *
@@ -238,6 +196,7 @@
 HMIDIIN *
 HMIDIOUT *
 HMIDISTRM *
+HMODULE *
 HMRU
 HOOKPROC
 HPCSTR
@@ -254,6 +213,8 @@
 ILockBytes *
 IMAGEINFO *
 IMAGELISTDRAWPARAMS *
+IMoniker *
+IMoniker **
 INPUT_RECORD *
 INT *
 IPersistStream *
@@ -283,8 +244,6 @@
 LPAUTHDLGSTRUCTA
 LPAUXCAPSA
 LPAUXCAPSW
-LPAVIFILEINFOA
-LPAVIFILEINFOW
 LPBC *
 LPBITMAPINFOHEADER
 LPBOOL
@@ -327,6 +286,7 @@
 LPDATAADVISEHOLDER *
 LPDATAOBJECT
 LPDCB
+LPDCB *
 LPDDENUMCALLBACKA
 LPDDENUMCALLBACKEXA
 LPDDENUMCALLBACKEXW
@@ -434,8 +394,10 @@
 LPMIXERLINEW
 LPMMCKINFO
 LPMMIOPROC
+LPMMIOPROC16
 LPMMTIME
 LPMODULEENTRY
+LPMODULEINFO
 LPMONIKER
 LPMONIKER *
 LPMONITORINFO
@@ -579,31 +541,12 @@
 PACE_HEADER *
 PACL
 PACL *
-PACMDRIVERDETAILSA
-PACMDRIVERDETAILSW
-PACMFILTERCHOOSEA
-PACMFILTERCHOOSEW
-PACMFILTERDETAILSA
-PACMFILTERDETAILSW
-PACMFILTERTAGDETAILSA
-PACMFILTERTAGDETAILSW
-PACMFORMATCHOOSEA
-PACMFORMATCHOOSEW
-PACMFORMATDETAILSA
-PACMFORMATDETAILSW
-PACMFORMATTAGDETAILSA
-PACMFORMATTAGDETAILSW
-PACMSTREAMHEADER
 PAINTSTRUCT *
 PALETTEENTRY *
 PANSI_STRING
 PAPCFUNC
 PAPI_VERSION
 PAPPBARDATA
-PAVIFILE
-PAVIFILE *
-PAVISTREAM
-PAVISTREAM *
 PBOOLEAN
 PBYTE
 PCHAR
@@ -623,9 +566,6 @@
 PGENERIC_MAPPING
 PGETFRAME
 PGET_MODULE_BASE_ROUTINE
-PHACMDRIVER
-PHACMDRIVERID
-PHACMSTREAM
 PHONECALLBACK
 PIMAGEHLP_MODULE
 PIMAGEHLP_STATUS_ROUTINE
@@ -646,7 +586,9 @@
 POINT *
 PPOLYTEXTA
 PPOLYTEXTW
+PPSAPI_WS_WATCH_INFORMATION
 PPRIVILEGE_SET
+PPROCESS_MEMORY_COUNTERS
 PREAD_PROCESS_MEMORY_ROUTINE
 PRTL_HEAP_DEFINITION
 PROPENUMPROCA
diff --git a/tools/winapi_check/winapi.pm b/tools/winapi_check/winapi.pm
index dfb3e6d..95af6ff 100644
--- a/tools/winapi_check/winapi.pm
+++ b/tools/winapi_check/winapi.pm
@@ -8,18 +8,48 @@
     my $self  = {};
     bless ($self, $class);
 
+    my $output = \${$self->{OUTPUT}};
+    my $name = \${$self->{NAME}};
+
+    $$output = shift;
+    $$name = shift;
+    my $file = shift;
+    my $path = shift;
+
+    $file =~ s/^.\/(.*)$/$1/;
+    $self->parse_api_file($file);
+
+    my @files = map {
+	s/^.\/(.*)$/$1/;
+	$_; 
+    } split(/\n/, `find $path -name \\*.api`);
+  
+    foreach my $file (@files) {
+	my $module = $file;
+	$module =~ s/.*?\/([^\/]*?)\.api$/$1/;
+	$self->parse_api_file($file,$module);
+    }   
+
+    return $self;
+}
+
+sub parse_api_file {
+    my $self = shift;
+    my $output = \${$self->{OUTPUT}};
     my $allowed_kind = \%{$self->{ALLOWED_KIND}};
     my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
     my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
+    my $allowed_modules_unlimited = \%{$self->{ALLOWED_MODULES_UNLIMITED}};
     my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
 
-    $self->{NAME} = shift;
     my $file = shift;
+    my $module = shift;
 
-    my @modules;
     my $kind;
     my $forbidden = 0;
 
+    $$output->progress("$file");
+
     open(IN, "< $file") || die "$file: $!\n";
     $/ = "\n";
     while(<IN>) {
@@ -29,34 +59,41 @@
 
 	if(s/^%(\S+)\s*//) {
 	    $kind = $1;
-	    @modules = ();
 	    $forbidden = 0;
 
 	    $$allowed_kind{$kind} = 1;
-	    if(/^--module=(\S*)/) {
-		@modules = split(/,/, $1);
-	    } elsif(/^--forbidden/) {
+	    if(/^--forbidden/) {
 		$forbidden = 1;
 	    }
 	} elsif(defined($kind)) {
 	    my $type = $_;
 	    if(!$forbidden) {
-		for my $module (@modules) {
-		    $$allowed_modules_limited{$type} = 1;
-		    $$allowed_modules{$type}{$module} = 1;
+		if(defined($module)) {
+		    if($$allowed_modules_unlimited{$type}) {
+			print "$file: type ($type) already specificed as an unlimited type\n";
+		    } elsif(!$$allowed_modules{$type}{$module}) {
+			$$allowed_modules{$type}{$module} = 1;
+			$$allowed_modules_limited{$type} = 1;
+		    } else {
+			print "$file: type ($type) already specificed\n";
+		    }
+		} else {
+		    $$allowed_modules_unlimited{$type} = 1;
 		}
 	    } else {
 		$$allowed_modules_limited{$type} = 1;
 	    }
-	    $$translate_argument{$type} = $kind;
+	    if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) {
+		print "$file: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n";
+	    } else {
+		$$translate_argument{$type} = $kind;
+	    }
 	} else {
 	    print "$file: file must begin with %<type> statement\n";
 	    exit 1;
 	}
     }
     close(IN);
-
-    return $self;
 }
 
 sub get_spec_file_type {
@@ -88,7 +125,12 @@
     my $win16api = shift;
     my $win32api = shift;
 
-    foreach my $file (split(/\n/, `find $path -name \\*.spec`)) {
+    my @files = map {
+	s/^.\/(.*)$/$1/;
+	$_; 
+    } split(/\n/, `find $path -name \\*.spec`);
+
+    foreach my $file (@files) {
 	my $type = 'winapi'->get_spec_file_type($file);
 	if($type eq "win16") {
 	    $win16api->parse_spec_file($file);
@@ -100,16 +142,22 @@
 
 sub parse_spec_file {
     my $self = shift;
+
+    my $output = \${$self->{OUTPUT}};
     my $function_arguments = \%{$self->{FUNCTION_ARGUMENTS}};
     my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
     my $function_stub = \%{$self->{FUNCTION_STUB}};
     my $function_module = \%{$self->{FUNCTION_MODULE}};
 
+
     my $file = shift;
-    
+
+    my %ordinals;
     my $type;
     my $module;
 
+    $$output->progress("$file");
+
     open(IN, "< $file") || die "$file: $!\n";
     $/ = "\n";
     my $header = 1;
@@ -126,18 +174,24 @@
 	    next;
 	} 
 
-	if(/^\d+\s+(pascal|pascal16|stdcall|cdecl|register|interrupt|varargs)\s+(\S+)\s*\(\s*(.*?)\s*\)\s*(\S+)$/) {
-	    my $calling_convention = $1;
-	    my $external_name = $2;
-	    my $arguments = $3;
-	    my $internal_name = $4;
+	my $ordinal;
+	if(/^(\d+)\s+(pascal|pascal16|stdcall|cdecl|register|interrupt|varargs)\s+(\S+)\s*\(\s*(.*?)\s*\)\s*(\S+)$/) {
+	    my $calling_convention = $2;
+	    my $external_name = $3;
+	    my $arguments = $4;
+	    my $internal_name = $5;
+	   
+	    $ordinal = $1;
 
 	    # FIXME: Internal name existing more than once not handled properly
 	    $$function_arguments{$internal_name} = $arguments;
 	    $$function_calling_convention{$internal_name} = $calling_convention;
-	    $$function_module{$internal_name} = $module;
-	} elsif(/^\d+\s+stub\s+(\S+)$/) {
-	    my $external_name = $1;
+	    $$function_module{$internal_name} = "$module";
+	} elsif(/^(\d+)\s+stub\s+(\S+)$/) {
+	    my $external_name = $2;
+
+	    $ordinal = $1;
+
 	    $$function_stub{$external_name} = 1;
 	    $$function_module{$external_name} = $module;
 	} elsif(/^\d+\s+(equate|long|word|extern|forward)/) {
@@ -151,13 +205,22 @@
 		$lookahead = 1;
 	    }
 	}
+	
+	if(defined($ordinal)) {
+	    if($ordinals{$ordinal}) {
+		print "$file: ordinal redefined: $_\n";
+	    }
+	    $ordinals{$ordinal}++;
+	}
     }
     close(IN);
 }
 
 sub name {
     my $self = shift;
-    return $self->{NAME};
+    my $name = \${$self->{NAME}};
+
+    return $$name;
 }
 
 sub is_allowed_kind {
@@ -172,6 +235,15 @@
     }
 }
 
+sub is_limited_type {
+    my $self = shift;
+    my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
+
+    my $type = shift;
+
+    return $$allowed_modules_limited{$type};
+}
+
 sub allowed_type_in_module {
     my $self = shift;
     my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
@@ -183,6 +255,34 @@
     return !$$allowed_modules_limited{$type} || $$allowed_modules{$type}{$module};
 }
 
+sub type_used_in_module {
+    my $self = shift;
+    my $used_modules = \%{$self->{USED_MODULES}};
+
+    my $type = shift;
+    my $module = shift;
+
+    $$used_modules{$type}{$module} = 1;
+    
+    return ();
+}
+
+sub types_not_used {
+    my $self = shift;
+    my $used_modules = \%{$self->{USED_MODULES}};
+    my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
+
+    my $not_used;
+    foreach my $type (sort(keys(%$allowed_modules))) {
+	foreach my $module (sort(keys(%{$$allowed_modules{$type}}))) {
+	    if(!$$used_modules{$type}{$module}) {
+		$$not_used{$module}{$type} = 1;
+	    }
+	}
+    }
+    return $not_used;
+}
+
 sub translate_argument {
     my $self = shift;
     my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
@@ -226,7 +326,7 @@
 
 sub all_functions_found {
     my $self = shift;
-    my $function_found = \$self->{FUNCTION_FOUND};
+    my $function_found = \%{$self->{FUNCTION_FOUND}};
 
     return sort(keys(%$function_found));
 }
@@ -282,11 +382,7 @@
 
     my $name = shift;
 
-    if($self->is_function($name)) { 
-	return $$function_module{$name};
-    } else {
-	return undef;
-    }
+    return $$function_module{$name};
 }
 
 sub function_stub {
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index 564dea2..d6f9e9e 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -20,15 +20,19 @@
     }
     @INC = ($winapi_check_dir);
 
-    require "winapi.pm";
     require "nativeapi.pm";
+    require "output.pm";
+    require "preprocessor.pm";
+    require "winapi.pm";
     require "winapi_local.pm";
     require "winapi_global.pm";
     require "winapi_options.pm";
     require "winapi_parser.pm";
 
-    import winapi;
     import nativeapi;
+    import output;
+    import preprocessor;
+    import winapi;
     import winapi_local;
     import winapi_global;
     import winapi_options;
@@ -41,11 +45,13 @@
     exit;
 }
 
-my $win16api = 'winapi'->new("win16", "$winapi_check_dir/win16api.dat");
-my $win32api = 'winapi'->new("win32", "$winapi_check_dir/win32api.dat");
+my $output = 'output'->new;
+
+my $win16api = 'winapi'->new($output, "win16", "$winapi_check_dir/win16api.dat", "$winapi_check_dir/win16");
+my $win32api = 'winapi'->new($output, "win32", "$winapi_check_dir/win32api.dat", "$winapi_check_dir/win32");
 'winapi'->read_spec_files($wine_dir, $win16api, $win32api);
 
-my $nativeapi = 'nativeapi'->new("$winapi_check_dir/nativeapi.dat");
+my $nativeapi = 'nativeapi'->new("$winapi_check_dir/nativeapi.dat", "$wine_dir/configure.in", "$wine_dir/include/config.h.in");
 
 for my $name ($win32api->all_functions) {
     my $module16 = $win16api->function_module($name);
@@ -61,13 +67,57 @@
     }
 }
 
+my %includes;
+{   
+    my @files = map {
+	s/^.\/(.*)$/$1/;
+	$_; 
+    } split(/\n/, `find . -name \\*.h`);
+    
+    foreach my $file (@files) {
+	$includes{$file} = { name => $file };
+	open(IN, "< $file");
+	while(<IN>) {
+	    if(/^\s*\#\s*include\s*\"(.*?)\"/) {
+		$includes{$file}{includes}{"include/$1"}++;
+	    }
+	}
+	close(IN);
+    }
+}
+
+my %functions;
+
+my $progress_output;
+my $progress_current=0;
+my $progress_max=scalar($options->files);
 foreach my $file ($options->files) {
+    $progress_current++;
+    if($options->progress) {
+	$output->progress("$file: file $progress_current of $progress_max");
+    }
+
+    my $file_dir = $file;
+    $file_dir =~ s/(.*?)\/[^\/]*$/$1/;
+
+    my $file_type;
+    if($file_dir =~ /^(libtest|program|rc)/) {
+	$file_type = "application";
+    } elsif($file_dir =~ /^(debug|miscemu)/) {
+	$file_type = "emulator";
+    } elsif($file_dir =~ /^(tools)/) {
+	$file_type = "tool";
+    } else {
+	$file_type = "library";
+    }
+    
     my $found_function = sub {
 	my $return_type = shift;
 	my $calling_convention = shift;
 	my $name = shift;
 	my $refarguments = shift;
 	my @arguments = @$refarguments;
+	my $statements = shift;
 
 	if($options->global) {
 	    $win16api->found_type($return_type) if $options->win16;
@@ -84,16 +134,38 @@
 	if($options->local) {
 	    my $module16 = $win16api->function_module($name);
 	    my $module32 = $win32api->function_module($name);
-	    my $output = sub { 
+
+	    my $module;
+	    if(defined($module16) && defined($module32)) {
+		$module = "$module16 & $module32";
+	    } elsif(defined($module16)) {
+		$module = $module16;
+	    } elsif(defined($module32)) {
+		$module = $module32;
+	    } else {
+		$module = "";
+	    }
+	    my $output_module = sub { 
 		my $module = shift;
 		return sub {
 		    my $msg = shift;
-		    print "$file: $module: $return_type $calling_convention $name(" . join(",", @arguments) . "): $msg\n";
+		    $output->write("$file: $module: $return_type ");
+		    $output->write("$calling_convention ") if $calling_convention;
+		    $output->write("$name(" . join(",", @arguments) . "): $msg\n");
 		}
 	    };
-	    my $output16 = &$output($module16);
-	    my $output32 = &$output($module32);
+	    my $output16 = &$output_module($module16);
+	    my $output32 = &$output_module($module32);
 	    
+	    my $function = $functions{$name};
+	    $$function{file} = $file;
+	    $$function{return_type} = $return_type;
+	    $$function{calling_convention} = $calling_convention;
+	    $$function{arguments} = [@arguments];
+	    $$function{module} = $module;
+	    $$function{module16} = $module16;
+	    $$function{module32} = $module32;
+
 	    if($options->argument) {
 		if($options->win16 && $options->report_module($module16)) {
 		  winapi_local::check_arguments $options, $output16,
@@ -122,12 +194,145 @@
 		    }
 		}		
 	    }
+	    if($options->cross_call) {
+		local $_ = $statements;	
+		my $called_function_names = {};
+		while(defined($_)) {
+		    if(/(\w+)\((.*?)\)/) {
+			$_ = $';
+			my $called_name = $1;
+			if($called_name !~ /^if|for|while|switch|sizeof$/) {
+			    $functions{$name}{called_function_names}{$called_name}++;
+			    $functions{$called_name}{called_by_function_names}{$name}++;
+			}
+		    } else {
+		       undef $_
+		    }
+		}
+	    }
 	}
-    };   
-  winapi_parser::parse_c_file $options, $file, $found_function;
+    };
+
+    my $config = 0;
+    my $conditional = 0;
+    my $found_include = sub {
+	local $_ = shift;
+	if(/^\"config.h\"/) {
+	    $config++;
+	}
+    };
+    my $found_conditional = sub {
+	local $_ = shift;
+	if(!$nativeapi->is_conditional($_)) {
+	    if(/^HAVE_/ && !/^HAVE_(IPX|MESAGL|BUGGY_MESAGL|WINE_CONSTRUCTOR)$/)
+	    {
+		$output->write("$file: $_ is not a declared as a conditional\n");
+	    }
+	} else {
+	    $conditional++;
+	    if(!$config) {
+		$output->write("$file: conditional $_ used but config.h is not included\n");
+	    }
+	}
+    };
+    my $preprocessor = 'preprocessor'->new($found_include, $found_conditional);
+    my $found_preprocessor = sub {
+	my $directive = shift;
+	my $argument = shift;
+
+	$preprocessor->directive($directive, $argument);
+
+	if($options->config) {
+	    if($directive eq "include") {
+		if($argument =~ /^<(.*?)>$/) {
+		    my $header = $1;
+
+		    if((-e "$wine_dir/include/$header" || -e "$file_dir/$header") && $file_type ne "application") {
+			$output->write("$file: #include \<$header\> is a local include\n");
+		    }
+
+		    my $macro = uc($header);
+		    $macro =~ y/\.\//__/;
+		    $macro = "HAVE_" . $macro;
+		    
+		    if($nativeapi->is_conditional_header($header)) { 
+			if(!$preprocessor->is_def($macro)) {
+			    if($macro =~ /^HAVE_X11/) {
+				if(!$preprocessor->is_undef("X_DISPLAY_MISSING")) {
+				    $output->write("$file: #$directive $argument: is a conditional include, but is not protected\n");
+				}
+			    } elsif($macro =~ /^HAVE_(.*?)_H$/) {
+				if($header ne "alloca.h" && !$preprocessor->is_def("STATFS_DEFINED_BY_$1")) {
+				    $output->write("$file: #$directive $argument: is a conditional include, but is not protected\n");
+				}
+			    }
+			}
+		    } elsif($preprocessor->is_def($macro)) {
+			$output->write("$file: #$directive $argument: is protected, but is not a conditional include\n");
+		    }
+		} elsif($argument =~ /^"(.*?)"$/) {
+		    my $header = $1;
+
+		    if(-e "$file_dir/$header") {
+			$includes{"$file_dir/$header"}{used}++;
+			foreach my $name (keys(%{$includes{"$file_dir/$header"}{includes}})) {
+			    $includes{$name}{used}++;
+			}
+		    } elsif(-e "include/$header") {
+			$includes{"include/$header"}{used}++;
+			foreach my $name (keys(%{$includes{"include/$header"}{includes}})) {
+			    $includes{$name}{used}++;
+			}
+		    } else {
+			$output->write("$file: #include \"$header\" is not a local include\n");
+		    }
+		}
+	    }
+	}
+    };
+  
+    winapi_parser::parse_c_file $options, $file, $found_function, $found_preprocessor;
+    
+    if($options->config_unnessary) {
+	if($config && $conditional == 0) {
+	    $output->write("$file: includes config.h but do not use any conditionals\n");
+	}
+    }
+
+    if($options->cross_call) {
+	my @names = sort(keys(%functions));
+	for my $name (@names) {
+	    my @called_names = sort(keys(%{$functions{$name}{called_function_names}}));
+	    my @called_by_names = sort(keys(%{$functions{$name}{called_by_function_names}}));
+	    my $module = $functions{$name}{module};
+	    my $module16 = $functions{$name}{module16};
+	    my $module32 = $functions{$name}{module32};
+
+	    if($#called_names >= 0 && (defined($module16) || defined($module32)) ) {
+		$output->write("$file: $module: $name: \\\n");
+		for my $called_name (@called_names) {
+		    my $function;
+		    if($function = $functions{$called_name}) {		    
+			$output->write("  $called_name\n");
+		    }
+		}
+	    }
+	}
+    }
 }
 
+$output->hide_progress;
+
 if($options->global) {
+    foreach my $name (sort(keys(%includes))) {
+	if(!$includes{$name}{used}) {
+	    if($options->include) {
+		print "$name: include file is never used\n";
+	    }
+	}
+    }
+
     winapi_global::check $options, $win16api, $nativeapi if $options->win16;
     winapi_global::check $options, $win32api, $nativeapi if $options->win32;
 }
+
diff --git a/tools/winapi_check/winapi_global.pm b/tools/winapi_check/winapi_global.pm
index 0c4322d..11f44ab 100644
--- a/tools/winapi_check/winapi_global.pm
+++ b/tools/winapi_check/winapi_global.pm
@@ -11,9 +11,9 @@
 
     if($options->argument) {
 	foreach my $type ($winapi->all_declared_types) {
-	    if(!$winapi->type_found($type) && $type ne "CONTEXT86 *") {
-		print "*.c: $winver: $type: ";
-		print "type not used\n";
+	    if(!$winapi->type_found($type) && !$winapi->is_type_limited($type) && $type ne "CONTEXT86 *") {
+		print "*.c: $winver: ";
+		print "type ($type) not used\n";
 	    }
 	}
     }
@@ -21,19 +21,22 @@
     if($options->declared) {
 	foreach my $name ($winapi->all_functions) {
 	    if(!$winapi->function_found($name) && !$nativeapi->is_function($name)) {
-		print "*.c: $winver: $name: ";
+		my $module = $winapi->function_module($name);
+		print "*.c: $module: $name: ";
 		print "function declared but not implemented: " . $winapi->function_arguments($name) . "\n";
 	    }
 	}
     }
 
-    if($options->implemented) {
-	foreach my $name ($winapi->all_functions_found) {
-	    if($winapi->function_stub($name)) {
-		print "*.c: $winver: $name: ";
-		print "function implemented but not declared\n";
+    if($options->argument_forbidden) {
+	my $not_used = $winapi->types_not_used;
+
+	foreach my $module (sort(keys(%$not_used))) {
+	    foreach my $type (sort(keys(%{$$not_used{$module}}))) {
+		print "*.c: $module: type $type not used\n";
 	    }
 	}
+	
     }
 }
 
diff --git a/tools/winapi_check/winapi_local.pm b/tools/winapi_check/winapi_local.pm
index 88126bb..fe1d356 100644
--- a/tools/winapi_check/winapi_local.pm
+++ b/tools/winapi_check/winapi_local.pm
@@ -14,8 +14,30 @@
 
     my $module = $winapi->function_module($name);
 
+    if($winapi->name eq "win16") {
+	my $name16 = $name;
+	$name16 =~ s/16$//;   
+	if($name16 ne $name && $winapi->function_stub($name16)) {
+	    if($options->implemented) {
+		&$output("function implemented but declared as stub in .spec file");
+	    }
+	    return;
+	} elsif($winapi->function_stub($name)) {
+	    if($options->implemented_win32) {
+		&$output("32-bit variant of function implemented but declared as stub in .spec file");
+	    }
+	    return;
+	}
+    } elsif($winapi->function_stub($name)) {
+	if($options->implemented) {
+	    &$output("function implemented but declared as stub in .spec file");
+	}
+	return;
+    }
+
     my $forbidden_return_type = 0;
     my $implemented_return_kind;
+    $winapi->type_used_in_module($return_type,$module);
     if(!defined($implemented_return_kind = $winapi->translate_argument($return_type))) {
 	if($return_type ne "") {
 	    &$output("no translation defined: " . $return_type);
@@ -48,8 +70,10 @@
 	    $implemented_calling_convention = "cdecl";
 	} elsif($calling_convention =~ /^VFWAPIV|WINAPIV$/) {
 	    $implemented_calling_convention = "varargs";
-	} elsif($calling_convention = ~ /^__stdcall|VFWAPI|WINAPI$/) {
+	} elsif($calling_convention =~ /^__stdcall|VFWAPI|WINAPI$/) {
 	    $implemented_calling_convention = "stdcall";
+	} else {
+	    $implemented_calling_convention = "<default>";
 	}
     }
 
@@ -85,15 +109,12 @@
 	
     if($name =~ /^CRTDLL__ftol|CRTDLL__CIpow$/) {
 	# ignore
-    } elsif($#argument_types != $#declared_argument_kinds) {
-	if($options->argument_count) {
-	    &$output("argument count differs: " . ($#argument_types + 1) . " != " . ($#declared_argument_kinds + 1));
-	}
     } else {
 	my $n = 0;
 	my @argument_kinds = map {
 	    my $type = $_;
 	    my $kind = "unknown";
+	    $winapi->type_used_in_module($type,$module);
 	    if(!defined($kind = $winapi->translate_argument($type))) {
 		&$output("no translation defined: " . $type);
 	    } elsif(!$winapi->is_allowed_kind($kind) ||
@@ -102,8 +123,13 @@
 		    &$output("forbidden argument " . ($n + 1) . " type (" . $type . ")");
 		}
 	    }
-	    $n++;
-	    $kind;
+	    if(defined($kind) && $kind eq "longlong") {
+		$n+=2;
+		("long", "long");
+	    } else {
+		$n++;
+		$kind;
+	    }
 	} @argument_types;
 
 	for my $n (0..$#argument_kinds) {
@@ -123,8 +149,13 @@
 			     $argument_types[$n] . " ($argument_kinds[$n]) != " . $declared_argument_kinds[$n]);
 		}
 	    }
-
 	}
+        if($#argument_kinds != $#declared_argument_kinds) {
+	    if($options->argument_count) {
+		&$output("argument count differs: " . ($#argument_types + 1) . " != " . ($#declared_argument_kinds + 1));
+	    }
+	}
+
     }
 
     if($segmented && $options->shared_segmented && $winapi->is_shared_function($name)) {
diff --git a/tools/winapi_check/winapi_options.pm b/tools/winapi_check/winapi_options.pm
index 47f58d6..d85b69d 100644
--- a/tools/winapi_check/winapi_options.pm
+++ b/tools/winapi_check/winapi_options.pm
@@ -23,12 +23,17 @@
     "help" => { default => 0, description => "help mode" },
     "verbose" => { default => 0, description => "verbose mode" },
 
+    "progress" => { default => 1, description => "show progress" },
+
     "win16" => { default => 1, description => "Win16 checking" },
     "win32" => { default => 1, description => "Win32 checking" },
 
     "shared" =>  { default => 0, description => "show shared functions between Win16 and Win32" },
     "shared-segmented" =>  { default => 0, description => "segmented shared functions between Win16 and Win32 checking" },
 
+    "config" => { default => 1, description => "check configuration include consistancy" },
+    "config-unnessary" => { default => 0, parent => "config", description => "check for unnessary #include \"config.h\"" },
+
     "local" =>  { default => 1, description => "local checking" },
     "module" => { 
 	default => { active => 1, filter => 0, hash => {} },
@@ -40,7 +45,7 @@
     "argument" => { default => 1, parent => "local", description => "argument checking" },
     "argument-count" => { default => 1, parent => "argument", description => "argument count checking" },
     "argument-forbidden" => {
-	default => { active => 0, filter => 0, hash => {} },
+	default => { active => 1, filter => 0, hash => {} },
 	parent => "argument",
 	parser => \&parser_comma_list,
 	description => "argument forbidden checking"
@@ -52,12 +57,14 @@
 	description => "argument kind checking"
     },
     "calling-convention" => { default => 0, parent => "local", description => "calling convention checking" },
-    "misplaced" => { default => 0, parent => "local", description => "checking for misplaced functions" },
+    "misplaced" => { default => 0, parent => "local", description => "check for misplaced functions" },
+    "cross-call" => { default => 0, parent => "local", description => "check for cross calling functions" },
              
     "global" => { default => 1, description => "global checking" }, 
     "declared" => { default => 1, parent => "global", description => "declared checking" }, 
-    "implemented" => { default => 0, parent => "global", description => "implemented checking" }
-
+    "implemented" => { default => 1, parent => "global", description => "implemented checking" },
+    "implemented-win32" => { default => 0, parent => "implemented", description => "implemented as win32 checking" },
+    "include" => { default => 0, parent => "global", description => "include checking" }
 );
 
 my %short_options = (
diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm
index d6b9c12..ee5a9fe 100644
--- a/tools/winapi_check/winapi_parser.pm
+++ b/tools/winapi_check/winapi_parser.pm
@@ -6,6 +6,27 @@
     my $options = shift;
     my $file = shift;
     my $function_found_callback = shift;
+    my $preprocessor_found_callback = shift;
+
+    my $return_type;
+    my $calling_convention;
+    my $function = "";
+    my $arguments;
+    my $statements;
+
+    my $function_begin = sub {
+	$return_type= shift;
+	$calling_convention = shift;
+	$function = shift;
+	$arguments = shift;
+
+	$statements = "";
+    };
+    my $function_end = sub {
+	&$function_found_callback($return_type,$calling_convention,$function,$arguments,$statements);
+
+	$function = "";
+    };
 
     my $level = 0;
     my $again = 0;
@@ -44,34 +65,61 @@
 	if(/^\s*$/) { next; }
 
 	# remove preprocessor directives
-	if(s/^\s*\#.*$//m) { $again = 1; next; }
+	if(s/^\s*\#/\#/m) {
+	    if(/^\\#.*?\\$/m) {
+		$lookahead = 1;
+		next;
+	    } elsif(s/^\#\s*(.*?)(\s+(.*?))?\s*$//m) {
+		if(defined($3)) {
+		    &$preprocessor_found_callback($1, $3);
+		} else {
+		    &$preprocessor_found_callback($1, "");
+		}
+		$again = 1;
+		next;
+	    }
+	}
 
 	if($level > 0)
 	{
-	    s/^[^\{\}]*//s;
-	    if(/^\{/) {
+	    my $line;
+	    s/^([^\{\}]*)//s;
+	    $line = $1;
+	    if(/^(\{)/) {
 		$_ = $'; $again = 1;
+		$line .= $1;
 		print "+1: $_\n" if $options->debug >= 2;
 		$level++;
-	    } elsif(/^\}/) {
+	    } elsif(/^(\})/) {
 		$_ = $'; $again = 1;
+		$line .= $1 if $level > 1;
 		print "-1: $_\n" if $options->debug >= 2; 
 		$level--;
 	    }
+	    if($line !~ /^\s*$/) {
+		$statements .= "$line\n";
+	    }	    
+	    if($function && $level == 0) {
+		&$function_end;
+	    }
 	    next;
-	} elsif(/((struct\s+|union\s+|enum\s+)?\w+((\s*\*)+\s*|\s+))(__cdecl|__stdcall|VFWAPIV|VFWAPI|WINAPIV|WINAPI)\s+(\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/s) {
+	} elsif(/((struct\s+|union\s+|enum\s+)?\w+((\s*\*)+\s*|\s+))((__cdecl|__stdcall|VFWAPIV|VFWAPI|WINAPIV|WINAPI)\s+)?(\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/s) {
 	    $_ = $'; $again = 1;
 
-	    if($9 eq ";") {
+	    if($10 eq ";") {
 		next;
-	    } elsif($9 eq "{")  {		
+	    } elsif($10 eq "{")  {	
 		$level++;
 	    }
 
 	    my $return_type = $1;
-	    my $calling_convention = $5;
-	    my $name = $6;
-	    my $arguments = $8;
+	    my $calling_convention = $6;
+	    my $name = $7;
+	    my $arguments = $9;
+
+	    if(!defined($calling_convention)) {
+		$calling_convention = "";
+	    }
 
 	    $return_type =~ s/\s*$//;
 	    $return_type =~ s/\s*\*\s*/*/g;
@@ -88,7 +136,8 @@
 		my $argument = $arguments[$n];
 		$argument =~ s/^\s*(.*?)\s*$/$1/;
 		#print "  " . ($n + 1) . ": '$argument'\n";
-		$argument =~ s/^(const(?=\s)|IN(?=\s)|OUT(?=\s)|(\s*))\s*//;
+		$argument =~ s/^(IN OUT(?=\s)|IN(?=\s)|OUT(?=\s)|\s*)\s*//;
+		$argument =~ s/^(const(?=\s)|\s*)\s*//;
 		if($argument =~ /^...$/) {
 		    $argument = "...";
 		} elsif($argument =~ /^((struct\s+|union\s+|enum\s+)?\w+)\s*((\*\s*?)*)\s*/) {
@@ -107,52 +156,66 @@
 	    if($options->debug) {
 		print "$file: $return_type $calling_convention $name(" . join(",", @arguments) . ")\n";
 	    }
-	    &$function_found_callback($return_type,$calling_convention,$name,\@arguments);
+	    &$function_begin($return_type,$calling_convention,$name,\@arguments);
 
 	} elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments = ("HDC16");
-	    &$function_found_callback($2, "WINAPI", $3, \@arguments);
+	    &$function_begin($2, "WINAPI", $3, \@arguments);
+	    &$function_end;
 	} elsif(/DC_(GET_VAL_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments = ("HDC");
-	    &$function_found_callback($2, "WINAPI", $3, \@arguments);
+	    &$function_begin($2, "WINAPI", $3, \@arguments);
+	    &$function_end;
 	} elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments16 = ("HDC16", "LP" . $5 . "16");
 	    my @arguments32 = ("HDC", "LP" . $5);
-	    &$function_found_callback("BOOL16", "WINAPI", $2 . "16", \@arguments16);
-	    &$function_found_callback("BOOL", "WINAPI", $2, \@arguments32);
+	    &$function_begin("BOOL16", "WINAPI", $2 . "16", \@arguments16);
+	    &$function_end;
+	    &$function_begin("BOOL", "WINAPI", $2, \@arguments32);
+	    &$function_end;
 	} elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments16 = ("HDC16", "INT16");
 	    my @arguments32 = ("HDC", "INT");
-	    &$function_found_callback("INT16", "WINAPI", $2 . "16", \@arguments16);
-	    &$function_found_callback("INT", "WINAPI", $2, \@arguments32);
+	    &$function_begin("INT16", "WINAPI", $2 . "16", \@arguments16);
+	    &$function_end;
+	    &$function_begin("INT", "WINAPI", $2, \@arguments32);
+	    &$function_end;
 	} elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments16 = ("HWAVEIN16");
 	    my @arguments32 = ("HWAVEIN");
-	    &$function_found_callback("UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
-	    &$function_found_callback("UINT", "WINAPI", "waveIn" . $1, \@arguments32);	    
+	    &$function_begin("UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
+	    &$function_end;
+	    &$function_begin("UINT", "WINAPI", "waveIn" . $1, \@arguments32);
+	    &$function_end;	    
 	} elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments16 = ("HWAVEOUT16");
 	    my @arguments32 = ("HWAVEOUT");
-	    &$function_found_callback("UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
-	    &$function_found_callback("UINT", "WINAPI", "waveOut" . $1, \@arguments32);	    
+	    &$function_begin("UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
+	    &$function_end;
+	    &$function_begin("UINT", "WINAPI", "waveOut" . $1, \@arguments32);	    
+	    &$function_end;
 	} elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    if($1 eq "1") {
 		my @arguments16 = ("HWAVEOUT16", $4);
 		my @arguments32 = ("HWAVEOUT", $4);
-		&$function_found_callback("UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
-		&$function_found_callback("UINT", "WINAPI", "waveOut" . $2, \@arguments32);
+		&$function_begin("UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
+		&$function_end;
+		&$function_begin("UINT", "WINAPI", "waveOut" . $2, \@arguments32);
+		&$function_end;
 	    } elsif($1 eq 2) {
 		my @arguments16 = ("UINT16", $4);
 		my @arguments32 = ("UINT", $4);
-		&$function_found_callback("UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
-		&$function_found_callback("UINT", "WINAPI", "waveOut" . $2, \@arguments32)
+		&$function_begin("UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
+		&$function_end;
+		&$function_begin("UINT", "WINAPI", "waveOut" . $2, \@arguments32);
+		&$function_end;
 	    }
 	} elsif(/;/s) {
 	    $_ = $'; $again = 1;