winedump doc

Eric Pouech eric.pouech at wanadoo.fr
Fri Sep 20 15:13:00 CDT 2002


this patch adds winedump documentation
(Alexandre, you can delete tools/winedump/README if you want)

A+
-------------- next part --------------
Name:          doc_winedump
ChangeLog:     added winedump doc to winelib book
License:       X11
GenDate:       2002/09/20 20:10:35 UTC
ModifiedFiles: documentation/authors.ent documentation/tools.sgml
AddedFiles:    
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/documentation/authors.ent,v
retrieving revision 1.2
diff -u -u -r1.2 authors.ent
--- documentation/authors.ent	24 Jul 2002 03:00:02 -0000	1.2
+++ documentation/authors.ent	20 Sep 2002 20:07:27 -0000
@@ -99,6 +99,9 @@
 <!entity name-jeremy-white "Jeremy White">
 <!entity email-jeremy-white "jwhite at codeweavers.com">
 
+<!entity name-jon-griffiths "Jon Griffiths">
+<!entity email-jon-griffiths "jon_p_griffiths at yahoo.com">
+
 <!-- *** Coders mentioned in docs, but not doc writers *** -->
 
 <!entity name-francis-beaudet "Francis Beaudet">
Index: documentation/tools.sgml
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/documentation/tools.sgml,v
retrieving revision 1.2
diff -u -u -r1.2 tools.sgml
--- documentation/tools.sgml	13 Dec 2000 21:52:37 -0000	1.2
+++ documentation/tools.sgml	20 Sep 2002 20:08:21 -0000
@@ -45,7 +45,7 @@
           filename. <command>bin2res -d bin rsrc.rc</command>
           generates binary files from all marked resources. If the
           binary file is newer it gets not overwritten. To force
-          overwriting use the <parameter>-f</parameter> switch.
+          overwriting use the <option>-f</option> switch.
         </para>
       </sect2>
 
@@ -65,7 +65,7 @@
           the resources into the <filename>.rc</filename> file if the
           binary resources are newer than the.rc file. To force the
           resources into the <filename>.rc</filename> file use the
-          <parameter>-f</parameter> switch. If there is already a
+          <option>-f</option> switch. If there is already a
           resource with the same filename in the
           <filename>.rc</filename> file it gets overwritten.
         </para>
@@ -83,6 +83,1100 @@
           means changed.
         </para>
       </sect2>
