- Addded support for API:s implemented with __ASM_GLOBAL_FUNC
- Reorganized documentation checking.
- Minor API files fixes

diff --git a/tools/winapi_check/win16/msvideo.api b/tools/winapi_check/win16/msvideo.api
index deb26e1..9aa96e2 100644
--- a/tools/winapi_check/win16/msvideo.api
+++ b/tools/winapi_check/win16/msvideo.api
@@ -10,6 +10,10 @@
 LPDWORD
 LPVOID
 
+%str
+
+LPSTR
+
 %word
 
 BOOL16
diff --git a/tools/winapi_check/win16/user.api b/tools/winapi_check/win16/user.api
index 289fdb0..48c6995 100644
--- a/tools/winapi_check/win16/user.api
+++ b/tools/winapi_check/win16/user.api
@@ -23,12 +23,14 @@
 CURSORICONINFO *
 DRAWSTATEPROC16
 DWORD *
+HANDLE *
 HHOOK *
 INT16 *
 LPBYTE
 LPCOMSTAT16
 LPCVOID
 LPDCB16
+LPDEVMODEA
 LPDRIVERINFOSTRUCT16
 LPDWORD
 LPICONINFO16
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index 77aacc0..9e963f3 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -36,6 +36,7 @@
     require "output.pm";
     require "preprocessor.pm";
     require "winapi.pm";
+    require "winapi_documentation.pm";
     require "winapi_function.pm";
     require "winapi_local.pm";
     require "winapi_global.pm";
@@ -47,6 +48,7 @@
     import output;
     import preprocessor;
     import winapi;
+    import winapi_documentation;
     import winapi_function;
     import winapi_local;
     import winapi_global;
@@ -245,9 +247,6 @@
     }
 }
 
-my %comment_width;
-my %comment_indent;
-my %comment_spacing;
 my %module_pseudo_stub_count16;
 my %module_pseudo_stub_count32;
 
@@ -322,6 +321,7 @@
 	    $function->internal_name($internal_name);
 	    $function->argument_types([@argument_types]);
 	    $function->argument_names([@argument_names]);
+ 	    $function->argument_documentations([@argument_documentations]);
 	    $function->statements($statements);
 	    $function->module16($module16);
 	    $function->module32($module32);
@@ -443,163 +443,7 @@
 	       (defined($module16) || defined($module32)) &&
 	       $linkage ne "extern" && $statements)
 	    {
-		my $external_name;
-		my $name1;
-		my $name2;
-		
-		if(defined($module16) && !defined($module32)) {
-		    my @uc_modules16 = split(/\s*\&\s*/, uc($module16));
-		    push @uc_modules16, "WIN16";
-
-		    $name1 = $internal_name;
-		    foreach my $uc_module16 (@uc_modules16) {
-			if($name1 =~ s/^$uc_module16\_//) { last; }
-		    }
-
-		    $name2 = $name1;
-		    $name2 =~ s/(?:_)?16$//;
-		    $name2 =~ s/16_fn/16_/;
-
-		    $external_name = $external_name16;
-		} elsif(!defined($module16) && defined($module32)) {
-		    my @uc_modules32 = split(/\s*\&\s*/, uc($module32));
-		    push @uc_modules32, "wine";
-
-		    foreach my $uc_module32 (@uc_modules32) {
-			if($uc_module32 =~ /^WS2_32$/) {
-			    push @uc_modules32, "WSOCK32"; 
-			}
-		    }
-
-		    $name1 = $internal_name;
-		    foreach my $uc_module32 (@uc_modules32) {
-			if($name1 =~ s/^$uc_module32\_//) { last; }
-		    }
-
-		    $name2 = $name1;
-		    $name2 =~ s/AW$//;
-
-		    $external_name = $external_name32;
-		} else {
-		    my @uc_modules = split(/\s*\&\s*/, uc($module16));
-		    push @uc_modules, split(/\s*\&\s*/, uc($module32));
-
-		    $name1 = $internal_name;
-		    foreach my $uc_module (@uc_modules) {
-			if($name1 =~ s/^$uc_module\_//) { last; }
-		    }
-
-		    $name2 = $name1;
-		    $external_name = $external_name32;
-		}
-
-		if(!defined($external_name)) {
-		    $external_name = $internal_name;
-		}
-
-		if($options->documentation_pedantic) {
-		    my $n = 0;
-		    if((++$n && defined($module16) && defined($external_name16) &&
-			$external_name16 ne "@" && $documentation !~ /\b\Q$external_name16\E\b/) ||
-		       (++$n && defined($module16) && defined($external_name16) &&
-			$external_name16 eq "@" && $documentation !~ /\@/) ||
-		       (++$n && defined($module32) && defined($external_name32) &&
-			$external_name32 ne "@" && $documentation !~ /\b\Q$external_name32\E\b/) ||
-		       (++$n && defined($module32) && defined($external_name32) &&
-			$external_name32 eq "@" && $documentation !~ /\@/))
-		    {
-			my $external_name = ($external_name16, $external_name32)[($n-1)/2];
-			$output->write("documentation: wrong or missing name ($external_name) \\\n$documentation\n");
-		    }
-		} else {
-		    if($documentation !~ /\b(?:\Q$external_name\E|$internal_name|$name1|$name2)\b/) {
-			$output->write("documentation: wrong or missing name \\\n$documentation\n");
-		    }
-		}
-
-		if($options->documentation_ordinal) {
-		    if(defined($module16)) {
-			my $ordinal16 = $win16api->function_ordinal($internal_name);
-			
-			if(!defined($ordinal16)) {
-			    $output->write("function have no ordinal\n");
-			} else { 
-			    my @uc_modules16 = split(/\s*\&\s*/, uc($module16));
-			    foreach my $uc_module16 (@uc_modules16) {
-				if($documentation !~ /\b$uc_module16\.\Q$ordinal16\E/) {
-				    $output->write("documentation: wrong or missing ordinal " .
-						   "expected (\U$module16\E.$ordinal16)\\\n$documentation\n");
-				}
-			    }
-			}
-		    }
-		    if(defined($module32)) {
-			my $ordinal32 = $win32api->function_ordinal($internal_name);
-
-			if(!defined($ordinal32)) {
-			    $output->write("function have no ordinal\n");			
-			} else { 
-			    my @uc_modules32 = split(/\s*\&\s*/, uc($module32));
-			    foreach my $uc_module32 (@uc_modules32) {
-				if($documentation !~ /\b$uc_module32\.\Q$ordinal32\E/) {
-				    $output->write("documentation: wrong or missing ordinal " .
-						   "expected (\U$module32\E.$ordinal32) \\\n$documentation\n");
-				}
-			    }
-			}
-		    }
-		}
-
-		if($options->documentation_pedantic) {
-		    if($documentation !~ /^ \*\t\t(?:\@|\w+)(?: \(\w+\.(?:\@|\d+)\))+/m) {
-			$output->write("documentation: pedantic check failed \\\n$documentation\n");
-		    }
-		}
-
-		if($options->documentation_comment_indent) {
-		    if($documentation =~ /^ \*(\s*)\w+(\s*)([\(\[])\s*\w+\.\s*(?:\@|\d+)\s*([\)\]])/m) {
-			my $indent = $1;
-			my $spacing = $2;
-			my $left = $3;
-			my $right = $4;
-
-			$indent =~ s/\t/        /g;
-			$indent = length($indent);
-			
-			$spacing =~ s/\t/        /g;
-			$spacing = length($spacing);
-
-			$comment_indent{$indent}++;
-			if($indent >= 20) {
-			    $output->write("documentation: comment indent is $indent\n");
-			}
-
-			$comment_spacing{$spacing}++;
-		    }
-		}
-
-		if($options->documentation_comment_width) {		
-		    if($documentation =~ /(^\/\*\*+)/) {
-			my $width = length($1);
-			
-			$comment_width{$width}++;
-			if($width <= 65 || $width >= 81) {
-			    $output->write("comment is $width columns wide\n");
-			}
-		    }
-		}
-		
-		if($options->documentation_arguments) {
-		    my $n = 0;
-		    for my $argument_documentation (@argument_documentations) {
-			$n++;
-			if($argument_documentation ne "") {
-			    if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?)\].*?\*\/$/s) {
-				$output->write("argument $n documentation: \\\n$argument_documentation\n");
-			    }
-			}
-		    }
-		}
+	        winapi_documentation::check_documentation $options, $output, $win16api, $win32api, $function;
 	    }
 	    $output->prefix("");
 	}
