diff --git a/documentation/implementation.sgml b/documentation/implementation.sgml index 260a9259af2..c2f7efc900d 100644 --- a/documentation/implementation.sgml +++ b/documentation/implementation.sgml @@ -2,151 +2,34 @@ Low-level Implementation Details of Wine's Low-level Implementation... - - Builtin DLLs - - - Written by &name-juergen-schmied; &email-juergen-schmied; - - - (Extracted from wine/documentation/internal-dll) - - - - This document describes some points you should know before - implementing the internal counterparts to external DLL's. - Only 32 bit DLL's are considered. - - - - 1. The LibMain function - - - This is the way to do some initializing when a process or - thread is attached to the DLL. The function name is taken - from a *.spec file line: - - -init YourFunctionName - - - Then, you have to implement the function: - - -BOOL32 WINAPI YourLibMain(HINSTANCE32 hinstDLL, - DWORD fdwReason, LPVOID lpvReserved) -{ if (fdwReason==DLL_PROCESS_ATTACH) - { ... - } - .... -} - - - - - 2. Using functions from other built-in DLL's - - - The problem here is, that you can't know if you have to call - the function from the internal or the external DLL. If you - just call the function you will get the internal - implementation. If the external DLL is loaded the executed - program will use the external DLL and you the internal one. - When you -as an example- fill an iconlist placed in the - internal DLL the application won't get the icons from the - external DLL. - - - To work around this, you should always use a pointer to call - such functions: - - -/* definition of the pointer type*/ -void (CALLBACK* pDLLInitComctl)(); - -/* getting the function address this should be done in the - LibMain function when called with DLL_PROCESS_ATTACH*/ - -BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, - LPVOID lpvReserved) -{ HINSTANCE32 hComctl32; - if (fdwReason==DLL_PROCESS_ATTACH) - { /* load the external / internal DLL*/ - hComctl32 = LoadLibrary32A("COMCTL32.DLL"); - if (hComctl32) - { /* get the function pointer */ - pDLLInitComctl=GetProcAddress32(hComctl32,"InitCommonControlsEx"); - - /* check it */ - if (pDLLInitComctl) - { /* use it */ - pDLLInitComctl(); - } - - /* free the DLL / decrease the ref count */ - FreeLibrary32(hComctl32); - } - else - { /* do some panic*/ - ERR(shell,"P A N I C error getting functionpointers\n"); - exit (1); - } - } - .... - - - - - 3. Getting resources from a <filename>*.rc</filename> file linked to the DLL - - - < If you know how, write some lines> - - - - Accelerators - - Findings researched by Uwe Bonnes, Ulrich Weigand and Marcus Meissner. - - - (Extracted from wine/documentation/accelerators) - - - - Some notes concerning accelerators. - There are three differently sized - accelerator structures exposed to the user. The general layout - is: + accelerator structures exposed to the user: - -BYTE fVirt; -WORD key; -WORD cmd; - - - We now have three different appearances: - - - Accelerators in NE resources. These have a size of 5 byte - and do not have any padding. This is also the internal + Accelerators in NE resources. This is also the internal layout of the global handle HACCEL (16 and 32) in Windows 95 and Wine. Exposed to the user as Win16 global handles HACCEL16 and HACCEL32 by the Win16/Win32 API. + These are 5 bytes long, with no padding: + +BYTE fVirt; +WORD key; +WORD cmd; + - Accelerators in PE resources. These have a size of 8 byte. - Layout is: + Accelerators in PE resources. They are exposed to the user + only by direct accessing PE resources. + These have a size of 8 bytes: BYTE fVirt; @@ -155,15 +38,14 @@ WORD key; WORD cmd; WORD pad1; - - They are exposed to the user only by direct accessing PE - resources. - - Accelerators in the Win32 API. These have a size of 6 - bytes. Layout is: + Accelerators in the Win32 API. These are exposed to the + user by the CopyAcceleratorTable + and CreateAcceleratorTable functions + in the Win32 API. + These have a size of 6 bytes: BYTE fVirt; @@ -171,12 +53,6 @@ BYTE pad0; WORD key; WORD cmd; - - These are exposed to the user by the - CopyAcceleratorTable and - CreateAcceleratorTable functions in - the Win32 API. - @@ -191,80 +67,8 @@ WORD cmd; - - File Handles - - - Written by (???) - - - (Extracted from wine/documentation/filehandles) - - - - DOS treats the first 5 file handles as special cases. They - map directly to stdin, - stdout, stderr, - stdaux and stdprn. - Windows 16 inherits this behavior, and in fact, win16 handles - are interchangeable with DOS handles. Some nasty windows - programs even do this! - - - Windows32 issues file handles starting from - 1, on the grounds that most GUI processes - don't need a stdin, - stdout, etc. - - - The Wine handle code is implemented in the Win32 style, and - the Win16 functions use two macros to convert to and from the - two types. - - - - The macros are defined in file.h as follows: - - -#define HFILE16_TO_HFILE32(handle) \ -(((handle)==0) ? GetStdHandle(STD_INPUT_HANDLE) : \ - ((handle)==1) ? GetStdHandle(STD_OUTPUT_HANDLE) : \ - ((handle)==2) ? GetStdHandle(STD_ERROR_HANDLE) : \ - ((handle)>0x400) ? handle : \ - (handle)-5) - -#define HFILE32_TO_HFILE16(handle) ({ HFILE32 hnd=handle; \ - ((hnd==HFILE_ERROR32) ? HFILE_ERROR16 : \ - ((handle>0x400) ? handle : \ - (HFILE16)hnd+5); }) - - - - - Be careful not to use the macro - HFILE16_TO_HFILE32 on functions with - side-effects, as it will cause them to be evaluated several - times. This could be considered a bug, but the use of this - macro is limited enough not to need a rewrite. - - - - - The 0x400 special case above deals with - LZW filehandles (see misc/lzexpand.c). - - - - - Doing A Hardware Trace In Wine - - - Written by &name-jonathan-buzzard; &email-jonathan-buzzard; - - - (Extracted from wine/documentation/ioport-trace-hints) - + Doing A Hardware Trace The primary reason to do this is to reverse engineer a @@ -280,21 +84,11 @@ WORD cmd; technique of using DOSemu to produce the traces does not work as the scanners invariably only have drivers for Windows. - - Please note that I have not been able to get my scanner - working properly (a UMAX Astra 600P), but a couple of people - have reported success with at least the Artec AS6e scanner. I - am not in the process of developing any driver nor do I intend - to, so don't bug me about it. My time is now spent writing - programs to set things like battery save options under Linux - on Toshiba laptops, and as such I don't have any spare time - for writing a driver for a parallel port scanner etc. - Presuming that you have compiled and installed wine the first thing to do is is to enable direct hardware access to your - parallel port. To do this edit wine.conf - (usually in /usr/local/etc) and in the + parallel port. To do this edit config + (usually in ~/.wine/) and in the ports section add the following two lines @@ -321,22 +115,14 @@ wine -debugmsg +io XXXX 2> >(sed 's/^[^:]*:io:[^ ]* //' > YYYY) performance a really fast processor and lots of RAM. - You might well find the log compression program that David - Campbell campbell@torque.net wrote helpful in - reducing the size of the log files. This can be obtained by - the following command: - - -sh ioport-trace-hints - - - This should extract shrink.c (which is - located at the end of this file. Compile the log compression - program by: - + You will need to postprocess the output into a more manageable + format, using the shrink program. First + you need to compile the source (which is located at the end of + this section): cc shrink.c -o shrink + Use the shrink program to reduce the physical size of the raw log as follows: @@ -418,24 +204,22 @@ XXXX > YY @ ZZZZ:ZZZZ #define w_str(x,y) outb(y, x+1) #define w_ctr(x,y) outb(y, x+2) -/* - * Seems to be sending a command byte to the scanner - * - */ +/* Seems to be sending a command byte to the scanner */ int udpp_put(int udpp_base, unsigned char command) { - int loop,value; + int loop, value; - w_dtr(udpp_base, command); - w_ctr(udpp_base, 0x05); + w_dtr(udpp_base, command); + w_ctr(udpp_base, 0x05); - for (loop=0;loop<10;loop++) - if (((value=r_str(udpp_base)) & 0x80)!=0x00) { - w_ctr(udpp_base, 0x04); - return value & 0xf8; - } + for (loop=0; loop < 10; loop++) + if ((value = r_str(udpp_base)) & 0x80) + { + w_ctr(udpp_base, 0x04); + return value & 0xf8; + } - return (value & 0xf8) | 0x01; + return (value & 0xf8) | 0x01; } @@ -487,11 +271,9 @@ wait: ff - The following is the shrink.c program. - - + The following is the shrink.c program: -cat > shrink.c <<EOF +/* Copyright David Campbell <campbell@torque.net> */ #include <stdio.h> #include <string.h> @@ -521,8 +303,8 @@ main (void) } } } -EOF +