| 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 <wine>/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 <Damyan@rocketmail.com> | |
| 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. |