diff --git a/tools/winapi_check/win16/compobj.api b/tools/winapi_check/win16/compobj.api
index cd5a8f45a28304aa596b37862cd6ec00d87cdc91..7c1eb3bd2410fd69a1ea1df2851731d5c1d62423 100644
--- a/tools/winapi_check/win16/compobj.api
+++ b/tools/winapi_check/win16/compobj.api
@@ -31,6 +31,10 @@ REFCLSID
 REFGUID
 REFIID
 
+%segptr
+
+SEGPTR
+
 %str
 
 LPCOLESTR16
diff --git a/tools/winapi_check/win32/gdi32.api b/tools/winapi_check/win32/gdi32.api
index ee4fd7d0bf24e10462c07d3a4098d6103c0dc149..659f0d8634fe2bb18560f6668f19fadf1f94d8c9 100644
--- a/tools/winapi_check/win32/gdi32.api
+++ b/tools/winapi_check/win32/gdi32.api
@@ -24,9 +24,10 @@ LPARAM
 UINT
 WORD
 
-%long --forbidden
+%long --extension
 
-int
+HDC16
+HMETAFILE16
 
 %ptr
 
@@ -62,6 +63,7 @@ LPABC
 LPABCFLOAT
 LPBYTE
 LPCOLORADJUSTMENT
+LPCHARSETINFO
 LPCVOID
 LPDEVMODEA
 LPDWORD
@@ -105,7 +107,7 @@ TEXTMETRICW *
 XFORM *
 void *
 
-%ptr # --forbidden
+%ptr --extension
 
 FARPROC16
 
diff --git a/tools/winapi_check/win32/kernel32.api b/tools/winapi_check/win32/kernel32.api
index 16fcfd4651321dba3d7666f61b77ddb3a3f31d19..4c900059726790e3908a6b2f4ef1b6083e2a1d98 100644
--- a/tools/winapi_check/win32/kernel32.api
+++ b/tools/winapi_check/win32/kernel32.api
@@ -31,12 +31,17 @@ ULONG_PTR
 
 %long # --forbidden
 
+int
+
+%long --extension
+
 BOOL16
 HGLOBAL16
 HINSTANCE16
 HMODULE16
+HRSRC16
+HTASK16
 UINT16
-int
 
 %ptr
 
@@ -145,11 +150,8 @@ va_list *
 
 %ptr --extension
 
-BUILTIN16_DESCRIPTOR *
-
-%ptr # --forbidden
-
 FARPROC16
+BUILTIN16_DESCRIPTOR *
 SEGPTR
 
 %str
diff --git a/tools/winapi_check/win32/ntdll.api b/tools/winapi_check/win32/ntdll.api
index 1947432711967601f2472141777fe295fff595d3..f1150340f77f5accd36a30e04de55cef193b4f02 100644
--- a/tools/winapi_check/win32/ntdll.api
+++ b/tools/winapi_check/win32/ntdll.api
@@ -107,11 +107,13 @@ void *
 
 %ptr --extension
 
+EXCEPTION_FRAME **
 GUID *
 WCHAR *
 char *
 char ***
 enum __DEBUG_CLASS
+enum request
 va_list
 
 %str
diff --git a/tools/winapi_check/win32/user32.api b/tools/winapi_check/win32/user32.api
index 7aa268b28f076cd8f3047fbcf537485f0c74a381..d09215db9a8f99f9d153bfcadf179480fe69af18 100644
--- a/tools/winapi_check/win32/user32.api
+++ b/tools/winapi_check/win32/user32.api
@@ -23,6 +23,7 @@ HHOOK
 HICON
 HINSTANCE
 HKL
+HPEN
 HMENU
 HMONITOR
 HRESULT
@@ -43,9 +44,18 @@ WPARAM
 
 %long # --forbidden
 
-HMODULE16
 int
 
+%long --extension
+
+INT16
+HANDLE16
+HMODULE16
+HINSTANCE16
+HWND16
+UINT16
+WPARAM16
+
 %longlong
 
 POINT 
@@ -124,6 +134,11 @@ WNDENUMPROC
 WNDPROC
 va_list
 
+%ptr --extension
+
+DLGPROC16
+WNDPROC16
+
 %str
 
 LPSTR
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index bd6f9e57176f64906acba89b8fc03ceb5380e0ba..c56531f669c3797a13dba58e85f37a982755dba2 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -439,6 +439,7 @@ foreach my $file ($options->c_files) {
 	       (defined($module16) || defined($module32)) &&
 	       $linkage ne "extern" && $statements)
 	    {
+		my $external_name;
 		my $name1;
 		my $name2;
 		
@@ -451,9 +452,11 @@ foreach my $file ($options->c_files) {
 			if($name1 =~ s/^$uc_module16\_//) { last; }
 		    }
 
-		    # FIXME: This special case is becuase of a very ugly kludge that should be fixed IMHO
 		    $name2 = $name1;
-		    $name2 = s/^(.*?)16_fn(.*?)$/$116_$2/;
+		    $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";
@@ -471,6 +474,8 @@ foreach my $file ($options->c_files) {
 
 		    $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));
@@ -481,9 +486,14 @@ foreach my $file ($options->c_files) {
 		    }
 
 		    $name2 = $name1;
+		    $external_name = $external_name32;
+		}
+
+		if(!defined($external_name)) {
+		    $external_name = $internal_name;
 		}
 
-		if($documentation !~ /\b($internal_name|$name1|$name2)\b/) {
+		if($documentation !~ /\b(\Q$external_name\E|$internal_name|$name1|$name2)\b/) {
 		    $output->write("documentation: \\\n$documentation\n");
 		}
 
@@ -503,7 +513,7 @@ foreach my $file ($options->c_files) {
 		    for my $argument_documentation (@argument_documentations) {
 			$n++;
 			if($argument_documentation ne "") {
-			    if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out)\].*?\*\/$/) {
+			    if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?)\].*?\*\/$/s) {
 				$output->write("argument $n documentation: \\\n$argument_documentation\n");
 			    }
 			}
diff --git a/tools/winapi_check/winapi_options.pm b/tools/winapi_check/winapi_options.pm
index 0536dcd21dac6f95e1c2488616cb08625b35736d..c7b899befb6f3c1614f1ae2a565175711a199e18 100644
--- a/tools/winapi_check/winapi_options.pm
+++ b/tools/winapi_check/winapi_options.pm
@@ -289,6 +289,9 @@ sub new {
     return $self;
 }
 
+sub DESTROY {
+}
+
 sub options_set {
     my $self = shift;
 
diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm
index 18c8f7136f4cf84da8a6a745007f4693d5c11e4b..a1a04f9845b9963c18d27ed851d4239e56c35eb4 100644
--- a/tools/winapi_check/winapi_parser.pm
+++ b/tools/winapi_check/winapi_parser.pm
@@ -123,11 +123,11 @@ sub parse_c_file {
 	}
 
 	my $documentation;
-	my @argument_documentations;
+	my @argument_documentations = ();
 	{
 	    my $n = $#comments;
 	    while($n >= 0 && ($comments[$n] !~ /^\/\*\*/ ||
-			      $comments[$n] =~ /^\/\*\*+\//)) 
+			      $comments[$n] =~ /^\/\*\*+\/$/)) 
 	    {
 		$n--;
 	    }
@@ -135,6 +135,10 @@ sub parse_c_file {
 	    if(defined($comments[$n]) && $n >= 0) {
 		$documentation = $comments[$n];
 		for(my $m=$n+1; $m <= $#comments; $m++) {
+		    if($comments[$m] =~ /^\/\*\*+\/$/) {
+			@argument_documentations = ();
+			next;
+		    }
 		    push @argument_documentations, $comments[$m];
 		}
 	    } else {