| This document should help new developers get started. Like all of Wine, it |
| is a work in progress. |
| |
| |
| SOURCE TREE STRUCTURE |
| ===================== |
| |
| The Wine source tree is loosely based on the original Windows modules. |
| Most of the source is concerned with implementing the Wine API, although |
| there are also various tools, documentation, sample Winelib code, and |
| code specific to the binary loader. Note that several of the libraries |
| listed here are "stubbed out", meaning they still need to be implemented. |
| |
| DLLs (under dlls/): |
| ------------------- |
| |
| advapi32/ - Crypto, systeminfo, security, eventlogging |
| advpack/ - Reads and verifies .INF files |
| amstream/ - MultiMedia Streams |
| atl/ - Active Template Library |
| avicap32/ - AVI capture window class |
| avifil32/ - COM object to play AVI files |
| cabinet/ - Cabinet file interface |
| capi2032/ - Wrapper library for CAPI4Linux access |
| cards/ - Card graphics |
| cfgmgr32/ - Config manager |
| comcat/ - Component category manager |
| comctl32/ - Common controls |
| commdlg/ - Common dialog boxes (both 16 & 32 bit) |
| crtdll/ - Old C runtime library |
| crypt32/ - Cryptography |
| ctl3d/ - 3D Effects for Common GUI Components |
| d3d8/ - Direct3D (3D graphics) |
| d3d9/ - Direct3D (3D graphics) |
| d3dim/ - Direct3D Immediate Mode |
| d3drm/ - Direct3D Retained Mode |
| d3dx8/ - Direct3D (3D graphics) |
| d3dxof/ - DirectX Files Functions |
| dbghelp/ - Engine for symbol and module enumeration |
| dciman32/ - DCI Manager (graphics) |
| ddraw/ - DirectDraw (graphics) |
| devenum/ - Device enumeration (part of DirectShow) |
| dinput/ - DirectInput (device input) |
| dinput8/ - DirectInput (device input) |
| dmband/ - DirectMusic Band |
| dmcompos/ - DirectMusic Composer |
| dmime/ - DirectMusic Interactive Engine |
| dmloader/ - DirectMusic Loader |
| dmscript/ - DirectMusic Scripting |
| dmstyle/ - DirectMusic Style Engine |
| dmsynth/ - DirectMusic Software Synthesizer |
| dmusic/ - DirectMusic Core Services |
| dmusic32/ - DirectMusic Legacy Port |
| dplay/ - DirectPlay (networking) |
| dplayx/ - DirectPlay (networking) |
| dpnet/ - DirectPlay (networking) |
| dpnhpast/ - DirectPlay NAT Helper PAST |
| dsound/ - DirectSound (audio) |
| dswave/ - DirectMusic Wave |
| dxdiagn/ - DirectX Diagnostic Tool |
| gdi/ - GDI (graphics) |
| glu32/ - OpenGL Utility library (graphics) |
| glut32/ - OpenGL Utility Toolkit |
| hhctrl.ocx/ - HHCTRL OCX implementation |
| iccvid/ - Radius Cinepak Video Decoder |
| icmp/ - ICMP protocol (networking) |
| ifsmgr.vxd/ - IFSMGR VxD implementation |
| imagehlp/ - PE (Portable Executable) Image Helper lib |
| imm32/ - Input Method Manager |
| iphlpapi/ - IP Helper API |
| itss/ - Infotech Structured Storage (HTML Help) |
| kernel/ - The Windows kernel |
| lzexpand/ - Lempel-Ziv compression/decompression |
| mapi32/ - Mail interface |
| mlang/ - Multi Language Support |
| mmdevldr.vxd/ - MMDEVLDR VxD implementation |
| monodebg.vxd/ - MONODEBG VxD implementation |
| mpr/ - Multi-Protocol Router (networking) |
| msacm/ - Audio Compression Manager (multimedia) |
| msacm/imaadp32/ - IMA ADPCM Audio Codec |
| msacm/msadp32/ - MS ADPCM Audio Codec |
| msacm/msg711/ - MS G711 Audio Codec (includes A-Law & MU-Law) |
| msacm/winemp3/ - Mpeg Layer 3 Audio Codec |
| mscms/ - Color Management System |
| msdmo/ - DirectX Media Objects |
| mshtml/ - MS HTML component |
| msi/ - Microsoft Installer |
| msimg32/ - Gradient and transparency (graphics) |
| msisys/ - System information |
| msnet32/ - Network interface |
| msrle32/ - Video codecs |
| msvcrt/ - C runtime library |
| msvcrt20/ - C runtime library version 2.0 |
| msvcrt40/ - C runtime library version 4.0 |
| msvcrtd/ - C runtime library debugging |
| msvidc32/ - Microsoft Video-1 Decoder |
| msvideo/ - 16 bit video manager |
| mswsock/ - Misc networking |
| netapi32/ - Network interface |
| newdev/ - New Hardware Device Library |
| ntdll/ - NT implementation of kernel calls |
| odbc32/ - Open DataBase Connectivity driver manager |
| ole32/ - 32 bit OLE 2.0 libraries |
| oleacc/ - OLE accessibility support |
| oleaut32/ - 32 bit OLE 2.0 automation |
| olecli/ - 16 bit OLE client |
| oledlg/ - OLE 2.0 user interface support |
| olepro32/ - 32 bit OLE 2.0 automation |
| olesvr/ - 16 bit OLE server |
| opengl32/ - OpenGL implementation (graphics) |
| psapi/ - Process Status interface |
| qcap/ - DirectShow runtime |
| quartz/ - DirectShow runtime |
| rasapi32/ - Remote Access Server interface |
| riched20/ - Rich text editing control version 2.0 |
| richedit/ - Rich text editing control |
| rpcrt4/ - Remote Procedure Call runtime |
| rsabase/ - RSA encryption |
| rsaenh/ - Crypto API that provides algorithms for DES, 3DES, and RSA among others |
| secur32/ - Contains Windows Security functions |
| sensapi/ - System Event Notification Service |
| serialui/ - Serial port property pages |
| setupapi/ - Setup interface |
| shdocvw/ - Shell document object and control |
| shell32/ - COM object implementing shell views |
| shfolder/ - Shell folder service |
| shlwapi/ - Shell Light-Weight interface |
| snmpapi/ - SNMP protocol interface (networking) |
| sti/ - Still Image service |
| tapi32/ - Telephone interface |
| ttydrv/ - TTY display driver (Wine specific) |
| twain/ - TWAIN Imaging device communications |
| unicows/ - Unicows replacement (Unicode layer for Win9x) |
| url/ - Internet shortcut shell extension |
| urlmon/ - URL Moniker allows binding to a URL (like KIO/gnome-vfs) |
| user/ - Window management, standard controls, etc. |
| uxtheme/ - Theme library |
| vdhcp.vxd/ - VDHCP VxD implementation |
| vdmdbg/ - Virtual DOS machine debug library |
| version/ - File installation library |
| vmm.vxd/ - VMM VxD implementation |
| vnbt.vxd/ - VNBT VxD implementation |
| vnetbios.vxd/ - VNETBIOS VxD implementation |
| vtdapi.vxd/ - VTDAPI VxD implementation |
| vwin32.vxd/ - VWIN32 VxD implementation |
| win32s/ - 32-bit function access for 16-bit systems |
| winaspi/ - 16 bit Advanced SCSI Peripheral Interface |
| wined3d/ - Wine internal Direct3D helper |
| winedos/ - DOS features and BIOS calls (interrupts) (wine specific) |
| wineps/ - Postscript driver (Wine specific) |
| wininet/ - Internet extensions |
| winmm/ - Multimedia (16 & 32 bit) |
| winmm/joystick/ - Joystick driver |
| winmm/mcianim/ - MCI animation driver |
| winmm/mciavi/ - MCI video driver |
| winmm/mcicda/ - MCI audio CD driver |
| winmm/mciseq/ - MCI MIDI driver |
| winmm/mciwave/ - MCI wave driver |
| winmm/midimap/ - MIDI mapper |
| winmm/wavemap/ - Audio mapper |
| winmm/winealsa/ - ALSA audio driver |
| winmm/winearts/ - aRts audio driver |
| winmm/wineaudioio/ - audioio audio driver |
| winmm/winejack/ - JACK audio server driver |
| winmm/winenas/ - NAS audio driver |
| winmm/wineoss/ - OSS audio driver |
| winnls/ - National Language Support |
| winsock/ - Sockets 2.0 (networking) |
| winspool/ - Printing & Print Spooler |
| wintab32/ - Tablet device interface |
| wintrust/ - Trust verification interface |
| wow32/ - WOW subsystem |
| wsock32/ - Sockets 1.1 (networking) |
| wtsapi32/ - Terminal Services |
| x11drv/ - X11 display driver (Wine specific) |
| |
| Winelib programs (under programs/): |
| ----------------------------------- |
| |
| avitools/ - AVI information viewer and player |
| clock/ - Graphical clock |
| cmdlgtst/ - Common dialog tests |
| control/ - Control panel |
| expand/ - Decompress Lempel-Ziv compressed archive |
| msiexec/ - Microsoft Installer frontend |
| notepad/ - Notepad replacement |
| progman/ - Program manager |
| regedit/ - Registry editor |
| regsvr32/ - Register COM server |
| rpcss/ - RPC services |
| rundll32/ - Execute DLL functions directly |
| start/ - Replacement for start.exe |
| taskmgr/ - Manage running Windows/Winelib applications |
| uninstaller/ - Remove installed programs |
| view/ - Metafile viewer |
| wcmd/ - Command line interface |
| wineboot/ - Wine bootstrap process |
| winecfg/ - Wine configuration utility |
| wineconsole/ - Console |
| winedbg/ - Debugger |
| winefile/ - File manager |
| winemenubuilder/ - Helper program for building Unix menu entries |
| winemine/ - Mine game |
| winepath/ - Translate between Wine and Unix paths |
| winetest/ - Wine testing shell |
| winevdm/ - Wine virtual DOS machine |
| winhelp/ - Help viewer |
| winver/ - Windows Version Program |
| |
| |
| Support programs, libraries, etc: |
| --------------------------------- |
| |
| dlls/dxerr8/ - DirectX 8 error import lib |
| dlls/dxerr9/ - DirectX 9 error import lib |
| dlls/dxguid/ - DirectX UUID import lib |
| dlls/strmiids/ - Exports class (CLSIDs) and interface (IIDs) identifiers |
| dlls/uuid/ - Windows-compatible UUID import lib |
| documentation/ - some documentation |
| documentation/samples/ - sample configuration files |
| include/ - Windows standard includes |
| include/msvcrt/ - MSVC compatible libc headers |
| include/wine/ - Wine specific headers |
| libs/ - the Wine libraries |
| libs/port/ - portability library |
| libs/unicode/ - Unicode support shared |
| libs/wine/ - Wine bootstrap library |
| libs/wpp/ - C preprocessor |
| loader/ - the main Wine loader |
| server/ - the Wine server |
| tools/ - various tools used to build/check Wine |
| tools/widl/ - the IDL compiler |
| tools/winapi{,_check}/ - A Win32 API checker |
| tools/winebuild/ - Wine build tool |
| tools/winedump/ - a .DLL dump utility |
| tools/winegcc/ - a MinGW command line compatible gcc wrapper |
| tools/wmc/ - the message compiler |
| tools/wpp/ - the C pre-processor library |
| tools/wrc/ - the resource compiler |
| |
| |
| Miscellaneous: |
| -------------- |
| |
| Note: these directories will ultimately get moved into their |
| respective dlls. |
| |
| misc/ - KERNEL registry |
| windows/ - USER window management |
| |
| |
| |
| IMPLEMENTING NEW API CALLS |
| ========================== |
| |
| This is the simple version, and covers only Win32. Win16 is slightly |
| uglier, because of the Pascal heritage and the segmented memory model. |
| |
| All of the Win32 APIs known to Wine are listed in the .spec file of |
| their corresponding dll. An unimplemented call will look like (from |
| gdi32.spec) |
| 269 stub PolyBezierTo |
| To implement this call, you need to do the following four things. |
| |
| 1. Find the appropriate parameters for the call, and add a prototype to |
| the correct header file. In this case, that means [include/wingdi.h], |
| and it might look like |
| BOOL WINAPI PolyBezierTo(HDC, LPCVOID, DWORD); |
| If the function has both an ASCII and a Unicode version, you need to |
| define both and add a #define WINELIB_NAME_AW declaration. See below |
| for discussion of function naming conventions. |
| |
| 2. Modify the .spec file to tell Wine that the function has an |
| implementation, what the parameters look like and what Wine function |
| to use for the implementation. In Win32, things are simple--everything |
| is 32-bits. However, the relay code handles pointers and pointers to |
| strings slightly differently, so you should use 'str' and 'wstr' for |
| strings, 'ptr' for other pointer types, and 'long' for everything else. |
| 269 stdcall PolyBezierTo(long ptr long) PolyBezierTo |
| The 'PolyBezierTo' at the end of the line is which Wine function to use |
| for the implementation. |
| |
| 3. Implement the function as a stub. Once you add the function to the .spec |
| file, you must add the function to the Wine source before it will link. |
| Add a function called 'PolyBezierTo' somewhere. Good things to put |
| into a stub: |
| o a correct prototype, including the WINAPI |
| o header comments, including full documentation for the function and |
| arguments (see documentation/README.documentation) |
| o A FIXME message and an appropriate return value are good things to |
| put in a stub. |
| |
| /************************************************************ |
| * PolyBezierTo (GDI32.269) |
| * |
| * Draw many Bezier curves. |
| * |
| * PARAMS |
| * hdc [I] Device context to draw to |
| * p [I] Array of POINT structs |
| * count [I] Number of points in p |
| * |
| * RETURNS |
| * Success: Non-zero. |
| * Failure: FALSE. Use GetLastError() to find the error cause. |
| * |
| * BUGS |
| * Unimplemented |
| */ |
| BOOL WINAPI PolyBezierTo(HDC hdc, LPCVOID p, DWORD count) |
| { |
| /* tell the user they've got a substandard implementation */ |
| FIXME("(%x,%p,%d): stub\n", hdc, p, count); |
| |
| /* some programs may be able to compensate, |
| * if they know what happened |
| */ |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
| return FALSE; /* error value */ |
| } |
| |
| 4. Implement and test the rest of the function. |
| |
| |
| IMPLEMENTING A NEW DLL |
| ====================== |
| |
| Generic directions |
| ------------------ |
| |
| Apart from writing the set of needed .c files, you also need to do the |
| following: |
| |
| 1. Create a directory <MyDll> where to store the implementation of |
| the DLL. This directory has to be put under the dlls/ directory. |
| If the DLL exists under Windows as both 16 and 32 bit DLL, you |
| should have a single directory with both implementations. |
| |
| 2. Create the Makefile.in in the ./dlls/<MyDll>/ directory. You can |
| copy an existing Makefile.in from another ./dlls/ subdirectory. |
| You need at least to change the MODULE and C_SRCS macros. |
| |
| 3. Add the directory in ./configure.ac (in AC_OUTPUT macro at the end |
| of the file to trigger the Makefile generation) |
| |
| 4. Run ./make_dlls in the dlls directory to update Makefile.in in |
| that directory. |
| |
| 5. You can now regenerate ./configure file (with 'make configure') |
| and the various Makefiles (with 'configure; make depend') (run |
| from the top of Wine's tree). |
| You should now have a Makefile file in ./dlls/<MyDll>/ |
| |
| 6. Create the .spec file for the DLL exported functions in your |
| directory. Refer to 'Implementation of new API calls' earlier in |
| this document for more information on this part. |
| |
| 7. You can now start adding .c files. For the .h files, if they are |
| standard Windows one, put them in include/. If they are linked to |
| *your* implementation of the dll, put them in your newly created |
| directory. |
| |
| Debug channels |
| -------------- |
| |
| If you need to create a new debug channel, just add the |
| WINE_DEFAULT_DEBUG_CHANNEL to your .c file(s), and use them. |
| All the housekeeping will happen automatically. |
| |
| Resources |
| --------- |
| |
| If you also need to add resources to your DLL, then create the .rc |
| file. Add to your ./dlls/<MyDll>/Makefile.in, in the RC_SRCS macro, |
| the list of .rc files to add to the DLL. See dlls/comctl32/ for an |
| example of this. |
| |
| Thunking |
| -------- |
| |
| If you're building a 16 & 32 bit DLLs pair, then from the 32 bit code |
| you might need to call 16 bit routine. The way to do it to add in the |
| code, fragments like: |
| /* ### Start build ### */ |
| extern WORD CALLBACK <PREFIX>_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG); |
| /* ### stop build ### */ |
| Where <PREFIX>_ is an internal prefix for your module. The first |
| parameter is always of type FARPROC16. Then, you can get the regular |
| list of parameters. The _word_wwlll indicates the type of return (long |
| or word) and the size of the parameters (here l=>long, w=>word; which |
| maps to WORD,WORD,LONG,LONG,LONG. |
| You can put several functions between the Start/Stop build pair. |
| |
| You can also read the winebuild manpage for more details on this. |
| |
| Then, add to ./dlls/<MyDll>/Makefile.in a line like: |
| |
| EXTRA_OBJS = $(MODULE).glue.o |
| |
| See dlls/winmm/ for an example of this. |
| |
| MEMORY AND SEGMENTS |
| =================== |
| |
| NE (Win16) executables consist of multiple segments. The Wine loader |
| loads each segment into a unique location in the Wine processes memory |
| and assigns a selector to that segment. Because of this, it's not |
| possible to exchange addresses freely between 16-bit and 32-bit code. |
| Addresses used by 16-bit code are segmented addresses (16:16), formed |
| by a 16-bit selector and a 16-bit offset. Those used by the Wine code |
| are regular 32-bit linear addresses. |
| |
| There are four ways to obtain a segmented pointer: |
| - Using the MapLS function (recommended). |
| - Allocate a block of memory from the global heap and use |
| WIN16_GlobalLock to get its segmented address. |
| - Declare the argument as 'segptr' instead of 'ptr' in the spec file |
| for a given API function. |
| |
| Once you have a segmented pointer, it must be converted to a linear |
| pointer before you can use it from 32-bit code. This can be done with |
| the MapSL function. The linear pointer can then be used freely with |
| standard Unix functions like memcpy() etc. without worrying about 64k |
| boundaries. Note: there's no easy way to convert back from a linear |
| to a segmented address. |
| |
| In most cases, you don't need to worry about segmented address, as the |
| conversion is made automatically by the callback code and the API |
| functions only see linear addresses. However, in some cases it is |
| necessary to manipulate segmented addresses; the most frequent cases |
| are: |
| - API functions that return a pointer |
| - lParam of Windows messages that point to a structure |
| - Pointers contained inside structures accessed by 16-bit code. |
| |
| It is usually a good practice to used the type 'SEGPTR' for segmented |
| pointers, instead of something like 'LPSTR' or 'char *'. As SEGPTR is |
| defined as a DWORD, you'll get a compilation warning if you mistakenly |
| use it as a regular 32-bit pointer. |
| |
| |
| STRUCTURE PACKING |
| ================= |
| |
| Under Windows, data structures are tightly packed, i.e. there is no |
| padding between structure members. On the other hand, by default gcc |
| aligns structure members (e.g. WORDs are on a WORD boundary, etc.). |
| This means that a structure like |
| |
| struct { BYTE x; WORD y; }; |
| |
| will take 3 bytes under Windows, but 4 with gcc, because gcc will add a |
| dummy byte between x and y. To have the correct layout for structures |
| used by Windows code, you need to embed the struct within two special |
| #include's which will take care of the packing for you: |
| |
| #include "pshpack1.h" |
| struct { BYTE x; WORD y; }; |
| #include "poppack1.h" |
| |
| For alignment on a 2-byte boundary, there is a "pshpack2.h", etc. |
| |
| |
| NAMING CONVENTIONS FOR API FUNCTIONS AND TYPES |
| ============================================== |
| |
| In order to support both Win16 and Win32 APIs within the same source |
| code, the following convention must be used in naming all API |
| functions and types. If the Windows API uses the name 'xxx', the Wine |
| code must use: |
| |
| - 'xxx16' for the Win16 version, |
| - 'xxx' for the Win32 version when no strings are involved, |
| - 'xxxA' for the Win32 version with ASCII strings, |
| - 'xxxW' for the Win32 version with Unicode strings. |
| |
| If the function has both ASCII and Unicode version, you should then |
| use the macros WINELIB_NAME_AW(xxx) or DECL_WINELIB_TYPE_AW(xxx) |
| (defined in include/windef.h) to define the correct 'xxx' function |
| or type for Winelib. When compiling Wine itself, 'xxx' is _not_ |
| defined, meaning that code inside of Wine must always specify |
| explicitly the ASCII or Unicode version. |
| |
| If 'xxx' is the same in Win16 and Win32, you can simply use the same |
| name as Windows, i.e. just 'xxx'. If 'xxx' is Win16 only, you could |
| use the name as is, but it's preferable to use 'xxx16' to make it |
| clear it is a Win16 function. |
| |
| Examples: |
| |
| typedef struct { /* Win32 ASCII data structure */ } WNDCLASSA; |
| typedef struct { /* Win32 Unicode data structure */ } WNDCLASSW; |
| typedef struct { /* Win16 data structure */ } WNDCLASS16; |
| DECL_WINELIB_TYPE_AW(WNDCLASS); |
| |
| ATOM RegisterClass16( WNDCLASS16 * ); |
| ATOM RegisterClassA( WNDCLASSA * ); |
| ATOM RegisterClassW( WNDCLASSW * ); |
| #define RegisterClass WINELIB_NAME_AW(RegisterClass) |
| |
| The Winelib user can then say: |
| |
| WNDCLASS wc = { ... }; |
| RegisterClass( &wc ); |
| |
| and this will use the correct declaration depending on the definition |
| of the UNICODE symbol. |
| |
| |
| DEBUG MESSAGES |
| ============== |
| |
| To display a message only during debugging, you normally write something |
| like this: |
| |
| TRACE("abc..."); or |
| FIXME("abc..."); or |
| WARN("abc..."); or |
| ERR("abc..."); |
| |
| depending on the seriousness of the problem. (documentation/debugging.sgml |
| explains when it is appropriate to use each of them). You need to declare |
| the debug channel name at the top of the file (after the includes) using |
| the WINE_DEFAULT_DEBUG_CHANNEL macro, like so: |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(win); |
| |
| If your debugging code is more complex than just printf, you can use |
| the macros: |
| |
| TRACE_ON(xxx), WARN_ON(xxx), ERR_ON(xxx) and FIXME_ON(xxx) |
| |
| to test if the given channel is enabled. Thus, you can write: |
| |
| if (TRACE_ON(win)) DumpSomeStructure(&str); |
| |
| Don't worry about the inefficiency of the test. If it is permanently |
| disabled (that is TRACE_ON(win) is 0 at compile time), the compiler will |
| eliminate the dead code. |
| |
| For more info about debugging messages, read: |
| |
| http://www.winehq.org/site/docs/wine-devel/debugging |
| |
| |
| MORE INFO |
| ========= |
| |
| 1. There is a FREE online version of the MSDN library (including |
| documentation for the Win32 API) on http://msdn.microsoft.com/ |
| or http://www.msdn.com/ |
| |
| 2. Windows apilist: http://www.mentalis.org/apilist/apilist.php |
| |
| 3. http://www.sonic.net/~undoc/bookstore.html |
| |
| 4. In 1993 Dr. Dobbs Journal published a column called "Undocumented Corner". |
| |
| 5. www.geocities.com/SiliconValley/4942/ |