Date: | February 1, 2006 / year-entry #43 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20060201-00/?p=32443 |
Comments: | 13 |
Summary: | Earlier, I discussed which window style bits belong to whom. One detail of this that I neglected to emphasize is that since the lower 16 bits of the window style are defined by the class, you can't just take styles from one class and apply them to another. For example, you can't create a button... |
Earlier, I discussed
which window style bits belong to whom.
One detail of this that I neglected to emphasize is that
since the
lower 16 bits of the window style are defined by the class,
you can't just take styles from one class and apply them to another.
For example, you can't create a button control and pass the
#define SS_ENDELLIPSIS 0x00004000L #define BS_NOTIFY 0x00004000L
The button control sees your 0x00004000L and treats it as
Remember that at the end of the day, window styles and window messages are just numbers. If you use a per-class window style or window message, you'd better be passing it to the class that defined it.
This also applies to window extra bytes.
The value returned by
|
Comments (13)
Comments are closed. |
From a program isolation standpoint, why should another process be allowed to mess with my window’s extra bytes unless I enable such behavior?
Virtual memory space is protected by default and that gives us much greater stability (shudder DOS days). Why not this sort of resource?
I don’t think the two examples are in the same class.
I agree with the first one. If I use a BS_* with a non-button, is wrong. The BS_ prefix and the doc spells it out.
GetWindowLongPtr is working on any window. And a dialog is a special type a window, as is a button and so on.
So I would expect that GetWindowLongPtr( DWLP_DLGPROC ) from a non-dialog will return zero ("I don’t have such a thing, because I am not a dialog, dummy!"). There are only 10 values, no overlapping, so there is no reason not to.
The documentation has no warning on this, so I don’t think it is fair to balme the "major commercial software manufacturer"
jwf: It’s one of Window’s principles that "everything on the desktop is equal" so to speak. That means you can move other windows, send messages to other windows and do pretty much anything to other windows that you like, as long as that window is on the same desktop as yours.
This is regardless of which USER owns the particular windows, which is why checking the "Allow service to interact with desktop" checkbox on a service is such a bad idea.
Re: Mihai
The second parameter to GetWindowLongPtr is just an offset to the value you want. If you look up the definitions of GWL_EXSTYLE, etc. in the file WinUser.h you’ll see that those are just negative offsets.
It therefore does not look like there is any "magic" involved. GetWindowLongPtr just adds the specified offset to some base address (defined by the hwnd I would guess) and returns whatever is stored there.
quote from msdn (GetWindowLong): "The following values are also available when the hWnd parameter identifies a dialog box."
It seems obvious that you cannot use these values if it is not a dialog box.
Of course adding an explicit warning in the documentation would not harm. :)
I have always thought that the dialog box system in Windows was written as a a high level layer above the lower-level window system. So, there should not be any special piece code for dialog boxes in non-dialog-boxes user32 functions. The fact that when we subclass a dialog box we must pass at least DLGWINDOWEXTRA bytes as cbWndExtra can also help someone to get an idea of what could be the implementation, and what he cannot assume.
Of course, we cannot ask for all programmers to know the whole Win32 API and have thought of the phylosophy and deep meaning of each function before they write any piece of code.
Maybe you noticed that MSDN’s documentation is improved each year. Warnings on some details that are not intuitive for everybody, are added.
jwf: to enable shatter attacks of course http://security.tombom.co.uk/shatter.html
John Doe — I know they are offsets. But if I pass -5000 I expect an error (invalid parameter), not a pointer to something random. I don’t suspect it of magic, only of bad design.
SuperKoko — You are right, the documentation spells it out. I have missed that.
But I still think this is bad design.
If the standard usage patern is:
if( TestIfWndIsDialog(hWnd) )
GetWindowLongPtr(hwnd, DWLP_DLGPROC)
then I think the right thing is to move this inside the API. Especially that TestIfWndIsDialog will probably retrieve the class and compare it with "#32770", quite expensive compared with GetWindowLongPtr which probably has access to the windows internals and can just check a flag somewhere (I guess).
You’re all missing the point. Look at the definition of DWLP_DLGPROC. Somebody else might have
#define XWLP_IMAGEINDEX 4
This is just like the
#define SS_ENDELLIPSIS 0x00004000L
#define BS_NOTIFY 0x00004000L
conflict. The window manager can’t read your source code. It sees a 4. It doesn’t know whether you passed DWLP_DLGPROC or XWLP_IMAGEINDEX.
If the test were moved into the API, you couldn’t use window extra bytes in your custom classes.
Hey, is there an RSS feed to get all the comments of all posts as they come in?
It looks like you can actually sandbox your program from other apps (minus broadcast messages): http://www.hpl.hp.com/techreports/2005/HPL-2005-87.pdf
asdf: The problem that article describes is a bug in the virus scanner – that is, it’s console runs as LocalSystem. Like I said, anything on the desktop is considered "equal" regardless of what user credentials it has. If everything on the desktop all had the same credentials, then that "flaw" would be meaningless because it wouldn’t let you do anything that you couldn’t already do.
It all goes back to the days of Windows 3.x (or even Windows 9X) where everything really *was* equal.
I don’t think the results of that report are any good. The problem is not that you sandbox your own application in a job, but that you have to sandbox the *malicious* program in a job with the right restrictions. And given that a process cannot be REassigned a job, all the malicious program has to do is assign itself to an unrestricted job before you get a chance to sandbox it.