[Mono-winforms-list] Mono under Wine troubles, importing of dlls into monostub.exe.so
Vlad Kaluzhny
vkaluzhny@openlinksw.co.uk
Tue, 1 Apr 2003 17:55:27 +0700
This is a multi-part message in MIME format.
------=_NextPart_000_0287_01C2F877.E105B700
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
All.
While I have been fighting with Mono under Wine, I had the following =
error mesage:
=20
err:win:GetDesktopWindow Wine init error: either you're trying to use an =
invalid native USER.EXE config, or some graphics/GUI libraries or DLLs =
didn't initialize properly. Aborting.
I found that, the reason of this error appearance is the fact that =
USER32.DLL libary
was not initialized. The question - why is this so?
Below is the part of monostub.exe.spec.c file while I see the above =
error mesage.
----------------------------------------------------------------------
static const char dllname[] =3D "monostub.exe";
extern int __wine_spec_exports[];
#define __stdcall __attribute__((__stdcall__))
static struct {
struct {
void *OriginalFirstThunk;
unsigned int TimeDateStamp;
unsigned int ForwarderChain;
const char *Name;
void *FirstThunk;
} imp[2];
const char *data[20];
} imports =3D {
{
{ 0, 0, 0, "kernel32.dll", &imports.data[0] },
{ 0, 0, 0, 0, 0 },
},
{
/* kernel32.dll */
"\305\000CreateEventA",
"\332\000CreateSemaphoreA",
.........
-------------------------------------------------------------------------=
what does this code mean?=20
this mean that monostub.exe.so does import only kernel32.dll library.
since the user32.dll have not been imported, and therefore have not been =
initialized,
the above error message have been raised.
Below is the same part of the same file, but after some changes
------------------------------------------------------------------
static const char dllname[] =3D "monostub.exe";
extern int __wine_spec_exports[];
#define __stdcall __attribute__((__stdcall__))
static struct {
struct {
void *OriginalFirstThunk;
unsigned int TimeDateStamp;
unsigned int ForwarderChain;
const char *Name;
void *FirstThunk;
} imp[4];
const char *data[34];
} imports =3D {
{
{ 0, 0, 0, "user32.dll", &imports.data[0] },
{ 0, 0, 0, "gdi32.dll", &imports.data[12] },
{ 0, 0, 0, "kernel32.dll", &imports.data[14] },
{ 0, 0, 0, 0, 0 },
},
{
/* user32.dll */
"\145\000CreateWindowExA",
"\223\000DefWindowProcA",
..................
"\215\002UpdateWindow",
0,
/* gdi32.dll */
"\161\001GetStockObject",
0,
/* kernel32.dll */
"\305\000CreateEventA",
"\332\000CreateSemaphoreA",
.......................
}
};
---------------------------------------------------
In this case the all required libraries have been imported,
and therefore the all Dlls have been initializated (and the USER32.DLL =
too).
To inderstand the situation, I have analyzed the clock.exe program in =
wine/program directory.
its clock.exe.spec.c has all imported libraries into it the same in =
file above.
This example and analyzing of the method used to create *.spec.c file =
made me clear, that=20
in order to get all imported libraries mentioned in *.spec.c file at =
least one method from the
required dll have to be included into any source file.=20
None of monostub files had methods from USER32.DLL, only from =
KERNEL32.DLL.
Therefore I have included into build the file, which has the fake =
functions with required code.
This below code is the attempt to fix the problem. I have it solved, =
but I think that this file
can be minimized to just hold one function (let it be CreateWindowEx).
In any way this code will never be called. :-)
-------------------------------------------------------------------------=
----
#include "config.h"
#include <stdio.h>
#include "windows.h"
#include "main.h"
#include "commdlg.h"
CLOCK_GLOBALS Globals;
/***********************************************************************
*
* CLOCK_WndProc
*/
LRESULT WINAPI CLOCK_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM =
lParam)
{
PAINTSTRUCT ps;
HDC context;
switch (msg) {
case WM_CREATE: {
printf("WM_CREATE\n");
break;
}
case WM_RBUTTONUP: {
printf("WM_RBUTTONUP\n");
break;
}
case WM_PAINT: {
printf("WM_PAINT\n");
break;
}
case WM_SIZE: {
printf("WM_SIZE\n");
break;
}
case WM_COMMAND: {
break;
}
case WM_DESTROY: {
printf("WM_DESTROY\n");
PostQuitMessage (0);
break;
}
default:
return DefWindowProc (hWnd, msg, wParam, lParam);
}
return 0l;
}
/***********************************************************************
*
* WinMain
*/
int PASCAL my_mainWinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR =
cmdline, int show)
{
MSG msg;
WNDCLASS class;
char szClassName[] =3D "CLClass"; /* To make sure className >=3D =
0x10000 */
char szWinName[] =3D "Clock";
/* Setup Globals */
Globals.bAnalog =3D TRUE;
Globals.bSeconds =3D TRUE;
Globals.lpszIniFile =3D "clock.ini";
Globals.lpszIcoFile =3D "clock.ico";
Globals.hInstance =3D hInstance;
Globals.hMainIcon =3D 0;//ExtractIcon(Globals.hInstance, =
Globals.lpszIcoFile, 0);
if (!Globals.hMainIcon) Globals.hMainIcon =3D
LoadIcon(0, =
MAKEINTRESOURCE(DEFAULTICON));
if (!prev){
class.style =3D CS_HREDRAW | CS_VREDRAW;
class.lpfnWndProc =3D CLOCK_WndProc;
class.cbClsExtra =3D 0;
class.cbWndExtra =3D 0;
class.hInstance =3D Globals.hInstance;
class.hIcon =3D LoadIcon (0, IDI_APPLICATION);
class.hCursor =3D LoadCursor (0, IDC_ARROW);
class.hbrBackground =3D GetStockObject (GRAY_BRUSH);
class.lpszMenuName =3D 0;
class.lpszClassName =3D szClassName;
}
if (!RegisterClass (&class)) return FALSE;
Globals.hMainWnd =3D CreateWindow (szClassName, szWinName, =
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, Globals.MaxX, Globals.MaxY, 0,
0, Globals.hInstance, 0);
ShowWindow (Globals.hMainWnd, show);
UpdateWindow (Globals.hMainWnd);
while (TRUE) {
Sleep(1);
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
if (msg.message =3D=3D WM_QUIT) return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/* We will never reach the following statement ! */
return 0;
}
-------------------------------------------------------------------------=
-----
The Question is - does some one else had the same problems?
Regards, Vlad
------=_NextPart_000_0287_01C2F877.E105B700
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2600.0" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>All.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>While I have been fighting with Mono =
under Wine,=20
I had the following error mesage:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3DArial size=3D2>err:win:GetDesktopWindow Wine init =
error: either=20
you're trying to use an invalid native USER.EXE config, or some =
graphics/GUI=20
libraries or DLLs didn't initialize properly. Aborting.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I found that, the reason of this error =
appearance=20
is the fact that USER32.DLL libary</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>was not initialized. The question - why =
is this=20
so?</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Below is the part of =
monostub.exe.spec.c =20
file </FONT><FONT face=3DArial size=3D2>while I see the above =
error=20
mesage.</FONT></DIV>
<DIV><FONT face=3DArial=20
size=3D2>----------------------------------------------------------------=
------</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>static const char dllname[] =3D=20
"monostub.exe";</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3DArial size=3D2>extern int =
__wine_spec_exports[];</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=3DArial size=3D2>#define __stdcall=20
__attribute__((__stdcall__))</FONT></DIV>
<DIV> </DIV><FONT face=3DArial size=3D2>
<DIV><BR>static struct {<BR> struct {<BR> =20
void =20
*OriginalFirstThunk;<BR> unsigned int=20
TimeDateStamp;<BR> unsigned int=20
ForwarderChain;<BR> const char =20
*Name;<BR> =
void =20
*FirstThunk;<BR> } imp[2];<BR> const char *data[20];<BR>} =
imports =3D=20
{<BR> {<BR> { 0, 0, 0, "kernel32.dll",=20
&imports.data[0] },<BR> { 0, 0, 0, 0, 0 =
},<BR> =20
},<BR> {<BR> /* kernel32.dll =
*/<BR> =20
"\305\000CreateEventA",<BR> =
"\332\000CreateSemaphoreA",</DIV>
<DIV>.........</DIV>
<DIV>--------------------------------------------------------------------=
-----</DIV>
<DIV>what does this code mean? </DIV>
<DIV>this mean that monostub.exe.so does import only kernel32.dll=20
library.</DIV>
<DIV>since the user32.dll have not been imported, and therefore have not =
been=20
initialized,</DIV>
<DIV>the above error message have been raised.</DIV>
<DIV> </DIV>
<DIV>Below is the same part of the same file, but after some =
changes</DIV>
<DIV>------------------------------------------------------------------</=
DIV>
<DIV>static const char dllname[] =3D "monostub.exe";</DIV>
<DIV> </DIV>
<DIV>extern int __wine_spec_exports[];</DIV>
<DIV> </DIV>
<DIV>#define __stdcall __attribute__((__stdcall__))</DIV>
<DIV> </DIV>
<DIV><BR>static struct {<BR> struct {<BR> =20
void =20
*OriginalFirstThunk;<BR> unsigned int=20
TimeDateStamp;<BR> unsigned int=20
ForwarderChain;<BR> const char =20
*Name;<BR> =
void =20
*FirstThunk;<BR> } imp[4];<BR> const char *data[34];<BR>} =
imports =3D=20
{<BR> {<BR> { 0, 0, 0, "user32.dll",=20
&imports.data[0] },<BR> { 0, 0, 0, "gdi32.dll",=20
&imports.data[12] },<BR> { 0, 0, 0, =
"kernel32.dll",=20
&imports.data[14] },<BR> { 0, 0, 0, 0, 0 =
},<BR> =20
},<BR> {<BR> /* user32.dll =
*/<BR> =20
"\145\000CreateWindowExA",<BR> =
"\223\000DefWindowProcA",</DIV>
<DIV> ..................</DIV>
<DIV><BR> =
"\215\002UpdateWindow",<BR> =20
0,<BR> /* gdi32.dll */<BR> =20
"\161\001GetStockObject",<BR> 0,<BR> =
/*=20
kernel32.dll */<BR> =20
"\305\000CreateEventA",<BR> =
"\332\000CreateSemaphoreA",</DIV>
<DIV>.......................<BR> =20
}<BR>};<BR>---------------------------------------------------</DIV>
<DIV>In this case the all required libraries have been =
imported,</DIV>
<DIV>and therefore the all Dlls have been initializated (and the =
USER32.DLL=20
too).</DIV>
<DIV> </DIV>
<DIV>To inderstand the situation, I have analyzed =
the clock.exe=20
program in wine/program directory.</DIV>
<DIV>its clock.exe.spec.c has all imported libraries into=20
it the same in file above.</DIV>
<DIV> </DIV>
<DIV>This example and analyzing of the method used to=20
create *.spec.c file made me clear, that </DIV>
<DIV>in order to get all imported libraries mentioned in=20
*.spec.c file at least one method from the</DIV>
<DIV>required dll have to be included into any source file. </DIV>
<DIV>None of monostub files had methods from USER32.DLL, only from =
KERNEL32.DLL.</DIV>
<DIV> </DIV>
<DIV>Therefore I have included into build the file, which =
has the=20
fake functions with required code.</DIV>
<DIV>This below code is the attempt to fix the problem. I have it =
solved,=20
but I think that this file</DIV>
<DIV>can be minimized to just hold one function (let it be=20
CreateWindowEx).</DIV>
<DIV>In any way this code will never be called. :-)</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>--------------------------------------------------------------------=
---------</DIV>
<DIV>#include "config.h"</DIV>
<DIV> </DIV>
<DIV>#include <stdio.h><BR>#include "windows.h"<BR>#include=20
"main.h"<BR>#include "commdlg.h"</DIV>
<DIV> </DIV>
<DIV>CLOCK_GLOBALS Globals;</DIV>
<DIV> </DIV>
<DIV><BR>/***************************************************************=
********<BR> *<BR> * &=
nbsp; =20
CLOCK_WndProc<BR> */</DIV>
<DIV> </DIV>
<DIV>LRESULT WINAPI CLOCK_WndProc (HWND hWnd, UINT msg, WPARAM wParam, =
LPARAM=20
lParam)<BR>{<BR> PAINTSTRUCT ps;<BR> =
HDC=20
context;</DIV>
<DIV> </DIV>
<DIV> switch (msg) {</DIV>
<DIV> </DIV>
<DIV> case WM_CREATE:=20
{<BR> =20
printf("WM_CREATE\n");<BR> =20
break;<BR> }</DIV>
<DIV> </DIV>
<DIV> case WM_RBUTTONUP:=20
{<BR> =20
printf("WM_RBUTTONUP\n");<BR> &n=
bsp; =20
break;<BR> }</DIV>
<DIV> </DIV>
<DIV> case WM_PAINT:=20
{<BR> =20
printf("WM_PAINT\n");<BR> =
=20
break;<BR> }</DIV>
<DIV> </DIV>
<DIV> case WM_SIZE:=20
{<BR> =20
printf("WM_SIZE\n");<BR> =20
break;<BR> }</DIV>
<DIV> </DIV>
<DIV> case WM_COMMAND:=20
{<BR> =20
break;<BR> }</DIV>
<DIV> </DIV>
<DIV> case WM_DESTROY:=20
{<BR> =20
printf("WM_DESTROY\n");<BR> &nbs=
p; =20
PostQuitMessage=20
(0);<BR>  =
;=20
break;<BR> }</DIV>
<DIV> </DIV>
<DIV> =20
default:<BR> =
return=20
DefWindowProc (hWnd, msg, wParam, lParam);<BR> =20
}<BR> return 0l;<BR>}</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>/*******************************************************************=
****<BR> *<BR> *  =
; =20
WinMain<BR> */</DIV>
<DIV> </DIV>
<DIV>int PASCAL my_mainWinMain (HINSTANCE hInstance, HINSTANCE prev, =
LPSTR=20
cmdline, int show)<BR>{<BR> =
MSG =20
msg;<BR> WNDCLASS class;</DIV>
<DIV> </DIV>
<DIV> char szClassName[] =3D "CLClass"; /* To =
make sure=20
className >=3D 0x10000 */<BR> char =
szWinName[] =3D=20
"Clock";</DIV>
<DIV> </DIV>
<DIV> /* Setup Globals */<BR> =20
Globals.bAnalog =3D TRUE;<BR> =20
Globals.bSeconds =3D=20
TRUE;<BR> Globals.lpszIniFile =
=3D=20
"clock.ini";<BR> =
Globals.lpszIcoFile =3D=20
"clock.ico";</DIV>
<DIV> </DIV>
<DIV> =
Globals.hInstance =3D=20
hInstance;<BR> =20
Globals.hMainIcon =3D=20
0;//ExtractIcon(Globals.hInstance, &nb=
sp; =20
Globals.lpszIcoFile, 0);</DIV>
<DIV> </DIV>
<DIV> if (!Globals.hMainIcon) Globals.hMainIcon=20
=3D<BR> =
&=
nbsp; =20
LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));</DIV>
<DIV> </DIV>
<DIV> if=20
(!prev){<BR> class.style &n=
bsp; =3D=20
CS_HREDRAW | CS_VREDRAW;<BR> class.lpfnWndProc =3D=20
CLOCK_WndProc;<BR> class.cbClsExtra =3D=20
0;<BR> class.cbWndExtra =3D=20
0;<BR> class.hInstance =3D=20
Globals.hInstance;<BR> class.hIcon &nbs=
p; =20
=3D LoadIcon (0,=20
IDI_APPLICATION);<BR> class.hCursor &nb=
sp; =3D=20
LoadCursor (0, IDC_ARROW);<BR> class.hbrBackground =3D =
GetStockObject=20
(GRAY_BRUSH);<BR> class.lpszMenuName =3D=20
0;<BR> class.lpszClassName =3D szClassName;<BR> =
}</DIV>
<DIV> </DIV>
<DIV> if (!RegisterClass (&class)) return =
FALSE;</DIV>
<DIV> </DIV>
<DIV> Globals.hMainWnd =3D CreateWindow (szClassName, =
szWinName,=20
WS_OVERLAPPEDWINDOW,<BR> =20
CW_USEDEFAULT, CW_USEDEFAULT, Globals.MaxX, Globals.MaxY,=20
0,<BR> 0, Globals.hInstance, =
0);</DIV>
<DIV> </DIV>
<DIV><BR> ShowWindow (Globals.hMainWnd,=20
show);<BR> UpdateWindow (Globals.hMainWnd);</DIV>
<DIV> </DIV>
<DIV> while (TRUE)=20
{<BR> =20
Sleep(1);<BR> if=20
(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))=20
{<BR> &n=
bsp; =20
if (msg.message =3D=3D WM_QUIT) return=20
msg.wParam;<BR> =20
TranslateMessage(&msg);<BR> =
=20
DispatchMessage(&msg);<BR> =
}<BR> }</DIV>
<DIV> </DIV>
<DIV> /* We will never reach the following statement=20
! */<BR> return 0;<BR>}</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>--------------------------------------------------------------------=
----------</DIV>
<DIV> </DIV>
<DIV>The Question is - does some one else had the same problems?</DIV>
<DIV> </DIV>
<DIV>Regards, Vlad</DIV>
<DIV></FONT> </DIV></BODY></HTML>
------=_NextPart_000_0287_01C2F877.E105B700--