From cef51849f76448bd08326206e8fc03a2599b1997 Mon Sep 17 00:00:00 2001 From: Richard Frith-MacDonald Date: Thu, 6 Mar 2008 13:48:40 +0000 Subject: [PATCH] fix for segementation violation accessing window of another app git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@26226 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 11 ++++++++ Headers/win32/WIN32Server.h | 7 +++-- Source/win32/WIN32Server.m | 54 ++++++++++++++++++------------------- Source/win32/w32_movesize.m | 32 +++++++++++----------- 4 files changed, 58 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b671fa..85a0d5e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-03-06 Richard Frith-Macdonald + + * Headers\win32\WIN32Server.h: make 'orderedIn' and 'level' 32bit + fields at start of structure so that we can easily use GetWindowLong() + and SetWindowLong() with them. + * Source\win32\w32_movesize.m: + * Source\win32\WIN32Server.m: + Change to accessing 'orderedIn' and 'level' directly using + GetWindowLong() and SetWindowLong() so that code weorks when windows + are owned by another app. + 2008-03-06 Richard Frith-Macdonald * Source\win32\w32_movesize.m: Bypass all existing code to send a diff --git a/Headers/win32/WIN32Server.h b/Headers/win32/WIN32Server.h index 6f51b0f..517fb92 100644 --- a/Headers/win32/WIN32Server.h +++ b/Headers/win32/WIN32Server.h @@ -198,13 +198,16 @@ typedef struct w32serverFlags { @end typedef struct _win_intern { + int32_t level; +#define OFF_LEVEL 0 + int32_t orderedIn; +#define OFF_ORDERED sizeof(int32_t) BOOL useHDC; BOOL backingStoreEmpty; - BOOL orderedIn; HDC hdc; HGDIOBJ old; MINMAXINFO minmax; - int level; } WIN_INTERN; + #endif /* _WIN32Server_h_INCLUDE */ diff --git a/Source/win32/WIN32Server.m b/Source/win32/WIN32Server.m index d1dc46f..c9ca114 100644 --- a/Source/win32/WIN32Server.m +++ b/Source/win32/WIN32Server.m @@ -1007,10 +1007,10 @@ NSLog(@"Callback"); - (void) orderwindow: (int) op : (int) otherWin : (int) winNum { - WIN_INTERN *win; - WIN_INTERN *other; int flag; int foreground = 0; + int otherLevel; + int level; NSDebugLLog(@"WTrace", @"orderwindow: %d : %d : %d", op, otherWin, winNum); @@ -1041,16 +1041,15 @@ NSLog(@"Callback"); flag = SW_RESTORE; ShowWindow((HWND)winNum, flag); - win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA); - if (op == NSWindowOut) { - win->orderedIn = NO; + SetWindowLong((HWND)winNum, OFF_ORDERED, 0); SetWindowPos((HWND)winNum, NULL, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER); return; } - win->orderedIn = YES; + SetWindowLong((HWND)winNum, OFF_ORDERED, 1); + level = GetWindowLong((HWND)winNum, OFF_LEVEL); if (otherWin <= 0) { @@ -1075,22 +1074,23 @@ NSLog(@"Callback"); /* Put this on the same window level as the window we are ordering * it against. */ - other = (WIN_INTERN *)GetWindowLong((HWND)otherWin, GWL_USERDATA); - if (win->level != other->level) + otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL); + if (level != otherLevel) { NSDebugLLog(@"WTrace", @"orderwindow: implicitly set level of %d (%d) to that of %d (%d)", - winNum, win->level, otherWin, other->level); - win->level = other->level; + winNum, level, otherWin, otherLevel); + level = otherLevel; + SetWindowLong((HWND)winNum, OFF_LEVEL, level); } } - if (win->level <= NSDesktopWindowLevel) + if (level <= NSDesktopWindowLevel) { // For desktop level, put this at the bottom of the z-order otherWin = (int)HWND_BOTTOM; NSDebugLLog(@"WTrace", - @"orderwindow: set %i (%i) to bottom", winNum, win->level); + @"orderwindow: set %i (%i) to bottom", winNum, level); } else if (otherWin == 0 || op == NSWindowAbove) { @@ -1108,7 +1108,7 @@ NSLog(@"Callback"); } NSDebugLLog(@"WTrace", @"orderwindow: traverse for %d (%d) starting at %d", - winNum, win->level, otherWin); + winNum, level, otherWin); while (otherWin > 0) { TCHAR buf[32]; @@ -1127,15 +1127,15 @@ NSLog(@"Callback"); && GetClassName((HWND)otherWin, buf, 32) == 18 && strncmp(buf, "GNUstepWindowClass", 18) == 0) { - other = (WIN_INTERN *)GetWindowLong((HWND)otherWin, GWL_USERDATA); - if (other->orderedIn == YES) + if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1) { + otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL); NSDebugLLog(@"WTrace", @"orderwindow: found gnustep window %d (%d)", - otherWin, other->level); - if (other->level >= win->level) + otherWin, otherLevel); + if (otherLevel >= level) { - if (other->level > win->level) + if (otherLevel > level) { /* On windows, there is no notion of levels, so * native apps will automatically move to the @@ -1169,17 +1169,17 @@ NSLog(@"Callback"); { otherWin = (int)HWND_TOP; NSDebugLLog(@"WTrace", - @"orderwindow: set %i (%i) to top", winNum, win->level); + @"orderwindow: set %i (%i) to top", winNum, level); } else if (otherWin == (int)HWND_BOTTOM) { NSDebugLLog(@"WTrace", - @"orderwindow: set %i (%i) to bottom", winNum, win->level); + @"orderwindow: set %i (%i) to bottom", winNum, level); } else { NSDebugLLog(@"WTrace", - @"orderwindow: set %i (%i) below %d", winNum, win->level, otherWin); + @"orderwindow: set %i (%i) below %d", winNum, level, otherWin); } SetWindowPos((HWND)winNum, (HWND)otherWin, 0, 0, 0, 0, @@ -1207,11 +1207,11 @@ NSLog(@"Callback"); && GetClassName((HWND)otherWin, buf, 32) == 18 && strncmp(buf, "GNUstepWindowClass", 18) == 0) { - other = (WIN_INTERN *)GetWindowLong((HWND)otherWin, GWL_USERDATA); - if (other->orderedIn == YES) + if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1) { + otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL); s = [s stringByAppendingFormat: - @"%d (%d)\n", otherWin, other->level]; + @"%d (%d)\n", otherWin, otherLevel]; } } } @@ -1288,12 +1288,12 @@ NSLog(@"Callback"); - (void) setwindowlevel: (int) level : (int) winNum { - WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA); + WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)winNum, GWLP_USERDATA); NSDebugLLog(@"WTrace", @"setwindowlevel: %d : %d", level, winNum); if (win->level != level) { - win->level = level; + SetWindowLong((HWND)winNum, OFF_LEVEL, level); if (win->orderedIn == YES) { [self orderwindow: NSWindowAbove : 0 : winNum]; @@ -1303,7 +1303,7 @@ NSLog(@"Callback"); - (int) windowlevel: (int) winNum { - WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA); + WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)winNum, GWLP_USERDATA); return win->level; } diff --git a/Source/win32/w32_movesize.m b/Source/win32/w32_movesize.m index 390324c..afb967a 100644 --- a/Source/win32/w32_movesize.m +++ b/Source/win32/w32_movesize.m @@ -280,8 +280,8 @@ { HWND hi; HWND lo; - WIN_INTERN *hInf; - WIN_INTERN *lInf; + int hl; + int ll; /* For debugging, log current window stack. */ @@ -305,11 +305,10 @@ && GetClassName(hi, buf, 32) == 18 && strncmp(buf, "GNUstepWindowClass", 18) == 0) { - hInf = (WIN_INTERN *)GetWindowLong(hi, GWL_USERDATA); - if (hInf->orderedIn == YES) + if (GetWindowLong(hi, OFF_ORDERED) == 1) { - s = [s stringByAppendingFormat: - @"%d (%d)\n", hi, hInf->level]; + hl = GetWindowLong(hi, OFF_LEVEL); + s = [s stringByAppendingFormat: @"%d (%d)\n", hi, hl]; } } } @@ -336,9 +335,9 @@ { if (GetClassName(hi, buf, 32) == 18 && strncmp(buf, "GNUstepWindowClass", 18) == 0 - && (hInf = (WIN_INTERN *)GetWindowLong(hi, GWL_USERDATA)) - && hInf->level > NSDesktopWindowLevel - && hInf->orderedIn == YES) + && GetWindowLong(hi, OFF_ORDERED) == 1 + && (hl = GetWindowLong(hi, OFF_LEVEL)) + > NSDesktopWindowLevel) { break; } @@ -347,7 +346,7 @@ if (hi > 0) { - NSDebugLLog(@"WTrace", @"sort hi %d (%d)", hi, hInf->level); + NSDebugLLog(@"WTrace", @"sort hi %d (%d)", hi, hl); /* Find the next (lower in z-order) GNUstep window which * is ordered in and above desktop */ @@ -356,9 +355,9 @@ { if (GetClassName(lo, buf, 32) == 18 && strncmp(buf, "GNUstepWindowClass", 18) == 0 - && (lInf = (WIN_INTERN *)GetWindowLong(lo, GWL_USERDATA)) - && lInf->level > NSDesktopWindowLevel - && lInf->orderedIn == YES) + && GetWindowLong(lo, OFF_ORDERED) == 1 + && (ll = GetWindowLong(lo, OFF_LEVEL)) + > NSDesktopWindowLevel) { break; } @@ -367,11 +366,11 @@ if (lo > 0) { - NSDebugLLog(@"WTrace", @"sort lo %d (%d)", lo, lInf->level); + NSDebugLLog(@"WTrace", @"sort lo %d (%d)", lo, ll); /* Check to see if the higher of the two windows should * actually be lower. */ - if (hInf->level < lInf->level) + if (hl < ll) { HWND higher; @@ -383,8 +382,7 @@ { higher = HWND_TOP; } -NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", - hi, hInf->level, lo, lInf->level); +NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", hi, hl, lo, ll); SetWindowPos(lo, higher, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);