Commit | Line | Data |
---|---|---|
692389d0 DR |
1 | This document should help new developers get started. Like all of Wine, it |
2 | is a work in progress. | |
dba420a7 | 3 | |
0a7aa169 | 4 | |
889f7424 AJ |
5 | SOURCE TREE STRUCTURE |
6 | ===================== | |
7 | ||
692389d0 DR |
8 | The Wine source tree is loosely based on the original Windows modules. |
9 | Most of the source is concerned with implementing the Wine API, although | |
10 | there are also various tools, documentation, sample Winelib code, and | |
11 | code specific to the binary loader. | |
889f7424 | 12 | |
692389d0 DR |
13 | Wine API directories: |
14 | --------------------- | |
889f7424 AJ |
15 | |
16 | KERNEL: | |
17 | ||
18 | files/ - file I/O | |
19 | loader/ - Win16-, Win32-binary loader | |
20 | memory/ - memory management | |
692389d0 | 21 | msdos/ - DOS features and BIOS calls (interrupts) |
889f7424 AJ |
22 | scheduler/ - process and thread management |
23 | ||
24 | GDI: | |
25 | ||
26 | graphics/ - graphics drivers | |
0a7aa169 KG |
27 | x11drv/ - X11 display driver |
28 | win16drv/ -> see below | |
29 | ttydrv/ - tty display driver | |
30 | psdrv/ - PostScript graphics driver | |
19dc2087 | 31 | metafiledrv/ - metafile driver |
0a7aa169 | 32 | enhmetafiledrv/ - enhanced metafile driver |
889f7424 AJ |
33 | objects/ - logical objects |
34 | ||
35 | USER: | |
36 | ||
37 | controls/ - built-in widgets | |
0a7aa169 | 38 | resources/ - built-in menu and message box resources |
889f7424 AJ |
39 | windows/ - window management |
40 | ||
692389d0 DR |
41 | Other DLLs: |
42 | ||
0a7aa169 KG |
43 | dlls/ - Other system DLLs implemented by Wine |
44 | advapi32/ - crypto, systeminfo, security, eventlogging | |
45 | avifil32/ - COM object to play AVI files | |
46 | comctl32/ - common controls | |
47 | commdlg/ - common dialog boxes (both 16 & 32 bit) | |
1db20bfd | 48 | crtdll/ - Old C runtime library |
19dc2087 EP |
49 | dplayx/ - DirectX dplayx |
50 | dsound/ - DirectX dsound | |
0a7aa169 | 51 | imagehlp/ - PE (Portable Executable) Image Helper lib |
19dc2087 EP |
52 | imm32/ |
53 | lzexpand/ - Liv-Zempel compression/decompression | |
54 | mpr/ - Multi-Protocol Router (interface to various | |
55 | network transport protocols) | |
56 | msacm/ - audio compression manager (multimedia) (16 bit) | |
57 | msacm32/ - audio compression manager (multimedia) (32 bit) | |
58 | msnet/ | |
1db20bfd | 59 | msvcrt/ - C runtime library |
19dc2087 | 60 | msvideo/ - 16 bit video manager |
7bed696a | 61 | ole32/ - 32 bit OLE 2.0 libraries |
19dc2087 EP |
62 | oleaut32/ - 32 bit OLE 2.0 automation |
63 | olecli/ - 16 bit OLE client | |
64 | oledlg/ - OLE 2.0 user interface support | |
65 | olesvr/ - 16 bit OLE server | |
0a7aa169 KG |
66 | ntdll/ - NT implementation of kernel calls |
67 | psapi/ - process status API | |
68 | rasapi32/ - remote access server API | |
69 | shell32/ - COM object implementing shell views | |
19dc2087 | 70 | sound/ - Sound on loudspeaker (not sound card) |
0a7aa169 KG |
71 | tapi32/ - telephone API |
72 | ver/ - File Installation Library (16 bit) | |
73 | version/ - File Installation Library (32 bit) | |
19dc2087 EP |
74 | win32s |
75 | win87em - 80387 math-emulation | |
76 | winaspi/ - 16 bit Advanced SCSI Peripheral Interface | |
77 | windebug/ - Windows debugger | |
78 | wing/ - WinG (for games) internface | |
79 | winmm/ - multimedia (16 & 32 bit) | |
80 | mciXXX/ - various MCI drivers | |
81 | wineoss/- MM driver for OSS systems | |
82 | wavemap/- audio mapper | |
83 | midimap/- midi mapper | |
0a7aa169 | 84 | winspool/ - Printing & Print Spooler |
19dc2087 | 85 | wnaspi32/ - 32 bit ASPI |
692389d0 | 86 | |
889f7424 AJ |
87 | Miscellaneous: |
88 | ||
692389d0 | 89 | misc/ - shell, registry, winsock, etc. |
692389d0 | 90 | ipc/ - SysV IPC based interprocess communication |
889f7424 | 91 | win32/ - misc Win32 functions |
0a7aa169 KG |
92 | ole/ - OLE code |
93 | nls/ - National Language Support | |
94 | configuration files | |
889f7424 AJ |
95 | |
96 | Tools: | |
692389d0 | 97 | ------ |
889f7424 | 98 | |
692389d0 | 99 | rc/ - old resource compiler |
0a7aa169 KG |
100 | tools/ - relay code builder, new rc, bugreport |
101 | generator, wineconfigurator, etc. | |
889f7424 AJ |
102 | documentation/ - some documentation |
103 | ||
104 | ||
692389d0 DR |
105 | Binary loader specific directories: |
106 | ----------------------------------- | |
889f7424 AJ |
107 | |
108 | debugger/ - built-in debugger | |
109 | if1632/ - relay code | |
110 | miscemu/ - hardware instruction emulation | |
111 | graphics/win16drv/ - Win16 printer driver | |
0a7aa169 KG |
112 | server/ - the main, controlling thread of wine |
113 | tsx11/ - thread-safe X11 wrappers (auto generated) | |
889f7424 | 114 | |
692389d0 | 115 | Winelib specific directories: |
889f7424 AJ |
116 | ----------------------------- |
117 | ||
692389d0 DR |
118 | library/ - Required code for programs using Winelib |
119 | libtest/ - Small samples and tests | |
120 | programs/ - Extended samples / system utilities | |
889f7424 | 121 | |
0a7aa169 | 122 | |
c7c217b3 AJ |
123 | IMPLEMENTING NEW API CALLS |
124 | ========================== | |
125 | ||
126 | This is the simple version, and covers only Win32. Win16 is slightly uglier, | |
127 | because of the Pascal heritage and the segmented memory model. | |
128 | ||
129 | All of the Win32 APIs known to Wine are listed in [relay32/*.spec]. An | |
130 | unimplemented call will look like (from gdi32.spec) | |
131 | 269 stub PolyBezierTo | |
132 | To implement this call, you need to do the following four things. | |
133 | ||
134 | 1. Find the appropriate parameters for the call, and add a prototype to | |
0a7aa169 KG |
135 | the correct header file. In this case, that means [include/wingdi.h], |
136 | and it might look like | |
9f69d893 AJ |
137 | BOOL WINAPI PolyBezierTo(HDC, LPCVOID, DWORD); |
138 | If the function has both an ASCII and a Unicode version, you need to | |
139 | define both and add a #define WINELIB_NAME_AW declaration. See below | |
140 | for discussion of function naming conventions. | |
c7c217b3 AJ |
141 | |
142 | 2. Modify the .spec file to tell Wine that the function has an | |
143 | implementation, what the parameters look like and what Wine function | |
144 | to use for the implementation. In Win32, things are simple--everything | |
145 | is 32-bits. However, the relay code handles pointers and pointers to | |
146 | strings slightly differently, so you should use 'str' and 'wstr' for | |
147 | strings, 'ptr' for other pointer types, and 'long' for everything else. | |
9f69d893 AJ |
148 | 269 stdcall PolyBezierTo(long ptr long) PolyBezierTo |
149 | The 'PolyBezierTo' at the end of the line is which Wine function to use | |
c7c217b3 AJ |
150 | for the implementation. |
151 | ||
152 | 3. Implement the function as a stub. Once you add the function to the .spec | |
153 | file, you must add the function to the Wine source before it will link. | |
9f69d893 | 154 | Add a function called 'PolyBezierTo' somewhere. Good things to put |
c7c217b3 AJ |
155 | into a stub: |
156 | o a correct prototype, including the WINAPI | |
157 | o header comments, including full documentation for the function and | |
0a7aa169 | 158 | arguments (see documentation/README.documentation) |
c7c217b3 AJ |
159 | o A FIXME message and an appropriate return value are good things to |
160 | put in a stub. | |
161 | ||
162 | /************************************************************ | |
0a7aa169 KG |
163 | * PolyBezierTo (GDI32.269) |
164 | * | |
165 | * Draw many Bezier curves | |
166 | * | |
167 | * RETURNS | |
168 | * nonzero on success or zero on faillure | |
c7c217b3 AJ |
169 | * |
170 | * BUGS | |
171 | * Unimplemented | |
172 | */ | |
0a7aa169 KG |
173 | BOOL WINAPI PolyBezierTo(HDC hdc, /* handle to device context */ |
174 | LPCVOID p, /* ptr to array of Point structs */ | |
175 | DWORD count /* nr of points in array */ | |
176 | ) | |
177 | { | |
178 | /* tell the user they've got a substandard implementation */ | |
c7c217b3 | 179 | FIXME(gdi, ":(%x,%p,%d): stub\n", hdc, p, count); |
0a7aa169 KG |
180 | |
181 | /* some programs may be able to compensate, | |
182 | * if they know what happened | |
183 | */ | |
c7c217b3 AJ |
184 | SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
185 | return FALSE; /* error value */ | |
186 | } | |
187 | ||
0a7aa169 KG |
188 | 4. Implement and test the rest of the function. |
189 | ||
889f7424 | 190 | |
19dc2087 EP |
191 | IMPLEMENTING A NEW DLL |
192 | ====================== | |
193 | ||
31b41cf6 EP |
194 | Generic directions |
195 | ------------------ | |
196 | ||
19dc2087 EP |
197 | Apart from writing the set of needed .c files, you also need to do the |
198 | following: | |
199 | ||
200 | 1. Create a directory <MyDll> where to store the implementation of | |
201 | the DLL. | |
202 | ||
203 | If the DLL exists under Windows as both 16 and 32 bit DLL, you can | |
204 | either create one directory for each, or have a single directory | |
205 | with both implementations. | |
206 | ||
207 | This (those) directory(ies) have to be put under the dlls/ | |
208 | directory in Wine tree structure. | |
209 | ||
210 | 2. Create the Makefile.in in the ./dlls/<MyDll>/ directory. You can | |
211 | copy an existing Makefile.in from another ./dlls/ subdirectory. | |
212 | ||
213 | You need at least to change the MODULE, SPEC_SRCS, and C_SRCS | |
214 | macros. | |
215 | ||
216 | 3. Add the directory (and the generated .o file for the module) in: | |
217 | + ./configure.in (in AC_OUTPUT macro at the end of the file to | |
218 | trigger the Makefile generation), | |
219 | + ./Makefile.in (in LIBSUBDIRS and LIBOBJS macros) | |
31b41cf6 | 220 | + ./dlls/Makefile.in (in SUBDIRS macro) |
19dc2087 EP |
221 | |
222 | 4. You can now regenerate ./configure file (with 'make configure') | |
223 | and the various Makefiles (with 'configure; make depend') (run | |
224 | from the top of Wine's tree). | |
225 | ||
226 | You shall now have a Makefile file in ./dlls/<MyDll>/ | |
227 | ||
228 | 5. You now need to declare the DLL in the module lists. This is done | |
229 | by adding the corresponding descriptor in ./if1632/builtin.c if | |
230 | your DLL is 16 bit (resp. ./relay32/builtin.c for a 32 bit DLL) | |
231 | (or both if your directory contains the dual 16/32 | |
232 | implementations). | |
233 | ||
234 | Note: the name of the descriptor is based on the module name, not | |
235 | on the file name (they are the same in most of the case, but for | |
236 | some DLLs it's not the case). | |
237 | ||
238 | 6. You also need to define the loadorder for the created DLL | |
31b41cf6 | 239 | (./wine.ini and ./loader/loadorder.c). Usually, "native,builtin" |
19dc2087 EP |
240 | is ok. If you have written a paired 16/32 bit implementation, don't |
241 | forget to define it also in those files. | |
242 | ||
243 | 7. Create the .spec file for the DLL export points in your | |
244 | directory. Refer to 'Implementation of new API calls' earlier in | |
245 | this document for more information on this part. | |
246 | ||
31b41cf6 EP |
247 | 8. Don't forget the .cvsignore file. The .cvsignore contain (on a per |
248 | directory basis) all the files generated by the compilation | |
249 | process, why cvs shall ignore when processing the dir. | |
250 | *.o is in there by default, but in Wine case you will find: | |
251 | - Makefile (generated from Makefile.in) | |
252 | - *.spec.c: those c files are generated by tools/build from the | |
253 | .spec file | |
254 | - when thunking down to 16 bit DLLs, you'll get some others (.glue.c) | |
255 | - result of .y => .c translation (by yacc or bison) | |
256 | - result of .rc compilation | |
257 | - ... | |
258 | For a simple DLL, listing in .cvsignore Makefile and | |
259 | <MyDll>.spec.c will do. | |
19dc2087 EP |
260 | |
261 | 9. You can now start adding .c files. | |
262 | ||
263 | 10. For the .h files, if they are standard Windows one, put them in | |
264 | include/. If they are linked to *your* implementation of the DLL, | |
265 | put them in your newly created directory. | |
266 | ||
31b41cf6 EP |
267 | Debug channels |
268 | -------------- | |
269 | ||
19dc2087 EP |
270 | If you need to create a new debug channel, just add the |
271 | DECLARE_DEBUG_CHANNEL to your .c file(s) and rerun | |
272 | tools/make_debug. When sending out your patch, you don't need to | |
7bed696a | 273 | provide neither ./configure nor the ./include/debugdefs.h diffs. Just |
19dc2087 EP |
274 | indicate that those files need to be regenerated. |
275 | ||
31b41cf6 EP |
276 | Resources |
277 | --------- | |
278 | ||
279 | If you also need to add resources to your DLL, the create the .rc | |
280 | file. Since, the .rc file will be translated into a .s file, and then | |
281 | compiled as a .o file, its basename must be different from the | |
282 | basename of any .c file. | |
283 | Add to your ./dlls/<MyDll>/Makefile.in, in the RC_SRCS macro, the list | |
284 | of .rc files to add to the DLL. You may also have to add the following | |
285 | directives | |
286 | 1/ to tell gnumake to translate .rc into .s files, | |
287 | $(RC_SRCS:.rc=.s): $(WRC) | |
288 | 2/ to give some parameters to wrc for helping the translation. | |
289 | WRCEXTRA = -s -p$(MODULE) | |
290 | ||
291 | See dlls/comctl32/ for an example of this. | |
292 | ||
293 | Thunking | |
294 | -------- | |
295 | ||
296 | If you're building a 16 & 32 bit DLLs pair, then from the 32 bit code | |
297 | you might need to call 16 bit routine. The way to do it to add in the | |
298 | code, fragments like: | |
299 | /* ### Start build ### */ | |
300 | extern WORD CALLBACK <PREFIX>_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG); | |
301 | /* ### stop build ### */ | |
302 | Where <PREFIX>_ is an internal prefix for your module. The first | |
303 | parameter is always of type FARPROC16. Then, you can get the regular | |
304 | list of parameters. The _word_wwlll indicates the type of return (long | |
305 | or word) and the size of the parameters (here l=>long, w=>word; which | |
306 | maps to WORD,WORD,LONG,LONG,LONG. | |
307 | You can put several functions between the Start/Stop build pair. | |
308 | ||
309 | You can also read tools/build.txt for more details on this. | |
310 | ||
311 | Then, add to ./dlls/<MyDll>/Makefile.in to the macro GLUE the list of | |
312 | .c files containing the /* ### Start build ### */ directives. | |
313 | ||
314 | See dlls/winmm/ for an example of this. | |
315 | ||
1285c2f9 AJ |
316 | MEMORY AND SEGMENTS |
317 | =================== | |
dba420a7 AJ |
318 | |
319 | NE (Win16) executables consist of multiple segments. The Wine loader | |
e2abbb1b AJ |
320 | loads each segment into a unique location in the Wine processes memory |
321 | and assigns a selector to that segment. Because of this, it's not | |
322 | possible to exchange addresses freely between 16-bit and 32-bit code. | |
323 | Addresses used by 16-bit code are segmented addresses (16:16), formed | |
324 | by a 16-bit selector and a 16-bit offset. Those used by the Wine code | |
325 | are regular 32-bit linear addresses. | |
dba420a7 | 326 | |
1e37a181 AJ |
327 | There are four ways to obtain a segmented pointer: |
328 | - Use the SEGPTR_* macros in include/heap.h (recommended). | |
e2abbb1b AJ |
329 | - Allocate a block of memory from the global heap and use |
330 | WIN16_GlobalLock to get its segmented address. | |
331 | - Allocate a block of memory from a local heap, and build the | |
332 | segmented address from the local heap selector (see the | |
333 | USER_HEAP_* macros for an example of this). | |
334 | - Declare the argument as 'segptr' instead of 'ptr' in the spec file | |
335 | for a given API function. | |
dba420a7 | 336 | |
e2abbb1b AJ |
337 | Once you have a segmented pointer, it must be converted to a linear |
338 | pointer before you can use it from 32-bit code. This can be done with | |
339 | the PTR_SEG_TO_LIN() and PTR_SEG_OFF_TO_LIN() macros. The linear | |
340 | pointer can then be used freely with standard Unix functions like | |
341 | memcpy() etc. without worrying about 64k boundaries. Note: there's no | |
342 | easy way to convert back from a linear to a segmented address. | |
dba420a7 | 343 | |
e2abbb1b AJ |
344 | In most cases, you don't need to worry about segmented address, as the |
345 | conversion is made automatically by the callback code and the API | |
346 | functions only see linear addresses. However, in some cases it is | |
347 | necessary to manipulate segmented addresses; the most frequent cases | |
348 | are: | |
349 | - API functions that return a pointer | |
350 | - lParam of Windows messages that point to a structure | |
351 | - Pointers contained inside structures accessed by 16-bit code. | |
dba420a7 | 352 | |
e2abbb1b AJ |
353 | It is usually a good practice to used the type 'SEGPTR' for segmented |
354 | pointers, instead of something like 'LPSTR' or 'char *'. As SEGPTR is | |
355 | defined as a DWORD, you'll get a compilation warning if you mistakenly | |
356 | use it as a regular 32-bit pointer. | |
dba420a7 | 357 | |
1285c2f9 | 358 | |
2d93d000 AJ |
359 | STRUCTURE PACKING |
360 | ================= | |
361 | ||
362 | Under Windows, data structures are tightly packed, i.e. there is no | |
363 | padding between structure members. On the other hand, by default gcc | |
364 | aligns structure members (e.g. WORDs are on a WORD boundary, etc.). | |
365 | This means that a structure like | |
366 | ||
367 | struct { BYTE x; WORD y; }; | |
368 | ||
369 | will take 3 bytes under Windows, but 4 with gcc, because gcc will add a | |
370 | dummy byte between x and y. To have the correct layout for structures | |
0a7aa169 KG |
371 | used by Windows code, you need to embed the struct within two special |
372 | #include's which will take care of the packing for you: | |
373 | ||
374 | #include "pshpack1.h" | |
19dc2087 | 375 | struct { BYTE x; WORD y; }; |
0a7aa169 KG |
376 | #include "poppack1.h" |
377 | ||
378 | For alignment on a 2-byte boundary, there is a "pshpack2.h", etc. | |
379 | ||
380 | The use of the WINE_PACKED attribute is obsolete. Please remove these | |
381 | in favour of the above solution. | |
382 | Using WINE_PACKED, you would declare the above structure like this: | |
2d93d000 AJ |
383 | |
384 | struct { BYTE x; WORD y WINE_PACKED; }; | |
385 | ||
0a7aa169 | 386 | You had to do this every time a structure member is not aligned |
2d93d000 | 387 | correctly under Windows (i.e. a WORD not on an even address, or a |
0a7aa169 | 388 | DWORD on a address that was not a multiple of 4). |
2d93d000 AJ |
389 | |
390 | ||
1285c2f9 AJ |
391 | NAMING CONVENTIONS FOR API FUNCTIONS AND TYPES |
392 | ============================================== | |
393 | ||
394 | In order to support both Win16 and Win32 APIs within the same source | |
692389d0 | 395 | code, the following convention must be used in naming all API |
1285c2f9 AJ |
396 | functions and types. If the Windows API uses the name 'xxx', the Wine |
397 | code must use: | |
398 | ||
9f69d893 AJ |
399 | - 'xxx16' for the Win16 version, |
400 | - 'xxx' for the Win32 version when no ASCII/Unicode strings are | |
1285c2f9 | 401 | involved, |
9f69d893 AJ |
402 | - 'xxxA' for the Win32 version with ASCII strings, |
403 | - 'xxxW' for the Win32 version with Unicode strings. | |
1285c2f9 | 404 | |
9f69d893 AJ |
405 | If the function has both ASCII and Unicode version, you should then |
406 | use the macros WINELIB_NAME_AW(xxx) or DECL_WINELIB_TYPE_AW(xxx) | |
0768424b | 407 | (defined in include/windef.h) to define the correct 'xxx' function |
9f69d893 AJ |
408 | or type for Winelib. When compiling Wine itself, 'xxx' is _not_ |
409 | defined, meaning that code inside of Wine must always specify | |
410 | explicitly the ASCII or Unicode version. | |
1285c2f9 | 411 | |
9f69d893 AJ |
412 | If 'xxx' is the same in Win16 and Win32, you can simply use the same |
413 | name as Windows, i.e. just 'xxx'. If 'xxx' is Win16 only, you could | |
414 | use the name as is, but it's preferable to use 'xxx16' to make it | |
415 | clear it is a Win16 function. | |
1285c2f9 AJ |
416 | |
417 | Examples: | |
418 | ||
9f69d893 AJ |
419 | typedef struct { /* Win32 ASCII data structure */ } WNDCLASSA; |
420 | typedef struct { /* Win32 Unicode data structure */ } WNDCLASSW; | |
1285c2f9 AJ |
421 | typedef struct { /* Win16 data structure */ } WNDCLASS16; |
422 | DECL_WINELIB_TYPE_AW(WNDCLASS); | |
423 | ||
424 | ATOM RegisterClass16( WNDCLASS16 * ); | |
9f69d893 AJ |
425 | ATOM RegisterClassA( WNDCLASSA * ); |
426 | ATOM RegisterClassW( WNDCLASSW * ); | |
1285c2f9 AJ |
427 | #define RegisterClass WINELIB_NAME_AW(RegisterClass) |
428 | ||
429 | The Winelib user can then say: | |
430 | ||
1285c2f9 AJ |
431 | WNDCLASS wc = { ... }; |
432 | RegisterClass( &wc ); | |
433 | ||
434 | and this will use the correct declaration depending on the definition | |
9f69d893 | 435 | of the UNICODE symbol. |
1285c2f9 AJ |
436 | |
437 | ||
0a7aa169 KG |
438 | NAMING CONVENTIONS FOR NON-API FUNCTIONS AND TYPES |
439 | ================================================== | |
440 | ||
441 | Functions and data which are internal to your code (or at least shouldn't be | |
e550ebe4 | 442 | visible to any Winelib or Windows program) should be preceded by |
0a7aa169 KG |
443 | an identifier to the module: |
444 | ||
445 | Examples: | |
446 | ||
447 | ENUMPRINTERS_GetDWORDFromRegistryA() (in dlls/winspool/info.c) | |
448 | IAVIFile_fnRelease() (in dlls/avifil32/avifile.c) | |
449 | X11DRV_CreateDC() (in graphics/x11drv/init.c) | |
450 | TIMER_Init() (implemented in windows/timer.c, | |
451 | used in loader/main.c ) | |
452 | ||
453 | if you need prototypes for these, there are a few possibilities: | |
454 | - within same source file only: | |
455 | put the prototypes at the top of your file and mark them as prototypes. | |
456 | - within the same module: | |
457 | create a header file within the subdirectory where that module resides, | |
458 | e.g. graphics/ddraw_private.h | |
459 | - from a totally different module, or for use in winelib: | |
460 | put your header file entry in /include/wine/ | |
461 | but be careful not to clutter this directory! | |
462 | under no circumstances, you should add non-api calls to the standard | |
463 | windoze include files. Unfortunately, this is often the case, e.g. | |
464 | the above example of TIMER_Init is defined in include/message.h | |
465 | ||
466 | ||
1285c2f9 AJ |
467 | API ENTRY POINTS |
468 | ================ | |
dba420a7 AJ |
469 | |
470 | Because Win16 programs use a 16-bit stack and because they can only | |
471 | call 16:16 addressed functions, all API entry points must be at low | |
472 | address offsets and must have the arguments translated and moved to | |
473 | Wines 32-bit stack. This task is handled by the code in the "if1632" | |
474 | directory. To define a new API entry point handler you must place a | |
475 | new entry in the appropriate API specification file. These files are | |
ca22b33d AJ |
476 | named *.spec. For example, the API specification file for the USER |
477 | DLL is contained in the file user.spec. These entries are processed | |
478 | by the "build" program to create an assembly file containing the entry | |
479 | point code for each API call. The format of the *.spec files is | |
8d24ae6d AJ |
480 | documented in the file "tools/build-spec.txt". |
481 | ||
1285c2f9 AJ |
482 | |
483 | DEBUG MESSAGES | |
484 | ============== | |
aca05783 AJ |
485 | |
486 | To display a message only during debugging, you normally write something | |
487 | like this: | |
488 | ||
54c2711f AJ |
489 | TRACE(win,"abc..."); or |
490 | FIXME(win,"abc..."); or | |
491 | WARN(win,"abc..."); or | |
492 | ERR(win,"abc..."); | |
493 | ||
494 | depending on the seriousness of the problem. (documentation/degug-msgs | |
495 | explains when it is appropriate to use each of them) | |
496 | ||
497 | These macros are defined in include/debug.h. The macro-definitions are | |
498 | generated by the shell-script tools/make_debug. It scans the source | |
499 | code for symbols of this forms and puts the necessary macro | |
500 | definitions in include/debug.h and include/debugdefs.h. These macros | |
501 | test whether the debugging "channel" associated with the first | |
502 | argument of these macros (win in the above example) is enabled and | |
503 | thus decide whether to actually display the text. In addition you can | |
504 | change the types of displayed messages by supplying the "-debugmsg" | |
505 | option to Wine. If your debugging code is more complex than just | |
506 | printf, you can use the symbols TRACE_ON(xxx), WARN_ON(xxx), | |
507 | ERR_ON(xxx) and FIXME_ON(xxx) as well. These are true when channel xxx | |
508 | is enabled, either permanent or in the command line. Thus, you can | |
509 | write: | |
510 | ||
511 | if(TRACE_ON(win))DumpSomeStructure(&str); | |
512 | ||
234bc24d | 513 | Don't worry about the inefficiency of the test. If it is permanently |
54c2711f | 514 | disabled (that is TRACE_ON(win) is 0 at compile time), the compiler will |
234bc24d | 515 | eliminate the dead code. |
aca05783 | 516 | |
aca05783 | 517 | You have to start tools/make_debug only if you introduced a new macro, |
54c2711f AJ |
518 | e.g. TRACE(win32). |
519 | ||
520 | For more info about debugging messages, read: | |
521 | ||
522 | documentation/debug-msgs | |
523 | ||
23946ad2 AJ |
524 | |
525 | MORE INFO | |
526 | ========= | |
527 | ||
33072e1f AJ |
528 | 1. There is a FREE online version of the MSDN library (including |
529 | documentation for the Win32 API) on http://www.microsoft.com/msdn/ | |
23946ad2 | 530 | |
33072e1f | 531 | 2. http://www.sonic.net/~undoc/bookstore.html |
23946ad2 | 532 | |
33072e1f AJ |
533 | 3. In 1993 Dr. Dobbs Journal published a column called "Undocumented Corner". |
534 | ||
535 | 4. You might want to check out BYTE from December 1983 as well :-) | |
23946ad2 | 536 |