[Bug 49178] Spitfire Audio 3.x crashes on start due to 'WTSQuerySessionInformationA' stub not initializing out parameters

WineHQ Bugzilla wine-bugs at winehq.org
Tue May 26 12:11:07 CDT 2020


https://bugs.winehq.org/show_bug.cgi?id=49178

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |focht at gmx.net
          Component|-unknown                    |wtsapi32
            Summary|Spitfire Audio crashes on   |Spitfire Audio 3.x crashes
                   |start                       |on start due to
                   |                            |'WTSQuerySessionInformation
                   |                            |A' stub not initializing
                   |                            |out parameters

--- Comment #17 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

confirming. The app doesn't care about WTSQuerySessionInformationA() API return
value but rather looks at out parameters. Wine's WTSQuerySessionInformationA()
is a stub that doesn't do anything in contrast to WTSQuerySessionInformationW()
which implements WTSUserName info class.

The app working with Wine built with CFLAGS="-O0" is just coincidence, the
"out" buffer parameter is NULL before + after return (different stack layout /
init values).

Relevant app disassembly:

--- snip ---
...
00959F50 | push ebp                                   |
00959F51 | mov ebp,esp                                |
00959F53 | sub esp,410                                |
00959F59 | mov eax,dword ptr ds:[12B8474]             |
00959F5E | xor eax,ebp                                |
00959F60 | mov dword ptr ss:[ebp-4],eax               |
00959F63 | push esi                                   |
00959F64 | lea eax,dword ptr ss:[ebp-40C]             |
00959F6A | mov dword ptr ss:[ebp-410],0               |
00959F74 | push eax                                   | &BytesReturned
00959F75 | lea eax,dword ptr ss:[ebp-408]             |
00959F7B | mov esi,ecx                                |
00959F7D | push eax                                   | &Buffer
00959F7E | push 5                                     | WTSInfoClass
00959F80 | push FFFFFFFF                              | SessionId
00959F82 | mov dword ptr ss:[ebp-40C],esi             |
00959F88 | push 0                                     | hServer
00959F8A | mov dword ptr ss:[ebp-40C],0               |
00959F94 | call dword ptr ds:[<&WTSQuerySessionInformationA>] |
00959F9A | push dword ptr ss:[ebp-408]                | Buffer
00959FA0 | mov edx,dword ptr ss:[ebp-40C]             | BytesReturned
00959FA6 | mov ecx,esi                                |
00959FA8 | call spitfire audio.68EBB0                 |
...
0068EBB0 | push ebp                                   |
0068EBB1 | mov ebp,esp                                |
0068EBB3 | sub esp,8                                  |
0068EBB6 | mov eax,dword ptr ss:[ebp+8]               | Buffer
0068EBB9 | mov dword ptr ss:[ebp-8],ecx               |
0068EBBC | push esi                                   |
0068EBBD | mov esi,edx                                | BytesReturned
0068EBBF | test eax,eax                               | Buffer != NULL?
0068EBC1 | je spitfire audio.68EC50                   |
0068EBC7 | cmp byte ptr ds:[eax],0                    | Buffer[0] != '\0'?
0068EBCA | je spitfire audio.68EC50                   |
0068EBD0 | test esi,esi                               |
0068EBD2 | je spitfire audio.68EC50                   |
--- snip ---

Stack layout/values before API call

--- snip ---
0031F804  00000000 hServer
0031F808  FFFFFFFF SessionId
0031F80C  00000005 WTSInfoClass
0031F810  0031F824 &Buffer
0031F814  0031F820 &BytesReturned
0031F818  0031FC40
0031F81C  00000000 
0031F820  00000000 BytesReturned
0031F824  00000002 Buffer (garbage) <-- will cause crash on deref
0031F828  00000060 
0031F82C  00000000 
0031F830  00000000 
0031F834  00000000 
0031F838  00000000 
...
--- snip ---

Wine source:

https://source.winehq.org/git/wine.git/blob/ba920246e502afe7bc664c1881d528a27e980101:/dlls/wtsapi32/wtsapi32.c#l287

--- snip ---
 287 /************************************************************
 288  *                WTSQuerySessionInformationA  (WTSAPI32.@)
 289  */
 290 BOOL WINAPI WTSQuerySessionInformationA(
 291     HANDLE hServer,
 292     DWORD SessionId,
 293     WTS_INFO_CLASS WTSInfoClass,
 294     LPSTR* Buffer,
 295     DWORD* BytesReturned)
 296 {
 297     /* FIXME: Forward request to winsta.dll::WinStationQueryInformationA
*/
 298     FIXME("Stub %p 0x%08x %d %p %p\n", hServer, SessionId, WTSInfoClass,
 299         Buffer, BytesReturned);
 300 
 301     return FALSE;
 302 }
 303 
 304 /************************************************************
 305  *                WTSQuerySessionInformationW  (WTSAPI32.@)
 306  */
 307 BOOL WINAPI WTSQuerySessionInformationW(
 308     HANDLE hServer,
 309     DWORD SessionId,
 310     WTS_INFO_CLASS WTSInfoClass,
 311     LPWSTR* Buffer,
 312     DWORD* BytesReturned)
 313 {
 314     /* FIXME: Forward request to winsta.dll::WinStationQueryInformationW
*/
 315     FIXME("Stub %p 0x%08x %d %p %p\n", hServer, SessionId, WTSInfoClass,
 316         Buffer, BytesReturned);
 317 
 318     if (WTSInfoClass == WTSUserName)
 319     {
 320         WCHAR *username;
 321         DWORD count = 0;
 322 
 323         GetUserNameW(NULL, &count);
 324         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE;
 325         if (!(username = heap_alloc(count * sizeof(WCHAR)))) return FALSE;
 326         GetUserNameW(username, &count);
 327         *Buffer = username;
 328         *BytesReturned = count * sizeof(WCHAR);
 329         return TRUE;
 330     }
 331     return FALSE;
 332 }
--- snip ---

Possible options:

(1) just zero-init out parameters but don't implement anything

(2) duplicate the code for WTSUserName info class handling from
WTSQuerySessionInformationW() but as ANSI

(3) make WTSQuerySessionInformationA() call WTSQuerySessionInformationW() with
W->A conversion of buffer

(4) combination of (1) and (2) or (3) to ensure other buggy apps don't crash as
well when querying for other unimplemented info classes, looking at out
parameters without checking BOOL return value first.

Depending on the solution taken, the ticket summary should be adapted before
release. Currently it refers to (1).

$ sha1sum SpitfireAudioWinSetup-3.2.6.exe 
c3c36a977c3c85d65b60c28de6074539a95da12c  SpitfireAudioWinSetup-3.2.6.exe

$ du -sh SpitfireAudioWinSetup-3.2.6.exe 
4.2M    SpitfireAudioWinSetup-3.2.6.exe

$ wine --version
wine-5.9-23-gba920246e5

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.


More information about the wine-bugs mailing list