GINA DLL Interface API

This section defines the APIs that a GINA DLL must export. Winlogon calls these APIs.

Each API description includes a section called Workstation State that describes which desktop GINA should have set for its thread when the call is made. This section indicates whether the desktop is locked, preventing the display of another desktop, or unlocked, allowing other desktops to be displayed.

WlxNegotiate

Winlogon and a GINA DLL can use this function to determine which version of the interface each was written for.


BOOL
WINAPI
WlxNegotiate(
    DWORD        dwWinlogonVersion,
    DWORD        *pdwDllVersion)

Parameters

dwWinlogonVersion

Version supported by Winlogon.

pdwDllVersion

Version supported by the GINA DLL. This version must be no greater than the version indicated in dwWinlogonVersion. This return value establishes which dispatch table will be passed to GINA in subsequent WlxInitialize() calls.

Workstation State

Thread Desktop:

Winlogon Desktop

Workstation:

Locked

Return Values

TRUE

The GINA DLL can operate with this version of Winlogon. Continue initializing Winlogon.

FALSE

The GINA DLL can not operate with this version of Winlogon. Winlogon (and the system) will not boot.

Sample


WINAPI
WlxNegotiate(
    DWORD        dwWinlogonVersion,
    DWORD        *pdwDllVersion)
{
    if (dwWinlogonVersion < WLX_CURRENT_VERSION)
        // panic: should never happen.
        return(FALSE);

    *pdwDllVersion = WLX_CURRENT_VERSION;
    return(TRUE)
}

WlxInitialize

Winlogon calls this function once for each window station present on the machine. (Note that Windows NT 3.5 supports only one window station. This window station is called "Winsta0". Additional physical window stations may be supported in future releases.) This allows the DLL to initialize itself, including obtaining addresses of Winlogon support functions used by this DLL.

The DLL can return a context pointer that will be passed in all future interactions from Winlogon to GINA. This allows GINA to keep global context associated with this window station.


BOOL
WINAPI
WlxInitialize(
    LPWSTR        lpWinsta,
    HANDLE        hWlx,
    PVOID        pvReserved,
    PVOID        pWinlogonFunctions,
    PVOID        *pWlxContext)

Parameters

lpWinsta

Points to the name of the window station being initialized.

hWlx

Handle to Winlogon that must be provided in future calls related to this window station.

pvReserved

Reserved.

pWinlogonFunctions

Receives a pointer to a Winlogon function dispatch table. The contents of the table is dependent upon the GINA DLL version returned from the WlxNegotiate() call. The table does not change, so the GINA DLL can reference the table rather than copying it.

pWlxContext

This is an OUT parameter. It allows GINA to return a 32-bit context value that will be provided in all future calls related to this window station. Generally the value returned will be something like a pointer to a context structure allocated by GINA for this window station.

Workstation State

Thread Desktop:

Winlogon Desktop

Workstation:

Locked

Return Values

True

Indicates the Gina DLL successfully initialized.

False

Indicates the Gina could not successfully initialize. If the DLL could not initialize, then the system will not boot.

Sample


static    PWLX_DISPATCH_VERSION_1_0    pWinlogon;
VOID
WlxInitialize(
    LPWSTR        lpWinsta,
    HANDLE        hWlx,
    PVOID        pWinlogonFunctions,
    PVOID        *pContext)
{
    PGINA_CONTEXT pGinaContext;

    // allocate a context block for this window station
    AllocateAndInitGinaContext( &pGinaContext, hWlx );
    (*pContext) = pGinaContext;

    // Save away where the dispatch table is
    pWinlogon = (PWLX_DISPATCH_VERSION_1_0)pWinlogonFunctions;

    // Any other initialization that the DLL needs, e.g. open a card
    // reader device

    // Optionally, at this point, call WlxSASNotify(), or return
}

WlxDisplaySASNotice

Winlogon calls this function when there is no one logged on.


VOID
WINAPI
WlxDisplaySASNotice(
    PVOID            pWlxContext)

Parameters

pWlxContext

(IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

Workstation State

Thread Desktop:

Winlogon Desktop

Workstation:

Locked

Return Values

None

Sample


VOID
WINAPI
WlxDisplaySASNotice(
    PVOID    pWlxContext)
{
    PGINA_CONTEXT    pContext;

    pContext = (PGINA_CONTEXT) pWlxContext;
    pContext->pWlxFuncs->WlxDialogBox(    pContext->hWlx,
                        pContext->hDllInstance,
                        MAKEINTRESOURCE(IDD_WELCOME_DIALOG),
                        NULL,
                        WelcomeDlgProc);
}

WlxLoggedOutSAS

Winlogon calls this function when an SAS event is received and no one is logged on. This indicates that a logon attempt should be made.


BOOL
WINAPI
WlxLoggedOutSas(
    PVOID            pWlxContext,
    DWORD            dwSasType,
    PLUID            pAuthenticationId,
    PSID            pLogonSid,
    PDWORD            pdwOptions,
    PHANDLE            phToken,
    PWLX_MPR_NOTIFY_INFO    pMprNotifyInfo,
    PVOID *            pProfile)

Parameters

pWlxContext

(IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

dwSasType

(IN parameter) A value indicating what type of secure attention sequence was entered. Values below WLX_SAS_TYPE_MAX_MSFT_VALUE are used to define Microsoft standard secure attention sequences. Values above this value are for definition by GINA developers.

pAuthenticationId

(IN parameter) The AuthenticationID associated with this logon. The GINA DLL should pass this value as the LogonId parameter to the LsaLogonUser() call. The pointer is good only until this routine returns. To keep the LUID value longer than that, the GINA DLL should copy it before returning.

pLogonSid

(IN parameter) This parameter contains a pointer to a SID. This sid is unique to this logon session. Winlogon uses this SID to change the protection on the window station and application desktop so that the newly logged on user can access them. To ensure proper user shell access to these objects, the GINA DLL should include this SID in the LocalGroups parameter passed to LsaLogonUser(). Winlogon frees this SID upon return from this call, so if it is required by GINA after returning, a copy must be made in this routine.

pdwOptions

(OUT parameter) Receives a set of logon options. These options are defined by the manifest constants named WLX_LOGON_OPT_xxx.

phToken

(OUT parameter) Upon completion of a successful logon, receives a handle that must be filled in upon return if a logon was successfully performed. This handle value is typically received from LsaLogonUser(). Winlogon closes this handle when it is done with it, so if the GINA DLL should be able to access the token, it should make a duplicate of this handle.

pMprNotifyInfo

(OUT parameter) This parameter contains a pointer to a structure for returning password information to other network providers. A GINA is not required to return this information. If a GINA returns password information, then it should fill in the pointers in the structure. Any NULL field in the structure will be ignored by Winlogon. The strings should be allocated individually by the GINA, and they will be freed by Winlogon.

pProfile

(OUT parameter) Upon return from a successful authentication, this field must point to one of the WLX_PROFILE_xxx structures. The first DWORD in the profile structure is used to indicate which of the WLX_PROFILE_xxx structures is being returned. The information in this structure is used by Winlogon to load the logged on user's profile. This structure, and any strings or buffers pointed to from withing this structure are freed by Winlogon when no longer needed.

Workstation State

Thread Desktop:

Winlogon Desktop

Workstation:

Locked

Return Values

WLX_SAS_ACTION_LOGON

A user has logged on.

WLX_SAS_ACTION_NONE

A logon attempt was unsuccessful or cancelled.

WLX_SAS_ACTION_SHUTDOWN

The user requested the system be shut down.

Sample


#define    LOCAL_GROUP_COUNT    (1)
WINAPI
WlxLoggedOutSas(
    PVOID            pWlxContext,
    DWORD            dwSasType,
    PLUID            pAuthenticationId,
    PSID            pLogonSid,
    PDWORD            pdwOptions,
    PHANDLE            phToken,
    PWLX_NPR_NOTIFY_INFO    pNprNotifyInfo,
    PVOID            pProfile)
{
    HANDLE        hToken;
    NTSTATUS    Status;
    INT        LengthLocalGroups;
    PTOKEN_GROUPS    LocalGroups;

    //
    // Gather credentials, e.g. from card reader
    //

    // Log the user on using LSA
    // Be sure to include the LogonSid in the token
    LengthLocalGroups = sizeof( TOKEN_GROUPS + 
                (LOCAL_GROUP_COUNT * sizeof(SID_AND_ATTRIBUTES_ARRAY)) );
    LocalGroups = (PTOKEN_GROUPS)Alloc(LengthLocalGroups);
    if (LocalGroups == NULL) return(FALSE);
    LocalGroups->GroupCount = LOCAL_GROUP_COUNT;
    LocalGroups->Groups[0].Sid = LogonSid;
    LocalGroups->Groups[0].Attributes =   SE_GROUP_ENABLED
                        | SE_GROUP_LOGON_ID
                        | SE_GROUP_MANDATORY
                        | SE_GROUP_ENABLED_BY_DEFAULT
    
    Status = LsaLogonUser(..,LocalGroups.., &hToken,...);
    Free(LocalGroups);
    if (!NT_SUCCESS(Status))
    {
        // Fail the logon.  Note, one could also reprompt, handle expired
        // passwords, etc
        return (FALSE);
    }
    
    *phToken = hToken;
    *ppszPassword = ???;    // If you have a password, return one.
                // Otherwise, return NULL and MPR apps will not get any credentials
    return (TRUE);
}

WlxActivateUserShell

Winlogon calls this function following a successful logon. Its purpose is to request GINA to activate the user shell program(s). Note that the user shell should be activated in this routine rather than in WlxLoggedOffSas() so that Winlogon has a chance to update its state, including setting workstation and desktop protections, before any logged-on user processes are allowed to run.


BOOL
WINAPI
WlxActivateUserShell(
    PVOID            pWlxContext,
    PWSTR            pszDesktopName,
    PWSTR            pszMprLogonScripts,
    PVOID            pEnvironment)

Parameters

pWlxContext

(IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

pszDesktopName

(IN parameter) Name of the desktop on which to start the shell. This should be supplied to CreateProcess() in the lpStartupInfo->lpDesktop field (q.v).

pszMprLogonScripts

(IN parameter) Script names returned from the provider DLLs. Provider DLLs may return scripts to be executed during logon. The GINA may reject these, but Winlogon will provide them if they are there.

pEnvironment

(IN parameter) Initial environment for the process. Winlogon creates this environment and hands it off to the GINA. The GINA can modify this environment before using it to initialize the user's shell.

Workstation State

Thread Desktop:

Application Desktop

Workstation:

Not Locked

Return Values

TRUE

Indicates that the shell processes were started by the GINA DLL.

FALSE

Indicates that the GINA could not start the shell, and that the logon session should be terminated by Winlogon.

Sample


WINAPI
WlxActivateUserShell(
    PVOID            pWlxContext,
    PWSTR            pszDesktopName,
    PWSTR            pszMprLogonScript,
    PVOID            pEnvironment)
{
    BOOL st;

    st = GinaActivateShellSuspended(pGinaContext, pszDesktopName, pEnvironment);
    if (!st) {
        return (FALSE);    // Could not start shell.  Tell Winlogon to start a logoff
    }
    return(TRUE);
}

Notes

The pszDesktop parameter should be passed to the CreateProcess API through the field lpDesktop in the STARTUPINFO structure. This field is designated "Reserved for future use. Must be NULL." in the Win32 documentation, but pass this parameter in.

WlxLoggedOnSAS

Winlogon calls this function when an SAS event is received, and there is a user logged on. This indicates that the user needs to talk to the security system. Note, this is distinguished from when the workstation is locked; see below.


int
WINAPI
WlxLoggedOnSAS(
    PVOID            pWlxContext,
    DWORD            dwSasType,
    PVOID            pReserved)

Parameters

pWlxContext

(IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

dwSasType

(IN parameter) A value indicating what type of secure attention sequence was entered. Values below WLX_SAS_TYPE_MAX_MSFT_VALUE are used to define Microsoft standard secure attention sequences. Values above this value are for definition by GINA developers.

pReserved

(IN parameter) Reserved.

Workstation State

Thread Desktop:

Winlogon Desktop

Workstation:

Locked

Return Values

WLX_SAS_ACTION_NONE

Return to the default desktop.

WLX_SAS_ACTION_LOCK_WKSTA

Lock the workstation, wait for next SAS.

WLX_SAS_ACTION_LOGOFF

Log the user off of the workstation.

WLX_SAS_ACTION_SHUTDOWN

Log the user off and shutdown the machine.

WLX_SAS_ACTION_SHUTDOWN_REBOOT

Shut down and reboot the machine.

WLX_SAS_ACTION_SHUTDOWN_POWER_OFF

Shut down and turn off the machine, if hardware allows.

WLX_SAS_ACTION_PWD_CHANGED

Indicates that the user changed their password. Notify network providers.

WLX_SAS_ACTION_TASKLIST

Invoke the task list.

This function is used generally when the logged-on user wishes to shut down, log out, or lock the workstation. The extension DLL can lock the workstation by returning WLX_LOCK_WKSTA. Winlogon locks the workstation, and calls WlxWkstaLockedSAS the next time an SAS is received.

The extension DLL can use the profile to determine any information needed about the system.

Sample


WINAPI
WlxLoggedOnSAS(
    PVOID            pWlxContext,
    DWORD            dwSasType,
    PVOID            pReserved)
{
    int    Ret;
    switch (

    Ret = MyLoggedOnSasDialog( pWlxContext );
    switch (Ret)
    {
        case    IDCANCEL:
            return (WLX_SAS_ACTION_NONE);

        case    MY_ID_LOCKWINSTA:
            return (WLX_SAS_ACTION_LOCK_WKSTA);

        case    MY_ID_CHANGEPWD:
            // run a password change dialog

        case    MY_ID_TASKLIST:
            return(WLX_SAS_ACTION_TASKLIST );

        case    MY_ID_SHUTDOWN:
            return(WLX_SAS_ACTION_SHUTDOWN);

        case    MY_ID_LOGOFF:
            return(WLX_LOGOFF);
    }
}

WlxDisplayLockedNotice

Winlogon calls this function when the workstation is placed in the locked state. This allows the GINA to display information about the lock, such as who locked the workstation and when. The GINA should display a dialog box that will be interrupted by a WLX_WM_SAS message, much like the WlxDisplaySASNotice function.


VOID
WINAPI
WlxDisplayLockedNotice(
    PVOID            pWlxContext)

Parameters

pWlxContext

(IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

Return Value

None

This function should display a notice that describes the machine as locked.

WlxIsLockOk

Winlogon calls this function before locking the workstation, if, for example, a screen saver is marked as secure.


BOOL
WINAPI
WlxIsLockOk(
    PVOID            pWlxContext)

Parameters

pWlxContext

IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

Return Values

True

Indicates it is OK to lock the workstation.

False

Indicates it is not OK to lock the workstation.

WlxWkstaLockedSAS

Winlogon calls this function when it receives an SAS and the workstation is locked. GINA may return indicating the workstation is to remain locked, the workstation is to be unlocked, or the logged-on user is being forced to log off (which leaves the workstation locked until the logoff is completed).


int
WINAPI
WlxWkstaLockedSAS(
    PVOID            pWlxContext,
    DWORD            dwSasType)

Parameters

pWlxContext

(IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

dwSasType

(IN parameter) A value indicating what type of secure attention sequence was entered. Values below WLX_SAS_TYPE_MAX_MSFT_VALUE are used to define Microsoft standard secure attention sequences. Values above this value are for definition by GINA developers.

Workstation State

Thread Desktop:

Winlogon Desktop

Workstation:

Locked

Return Values

WLX_SAS_ACTION_NONE

Workstation remains locked.

WLX_SAS_ACTION_UNLOCK_WKSTA

Unlock the workstation.

WLX_SAS_ACTION_FORCE_LOGOFF

Force the user to log off.

Sample


WINAPI
WlxWkstaLockedSAS(
    PVOID            pWlxContext)
{
    //
    //  Validate the users credentials again (e.g. read from smart
    //  card reader)
    //

    if (valid credentials)
    {
        return(WLX_UNLOCK_WKSTA);
    }

    if (administrative override)
    {
        return(WLX_FORCE_LOGOFF);
    }

    return(WLX_NO_ACTION);
}

WlxIsLogoffOk

Winlogon calls this function when the user has initiated a logoff, for eaxmple by calling ExitWindowsEx(). The GINA can determine whether the logoff attempt is to be allowed.


BOOL
WINAPI
WlxIsLockOk(
    PVOID            pWlxContext)

Parameters

pWlxContext

(IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

Return Values

True

Indicates that it is OK to lock the workstation.

False

Indicates that it is not OK to lock the workstation.

WlxLogoff

Winlogon calls this function to notify GINA of a logoff on this workstation. No action is necessary.


VOID
WINAPI
WlxLogoff(
    PVOID            pWlxContext)

Parameters

pWlxContext

(IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

Workstation State

Thread Desktop:

Winlogon Desktop

Workstation:

Locked

Return Values

None.

Sample


VOID
WlxLogoff(
    PVOID            pWlxContext)
{
    //
    // Logoff action, if any:
    //
    // e.g. spit out the smart card from the smart card reader...
}

WlxShutdown

Winlogon calls this function right before shutdown so GINA can perform any shutdown tasks, such as ejecting a smart card from a reader. The user has already logged off, and the WlxLogoff function has been called.


VOID
WINAPI
WlxShutdown(
    PVOID            pWlxContext,
    DWORD            ShutdownType)

Parameters

pWlxContext

(IN parameter) Context value associated with this window station that GINA returned in the WlxInitialize() call.

ShutdownType

(IN parameter) Type of shutdown, one of: WLX_SAS_ACTION_SHUTDOWN, WLX_SAS_ACTION_SHUTDOWN_REBOOT, or WLX_SAS_ACTION_SHUTDOWN_POWER_OFF.

Workstation State

Thread Desktop:

Application desktop if user logged on and the workstation isn't locked, otherwise Winlogon desktop.

Workstation:

Not locked if application desktop, locked if Winlogon desktop.

Return Values

None.

Sample


VOID
 WlxShutdown(
    PVOID            pWlxContext,
    DWORD            ShutdownType)
{
    PGINA_CONTEXT    pGinaContext = (PGINA_CONTEXT)pWlxContext;
    CloseHandle(GinaContext->hCardReaderDevice);
    return;
}