+    </sect1>
+
+    <sect1 id="winedump">
+      <title>winedump</title>
+
+      <para>Generated from tools/winedump/README, written by
+&name-jon-griffiths; &email-jon-griffiths;.</para>
+
+      <sect2 id="overview">
+	<title>Overview</title>
+
+<para>
+<command>winedump</command> is a tool used to manipulate native
+modules. It comes with different usages: 
+          <itemizedlist>
+	    <listitem>
+<para>
+generating default source files (<filename>.spec</filename>,
+<filename>.c</filename>...) for using a native DLL in Wine
+</para>
+	    </listitem>
+	    <listitem>
+	      <para>
+                demangling MSVC C++ symbol names
+              </para>
+	    </listitem>
+	    <listitem>
+	      <para>dumping the 'PE' files contents</para>
+	    </listitem>
+	  </itemizedlist>
+        </para>
+
+	<sect3 id="usage">
+	  <title>Usage</title>
+	  
+	  <para>
+	    <command>winedump</command> is a command line
+            tool. Running it with no arguments or passing it '-h' on
+            the command line lists the available options.
+
+<screen>
+Usage: winedump [-h | sym &lt;sym&gt; | spec &lt;dll&gt; | dump
+	         &lt;dll&gt;] [mode options]
+</screen>
+
+	    Winedump can be used in several different modes. The first
+	    argument to the program determines the mode winedump will
+	    run in.
+<screen>
+   -h           Help mode. Basic usage help is printed.
+   sym          Symbol mode. Used to demangle C++ symbols
+   spec         For generating .spec files and stub DLL's
+   dump         To dump the contents of a PE file.
+</screen>
+
+[mode options] depend on the mode given as the first argument.
+
+<screen>
+Help mode:
+   No options are used. The program prints help and then exits
+
+Sym mode:
+   &lt;sym&gt;        Demangles C++ symbol &lt;sym&gt; and then exits.
+
+Spec mode:
+   &lt;dll&gt;        Use dll for input file and generate implementation code
+   -I dir       Look for prototypes in 'dir' (implies -c)
+   -c           Generate skeleton code (requires -I)
+   -t           TRACE arguments (implies -c)
+   -f dll       Forward calls to 'dll' (implies -t)
+   -D           Generate documentation
+   -o name      Set the output dll name (default: dll)
+   -C           Assume __cdecl calls (default: __stdcall)
+   -s num       Start prototype search after symbol 'num'
+   -e num       End prototype search after symbol 'num'
+   -S symfile   Search only prototype names found in 'symfile'
+   -q           Don't show progress (quiet).
+   -v           Show lots of detail while working (verbose).
+
+Dump mode
+   &lt;dll&gt;        Dumps the content of the dll named &lt;dll&gt;
+   -C           Turns on symbol demangling
+   -f           Dumps file header information
+   -j sect_name Dumps only the content of section sect_name (import, export, debug)
+   -x           Dumps everything
+</screen>
+	  </para>
+
+	  <sect4 id="opts">
+	    <title>Basic options</title>
+
+	    <para>
+<screen>
+OPTION: -o name  Set the output dll name (default: dll)
+</screen>
+
+	      By default, if <command>winedump</command> is run on DLL
+	      '<filename>foo</filename>', it creates files called
+	      '<filename>foo.spec</filename>',
+	      '<filename>foo_main.c</filename>' etc, and prefixes any
+	      functions generated with '<function>FOO_</function>'. If
+	      '<option>-o bar</option>' is given, these will
+	      become <filename>'bar.spec</filename>',
+	      '<filename>bar_main.c</filename>' and
+	      '<function>BAR_</function>' respectively.
+	    </para>
+	    <para>
+	      This option is mostly useful when generating a
+	      forwarding DLL. See below for more information.
+	    </para>
+
+	    <para>
+<screen>
+OPTION: -q       Don't show progress (quiet).
+        -v       Show lots of detail while working (verbose).
+</screen>
+
+	      There are 3 levels of output while
+	      <command>winedump</command> is running. The default
+	      level, when neither <option>-q</option> or
+	      <option>-v</option> are given, prints the number
+	      of exported functions found in the DLL, followed by the
+	      name of each function as it is processed, and a status
+	      indication of whether it was processed OK. With
+	      <option>-v</option> given, a lot of information is
+	      dumped while <command>winedump</command> works: this is
+	      intended to help debug any problems. Giving
+	      <option>-q</option> means nothing will be printed
+	      unless a fatal error occurs, and could be used when
+	      calling winedump from a script.
+	    </para>
+
+	    <para>
+<screen>
+OPTION: -C       Assume __cdecl calls (default: __stdcall)
+</screen>
+
+	      This option determines the default calling convention
+	      used by the functions in the DLL. If
+	      <command>winedump</command> cannot determine the
+	      convention, <type>__stdcall</type> is used by default,
+	      unless this option has been given. 
+	    </para>
+
+	    <para>
+	      Unless <option>-q</option> is given, a warning
+	      will be printed for every function that
+	      <command>winedump</command> determines the calling
+	      convention for and which does not match the assumed
+	      calling convention. 
+	    </para>
+	  </sect4>
+	</sect3>
+      </sect2>
+
+      <sect2 id="spec">
+	<title>Using native DLLs in Wine</title>
+
+	<sect3 id="background">
+	  <title>Background</title>
+
+	  <para>
+            Most of the functions available in Windows, and in Windows
+	    applications, are made available to applications from
+            DLL's. Wine implements the Win32 API by providing
+            replacement's for the essential Windows DLLs in the form
+            of Unix shared library (<filename>.so</filename>) files,
+            and provides a tool, <command>winebuild</command>, to
+            allow Winelib applications to link to functions exported
+            from shared libraries/DLLs.
+          </para>
+
+	  <para>
+            The first thing to note is that there are many DLLs that
+            aren't yet implemented in Wine. Mostly this doesn't
+            present a problem because the native Win32 versions of
+            lots of DLLs can be used without problems, at least on x86
+            platforms. However, one of Wine's goals is the eventual
+            replacement of every essential O/S DLL so that the whole
+            API is implemented. This not only means that a copy of the
+            real O/S is not needed, but also that non-x86 platforms
+            can run most Win32 programs after recompiling. 
+          </para>
+
+	  <para>
+	    The second thing to note is that applications commonly use
+	    their own or 3rd party DLLs to provide functionality. In
+	    order to call these functions with a Winelib program, some
+	    'glue' is needed. This 'glue' comes in the form of a
+	    <filename>.spec</filename> file. The
+	    <filename>.spec</filename> file, along with some dummy
+	    code, is used to create a Wine <filename>.so</filename>
+	    corresponding to the Windows DLL. The
+	    <command>winebuild</command> program can then resolve
+	    calls made to DLL functions to call your dummy DLL. You
+	    then tell Wine to only use the native Win32 version of the
+	    DLL, and at runtime your calls will be made to the Win32
+	    DLL. If you want to reimplement the dll, you simply add
+	    the code for the DLL calls to your stub
+	    <filename>.so</filename>, and then tell Wine to use the
+	    <filename>.so</filename> version instead.
+	    <footnote>
+	      <para>
+		See the Wine and Wine.conf man pages for details on
+		how to tell Wine whether to use native (Win32) or
+		internal DLLs.
+	      </para>
+	    </footnote>
+          </para>
+
+	  <para>
+            These two factors mean that if you are:
+            <itemizedlist>
+	      <listitem>
+		<para>
+                  A: Reimplementing a Win32 DLL for use within Wine,
+		  or 
+                </para>
+	      </listitem>
+	      <listitem>
+                <para>
+		  B: Compiling a Win32 application with Winelib that
+		  uses x86 DLLs 
+		</para> 
+	      </listitem>
+	    </itemizedlist>
+          </para>
+
+	  <para>
+            Then you will need to create a <filename>.spec</filename>
+            file (amongst other things). If you won't be doing either of
+            the above, then you won't need <command>winedump</command>.
+          </para>
+
+	  <para>
+	    Creating a <filename>.spec</filename> file is a labour
+	    intensive task during which it is easy to make a
+	    mistake. The idea of <command>winedump</command> is to
+	    automate this task and create the majority of the support
+	    code needed for your DLL. In addition you can have
+	    <command>winedump</command> create code to help you
+	    reimplement a DLL, by providing tracing of calls to the
+	    DLL, and (in some cases) automatically determining the
+	    parameters, calling conventions, and return values of the
+	    DLLs functions. 
+          </para>
+
+	  <para>
+            You can think of <command>winedump</command> as somewhat
+            similar to the <command>IMPLIB</command> tool when only its
+            basic functionality is used. 
+          </para>
+
+	</sect3>
+
+	<sect3 id="stubdll">
+	  <title>Generating stub DLLS</title>
+
+	  <para>
+            If all you want to do is generate a stub DLL to allow you
+            to link your Winelib application to an x86 DLL, the above
+            options are all you need.
+          </para>
+
+	  <para>
+            As an example, lets assume the application you are porting
+            uses functions from a 3rd party dll called
+            '<filename>zipextra.dll</filename>', and the functions in
+            the DLL use the <type>__stdcall</type> calling
+            convention. Copy <filename>zipextra.dll</filename> to an
+            empty directory, change to it, and run
+            <command>winedump</command> as follows: 
+
+<screen>
+winedump spec zipextra
+</screen>
+            (Note: this assumes <command>winedump</command> is in your
+	    path) 
+</para>
+
+<para>
+	    The output will look something like the following:
+<screen>
+22 named symbols in DLL, 22 in total ...
+Export    1 - '_OpenZipFile' ... [Ignoring]
+Export    2 - '_UnZipFile' ... [Ignoring]
+...
+</screen>
+
+	    "[Ignoring]" Just tells you that
+	    <command>winedump</command> isn't trying to determine the
+	    parameters or return types of the functions, its just
+	    creating stubs. 
+	  </para>
+
+	  <para>
+	    The following files are created:
+	    <itemizedlist>
+	      <listitem>
+		<para><filename>zipextra.spec</filename></para>
+		<para>
+		  This is the <filename>.spec</filename> file. Each
+		  exported function is listed as a stub: 
+<screen>
+@ stub _OpenZipFile
+@ stub _UnZipFile
+...
+</screen>
+		</para>
+
+		<para>
+		  This means that <command>winebuild</command> will
+		  generate dummy code for this function. That doesn't
+		  concern us, because all we want is for
+		  <command>winebuild</command> to allow the symbols to
+		  be resolved. At run-time, the functions in the
+		  native DLL will be called; this just allows us to link.
+		</para>
+	      </listitem>
+	      <listitem>
+		<para>
+		  <filename>zipextra_dll.h zipextra_main.c</filename>
+		</para>
+		<para>
+		  These are source code files containing the minimum
+		  set of code to build a stub DLL. The C file contains
+		  one function, <function>ZIPEXTRA_Init</function>,
+		  which does nothing (but must be present).
+		</para>
+	      </listitem>
+	      <listitem>
+		<para>
+		  <filename>Makefile.in</filename>
+		</para>
+
+		<para>
+		  This is a template for
+		  '<command>configure</command>' to produce a
+		  <filename>makefile</filename>. It is designed for a
+		  DLL that will be inserted into the Wine source
+		  tree. If your DLL will not be part of Wine, or you
+		  don't wish to build it this way, you should look at
+		  the Wine tool '<command>winemaker</command>' to
+		  generate a DLL project.  
+		</para>
+
+		<para>
+		  FIXME: <command>winemaker</command> could run this
+		  tool automatically when generating projects that use
+		  extra DLL's (*.lib in the "ADD LINK32" line in .dsp)...
+		</para>
+	      </listitem>
+	      <listitem>
+		<para>
+		  <filename>zipextra_install</filename>
+		</para>
+		<para>
+		  A shell script for adding zipextra to the Wine
+		  source tree (see below). 
+		</para>
+	      </listitem>
+	    </itemizedlist>
+	  </para>
+	</sect3>
+
+	<sect3 id="stubwine">
+	  <title>Inserting a stub DLL into the Wine tree</title>
+
+	  <para>
+	    To build your stub DLL as part of Wine, do the following: 
+<screen>
+ chmod a+x ./zipextra_install
+ ./zipextra_install &lt;wine-path&gt;
+ cd &lt;wine-path&gt;
+ autoconf
+ ./configure
+ make depend && make
+ make install
+</screen>
+
+	    Your application can now link with the DLL.
+	  </para>
+
+	  <para>
+	    If you recieve the following error when running autoconf:
+<screen>
+autoconf: configure.in: No such file or directory
+</screen>
+
+	    Then you need to install a newer version of autoconf. At
+	    the time of writing version 2.53 or later is required to
+	    re-generate configure.
+	  </para>
+
+	  <para>
+	    If you have problems with this step, you can post to the
+	    wine-devel mailing list for help. The build process can
+	    change regularly and winebuild may lag behind in support.
+	  </para>
+
+	  <note>
+	    <title>Note</title>
+	    <para>
+	      **DO NOT** submit patches to Wine for 3rd party
+	      DLLs! Building DLLs into your copy of the tree is just
+	      a simple way for you to link. When you release your
+	      application you won't be distributing the Unix
+	      <filename>.so</filename> anyway, just the Win32
+	      DLL. As you update your version of Wine you can simply
+	      re-run the procedure above (Since no patches are
+	      involved, it should be pretty resiliant to changes).
+	    </para>
+	  </note>
+	</sect3>
+
+	<sect3 id="advanced">
+	  <title>Advanced Options</title>
+
+	  <para>
+	    This section discusses features of
+	    <command>winedump</command> that are useful to Wine
+	    Hackers or developers looking to reimplement a Win32 DLL
+	    for Unix. Using these features means you will need to be
+	    able to resolve compilation problems and have a general
+	    understanding of Wine programming.
+	  </para>
+
+	  <para>
+<screen>
+OPTION: -I dir   Look for prototypes in 'dir' (implies -c)
+</screen>
+
+	    For all advanced functionality, you must give
+	    <command>winedump</command> a directory or file that
+	    contains prototypes for the DLL. In the case of Windows
+	    DLLs, this could be either the standard include directory
+	    from your compiler, or an SDK include directory. If you
+	    have a text document with prototypes (such as
+	    documentation) that can be used also, however you may need
+	    to delete some non-code lines to ensure that prototypes
+	    are parsed correctly.
+	  </para>
+
+	  <para>
+	    The 'dir' argument can also be a file specification
+	    (e.g. "include/*"). If it contains wildcards you must
+	    quote it to prevent the shell from expanding it. 
+	  </para>
+
+	  <para>
+	    If you have no prototypes, specify
+	    <filename>/dev/null</filename> for
+	    'dir'. <command>winedump</command> may still be able to
+	    generate some working stub code for you. 
+	  </para>
+
+	  <para>
+	    Once you have created your DLL, if you generated code (see
+	    below), you can backup the DLL header file created and use
+	    it for rebuilding the DLL (you should remove the
+	    <function>DLLNAME_</function> prefix from the prototypes
+	    to make this work). This allows you to add names to the
+	    function arguments, for example, so that the comments and
+	    prototype in the regenerated DLL will be clearer.
+	  </para>
+
+	  <para>
+	    <command>winedump</command> searches for prototypes using
+	    '<command>grep</command>', and then retrieves each
+	    prototype by calling
+	    '<command>function_grep.pl</command>', a Perl script. When
+	    you pass the <option>-v</option> option on the
+	    command line, the calls to both of these programs are
+	    logged. This allows you to see where each function
+	    definition has come from. Should
+	    <command>winedump</command> take an excessively long time
+	    to locate a prototype, you can check that it is searching
+	    the right files; you may want to limit the number of files
+	    searched if locating the prototype takes too long.
+	  </para>
+
+	  <para>
+	    You can compile <command>function_grep.pl</command> for a
+	    slight increase in performance; see 'man perlcc' for details.
+	  </para>
+
+	  <para>
+<screen>
+OPTION: -s num   Start prototype search after symbol 'num'
+        -e num   End prototype search after symbol 'num'
+</screen>
+
+	    By passing the <option>-s</option> or
+	    <option>-e</option> options you can have
+	    <command>winedump</command> try to generate code for only
+	    some functions in your DLL. This may be used to generate a
+	    single function, for example, if you wanted to add
+	    functionality to an existing DLL. 
+	  </para>
+
+	  <para>
+	    They is also useful for debugging problems, in conjunction
+	    with <option>-v</option>.
+	  </para>
+
+	  <para>
+<screen>
+OPTION: -D       Generate documentation
+</screen>
+
+	    By default, <command>winedump</command> generates a
+	    standard comment at the header of each function it
+	    generates. Passing this option makes
+	    <command>winedump</command> output a full header template
+	    for standard Wine documentation, listing the parameters
+	    and return value of the function. 
+	  </para>
+
+	  <para>
+<screen>
+OPTION: -S symfile Search only prototype names found in '<filename>symfile</filename>'
+</screen>
+
+	    If you want to only generate code for a subset of exported
+	    functions from your source DLL, you can use this option to
+	    provide a text file containing the names of the symbols to
+	    extract, one per line. Only the symbols present in this
+	    file will be used in your output DLL.
+	  </para>
+
+ 	  <para>
+<screen>
+OPTION: -c       Generate skeleton code (requires -I)
+</screen>
+
+	    This option tells <command>winedump</command> that you
+	    want to create function stubs for each function in the
+	    DLL. This is the most basic level of code generation. As
+	    <command>winedump</command> reads each exported symbol
+	    from the source DLL, it first tries to demangle the
+	    name. If the name is a C++ symbol, the arguments, class
+	    and return value are all encoded into the symbol
+	    name. <command>winedump</command> converts this
+	    information into a C function prototype. If this fails,
+	    the file(s) specified in the <option>-I</option>
+	    argument are scanned for a function prototype. If one is
+	    found it is used for the next step of the process, code
+	    generation.
+	  </para>
+
+	  <note>
+	    <title>Note</title>
+	    <para>
+		Note: C++ name demangling is currently under
+		development. Since the algorithm used is not
+		documented, it must be decoded. Many simple prototypes
+		are already working however.
+	    </para>
+	  </note>
+
+	  <para>
+	    If <command>winedump</command> does not find a prototype,
+	    it emits code like the following: 
+	    <itemizedlist>
+	      <listitem>
+		<para>
+		  In the <filename>.spec</filename> file:
+<programlisting>
+ at stub _OpenZipFile
+</programlisting>
+		</para>
+	      </listitem>
+	      <listitem>
+		<para>
+		  in the header file:
+<programlisting>
+/* __cdecl ZIPEXTRA__OpenZipFile() */
+</programlisting>
+		</para>
+	      </listitem>
+	      <listitem>
+		<para>
+		  in the C source file:
+<programlisting>
+/*********************************************************************
+ *      _OpenZipFile     (ZIPEXTRA.@)
+ *
+ */
+#if 0
+__stdcall ZIPEXTRA__OpenZipFile()
+{
+    /* '@Stubbed'ed in .spec */
+}
+#endif
+</programlisting>
+
+		  If a prototype is found, or correctly demangled, the
+		  following is emitted: 
+<programlisting>
+.spec:
+@ stdcall _OpenZipFile ZIPEXTRA__OpenZipFile
+
+.h:
+BOOL __stdcall ZIPEXTRA__OpenZipFile(LPCSTR pszFileName);
+
+.c:
+BOOL __stdcall ZIPEXTRA__OpenZipFile(LPCSTR pszFileName)
+{
+  TRACE("stub\n");
+  return 0;
+}
+</programlisting>
+		</para>
+	      </listitem>
+	    </itemizedlist>
+	  </para>
+
+	  <para>
+	    Note that if the prototype does not contain argument
+	    names, <command>winedump</command> will add them following
+	    the convention arg0, arg1 ... argN. If the function is
+	    demangled C++, the first argument will be called '_this'
+	    if an implicit this pointer is passed (i.e. the function
+	    is a non-static class member function).
+	  </para>
+
+	  <para>
+<screen>
+OPTION: -t       TRACE arguments (implies -c)
+</screen>
+
+	    This option produces the same code as
+	    <option>-c</option>, except that arguments are
+	    printed out when the function is called, so the FIXME in
+	    the above example becomes:  
+<programlisting>
+  FIXME("(%s) stub", pszFileName);
+</programlisting>
+	  </para>
+
+	  <para>
+	    Structs that are passed by value are printed as "struct",
+	    and functions that take variable argument lists print "...".
+	  </para>
+
+	  <para>
+<screen>
+OPTION: -f dll   Forward calls to 'dll' (implies -t)
+</screen>
+
+	    This is the most complicated level of code generation. The
+	    same code is generated as <option>-t</option>,
+	    however support is added for forwarding calls to another
+	    DLL. The DLL to forward to is given as 'dll'. Lets suppose
+	    we built the examples above using "<option>-f
+	    real_zipextra</option>". The code generated will look
+	    like the following: 
+	    <itemizedlist>
+	      <listitem>
+		<para>.spec</para>
+		<para>
+		  As for <option>-c</option>, except if a
+		  function prototype was not found:</para>
+		<programlisting>
+@ forward _OpenZipFile real_zipextra._OpenZipFile
+</programlisting>
+		<para>
+		  In this case the function is forwarded to the
+		  destination DLL rather than stubbed.
+		</para>
+	      </listitem>
+	      <listitem>
+		<para>.h</para>
+		<para>As for <option>-c</option>.</para>
+	      </listitem>
+	      <listitem>
+		<para>.c</para>
+		<para>
+		  A variable "hDLL" is added to hold a pointer to the
+		  DLL to forward to, and the initialisation code in
+		  <function>ZIPEXTRA_Init</function> is changed to
+		  load and free the forward DLL automatically:
+		</para>
+
+<programlisting>
+HMODULE hDLL = 0; /* DLL to call through to */
+
+BOOL WINAPI ZIPEXTRA_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    TRACE("(0x%08x, %ld, %p)\n", hinstDLL, fdwReason, lpvReserved);
+
+    if (fdwReason == DLL_PROCESS_ATTACH)
+    {
+        hDLL = LoadLibraryA( "real_zipextra" );
+        TRACE ("Forwarding DLL (real_zipextra) loaded\n" );
+    }
+    else if (fdwReason == DLL_PROCESS_DETACH)
+    {
+        FreeLibrary( hDLL );
+        TRACE ("Forwarding DLL (real_zipextra) freed\n" );
+    }
+
+    return TRUE;
+}
+</programlisting>
+
+		<para>
+		  The stub function is changed to call the forwarding
+		  DLL and return that value. 
+		</para>
+
+<programlisting>
+BOOL __stdcall ZIPEXTRA__OpenZipFile(LPCSTR pszFileName)
+{
+  BOOL (__stdcall *pFunc)(LPCSTR) = (void*)GetProcAddress(hDLL,"_OpenZipFile");
+  BOOL retVal;
+  TRACE("((LPCSTR)%s) stub\n", pszFileName);
+  retVal = pFunc(pszFileName);
+  TRACE("returned (%ld)\n",(LONG)retVal));
+  return retVal;
+}
+</programlisting>
+
+		<para>
+		  This allows you to investigate the workings of a DLL
+		  without interfering in its operation in any way
+		  (unless you want to). 
+		</para>
+	      </listitem>
+	    </itemizedlist>
+	  </para>
+
+	  <para>
+	    In the example I have been using, we probably should have
+	    used the <option>-o</option> option to change the
+	    ouput name of our DLL to something else, and used the
+	    <option>-f</option> option to forward to the real
+	    <filename>zipextra</filename> DLL:
+	  </para>
+
+	  <para>
+<screen>
+winedump spec zipextra -f zipextra -o myzipextra -I "~/zipextra/include/*h"
+</screen>
+
+	    Then in the .spec file for our Winelib application, we add
+	    the line: 
+<programlisting>
+import myzipextra
+</programlisting>
+	  </para>
+
+	  <para>
+	    When we build our application,
+	    <command>winebuild</command> resolves the calls to our
+	    Unix <filename>.so</filename>. As our application runs we
+	    can see the values of all parameters passed to the DLL,
+	    and any values returned, without having to write code to
+	    dump them ourselves (see below for a better way to wrap a DLL for forwarding). 
+	  </para>
+
+	  <para>
+	    This isn't a very realistic example of the usefulness of
+	    this feature, however, since we could print out the
+	    results anyway, because it is our application making the
+	    calls to the DLL. Where DLL forwarding is most useful is
+	    where an application or DLL we didn't write calls
+	    functions in the DLL. In this case we can capture the
+	    sequence of calls made, and the values passed around. This
+	    is an aid in reimplementing the DLL, since we can add code
+	    for a function, print the results, and then call the real
+	    DLL and compare. Only when our code is the same do we need
+	    to remove the function pointer and the call to the real
+	    DLL. A similar feature in wine is +relay debugging. Using
+	    a fowarding DLL allows more granular reporting of
+	    arguments, because you can write code to dump out the
+	    contents of types/structures rather than just their
+	    address in memory. A future version of
+	    <command>winedump</command> may generate this code
+	    automatically for common Win32 types.
+	  </para>
+
+	  <para>
+	    See below for more information on setting up a forwarding DLL.
+	  </para>
+
+	</sect3>
+
+	<sect3 id="comp">
+	  <title>Problems compiling a DLL containing generated code</title>
+
+	  <para>
+	    Unless you are very lucky, you will need to do a small
+	    amount of work to get a DLL generated with
+	    <option>-c</option>, <option>-t</option> or
+	    <option>-f</option> to compile. The reason for this
+	    is that most DLLs will use custom types such as structs
+	    whose definition is not known to the code in the DLL. 
+	  </para>
+
+	  <para>
+	    Heres an example prototype from crtdll:
+<programlisting>
+double __cdecl _cabs(struct _complex arg0)
+</programlisting>
+	  </para>
+
+	  <para>
+	    The definition for the <type>_complex</type> struct needs
+	    to be given. Since it is passed by value, its size also
+	    needs to be correct in order to forward the call correctly
+	    to a native DLL. In this case the structure is 8 bytes in
+	    size, which means that the gcc compile flag
+	    <option>-freg-struct-return</option> must be given
+	    when compiling the function in order to be compatable with
+	    the native DLL. (In general this is not an issue, but you
+	    need to be aware of such issues if you encounter problems
+	    with your forwarding DLL). 
+	  </para>
+	  
+	  <para>
+	    For third party (non C++) DLL's, the header(s) supplied
+	    with the DLL can normally be added as an include to the
+	    generated DLL header. For other DLLs I suggest creating a
+	    seperate header in the DLL directory and adding any needed
+	    types to that. This allows you to rebuild the DLL at whim,
+	    for example if a new version of
+	    <command>winedump</command> brings increased
+	    functionality, then you only have to overwrite the
+	    generated files and re-include the header to take
+	    advantage of it. 
+	  </para>
+
+	  <para>
+	    Usually there isn't much work to do to get the DLL to
+	    compile if you have headers. As an example, building a
+	    forwarded crtdll, which contains 520 functions, required
+	    20 types to be defined before it compiled. Of these, about
+	    half were structures, so about 35 lines of code were
+	    needed. The only change to the generated code was one line
+	    in the header to include the type definitions.
+	  </para>
+
+	  <para>
+	    To save some typing in case you don't have headers for
+	    your DLL type, <command>winedump</command> will dump dummy
+	    declarations for unknown classes and types it encounters,
+	    if you use the <option>-v</option> option. These can
+	    be piped directly into a fix-up header file for use in
+	    compiling your DLL. For example, if
+	    <command>winedump</command> encounters the (C++ ) symbol:
+<programlisting>
+ ??0foobar@@QAE at ABV0@@Z   (Which is a constructor for a foobar object) 
+</programlisting>
+
+	    It will emit the following with <option>-v</option> set:
+<programlisting>
+struct foobar { int _FIXME; };
+</programlisting>
+
+	    (Classes are mapped to C structs when generating code).
+	  </para>
+
+	  <para>
+	    The output should be piped through
+	    '<command>sort</command>' and '<command>uniq</command>' to
+	    remove multiple declarations, e.g: 
+<screen>
+winedump foo -c -I "inc/*.h" -v | grep FIXME | sort | uniq &gt; fixup.h
+</screen>
+	  </para>
+
+	  <para>
+	    By adding '<programlisting>#include
+	      "fixup.h"</programlisting>' to
+	    <filename>foobar_dll.h</filename> your compile errors will
+	    be greatly reduced. 
+	  </para>
+
+	  <para>
+	    If <command>winedump</command> encounters a type it doesnt
+	    know that is passed by value (as in the
+	    <function>_cabs</function> example above), it also prints
+	    a FIXME message like:  
+<programlisting>
+/* FIXME: By value type: Assumed 'int' */ typedef int ldiv_t;
+</programlisting>
+	  </para>
+
+	  <para>
+	    If the type is not an <type>int</type>, you will need to
+	    change the code and possibly the
+	    <filename>.spec</filename> entry in order to forward
+	    correctly. Otherwise, include the typedef in your fixup
+	    header to avoid compile errors. 
+	  </para>
+	</sect3>
+
+	<sect3 id="forward">
+	  <title>Using a forwarding DLL</title>
+
+	  <para>
+	    To create and use a forwarding DLL to trace DLL calls, you
+	    need to first create a DLL using the
+	    <option>-f</option> option as outlined above, and
+	    get it to compile. In order to forward calls the following
+	    procedure can be used (for this example we are going to
+	    build a forwarding <filename>msvcrt.dll</filename> for the
+	    purpose of reimplementing it). 
+	  </para>
+
+	  <para>
+	    First we create the forwarding DLL. We will rename the real
+	    <filename>msvcrt.dll</filename> on our system to
+	    <filename>ms_msvcrt.dll</filename>, and our msvcrt
+	    implementation will call it: 
+<screen>
+winedump spec msvcrt -C -f ms_msvcrt -I "inc/*.h"
+</screen>
+	  </para>
+
+	  <para>
+	    We then install this DLL into the Wine tree and add the
+	    types we need to make it compile. Once the DLL compiles,
+	    we create a dummy <filename>ms_msvcrt</filename> DLL so
+	    <command>winebuild</command> will resolve our forward
+	    calls to it (for the cases where
+	    <command>winedump</command> couldn't generate code and has
+	    placed an '<type>@forward</type>' line in the
+	    <filename>.spec</filename> file): 
+<screen>
+winedump spec msvcrt -C -o ms_msvcrt
+</screen>
+	  </para>
+
+	  <para>
+	    Install this DLL into the wine tree (since its a stub DLL,
+	    no changes are needed to the code).
+	  </para>
+
+	  <para>
+	    Now uncomment the line that <command>winedump</command>
+	    inserted into <filename>msvcrt.spec</filename>: 
+<programlisting>
+#inport ms_msvcrt.dll
+</programlisting>
+	    And recompile Wine.
+	  </para>
+
+	  <para>
+	    Finally, we must tell Wine to only use the builtin
+	    <filename>msvcrt.dll</filename> and to only use the native
+	    (Win32) <filename>ms_msvcrt.dll</filename>. Add the
+	    following two lines to <filename>~/.wine/config</filename>
+	    under the [DllOverrides] section: 
+<screen>
+;Use our implmentation of msvcrt
+"msvcrt" = "builtin, so"
+;Use only the Win32 ms_msvcrt
+"ms_msvcrt" = "native"
+</screen>
+	  </para>
+
+	  <para>
+	    At this point, when any call is made to
+	    <filename>msvcrt.dll</filename>, Our
+	    <filename>libmsvcrt.so</filename> recieves the call. It
+	    then forwards our calls
+	    <filename>ms_msvcrt.dll</filename>, which is the native
+	    dll. We recieve a return value and pass it back to our
+	    caller, having TRACEd the arguments on the way.
+	  </para>
+
+	  <para>
+	    At this point you are ready to start reimplementing the
+	    calls. 
+	  </para>
+	</sect3>
+
+	<sect3 id="final">
+	  <title>Final comments</title>
+
+	  <para>
+	    If you have any suggestions for improving this tool,
+	    please let me know. If anyone can help answer the
+	    <function>FIXME</function> questions in
+	    <filename>msmangle.c</filename> or can fill me in on any
+	    aspect of the C++ mangling scheme, I would appreciate
+	    it. In particular I want to know what _E and _G
+	    represent.
+	  </para>
+
+	  <para>
+	    If you encounter a C++ symbol that doesn't demangle
+	    **AND** you have the prototype for it, please send me the
+	    symbol as reported by <command>winedump</command> and the
+	    prototype. The more examples I have the easier it is to
+	    decypher the scheme, and generating them myself is very slow.
+	  </para>
+
+	  <para>
+	    Finally, although it is easy to generate a DLL, I _very
+	    strongly_ suggest that you dont submit a generated DLL for
+	    inclusion into Wine unless you have actually implemented a
+	    fairly reasonable portion of it. Even then, you should
+	    only send the portions of the DLL you have
+	    implemented. Thousands of lines of stub code don't help the project at all.
+	  </para>
+
+	</sect3>
+
+      </sect2>
+
+      <sect2 id="demangl">
+	<title>Demangling</title>
+	
+	<para>
+	  If you need to demangle a single C++ symbol, you can use the
+	  demangling mode of <command>winedump</command>. This is
+	  useful for testing the demangler or implementing C++
+	  functions in partially implemented wine DLLS. As an example: 
+<screen>
+winedump sym "??3 at YAXPAX@Z"
+</screen>
+
+	  Gives: <function>void __cdecl _global_operator_delete_1(void
+	    * arg0)</function> 
+
+	  Which is enough information to begin implementing the function.
+	</para>
+      </sect2>
+
+      <sect2 id="dump">
+	<title>Dumping a PE file</title>
+
+	<para>
+	  Another use for this tool is to diplay information about a
+	  32bit DLL or PE format image file. When used in this way
+	  winedump functions similarly to tools such as
+	  <command>pedump</command> provided by many Win32 compiler
+	  vendors.
+	</para>
+
+	<para>
+<screen>
+Usage:
+winedump dump &lt;dllname.dll&gt; [switches]
+
+dump mode switches:
+   -h           Display this help message
+   -C           Turns on symbol demangling
+   -f           Dump file header information
+   -j dir_name  Dump only the contents of directory dir_name (import, export, debug)
+   -x           Dump everything
+</screen>
+
+	  </para>
+	
+	<sect3 id="dump_opt">
+	  <title>Dump mode options</title>
+
+	  <para>
+<screen>	    
+OPTION: -x           Dump everything
+</screen>
+
+	    This command prints all available information about the
+	    file. You may wish to pipe the output through more/less or
+	    into a file, since a lot of output will be produced.
+	  </para>
+
+	  <para>
+	    If you are only interested in a subset of the available
+	    information, you can use one of the following switches:
+<screen>
+OPTION: -f           Dump file header information-x  Dump everything
+</screen>
+
+	    This option dumps only the standard PE header structures,
+	    along with the COFF sections available in the file.
+	  </para>
+
+	  <para>
+<screen>
+OPTION: -j dir_name  Dump directory dir_name (import, export, debug)
+</screen>
+
+	    To dump only a given directory, specify them using this
+	    option. Currently only the import, export and debug
+	    directories are implemented.
+	  </para>
+	</sect3>
+      </sect2>
+
     </sect1>
   </chapter>
 


More information about the wine-patches mailing list