diff --git a/tools/winapi/msvcmaker b/tools/winapi/msvcmaker
index 7a6bfc581e46779845ddc08d1ea96a58b8ca9a7d..de4a250505adefeac207b0ef5a0919cb18f9c726 100755
--- a/tools/winapi/msvcmaker
+++ b/tools/winapi/msvcmaker
@@ -11,48 +11,14 @@ BEGIN {
 
 use config qw(&file_directory &get_spec_files &get_makefile_in_files $current_dir $wine_dir);
 use output qw($output);
+use util qw(replace_file);
 
-########################################################################
-# _compare_files
-
-sub _compare_files {
-    my $file1 = shift;
-    my $file2 = shift;
-
-    local $/ = undef;
-
-    return -1 if !open(IN, "< $file1");
-    my $s1 = <IN>;
-    close(IN);
+use msvcmaker_options qw($options);
 
-    return 1 if !open(IN, "< $file2");
-    my $s2 = <IN>;
-    close(IN);
-
-    return $s1 cmp $s2;
-}
-
-########################################################################
-# replace_file
-
-sub replace_file {
-    my $filename = shift;
-    my $function = shift;
-
-    open(OUT, "> $filename.tmp") || die "Can't open file '$filename.tmp'";
-
-    my $result = &$function(\*OUT, @_);
-
-    close(OUT);
-
-    if($result && _compare_files($filename, "$filename.tmp")) {
-        unlink("$filename");
-        rename("$filename.tmp", $filename);
-    } else {
-        unlink("$filename.tmp");
-    }
-
-    return $result;
+if($options->progress) {
+    $output->enable_progress;
+} else {
+    $output->disable_progress;
 }
 
 ########################################################################
@@ -66,9 +32,17 @@ my $wine = 1;
 my $output_prefix_dir = "Output";
 my $no_release = 1;
 
+if ($options->wine || $options->winetest) {
+    foreach my $spec_file (@spec_files) {
+	read_spec_file($spec_file);
+    }
+}
+
 my %modules;
 
-foreach my $spec_file (@spec_files) {
+sub read_spec_file {
+    my $spec_file = shift;
+
     my $module = $spec_file;
     $module =~ s%^.*?([^/]+)\.spec$%$1%;
     $module .= ".dll" if $module !~ /\./;
@@ -289,6 +263,8 @@ MAKEFILE_IN: foreach my $makefile_in_file (@makefile_in_files) {
 	    ($header_files, my $local_header_files) = filter_files($header_files, "$dir2/");
 	    ($resource_files, my $local_resource_files) = filter_files($resource_files, "$dir2/");
 
+	    $modules{$module}{wine} = 1;
+	    $modules{$module}{winetest} = 0;
 	    $modules{$module}{project} = $project;
 	    $modules{$module}{type} = $type;
 	    $modules{$module}{dsp_file} = $dsp_file;
@@ -313,6 +289,8 @@ MAKEFILE_IN: foreach my $makefile_in_file (@makefile_in_files) {
 	    ($header_files, my $local_header_files) = filter_files($header_files, "/$dir/");
 	    ($resource_files, my $local_resource_files) = filter_files($resource_files, "/$dir/");
 
+	    $modules{$module}{wine} = 1;
+	    $modules{$module}{winetest} = 0;
 	    $modules{$module}{project} = $project;
 	    $modules{$module}{type} = $type;
 	    $modules{$module}{dsp_file} = $dsp_file;
@@ -340,6 +318,8 @@ MAKEFILE_IN: foreach my $makefile_in_file (@makefile_in_files) {
 	    ($header_files, my $local_header_files) = filter_files($header_files, "$dir2/");
 	    ($resource_files, my $local_resource_files) = filter_files($resource_files, "$dir2/");
 
+	    $modules{$module}{wine} = 1;
+	    $modules{$module}{winetest} = 0;
 	    $modules{$module}{project} = $project;
 	    $modules{$module}{type} = $type;
 	    $modules{$module}{dsp_file} = $dsp_file;
@@ -351,6 +331,8 @@ MAKEFILE_IN: foreach my $makefile_in_file (@makefile_in_files) {
 	}
     }
 
+    $modules{$module}{wine} = 1;
+    $modules{$module}{winetest} = 0;
     $modules{$module}{project} = $project;
     $modules{$module}{type} = $type;
     $modules{$module}{dsp_file} = $dsp_file;
@@ -403,6 +385,9 @@ foreach my $dsp_file (keys(%wine_test_dsp_files)) {
     }
     my $module = "$project.$type";
 
+    $modules{$module}{wine} = 0;
+    $modules{$module}{winetest} = 1;
+
     $modules{$module}{project} = $project;
     $modules{$module}{type} = $type;
     $modules{$module}{dsp_file} = $dsp_file;
@@ -421,13 +406,21 @@ foreach my $module (sort(keys(%modules))) {
     }
 }
 
+my @modules = ();
+foreach my $module (sort(keys(%modules))) {
+    if (($options->wine && $modules{$module}{wine}) ||
+	($options->winetest && $modules{$module}{winetest}))
+    {
+	push @modules, $module;
+    }
+}
+
 my $progress_output;
 my $progress_current = 0;
-my $progress_max = scalar(keys(%modules));
+my $progress_max = scalar(@modules);
 
-foreach my $module (sort(keys(%modules))) {
+foreach my $module (@modules) {
     my $dsp_file = $modules{$module}{dsp_file};
-
     replace_file("$wine_dir/$dsp_file", \&_generate_dsp, $module);
 }
 
@@ -963,11 +956,11 @@ sub _generate_dsw_footer {
     print OUT "\r\n";
 }
 
-do {
+if ($options->wine) {
     my $dsw_file = "wine.dsw";
     $output->progress("$dsw_file");
     replace_file("$wine_dir/$dsw_file", \&_generate_wine_dsw);
-};
+}
 
 sub _generate_wine_dsw {
     local *OUT = shift;
@@ -1023,11 +1016,11 @@ sub _generate_wine_dsw {
     return 1;
 }
 
-do {
+if ($options->winetest) {
     my $dsw_file = "winetest.dsw";
     $output->progress("$dsw_file");
     replace_file("$wine_dir/$dsw_file", \&_generate_winetest_dsw);
-};
+}
 
 sub _generate_winetest_dsw {
     local *OUT = shift;
@@ -1053,7 +1046,7 @@ sub _generate_winetest_dsw {
     _generate_dsw_footer(\*OUT);
 }
 
-do {
+if ($options->winetest) {
     foreach my $module (sort(keys(%modules))) {
 	next if $module !~ /_test\.exe$/;
 
@@ -1066,7 +1059,7 @@ do {
 
 	replace_file("$wine_dir/$testlist_c", \&_generate_testlist_c, \@tests);
     }
-};
+}
 
 sub _generate_testlist_c {
     local *OUT = shift;
@@ -1092,13 +1085,13 @@ sub _generate_testlist_c {
     print OUT "};\n";
 }
 
-do {
+if ($options->wine) {
     my $config_h = "include/config.h";
 
     $output->progress("$config_h");
 
     replace_file("$wine_dir/$config_h", \&_generate_config_h);
-};
+}
 
 sub _generate_config_h {
     local *OUT = shift;
diff --git a/tools/winapi/msvcmaker_options.pm b/tools/winapi/msvcmaker_options.pm
new file mode 100644
index 0000000000000000000000000000000000000000..e459e4b6e10da2d28a413b62f9d272a446ab08d4
--- /dev/null
+++ b/tools/winapi/msvcmaker_options.pm
@@ -0,0 +1,54 @@
+#
+# Copyright 2002 Patrik Stridvall
+#
+# 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
+#
+
+package msvcmaker_options;
+use base qw(options);
+
+use strict;
+
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw($options);
+
+use options qw($options &parse_comma_list);
+
+my %options_long = (
+    "debug" => { default => 0, description => "debug mode" },
+    "help" => { default => 0, description => "help mode" },
+    "verbose" => { default => 0, description => "verbose mode" },
+
+    "progress" => { default => 1, description => "show progress" },
+
+    "wine" => { default => 1, description => "generate workspace and project files for building Winelib" },
+    "winetest" => { default => 1, description => "generate workspace and project files for building Wine tests" },
+);
+
+my %options_short = (
+    "d" => "debug",
+    "?" => "help",
+    "v" => "verbose"
+);
+
+my $options_usage = "usage: msvcmaker [--help]\n";
+
+$options = '_options'->new(\%options_long, \%options_short, $options_usage);
+
+1;
diff --git a/tools/winapi/util.pm b/tools/winapi/util.pm
index dfbf834fd09ab500ef34af5f88f6f6249bf7c45a..d8e536147244c9eb52fcd1c396a4ef9336431d9f 100644
--- a/tools/winapi/util.pm
+++ b/tools/winapi/util.pm
@@ -31,6 +31,26 @@ require Exporter;
 @EXPORT_OK = qw();
 %EXPORT_TAGS = ();
 
+########################################################################
+# _compare_files
+
+sub _compare_files {
+    my $file1 = shift;
+    my $file2 = shift;
+
+    local $/ = undef;
+
+    return -1 if !open(IN, "< $file1");
+    my $s1 = <IN>;
+    close(IN);
+
+    return 1 if !open(IN, "< $file2");
+    my $s2 = <IN>;
+    close(IN);
+
+    return $s1 cmp $s2;
+}
+
 ########################################################################
 # append_file
 
@@ -97,9 +117,9 @@ sub replace_file {
 
     close(OUT);
 
-    if($result) {
+    if($result && _compare_files($filename, "$filename.tmp")) {
         unlink("$filename");
-        rename("$filename.tmp", "$filename");
+        rename("$filename.tmp", $filename);
     } else {
         unlink("$filename.tmp");
     }