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;
}