diff --git a/tools/winapi/tests.dat b/tools/winapi/tests.dat
index 4d5484c1acbea6bfa82c97c2afc04f140c4cea6a..72379dfe5b6e8c8e9ec524f7c8bfff3d17212d72 100644
--- a/tools/winapi/tests.dat
+++ b/tools/winapi/tests.dat
@@ -47,7 +47,11 @@ EMR
 EMRABORTPATH
 EMRANGLEARC
 EMRARC
+EMRARCTO
+EMRBEGINPATH
 EMRBITBLT
+EMRCHORD
+EMRCLOSEFIGURE
 EMRCREATEBRUSHINDIRECT
 !EMRCREATECOLORSPACE
 !EMRCREATECOLORSPACEW
@@ -58,6 +62,7 @@ EMRCREATEPEN
 EMRDELETECOLORSPACE
 EMRDELETEOBJECT
 EMRELLIPSE
+EMRENDPATH
 EMREOF
 EMREXCLUDECLIPRECT
 EMREXTCREATEFONTINDIRECTW
@@ -65,45 +70,80 @@ EMREXTCREATEPEN
 EMREXTFLOODFILL
 EMREXTSELECTCLIPRGN
 EMREXTTEXTOUTA
+EMREXTTEXTOUTW
 EMRFILLPATH
 EMRFILLRGN
+EMRFLATTENPATH
 EMRFORMAT
 EMRFRAMERGN
 EMRGDICOMMENT
 EMRGLSBOUNDEDRECORD
 EMRGLSRECORD
 EMRINVERTRGN
+EMRINTERSECTCLIPRECT
 EMRLINETO
 EMRMASKBLT
 EMRMODIFYWORLDTRANSFORM
+EMRMOVETOEX
 EMROFFSETCLIPRGN
+EMRPAINTRGN
+EMRPIE
 EMRPIXELFORMAT
 EMRPLGBLT
+EMRPOLYBEZIER
+EMRPOLYBEZIERTO
 EMRPOLYDRAW
+EMRPOLYGON
 EMRPOLYLINE
+EMRPOLYLINETO
+EMRPOLYPOLYGON
 EMRPOLYPOLYLINE
 EMRPOLYTEXTOUTA
+EMRPOLYTEXTOUTW
+EMRREALIZEPALETTE
+EMRRECTANGLE
 EMRRESIZEPALETTE
 EMRRESTOREDC
 EMRROUNDRECT
+EMRSAVEDC
 EMRSCALEVIEWPORTEXTEX
+EMRSCALEWINDOWEXTEX
 EMRSELECTCLIPPATH
+EMRSELECTCOLORSPACE
+EMRSELECTOBJECT
 EMRSELECTPALETTE
 EMRSETARCDIRECTION
 EMRSETBKCOLOR
+EMRSETBKMODE
 EMRSETBRUSHORGEX
 EMRSETCOLORADJUSTMENT
+!EMRSETCOLORSPACE
 EMRSETDIBITSTODEVICE
+EMRSETICMMODE
+!EMRSETLAYOUT
+EMRSETMAPMODE
 EMRSETMAPPERFLAGS
+EMRSETMETARGN
 EMRSETMITERLIMIT
 !EMRSETPALETTEENTRIES
 EMRSETPIXELV
+EMRSETPOLYFILLMODE
+EMRSETROP2
+EMRSETSTRETCHBLTMODE
+EMRSETTEXTALIGN
+EMRSETTEXTCOLOR
 !EMRSETTEXTJUSTIFICATION
 EMRSETVIEWPORTEXTEX
+EMRSETVIEWPORTORGEX
+EMRSETWINDOWEXTEX
+EMRSETWINDOWORGEX
 EMRSETWORLDTRANSFORM
 EMRSTRETCHBLT
 EMRSTRETCHDIBITS
+EMRSTROKEANDFILLPATH
+EMRSTROKEPATH
 EMRTEXT
+EMRWIDENPATH
 ENHMETAHEADER: !szlMicrometers
 ENHMETARECORD
 ENHMFENUMPROC
@@ -178,7 +218,7 @@ LPGRADIENT_RECT
 LPGRADIENT_TRIANGLE
 LPHANDLETABLE
 LPKERNINGPAIR
-LPLOCALESIGNATUREE
+LPLOCALESIGNATURE
 LPLOGBRUSH
 LPLOGCOLORSPACEA
 LPLOGCOLORSPACEW
@@ -325,6 +365,7 @@ PEMRSETBRUSHORGEX
 PEMRSETCOLORADJUSTMENT
 !PEMRSETCOLORSPACE
 PEMRSETDIBITSTODEVICE
+PEMRSETICMMODE
 !PEMRSETLAYOUT
 PEMRSETMAPMODE
 PEMRSETMAPPERFLAGS
@@ -359,7 +400,7 @@ PGRADIENT_RECT
 PGRADIENT_TRIANGLE
 PHANDLETABLE
 PIXELFORMATDESCRIPTOR
-PLOCALESIGNATUR
+PLOCALESIGNATURE
 PLOGBRUSH
 PLOGFONTA
 PLOGFONTW
@@ -428,17 +469,18 @@ CRITICAL_SECTION
 CRITICAL_SECTION_DEBUG
 DCB
 DEBUG_EVENT
-ENUMRESLANGPROCA
-ENUMRESLANGPROCW
-ENUMRESNAMEPROCA
-ENUMRESNAMEPROCW
-ENUMRESTYPEPROCA
-ENUMRESTYPEPROCW
+!ENUMRESLANGPROCA
+!ENUMRESLANGPROCW
+!ENUMRESNAMEPROCA
+!ENUMRESNAMEPROCW
+!ENUMRESTYPEPROCA
+!ENUMRESTYPEPROCW
 EXCEPTION_DEBUG_INFO
 EXIT_PROCESS_DEBUG_INFO
 EXIT_THREAD_DEBUG_INFO
 !FILETIME
 HW_PROFILE_INFOA
+HW_PROFILE_INFOW
 LDT_ENTRY
 LOAD_DLL_DEBUG_INFO
 LPBY_HANDLE_FILE_INFORMATION
@@ -520,7 +562,7 @@ SYSTEMTIME
 SYSTEM_POWER_STATUS
 TIME_ZONE_INFORMATION
 UNLOAD_DLL_DEBUG_INFO
-WAITORTIMERCALLBACK
+!WAITORTIMERCALLBACK
 WIN32_FILE_ATTRIBUTE_DATA
 WIN32_FIND_DATAA
 WIN32_FIND_DATAW
@@ -560,9 +602,11 @@ CCHAR
 CHAR
 COLORREF
 !CONTEXT
+!CONTEXT86
 !DATE
 !DOUBLE
 DWORD
+DWORD32
 !DWORD64
 !DWORDLONG
 DWORD_PTR
@@ -576,6 +620,7 @@ FLOATING_SAVE_AREA
 FPO_DATA
 GENERIC_MAPPING
 GLOBALHANDLE
+HALF_PTR
 HANDLE
 HCURSOR
 HFILE
@@ -617,7 +662,10 @@ IMAGE_THUNK_DATA
 IMAGE_TLS_DIRECTORY
 IMAGE_VXD_HEADER
 INT
+!INT16
+INT32
 !INT64
+!INT8
 INT_PTR
 LANGID
 !LARGE_INTEGER
@@ -625,6 +673,7 @@ LCID
 LIST_ENTRY
 LOCALHANDLE
 LONG
+LONG32
 !LONG64
 !LONGLONG
 LONG_PTR
@@ -664,7 +713,7 @@ PCSTR
 PCWCH
 PCWSTR
 !PEXCEPTION_FRAME
-PEXCEPTION_HANDLER
+!PEXCEPTION_HANDLER
 PEXCEPTION_POINTERS
 PEXCEPTION_RECORD
 PFLOATING_SAVE_AREA
@@ -713,6 +762,9 @@ PMESSAGE_RESOURCE_BLOCK
 PMESSAGE_RESOURCE_DATA
 PMESSAGE_RESOURCE_ENTRY
 PNT_TIB
+POINT
+POINTL
+POINTS
 PPOINT
 PPOINTS
 PPRIVILEGE_SET
@@ -741,8 +793,11 @@ PULARGE_INTEGER
 PVOID
 PWCH
 PWSTR
+RECT
+RECTL
 RTL_CRITICAL_SECTION
 RTL_CRITICAL_SECTION_DEBUG
+RTL_RESOURCE_DEBUG
 SECURITY_CONTEXT_TRACKING_MODE
 SECURITY_DESCRIPTOR
 SECURITY_DESCRIPTOR_CONTROL
@@ -754,9 +809,11 @@ SID
 SID_AND_ATTRIBUTES
 SID_IDENTIFIER_AUTHORITY
 SINGLE_LIST_ENTRY
+SIZE
 SIZEL
 SIZE_T
 SSIZE_T
+!STACK_FRAME_HEADER
 SYSTEM_ALARM_ACE
 SYSTEM_AUDIT_ACE
 TCHAR
@@ -769,11 +826,16 @@ TOKEN_SOURCE
 !TOKEN_STATISTICS
 TOKEN_USER
 UCHAR
+UHALF_PTR
 UINT
+!UINT16
+UINT32
 !UINT64
+!UINT8
 UINT_PTR
 !ULARGE_INTEGER
 ULONG
+ULONG32
 !ULONG64
 !ULONGLONG
 ULONG_PTR
@@ -784,6 +846,7 @@ WORD
 WPARAM
 __int16
 __int32
+!__int64
 __int8
 
 %%%dlls/user/tests
@@ -816,6 +879,7 @@ CBTACTIVATESTRUCT
 CBT_CREATEWNDA
 CBT_CREATEWNDW
 CLIENTCREATESTRUCT
+COMBOBOXINFO
 COMPAREITEMSTRUCT
 COPYDATASTRUCT
 CREATESTRUCTA
@@ -829,19 +893,15 @@ DESKTOPENUMPROCA
 DESKTOPENUMPROCW
 DLGITEMTEMPLATE
 DLGPROC
-DLGPROC
 DLGTEMPLATE
 !DRAWITEMSTRUCT
 DRAWSTATEPROC
-DRAWSTATEPROC
 DRAWTEXTPARAMS
 EDITWORDBREAKPROCA
-EDITWORDBREAKPROCA
-EDITWORDBREAKPROCW
 EDITWORDBREAKPROCW
 EVENTMSG
 FILTERKEYS
-GRAYSTRINGPROC
+GUITHREADINFO
 GRAYSTRINGPROC
 HARDWAREHOOKSTRUCT
 HARDWAREINPUT
@@ -853,7 +913,6 @@ HELPWININFOW
 HIGHCONTRASTA
 HIGHCONTRASTW
 HOOKPROC
-HOOKPROC
 ICONINFO
 ICONMETRICSA
 ICONMETRICSW
@@ -974,8 +1033,6 @@ MSLLHOOKSTRUCT
 MULTIKEYHELPA
 MULTIKEYHELPW
 NAMEENUMPROCA
-NAMEENUMPROCA
-NAMEENUMPROCW
 NAMEENUMPROCW
 NCCALCSIZE_PARAMS
 NMHDR
@@ -1024,12 +1081,8 @@ PNONCLIENTMETRICSA
 PNONCLIENTMETRICSW
 PPAINTSTRUCT
 PROPENUMPROCA
-PROPENUMPROCA
-PROPENUMPROCEXA
 PROPENUMPROCEXA
 PROPENUMPROCEXW
-PROPENUMPROCEXW
-PROPENUMPROCW
 PROPENUMPROCW
 PWINDOWINFO
 PWINDOWPLACEMENT
@@ -1040,7 +1093,6 @@ PWNDCLASSEXW
 PWNDCLASSW
 SCROLLINFO
 SENDASYNCPROC
-SENDASYNCPROC
 SERIALKEYSA
 SERIALKEYSW
 SOUNDSENTRYA
@@ -1048,7 +1100,6 @@ SOUNDSENTRYW
 STICKYKEYS
 STYLESTRUCT
 TIMERPROC
-TIMERPROC
 TOGGLEKEYS
 TPMPARAMS
 TRACKMOUSEEVENT
@@ -1056,7 +1107,6 @@ WINDOWINFO: !dwWindowStatus
 !WINDOWPLACEMENT
 WINDOWPOS
 WINEVENTPROC
-WINEVENTPROC
 WINSTAENUMPROCA
 WINSTAENUMPROCW
 WNDCLASSA
@@ -1064,5 +1114,4 @@ WNDCLASSEXA
 WNDCLASSEXW
 WNDCLASSW
 WNDENUMPROC
-WNDENUMPROC
 WNDPROC
diff --git a/tools/winapi/winapi_test b/tools/winapi/winapi_test
index b2402b1f88acce3444d48a3913a6f897b177e76d..9ed317c173476550d78c4e28cf38aedd88e4cdab 100755
--- a/tools/winapi/winapi_test
+++ b/tools/winapi/winapi_test
@@ -225,11 +225,7 @@ sub _find_align_kind_size {
 	$align = 4;
 	$kind = "unsigned";
 	$size = 4;
-    } elsif (/^LP(?:CSTR|CWSTR|DWORD|STR|VOID|THREAD_START_ROUTINE|WSTR)$/) {
-	$align = 4;
-	$kind = "pointer";
-	$size = 4;
-    } elsif (/^(?:(?:MSGBOX)CALLBACK[AW]?|(?:FAR|WND)PROC[AW]?)$/) {
+    } elsif (/^LP(?:CSTR|CWSTR|DWORD|VOID|WSTR)$/) {
 	$align = 4;
 	$kind = "pointer";
 	$size = 4;
@@ -247,7 +243,10 @@ sub _find_align_kind_size {
 	    $output->write("$type_name: can't parse type\n");
 	    $size_parse_reported{$_} = 1;
 	}
-
+    } elsif (/^\w+\s*\((?:\s*CALLBACK|\s*NTAPI|\s*WINAPI)?\s*\*\s*\)\s*\(.*?\)$/) { 
+	$align = 4;
+	$kind = "pointer";
+	$size = 4;    
     }
 
     my $align2;
@@ -627,17 +626,24 @@ sub output_test_pack_type {
 		if (defined($type2)) {
 		    return $type2;
 		} else {
-		    $output->write("$type_name2: type not found (ignored)\n");
+		    if ($type_name2 !~ /^(?:PVOID|VOID|void)$/) {
+			$output->write("$type_name2: warning: type not found 1\n");
+		    }
 		    return undef;
 		}
-	    } else {
+	    } elsif ($type_name2 =~ /^\w+$/) {
 		my $type2 = $$type_name2type{$type_name2};
 		if (defined($type2)) {
 		    return &$dereference_type($type2);
 		} else {
-		    $output->write("$type_name2: type not found (ignored)\n");
+		    $output->write("$type_name2: warning: type not found\n");
 		    return undef;
 		}
+	    } elsif ($type_name2 =~ /^\w+\s*\((?:\s*CALLBACK|\s*NTAPI|\s*WINAPI)?\s*\*\s*\)\s*\(.*?\)$/) {
+		return undef;
+	    } else {
+		$output->write("$type_name2: warning: type can't be parsed\n");
+		return undef;
 	    }
 	};
 
@@ -653,7 +659,7 @@ sub output_test_pack_type {
 	    if (!$optional && !scalar(keys(%$optional_fields2)) && defined($type_align2) && defined($type_size2)) {
 		print OUT "    TEST_TYPE_POINTER($type_name, $type_size2, $type_align2);\n";
 	    } else {
-		$output->write("$type_name: type size not found (ignored)\n");
+		# $output->write("$type_name: warning: type size not found\n");
 	    }
 	}
     } elsif ($type_kind eq "signed") {
@@ -715,12 +721,13 @@ sub output_test_pack {
     my $test_dir = shift;
     my $test = shift;
 
+    my $type_names_used = shift;
+
     $output->prefix("$test_dir: $test: ");
 
     my @headers = $tests->get_section($test_dir, $test, "header");
     my @type_names = $tests->get_section($test_dir, $test, "type");
 
-    my %type_name_not_used;
     my %type_name2optional;
     my %type_name2optional_fields;
 
@@ -742,7 +749,6 @@ sub output_test_pack {
 	} 
 
 	$type_name2optional_fields{$type_name} = $optional_fields;
-	$type_name_not_used{$type_name} = 1;
     }
 
     foreach my $header (@headers) {
@@ -751,31 +757,25 @@ sub output_test_pack {
 	foreach my $_type_name (@type_names) {
 	    my $type_name = $_type_name;
 
-	    next if $type_name =~ /^!/;
+	    my $skip = ($type_name =~ s/^!//);
 	    $type_name =~ s/:.*?$//;
-
 	    my $type = $$type_name2type{$type_name};
 	    if (!defined($type)) {
 		next;
 	    }
-	    $type_name_not_used{$type_name} = 0;
-	    
-	    output_test_pack_type(\*OUT, $type_name2type, \%type_name2optional, \%type_name2optional_fields, $type_name, $type);
-	    output_test_pack_fields(\*OUT, $type_name2type, \%type_name2optional, \%type_name2optional_fields, $type_name, $type, 0);
+	    $$type_names_used{$type_name} = $skip ? -1 : 1;
+	    next if $skip;
+
+	    print OUT "static void test_${test}_$type_name(void)\n";
+	    print OUT "{\n";
+	    output_test_pack_type(\*OUT, $type_name2type, \%type_name2optional, \%type_name2optional_fields,
+				  $type_name, $type);
+	    output_test_pack_fields(\*OUT, $type_name2type, \%type_name2optional, \%type_name2optional_fields, 
+				    $type_name, $type, 0);
+	    print OUT "}\n";
 	    print OUT "\n";
 	}
     }
-
-    foreach my $_type_name (@type_names) {
-	my $type_name = $_type_name;
-
-	next if $type_name =~ /^!/;
-	$type_name =~ s/:.*?$//;
-
-	if ($type_name_not_used{$type_name}) {
-	    # $output->write("$type_name: type not found (ignored)\n");
-	}
-    }
 }
 
 
@@ -788,18 +788,27 @@ sub output_file {
     my $test_dir = shift;
     my @tests = @{(shift)};
 
+    my $type_names_used = shift;
+
     output_header(\*OUT, $test_dir, \@tests);
 
     foreach my $test (@tests) {
-	print OUT "void test_$test(void)\n";
-	print OUT "{\n";
+	my %type_names_used2;
 
 	if ($test eq "pack") {
-	    output_test_pack(\*OUT, $test_dir, $test);
+	    output_test_pack(\*OUT, $test_dir, $test, \%type_names_used2);
 	} else {
 	    die "no such test ($test)\n";
 	}
 
+	print OUT "static void test_$test(void)\n";
+	print OUT "{\n";
+	foreach my $type_name (sort(keys(%type_names_used2))) {
+	    $$type_names_used{$type_name} = $type_names_used2{$type_name};
+	    if ($type_names_used2{$type_name} > 0) {
+		print OUT "    test_${test}_$type_name();\n";
+	    }
+	}
 	print OUT "}\n";
 	print OUT "\n";
     }
@@ -812,8 +821,38 @@ sub output_file {
 ########################################################################
 # main
 
+my %type_names_used = ();
+
 my @test_dirs = $tests->get_test_dirs();
 foreach my $test_dir (@test_dirs) {
     my $file = "$wine_dir/$test_dir/generated.c";
-    replace_file($file, \&output_file, $test_dir, \@tests);
+    replace_file($file, \&output_file, $test_dir, \@tests, \%type_names_used);
+}
+
+foreach my $header (sort(keys(%file2types))) {
+    $output->prefix("$header: ");
+    $header =~ s%^include/%%;
+    my $type_name2type = $file2types{"include/$header"};
+    foreach my $_type_name (sort(keys(%$type_name2type))) {
+	my $type_name = $_type_name;
+
+	if (!exists($type_names_used{$type_name})) {
+	    $output->write("$type_name: type not used\n");
+	}
+    }
+}
+
+$output->prefix("$winapi_dir/tests.dat: ");
+foreach my $type_name (sort(keys(%type_names_used))) {
+    my $found = 0;
+    foreach my $header (sort(keys(%file2types))) {
+	my $type_name2type = $file2types{"include/$header"};
+	if (exists($type_name2type{$type_name})) {
+	    $found = 1;
+	}
+    }
+
+    if (!$found) {
+	$output->write("$type_name: type not used\n");
+    }
 }