diff --git a/documentation/HOWTO-winelib b/documentation/HOWTO-winelib deleted file mode 100644 index 92636423ccc..00000000000 --- a/documentation/HOWTO-winelib +++ /dev/null @@ -1,617 +0,0 @@ -WineLib HOWTO -Version 28-Dec-2000 - -AUTHOR: -Wilbur Dale -Lumin Software BV -Zandheuvel 52 B -4901 HW Oosterhout (NB) -The Netherlands - -wilbur.dale@lumin.nl - -WARNING: This HOWTO is incomplete. I expect to add to it on a weekly -basis until it is complete. - -===================================================================== - -Table of Contents - - I. Introduction: Wine vs. WineLib - - IV. File Format Conversion - - V. Compiling A Simple Win32 Program - - VII. DLLs - A. Windows executable and Windows DLL. - B. Windows executable and WineLib DLL. - C. WineLib executable and Windows DLL. - D. WineLib executable and WineLib DLL. - -VIII. How to use MFC - A. Using a native MFC DLL - B. Compiling MFC - -===================================================================== - -I. Introduction: Wine vs. WineLib - -WineLib provides the Win32 API to a non-Microsoft operating -system. The WineLib Win32 functions use X11 functions to perform the -actual drawing on the screen. Wine and WineLib are based on the same -set of functions that implement the Win32 API. The difference between -Wine and WineLib is the type of executable that is loaded into memory -and executed. If an executable and any associated DLLs were compiled -for x86 hardware running the Windows 95, 98, or Windows NT (TM) -operating systems, then Wine can use a special binary loader to load -the program and the libraries into memory and execute it. WineLib on -the other hand allows you to take the source for such a program and -DLLs and compile it into the native format of a x86 Unix or Linux -operating system. WineLib also allows you to partially compile the -program and DLLs into the native format. For example, if you use a DLL -from a vendor to provide some functions to your program and the vendor -does not give you source, then you can use the Windows version of the -DLL to provide the functions and compile the rest of your program in -the native form for your system. [1] - -Windows compilers and linkers generate executables with a different -structure than standard compilers. Windows has two executable formats: -the NE format and the PE format. The NE executable format provides for -two entry points and the PE format provides for three entry points -while a standard executable has a single entry point. Usually, a NE or -a PE executable will use one of the entry points for your program and -the other entry points will print an error message and exit. However, -a linker can link 16 bit objects into one or both of the alternate -entry points of a NE or PE executable. - -Standard compilers assume that the function main() exists. The entry -point for a standard program is constructed from the C runtime -library, initialization code for static variables in your program, the -initialization code for your classes (C++), and your function main(). -On the other hand, windows compilers assume WinMain() exists. The -entry point for a windows program is constructed from the C runtime -library, initialization code for static variables in your program, the -initialization code for your classes (C++), and your function -WinMain(). [4] - -Since main() and WinMain() have different type signatures (parameter -types), WineLib provides certain aids to generate code so that your -program can be compiled and run as written for windows. For example, -WineLib generates a main() to initialize the windows API, to load any -necessary DLLs and then call your WinMain(). Therefore, you need to -learn four basic operations to compile a windows program using -WineLib: compiling a simple program, compiling resources, compiling -libraries, and compiling MFC (if you will be using MFC). Each of these -skills or operations are explained in later sections of this HOWTO. - -Before you start porting your windows code to WineLib, you need to -consider whether you are allowed to port your program to WineLib. As -you compile your program using WineLib, you will be combining software -from several sources and you need to ensure that the licenses for the -components are compatible. Hence, in the next section, we will examine -several legal issues. - - -IV. File Format Conversion - -Before you can compile your program, you must deal with one major -difference between Windows and WineLib. Window sources are in DOS -format with carriage return / line feed at the end of each line of -text while WineLib files are in Unix format with only line feed at the -end of each line of text. - -The main problem with the difference between Unix and DOS format -source files occurs with macro line continuation. A Unix compiler -expects a backslash (\) followed by a newline (^J) to indict that a -macro is continued on the next line. However, a file in DOS format will -have the characters backslash (\), carriage return (^M), and newline -(^J). The Unix compiler will interpret the backslash (\), carriage -return (^M), newline (^) of a file in DOS format as a quoted carriage -return and newline. The Unix compiler will think the line has ended -and the macro is completely defined. Hence, before you compile your -sources, you will need to convert you DOS format sources to Unix -format. There are several tools such as dos2unix and tr that are -available to convert the format. - -FIXME: get more info on dos2unix, tr, and all other such tools and -give example commands. Until I do [3] is a good source. - -FIXME: is CR/LF conversion necessary for gcc 2.95 ? - -V. Compiling A Simple Win32 Program - -Wine and WineLib are written in C as is the MS Win32 API; thus, if -have a program that calls only the Win32 API directly, you can compile -the program using a C compiler and link it with some of the WineLib -libraries. There are several simple examples of WineLib programs in -the directory libtest/ in the Wine source tree. We shall examine one -of these to show you how to compile a WineLib program. - -The example we shall examine is hello2. If you examine hello2.c, you -will see it is a windows program that pops up a message box that says -"Hello, hello!". It can be compiled and run using a windows compiler -just like any other windows program. However, it can not be compiled -and run with a non-windows compiler. As mentioned previously, windows -programs have an entry point called WinMain(), while non-windows -compilers use an entry point of main(). Hence, we need some "glue" to -glue the main() entry point to the WinMain() in the windows program. - -In WineLib, some of the glue is provided by the spec file. Spec files -are used in several places in Wine and WineLib to provide glue between -windows code and code for non-windows compilers. WineLib provides a -tool called winebuild in the tools/winebuild directory that converts a -spec file into a C file that can be compiled and linked with the -windows source files. ... - -VII. DLLs - -As mentioned in the introduction, Wine allows you to execute windows -executables and windows libraries under non-Microsoft operating -systems. WineLib allows you to take sources intended for the windows -operating system and to compile them to run as native executables -under a Unix/Linux operating system. With an executable and a single -library, there are four combinations in which to run the programs and -the library: - 1. a Windows executable with a Windows DLL, - 2. a Windows executable with WineLib DLL, - 3. a WineLib executable with Windows DLL, and - 4. a WineLib executable with WineLib DLL. -In this section, we will discuss each of these and discuss the steps -required to implement the executable/DLL combination. - -A. Windows executable and Windows DLL - -Running a windows executable with a windows DLL is not a WineLib -program: it is a Wine program. If you type - wine program.exe -and the DLL is in the search path, then the windows program should run -using the windows DLL. - -FIXME: find out what is the search path. - -B. Windows executable and WineLib DLL - -Running a windows executable with a WineLib DLL is also accomplished -using the Wine program. The source code for the DLL is compiled into a -Unix style shared library. When the windows executable "loads" the -DLL, Wine will use the shared library (.so file) instead. - -At first you may wonder why you would want to run a windows executable -with a WineLib DLL. Such a situation implies you do not have the -source for the executable, but you do have the source for the -DLL. This is backwards from what you might expect. However, I do have -an example where this situation might arise. - -Codewright is a popular editor in the windows world, and the -capabilities of Codewright can be extended by using DLLs. Since -Codewright is a commercial product, you do not have the source and -must use the windows executable with Wine. If you have written a DLL -to add functionality to Codewright, you have two choices: you can -compile the DLL using a windows compiler and use both a windows -executable and a windows DLL as in case A above, or you can use -WineLib and compile the DLL as a shared library (.so file). I have no -idea if Codewright actually runs under Wine, but this is an example of -why you might decide to use a windows executable and a WineLib -DLL. Many other editors and other programs use DLLs to extend their -functionality. - -In order for Wine to use the WineLib DLL, certain glue code is need to -replace the linker magic that windows compilers use. As with a simple -executable, the winebuild program uses a spec file to generate the glue -code. For example, in the spec file for the DLL will look something like - name winedll - type win32 - init winedll_DllMain - 1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay - 2 cdecl _WINEfullName@4 ( str ) WINEfullName -The name is the name of the DLL. Since WineLib only supports win32, -the type should always be win32. The init function is the name of the -initialization function for the DLL. The initialization function for a -windows DLL is named DllMain(). You will need to rename the function -in the DLL source so there will not be any name clashes with the -DllMain() of other DLLs in you program. - -The last two lines of the spec file above, provide the export -information for the DLL. For example, the line - 1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay -says that the function at ordinal 1 uses the cdecl calling convention -for the parameters. The DLL export name is _WINEbirthDay@4. The -function takes a single parameter that is a string. Finally, the C -function name to be called whenever this DLL function is called is -WINEbirthday. You will need a function ordinal line for each function -in the DLL. The export name and the ordinal can be obtained from the -windows program dumpbin and the windows version of the DLL. See the -file /tools/winebuild/README for more details on the spec file -format. - -During the compile process, a command like - winebuild -fPIC -o winedll.spec.c -spec winedll.spec -will be executed to create the file winedll.spec.c from information in -the file winedll.spec. The file winedll.spec.c and winedll.c are -compiled into object files and used to create the shared library. - -In order for the program to run, a copy of the shared library must be in -your EXTRA_LD_LIBRARY_PATH. For example, if your wine.conf file has -the following line, - EXTRA_LD_LIBRARY_PATH=${HOME}/wine/lib -then you must copy the shared library into the directory ~/wine/lib/ -and the shared library will now be in the correct search path. - -Now when you type - wine program.exe -the program will load the shared library (.so). - -C. WineLib executable and Windows DLL - -Running a WineLib executable with a Windows DLL is accomplished -using WineLib. This situation will be common since you may have -purchased DLLs to use with you project and the DLL vendor may not give -you the source code for the DLL. - -In order for WineLib to use the Windows DLL, certain glue code is -needed to replace the linker magic that windows compilers use. Part of -the glue code must be written by you. The basic idea of the glue code -is that you write a new DLL that consists of function pointers. Each -function in the DLL will consist of a call on a function pointer. For -example, - WINEDLL_ConstString WINEDLL_INTERFACE - WINEfullName( WINEDLL_ConstString handle ) { - return (* pWINEfullName) ( handle ); - } -The initialization function for the DLL will use the function -LoadLibrary() to load the windows DLL and initialize the function -pointers using the function GetProcAddress(). - -Since Wine can use either windows DLLs or Unix shared libraries (.so), -the LoadLibrary() function call may have unexpected results if there -is a winedll.dll and a winedll.so file. Hence, the windows version of -the DLL should be named something like hiddenWinedll.dll and the -shared library should be named winedll.so. Now the shared library will -use LoadLibrary() to load the "hidden" DLL. - -The shared library will need a spec file. Fortunately, it is simpler -than case B above. The spec file will look something like - name winedll - type win32 - init winedll_DllMain -The name is the name of the DLL. Since WineLib only supports win32, -the type should always be win32. The init function is the name of the -initialization function for the shared library. This is the function -that will load the "hidden" DLL and initialize the function -pointers. There is no need for any function ordinals unless your -program calls functions by the ordinal. - -During the compile process, a command like - winebuild -fPIC -o winedll.spec.c -spec winedll.spec -will be executed to create the file winedll.spec.c from information in -the file winedll.spec. The file winedll.spec.c and winedll.c are -compiled into object files and used to create the shared library. - -Now that the shared library is compiled, you still need to compile -your program. Part of the compile process for your program will -consist of a spec file for your program. For example, - name program - mode guiexe - type win32 - init WinMain - import winedll.dll -This spec file is similar to the spec file of the simple WineLib -example in part V above. The only difference is the import -specification that tells WineLib that the main program uses -winedll.dll. If this import line is not included, the "hidden" DLL -will not be loaded and the function pointers will not be initialized. - -During the compile process, a command like - winebuild -fPIC -o program.spec.c -spec program.spec -will be executed to create the file program.spec.c from information in -the file program.spec. The file program.spec.c and your source code are -compiled into object files and used to create the executable. - -D. WineLib executable and WineLib DLL. - -Running a WineLib executable with a WineLib DLL is accomplished using -WineLib. The source for the DLL will be combined with a spec file to -generate the shared library. Likewise, the source for your program and -a spec file will be combined to create the executable. In the source -for the DLL, you should change the name of DllMain() to a name like -winedll_DllMain() so that there will not be a name clash with other -initialization functions for other DLLs. - -The shared library's spec file is like case C above. The spec file -will look something like - name winedll - type win32 - init winedll_DllMain -The init function is the name of the initialization function for the -shared library (what you renamed DllMain to). There is no need for any -function ordinals unless your program calls functions by the ordinal. - -During the compile process, a command like - winebuild -fPIC -o winedll.spec.c -spec winedll.spec -will be executed to create the file winedll.spec.c from information in -the file winedll.spec. The file winedll.spec.c and the source code for -your DLL are compiled into object files and used to create the shared -library. - -Compiling your program is exactly like case C above. For example, the -spec file for you program will look something like - name program - mode guiexe - type win32 - init WinMain - import winedll.dll - -During the compile process, a command like - winebuild -fPIC -o program.spec.c -spec program.spec -will be executed to create the file program.spec.c from information in -the file program.spec. The file program.spec.c and your source code are -compiled into object files and used to create the executable. - -VIII. How to use MFC - A. Using a native MFC DLL - B. Compiling MFC - -FIXME: to be continued. - -A Windows compiler does NOT generate a fake main. Instead, the -executable file format provides for 2 (NE) or 3 (PE) entry points. -One of these is your program, the other(s) are normally filled with -stubs that print an error message and exit. It is possible to instruct -the _linker_ to link 16-bit objects into one or both of the alternate -entry points, and create a fat binary. - -At the C/C++ level, your statement about WinMain() is correct. Of -course the actual entry point first inits run time lib etc, and then -calls the C/C++ level entry, but that is also true for main() in the -standard setup. It may be important to regurgitate this info here, -though, because some of the fun things that can happen with multiple -run time libs and DLLs occur at this level. - -Line 86: I only need to know how compile MFC if I use it... :-) - - -From: Damyan Ognyanoff -Subject: Re: Wine MFC info request - -hi, -my MFC is from VC6.0 with SP3 -MFC Bulid: (form afxbld_.h) - #define _MFC_BUILD 8447 - #define _MFC_USER_BUILD "8447" - #define _MFC_RBLD 0 -mfcdll.rc - FILEVERSION 6,0,_MFC_BUILD,_MFC_RBLD - PRODUCTVERSION 6,0,0,0 - -Hints: - 1. Wine include files - -In some of them you will find error about '__attribute__' all kinds of -similar errors can be fixed using proper typedefs first example : - -typedef BOOL (CALLBACK *DLGPROC)(HWND,UINT,WPARAM,LPARAM); - -must be converted to - -typedef BOOL CALLBACK (*DLGPROC)(HWND,UINT,WPARAM,LPARAM); - -and the second kind is something like - -TYPE* WINAPI SomeFunction(HWND param1,UINT param2); - -The problem here is a TYPE* or TYPE& (in some of mfc files) the -workaround is to declare a type before: - -typedef TYPE* TYPEPtr; - -or - -typedef TYPE& TYPERef; - -and declaration will look like: - -TYPEPtr WINAPI SomeFunction(HWND param1,UINT param2); - -note: don't miss a 'struct' when you define struct type pointers. I -miss it and get a lot of problems compiling MFC: - ->> -struct _TEB; -typedef !!!struct!!! _TEB* P_TEB; -extern inline P_TEB WINAPI NtCurrentTeb(void); -<< - -Those conversions are semantically the same as above but g++ compile -them and generate proper code to invoke __stdcall kind of functions - -in some of Wine/obj_XXX.h files: Wine/obj_base.h - there are a lot of -defines's that are used to declare a COM interfaces - -#define ICOM_METHOD(ret,xfn) \ - public: virtual ret (CALLBACK xfn)(void) = 0; - -will be (for all of them that are related to C++ (watch #ifdef's -carefully)): - -#define ICOM_METHOD(ret,xfn) \ - public: virtual ret CALLBACK (xfn)(void) = 0; - -and the second tip is an error when compiler stops on line like: - - ICOM_DEFINE(ISomeInterfase,IUnknown) - -watch method declarations above to find something like: - -ICOM_METHOD1(TYPE*,MethodName, DWORD,dwParam) - -and replace TYPE* with proper TYPEPtr type. In many cases You will see -void* which can be replaced simply by LPVOID. - -qthere are several errors related to anonymous structs and unions but -they can be avoided with proper - #ifdef __cplusplus - -This is all about Wine headers I think. If you find something that I -miss type a line of mail to me. - -2. MFC -The rules are the same with some new issues: - -virtual BOOL Method1(int param1, BOOL (CALLBACK *param2) -(HWND,UINT,WPARAM,LPARAM)); - -don't compile. I remove a function pointer declaration -outside method: - -typedef BOOL CALLBACK -(*param2Type)(HWND,UINT,WPARAM,LPARAM); - -virtual BOOL Method1(int param1, param2Type param2); - -I didn't apply this technique to a operator new -definitions: - - void* AFXAPI operator new(size_t nSize); - -so i remove AFXAPI from these declarations: - -I got some missed #defines from commctrl.h and I added -them form VC6.0 include. - -these are my defines form Makefile which I used to -compile MFC - --DTWINE_NO_CMONIKER \ -- this is related to exclude -CMonikerFile --D__urlmon_h__ \ -- Wine didn't have URL interfaces --D_AFX_NO_OLEDB_SUPPORT \ --D_WIN32 \ --DNOWIN98 \ -- this is used to exclude all -unimplemented classes from commctrl --D_AFX_PACKING \ --D_AFX_NO_DHTML_SUPPORT \ --D_AFX_NO_SOCKET_SUPPORT \ --D_AFX_NO_SYNC_SUPPORT \ --D_AFX_NO_OCX_SUPPORT \ --D_AFX_PORTABLE \ --D_AFX_OLD_EXCEPTIONS \ --D_AFX_NO_SOCKET_SUPPORT \ --D_AFX_NO_DEBUG_CRT \ --D_AFX_NO_DAO_SUPPORT \ --D_AFX_NO_OCC_SUPPORT \ --D_AFX_NO_INET_SUPPORT \ --D_AFX_NO_RICHEDIT_SUPPORT \ --D_X86_ \ --DLONGHANDLES - -may be you will try to enable some of features of mfc I tested only --D_AFX_NO_OCC_SUPPORT but got missing interfaces from Wine - -in file afxcom_.h -- _CIP<_Interface, _IID>::~_CIP<_Interface, _IID>() -+ _CIP<_Interface, _IID>::~_CIP() - -in file afxtempl.h -- BOOL Lookup(BASE_CLASS::BASE_ARG_KEY key, -VALUE& rValue) const -- { return BASE_CLASS::Lookup(key, -(BASE_CLASS::BASE_VALUE&)rValue); } -+ BOOL Lookup(typename BASE_CLASS::BASE_ARG_KEY -key, VALUE& rValue) const -+ { return BASE_CLASS::Lookup(key, -(typename BASE_CLASS::BASE_VALUE&)rValue); } - -and all releated errors can be fixed in this way. - -3. spec file - name mfc42 - type win32 - rsrc mfc42 - - 10 stdcall WinMain(long long ptr long) WinMain - -4. linking - use -rdynamic wnen link libmfc.so to get ARGV and -ARGC from loader - -5. I didn'n build a extension dll with Wine but I suspect that there -will be some problems related to a chaining Runtime classes form MFC -to a new dll - -6. build your app as a MODULE too. - -7. make a loader and in it's _WinMain: -... includes are here -iint PASCAL (*winMain)(HINSTANCE,HINSTANCE,LPSTR,int) = -0; -my app uses these to manage filenames -VOID __cdecl (*_splitpath1)(LPCSTR path, LPSTR drive, -LPSTR directory, LPSTR filename, LPSTR extension ) = -NULL; -VOID __cdecl _splitpath(LPCSTR path, LPSTR drive, -LPSTR directory, LPSTR filename, LPSTR extension ) -{ - if (_splitpath1) - _splitpath1(path, drive, directory, filename, -extension ); -} -VOID __cdecl (*_makepath1)(LPSTR path, LPCSTR drive, -LPCSTR directory, LPCSTR filename, LPCSTR extension ) -= NULL; -VOID __cdecl _makepath(LPSTR path, LPCSTR drive, -LPCSTR directory, LPCSTR filename, LPCSTR extension ) -{ - if (_makepath1) - _makepath1(path, drive, directory, filename, -extension); -} -int PASCAL _WinMain(HINSTANCE h,HINSTANCE h1,LPSTR -lpszCmdParam,int c) -{ - HINSTANCE hInstance,hins,hlib,htst,hform,himag,hexe; - int retv; - - hins = LoadLibrary("CRTDLL.DLL"); - _splitpath1 = GetProcAddress(hins, -"_splitpath"); - _makepath1 = GetProcAddress(hins, -"_makepath"); - hins = LoadLibrary("COMCTL32.DLL"); - hins = LoadLibrary("COMDLG32.DLL"); - - - hins = dlopen("libmfc42.so",2); - hlib = LoadLibrary("mfc42"); - himag = dlopen("libmxformatslib.so",2); - hform = LoadLibrary("mxformatslib"); - hexe = dlopen("libmxpaint.so",2); - htst = LoadLibrary("mxpaint"); - - winMain = GetProcAddress(hlib, "WinMain"); - if (winMain) - { - retv = winMain (htst, // note the > htst -< HERE - 0, - lpszCmdParam, - SW_NORMAL); - } - FreeLibrary(htst); - FreeLibrary(hform); - FreeLibrary(hlib); - dlclose(hexe); - dlclose(himag); - dlclose(hins); - return retv; -} -the spec for loader is: -name c10 -mode guiexe -type win32 -init _WinMain - -please find attached a Makefile which i use to build -MFC - -Regards -Damyan. diff --git a/documentation/status/dde b/documentation/status/dde deleted file mode 100644 index 27188711792..00000000000 --- a/documentation/status/dde +++ /dev/null @@ -1,50 +0,0 @@ -This is the status for DDE (i.e. raw dde messages) and ddeml. - -DDE was implemented by Micheal Veksler some time ago, it has been reported as broken -by changes in the server and related parts of wine. AFAIK no-one has tried to fix these -and I have not tried to test them. - -ddeml was untouched until December 1998 when some of the Corel/Macadamian team started -writing bits that were needed by Corel for the WordPerfect Suite port. These were mainly -around string handling and have been identified in the change history for each routine. -They were written to cope with a single instance only. About a week later I started -looking at ddeml as a whole. - -The initialisation was tackled first, then the routines produced by Corel/Macadamian -were modified to cope with multiple instances of dde client/server and a first cut at -the un-initialise routine. - -DdeNameService has now been produced as a first-cut routine, but the monitor notification -must be tackled, followed by the main message reception routine and the invoking of the -callback. Serious testing from this point may well depend on Wine thread handling -settling down. - -The strategy so far has been to tackle the Unicode versions first. Once they have been -accepted as close to complete then the 32-bit ASCII routines then the 16-bit routines. - -It is recognised that the solutions adopted may well not be suitable for wine-OS2, since -that OS has its own DDE rotuines intermediate in integration between raw DDE and ddeml, -also O/S 2 users may well want programs running under Wine to talk to native O/S 2 programs. -I do not have knowledge of MacOS or the internals of BeOS, but these may suffer from the -same problems. - -TO DO - -Complete initialisation, some of the 2nd call validation conditions have not been worked out -yet and the code for enabling the message loop needs writing. - -Complete initialize and unitialize, also add the callback handling to DdeNameService. - -Add true Unicode handling to CreateStringHandle, QueryString, CmpStringHandles. Also find -out why Initialize needs ASCII and Unicode variants. - -Add DdeGetLAstError and related handling in all other modules. Also find out what to do about -storing errors that result in the instance failing to initialise in some way. - - -Just about all the rest - -More specific items are commented in the code. - - -Keith Matthews