Commit b817f4fb authored by Alexandre Julliard's avatar Alexandre Julliard

Release 960314

Wed Mar 13 19:46:50 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [controls/edit.c] Removed calls to memmove (not portable). * [debugger/dbg.y] [debugger/debug.l] Prefixed all token with 't' to avoid conflicts with type definitions. Added 'walk queue', 'walk class' and 'info class' commands. * [debugger/info.c] Moved queue and window information functions to windows/queue.c and windows/win.c respectively. * [loader/signal.c] Added SIGHUP handling to force entry into built-in debugger. Cleaned up a bit. * [misc/spy.c] General cleanup and performance improvements. * [windows/class.c] Added CLASS_DumpClass() and CLASS_WalkClasses() functions for debugger. * [windows/event.c] Pressing Ctrl-Alt-Return forces an entry into the debugger. Not sure if this key combination is a good choice... * [windows/message.c] [windows/queue.c] (New file) Moved message queue handling functions to windows/queue.c. Tue Mar 12 14:55:16 1996 Onno Hovers <onno@stack.urc.tue.nl> * [if1632/except.S] [include/except.h] [win32/except.c] (New files) Implemented Win32 exception functions: RaiseException(), RtlUnwind(), SetUnhandledExceptionFilter() and UnhandledExceptionFilter(). Mon Mar 11 19:23:29 1996 Albrecht Kleine <kleine@ak.sax.de> * [controls/listbox.c] [include/listbox.h] Special handling for COMBOLBOX styles introduced via extension of HEADLIST structure: lphl->dwStyle. Mon Mar 11 13:31:06 1996 Greg Kreider <kreider@natlab.research.philips.com> * [controls/combo.c] Any mouse movement within a small distance (defined by CBLMM_EDGE) of the top or bottom edge causes the window to scroll. Also moved some assignments so the routine works correctly. * [controls/listbox.c] Changing selection in ListBoxSetCurSel now updates PrevFocused. Added to LBSetFont and CreateListBoxStruct a fake hdc that tests and sets the standard text height. Sun Mar 10 08:39:23 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu> * [windows/dce.c] Fixed memory leak in DCE_ClipWindows().
parent d2e1c1a4
This is release 960309 of Wine the MS Windows emulator. This is still a
This is release 960314 of Wine the MS Windows emulator. This is still a
developer's only release. There are many bugs and many unimplemented API
features. Most applications still do not work.
Patches should be submitted to "julliard@lrc.epfl.ch". Please don't
forget to include a ChangeLog entry.
WHAT'S NEW with Wine-960309: (see ChangeLog for details)
- More edit control improvements.
- Help begins to work.
- Internal LZEXPAND.DLL.
WHAT'S NEW with Wine-960314: (see ChangeLog for details)
- Many combo and listbox fixes.
- Win32 exception handling.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
......@@ -17,10 +16,10 @@ Because of lags created by using mirror, this message may reach you before
the release is available at the ftp sites. The sources will be available
from the following locations:
sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960309.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960309.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960309.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-960309.tar.gz
sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960314.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960314.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960314.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-960314.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
......
----------------------------------------------------------------------
Wed Mar 13 19:46:50 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [controls/edit.c]
Removed calls to memmove (not portable).
* [debugger/dbg.y] [debugger/debug.l]
Prefixed all token with 't' to avoid conflicts with type
definitions.
Added 'walk queue', 'walk class' and 'info class' commands.
* [debugger/info.c]
Moved queue and window information functions to windows/queue.c
and windows/win.c respectively.
* [loader/signal.c]
Added SIGHUP handling to force entry into built-in debugger.
Cleaned up a bit.
* [misc/spy.c]
General cleanup and performance improvements.
* [windows/class.c]
Added CLASS_DumpClass() and CLASS_WalkClasses() functions for
debugger.
* [windows/event.c]
Pressing Ctrl-Alt-Return forces an entry into the debugger. Not
sure if this key combination is a good choice...
* [windows/message.c] [windows/queue.c] (New file)
Moved message queue handling functions to windows/queue.c.
Tue Mar 12 14:55:16 1996 Onno Hovers <onno@stack.urc.tue.nl>
* [if1632/except.S] [include/except.h] [win32/except.c] (New files)
Implemented Win32 exception functions: RaiseException(),
RtlUnwind(), SetUnhandledExceptionFilter() and
UnhandledExceptionFilter().
Mon Mar 11 19:23:29 1996 Albrecht Kleine <kleine@ak.sax.de>
* [controls/listbox.c] [include/listbox.h]
Special handling for COMBOLBOX styles introduced via extension of
HEADLIST structure: lphl->dwStyle.
Mon Mar 11 13:31:06 1996 Greg Kreider <kreider@natlab.research.philips.com>
* [controls/combo.c]
Any mouse movement within a small distance (defined by CBLMM_EDGE)
of the top or bottom edge causes the window to scroll. Also moved
some assignments so the routine works correctly.
* [controls/listbox.c]
Changing selection in ListBoxSetCurSel now updates PrevFocused.
Added to LBSetFont and CreateListBoxStruct a fake hdc that tests
and sets the standard text height.
Sun Mar 10 08:39:23 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [windows/dce.c]
Fixed memory leak in DCE_ClipWindows().
----------------------------------------------------------------------
Fri Mar 8 19:07:18 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [configure.in]
......@@ -69,6 +132,11 @@ Mon Mar 4 23:22:40 1996 Jim Peterson <jspeter@birch.ee.vt.edu>
* [include/wintypes.h]
Added "#define __export".
* [objects/bitblt.c]
Put in a few hacks to make bitblt-ing work when upside-down and/or
mirrored. BITBLT_StretchImage should really be checked over
thoroughly.
* [programs/progman/main.c]
Added "#include <resource.h>" for definition of HAVE_WINE_CONSTRUCTOR.
......
......@@ -32,6 +32,9 @@
* I hope no programs rely on the implementation of combos.
*/
#define CBLMM_EDGE 4 /* distance inside box which is same as moving mouse
outside box, to trigger scrolling of CBL */
static HBITMAP hComboBit = 0;
static WORD CBitHeight, CBitWidth;
......@@ -470,6 +473,8 @@ static LRESULT CBSetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
wRet = ListBoxSetCurSel(lphl, wParam);
dprintf_combo(stddeb,"CBSetCurSel: hwnd "NPFMT" wp %x lp %lx wRet %d\n",
hwnd,wParam,lParam,wRet);
/* SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);*/
InvalidateRect(hwnd, NULL, TRUE);
......@@ -877,37 +882,41 @@ static LRESULT CBLLButtonUp( HWND hwnd, WPARAM wParam, LPARAM lParam )
static LRESULT CBLMouseMove( HWND hwnd, WPARAM wParam, LPARAM lParam )
{
LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
int y;
short y;
WORD wRet;
RECT rect, rectsel; /* XXX Broken */
RECT rect, rectsel;
y = SHIWORD(lParam);
wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
ListBoxGetItemRect(lphl, wRet, &rectsel);
GetClientRect(hwnd, &rect);
dprintf_combo(stddeb,"CBLMouseMove: hwnd "NPFMT" wp %x lp %lx y %d if %d wret %d %d,%d-%d,%d\n",
hwnd,wParam,lParam,y,lphl->ItemFocused,wRet,rectsel.left,rectsel.top,rectsel.right,rectsel.bottom);
if ((wParam & MK_LBUTTON) != 0) {
y = SHIWORD(lParam);
if (y < 0) {
if (y < CBLMM_EDGE) {
if (lphl->FirstVisible > 0) {
lphl->FirstVisible--;
SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
ListBoxSetCurSel(lphl, wRet);
InvalidateRect(hwnd, NULL, TRUE);
return 0;
}
}
GetClientRect(hwnd, &rect);
if (y >= rect.bottom) {
else if (y >= (rect.bottom-CBLMM_EDGE)) {
if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) {
lphl->FirstVisible++;
SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
ListBoxSetCurSel(lphl, wRet);
InvalidateRect(hwnd, NULL, TRUE);
return 0;
}
}
if ((y > 0) && (y < (rect.bottom - 4))) {
if ((y < rectsel.top) || (y > rectsel.bottom)) {
wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
if (wRet == lphl->ItemFocused) return 0;
ListBoxSetCurSel(lphl, wRet);
ListBoxGetItemRect(lphl, wRet, &rectsel);
InvalidateRect(hwnd, NULL, TRUE);
}
else {
if ((short) wRet == lphl->ItemFocused) return 0;
ListBoxSetCurSel(lphl, wRet);
InvalidateRect(hwnd, NULL, TRUE);
}
}
......
......@@ -1757,7 +1757,7 @@ static void EDIT_InsertText(HWND hwnd, char *str, int len)
{
int plen;
EDITSTATE *es = EDIT_GetEditState(hwnd);
char *text = EDIT_HeapLock(hwnd, es->hText);
char *p, *text = EDIT_HeapLock(hwnd, es->hText);
plen = strlen(text) + len;
if (plen + 1 > es->textlen)
......@@ -1767,7 +1767,7 @@ static void EDIT_InsertText(HWND hwnd, char *str, int len)
text = EDIT_HeapLock(hwnd, es->hText);
es->textlen = plen + 1;
}
memmove(CurrChar + len, CurrChar, strlen(CurrChar) + 1);
for (p = CurrChar + strlen(CurrChar); p >= CurrChar; p--) p[len] = *p;
memcpy(CurrChar, str, len);
EDIT_BuildTextPointers(hwnd);
......@@ -1834,7 +1834,7 @@ static void EDIT_KeyTyped(HWND hwnd, short ch)
{
EDITSTATE *es = EDIT_GetEditState(hwnd);
char *text = EDIT_HeapLock(hwnd, es->hText);
char *currchar;
char *currchar, *p;
RECT rc;
BOOL FullPaint = FALSE;
......@@ -1890,14 +1890,14 @@ static void EDIT_KeyTyped(HWND hwnd, short ch)
/* make space for new character and put char in buffer */
if (ch == '\n')
{
memmove(currchar + 2, currchar, strlen(currchar) + 1);
for (p = currchar + strlen(currchar); p >= currchar; p--) p[2] = p[0];
*currchar = '\r';
*(currchar + 1) = '\n';
EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 2);
}
else
{
memmove(currchar + 1, currchar, strlen(currchar) + 1);
for (p = currchar + strlen(currchar); p >= currchar; p--) p[1] = p[0];
*currchar = ch;
EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 1);
}
......
......@@ -35,7 +35,7 @@ IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
%%
\n { syntax_error = 0; return EOL; } /*Indicates end of command*/
\n { syntax_error = 0; return tEOL; } /*Indicates end of command*/
"||" { return OP_LOR; }
"&&" { return OP_LAND; }
......@@ -47,77 +47,76 @@ IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
">>" { return OP_SHR; }
[-+<=>|&^()*/%:!~] { return *yytext; }
"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval.integer); return NUM; }
{DIGIT}+ { sscanf(yytext, "%d", &yylval.integer); return NUM; }
"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval.integer); return tNUM; }
{DIGIT}+ { sscanf(yytext, "%d", &yylval.integer); return tNUM; }
"/"{DIGIT}+{FORMAT} { char * last;
yylval.integer = strtol( yytext+1, &last, NULL );
yylval.integer = (yylval.integer << 8) | *last;
return FORMAT; }
"/"{FORMAT} { yylval.integer = (1 << 8) | yytext[1]; return FORMAT; }
$pc { yylval.reg = REG_EIP; return REG; }
$flags { yylval.reg = REG_EFL; return REG; }
$eip { yylval.reg = REG_EIP; return REG; }
$ip { yylval.reg = REG_IP; return REG; }
$esp { yylval.reg = REG_ESP; return REG; }
$sp { yylval.reg = REG_SP; return REG; }
$eax { yylval.reg = REG_EAX; return REG; }
$ebx { yylval.reg = REG_EBX; return REG; }
$ecx { yylval.reg = REG_ECX; return REG; }
$edx { yylval.reg = REG_EDX; return REG; }
$esi { yylval.reg = REG_ESI; return REG; }
$edi { yylval.reg = REG_EDI; return REG; }
$ebp { yylval.reg = REG_EBP; return REG; }
$ax { yylval.reg = REG_AX; return REG; }
$bx { yylval.reg = REG_BX; return REG; }
$cx { yylval.reg = REG_CX; return REG; }
$dx { yylval.reg = REG_DX; return REG; }
$si { yylval.reg = REG_SI; return REG; }
$di { yylval.reg = REG_DI; return REG; }
$bp { yylval.reg = REG_BP; return REG; }
$es { yylval.reg = REG_ES; return REG; }
$ds { yylval.reg = REG_DS; return REG; }
$cs { yylval.reg = REG_CS; return REG; }
$ss { yylval.reg = REG_SS; return REG; }
info|inf|in { return INFO; }
show|sho|sh { return INFO; }
list|lis|li|l { return LIST; }
segments|segment|segm|seg|se { return SEGMENTS; }
break|brea|bre|br|b { return BREAK; }
enable|enabl|enab|ena { return ENABLE;}
disable|disabl|disab|disa|dis { return DISABLE; }
delete|delet|dele|del { return DELETE; }
quit|qui|qu|q { return QUIT; }
walk|w { return WALK; }
queue|queu|que { return QUEUE; }
window|windo|wind|win|wnd { return WND; }
x { return EXAM; }
help|hel|he|"?" { return HELP; }
set|se { return SET; }
bt { return BACKTRACE; }
cont|con|co|c { return CONT; }
step|ste|st|s { return STEP; }
next|nex|ne|n { return NEXT; }
symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return SYMBOLFILE; }
define|defin|defi|def|de { return DEFINE; }
abort|abor|abo { return ABORT; }
print|prin|pri|pr|p { return PRINT; }
mode { return MODE; }
registers|regs|reg|re { return REGS; }
stack|stac|sta|st { return STACK; }
{IDENTIFIER} { yylval.string = make_symbol(yytext); return IDENTIFIER; }
return tFORMAT; }
"/"{FORMAT} { yylval.integer = (1 << 8) | yytext[1]; return tFORMAT; }
$pc { yylval.reg = REG_EIP; return tREG; }
$flags { yylval.reg = REG_EFL; return tREG; }
$eip { yylval.reg = REG_EIP; return tREG; }
$ip { yylval.reg = REG_IP; return tREG; }
$esp { yylval.reg = REG_ESP; return tREG; }
$sp { yylval.reg = REG_SP; return tREG; }
$eax { yylval.reg = REG_EAX; return tREG; }
$ebx { yylval.reg = REG_EBX; return tREG; }
$ecx { yylval.reg = REG_ECX; return tREG; }
$edx { yylval.reg = REG_EDX; return tREG; }
$esi { yylval.reg = REG_ESI; return tREG; }
$edi { yylval.reg = REG_EDI; return tREG; }
$ebp { yylval.reg = REG_EBP; return tREG; }
$ax { yylval.reg = REG_AX; return tREG; }
$bx { yylval.reg = REG_BX; return tREG; }
$cx { yylval.reg = REG_CX; return tREG; }
$dx { yylval.reg = REG_DX; return tREG; }
$si { yylval.reg = REG_SI; return tREG; }
$di { yylval.reg = REG_DI; return tREG; }
$bp { yylval.reg = REG_BP; return tREG; }
$es { yylval.reg = REG_ES; return tREG; }
$ds { yylval.reg = REG_DS; return tREG; }
$cs { yylval.reg = REG_CS; return tREG; }
$ss { yylval.reg = REG_SS; return tREG; }
info|inf|in { return tINFO; }
show|sho|sh { return tINFO; }
list|lis|li|l { return tLIST; }
break|brea|bre|br|b { return tBREAK; }
enable|enabl|enab|ena { return tENABLE;}
disable|disabl|disab|disa|dis { return tDISABLE; }
delete|delet|dele|del { return tDELETE; }
quit|qui|qu|q { return tQUIT; }
set|se { return tSET; }
walk|w { return tWALK; }
x { return tEXAM; }
class|clas|cla { return tCLASS; }
queue|queu|que { return tQUEUE; }
registers|regs|reg|re { return tREGS; }
segments|segment|segm|seg|se { return tSEGMENTS; }
stack|stac|sta|st { return tSTACK; }
window|windo|wind|win|wnd { return tWND; }
help|hel|he|"?" { return tHELP; }
backtrace|bt { return tBACKTRACE; }
cont|con|co|c { return tCONT; }
step|ste|st|s { return tSTEP; }
next|nex|ne|n { return tNEXT; }
symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return tSYMBOLFILE; }
define|defin|defi|def|de { return tDEFINE; }
abort|abor|abo { return tABORT; }
print|prin|pri|pr|p { return tPRINT; }
mode { return tMODE; }
{IDENTIFIER} { yylval.string = make_symbol(yytext); return tIDENTIFIER; }
[ \t]+ /* Eat up whitespace */
......
......@@ -215,7 +215,6 @@ void DEBUG_LoadEntryPoints(void)
unsigned int address;
BOOL ok;
fprintf( stderr, "Adding symbols from loaded modules\n" );
for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
{
if (!(pModule = (NE_MODULE *)GlobalLock( entry.hModule ))) continue;
......
......@@ -7,191 +7,8 @@
#include <stdio.h>
#include <stdlib.h>
#include "global.h"
#include "user.h"
#include "class.h"
#include "win.h"
#include "message.h"
#include "spy.h"
#include "debugger.h"
int iWndIndent = 0;
extern char lpstrSpyMessageIndent[]; /* from misc/spy.c */
/***********************************************************************
* DEBUG_InitWalk
*/
void DEBUG_InitWalk(void)
{
fprintf(stderr,"%-24.24s %-6.6s %-17.17s %-8.8s %s\n",
"HWND / WNDPTR","hQueue","Class Name", "Style", "WndProc");
lpstrSpyMessageIndent[0]='\0';
}
/***********************************************************************
* DEBUG_WndWalk
*
*/
void DEBUG_WndWalk(HWND hStart)
{
WND* wndPtr;
CLASS* classPtr;
char className[0x10];
int i;
if( !hStart )
hStart = GetDesktopHwnd();
wndPtr = WIN_FindWndPtr(hStart);
if( !wndPtr )
{ fprintf(stderr, "Invalid window handle: %04x\n", hStart);
return; }
i = strlen(lpstrSpyMessageIndent);
/* 0x10 bytes are always reserved at the end of lpstrSpyMessageIndent */
sprintf(lpstrSpyMessageIndent + i,"%04x %08x",hStart, (unsigned) wndPtr);
classPtr = CLASS_FindClassPtr(wndPtr->hClass);
if(classPtr)
GlobalGetAtomName(classPtr->atomName ,className, 0x10);
else
strcpy(className,"<BAD>");
fprintf(stderr,"%-24.24s %-6.4x %-17.17s %08x %04x:%04x\n",
lpstrSpyMessageIndent,
wndPtr->hmemTaskQ,
className,
(unsigned) wndPtr->dwStyle,
HIWORD(wndPtr->lpfnWndProc),
LOWORD(wndPtr->lpfnWndProc));
lpstrSpyMessageIndent[i] = '\0';
if( wndPtr->hwndChild )
{
/* walk children */
hStart = wndPtr->hwndChild;
wndPtr = WIN_FindWndPtr(hStart);
iWndIndent ++;
if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 )
{
lpstrSpyMessageIndent[iWndIndent - 1] = ' ';
lpstrSpyMessageIndent[iWndIndent] = '\0';
}
while( wndPtr )
{
DEBUG_WndWalk(hStart);
hStart = wndPtr->hwndNext;
wndPtr = WIN_FindWndPtr(hStart);
}
if( hStart )
fprintf(stderr, "%s%s"NPFMT"\n", lpstrSpyMessageIndent,
"<BAD>", hStart);
if( iWndIndent )
{
iWndIndent--;
if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 )
lpstrSpyMessageIndent[iWndIndent] = '\0';
}
}
}
/***********************************************************************
* DEBUG_WndDump
*
*/
void DEBUG_WndDump(HWND hWnd)
{
WND* wnd;
char* lpWndText = NULL;
wnd = WIN_FindWndPtr(hWnd);
if( !wnd )
{ fprintf(stderr, "Invalid window handle: %04x\n", hWnd);
return; }
if( wnd->hText )
lpWndText = (LPSTR) USER_HEAP_LIN_ADDR( wnd->hText );
fprintf( stderr, "next: %12.4x\n"
"child: %10.4x\n"
"parent: %10.4x\n"
"owner: %10.4x\n"
"hClass: %10.4x\n"
"hInst: %10.4x\n"
"clientRect: %i,%i - %i,%i\n"
"windowRect: %i,%i - %i,%i\n"
"hRgnUpdate: %6.4x\n"
"hLastPopup: %6.4x\n"
"Style: %10.8x\n"
"StyleEx: %9.8x\n"
"hDCE: %10.4x\n"
"hVscroll: %8.4x\n"
"hHscroll: %8.4x\n"
"menuID: %10.4x\n"
"hText: %10.4x (\"%s\")\n"
"flags: %10.4x\n",
wnd->hwndNext, wnd->hwndChild,wnd->hwndParent,
wnd->hwndOwner,wnd->hClass,wnd->hInstance,
wnd->rectClient.left, wnd->rectClient.top,
wnd->rectClient.right, wnd->rectClient.bottom,
wnd->rectWindow.left, wnd->rectWindow.top,
wnd->rectWindow.right, wnd->rectWindow.bottom,
wnd->hrgnUpdate, wnd->hwndLastActive,
(unsigned) wnd->dwStyle, (unsigned) wnd->dwExStyle,
wnd->hdce, wnd->hVScroll, wnd->hHScroll,
wnd->wIDmenu, wnd->hText, (lpWndText)?lpWndText:"NULL",
wnd->flags);
}
/***********************************************************************
* DEBUG_QueueDump
*
*/
void DEBUG_QueueDump(HQUEUE hQ)
{
MESSAGEQUEUE* pq;
if( !hQ || IsBadReadPtr((SEGPTR)MAKELONG( 0, GlobalHandleToSel(hQ)),
sizeof(MESSAGEQUEUE)) )
{
fprintf(stderr, "Invalid queue handle: "NPFMT"\n", hQ);
return;
}
pq = (MESSAGEQUEUE*) GlobalLock( hQ );
fprintf(stderr,"next: %12.4x Intertask SendMessage:\n"
"hTask: %11.4x ----------------------\n"
"msgSize: %9.4x hWnd: %10.4x\n"
"msgCount: %8.4x msg: %11.4x\n"
"msgNext: %9.4x wParam: %8.4x\n"
"msgFree: %9.4x lParam: %8.8x\n"
"qSize: %11.4x lRet: %10.8x\n"
"wWinVer: %9.4x ISMH: %10.4x\n"
"paints: %10.4x hSendTask: %5.4x\n"
"timers: %10.4x hPrevSend: %5.4x\n"
"wakeBits: %8.4x\n"
"wakeMask: %8.4x\n"
"hCurHook: %8.4x\n",
pq->next, pq->hTask, pq->msgSize, pq->hWnd,
pq->msgCount, pq->msg, pq->nextMessage, pq->wParam,
pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize,
(unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
pq->hPrevSendingTask, pq->status, pq->wakeMask, pq->hCurHook);
}
/***********************************************************************
* DEBUG_Print
*
......
......@@ -46,7 +46,8 @@ C_SRCS = \
ASM_SRCS = \
$(SPEC16_FILES) \
call16.S \
call32.S
call32.S \
except.S
.SUFFIXES: .spec
......
/*
* Win32 exception assembly functions
*
* Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl)
*
*/
#ifndef __ELF__
.globl _EXC_CallUnhandledExceptionFilter
.extern _pTopExcHandler
_EXC_CallUnhandledExceptionFilter:
#else /* __ELF__ */
.globl EXC_CallUnhandledExceptionFilter
.extern pTopExcHandler
EXC_CallUnhandledExceptionFilter:
#endif /* __ELF__ */
leal 4(%esp),%eax
pushl %eax
#ifndef __ELF__
call *_pTopExcHandler
#else /* __ELF__ */
call *pTopExcHandler
#endif /* __ELF__ */
movl %ebp,%esp
ret
/*******************************************************************
*
* RaiseException (KERNEL32. 418 )
* RtlUnwind (KERNEL32. 443 )
*
* we need to save our context before a call to
*
* -RaiseException
* -RtlUnwind
*
* after these functions we need to restore that context structure as
* the actual context so changes made to the context structure in an
* exception-handler will be reflected in the context after these
* functions return. Fortunately both functions have 4 DWORD params.
* we pass the function to be called as a fifth parameter to ContextCall
*
*/
.equ CONTEXT_SegSs, -4
.equ CONTEXT_Esp, -8
.equ CONTEXT_EFlags, -12
.equ CONTEXT_SegCs, -16
.equ CONTEXT_Eip, -20
.equ CONTEXT_Ebp, -24
.equ CONTEXT_Eax, -28
.equ CONTEXT_Ecx, -32
.equ CONTEXT_Edx, -36
.equ CONTEXT_Ebx, -40
.equ CONTEXT_Esi, -44
.equ CONTEXT_Edi, -48
.equ CONTEXT_SegDs, -52
.equ CONTEXT_SegEs, -56
.equ CONTEXT_SegFs, -60
.equ CONTEXT_SegGs, -64
.equ FLOAT_Cr0NpxState, -68
.equ FLOAT_RegisterArea, -148
.equ FLOAT_DataSelector, -152
.equ FLOAT_DataOffset, -156
.equ FLOAT_ErrorSelector, -160
.equ FLOAT_ErrorOffset, -164
.equ FLOAT_TagWord, -168
.equ FLOAT_StatusWord, -172
.equ FLOAT_ControlWord, -176
.equ CONTEXT_FloatSave, -176
.equ CONTEXT_Dr7, -180
.equ CONTEXT_Dr6, -184
.equ CONTEXT_Dr3, -188
.equ CONTEXT_Dr2, -192
.equ CONTEXT_Dr1, -196
.equ CONTEXT_Dr0, -200
.equ CONTEXT_ContextFlags, -204
.equ CONTEXT, -204
.equ CONTEXTSIZE, 204
.equ CONTEXTFLAGS, 0x10007
.equ ORIG_ESP, 16 /** cdecl !!! **/
.equ PARM_ARG4, 28
.equ PARM_ARG3, 24
.equ PARM_ARG2, 20
.equ PARM_ARG1, 16
.equ PARM_RETURN, 12
.equ PARM_CALLFUNC, 8
.equ PARM_EBP, 4
.equ PARM_EFLAGS, 0
#ifndef __ELF__
.globl _RaiseException
.extern _EXC_RaiseException
_RaiseException:
push $_EXC_RaiseException
jmp ContextCall
.globl _RtlUnwind
_RtlUnwind:
push $_EXC_RtlUnwind
#else /* __ELF__ */
.globl RaiseException
.extern EXC_RaiseException
RaiseException:
push $EXC_RaiseException
jmp ContextCall
.globl RtlUnwind
RtlUnwind:
push $EXC_RtlUnwind
#endif /* __ELF__ */
ContextCall:
pushl %ebp
pushfl
movl %esp, %ebp
subl $CONTEXTSIZE, %esp
movl %eax, CONTEXT_Eax(%ebp)
leal ORIG_ESP(%ebp), %eax
movl %eax, CONTEXT_Esp(%ebp)
movl PARM_EFLAGS(%ebp), %eax
movl %eax, CONTEXT_EFlags(%ebp)
movl PARM_EBP(%ebp), %eax
movl %eax, CONTEXT_Ebp(%ebp)
movl PARM_RETURN(%ebp), %eax
movl %eax, CONTEXT_Eip(%ebp)
movl %edi, CONTEXT_Edi(%ebp)
movl %esi, CONTEXT_Esi(%ebp)
movl %ebx, CONTEXT_Ebx(%ebp)
movl %edx, CONTEXT_Edx(%ebp)
movl %ecx, CONTEXT_Ecx(%ebp)
xorl %eax, %eax
movw %ss, %ax
movl %eax, CONTEXT_SegSs(%ebp)
movw %cs, %ax
movl %eax, CONTEXT_SegCs(%ebp)
movw %gs, %ax
movl %eax, CONTEXT_SegGs(%ebp)
movw %fs, %ax
movl %eax, CONTEXT_SegFs(%ebp)
movw %es, %ax
movl %eax, CONTEXT_SegEs(%ebp)
movw %ds, %ax
movl %eax, CONTEXT_SegDs(%ebp)
fsave CONTEXT_FloatSave(%ebp)
movl $CONTEXTFLAGS, %eax
movl %eax, CONTEXT_ContextFlags(%ebp)
pushl %ebp
leal CONTEXT(%ebp), %eax
pushl %eax
pushl PARM_ARG4(%ebp)
pushl PARM_ARG3(%ebp)
pushl PARM_ARG2(%ebp)
pushl PARM_ARG1(%ebp)
call *PARM_CALLFUNC(%ebp)
addl $20,%esp
popl %ebp
lds CONTEXT_Esp(%ebp),%edi
movl CONTEXT_Eip(%ebp),%eax
movl %eax,-4(%edi)
movl CONTEXT_EFlags(%ebp),%eax
movl %eax,-8(%edi)
movl CONTEXT_Edi(%ebp),%eax
movl %eax,-12(%edi)
movl CONTEXT_SegDs(%ebp),%eax
movw %ax,%ds
movl CONTEXT_SegEs(%ebp),%eax
movw %ax,%es
movl CONTEXT_SegFs(%ebp),%eax
movw %ax,%fs
movl CONTEXT_SegGs(%ebp),%eax
movw %ax,%gs
frstor CONTEXT_FloatSave(%ebp)
movl CONTEXT_Ecx(%ebp),%ecx
movl CONTEXT_Edx(%ebp),%edx
movl CONTEXT_Ebx(%ebp),%ebx
movl CONTEXT_Esi(%ebp),%esi
movl CONTEXT_Eax(%ebp),%eax
movl CONTEXT_Ebp(%ebp),%ebp
lea -12(%edi),%esp
popl %edi
popfl
ret
......@@ -445,7 +445,7 @@ base 1
0440 stub ResumeThread
0441 stub RtlFillMemory
0442 stub RtlMoveMemory
0443 stub RtlUnwind
0443 stdcall RtlUnwind(ptr long ptr long) RtlUnwind
0444 stub RtlZeroMemory
0445 stub ScrollConsoleScreenBufferA
0446 stub ScrollConsoleScreenBufferW
......@@ -518,7 +518,7 @@ base 1
0513 stub SetThreadLocale
0514 stub SetThreadPriority
0515 stub SetTimeZoneInformation
0516 stub SetUnhandledExceptionFilter
0516 stdcall SetUnhandledExceptionFilter(ptr) SetUnhandledExceptionFilter
0517 stub SetVDMCurrentDirectories
0518 stub SetVolumeLabelA
0519 stub SetVolumeLabelW
......@@ -539,7 +539,7 @@ base 1
0534 stub TransactNamedPipe
0535 stub TransmitCommChar
0536 stub TrimVirtualBuffer
0537 stub UnhandledExceptionFilter
0537 stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter
0538 stub UnlockFile
0539 stub UnlockFileEx
0540 stub UnmapViewOfFile
......
......@@ -7,7 +7,7 @@ id 7
4 pascal16 ToAscii(word word ptr ptr word) ToAscii
5 pascal16 AnsiToOem(ptr ptr) AnsiToOem
6 pascal16 OemToAnsi(ptr ptr) OemToAnsi
#7 pascal SetSpeed
7 return SetSpeed 2 65535
#100 pascal ScreenSwitchEnable
#126 pascal GetTableSeg
#127 pascal NewTable
......
......@@ -13,7 +13,7 @@ id 2
12 pascal16 KillTimer(word word) KillTimer
13 pascal GetTickCount() GetTickCount
14 pascal GetTimerResolution() GetTimerResolution
15 pascal GetCurrentTime() GetTickCount
15 pascal GetCurrentTime() GetCurrentTime
16 pascal16 ClipCursor(ptr) ClipCursor
17 pascal16 GetCursorPos(ptr) GetCursorPos
18 pascal16 SetCapture(word) SetCapture
......
......@@ -31,9 +31,10 @@ typedef struct tagCLASS
#pragma pack(4)
#endif
HCLASS CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance, CLASS **ptr );
CLASS * CLASS_FindClassPtr( HCLASS hclass );
extern void CLASS_DumpClass( HCLASS hClass );
extern void CLASS_WalkClasses(void);
extern HCLASS CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance,
CLASS **ptr );
extern CLASS * CLASS_FindClassPtr( HCLASS hclass );
#endif /* CLASS_H */
......@@ -89,10 +89,6 @@ extern void DEBUG_Print( const DBG_ADDR *addr, int count, char format );
extern void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen );
extern void DEBUG_Help(void);
extern void DEBUG_List( DBG_ADDR *addr, int count );
extern void DEBUG_InitWalk(void);
extern void DEBUG_WndWalk( HWND );
extern void DEBUG_WndDump( HWND );
extern void DEBUG_QueueDump( HQUEUE );
/* debugger/memory.c */
extern BOOL DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size );
......
/*
* except.h
* Copyright (c) 1996, Onno Hovers (onno@stack.urc.tue.nl)
*/
#ifndef __WINE_EXCEPT_H
#define __WINE_EXCEPT_H
#include"windows.h"
/*
* general definitions
*/
#ifndef PVOID
#define PVOID void *
#endif
/*
* exception codes
*/
#define STATUS_WAIT_0 0x00000000
#define STATUS_ABANDONED_WAIT_0 0x00000080
#define STATUS_USER_APC 0x000000C0
#define STATUS_TIMEOUT 0x00000102
#define STATUS_PENDING 0x00000103
#define STATUS_DATATYPE_MISALIGNMENT 0x80000002
#define STATUS_BREAKPOINT 0x80000003
#define STATUS_SINGLE_STEP 0x80000004
#define STATUS_ACCESS_VIOLATION 0xC0000005
#define STATUS_IN_PAGE_ERROR 0xC0000006
#define STATUS_NO_MEMORY 0xC0000017
#define STATUS_ILLEGAL_INSTRUCTION 0xC000001D
#define STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025
#define STATUS_INVALID_DISPOSITION 0xC0000026
#define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C
#define STATUS_FLOAT_DENORMAL_OPERAND 0xC000008D
#define STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008E
#define STATUS_FLOAT_INEXACT_RESULT 0xC000008F
#define STATUS_FLOAT_INVALID_OPERATION 0xC0000090
#define STATUS_FLOAT_OVERFLOW 0xC0000091
#define STATUS_FLOAT_STACK_CHECK 0xC0000092
#define STATUS_FLOAT_UNDERFLOW 0xC0000093
#define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094
#define STATUS_INTEGER_OVERFLOW 0xC0000095
#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096
#define STATUS_STACK_OVERFLOW 0xC00000FD
#define STATUS_CONTROL_C_EXIT 0xC000013A
#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT
#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT
#define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP
#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED
#define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND
#define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO
#define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT
#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION
#define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW
#define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK
#define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW
#define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO
#define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW
#define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION
#define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR
/*
* return values from the actual exception handlers
*/
#define ExceptionContinueExecution 0
#define ExceptionContinueSearch 1
#define ExceptionNestedException 2
#define ExceptionCollidedUnwind 3
/*
* return values from filters in except() and from UnhandledExceptionFilter
*/
#define EXCEPTION_EXECUTE_HANDLER 1
#define EXCEPTION_CONTINUE_SEARCH 0
#define EXCEPTION_CONTINUE_EXECUTION -1
/*
* from OS/2 2.0 exception handling
* Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD
*/
#define EH_NONCONTINUABLE 0x01
#define EH_UNWINDING 0x02
#define EH_EXIT_UNWIND 0x04
#define EH_STACK_INVALID 0x08
#define EH_NESTED_CALL 0x10
#define EXCEPTION_CONTINUABLE 0
#define EXCEPTION_NONCONTINUABLE EH_NONCONTINUABLE
/*
* data types
*/
/*
* The i386 context used by Win32 for almost everything.
*/
#define SIZE_OF_80387_REGISTERS 80
typedef struct _FLOATING_SAVE_AREA
{
DWORD ControlWord;
DWORD StatusWord;
DWORD TagWord;
DWORD ErrorOffset;
DWORD ErrorSelector;
DWORD DataOffset;
DWORD DataSelector;
BYTE RegisterArea[SIZE_OF_80387_REGISTERS];
DWORD Cr0NpxState;
} FLOATING_SAVE_AREA;
typedef struct __CONTEXT
{
DWORD ContextFlags;
DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;
FLOATING_SAVE_AREA FloatSave;
DWORD SegGs;
DWORD SegFs;
DWORD SegEs;
DWORD SegDs;
DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;
DWORD Ebp;
DWORD Eip;
DWORD SegCs;
DWORD EFlags;
DWORD Esp;
DWORD SegSs;
} CONTEXT;
typedef struct __CONTEXT *PCONTEXT;
/*
* The exception record used by Win32 to give additional information
* about exception to exception handlers.
*/
#define EXCEPTION_MAXIMUM_PARAMETERS 15
typedef struct __EXCEPTION_RECORD
{
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct __EXCEPTION_RECORD *ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;
typedef struct __EXCEPTION_RECORD_MIN
{
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct __EXCEPTION_RECORD *ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
DWORD ExceptionInformation[0];
} EXCEPTION_RECORD_MIN;
typedef struct __EXCEPTION_RECORD *PEXCEPTION_RECORD;
/*
* The exception pointers structure passed to exception filters
* in except() and the UnhandledExceptionFilter().
*/
typedef struct __EXCEPTION_POINTERS
{
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS;
typedef struct __EXCEPTION_POINTERS *PEXCEPTION_POINTERS;
/*
* the function pointer to a exception handler
*/
/* forward definition */
struct __EXCEPTION_FRAME;
typedef DWORD ( *PEXCEPTION_HANDLER)( PEXCEPTION_RECORD pexcrec,
struct __EXCEPTION_FRAME *pestframe,
PCONTEXT pcontext,
PVOID pdispatcher);
/*
* function pointer to a UnhandledExceptionFilter();
*/
typedef long (WINAPI *__PTOP_EXCFILTER)
(PEXCEPTION_POINTERS ExceptionInfo);
typedef __PTOP_EXCFILTER PTOP_LEVER_EXCEPTION_FILTER;
typedef __PTOP_EXCFILTER LPTOP_LEVEL_EXCEPTION_FILTER;
/*
* The exception frame, used for registering exception handlers
* Win32 cares only about this, but compilers generally emit
* larger exception frames for their own use.
*/
typedef struct __EXCEPTION_FRAME
{
struct __EXCEPTION_FRAME *Prev;
PEXCEPTION_HANDLER Handler;
} EXCEPTION_FRAME;
typedef struct __EXCEPTION_FRAME *PEXCEPTION_FRAME;
extern PEXCEPTION_FRAME TebExceptionFrame asm("%fs:0");
#define EXC_GetFrame() TebExceptionFrame
#define EXC_SetFrame(a) (TebExceptionFrame=(a))
/*
* Function definitions
*/
void EXC_RaiseException(DWORD exccode, DWORD excflags,
DWORD nargs, const LPDWORD pargs,
PCONTEXT pcontext);
void EXC_RtlUnwind( PEXCEPTION_FRAME pestframe,
LPVOID unusedEIP,
PEXCEPTION_RECORD pexcrec,
DWORD contextEAX,
PCONTEXT pcontext );
DWORD EXC_CallUnhandledExceptionFilter( PEXCEPTION_RECORD precord,
PCONTEXT pcontext);
void EXC_Init(void);
BOOL WINAPI RaiseException(DWORD exccode, DWORD excflags,
DWORD nargs, const LPDWORD pargs);
/*
* this undocumented function is called when an exception
* handler wants all the frames to be unwound. RtlUnwind
* calls all exception handlers with the EH_UNWIND or
* EH_EXIT_UNWIND flags set in the exception record
*
* This prototype assumes RtlUnwind takes the same
* parameters as OS/2 2.0 DosUnwindException
* Disassembling RtlUnwind shows this is true, except for
* the TargetEIP parameter, which is unused. There is
* a fourth parameter, that is used as the eax in the
* context.
*/
BOOL WINAPI RtlUnwind( PEXCEPTION_FRAME pestframe,
LPVOID unusedEIP,
PEXCEPTION_RECORD pexcrec,
DWORD contextEAX );
DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers);
__PTOP_EXCFILTER WINAPI SetUnhandledExceptionFilter(
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
#endif /* __WINE_EXCEPT_H */
......@@ -10,6 +10,7 @@
int KERN32_Init(void);
void SetLastError(DWORD error);
DWORD ErrnoToLastError(int errno_num);
void ExitProcess(DWORD exitcode);
/* Code page information.
*/
......
......@@ -25,6 +25,7 @@ typedef struct {
WORD CtlID;
LPLISTSTRUCT lpFirst;
HWND hSelf;
DWORD dwStyle; /* added for COMBOLBOX style faking */
HWND hParent;
HFONT hFont;
BOOL bRedrawFlag;
......
/*
* Message queues definitions
* Message definitions
*
* Copyright 1993 Alexandre Julliard
*/
#ifndef MESSAGE_H
#define MESSAGE_H
#ifndef __WINE_MESSAGE_H
#define __WINE_MESSAGE_H
#include "windows.h"
#ifndef WINELIB
#pragma pack(1)
#endif
/* Message as stored in the queue (contains the extraInfo field) */
typedef struct tagQMSG
{
DWORD extraInfo; /* Only in 3.1 */
MSG msg;
} QMSG;
typedef struct tagMESSAGEQUEUE
{
HANDLE next; /* 00 Next queue */
HTASK hTask; /* 02 hTask owning the queue */
WORD msgSize; /* 04 Size of messages in the queue */
WORD msgCount; /* 06 Number of waiting messages */
WORD nextMessage; /* 08 Next message to be retrieved */
WORD nextFreeMessage; /* 0a Next available slot in the queue */
WORD queueSize; /* 0c Size of the queue */
DWORD GetMessageTimeVal WINE_PACKED; /* 0e Value for GetMessageTime */
DWORD GetMessagePosVal WINE_PACKED; /* 12 Value for GetMessagePos */
WORD reserved1; /* 16 Unknown */
DWORD GetMessageExtraInfoVal; /* 18 Value for GetMessageExtraInfo */
WORD reserved2; /* 1c Unknown */
LPARAM lParam WINE_PACKED; /* 1e Next 4 values set by SendMessage */
WPARAM wParam; /* 22 */
UINT msg; /* 24 */
HWND hWnd; /* 26 */
DWORD SendMessageReturn; /* 28 Return value for SendMessage */
WORD wPostQMsg; /* 2c PostQuitMessage flag */
WORD wExitCode; /* 2e PostQuitMessage exit code */
WORD reserved3[3]; /* 30 Unknown */
WORD wWinVersion; /* 36 Expected Windows version */
HQUEUE InSendMessageHandle; /* 38 Queue of task that sent a message */
HTASK hSendingTask; /* 3a Handle of task that sent a message */
HTASK hPrevSendingTask; /* 3c Handle of previous sender */
WORD wPaintCount; /* 3e Number of WM_PAINT needed */
WORD wTimerCount; /* 40 Number of timers for this task */
WORD tempStatus; /* 42 State reset by GetQueueStatus */
WORD status; /* 44 Queue state */
WORD wakeMask; /* 46 Task wake-up mask */
WORD SendMsgReturnPtrs[3]; /* 48 Near ptr to return values (?) */
HANDLE hCurHook; /* 4e Current hook */
HANDLE hooks[WH_NB_HOOKS]; /* 50 Task hooks list */
WORD reserved4[3]; /* 68 Unknown */
QMSG messages[1]; /* 6e Queue messages */
} MESSAGEQUEUE;
#ifndef WINELIB
#pragma pack(4)
#endif
extern DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
extern void MSG_IncPaintCount( HANDLE hQueue );
extern void MSG_DecPaintCount( HANDLE hQueue );
extern void MSG_IncTimerCount( HANDLE hQueue );
extern void MSG_DecTimerCount( HANDLE hQueue );
extern void MSG_Synchronize();
extern BOOL MSG_WaitXEvent( LONG maxWait );
extern BOOL MSG_CreateSysMsgQueue( int size );
extern BOOL MSG_DeleteMsgQueue( HANDLE hQueue );
extern HTASK MSG_GetQueueTask( HANDLE hQueue );
extern void hardware_event( WORD message, WORD wParam, LONG lParam,
int xPos, int yPos, DWORD time, DWORD extraInfo );
extern BOOL MSG_GetHardwareMessage( LPMSG msg );
extern BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner,
short code, WORD flags, BOOL sendIdle );
#endif /* MESSAGE_H */
#endif /* __WINE_MESSAGE_H */
/*
* Message queues definitions
*
* Copyright 1993 Alexandre Julliard
*/
#ifndef __WINE_QUEUE_H
#define __WINE_QUEUE_H
#include "windows.h"
#ifndef WINELIB
#pragma pack(1)
#endif
/* Message as stored in the queue (contains the extraInfo field) */
typedef struct tagQMSG
{
DWORD extraInfo; /* Only in 3.1 */
MSG msg;
} QMSG;
typedef struct tagMESSAGEQUEUE
{
HQUEUE next; /* 00 Next queue */
HTASK hTask; /* 02 hTask owning the queue */
WORD msgSize; /* 04 Size of messages in the queue */
WORD msgCount; /* 06 Number of waiting messages */
WORD nextMessage; /* 08 Next message to be retrieved */
WORD nextFreeMessage; /* 0a Next available slot in the queue */
WORD queueSize; /* 0c Size of the queue */
DWORD GetMessageTimeVal WINE_PACKED; /* 0e Value for GetMessageTime */
DWORD GetMessagePosVal WINE_PACKED; /* 12 Value for GetMessagePos */
WORD reserved1; /* 16 Unknown */
DWORD GetMessageExtraInfoVal; /* 18 Value for GetMessageExtraInfo */
WORD reserved2; /* 1c Unknown */
LPARAM lParam WINE_PACKED; /* 1e Next 4 values set by SendMessage */
WPARAM wParam; /* 22 */
UINT msg; /* 24 */
HWND hWnd; /* 26 */
DWORD SendMessageReturn; /* 28 Return value for SendMessage */
WORD wPostQMsg; /* 2c PostQuitMessage flag */
WORD wExitCode; /* 2e PostQuitMessage exit code */
WORD reserved3[3]; /* 30 Unknown */
WORD wWinVersion; /* 36 Expected Windows version */
HQUEUE InSendMessageHandle; /* 38 Queue of task that sent a message */
HTASK hSendingTask; /* 3a Handle of task that sent a message */
HTASK hPrevSendingTask; /* 3c Handle of previous sender */
WORD wPaintCount; /* 3e Number of WM_PAINT needed */
WORD wTimerCount; /* 40 Number of timers for this task */
WORD tempStatus; /* 42 State reset by GetQueueStatus */
WORD status; /* 44 Queue state */
WORD wakeMask; /* 46 Task wake-up mask */
WORD SendMsgReturnPtrs[3]; /* 48 Near ptr to return values (?) */
HANDLE hCurHook; /* 4e Current hook */
HANDLE hooks[WH_NB_HOOKS]; /* 50 Task hooks list */
WORD reserved4[3]; /* 68 Unknown */
QMSG messages[1]; /* 6e Queue messages */
} MESSAGEQUEUE;
#ifndef WINELIB
#pragma pack(4)
#endif
extern void QUEUE_DumpQueue( HQUEUE hQueue );
extern void QUEUE_WalkQueues(void);
extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
extern void QUEUE_IncPaintCount( HQUEUE hQueue );
extern void QUEUE_DecPaintCount( HQUEUE hQueue );
extern void QUEUE_IncTimerCount( HQUEUE hQueue );
extern void QUEUE_DecTimerCount( HQUEUE hQueue );
extern BOOL QUEUE_CreateSysMsgQueue( int size );
extern BOOL QUEUE_DeleteMsgQueue( HQUEUE hQueue );
extern HTASK QUEUE_GetQueueTask( HQUEUE hQueue );
extern BOOL QUEUE_AddMsg( HQUEUE hQueue, MSG * msg, DWORD extraInfo );
extern int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND hwnd,
int first, int last );
extern void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos );
extern void hardware_event( WORD message, WORD wParam, LONG lParam,
int xPos, int yPos, DWORD time, DWORD extraInfo );
#endif /* __WINE_QUEUE_H */
......@@ -5,18 +5,16 @@
#ifndef __WINE_SPY_H
#define __WINE_SPY_H
#define SPY_DISPATCHMESSAGE 0x0099
#define SPY_SENDMESSAGE 0x0100
#define SPY_DEFWNDPROC 0x0101
#define SPY_DISPATCHMESSAGE 0x0100
#define SPY_SENDMESSAGE 0x0101
#define SPY_DEFWNDPROC 0x0102
#define SPY_RESULT_OK 0x0000
#define SPY_RESULT_INVALIDHWND 0x0001
#define SPY_MAX_MSGNUM WM_USER
#define SPY_MAX_INDENTLEVEL 64
extern void EnterSpyMessage( int, HWND, WORD, WORD, LONG);
extern void ExitSpyMessage( int, HWND, WORD, LONG);
extern void SpyInit( void);
extern void SPY_EnterMessage( int iFlag, HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam );
extern void SPY_ExitMessage( int iFlag, HWND hwnd, UINT msg, LRESULT lReturn );
extern int SPY_Init(void);
#endif /* __WINE_SPY_H */
......@@ -73,7 +73,7 @@ typedef struct
WORD version; /* Expected Windows version */
HANDLE hInstance; /* Instance handle for this task */
HMODULE hModule; /* Module handle */
HANDLE hQueue; /* Selector of task message queue */
HQUEUE hQueue; /* Selector of task message queue */
HTASK hParent; /* Selector of TDB of parent task */
WORD signal_flags; /* Flags related to signal handler */
DWORD sighandler WINE_PACKED; /* Signal handler */
......
......@@ -75,6 +75,8 @@ typedef struct tagWND
/* Window functions */
extern WND *WIN_FindWndPtr( HWND hwnd );
extern void WIN_DumpWindow( HWND hwnd );
extern void WIN_WalkWindows( HWND hwnd, int indent );
extern Window WIN_GetXWindow( HWND hwnd );
extern BOOL WIN_UnlinkWindow( HWND hwnd );
extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter );
......
......@@ -2222,6 +2222,14 @@ typedef struct
typedef COMPAREITEMSTRUCT NEAR* PCOMPAREITEMSTRUCT;
typedef COMPAREITEMSTRUCT FAR* LPCOMPAREITEMSTRUCT;
/* WM_KEYUP/DOWN/CHAR HIWORD(lParam) flags */
#define KF_EXTENDED 0x0100
#define KF_DLGMODE 0x0800
#define KF_MENUMODE 0x1000
#define KF_ALTDOWN 0x2000
#define KF_REPEAT 0x4000
#define KF_UP 0x8000
/* Virtual key codes */
#define VK_LBUTTON 0x01
#define VK_RBUTTON 0x02
......@@ -2947,7 +2955,7 @@ WORD GetSystemPaletteUse(HDC);
VOID GetSystemTime(LPSYSTEMTIME); /* Win32 */
DWORD GetTabbedTextExtent(HDC,LPSTR,int,int,LPINT);
HINSTANCE GetTaskDS(void);
HGLOBAL GetTaskQueue(HTASK);
HQUEUE GetTaskQueue(HTASK);
BYTE GetTempDrive(BYTE);
INT GetTempFileName(BYTE,LPCSTR,UINT,LPSTR);
WORD GetTextAlign(HDC);
......@@ -3122,7 +3130,7 @@ BOOL Polygon(HDC,LPPOINT,int);
BOOL Polyline(HDC,LPPOINT,int);
BOOL PostAppMessage(HANDLE,WORD,WORD,LONG);
BOOL PostMessage(HWND,WORD,WORD,LONG);
void PostQuitMessage(int);
void PostQuitMessage(INT);
WORD PrestoChangoSelector(WORD,WORD);
void ProfClear(void);
void ProfFinish(void);
......@@ -3244,7 +3252,7 @@ void SetSysColors(int,LPINT,COLORREF*);
HWND SetSysModalWindow(HWND);
WORD SetSystemPaletteUse(HDC,WORD);
WORD SetSystemTimer(HWND,WORD,WORD,FARPROC);
HGLOBAL SetTaskQueue(HTASK,HGLOBAL);
HQUEUE SetTaskQueue(HTASK,HQUEUE);
WORD SetTextAlign(HDC,WORD);
short SetTextCharacterExtra(HDC,short);
DWORD SetTextColor(HDC,DWORD);
......
......@@ -22,7 +22,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include "dialog.h"
#include "directory.h"
#include "drive.h"
#include "message.h"
#include "queue.h"
#include "syscolor.h"
#include "sysmetrics.h"
#include "gdi.h"
......@@ -54,7 +54,8 @@ int MAIN_Init(void)
/* Load the configuration file */
if (!PROFILE_LoadWineIni()) return 0;
SpyInit();
/* Initialize message spying */
if (!SPY_Init()) return 0;
#ifndef WINELIB
/* Initialize relay code */
......@@ -120,7 +121,10 @@ int MAIN_Init(void)
/* Create system message queue */
queueSize = GetProfileInt( "windows", "TypeAhead", 120 );
if (!MSG_CreateSysMsgQueue( queueSize )) return 0;
if (!QUEUE_CreateSysMsgQueue( queueSize )) return 0;
/* Set double click time */
SetDoubleClickTime( GetProfileInt( "windows", "DoubleClickSpeed", 452 ) );
return 1;
}
......
......@@ -22,8 +22,6 @@
#if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
char * cstack[4096];
#endif
struct sigaction segv_act;
struct sigaction usr2_act;
#ifdef linux
extern void ___sig_restore();
......@@ -56,27 +54,32 @@ static void win_fault(int signal, void *siginfo, ucontext_t *context)
static void win_fault(int signal, int code, struct sigcontext *context)
{
#endif
if (signal != SIGTRAP)
if (signal == SIGTRAP)
{
/* If SIGTRAP not caused by breakpoint or single step
don't jump into the debugger */
if (!(EFL_reg(context) & STEP_FLAG))
{
DBG_ADDR addr;
addr.seg = CS_reg(context);
addr.off = EIP_reg(context) - 1;
if (DEBUG_FindBreakpoint(&addr) == -1) return;
}
}
else if (signal != SIGHUP)
{
if (CS_reg(context) == WINE_CODE_SELECTOR)
{
fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)."
" Please debug\n",
" Please debug.\n",
CS_reg(context), EIP_reg(context) );
}
else if (INSTR_EmulateInstruction( context )) return;
fprintf( stderr,"In win_fault %x:%lx\n",
CS_reg(context), EIP_reg(context) );
}
/* If SIGTRAP not caused by breakpoint or single step
don't jump into the debugger */
if ((signal == SIGTRAP) && !(EFL_reg(context) & STEP_FLAG))
{
DBG_ADDR addr;
addr.seg = CS_reg(context);
addr.off = EIP_reg(context) - 1;
if (DEBUG_FindBreakpoint(&addr) == -1) return;
else
{
if (INSTR_EmulateInstruction( context )) return;
fprintf( stderr, "Segmentation fault in Windows program %x:%lx.\n",
CS_reg(context), EIP_reg(context) );
}
}
XUngrabPointer(display, CurrentTime);
......@@ -85,131 +88,104 @@ static void win_fault(int signal, int code, struct sigcontext *context)
wine_debug( signal, context ); /* Enter our debugger */
}
void init_wine_signals(void)
/**********************************************************************
* SIGNAL_SetHandler
*/
static void SIGNAL_SetHandler( int sig, void (*func)() )
{
extern void stop_wait(int a);
int ret;
struct sigaction sig_act;
#ifdef linux
segv_act.sa_handler = (__sighandler_t) win_fault;
/* Point to the top of the stack, minus 4 just in case, and make
it aligned */
segv_act.sa_restorer =
(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
/* Point to the top of the stack, minus 4 just in case, and make
it aligned */
wine_sigaction(SIGSEGV, &segv_act, NULL);
wine_sigaction(SIGILL, &segv_act, NULL);
wine_sigaction(SIGFPE, &segv_act, NULL);
#ifdef SIGBUS
wine_sigaction(SIGBUS, &segv_act, NULL);
#endif
wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
#ifdef CONFIG_IPC
usr2_act.sa_restorer= segv_act.sa_restorer;
usr2_act.sa_handler = (__sighandler_t) stop_wait;
wine_sigaction(SIGUSR2, &usr2_act, NULL);
#endif /* CONFIG_IPC */
sig_act.sa_handler = func;
/* Point to the top of the stack, minus 4 just in case, and make
it aligned */
sig_act.sa_restorer =
(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
ret = wine_sigaction( sig, &sig_act, NULL );
#endif /* linux */
#if defined(__NetBSD__) || defined(__FreeBSD__)
sigset_t sig_mask;
struct sigaltstack ss;
sig_act.sa_handler = func;
sig_act.sa_flags = SA_ONSTACK;
sig_act.sa_mask = sig_mask;
ret = sigaction( sig, &sig_act, NULL );
#endif /* __FreeBSD__ || __NetBSD__ */
#if defined (__svr4__)
sig_act.sa_handler = func;
sig_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
sig_act.sa_mask = sig_mask;
ret = sigaction( sig, &sig_act, NULL );
#endif /* __svr4__ */
if (ret < 0)
{
perror( "sigaction" );
exit(1);
}
}
/**********************************************************************
* init_wine_signals
*/
void init_wine_signals(void)
{
extern void stop_wait(int a);
#if defined(__NetBSD__) || defined(__FreeBSD__)
sigset_t sig_mask;
struct sigaltstack ss;
#if !defined (__FreeBSD__)
if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
#else
if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
#endif
fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
MINSIGSTKSZ);
exit(1);
}
ss.ss_size = MINSIGSTKSZ;
ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) < 0) {
perror("sigstack");
exit(1);
}
sigemptyset(&sig_mask);
segv_act.sa_handler = (void (*)) win_fault;
segv_act.sa_flags = SA_ONSTACK;
segv_act.sa_mask = sig_mask;
if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
perror("sigaction: SIGBUS");
exit(1);
}
segv_act.sa_handler = (void (*)) win_fault;
segv_act.sa_flags = SA_ONSTACK;
segv_act.sa_mask = sig_mask;
if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
perror("sigaction: SIGSEGV");
exit(1);
}
segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
segv_act.sa_flags = SA_ONSTACK;
segv_act.sa_mask = sig_mask;
if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
perror("sigaction: SIGTRAP");
exit(1);
}
#ifdef CONFIG_IPC
usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */
usr2_act.sa_flags = SA_ONSTACK;
usr2_act.sa_mask = sig_mask;
if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) {
perror("sigaction: SIGUSR2");
exit(1);
}
#endif /* CONFIG_IPC */
fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
MINSIGSTKSZ);
exit(1);
}
ss.ss_size = MINSIGSTKSZ;
ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) < 0) {
perror("sigstack");
exit(1);
}
sigemptyset(&sig_mask);
#endif /* __FreeBSD__ || __NetBSD__ */
#if defined (__svr4__)
sigset_t sig_mask;
struct sigaltstack ss;
if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
SIGSTKSZ);
exit(1);
}
ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) < 0) {
perror("sigstack");
exit(1);
}
sigemptyset(&sig_mask);
segv_act.sa_handler = (void (*)) win_fault;
segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
segv_act.sa_mask = sig_mask;
if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
perror("sigaction: SIGBUS");
exit(1);
}
segv_act.sa_handler = (void (*)) win_fault;
segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
segv_act.sa_mask = sig_mask;
if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
perror("sigaction: SIGSEGV");
exit(1);
}
sigset_t sig_mask;
struct sigaltstack ss;
if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
SIGSTKSZ);
exit(1);
}
ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) < 0) {
perror("sigstack");
exit(1);
}
sigemptyset(&sig_mask);
#endif /* __svr4__ */
segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
segv_act.sa_mask = sig_mask;
if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
perror("sigaction: SIGTRAP");
exit(1);
}
SIGNAL_SetHandler( SIGSEGV, (void (*)())win_fault );
SIGNAL_SetHandler( SIGILL, (void (*)())win_fault );
SIGNAL_SetHandler( SIGFPE, (void (*)())win_fault );
SIGNAL_SetHandler( SIGTRAP, (void (*)())win_fault ); /* For debugger */
SIGNAL_SetHandler( SIGHUP, (void (*)())win_fault ); /* For forced break */
#ifdef SIGBUS
SIGNAL_SetHandler( SIGBUS, (void (*)())win_fault );
#endif
#ifdef CONFIG_IPC
usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */
usr2_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
usr2_act.sa_mask = sig_mask;
if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) {
perror("sigaction: SIGUSR2");
exit(1);
}
#endif /* CONFIG_IPC */
#endif /* __svr4__ */
SIGNAL_SetHandler( SIGUSR2, (void (*)())stop_wait ); /* For IPC */
#endif
}
#endif /* ifndef WINELIB */
......@@ -16,11 +16,11 @@
#include "debugger.h"
#include "global.h"
#include "instance.h"
#include "message.h"
#include "miscemu.h"
#include "module.h"
#include "neexe.h"
#include "options.h"
#include "queue.h"
#include "selectors.h"
#include "toolhelp.h"
#include "stddebug.h"
......@@ -583,7 +583,7 @@ static void TASK_DeleteTask( HTASK hTask )
/* Free the message queue */
MSG_DeleteMsgQueue( pTask->hQueue );
QUEUE_DeleteMsgQueue( pTask->hQueue );
/* Free the selector aliases */
......@@ -988,9 +988,9 @@ HANDLE GetCodeHandle( FARPROC proc )
/***********************************************************************
* SetTaskQueue (KERNEL.34)
*/
HGLOBAL SetTaskQueue( HANDLE hTask, HGLOBAL hQueue )
HQUEUE SetTaskQueue( HANDLE hTask, HQUEUE hQueue )
{
HGLOBAL hPrev;
HQUEUE hPrev;
TDB *pTask;
if (!hTask) hTask = hCurrentTask;
......@@ -1004,7 +1004,7 @@ HGLOBAL SetTaskQueue( HANDLE hTask, HGLOBAL hQueue )
/***********************************************************************
* GetTaskQueue (KERNEL.35)
*/
HGLOBAL GetTaskQueue( HANDLE hTask )
HQUEUE GetTaskQueue( HANDLE hTask )
{
TDB *pTask;
......
......@@ -194,8 +194,8 @@ _LoadKey(HKEY hKey,char *from)
f=fopen(from,"r");
if (f==NULL) {
perror("fopen-registry-read");
return;
dprintf_reg(stddeb,"fopen-registry-read");
return;
}
switch ((DWORD)hKey) {
case HKEY_CLASSES_ROOT:
......
/*
static char RCSId[] = "$Id: user.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
*/
* Misc. USER functions
*
* Copyright 1993 Robert J. Amstadt
*/
#include <stdio.h>
#include <stdlib.h>
#include "windows.h"
#include "gdi.h"
#include "user.h"
#include "win.h"
#include "message.h"
#include "toolhelp.h"
#define USER_HEAP_SIZE 0x10000
......@@ -64,26 +65,6 @@ BOOL SystemHeapInfo( SYSHEAPINFO *pHeapInfo )
/***********************************************************************
* TimerCount (TOOLHELP.80)
*/
BOOL TimerCount( TIMERINFO *pTimerInfo )
{
/* FIXME
* In standard mode, dwmsSinceStart = dwmsThisVM
*
* I tested this, under Windows in enhanced mode, and
* if you never switch VM (ie start/stop DOS) these
* values should be the same as well.
*
* Also, Wine should adjust for the hardware timer
* to reduce the amount of error to ~1ms.
* I can't be bothered, can you?
*/
pTimerInfo->dwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount();
return TRUE;
}
/***********************************************************************
* USER_HeapInit
*/
BOOL USER_HeapInit(void)
......@@ -96,6 +77,27 @@ BOOL USER_HeapInit(void)
#endif
/***********************************************************************
* TimerCount (TOOLHELP.80)
*/
BOOL TimerCount( TIMERINFO *pTimerInfo )
{
/* FIXME
* In standard mode, dwmsSinceStart = dwmsThisVM
*
* I tested this, under Windows in enhanced mode, and
* if you never switch VM (ie start/stop DOS) these
* values should be the same as well.
*
* Also, Wine should adjust for the hardware timer
* to reduce the amount of error to ~1ms.
* I can't be bothered, can you?
*/
pTimerInfo->dwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount();
return TRUE;
}
/**********************************************************************
* USER_InitApp
*/
......
......@@ -7,6 +7,7 @@ C_SRCS = \
console.c \
environment.c \
error.c \
except.c \
file.c \
gdi32.c \
heap.c \
......
/*
* Win32 exception functions
*
* Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl)
*
* Notes:
* What really happens behind the scenes of those new
* __try{...}__except(..){....} and
* __try{...}__finally{...}
* statements is simply not documented by Microsoft. There could be different
* reasons for this:
* One reason could be that they try to hide the fact that exception
* handling in Win32 looks almost the same as in OS/2 2.x.
* Another reason could be that Microsoft does not want others to write
* binary compatible implementations of the Win32 API (like us).
*
* Whatever the reason, THIS SUCKS!! Ensuring portabilty or future
* compatability may be valid reasons to keep some things undocumented.
* But exception handling is so basic to Win32 that it should be
* documented!
*
* Fixmes:
* -Most functions need better parameter checking.
* -I do not know how to handle exceptions within an exception handler.
* or what is done when ExceptionNestedException is returned from an
* exception handler
* -Real exceptions are not yet implemented. only the exception functions
* are implemented. A real implementation needs some new code in
* loader/signal.c. There would also be a need for showing debugging
* information in UnhandledExceptionFilter.
*
*/
#ifndef WINELIB
#include <stdio.h>
#include "windows.h"
#include "winerror.h"
#include "kernel32.h"
#include "stddebug.h"
#include "debug.h"
#include "except.h"
WINAPI DWORD KERNEL32_537(PEXCEPTION_POINTERS ptrs);
LPTOP_LEVEL_EXCEPTION_FILTER pTopExcHandler=
(LPTOP_LEVEL_EXCEPTION_FILTER) KERNEL32_537;
/*
* EXC_RtlUnwind
*
* This function is undocumented. This is the general idea of
* RtlUnwind, though. Note that error handling is not yet implemented
*
*/
void EXC_RtlUnwind(PEXCEPTION_FRAME pEndFrame,PVOID unusedEip,
PEXCEPTION_RECORD pRecord, DWORD returnEax,
PCONTEXT pcontext)
{
EXCEPTION_RECORD record;
DWORD dispatch;
int retval;
pcontext->Eax=returnEax;
/* build an exception record, if we do not have one */
if(!pRecord)
{
record.ExceptionCode= 0xC0000026; /* invalid disposition */
record.ExceptionFlags= 0;
record.ExceptionRecord= NULL;
record.ExceptionAddress=(PVOID) pcontext->Eip;
record.NumberParameters= 0;
pRecord=&record;
}
if(pEndFrame)
pRecord->ExceptionFlags|=EH_UNWINDING;
else
pRecord->ExceptionFlags|=EH_UNWINDING | EH_EXIT_UNWIND;
/* get chain of exception frames */
while((TebExceptionFrame!=NULL)&&
(TebExceptionFrame!=((void *)-1)) &&
(TebExceptionFrame!=pEndFrame))
{
dprintf_win32(stddeb,"calling exception handler at 0x%x\n",
(int) TebExceptionFrame->Handler);
dispatch=0;
retval=TebExceptionFrame->Handler(pRecord, TebExceptionFrame,
pcontext, &dispatch);
dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n",
retval, (int) dispatch);
if(retval==ExceptionCollidedUnwind)
TebExceptionFrame=(PVOID) dispatch;
else if(TebExceptionFrame!=pEndFrame)
TebExceptionFrame=TebExceptionFrame->Prev;
else
break;
}
}
/*
* EXC_RaiseException
*
*/
VOID EXC_RaiseException(DWORD dwExceptionCode,
DWORD dwExceptionFlags,
DWORD cArguments,
const LPDWORD lpArguments,
PCONTEXT pcontext)
{
PEXCEPTION_FRAME pframe;
EXCEPTION_RECORD record;
DWORD dispatch; /* is this used in raising exceptions ?? */
int retval;
int i;
/* compose an exception record */
record.ExceptionCode = dwExceptionCode;
record.ExceptionFlags = dwExceptionFlags;
record.ExceptionRecord = NULL;
record.NumberParameters = cArguments;
record.ExceptionAddress = (PVOID) pcontext->Eip;
for(i=0;i<cArguments;i++)
record.ExceptionInformation[i]=lpArguments[i];
/* get chain of exception frames */
retval=ExceptionContinueSearch;
pframe=TebExceptionFrame;
while((pframe!=NULL)&&(pframe!=((void *)0xFFFFFFFF)))
{
dprintf_win32(stddeb,"calling exception handler at 0x%x\n",
(int) pframe->Handler);
dispatch=0;
retval=pframe->Handler(&record,pframe,pcontext,&dispatch);
dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n",
retval, (int) dispatch);
if(retval==ExceptionContinueExecution)
break;
pframe=pframe->Prev;
}
if(retval!=ExceptionContinueExecution)
{
retval=EXC_CallUnhandledExceptionFilter(&record,pcontext);
if(retval!=EXCEPTION_CONTINUE_EXECUTION)
{
dprintf_win32(stddeb,"no handler wanted to handle "
"the exception, exiting\n" );
ExitProcess(dwExceptionCode); /* what status should be used here ? */
}
}
}
/*******************************************************************
* UnhandledExceptionFilter (KERNEL32.537)
*
* This is the unhandled exception code.
* Actually, this should show up a dialog box, with all kinds of
* fancy debugging information. It does nothing now!
*/
DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
{
PEXCEPTION_RECORD pRecord;
PCONTEXT pContext;
pRecord=epointers->ExceptionRecord;
pContext=epointers->ContextRecord;
if(pRecord->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND) )
{
dprintf_win32(stddeb,"UnhandledExceptionFilter: exiting\n");
ExitProcess(pRecord->ExceptionCode);
}
else
{
RtlUnwind(0,pRecord,0,-1 );
}
/*
* This is just to avoid a warning, code should not get here
* if it does, EXC_RaiseException will terminate it.
*/
return EXCEPTION_CONTINUE_SEARCH;
}
/*************************************************************
* SetUnhandledExceptionFilter (KERNEL32.516)
*
*
*/
WINAPI LPTOP_LEVEL_EXCEPTION_FILTER
SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER efilter)
{
pTopExcHandler=efilter;
return efilter;
}
#endif /* WINELIB */
......@@ -16,19 +16,6 @@ at a later date. */
#include "debug.h"
/***********************************************************************
* RaiseException (KERNEL32.??)
*
* Stub function - does not allow exceptions to be caught yet
*/
WINAPI VOID RaiseException(DWORD dwExceptionCode,
DWORD dwExceptionFlags,
DWORD cArguments,
const DWORD * lpArguments)
{
ExitProcess(dwExceptionCode); /* what status should be used here ? */
}
/***********************************************************************
* GetProcAddress (KERNEL32.257)
*
*/
......
......@@ -21,6 +21,7 @@ C_SRCS = \
nonclient.c \
painting.c \
property.c \
queue.c \
scroll.c \
syscolor.c \
sysmetrics.c \
......
......@@ -23,6 +23,72 @@ static HCLASS firstClass = 0;
/***********************************************************************
* CLASS_DumpClass
*
* Dump the content of a class structure to stderr.
*/
void CLASS_DumpClass( HCLASS hClass )
{
CLASS *ptr;
char className[80];
int i;
if (!(ptr = CLASS_FindClassPtr( hClass )))
{
fprintf( stderr, "%04x is not a class handle\n", hClass );
return;
}
GlobalGetAtomName( ptr->atomName, className, sizeof(className) );
fprintf( stderr, "Class %04x:\n", hClass );
fprintf( stderr,
"next=%04x name=%04x '%s' style=%04x wndProc=%08lx\n"
"inst=%04x hdce=%04x icon=%04x cursor=%04x bkgnd=%04x\n"
"clsExtra=%d winExtra=%d #windows=%d\n",
ptr->hNext, ptr->atomName, className, ptr->wc.style,
(DWORD)ptr->wc.lpfnWndProc, ptr->wc.hInstance, ptr->hdce,
ptr->wc.hIcon, ptr->wc.hCursor, ptr->wc.hbrBackground,
ptr->wc.cbClsExtra, ptr->wc.cbWndExtra, ptr->cWindows );
if (ptr->wc.cbClsExtra)
{
fprintf( stderr, "extra bytes:" );
for (i = 0; i < ptr->wc.cbClsExtra; i++)
fprintf( stderr, " %02x", *((BYTE *)ptr->wExtra+i) );
fprintf( stderr, "\n" );
}
fprintf( stderr, "\n" );
}
/***********************************************************************
* CLASS_WalkClasses
*
* Walk the class list and print each class on stderr.
*/
void CLASS_WalkClasses(void)
{
HCLASS hClass = firstClass;
CLASS *ptr;
char className[80];
fprintf( stderr, "Class Name Style WndProc\n" );
while (hClass)
{
if (!(ptr = CLASS_FindClassPtr( hClass )))
{
fprintf( stderr, "*** Bad class %04x in list\n", hClass );
return;
}
GlobalGetAtomName( ptr->atomName, className, sizeof(className) );
fprintf( stderr, "%04x %-20.20s %04x %08lx\n",
hClass, className, ptr->wc.style, (DWORD)ptr->wc.lpfnWndProc);
hClass = ptr->hNext;
}
fprintf( stderr, "\n" );
}
/***********************************************************************
* CLASS_FindClassByName
*
* Return a handle and a pointer to the class.
......
......@@ -152,7 +152,7 @@ static HRGN DCE_ClipWindows( HWND hwndStart, HWND hwndEnd,
if (!hwndStart) return hrgn;
if (!(hrgnNew = CreateRectRgn( 0, 0, 0, 0 )))
{
if (hrgn) DeleteObject( hrgn );
DeleteObject( hrgn );
return 0;
}
for (; hwndStart != hwndEnd; hwndStart = wndPtr->hwndNext)
......@@ -165,10 +165,10 @@ static HRGN DCE_ClipWindows( HWND hwndStart, HWND hwndEnd,
wndPtr->rectWindow.bottom + yoffset );
if (!CombineRgn( hrgn, hrgn, hrgnNew, RGN_DIFF )) break;
}
DeleteObject( hrgnNew );
if (hwndStart != hwndEnd) /* something went wrong */
{
DeleteObject( hrgnNew );
if (hrgn) DeleteObject( hrgn );
DeleteObject( hrgn );
return 0;
}
return hrgn;
......
......@@ -54,7 +54,7 @@ LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
int len;
WND * wndPtr = WIN_FindWndPtr( hwnd );
EnterSpyMessage(SPY_DEFWNDPROC,hwnd,msg,wParam,lParam);
SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
switch(msg)
{
......
......@@ -6,8 +6,11 @@
*/
#include <ctype.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
......@@ -16,9 +19,9 @@
#include "windows.h"
#include "win.h"
#include "class.h"
#include "message.h"
#include "clipboard.h"
#include "options.h"
#include "queue.h"
#include "winpos.h"
#include "registers.h"
#include "stackframe.h"
......@@ -305,6 +308,11 @@ static void EVENT_key( XKeyEvent *event )
dprintf_key(stddeb,"WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n",
keysym, count, Str[0], Str);
/* Ctrl-Alt-Return enters the debugger */
if ((keysym == XK_Return) && (event->type == KeyPress) &&
(event->state & ControlMask) && (event->state & Mod1Mask))
kill( getpid(), SIGHUP );
xkey = LOWORD(keysym);
key_type = HIBYTE(xkey);
key = LOBYTE(xkey);
......@@ -348,7 +356,7 @@ static void EVENT_key( XKeyEvent *event )
KeyStateTable[vkey] ^= 0x80;
KeyStateTable[vkey] |= 0x01;
keylp.lp1.count = 1;
keylp.lp1.code = LOBYTE(event->keycode);
keylp.lp1.code = LOBYTE(event->keycode) - 8;
keylp.lp1.extended = (extended ? 1 : 0);
keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
keylp.lp1.previous = (KeyDown ? 0 : 1);
......@@ -379,7 +387,7 @@ static void EVENT_key( XKeyEvent *event )
if (vkey == VK_MENU) ALTKeyState = FALSE;
KeyStateTable[vkey] &= 0xf0;
keylp.lp1.count = 1;
keylp.lp1.code = LOBYTE(event->keycode);
keylp.lp1.code = LOBYTE(event->keycode) - 8;
keylp.lp1.extended = (extended ? 1 : 0);
keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
keylp.lp1.previous = 1;
......
......@@ -15,7 +15,7 @@
*/
#include "hook.h"
#include "message.h"
#include "queue.h"
#include "user.h"
#include "stddebug.h"
#include "debug.h"
......
......@@ -8,7 +8,7 @@
#include <X11/Xlib.h>
#include "win.h"
#include "message.h"
#include "queue.h"
#include "gdi.h"
#include "stddebug.h"
/* #define DEBUG_WIN */
......@@ -32,7 +32,7 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps )
if (!(hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ))) return 0;
if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT))
MSG_DecPaintCount( wndPtr->hmemTaskQ );
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
wndPtr->hrgnUpdate = 0;
wndPtr->flags &= ~(WIN_NEEDS_BEGINPAINT | WIN_INTERNAL_PAINT);
......@@ -168,7 +168,7 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
else /* No update region yet */
{
if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
MSG_IncPaintCount( wndPtr->hmemTaskQ );
QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
if (hrgnUpdate)
{
wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
......@@ -206,7 +206,7 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
}
if (!wndPtr->hrgnUpdate) /* No more update region */
if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
MSG_DecPaintCount( wndPtr->hmemTaskQ );
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
}
if (flags & RDW_NOFRAME) wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
......@@ -217,13 +217,13 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
if (flags & RDW_INTERNALPAINT)
{
if (!wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT))
MSG_IncPaintCount( wndPtr->hmemTaskQ );
QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
wndPtr->flags |= WIN_INTERNAL_PAINT;
}
else if (flags & RDW_NOINTERNALPAINT)
{
if (!wndPtr->hrgnUpdate && (wndPtr->flags & WIN_INTERNAL_PAINT))
MSG_DecPaintCount( wndPtr->hmemTaskQ );
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
wndPtr->flags &= ~WIN_INTERNAL_PAINT;
}
......
This diff is collapsed. Click to expand it.
......@@ -5,7 +5,7 @@
*/
#include "windows.h"
#include "message.h"
#include "queue.h"
#include "stddebug.h"
/* #define DEBUG_TIMER */
#include "debug.h"
......@@ -173,7 +173,7 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout,
dprintf_timer(stddeb, "Timer added: %p, "NPFMT", %04x, %04x, %08lx\n",
pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc);
TIMER_InsertTimer( pTimer );
MSG_IncTimerCount( GetTaskQueue(0) );
QUEUE_IncTimerCount( GetTaskQueue(0) );
if (!id)
return TRUE;
else
......@@ -207,7 +207,7 @@ static BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys )
pTimer->timeout = 0;
pTimer->proc = 0;
TIMER_RemoveTimer( pTimer );
MSG_DecTimerCount( GetTaskQueue(0) );
QUEUE_DecTimerCount( GetTaskQueue(0) );
return TRUE;
}
......
......@@ -15,8 +15,8 @@
#include "sysmetrics.h"
#include "cursoricon.h"
#include "event.h"
#include "message.h"
#include "nonclient.h"
#include "queue.h"
#include "winpos.h"
#include "color.h"
#include "shm_main_blk.h"
......@@ -52,6 +52,97 @@ WND * WIN_FindWndPtr( HWND hwnd )
/***********************************************************************
* WIN_DumpWindow
*
* Dump the content of a window structure to stderr.
*/
void WIN_DumpWindow( HWND hwnd )
{
CLASS *classPtr;
WND *ptr;
char className[80];
int i;
if (!(ptr = WIN_FindWndPtr( hwnd )))
{
fprintf( stderr, "%04x is not a window handle\n", hwnd );
return;
}
if (!GetClassName( hwnd, className, sizeof(className ) ))
strcpy( className, "#NULL#" );
fprintf( stderr, "Window %04x:\n", hwnd );
fprintf( stderr,
"next=%04x child=%04x parent=%04x owner=%04x class=%04x '%s'\n"
"inst=%04x taskQ=%04x updRgn=%04x active=%04x hdce=%04x idmenu=%04x\n"
"style=%08lx exstyle=%08lx wndproc=%08lx text=%04x '%s'\n"
"client=%d,%d-%d,%d window=%d,%d-%d,%d iconpos=%d,%d maxpos=%d,%d\n"
"sysmenu=%04x flags=%04x props=%04x vscroll=%04x hscroll=%04x\n",
ptr->hwndNext, ptr->hwndChild, ptr->hwndParent, ptr->hwndOwner,
ptr->hClass, className, ptr->hInstance, ptr->hmemTaskQ,
ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu,
ptr->dwStyle, ptr->dwExStyle, (DWORD)ptr->lpfnWndProc, ptr->hText,
ptr->hText ? (char*)USER_HEAP_LIN_ADDR(ptr->hText) : "",
ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
ptr->flags, ptr->hProp, ptr->hVScroll, ptr->hHScroll );
if ((classPtr = CLASS_FindClassPtr( ptr->hClass )) &&
classPtr->wc.cbWndExtra)
{
fprintf( stderr, "extra bytes:" );
for (i = 0; i < classPtr->wc.cbWndExtra; i++)
fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
fprintf( stderr, "\n" );
}
fprintf( stderr, "\n" );
}
/***********************************************************************
* WIN_WalkWindows
*
* Walk the windows tree and print each window on stderr.
*/
void WIN_WalkWindows( HWND hwnd, int indent )
{
WND *ptr;
CLASS *classPtr;
char className[80];
if (!hwnd) hwnd = hwndDesktop;
if (!indent) /* first time around */
fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
"hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
while (hwnd)
{
fprintf( stderr, "%*s%04x%*s", indent, "", hwnd, 13-indent, "" );
if (!(ptr = WIN_FindWndPtr( hwnd )))
{
fprintf( stderr, "*** Invalid window handle\n" );
return;
}
if (!(classPtr = CLASS_FindClassPtr( ptr->hClass ))) strcpy( className, "#NULL#" );
else GlobalGetAtomName( classPtr->atomName, className, sizeof(className) );
fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %04x:%04x\n",
(DWORD)ptr, ptr->hmemTaskQ, className,
(unsigned) ptr->dwStyle,
HIWORD(ptr->lpfnWndProc),
LOWORD(ptr->lpfnWndProc));
if (ptr->hwndChild) WIN_WalkWindows( ptr->hwndChild, indent+1 );
hwnd = ptr->hwndNext;
}
}
/***********************************************************************
* WIN_GetXWindow
*
* Return the X window associated to a window.
......@@ -209,7 +300,7 @@ static void WIN_DestroyWindow( HWND hwnd )
if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
{
if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
MSG_DecPaintCount( wndPtr->hmemTaskQ );
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
}
if (!(wndPtr->dwStyle & WS_CHILD))
{
......
......@@ -12,6 +12,7 @@
#include "event.h"
#include "hook.h"
#include "message.h"
#include "queue.h"
#include "stackframe.h"
#include "winpos.h"
#include "nonclient.h"
......@@ -632,12 +633,8 @@ BOOL SetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
BOOL ACTIVATEAPP_callback(HWND hWnd, LPARAM lParam)
{
ACTIVATESTRUCT *lpActStruct = (ACTIVATESTRUCT*)lParam;
WND *wndPtr = WIN_FindWndPtr( hWnd );
if( !wndPtr || hWnd == GetDesktopWindow()) return 1;
if( MSG_GetQueueTask(wndPtr->hmemTaskQ) != lpActStruct->hTaskSendTo )
return 1;
if (GetWindowTask(hWnd) != lpActStruct->hTaskSendTo) return 1;
SendMessage( hWnd, WM_ACTIVATEAPP, lpActStruct->wFlag,
(LPARAM)((lpActStruct->hWindowTask)?lpActStruct->hWindowTask:0));
......@@ -742,10 +739,10 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus )
/* send WM_ACTIVATEAPP if necessary */
if (hActiveQ != wndPtr->hmemTaskQ)
{
HTASK hT = MSG_GetQueueTask( hActiveQ );
HTASK hT = QUEUE_GetQueueTask( hActiveQ );
actStruct.wFlag = 0; /* deactivate */
actStruct.hWindowTask = MSG_GetQueueTask(wndPtr->hmemTaskQ);
actStruct.hWindowTask = QUEUE_GetQueueTask(wndPtr->hmemTaskQ);
actStruct.hTaskSendTo = hT;
/* send WM_ACTIVATEAPP to top-level windows
......@@ -755,7 +752,7 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus )
actStruct.wFlag = 1; /* activate */
actStruct.hWindowTask = hT;
actStruct.hTaskSendTo = MSG_GetQueueTask( wndPtr->hmemTaskQ );
actStruct.hTaskSendTo = QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
EnumWindows( enumCallback , (LPARAM)&actStruct );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment