Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SetWindowLong GWL_WNDPROC XP,2003

131 views
Skip to first unread message

Hector Santos

unread,
Jan 3, 2010, 8:19:37 PM1/3/10
to
Folks,

I'm trying to get a handle of this situation which makes it hard to
find out what the issue because of all the different version of
Windows and all possible all the different security patches available.

I have an old Borland C/C++ OWL (Object Windows Library) GUI
application that depending on the version of XP and 2003, it fails to
run with a GPF in its WndProc procedure.

I was able to repeat it on my boxes:

XP SP2
20003 SP1

I updated the XP box to SP3 and this resolved the issue. But other
customers still with XP SP2 it works fine. In the 2003 box, I updated
it SP2 and it still has the problem.

I just asked a large customer who has every current windows, and he
just reported it works find on VISTA, 2008, Windows 7 and an older box
with 2003. He is always updated, so I take it the 2003 is SP2.

The issue seems to be related to the version of USER32.DLL and
possible SetWindowLong. The old BC45 compiler didn't have a wrapper
for the SetWindowLongPtr() so I set that. Its just a wrapper to a pointer.

There are some KB articles, namely, this security patch:

http://support.microsoft.com/default.aspx?scid=kb;en-us;840987

Anyway, I am not 100% familar with "thunking" or why it is needed for
a 32 bit application, but the BC45 OWL library has this for its
InitWndProc which is used in the WNDCLASS.lpfnWndProc;

//
// Creation window pointer for InitWndProc
//
TWindow* _OWLDATA CreationWindow = 0;

void _OWLFUNC
SetCreationWindow(TWindow* w)
{
CreationWindow = w;
}

LRESULT CALLBACK __export
InitWndProc(HWND hWindow, uint message, WPARAM wParam, LPARAM lParam)
{
// If there's no creation window, i.e. we'll be aliasing a resource,
// then we can't do anything now. Create() will take care of it
// later

if (!CreationWindow)
return ::DefWindowProc(hWindow, message, wParam, lParam);

// install "DefWindowProc" as the window function BEFORE we
// request the subclassings; otherwise it looks like we
// subclassed "InitWndProc"
//
CreationWindow->HWindow = hWindow;
#if defined(BI_PLAT_WIN32)
CreationWindow->DefaultProc = (WNDPROC)GetProcAddress(
(HINSTANCE)GetModuleHandle("USER32"), "DefWindowProcA");
#else
CreationWindow->DefaultProc = ::DefWindowProc;
#endif

// Get the thunk & then zero out creation window so that it is not
// inadvertently used.
//
WNDPROC thunk = CreationWindow->GetThunk();
CreationWindow = 0;

// Set the thunk as the window proc, & call it with this
// first message.
SetWindowLong(hWindow, GWL_WNDPROC, uint32(thunk));

//---------------- GPF IN 2003 occurs here -------------
return (*(WNDPROC)(thunk))(hWindow, message, wParam, lParam);
}

What I traced in the OWL library it shows that after it create a
TFrameWindow which is a sub class TWindow, it calls TWindow::Create()
and in here it prepares the class and registers it:

void
TWindow::GetWindowClass(WNDCLASS& wndClass)
{
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = *GetModule();
wndClass.hIcon = 0;
wndClass.hCursor = ::LoadCursor(0, IDC_ARROW);
wndClass.hbrBackground = HBRUSH(COLOR_WINDOW + 1);
wndClass.lpszMenuName = 0;
wndClass.lpszClassName = GetClassName();
wndClass.style = CS_DBLCLKS;
wndClass.lpfnWndProc = ::InitWndProc;
}

In the TWindows.RegisterClass(), it finally calls the global
SetCreationWindow() function:

::SetCreationWindow(this)

with this being TWindow * object.

It sets the TWindow.Thunk member accessed by TWindow:GetThunk() used
in InitWndProc() above in the TWindow constructor using the following:

struct TInstanceThunk {
char Call;
int Offset;
PROC WndProcPtr;
TWindow* Window;
char Code[6];
};

static const int CODEDISP = offsetof(TInstanceThunk, Code) -
offsetof(TInstanceThunk, WndProcPtr);

WNDPROC
CreateInstanceThunk(TWindow* w)
{
TInstanceThunk* thunk = new TInstanceThunk;

thunk->Call = 0xE8; // CALL rel32
thunk->Offset = CODEDISP; // relative displacement to Code[5]
thunk->WndProcPtr = StdWndProcInstance;
thunk->Window = w;

//
// POP ECX
//
// pop return address of call into ecx (address of member
// "WndProcPtr")
//
thunk->Code[0] = 0x59;

//
// MOV EAX,[ECX+4]
//
// load "Window" into ebx
//
thunk->Code[1] = 0x8B; // MOV r32,r/m32
thunk->Code[2] = 0x41; // eax,disp8[ECX]
thunk->Code[3] = 0x04; // +4

//
// JMP [ECX]
//
// jump to window function StdWndProc
//
thunk->Code[4] = 0xFF; // JMP r/m32
thunk->Code[5] = 0x21; // [ECX]

return (WNDPROC)thunk;
}

The problem is that this is nearly 15+ year old code By Borland for
what was a solid OWL library and worked on very windows until recently
and right now it seems to be only with Window 2003.

So I am wondering if there a known issue.

I did see one "How to Thunk" KB where it shows using the Call 0xE9
instead of 0xE8 as shown above.

Some guidance would be appreciated from Win32 Kernel experts. I have
exhausted everything I can think of.

Thanks

--
HLS

Ivan Brugiolo [MSFT]

unread,
Jan 3, 2010, 9:34:14 PM1/3/10
to
First of all, have you considered Data-Execution-Protection / NX issues ?

NX is disabled in all but trusted system processes on WinXp, while it is
enabled on all but explicitly disabled applications on Server SKUs.
There is a long list of DLLs, more or less known to the system and complete
,
where DEP is disabled for a process that fails to set the execution bit
on pieces of memory where it uses to generate code to be later-on executed.
SetProcessDEPPolicy should be your friend here, if you are writing code,
or, the UI for DEP/NX should allow you to white-list that application.

--

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


"Hector Santos" <sant...@nospam.gmail.com> wrote in message
news:uAkbawNj...@TK2MSFTNGP05.phx.gbl...

Hector Santos

unread,
Jan 4, 2010, 1:23:08 AM1/4/10
to
Oh brother! Thanks that was it. Appreciate it. Wasted 3 days on
this. Never had to deal with it before.


Ivan Brugiolo [MSFT] wrote:

> First of all, have you considered Data-Execution-Protection / NX issues ?
>
> NX is disabled in all but trusted system processes on WinXp, while it is
> enabled on all but explicitly disabled applications on Server SKUs.
> There is a long list of DLLs, more or less known to the system and
> complete ,
> where DEP is disabled for a process that fails to set the execution bit
> on pieces of memory where it uses to generate code to be later-on executed.
> SetProcessDEPPolicy should be your friend here, if you are writing code,
> or, the UI for DEP/NX should allow you to white-list that application.
>

--
HLS

Hector Santos

unread,
Jan 4, 2010, 2:33:38 AM1/4/10
to
Apparently for 2003, this SetProcessDEPPolicy() is not available in
kernel32.dll.

Oh well, has to be a manual instruction for customers having this issue.

Thanks to all.

Paul Baker [MVP, Windows Desktop Experience]

unread,
Jan 4, 2010, 8:45:46 AM1/4/10
to
Hector,

It is possible to configure DEP programatically without instructing the user
to follow a manual process.

There are DisableNXShowUI and DisableNXHideUI compatibility modes. They are
not well documented, but here is a forum post that may explain enough for
you to successfully implement it. If not, you can search the Internet for
additional information.

http://social.msdn.microsoft.com/Forums/en-US/os_fileservices/thread/f6283fee-af4c-4b1a-9024-96426c586f0a

Paul

"Hector Santos" <sant...@nospam.gmail.com> wrote in message

news:e2i8ZBRj...@TK2MSFTNGP05.phx.gbl...

Hector Santos

unread,
Jan 5, 2010, 4:37:32 AM1/5/10
to
Wonderful Paul!

I was trying to see how to get the Exe listed in that box. That is
what I thought SetProcessDepPolicy() would do which does seem to do
the job to white list the process during its run time.

I just tried the registry option, it worked!

Appreciate the great input.

--

--
HLS

Paul Baker [MVP, Windows Desktop Experience]

unread,
Jan 5, 2010, 9:06:59 AM1/5/10
to
I think SetProcessDepPolicy() is just a convenient wrapper. If you don't
have it, it's not a problem.

Paul

"Hector Santos" <sant...@nospam.gmail.com> wrote in message

news:OP1LXrej...@TK2MSFTNGP02.phx.gbl...

Jogy

unread,
Jan 15, 2010, 6:32:01 AM1/15/10
to


"Hector Santos" wrote:


Hello,

This is a known issue.

The OWL uses a thunking mechanism in order to maintain the relation
between the framework class (TWindow) and the Windows handle (a HWND)

All C++ GUI frameworks have to di this in one way or another,
in order to be able to process Windows messages in an object-oriented way.

The MFC approach was, I believe, to use a map between HWNDs and CWnd pointers.

The OWL approach, with low level thunks, was faster, but non-portable.

OWL was dropped by Borland 10 years ago, but an open-source project
named OWLNext picked it up and continued the development.

The latest versions of OWLNext solve the DEP/thunking problems,
and also have added support for modern Windows GUI elements,
and can be used with recent C++ compilers like Visual C++ 2008/2010

If you are interested in upgrading your application, come to the OWLNext
project site
(http://owlnext.sourceforge.net/) for more information.

Jogy

Hector Santos

unread,
Jan 16, 2010, 1:47:04 AM1/16/10
to
Hi Jogy,

I really did try to search for a "group" that took over OWL. It was
hard to believe that this issue was not already encountered and
addressed in some OWL patch or 3rd party update. I am normally a good
researcher but I missed this one. :)

So I appreciate your input and I will most definitely look into
OwlNext. I will be interested to see how much single sourcing I can
do by compiling with the VS C/C++ compiler. :)

Thanks for the input again.

--
HLS

Hector Santos

unread,
Jan 16, 2010, 2:50:22 AM1/16/10
to
Jogy,

I'm been trying to download the OwlNext source code from

http://cc.embarcadero.com/item/27219

There is no server response and I tried from SOHO and from my company
network - two different sub-nets. What gives with this company that
took over the once upon a time 'best kept secret' in the market? :)

Also, is there a minimum patch available to resolve the thunking issue
within a BC 4.5 compile?

Thanks

--
HLS

Jogy

unread,
Jan 18, 2010, 4:17:01 AM1/18/10
to

"Hector Santos" wrote:

> Jogy,
>
> I'm been trying to download the OwlNext source code from
>
> http://cc.embarcadero.com/item/27219
>
> There is no server response and I tried from SOHO and from my company
> network - two different sub-nets. What gives with this company that
> took over the once upon a time 'best kept secret' in the market? :)
>

Try again, it is possible that theirs servers were down during the weekend.


> Also, is there a minimum patch available to resolve the thunking issue
> within a BC 4.5 compile?
>

Well, no. OWLNext was based on OWL5.0 which came with Borland C++ 5.01/5.02
and was the last official OWL version.

You will have to port to OWLNext, which at the beginning can be not an easy
task.

But if you want to maintain and update your applications to work under the
new versions of Windows, this is the way to go.

Jogy

> Thanks
>
> --
> HLS
>
> Hector Santos wrote:
>
> > Hi Jogy,
> >
> > I really did try to search for a "group" that took over OWL. It was hard
> > to believe that this issue was not already encountered and addressed in
> > some OWL patch or 3rd party update. I am normally a good researcher but
> > I missed this one. :)
> >
> > So I appreciate your input and I will most definitely look into
> > OwlNext. I will be interested to see how much single sourcing I can do
> > by compiling with the VS C/C++ compiler. :)
> >
> > Thanks for the input again.
> >

> .
>

Hector Santos

unread,
Jan 18, 2010, 5:33:42 AM1/18/10
to
Hi. I was able to finally download it. Yes, a major change, just
looking at OWL.CPP It might be easier to do a pure port to MFC. :)

Thanks again.

Jogy wrote:

--
HLS

Jogy

unread,
Jan 18, 2010, 7:06:01 AM1/18/10
to

"Hector Santos" wrote:

> Hi. I was able to finally download it. Yes, a major change, just
> looking at OWL.CPP It might be easier to do a pure port to MFC. :)
>
> Thanks again.
>

Hello,

I doubt that a pure port to MFC will be easier, it would need a complete
rewrite of the UI :-)
In this case, it is better to move to a more modern framework, like
WinForms.NET


But the changes from OWL 2 to OWLNext are not that big, the core of the
framework
is still the same.

Check this article:
http://owlnext.sourceforge.net/articleowlcompat.html
It shows most of the changes in the methods of OWL2 classes and how to
replace them.

Jogy

0 new messages