Search code examples
c++dllnotifywinlogon

Winlogon Notification DLL -- Create Process as the user who logged in


I have a requirement to run an app as a user unlocks his computer. This works swimmingly in Win 7 with regular task scheduler. For XP -- ive Created a C++ DLL to do this. This seems to work great, except that it does so under the system account (and thus doesnt show up ont he user's desktop).

I have 2 functions, the first WLEventLogon launches the process under the system acct,

The 2nd, (I havent done C++ in like 15 years so Im a tad rusty!) is most likely wildly incorrect. I'm trying to get a simple app to run on the user's account whenever he unlocks the system.

Below is my code -- the dll works and Ive tested the methods with rundll32 and using them in winlogon/notify

    // Here is the event handler for the Winlogon Logon event.
//__declspec( dllexport ) void WLEventLogon (PWLX_NOTIFICATION_INFO pInfo);

WINLOGINDLL_API void WLEventLogon (PWLX_NOTIFICATION_INFO pInfo)
{   

    const wchar_t* path =  L"C:\\path\\app.exe";


    ShellExecute(GetDesktopWindow(),L"open",path,NULL,NULL,SW_SHOWNORMAL);      
}


WINLOGINDLL_API void Test (PWLX_NOTIFICATION_INFO pInfo)
{   


STARTUPINFOW        lpStartupInfo;
PROCESS_INFORMATION lpProcessInfo;

ZeroMemory(&lpStartupInfo, sizeof(lpStartupInfo));
ZeroMemory(&lpProcessInfo, sizeof(lpProcessInfo));
lpStartupInfo.cb = sizeof(lpStartupInfo);
lpStartupInfo.dwFlags = STARTF_USESHOWWINDOW;
lpStartupInfo.wShowWindow = SW_SHOW;
CreateProcessAsUser(pInfo->hToken, L"C:\\path\\app.exe",L"test",NULL,NULL,FALSE,NULL,NULL,NULL,&lpStartupInfo,&lpProcessInfo);

   }

The 'test' function doesnt seem to be working at all -- My CreateProcessAsUser is most likely wildly wrong.


Solution

  • Did you make sure the hToken value is not NULL? If it is not, try using DuplicateTokenEx() to retreive the user's primary token, then pass that to CreateProcessAsUser().

    WINLOGINDLL_API void Test (PWLX_NOTIFICATION_INFO pInfo)
    {
        if( !pInfo->hToken )
            return;
    
        STARTUPINFOW        lpStartupInfo;
        PROCESS_INFORMATION lpProcessInfo;
        ZeroMemory(&lpStartupInfo, sizeof(lpStartupInfo));
        ZeroMemory(&lpProcessInfo, sizeof(lpProcessInfo));
        lpStartupInfo.cb = sizeof(lpStartupInfo);
        lpStartupInfo.dwFlags = STARTF_USESHOWWINDOW;
        lpStartupInfo.wShowWindow = SW_SHOW;
    
        HANDLE hUserToken;
        if( !DuplicateTokenEx(pInfo->hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hToken) )
            return;
    
        if( CreateProcessAsUser(hUserToken, ...) )
        {
            ...
        }
    
        CloseHandle(hUserToken);
    }