@@ -731,19 +575,7 @@
 $output->hide_progress;
 
 if($options->global) {
-    if($options->documentation_comment_indent) {
-	foreach my $indent (sort(keys(%comment_indent))) {
-	    my $count = $comment_indent{$indent};
-	    $output->write("*.c: $count functions have comment that is indented $indent\n");
-	}
-    }
-
-    if($options->documentation_comment_width) {
-	foreach my $width (sort(keys(%comment_width))) {
-	    my $count = $comment_width{$width};
-	    $output->write("*.c: $count functions have comments of width $width\n");
-	}
-    }
+    winapi_documentation::report_documentation $options, $output;
 
     if($options->stubs) {
 	if($options->win16) {
diff --git a/tools/winapi_check/winapi_documentation.pm b/tools/winapi_check/winapi_documentation.pm
new file mode 100644
index 0000000..435f756
--- /dev/null
+++ b/tools/winapi_check/winapi_documentation.pm
@@ -0,0 +1,202 @@
+package winapi_documentation;
+
+use strict;
+
+my %comment_width;
+my %comment_indent;
+my %comment_spacing;
+
+sub check_documentation {
+    my $options = shift;
+    my $output = shift;
+    my $win16api = shift;
+    my $win32api = shift;
+    my $function = shift;
+
+    my $module16 = $function->module16;
+    my $module32 = $function->module32;
+    my $external_name16 = $function->external_name16;
+    my $external_name32 = $function->external_name32;
+    my $internal_name = $function->internal_name;
+    my $documentation = $function->documentation;
+    my @argument_documentations = @{$function->argument_documentations};
+
+    my $external_name;
+    my $name1;
+    my $name2;
+
+    if(defined($module16) && !defined($module32)) {
+	my @uc_modules16 = split(/\s*\&\s*/, uc($module16));
+	push @uc_modules16, "WIN16";
+
+	$name1 = $internal_name;
+	foreach my $uc_module16 (@uc_modules16) {
+	    if($name1 =~ s/^$uc_module16\_//) { last; }
+	}
+
+	$name2 = $name1;
+	$name2 =~ s/(?:_)?16$//;
+	$name2 =~ s/16_fn/16_/;
+
+	$external_name = $external_name16;
+    } elsif(!defined($module16) && defined($module32)) {
+	my @uc_modules32 = split(/\s*\&\s*/, uc($module32));
+	push @uc_modules32, "wine";
+
+	foreach my $uc_module32 (@uc_modules32) {
+	    if($uc_module32 =~ /^WS2_32$/) {
+		push @uc_modules32, "WSOCK32";
+	    }
+	}
+
+	$name1 = $internal_name;
+	foreach my $uc_module32 (@uc_modules32) {
+	    if($name1 =~ s/^$uc_module32\_//) { last; }
+	}
+
+	$name2 = $name1;
+	$name2 =~ s/AW$//;
+
+	$external_name = $external_name32;
+    } else {
+	my @uc_modules = split(/\s*\&\s*/, uc($module16));
+	push @uc_modules, split(/\s*\&\s*/, uc($module32));
+
+	$name1 = $internal_name;
+	foreach my $uc_module (@uc_modules) {
+	    if($name1 =~ s/^$uc_module\_//) { last; }
+	}
+
+	$name2 = $name1;
+	$external_name = $external_name32;
+    }
+
+    if(!defined($external_name)) {
+	$external_name = $internal_name;
+    }
+
+    if($options->documentation_pedantic) {
+	my $n = 0;
+	if((++$n && defined($module16) && defined($external_name16) &&
+	    $external_name16 ne "@" && $documentation !~ /\b\Q$external_name16\E\b/) ||
+	   (++$n && defined($module16) && defined($external_name16) &&
+	    $external_name16 eq "@" && $documentation !~ /\@/) ||
+	   (++$n && defined($module32) && defined($external_name32) &&
+	    $external_name32 ne "@" && $documentation !~ /\b\Q$external_name32\E\b/) ||
+	   (++$n && defined($module32) && defined($external_name32) &&
+	    $external_name32 eq "@" && $documentation !~ /\@/))
+	{
+	    my $external_name = ($external_name16, $external_name32)[($n-1)/2];
+	    $output->write("documentation: wrong or missing name ($external_name) \\\n$documentation\n");
+	}
+    } else {
+	if($documentation !~ /\b(?:\Q$external_name\E|$internal_name|$name1|$name2)\b/) {
+	    $output->write("documentation: wrong or missing name \\\n$documentation\n");
+	}
+    }
+
+    if($options->documentation_ordinal) {
+	if(defined($module16)) {
+	    my $ordinal16 = $win16api->function_ordinal($internal_name);
+
+	    if(!defined($ordinal16)) {
+		$output->write("function have no ordinal\n");
+	    } else {
+		my @uc_modules16 = split(/\s*\&\s*/, uc($module16));
+		foreach my $uc_module16 (@uc_modules16) {
+		    if($documentation !~ /\b$uc_module16\.\Q$ordinal16\E/) {
+			$output->write("documentation: wrong or missing ordinal " .
+				       "expected (\U$module16\E.$ordinal16)\\\n$documentation\n");
+		    }
+		}
+	    }
+	}
+	if(defined($module32)) {
+	    my $ordinal32 = $win32api->function_ordinal($internal_name);
+
+	    if(!defined($ordinal32)) {
+		$output->write("function have no ordinal\n");
+	    } else {
+		my @uc_modules32 = split(/\s*\&\s*/, uc($module32));
+		foreach my $uc_module32 (@uc_modules32) {
+		    if($documentation !~ /\b$uc_module32\.\Q$ordinal32\E/) {
+			$output->write("documentation: wrong or missing ordinal " .
+						   "expected (\U$module32\E.$ordinal32) \\\n$documentation\n");
+		    }
+		}
+	    }
+	}
+    }
+
+    if($options->documentation_pedantic) {
+	if($documentation !~ /^ \*\s+(?:\@|\w+)(?:\s+\(\w+\.(?:\@|\d+)\))+/m) {
+	    $output->write("documentation: pedantic check failed \\\n$documentation\n");
+	}
+    }
+
+    if($options->documentation_comment_indent) {
+	if($documentation =~ /^ \*(\s*)\w+(\s*)([\(\[])\s*\w+\.\s*(?:\@|\d+)\s*([\)\]])/m) {
+	    my $indent = $1;
+	    my $spacing = $2;
+	    my $left = $3;
+	    my $right = $4;
+
+	    $indent =~ s/\t/        /g;
+	    $indent = length($indent);
+
+	    $spacing =~ s/\t/        /g;
+	    $spacing = length($spacing);
+
+	    $comment_indent{$indent}++;
+	    if($indent >= 20) {
+		$output->write("documentation: comment indent is $indent\n");
+	    }
+
+	    $comment_spacing{$spacing}++;
+	}
+    }
+
+    if($options->documentation_comment_width) {
+	if($documentation =~ /(^\/\*\*+)/) {
+	    my $width = length($1);
+
+	    $comment_width{$width}++;
+	    if($width <= 65 || $width >= 81) {
+		$output->write("comment is $width columns wide\n");
+	    }
+	}
+    }
+
+    if($options->documentation_arguments) {
+	my $n = 0;
+	for my $argument_documentation (@argument_documentations) {
+	    $n++;
+	    if($argument_documentation ne "") {
+		if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?)\].*?\*\/$/s) {
+		    $output->write("argument $n documentation: \\\n$argument_documentation\n");
+		}
+	    }
+	}
+    }
+}
+
+sub report_documentation {
+    my $options = shift;
+    my $output = shift;
+
+    if($options->documentation_comment_indent) {
+	foreach my $indent (sort(keys(%comment_indent))) {
+	    my $count = $comment_indent{$indent};
+	    $output->write("*.c: $count functions have comment that is indented $indent\n");
+	}
+    }
+
+    if($options->documentation_comment_width) {
+	foreach my $width (sort(keys(%comment_width))) {
+	    my $count = $comment_width{$width};
+	    $output->write("*.c: $count functions have comments of width $width\n");
+	}
+    }
+}
+
+1;
diff --git a/tools/winapi_check/winapi_function.pm b/tools/winapi_check/winapi_function.pm
index 50a52b5..e6b1879 100644
--- a/tools/winapi_check/winapi_function.pm
+++ b/tools/winapi_check/winapi_function.pm
@@ -121,6 +121,17 @@
     return $$argument_names;
 }
 
+sub argument_documentations {
+    my $self = shift;
+    my $argument_documentations = \${$self->{ARGUMENT_DOCUMENTATIONS}};
+
+    local $_ = shift;
+
+    if(defined($_)) { $$argument_documentations = $_; }
+    
+    return $$argument_documentations;
+}
+
 sub module16 {
     my $self = shift;
     my $module16 = \${$self->{MODULE16}};
diff --git a/tools/winapi_check/winapi_local.pm b/tools/winapi_check/winapi_local.pm
index 8c4113c..6404a6c 100644
--- a/tools/winapi_check/winapi_local.pm
+++ b/tools/winapi_check/winapi_local.pm
@@ -60,12 +60,16 @@
 	    $implemented_calling_convention = "cdecl";
 	} elsif($calling_convention =~ /^VFWAPIV|WINAPIV$/) {
 	    $implemented_calling_convention = "varargs";
-	} elsif($calling_convention = ~ /^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
+	} elsif($calling_convention =~ /^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
 	    if($implemented_return_kind =~ /^s_word|word|void$/) {
 		$implemented_calling_convention = "pascal16";
 	    } else {
 		$implemented_calling_convention = "pascal";
 	    }
+	} elsif($calling_convention =~ /^__asm$/) {
+    	    $implemented_calling_convention = "asm";
+	} else {
+    	    $implemented_calling_convention = "cdecl";
 	}
     } elsif($winapi->name eq "win32") {
 	if($calling_convention =~ /^__cdecl$/) {
@@ -78,6 +82,8 @@
 	    } else {
 		$implemented_calling_convention = "stdcall";
 	    }
+	} elsif($calling_convention =~ /^__asm$/) {
+    	    $implemented_calling_convention = "asm";
 	} else {
 	    $implemented_calling_convention = "cdecl";
 	}
@@ -95,7 +101,8 @@
          (($winapi->name eq "win16" && $implemented_calling_convention =~ /^pascal/))))
     {
 	# correct
-    } elsif($implemented_calling_convention ne $declared_calling_convention && 
+    } elsif($implemented_calling_convention ne $declared_calling_convention &&
+       $implemented_calling_convention ne "asm" &&
        !($declared_calling_convention =~ /^pascal/ && $forbidden_return_type) &&
        !($implemented_calling_convention =~ /^cdecl|varargs$/ && $declared_calling_convention =~ /^cdecl|varargs$/))
     {
@@ -182,7 +189,10 @@
 		}
 	    }
 	}
-        if($#argument_kinds != $#declared_argument_kinds) {
+
+        if($#argument_kinds != $#declared_argument_kinds &&
+	   $implemented_calling_convention ne "asm")
+	{
 	    if($options->argument_count) {
 		$output->write("argument count differs: " . 
 		    ($#argument_types + 1) . " != " . 
diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm
index c45b21d..9eb882a 100644
--- a/tools/winapi_check/winapi_parser.pm
+++ b/tools/winapi_check/winapi_parser.pm
@@ -303,6 +303,11 @@
 	    if($level == 0) {
 		&$function_end;
 	    }
+	} elsif(/__ASM_GLOBAL_FUNC\(\s*(.*?)\s*,/s) {
+	    $_ = $'; $again = 1;
+	    my @arguments = ();
+	    &$function_begin($documentation, "", "void", "__asm", $1, \@arguments);
+	    &$function_end;
 	} elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments = ("HDC16");