Fix a regression when loading a real windows registry.
[wine] / documentation / HOWTO-winelib
1 WineLib HOWTO
2 Version 28-Dec-2000
3
4 AUTHOR: 
5 Wilbur Dale
6 Lumin Software BV
7 Zandheuvel 52 B
8 4901 HW Oosterhout (NB)
9 The Netherlands
10
11 wilbur.dale@lumin.nl
12
13 WARNING: This HOWTO is incomplete. I expect to add to it on a weekly
14 basis until it is complete.
15
16 =====================================================================
17
18 Table of Contents
19
20    I. Introduction: Wine vs. WineLib
21
22   II. Legal Issues
23
24  III. How Much Work?
25
26   IV. File Format Conversion
27
28    V. Compiling A Simple Win32 Program 
29
30   VI. Compiling A Win32 Program With Resources
31
32  VII. DLLs
33     A. Windows executable and Windows DLL.
34     B. Windows executable and WineLib DLL.
35     C. WineLib executable and Windows DLL.
36     D. WineLib executable and WineLib DLL.
37
38 VIII. How to use MFC
39     A. Using a native MFC DLL
40     B. Compiling MFC
41
42 VIII. Trademarks
43 Windows 3.x, Windows 95, Windows 98, Windows NT are trademarks of
44 Microsoft Corporation. 
45
46 Unix is a trademark of ???? FIXME: who has the trademark this week?
47
48 CrypKey is a trademark of Kenonic Controls Ltd.
49
50 FIXME: Codewright copyright ???
51
52 All other trademarks are the property of their respective owners.
53
54 =====================================================================
55
56 I. Introduction: Wine vs. WineLib
57
58 WineLib provides the Win32 API to a non-Microsoft operating
59 system. The WineLib Win32 functions use X11 functions to perform the
60 actual drawing on the screen. Wine and WineLib are based on the same
61 set of functions that implement the Win32 API. The difference between
62 Wine and WineLib is the type of executable that is loaded into memory
63 and executed. If an executable and any associated DLLs were compiled
64 for x86 hardware running the Windows 95, 98, or Windows NT (TM)
65 operating systems, then Wine can use a special binary loader to load
66 the program and the libraries into memory and execute it. WineLib on
67 the other hand allows you to take the source for such a program and
68 DLLs and compile it into the native format of a x86 Unix or Linux
69 operating system. WineLib also allows you to partially compile the
70 program and DLLs into the native format. For example, if you use a DLL
71 from a vendor to provide some functions to your program and the vendor
72 does not give you source, then you can use the Windows version of the
73 DLL to provide the functions and compile the rest of your program in
74 the native form for your system. [1]
75
76 Windows compilers and linkers generate executables with a different
77 structure than standard compilers. Windows has two executable formats:
78 the NE format and the PE format. The NE executable format provides for
79 two entry points and the PE format provides for three entry points
80 while a standard executable has a single entry point. Usually, a NE or
81 a PE executable will use one of the entry points for your program and
82 the other entry points will print an error message and exit. However,
83 a linker can link 16 bit objects into one or both of the alternate
84 entry points of a NE or PE executable.
85
86 Standard compilers assume that the function main() exists. The entry
87 point for a standard program is constructed from the C runtime
88 library, initialization code for static variables in your program, the
89 initialization code for your classes (C++), and your function main().
90 On the other hand, windows compilers assume WinMain() exists. The
91 entry point for a windows program is constructed from the C runtime
92 library, initialization code for static variables in your program, the
93 initialization code for your classes (C++), and your function
94 WinMain(). [4]
95
96 Since main() and WinMain() have different type signatures (parameter
97 types), WineLib provides certain aids to generate code so that your
98 program can be compiled and run as written for windows. For example,
99 WineLib generates a main() to initialize the windows API, to load any
100 necessary DLLs and then call your WinMain(). Therefore, you need to
101 learn four basic operations to compile a windows program using
102 WineLib: compiling a simple program, compiling resources, compiling
103 libraries, and compiling MFC (if you will be using MFC). Each of these
104 skills or operations are explained in later sections of this HOWTO.
105
106 Before you start porting your windows code to WineLib, you need to
107 consider whether you are allowed to port your program to WineLib. As
108 you compile your program using WineLib, you will be combining software
109 from several sources and you need to ensure that the licenses for the
110 components are compatible. Hence, in the next section, we will examine
111 several legal issues.
112
113
114 IV. File Format Conversion
115
116 Before you can compile your program, you must deal with one major
117 difference between Windows and WineLib. Window sources are in DOS
118 format with carriage return / line feed at the end of each line of
119 text while WineLib files are in Unix format with only line feed at the
120 end of each line of text. 
121
122 The main problem with the difference between Unix and DOS format
123 source files occurs with macro line continuation. A Unix compiler
124 expects a backslash (\) followed by a newline (^J) to indict that a
125 macro is continued on the next line. However, a file in DOS format will
126 have the characters backslash (\), carriage return (^M), and newline
127 (^J). The Unix compiler will interpret the backslash (\), carriage
128 return (^M), newline (^) of a file in DOS format as a quoted carriage
129 return and newline. The Unix compiler will think the line has ended
130 and the macro is completely defined. Hence, before you compile your
131 sources, you will need to convert you DOS format sources to Unix
132 format. There are several tools such as dos2unix and tr that are
133 available to convert the format.
134
135 FIXME: get more info on dos2unix, tr, and all other such tools and
136 give example commands. Until I do [3] is a good source.
137
138 FIXME: is CR/LF conversion necessary for gcc 2.95 ?
139
140 V. Compiling A Simple Win32 Program 
141
142 Wine and WineLib are written in C as is the MS Win32 API; thus, if
143 have a program that calls only the Win32 API directly, you can compile
144 the program using a C compiler and link it with some of the WineLib
145 libraries. There are several simple examples of WineLib programs in
146 the directory libtest/ in the Wine source tree. We shall examine one
147 of these to show you how to compile a WineLib program.
148
149 The example we shall examine is hello2. If you examine hello2.c, you
150 will see it is a windows program that pops up a message box that says
151 "Hello, hello!". It can be compiled and run using a windows compiler
152 just like any other windows program. However, it can not be compiled
153 and run with a non-windows compiler. As mentioned previously, windows
154 programs have an entry point called WinMain(), while non-windows
155 compilers use an entry point of main(). Hence, we need some "glue" to
156 glue the main() entry point to the WinMain() in the windows program.
157
158 In WineLib, some of the glue is provided by the spec file. Spec files
159 are used in several places in Wine and WineLib to provide glue between
160 windows code and code for non-windows compilers. WineLib provides a
161 tool called winebuild in the tools/winebuild directory that converts a
162 spec file into a C file that can be compiled and linked with the
163 windows source files. If you examine hello2.spec, you will see the
164 following:
165
166 name    hello2
167 mode    guiexe
168 type    win32
169
170 import  user32.dll
171 import  kernel32.dll
172 import  ntdll.dll
173
174 Information on the complete format of the spec file can be found in
175 <wine>/tools/winebuild/README. Name is the name of the
176 application. Mode is the type of "glue" that winebuild needs to
177 create. Possible modes are 'dll' for a library, 'cuiexe' for a console
178 application, and 'guiexe' for a regular graphical application. Type is
179 the type of API, either win32 or win16. Win16 is supported only in
180 Wine, not WineLib, so you should use win32. Import is a dll that must
181 be loaded for the program to execute.
182
183 During compilation of the hello2 executable, the following command is
184 executed. 
185
186 LD_LIBRARY_PATH="..:$LD_LIBRARY_PATH" \
187     ../tools/winebuild/winebuild -fPIC -L ../dlls -sym hello2.o \
188     -o hello2.spec.c -spec hello2.spec
189
190 The program winebuild will generate the output file hello2.spec.c (option
191 -o hello2.spec.c) from the spec file hello2.spec (option -spec
192 hello2.spec). The option -fPIC specifies that winebuild should generate
193 position independent code and is only necessary for building shared
194 library files (.so files). It is not needed when building the main
195 executable spec file, but since there is no assembly code generated
196 for the main executable, it doesn't make any difference anyway. [5]
197
198 The winebuild program is used in several places in Wine as well as
199 WineLib; however, only the -spec option will be used in WineLib. The
200 output file hello2.spec.c contains the glue code to initialize WineLib
201 and call WinMain().
202
203 In order to run hello2, we will compile the code into a shared library
204 (hello2.so) and create a symbolic link (hello2) with the wine
205 executable with the following steps.
206
207 gcc -c -I. -I. -I../include -I../include -g -O2 -Wall -fPIC -DSTRICT \
208     -D_REENTRANT -I/usr/X11R6/include -o hello2.o hello2.c
209
210 to compile the windows program itself and 
211
212 gcc -c -I. -I. -I../include -I../include -g -O2 -Wall -fPIC -DSTRICT \
213     -D_REENTRANT -I/usr/X11R6/include -o hello2.spec.o hello2.spec.c
214
215 to compile the spec file and the glue code. Finally,
216
217 gcc -shared  -Wl,-rpath,/usr/local/lib -Wl,-Bsymbolic -o hello2.so \
218     hello2.o hello2.spec.o -L.. -lwine -lncurses -lm  -lutil -ldl
219
220 links the compiled files into a shared library.
221
222 FIXME: -D_REENTRANT why?
223 FIXME: explain compiler options
224 FIXME: explain linker options
225
226 All of the steps are automated with the makefile, so "make hello2.so"
227 will execute all of the steps for you.  A final step is "make hello2",
228 which creates a symbolic link from hello2 to the wine executable. Now,
229 when "./hello2" is run, the wine executable sees it was called by the
230 name "hello2" and loads the shared library "hello2.so" and executes
231 the program.
232
233 THE INFO BELOW IS OUT OF DATE (28-Dec-2000)
234
235 Thus, you now have the basics of compiling a simple windows
236 program. There are two more things to learn for compiling more complex
237 windows programs: windows resources and DLL dependencies. Window
238 resources are described in the next section. DLL dependencies are
239 handled by linker magic with windows compilers. Thus, in WineLib, you
240 will need to provide information about which DLLs your program
241 depends. This information is given in the spec file. For example, if
242 our hello2 program had a .wav file that it played, it would need the
243 multi-media DLL winmm. Our spec file would then be
244
245 name    hello2
246 mode    guiexe
247 type    win32
248 init    WinMain
249 import  winmm
250
251 If you need to list multiple DLLs, then the import specification can
252 appear multiple times, one line per imported DLL.
253
254 VII. DLLs
255
256 As mentioned in the introduction, Wine allows you to execute windows
257 executables and windows libraries under non-Microsoft operating
258 systems. WineLib allows you to take sources intended for the windows
259 operating system and to compile them to run as native executables
260 under a Unix/Linux operating system. With an executable and a single
261 library, there are four combinations in which to run the programs and
262 the library:
263     1. a Windows executable with a Windows DLL,
264     2. a Windows executable with WineLib DLL,
265     3. a WineLib executable with Windows DLL, and
266     4. a WineLib executable with WineLib DLL.
267 In this section, we will discuss each of these and discuss the steps
268 required to implement the executable/DLL combination. 
269
270 A. Windows executable and Windows DLL
271
272 Running a windows executable with a windows DLL is not a WineLib
273 program: it is a Wine program. If you type
274     wine program.exe
275 and the DLL is in the search path, then the windows program should run
276 using the windows DLL.
277
278 FIXME: find out what is the search path.
279
280 B. Windows executable and WineLib DLL
281
282 Running a windows executable with a WineLib DLL is also accomplished
283 using the Wine program. The source code for the DLL is compiled into a
284 Unix style shared library. When the windows executable "loads" the
285 DLL, Wine will use the shared library (.so file) instead.
286
287 At first you may wonder why you would want to run a windows executable
288 with a WineLib DLL. Such a situation implies you do not have the
289 source for the executable, but you do have the source for the
290 DLL. This is backwards from what you might expect. However, I do have
291 an example where this situation might arise.
292
293 Codewright is a popular editor in the windows world, and the
294 capabilities of Codewright can be extended by using DLLs. Since
295 Codewright is a commercial product, you do not have the source and
296 must use the windows executable with Wine. If you have written a DLL
297 to add functionality to Codewright, you have two choices: you can
298 compile the DLL using a windows compiler and use both a windows
299 executable and a windows DLL as in case A above, or you can use
300 WineLib and compile the DLL as a shared library (.so file). I have no
301 idea if Codewright actually runs under Wine, but this is an example of
302 why you might decide to use a windows executable and a WineLib
303 DLL. Many other editors and other programs use DLLs to extend their
304 functionality.
305
306 In order for Wine to use the WineLib DLL, certain glue code is need to
307 replace the linker magic that windows compilers use. As with a simple
308 executable, the winebuild program uses a spec file to generate the glue
309 code. For example, in the spec file for the DLL will look something like
310     name        winedll
311     type        win32
312     init        winedll_DllMain
313     1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay
314     2 cdecl _WINEfullName@4 ( str ) WINEfullName
315 The name is the name of the DLL. Since WineLib only supports win32,
316 the type should always be win32. The init function is the name of the
317 initialization function for the DLL. The initialization function for a
318 windows DLL is named DllMain(). You will need to rename the function
319 in the DLL source so there will not be any name clashes with the
320 DllMain() of other DLLs in you program.
321
322 The last two lines of the spec file above, provide the export
323 information for the DLL. For example, the line
324     1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay
325 says that the function at ordinal 1 uses the cdecl calling convention
326 for the parameters. The DLL export name is _WINEbirthDay@4. The
327 function takes a single parameter that is a string. Finally, the C
328 function name to be called whenever this DLL function is called is
329 WINEbirthday. You will need a function ordinal line for each function
330 in the DLL. The export name and the ordinal can be obtained from the
331 windows program dumpbin and the windows version of the DLL. See the
332 file <wine>/tools/winebuild/README for more details on the spec file
333 format.
334
335 During the compile process, a command like
336     winebuild -fPIC -o winedll.spec.c -spec winedll.spec
337 will be executed to create the file winedll.spec.c from information in
338 the file winedll.spec. The file winedll.spec.c and winedll.c are
339 compiled into object files and used to create the shared library.
340
341 In order for the program to run, a copy of the shared library must be in
342 your EXTRA_LD_LIBRARY_PATH. For example, if your wine.conf file has
343 the following line,
344     EXTRA_LD_LIBRARY_PATH=${HOME}/wine/lib
345 then you must copy the shared library into the directory ~/wine/lib/
346 and the shared library will now be in the correct search path.
347
348 Now when you type 
349     wine program.exe
350 the program will load the shared library (.so).
351
352 C. WineLib executable and Windows DLL
353
354 Running a WineLib executable with a Windows DLL is accomplished
355 using WineLib. This situation will be common since you may have
356 purchased DLLs to use with you project and the DLL vendor may not give
357 you the source code for the DLL.
358
359 In order for WineLib to use the Windows DLL, certain glue code is
360 needed to replace the linker magic that windows compilers use. Part of
361 the glue code must be written by you. The basic idea of the glue code
362 is that you write a new DLL that consists of function pointers. Each
363 function in the DLL will consist of a call on a function pointer. For
364 example, 
365     WINEDLL_ConstString WINEDLL_INTERFACE 
366     WINEfullName( WINEDLL_ConstString handle ) {
367         return (* pWINEfullName) ( handle );
368     }
369 The initialization function for the DLL will use the function
370 LoadLibrary() to load the windows DLL and initialize the function
371 pointers using the function GetProcAddress(). 
372
373 Since Wine can use either windows DLLs or Unix shared libraries (.so),
374 the LoadLibrary() function call may have unexpected results if there
375 is a winedll.dll and a winedll.so file. Hence, the windows version of
376 the DLL should be named something like hiddenWinedll.dll and the
377 shared library should be named winedll.so. Now the shared library will
378 use LoadLibrary() to load the "hidden" DLL.
379
380 The shared library will need a spec file. Fortunately, it is simpler
381 than case B above. The spec file will look something like
382     name        winedll
383     type        win32
384     init        winedll_DllMain
385 The name is the name of the DLL. Since WineLib only supports win32,
386 the type should always be win32. The init function is the name of the
387 initialization function for the shared library. This is the function
388 that will load the "hidden" DLL and initialize the function
389 pointers. There is no need for any function ordinals unless your
390 program calls functions by the ordinal.
391
392 During the compile process, a command like
393     winebuild -fPIC -o winedll.spec.c -spec winedll.spec
394 will be executed to create the file winedll.spec.c from information in
395 the file winedll.spec. The file winedll.spec.c and winedll.c are
396 compiled into object files and used to create the shared library.
397
398 Now that the shared library is compiled, you still need to compile
399 your program. Part of the compile process for your program will
400 consist of a spec file for your program. For example,
401     name        program
402     mode        guiexe
403     type        win32
404     init        WinMain
405     import winedll.dll
406 This spec file is similar to the spec file of the simple WineLib
407 example in part V above. The only difference is the import
408 specification that tells WineLib that the main program uses
409 winedll.dll. If this import line is not included, the "hidden" DLL
410 will not be loaded and the function pointers will not be initialized.
411
412 During the compile process, a command like
413     winebuild -fPIC -o program.spec.c -spec program.spec
414 will be executed to create the file program.spec.c from information in
415 the file program.spec. The file program.spec.c and your source code are
416 compiled into object files and used to create the executable.
417
418 D. WineLib executable and WineLib DLL.
419
420 Running a WineLib executable with a WineLib DLL is accomplished using
421 WineLib. The source for the DLL will be combined with a spec file to
422 generate the shared library. Likewise, the source for your program and
423 a spec file will be combined to create the executable. In the source
424 for the DLL, you should change the name of DllMain() to a name like
425 winedll_DllMain() so that there will not be a name clash with other
426 initialization functions for other DLLs.
427
428 The shared library's spec file is like case C above. The spec file
429 will look something like
430     name        winedll
431     type        win32
432     init        winedll_DllMain
433 The init function is the name of the initialization function for the
434 shared library (what you renamed DllMain to). There is no need for any
435 function ordinals unless your program calls functions by the ordinal.
436
437 During the compile process, a command like
438     winebuild -fPIC -o winedll.spec.c -spec winedll.spec
439 will be executed to create the file winedll.spec.c from information in
440 the file winedll.spec. The file winedll.spec.c and the source code for
441 your DLL are compiled into object files and used to create the shared
442 library.
443
444 Compiling your program is exactly like case C above. For example, the
445 spec file for you program will look something like
446     name        program
447     mode        guiexe
448     type        win32
449     init        WinMain
450     import winedll.dll
451
452 During the compile process, a command like
453     winebuild -fPIC -o program.spec.c -spec program.spec
454 will be executed to create the file program.spec.c from information in
455 the file program.spec. The file program.spec.c and your source code are
456 compiled into object files and used to create the executable.
457
458 VIII. How to use MFC
459     A. Using a native MFC DLL
460     B. Compiling MFC
461
462 FIXME: to be continued.
463
464 =====================================================================
465 References
466
467 Until this HOWTO is complete, I will document who gives me what
468 information. 
469
470 Reference [1] 
471 From: Patrik Stridvall <ps@leissner.se>
472 To: "'wilbur.dale@lumin.nl'" <wilbur.dale@lumin.nl>,
473 Date:   Mon, 5 Jun 2000 14:25:22 +0200 
474
475 First of all WineLib suppport for Win16 has been discontinued
476 for quite some time, because:
477
478 1. It is difficult for us to support and it is impossible
479    to do so perfectly without special compiler support,
480    because of memory layout issues. For example Win16 int
481    is 16-bit and data is aligned 16-bit.
482 2. It is in almost all cases easier to port a
483    Win16 application to Win32.
484
485 A minor detail, I personally would prefer that Wine and WineLib
486 was always used in the uppercase W and uppercase L variant,
487 instead of, as in your document, sometime one variant, sometimes
488 another.
489
490 Reference [2] 
491
492 The exact options for controlling error messages mentioned in the
493 reference are apparently incorrect, but may have been correct for some
494 earlier version of Wine.
495
496 From: michael cardenas <mbc@deneba.com>
497 To: wilbur.dale@lumin.nl
498 Date:   Mon, 5 Jun 2000 13:19:34 -0400
499
500 a few things you should mention...
501
502 - you can compile resources as a dll under windows and then load the dll
503 with wine. That's what we do for canvas. This is probably not ideal, but
504 most of my problems porting were in the code. We very seldomly have to
505 change the resources for the porting process. But wrc does work for most
506 cases...
507
508 - the error messages can be turned off or turned up with options to
509 configure like --enable-trace-msgs=wireoff or --enable-trace-msgs=wireon .
510 Take a look at configure.
511
512 - you probably want to compile your WineLib with --disable-debugger, at
513 least for the release version of your app.
514
515 Reference [3] 
516 http://fgouget.free.fr/wine/winelib-en.shtml
517
518 Reference [4]
519 Date: Wed, 21 Jun 2000 10:34:10 +0200
520 From: Rob Carriere <rob.carriere@lumin.nl>
521 To: Wilbur N Dale <wilbur.dale@lumin.nl>
522 Subject: WineLib-HOWTO comments
523
524 Hello Wilbur,
525
526 Some picking of nits.  It reads right well.
527
528 Some of Windows xyz are registered trade marks, other are vanilla:
529 Microsoft: Registered
530 Windows NT: Registered
531 Windows (95,98): plain
532
533 A Windows compiler does NOT generate a fake main.  Instead, the
534 executable file format provides for 2 (NE) or 3 (PE) entry points.
535 One of these is your program, the other(s) are normally filled with
536 stubs that print an error message and exit.  It is possible to instruct
537 the _linker_ to link 16-bit objects into one or both of the alternate
538 entry points, and create a fat binary.
539
540 At the C/C++ level, your statement about WinMain() is correct.  Of
541 course the actual entry point first inits run time lib etc, and then
542 calls the C/C++ level entry, but that is also true for main() in the
543 standard setup.  It may be important to regurgitate this info here,
544 though, because some of the fun things that can happen with multiple
545 run time libs and DLLs occur at this level.
546
547 Line 86: I only need to know how compile MFC if I use it... :-)
548
549
550 Best regards,
551  Rob                          mailto:rob.carriere@lumin.nl
552
553 Reference [5]
554 To: wilbur.dale@lumin.nl
555 Subject: Re: tool/build questions
556 From: Alexandre Julliard <julliard@winehq.com>
557 Date:   13 Jun 2000 20:06:23 -0700
558
559 "Wilbur N. Dale" <wilbur.dale@lumin.nl> writes:
560
561 > 2. tools/build for WineLib users -- is there ever a need to not specify -pic?
562
563 -pic is only necessary for building .so files, so it's not needed when
564 building the main executable spec file (but since there is no assembly
565 code generated for the main exe it doesn't make any difference anyway).
566
567 -- 
568 Alexandre Julliard
569 julliard@winehq.com
570
571 Reference [6]
572 Wine Weekly News #51 (2000 Week 28)
573
574 Events, progress, and happenings in the Wine community for 
575 July 10, 2000. 
576
577 Uwe Bonnes and Ove Kaven also reminded of some tools to generate under
578    Linux some Windows executables:
579      * Cygwin/Mingw: as native Linux apps
580      * LCC-Win32: run with the help of Wine
581      * Borland C++ 5.5: command line version available for free (after
582        registering to Borland users' database)
583        
584 =====================================================================
585
586 The information included here is from various Wine-devel posting and
587 private e-mails. I am including them so that any one starting on MFC
588 will have some documentation. Glean what you can and good luck.
589
590 Before I write more detailed info on compiling MFC I have three
591 questions. The info I have mentions three problems:
592
593     1. Wine header files---what is the status of this? Do changes need
594     to be made in the headers and if so, do I submit the changes back
595     into Wine cvs? Do the changes need #ifdef for C vs. C++
596     compilation? 
597
598     Francois Gouget <fgouget@psn.net> has been doing a lot of work in
599     this area. It should be a lot easier to compile using C++ now and to
600     compile MFC.
601
602     2. DOS format files <CR/LF> and no case distinction in
603     filenames. Do the extensions Corel made to gcc 2.95 handle this?
604     If so, how?
605
606     3. Microsoft extensions to the C++ syntax. Do the extensions Corel
607     made to gcc 2.95 handle this? If so, how?
608
609 If you have info that needs to be added, send me email at
610 <wilbur.dale@lumin.nl> and I will add it.
611
612 =====================================================================
613
614 THANKS
615
616 Most of the information in this file came from postings on
617 <Wine-devel@Winehq.com> and from private e-mails. The following people
618 contributed information for this document and I thank them for their
619 time and effort in answering my questions. I also want to thank them
620 for encouraging me to attack the MFC problem. 
621
622 CONTRIBUTERS:
623
624     Damyan Ognyanoff <Damyan@rocketmail.com>
625     Gavriel State <gav@magmacom.com>
626     Ian Schmidt <ischmidt@cfl.rr.com>
627     Jeremy White <jwhite@codeweavers.com>
628
629
630 From: Damyan Ognyanoff <Damyan@rocketmail.com>
631 Subject: Re: Wine MFC info request
632
633 hi,
634 my MFC is from VC6.0 with SP3
635 MFC Bulid: (form  afxbld_.h)
636     #define _MFC_BUILD 8447
637     #define _MFC_USER_BUILD "8447"
638     #define _MFC_RBLD 0
639 mfcdll.rc
640     FILEVERSION       6,0,_MFC_BUILD,_MFC_RBLD
641     PRODUCTVERSION    6,0,0,0
642
643 Hints:
644     1. Wine include files
645
646 In some of them you will find error about '__attribute__' all kinds of
647 similar errors can be fixed using proper typedefs first example :
648
649 typedef BOOL (CALLBACK *DLGPROC)(HWND,UINT,WPARAM,LPARAM);
650
651 must be converted to
652
653 typedef BOOL CALLBACK (*DLGPROC)(HWND,UINT,WPARAM,LPARAM);
654
655 and the second kind is something like
656
657 TYPE* WINAPI SomeFunction(HWND param1,UINT param2);
658
659 The problem here is a TYPE* or TYPE& (in some of mfc files) the
660 workaround is to declare a type before:
661
662 typedef TYPE* TYPEPtr; 
663
664 or
665
666 typedef TYPE& TYPERef;
667
668 and declaration will look like:
669
670 TYPEPtr WINAPI SomeFunction(HWND param1,UINT param2);
671
672 note: don't miss a 'struct' when you define struct type pointers. I
673 miss it and get a lot of problems compiling MFC:
674
675 >>
676 struct _TEB;
677 typedef !!!struct!!! _TEB* P_TEB;
678 extern inline P_TEB WINAPI NtCurrentTeb(void);
679 <<
680
681 Those conversions are semanticaly the same as above but g++ compile
682 them and generate proper code to invoke __stdcall kind of functions
683
684 in some of Wine/obj_XXX.h files: Wine/obj_base.h - there are a lot of
685 defines's that are used to declare a COM interfaces
686
687 #define ICOM_METHOD(ret,xfn) \
688      public: virtual ret (CALLBACK xfn)(void) = 0;
689
690 will be (for all of them that are related to C++ (watch #ifdef's
691 carefully)):
692
693 #define ICOM_METHOD(ret,xfn) \
694      public: virtual ret CALLBACK (xfn)(void) = 0;
695
696 and the second tip is an error when compiler stops on line like:
697  
698    ICOM_DEFINE(ISomeInterfase,IUnknown)
699
700 watch method declarations above to find something like:
701
702 ICOM_METHOD1(TYPE*,MethodName, DWORD,dwParam)
703
704 and replace TYPE* with proper TYPEPtr type. In many cases You will see
705 void* which can be replaced simply by LPVOID.
706
707 qthere are several errors related to anonymous structs and unions but
708 they can be avoided with proper - #ifdef __cplusplus
709
710 This is all about Wine headers I think. If you find something that I
711 miss type a line of mail to me.
712
713 2. MFC
714 The rules are the same with some new issues:
715
716 virtual BOOL Method1(int param1, BOOL (CALLBACK *param2)
717 (HWND,UINT,WPARAM,LPARAM));
718
719 don't compile. I remove a function pointer declaration
720 outside method:
721
722 typedef BOOL CALLBACK
723 (*param2Type)(HWND,UINT,WPARAM,LPARAM);
724
725 virtual BOOL Method1(int param1, param2Type param2);
726
727 I didn't apply this technique to a operator new
728 definitions:
729
730         void* AFXAPI operator new(size_t nSize);
731
732 so i remove AFXAPI from these declarations:
733
734 I got some missed #defines from commctrl.h and I added
735 them form VC6.0 include.
736
737 these are my defines form Makefile which I used to
738 compile MFC
739
740 -DTWINE_NO_CMONIKER \ -- this is related to exclude
741 CMonikerFile 
742 -D__urlmon_h__ \ -- Wine didn't have URL interfaces 
743 -D_AFX_NO_OLEDB_SUPPORT \
744 -D_WIN32  \
745 -DNOWIN98  \ -- this is used to exclude all
746 unimplemented classes from commctrl 
747 -D_AFX_PACKING \
748 -D_AFX_NO_DHTML_SUPPORT \
749 -D_AFX_NO_SOCKET_SUPPORT \
750 -D_AFX_NO_SYNC_SUPPORT \
751 -D_AFX_NO_OCX_SUPPORT  \
752 -D_AFX_PORTABLE \
753 -D_AFX_OLD_EXCEPTIONS \
754 -D_AFX_NO_SOCKET_SUPPORT \
755 -D_AFX_NO_DEBUG_CRT \
756 -D_AFX_NO_DAO_SUPPORT \
757 -D_AFX_NO_OCC_SUPPORT \
758 -D_AFX_NO_INET_SUPPORT \
759 -D_AFX_NO_RICHEDIT_SUPPORT  \
760 -D_X86_ \
761 -DLONGHANDLES
762
763 may be you will try to enable some of features of mfc I tested only
764 -D_AFX_NO_OCC_SUPPORT but got missing interfaces from Wine
765
766 in file afxcom_.h
767 - _CIP<_Interface, _IID>::~_CIP<_Interface, _IID>()
768 + _CIP<_Interface, _IID>::~_CIP()
769
770 in file afxtempl.h
771 -       BOOL Lookup(BASE_CLASS::BASE_ARG_KEY key,
772 VALUE& rValue) const
773 -               { return BASE_CLASS::Lookup(key,
774 (BASE_CLASS::BASE_VALUE&)rValue); }
775 +       BOOL Lookup(typename BASE_CLASS::BASE_ARG_KEY
776 key, VALUE& rValue) const
777 +               { return BASE_CLASS::Lookup(key,
778 (typename BASE_CLASS::BASE_VALUE&)rValue); }
779
780 and all releated errors can be fixed in this way.
781
782 3. spec file
783     name        mfc42
784     type        win32
785     rsrc        mfc42
786
787     10 stdcall WinMain(long long ptr long) WinMain
788
789 4. linking 
790     use -rdynamic wnen link libmfc.so to get ARGV and
791 ARGC from loader
792     
793 5. I didn'n build a extension dll with Wine but I suspect that there
794 will be some problems related to a chaining Runtime classes form MFC
795 to a new dll
796
797 6. build your app as a MODULE too.
798
799 7. make a loader and in it's _WinMain:
800 ... includes are here
801 iint PASCAL (*winMain)(HINSTANCE,HINSTANCE,LPSTR,int) =
802 0;
803 my app uses these to manage filenames
804 VOID __cdecl (*_splitpath1)(LPCSTR path, LPSTR drive,
805 LPSTR directory, LPSTR filename, LPSTR extension ) =
806 NULL;
807 VOID __cdecl _splitpath(LPCSTR path, LPSTR drive,
808 LPSTR directory, LPSTR filename, LPSTR extension )
809 {
810     if (_splitpath1)
811         _splitpath1(path, drive, directory, filename,
812 extension );
813 }
814 VOID __cdecl (*_makepath1)(LPSTR path, LPCSTR drive,
815 LPCSTR directory, LPCSTR filename, LPCSTR extension )
816 = NULL;
817 VOID __cdecl _makepath(LPSTR path, LPCSTR drive,
818 LPCSTR directory, LPCSTR filename, LPCSTR extension )
819 {
820     if (_makepath1)
821         _makepath1(path, drive, directory, filename,
822 extension);
823 }
824 int PASCAL _WinMain(HINSTANCE h,HINSTANCE h1,LPSTR
825 lpszCmdParam,int c)
826 {
827   HINSTANCE hInstance,hins,hlib,htst,hform,himag,hexe;
828         int retv;
829
830         hins = LoadLibrary("CRTDLL.DLL");
831         _splitpath1 = GetProcAddress(hins,
832 "_splitpath");
833         _makepath1 = GetProcAddress(hins,
834 "_makepath");
835         hins = LoadLibrary("COMCTL32.DLL");
836         hins = LoadLibrary("COMDLG32.DLL");
837
838
839         hins = dlopen("libmfc42.so",2);
840         hlib = LoadLibrary("mfc42");
841         himag = dlopen("libmxformatslib.so",2);
842         hform = LoadLibrary("mxformatslib");
843         hexe = dlopen("libmxpaint.so",2);
844         htst = LoadLibrary("mxpaint");
845
846         winMain = GetProcAddress(hlib, "WinMain");
847         if (winMain)
848         {
849           retv = winMain (htst,    // note the > htst
850 < HERE
851                   0,            
852                   lpszCmdParam, 
853                   SW_NORMAL);   
854         }
855     FreeLibrary(htst);
856     FreeLibrary(hform);
857     FreeLibrary(hlib);
858     dlclose(hexe);
859     dlclose(himag);
860     dlclose(hins);
861     return retv;
862 }
863 the spec for loader is:
864 name    c10
865 mode    guiexe
866 type    win32
867 init    _WinMain
868
869 please find attached a Makefile which i use to build
870 MFC
871
872 Regards 
873 Damyan.