The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: jj2007 on January 21, 2011, 01:59:14 PM

Title: Windows plays foul with tooltips_class32
Post by: jj2007 on January 21, 2011, 01:59:14 PM
Although all params seem to be correct, Windows sets an error 1309, ERROR_NO_IMPERSONATION_TOKEN:

invoke SetLastError, 1 ; for testing, set "incorrect function"
invoke CreateWindowEx, WS_EX_TOPMOST, chr$("tooltips_class32"), 0,
WS_POPUP, 0, 0, 0, 0, hWnd, 0, hInstance, 0
xchg eax, edi ; save handle
mov eax, LastError$()
invoke MessageBox, 0, eax, 0, MB_OK ; An attempt has been made ...


The good news is that CreateWindowEx still returns a useful and perfectly working handle. It chokes much later, when I try to use LoadString (http://msdn.microsoft.com/en-us/library/ms647486%28VS.85%29.aspx) for a non-existent string:

QuoteIf the function succeeds, the return value is the number of characters copied into the buffer, not including the terminating null character, or zero if the string resource does not exist. To get extended error information, call GetLastError.

LoadString returns zero, no string. Now guess which error message is reported by GetLastError?

Yeah, "An attempt has been made to operate on an impersonation token by a thread that is not bla bla..."
Title: Re: Windows plays foul with tooltips_class32
Post by: xandaz on January 21, 2011, 02:25:34 PM
   Im not sure this is corrent but should ExStyle be WS_EX_TOOLWINDOW?
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 21, 2011, 03:21:14 PM
The ex_style apparently plays no role in this. I have tested quite a number of combinations, but cwex always returns that cryptic error. I run Win XP SP2.
I also tested in on my other system (XP SP2), same result.
Title: Re: Windows plays foul with tooltips_class32
Post by: dedndave on January 21, 2011, 07:52:39 PM
i found this - maybe it will help...

http://www.codeproject.com/KB/miscctrl/ballontooltip.aspx

they use
WS_POPUP or TTS_BALLOON or TTS_NOPREFIX or TTS_ALWAYSTIP

another possibility is that you aren't wiggling the right bit in InitCommonControlsEx   :P
Title: Re: Windows plays foul with tooltips_class32
Post by: xandaz on January 21, 2011, 09:13:38 PM
  hey jj. The reasone i mentioned WS_EX_TOOLWINDOW was that the other day i was making a tooltip myself and didnt mention that style nor WS_POPUP because the docs say it'll have those styles even if you don't reffer them. The tooltips went all wrong and started appearing in the bottom of the window. Not sure this helps
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 21, 2011, 11:23:04 PM
Quote from: xandaz on January 21, 2011, 09:13:38 PM
  hey jj. The reasone i mentioned WS_EX_TOOLWINDOW was that the other day i was making a tooltip myself and didnt mention that style nor WS_POPUP because the docs say it'll have those styles even if you don't reffer them. The tooltips went all wrong and started appearing in the bottom of the window. Not sure this helps

Yes indeed. MSDN: (http://msdn.microsoft.com/en-us/library/bxbh2tyk.aspx) A tool tip control has the WS_POPUP and WS_EX_TOOLWINDOW  window styles, regardless of whether you specify them when creating the control.

Dave,
I tried (erroneously) the styles you proposed, and the good news is that now GetLastError returns zero==everything fine. Except that cwex retval eax==00, i.e. it also returns no handle :cheekygreen:
Title: Re: Windows plays foul with tooltips_class32
Post by: Antariy on January 21, 2011, 11:42:48 PM
Quote from: jj2007 on January 21, 2011, 11:23:04 PM
Quote from: xandaz on January 21, 2011, 09:13:38 PM
  hey jj. The reasone i mentioned WS_EX_TOOLWINDOW was that the other day i was making a tooltip myself and didnt mention that style nor WS_POPUP because the docs say it'll have those styles even if you don't reffer them. The tooltips went all wrong and started appearing in the bottom of the window. Not sure this helps

Yes indeed. MSDN: (http://msdn.microsoft.com/en-us/library/bxbh2tyk.aspx) A tool tip control has the WS_POPUP and WS_EX_TOOLWINDOW  window styles, regardless of whether you specify them when creating the control.

Dave,
I tried (erroneously) the styles you proposed, and the good news is that now GetLastError returns zero==everything fine. Except that cwex retval eax==00, i.e. it also returns no handle :cheekygreen:


Try to set window position and size of tooltips window as CW_USEDEFAULT in CWEx.
Title: Re: Windows plays foul with tooltips_class32
Post by: xandaz on January 22, 2011, 12:13:10 AM
   That's right antaryi. Look at this jj.
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 22, 2011, 12:24:15 AM
Quote from: Antariy on January 21, 2011, 11:42:48 PMTry to set window position and size of tooltips window as CW_USEDEFAULT in CWEx.

No effect, same error. But the tooltips work fine anyway; I think it's a kind of internal error. Strictly speaking, if cwex returns a non-zero handle, there is no error. The nuisance is that internally it gets set, and shows up where you don't expect it, i.e. when LoadString returns a zero value and you want to know why. This is not by design, this is a big fat Windows bug.
Title: Re: Windows plays foul with tooltips_class32
Post by: dedndave on January 22, 2011, 12:31:50 AM
Quotethis is a big fat Windows bug

i had a gal like that, once   :eek
Title: Re: Windows plays foul with tooltips_class32
Post by: oex on January 22, 2011, 12:32:59 AM
Quote from: dedndave on January 22, 2011, 12:31:50 AM
Quotethis is a big fat Windows bug
i had a gal like that, once   :eek

:lol No comment

(http://t3.gstatic.com/images?q=tbn:ANd9GcRLKZLi4Iap9OopjXccMOai6umprJKp5Z_ii956gMeHDhsdKR2v&t=1)
Title: Re: Windows plays foul with tooltips_class32
Post by: xandaz on January 22, 2011, 12:37:36 AM
   Nice oex.
Title: Re: Windows plays foul with tooltips_class32
Post by: Antariy on January 22, 2011, 12:50:33 AM
Quote from: jj2007 on January 22, 2011, 12:24:15 AM
Strictly speaking, if cwex returns a non-zero handle, there is no error.

Quote
Most Win32 functions call SetLastError when they fail. Function failure is typically indicated by a return value error code such as FALSE, NULL, 0xFFFFFFFF, or -1. Some functions call SetLastError under conditions of success; those cases are noted in each function's reference page.
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 22, 2011, 01:02:02 AM
Alex,

MSDN for CreateWindowEx: (http://msdn.microsoft.com/en-us/library/ms632680%28v=vs.85%29.aspx)
QuoteIf the function fails, the return value is NULL. To get extended error information, call GetLastError.
CreateWindowEx returns a valid handle but sets this obscure error.

LoadString returns an error (eax=0 bytes, no string found) but does not set lasterror, in conflict with its documentation (http://msdn.microsoft.com/en-us/library/ms647486%28v=vs.85%29.aspx):
QuoteIf the function succeeds, the return value is the number of characters copied into the buffer, not including the terminating null character, or zero if the string resource does not exist. To get extended error information, call GetLastError.
IMHO nobody can call that "by design", not even Billieboy.
Title: Re: Windows plays foul with tooltips_class32
Post by: Antariy on January 22, 2011, 01:12:19 AM
Quote from: jj2007 on January 22, 2011, 01:02:02 AM
Alex,

MSDN for CreateWindowEx: (http://msdn.microsoft.com/en-us/library/ms632680%28v=vs.85%29.aspx) If the function fails, the return value is NULL. To get extended error information, call GetLastError.

This value is set not by CWEx, but anything other call which CWEx does. It meant nothing regardless to CWEx *if* it is returns the handle.
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 22, 2011, 01:55:48 AM
Alex,
You are splitting hairs. CwEx should set LastError to zero, even if internal calls fail. Worse is the behaviour of LoadString

.data?
bufferx db 1000 dup(?) ; Stringtable ID 01 is "Enter text here"
.code
invoke LoadString, hInstance, 999, offset bufferx, 5 ; size too small
mov esi, offset bufferx
mov edi, eax
mov eax, LastError$()
deb 4, "LoadString bugs:", edi, $eax, $esi


invoke LoadString, hInstance, 01, offset bufferx, -3 ; negative size
LoadString bugs:
edi             -4  (=-4 characters successful copied, congrats...)
$eax            Operazione completata = OK
$esi            (empty string)

invoke LoadString, hInstance, 01, offset bufferx, 5 ; size too small
LoadString bugs:
edi             4
$eax            Operazione completata.
$esi            Ente

invoke LoadString, 0, 01, offset bufferx, 5 ; zero hInstance, size too small
LoadString bugs:
edi             4
$eax            Operazione completata.
$esi            Ente

invoke LoadString, 0, -99, offset bufferx, 5 ; zero hInstance, size too small, wrong ID
LoadString bugs:
edi             0
$eax            Can't find the name of the resource
$esi
Title: Re: Windows plays foul with tooltips_class32
Post by: Antariy on January 22, 2011, 02:06:25 AM
Quote from: jj2007 on January 22, 2011, 01:55:48 AM
Alex,
You are splitting hairs. CwEx should set LastError to zero, even if internal calls fail.

I'll not say anything more, since I'm splitting hairs (as usual).

CWEx *should NOT SetLastError if it succeeded*. No ANY APY should set it if succeeded. This is documented behavious which you may rely. "Some" apis set last error to 0, but not all and number of that apis is very small. If API set SLE it even if succeeded, then this is just favour, not rule.
Title: Re: Windows plays foul with tooltips_class32
Post by: MichaelW on January 22, 2011, 02:08:43 AM
In my test of this under Windows 2000 CreateWindowEx returned a handle and GetLastError returned ERROR_SUCCESS.

Per the PSDK documentation for GetLastError:

"The GetLastError function retrieves the calling thread's last-error code value.
. . .
You should call the GetLastError function immediately when a function's return value indicates that such a call will return useful data. That is because some functions call SetLastError with a zero when they succeed, wiping out the error code set by the most recently failed function."

Within my experience most functions do not reset the last error value on success.

Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 22, 2011, 02:12:01 AM
Quote from: Antariy on January 22, 2011, 02:06:25 AMCWEx *should NOT SetLastError if it succeeded*. No ANY APY should set it if succeeded. This is documented behavious which you may rely. "Some" apis set last error to 0, but not all and number of that apis is very small. If API set SLE it even if succeeded, then this is just favour, not rule.

As a matter of fact, CwEx changes lasterror to an obscure message in spite of the fact that it succeeds, and a subsequent API, LoadString, does not change lasterror in spite of the fact that it fails. It is by sheer accident that I was able to track down the reason for this behaviour.
Title: Re: Windows plays foul with tooltips_class32
Post by: MichaelW on January 22, 2011, 02:22:56 AM
Quote from: jj2007 on January 22, 2011, 02:12:01 AM
As a matter of fact, CwEx changes lasterror to ...

Are you sure that CwEx changed it? CwEx probably calls many other functions, and its success may depend on one or more of these called functions returning an error.



Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 22, 2011, 02:44:31 AM
Quote from: MichaelW on January 22, 2011, 02:22:56 AM
Quote from: jj2007 on January 22, 2011, 02:12:01 AM
As a matter of fact, CwEx changes lasterror to ...
Are you sure that CwEx changed it? CwEx probably calls many other functions, and its success may depend on one or more of these called functions returning an error.

Michael,
That is a strange argument. If one of your procedures uses a WinAPI, and finds out, for example, that a file is missing, does it report "all is fine", or does it pass on the message...?
Title: Re: Windows plays foul with tooltips_class32
Post by: japheth on January 22, 2011, 05:05:42 AM
Quote from: jj2007 on January 22, 2011, 02:12:01 AM
As a matter of fact, CwEx changes lasterror to an obscure message in spite of the fact that it succeeds, and a subsequent API, LoadString, does not change lasterror in spite of the fact that it fails. It is by sheer accident that I was able to track down the reason for this behaviour.

This is partly a misconception. CreateWindowEx may change last error to any value it likes as long as it succeeds, since the value of "last error" is to be regarded as undefined if the function doesn't fail.

LoadString() returning 0 and not setting "last error" would be a true bug. However, when I  try this, the OS (WinXP SP2) always returns error code 1812 (ERROR_RESOURCE_DATA_NOT_FOUND), which sounds plausible.
Title: Re: Windows plays foul with tooltips_class32
Post by: MichaelW on January 22, 2011, 08:21:31 AM
Quote from: jj2007 on January 22, 2011, 02:44:31 AM
That is a strange argument. If one of your procedures uses a WinAPI, and finds out, for example, that a file is missing, does it report "all is fine", or does it pass on the message...?

What about a procedure that needs to use a file of a given name if it exists, or create the file if it does not exist? How do you go about determining if the file exists?

Title: Re: Windows plays foul with tooltips_class32
Post by: sinsi on January 22, 2011, 08:34:29 AM
Have you tried calling SetLastError with an unusual value before the API call?
Most functions won't change it if they succeed.

Maybe you could put a watch in a debugger on the error code variable? It should be in the TIB somewhere.
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 22, 2011, 11:21:07 AM
Quote from: MichaelW on January 22, 2011, 08:21:31 AM
What about a procedure that needs to use a file of a given name if it exists, or create the file if it does not exist? How do you go about determining if the file exists?

I would return 1 for "file existed" and 2 for "file was created", but definitely not "I used the file you indicated, but I won't tell you if it existed or not, and by the way, you should be ashamed because you impersonated the wrong token" :wink

@Sinsi: That's what I did: invoke SetLastError, 1. The value persists with LoadString (and LoadStringW), in spite of eax==0 returned.
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 22, 2011, 08:07:32 PM
Quote from: japheth on January 22, 2011, 05:05:42 AM
LoadString() returning 0 and not setting "last error" would be a true bug. However, when I  try this, the OS (WinXP SP2) always returns error code 1812 (ERROR_RESOURCE_DATA_NOT_FOUND), which sounds plausible.

Here is the relevant part of the code - attached the executable and the *.asc file (MasmBasic and RichMasm needed to assemble the source).

         MbToolExS = WS_EX_TOPMOST
         MbToolFlags = TTS_BALLOON
         invoke SetLastError, 1
         invoke CreateWindowEx, MbToolExS, chr$("tooltips_class32"), ebx,
         MbToolFlags, ebx, ebx, ebx, ebx, hWnd, ebx, hInstance, ebx
         mov [esi-4], eax      ; store handle in hMbTIS
         xchg eax, edi
;         mov eax, LastError$()
;         deb 1, "Create TT", edi, $eax
      .data?
         bufferx   db 1024 dup(?)      ; Stringtable ID 01 is "Enter text here"
      .code
         pushad
         invoke LoadString, hInstance, 3, offset bufferx, 1000
         mov esi, offset bufferx
         mov edi, eax
         mov eax, LastError$()
         deb 4, "LoadString bugs:", edi, $eax, $esi
         LoadString bugs:
         edi      0   ; retval
         $eax   Un thread che attualmente non rappresenta un client ha tentato di operare su un token di rappresentazione di client.
         popad
Title: Re: Windows plays foul with tooltips_class32
Post by: japheth on January 23, 2011, 09:33:46 AM
Quote from: jj2007 on January 22, 2011, 08:07:32 PM
Quote from: japheth on January 22, 2011, 05:05:42 AM
LoadString() returning 0 and not setting "last error" would be a true bug. However, when I  try this, the OS (WinXP SP2) always returns error code 1812 (ERROR_RESOURCE_DATA_NOT_FOUND), which sounds plausible.

Here is the relevant part of the code - attached the executable and the *.asc file (MasmBasic and RichMasm needed to assemble the source).

Thanks, but since I know that my code - which uses the pure Win32 API - works,  there are only a few possibilities left:

1.Japheth does something wrong
2. there's a big, fat bug in the Win XP LoadString function
3. JJ is doing something wrong
4. JJ's MasmBasic does something wrong
5. your machine is infected (rather unlikely)

IMO there is only one person left who can fix this issue ...
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 23, 2011, 09:46:29 AM
Special edition for my clever German friend, with an int 3 before the LoadString - to be run with a debugger, obviously.

On my Win XP SP 2 machines, LoadString returns zero in eax (= an error) but keeps the error previously set by CreateWindowEx.

Grateful for feedback if others see the same error.
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 23, 2011, 10:00:22 AM
Here another version. To make Japheth happy, I have called it LoadStringBugNoMB.zip  :bg

(which implies you can assemble it with the standard Masm32 package)
Title: Re: Windows plays foul with tooltips_class32
Post by: qWord on January 23, 2011, 10:33:54 AM
not sure ... but in your exe there is only one resource with the ID=3: an icon - maybe this is the problem. On Win7-x64 LoadString returns zero+ERROR_SUCCESS - so it has load an zero-sized string (icon data)?

qWord
Title: Re: Windows plays foul with tooltips_class32
Post by: japheth on January 23, 2011, 11:01:00 AM
Quote from: jj2007 on January 23, 2011, 09:46:29 AM
Special edition for my clever German friend, with an int 3 before the LoadString - to be run with a debugger, obviously.

Ok, thanks! I have to apologize! The updated list looks like this:

1.Japheth did something wrong AND there's a big, fat bug in the Win XP LoadString function
2. JJ is doing something wrong
3. JJ's MasmBasic does something wrong
4. your machine is infected (rather unlikely)

If the string doesn't exist or has size zero, 0 is returned and last error is NOT set. Same happens in Win98.
Title: Re: Windows plays foul with tooltips_class32
Post by: jj2007 on January 23, 2011, 11:24:02 AM
Quote from: qWord on January 23, 2011, 10:33:54 AM
not sure ... but in your exe there is only one resource with the ID=3: an icon - maybe this is the problem. On Win7-x64 LoadString returns zero+ERROR_SUCCESS - so it has load an zero-sized string (icon data)?

Hi qWord,

There is an icon but its ID is 32512. There is also a stringtable, but the requested ID 3 is missing. IMHO a missing string should return an error... and it should not be an obscure error set by CreateWindowEx. But Japheth may have another UHO, of course.

Quote32512 ICON "\\masm32\\RichMasm\\icons\\Globe.ico"   ; Asm, House, Keys, Globe, Hammer, Setup, Disc, Eye, ...
STRINGTABLE
BEGIN
   001,   "Enter text here"         ; e.g. for ToolTips hEdit=wRes$(1+400*MyLanguage)
   002,   "Click on this button"   ; e.g. for wSetWin$ hButton=wRes$(2+400*MyLanguage)
;   003,   "Welcome"
   401,   "Введите текст  здесь"   ; "Enter text here" in Russian
   402,   "Нажмите на эту кнопку"   ; "Click on this button" in Russian
   403,   "Добро пожаловать"   ; "Welcome" in Russian
   801,   "أدخل النص هنا"               ; "Enter text here" in Arabic
   802,   "دفع هذا الزر"                  ; "Click on this button" in Arabic
   803,   "مرحبا بكم"                  ; "Welcome" in Arabic
   1201,   "在這裡輸入文字"      ; "Enter text here" in Chinese
   1202,   "按一下這個按鈕"      ; "Click on this button" in Chinese
   1203,   "歡迎"                     ; "Welcome" in Chinese
;    Try wMsgBox 0, wRes$(402), wChr$("Wow:")
END