Just Let It Flow

August 22, 2010

Things Microsoft Can Do That You Can’t

Filed under: Windows — adeyblue @ 4:03 am

Fading Between Desktops

From a macro standpoint, the Windows Vista/7 login process follows the same architecture as all the previous NT versions. It starts with the dialog that you enter the details in, it validates the credentials, then it switches the view from the winlogon secure desktop to the WinSta0\default. As I’m sure you noticed, this last step is where the biggest difference between Vista and the previous generation is. Instead of just plain switching there’s a fade to black first and then the switch happens before the fade is reversed.

All of this extra behaviour is implemented by the user32.dll function SwitchDesktopWithFade(HDESK hDesk, DWORD duration). Well, that’s mostly a lie as the export is nothing more than a user mode trampoline to NtUserSwitchDesktop. So there’s nothing untoward happening so far, what stops you from achieving the same effect? Well, this:

.text:BF8235D1 ; __stdcall xxxSwitchDesktopWithFade(x, x, x, x)
.text:BF8235D1 _xxxSwitchDesktopWithFade@16 proc near  ; CODE XREF: NtUserSwitchDesktop(x,x)+AD
.text:BF8235D1
.text:BF8235D1                 mov     edi, edi
.text:BF8235D3                 push    ebp
.text:BF8235D4                 mov     ebp, esp
.text:BF8235D6                 sub     esp, 28h                          ; setup local variables
.text:BF8235D9                 call    ds:__imp__PsGetCurrentProcessId@0 ; Call PsGetCurrentProcessId()
.text:BF8235DF                 cmp     eax, _gpidLogon                   ; See if the pid is the same as the logon process
.text:BF8235E5                 jz      short loc_BF8235F1                ; if it is, do the function
.text:BF8235E7                 mov     eax, 0C0000022h                   ; else return STATUS_ACCESS_DENIED
.text:BF8235EC                 jmp     locret_BF82373F

After NtUserSwitchDesktop validates the parameters and checks the request is a fade operation, it calls xxxSwitchDesktopWithFade(tagWINDOWSTATION* pDeskWinSta, tagDESKTOP* pDesk, ULONG flags, ULONG fadeTime) which does the above comparison. Only the process which calls RegisterLogonProcess can therefore use this SwitchDesktopWithFade and as the checked build mesage in _RegisterLogonProcess says:

.text:BF8BFB2F                 push    ecx
.text:BF8BFB30                 push    offset aOnlyWinlogonPi ; "Only winlogon (pid = 0x%x) can call this API"
.text:BF8BFB35                 push    offset a_registerlogon ; "_RegisterLogonProcess"
.text:BF8BFB3A                 push    2Dh
.text:BF8BFB3C                 push    offset aDWin7rcWind_13 ; "d:\\win7rc\\windows\\core\\ntuser\\kernel\\lo"...
.text:BF8BFB41                 push    5
.text:BF8BFB43                 push    2000000h
.text:BF8BFB48                 call    _VRipOutput
...

So unless you replace winlogon, you ain’t fading between desktops anytime soon.

1 Comment »

  1. nice 🙂 during NtUserSwitchDesktop debugging I found out, there’s xxxSwitchDesktopWithFade API fn. I like it and I’m going to simulate this fn (with using GetDeviceGammaRamp/SetDeviceGammaRamp APIs). If you debug that win32k’s fade fn, it also uses Gre[Get/Set]DeviceGammaRamp internal functions.

    Comment by pk — March 10, 2011 @ 3:25 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress