diff --git a/tools/genpatch b/tools/genpatch
new file mode 100755
index 0000000000000000000000000000000000000000..487808659658b10f9ee4954818bdf0975ae6a1c2
--- /dev/null
+++ b/tools/genpatch
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+# 
+# genpatch - A utility that generates patches for submission to
+# wine-patches@winehq.com
+#
+# By Steven Elliott <elliotsl@mindspring.com>
+#
+# This program is subject to the same license as Wine (www.winehq.com).
+
+use Getopt::Std;
+use File::Basename;
+use POSIX qw(strftime);
+use strict;
+
+my $gen_date;    # date the patch was generated
+my %options;     # command line options
+my @new_files;   # new files as an array
+my $new_file;    # new file being considered
+my $patches_dir; # location of the patch file
+
+# Default the patch name to the UTC time.  Use a more descriptive date for the
+# patch generation date.
+$options{n} = strftime "%Y%m%d%H%M", gmtime;
+$gen_date = strftime "%Y/%m/%d %H:%M:%S UTC", gmtime;
+
+unless(getopts("n:c:f:a:", \%options))
+{
+    print STDERR "Usage: $0 [-n patch_name] [-c change_log] [-f patch_file] " .
+        "[-a new_files]\n";
+    exit 1;
+}
+
+$options{f} = "patches/$options{n}.diff" unless(exists $options{f});
+$patches_dir = dirname $options{f};
+@new_files = split ' ', $options{a};
+
+if(-d $patches_dir)
+{
+    if(-e $options{f})
+    {
+        print STDERR "$options{f} already exists.  Aborting.\n";
+        exit 1;
+    }
+}
+else
+{
+    mkdir $patches_dir, (0777 & ~umask) or
+        die "Unable to mkdir $patches_dir: $!";
+}
+
+print "Generating $options{f}.\n";
+open OPT_F, ">$options{f}" or die "Unable to open $options{f} for write: $!";
+print OPT_F <<EOF;
+Name: $options{n}
+ChangeLog: $options{c}
+GenDate: $gen_date
+NewFiles: $options{a}
+EOF
+
+foreach $new_file (@new_files)
+{
+    print "Adding $new_file as a new file.\n";
+    open DIFF_IN, "diff -u /dev/null $new_file|" or die "Unable to " .
+        "invoke diff: $!";
+    print OPT_F <DIFF_IN>;
+    close DIFF_IN;
+}
+
+print "Invoking cvs diff.\n";
+open CVS_IN, "cvs diff -u|" or die "Unable to invoke cvs: $!";
+print OPT_F <CVS_IN>;
+close CVS_IN;