Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1045 lines
27 KiB

/****************************** Module Header ******************************\
* Module Name: provider.c
*
* Copyright (c) 1991, Microsoft Corporation
*
* Implements functions that support multiple network providers.
* Currently this involves notifying credential managers of logon and
* password change operations.
*
* History:
* 01-10-93 Davidc Created.
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
//
// Define this to enable verbose output for this module
//
// #define DEBUG_PROVIDER
#ifdef DEBUG_PROVIDER
#define VerbosePrint(s) WLPrint(s)
#else
#define VerbosePrint(s)
#endif
//
// Define the key in the winlogon section of win.ini that
// defines the the multiple provider notify app name.
//
#define NOTIFY_KEY_NAME TEXT("mpnotify")
//
// Define the default multiple provider notify app name.
//
#define DEFAULT_NOTIFY_APP_NAME TEXT("mpnotify.exe")
//
// Define environment variables used to pass information to multiple
// provider notify process
//
#define MPR_STATION_NAME_VARIABLE TEXT("WlMprNotifyStationName")
#define MPR_STATION_HANDLE_VARIABLE TEXT("WlMprNotifyStationHandle")
#define MPR_WINLOGON_WINDOW_VARIABLE TEXT("WlMprNotifyWinlogonWindow")
#define MPR_LOGON_FLAG_VARIABLE TEXT("WlMprNotifyLogonFlag")
#define MPR_USERNAME_VARIABLE TEXT("WlMprNotifyUserName")
#define MPR_DOMAIN_VARIABLE TEXT("WlMprNotifyDomain")
#define MPR_PASSWORD_VARIABLE TEXT("WlMprNotifyPassword")
#define MPR_OLD_PASSWORD_VARIABLE TEXT("WlMprNotifyOldPassword")
#define MPR_OLD_PASSWORD_VALID_VARIABLE TEXT("WlMprNotifyOldPasswordValid")
#define MPR_LOGONID_VARIABLE TEXT("WlMprNotifyLogonId")
#define MPR_CHANGE_INFO_VARIABLE TEXT("WlMprNotifyChangeInfo")
#define MPR_PASSTHROUGH_VARIABLE TEXT("WlMprNotifyPassThrough")
#define MPR_PROVIDER_VARIABLE TEXT("WlMprNotifyProvider")
// Message we send to ourselves so we can hide.
#define WM_HIDEOURSELVES (WM_USER + 0)
//
// Define the structure used to pass data into the notify control dialog
//
typedef struct {
PGLOBALS pGlobals;
LPWSTR ReturnBuffer; // Returned from dialog
HANDLE hProcess;
POBJECT_MONITOR Monitor;
BOOL ProcessRunning;
} NOTIFY_DATA;
typedef NOTIFY_DATA *PNOTIFY_DATA;
//
// Private prototypes
//
BOOL
MprNotifyDlgInit(
HWND hDlg
);
BOOL
StartNotifyProcessMonitor(
HWND hDlg
);
VOID
DeleteNotifyProcessMonitor(
HWND hDlg
);
BOOL
KillNotifyProcess(
PNOTIFY_DATA pNotifyData
);
/***************************************************************************\
* FUNCTION: DeleteNotifyVariables
*
* PURPOSE: Deletes all the notify data environment variables from the
* current process's environment.
*
* RETURNS: Nothing
*
* HISTORY:
*
* 01-12-93 Davidc Created.
*
\***************************************************************************/
VOID
DeleteNotifyVariables(
VOID
)
{
SetEnvironmentVariable(MPR_STATION_NAME_VARIABLE, NULL);
SetEnvironmentVariable(MPR_STATION_HANDLE_VARIABLE, NULL);
SetEnvironmentVariable(MPR_WINLOGON_WINDOW_VARIABLE, NULL);
SetEnvironmentVariable(MPR_LOGON_FLAG_VARIABLE, NULL);
SetEnvironmentVariable(MPR_USERNAME_VARIABLE, NULL);
SetEnvironmentVariable(MPR_DOMAIN_VARIABLE, NULL);
SetEnvironmentVariable(MPR_PASSWORD_VARIABLE, NULL);
SetEnvironmentVariable(MPR_OLD_PASSWORD_VALID_VARIABLE, NULL);
SetEnvironmentVariable(MPR_OLD_PASSWORD_VARIABLE, NULL);
SetEnvironmentVariable(MPR_LOGONID_VARIABLE, NULL);
SetEnvironmentVariable(MPR_CHANGE_INFO_VARIABLE, NULL);
SetEnvironmentVariable(MPR_PASSTHROUGH_VARIABLE, NULL);
SetEnvironmentVariable(MPR_PROVIDER_VARIABLE, NULL);
}
/***************************************************************************\
* FUNCTION: SetWinlogonWindowVariable
*
* PURPOSE: Sets winlogon window environment variable in current process's
* environment - this is inherited by notify process.
*
* RETURNS: TRUE on success, FALSE on failure
*
* HISTORY:
*
* 01-12-93 Davidc Created.
*
\***************************************************************************/
BOOL
SetWinlogonWindowVariable(
HWND hwnd
)
{
BOOL Result;
Result = SetEnvironmentULong(MPR_WINLOGON_WINDOW_VARIABLE, (ULONG)hwnd);
if (!Result) {
DebugLog((DEB_ERROR, "SetWinlogonWindowVariable: Failed to set variable, error = %d\n", GetLastError()));
}
return(Result);
}
/***************************************************************************\
* FUNCTION: SetCommonNotifyVariables
*
* PURPOSE: Sets environment variables to pass information to notify process
* for data that is common to all notifications.
* The variables are set in winlogon's environment - this is
* inherited by the notify process.
*
* RETURNS: TRUE on success, FALSE on failure
*
* On failure return, all notify variables have been deleted
*
* HISTORY:
*
* 01-12-93 Davidc Created.
*
\***************************************************************************/
BOOL
SetCommonNotifyVariables(
PGLOBALS pGlobals,
HWND hwndOwner,
LPTSTR Name OPTIONAL,
LPTSTR Domain OPTIONAL,
LPTSTR Password OPTIONAL,
LPTSTR OldPassword OPTIONAL
)
{
BOOL Result = TRUE;
if (Result) {
Result = SetEnvironmentVariable(MPR_STATION_NAME_VARIABLE, WINDOW_STATION_NAME);
}
if (Result) {
Result = SetEnvironmentULong(MPR_STATION_HANDLE_VARIABLE, (ULONG)hwndOwner);
}
if (Result && ARGUMENT_PRESENT( Name )) {
Result = SetEnvironmentVariable(MPR_USERNAME_VARIABLE, Name);
}
if (Result && ARGUMENT_PRESENT( Domain )) {
Result = SetEnvironmentVariable(MPR_DOMAIN_VARIABLE, Domain);
}
if (Result && ARGUMENT_PRESENT( Password )) {
Result = SetEnvironmentVariable(MPR_PASSWORD_VARIABLE, Password);
}
if (Result) {
Result = SetEnvironmentULong(MPR_OLD_PASSWORD_VALID_VARIABLE,
(OldPassword != NULL) ? 1 : 0);
}
if (Result) {
Result = SetEnvironmentVariable(MPR_OLD_PASSWORD_VARIABLE, OldPassword);
if (OldPassword == NULL) {
Result = TRUE; // Ignore failure since deleting a variable that
// doesn't exist returns failure.
}
}
if (!Result) {
DebugLog((DEB_ERROR, "SetCommonNotifyVariables: Failed to set a variable, error = %d\n", GetLastError()));
DeleteNotifyVariables();
}
return(Result);
}
/***************************************************************************\
* FUNCTION: SetLogonNotifyVariables
*
* PURPOSE: Sets environment variables to pass information to notify process
* for data that is specific to logon notifications.
* The variables are set in winlogon's environment - this is
* inherited by the notify process.
*
* RETURNS: TRUE on success, FALSE on failure
*
* On failure return, all notify variables have been deleted
*
* HISTORY:
*
* 01-12-93 Davidc Created.
*
\***************************************************************************/
BOOL
SetLogonNotifyVariables(
PLUID LogonId
)
{
BOOL Result;
LARGE_INTEGER LargeInt;
LargeInt.LowPart = LogonId->LowPart;
LargeInt.HighPart = LogonId->HighPart;
Result = SetEnvironmentLargeInt(MPR_LOGONID_VARIABLE, LargeInt);
if (Result) {
Result = SetEnvironmentULong(MPR_LOGON_FLAG_VARIABLE, 1);
}
if (!Result) {
DebugLog((DEB_ERROR, "SetLogonNotifyVariables: Failed to set variable, error = %d\n", GetLastError()));
DeleteNotifyVariables();
}
return(Result);
}
/***************************************************************************\
* FUNCTION: SetChangePasswordNotifyVariables
*
* PURPOSE: Sets environment variables to pass information to notify process
* for data that is specific to change password notifications.
* The variables are set in winlogon's environment - this is
* inherited by the notify process.
*
* RETURNS: TRUE on success, FALSE on failure
*
* On failure return, all notify variables have been deleted
*
* HISTORY:
*
* 01-12-93 Davidc Created.
*
\***************************************************************************/
BOOL
SetChangePasswordNotifyVariables(
DWORD ChangeInfo,
BOOL PassThrough,
PWSTR Provider OPTIONAL
)
{
BOOL Result;
Result = SetEnvironmentULong(MPR_CHANGE_INFO_VARIABLE, ChangeInfo);
if (Result) {
Result = SetEnvironmentULong(MPR_LOGON_FLAG_VARIABLE, 0);
}
if (Result) {
Result = SetEnvironmentULong(MPR_PASSTHROUGH_VARIABLE, (PassThrough ? 1 : 0));
}
if (Result && ARGUMENT_PRESENT( Provider ) )
{
Result = SetEnvironmentVariable( MPR_PROVIDER_VARIABLE, Provider );
}
if (!Result) {
DebugLog((DEB_ERROR, "SetChangePasswordNotifyVariables: Failed to set variable, error = %d\n", GetLastError()));
DeleteNotifyVariables();
}
return(Result);
}
/***************************************************************************\
* FUNCTION: MprNotifyDlgProc
*
* PURPOSE: Processes messages for the Mpr Notify dialog
*
* RETURNS: DLG_SUCCESS - the notification went without a hitch
* - NotifyData->ReturnBuffer is valid.
* DLG_FAILURE - something failed or there is no buffer to return.
* - NotifyData->ReturnBuffer is invalid.
*
* DLG_INTERRUPTED() - a set defined in winlogon.h
*
* HISTORY:
*
* 01-11-93 Davidc Created.
*
\***************************************************************************/
BOOL WINAPI
MprNotifyDlgProc(
HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
PNOTIFY_DATA pNotifyData = (PNOTIFY_DATA)GetWindowLong(hDlg, GWL_USERDATA);
PCOPYDATASTRUCT CopyData;
switch (message) {
case WM_INITDIALOG:
SetWindowLong(hDlg, GWL_USERDATA, lParam);
if (!MprNotifyDlgInit(hDlg)) {
EndDialog(hDlg, DLG_FAILURE);
return(TRUE);
}
//
// Send ourselves a message so we can hide without the
// dialog code trying to force us to be visible
//
PostMessage(hDlg, WM_HIDEOURSELVES, 0, 0);
return(TRUE);
case WM_HIDEOURSELVES:
ShowWindow(hDlg, SW_HIDE);
return(TRUE);
case WLX_WM_SAS:
if (wParam == WLX_SAS_TYPE_USER_LOGOFF)
{
DebugLog((DEB_TRACE_MPR, "Got a logoff notification\n"));
}
//
// Interrupt the notify process
// This gives us a way to terminate the notify process if it hangs up.
//
DebugLog((DEB_TRACE_MPR, "Got SAS message - interrupting notify process\n"));
EndDialog(hDlg, DLG_FAILURE);
return(TRUE);
case WM_COPYDATA:
//
// The notify process completed and is passing us the result
//
CopyData = (PCOPYDATASTRUCT)lParam;
DebugLog((DEB_TRACE_MPR, "Got WM_COPYDATA message from notify process\n"));
DebugLog((DEB_TRACE_MPR, "/tdwData = %d", CopyData->dwData));
DebugLog((DEB_TRACE_MPR, "/tcbData = %d", CopyData->cbData));
//
// End the screen-saver if it's running
// This assumes the screen-saver dialog terminates when it gets SAS.
// If it's not running this will come straight to us which is OK
//
DebugLog((DEB_TRACE_MPR, "Forwarding SAS message to top window\n"));
//ForwardMessage(pNotifyData->pGlobals, WM_SAS, 0, 0);
//
// Copy the passed data and quit this dialog
//
if (CopyData->dwData == 0) {
if (CopyData->cbData != 0) {
pNotifyData->ReturnBuffer = Alloc(CopyData->cbData);
if (pNotifyData->ReturnBuffer != NULL) {
CopyMemory(pNotifyData->ReturnBuffer, CopyData->lpData, CopyData->cbData);
} else {
DebugLog((DEB_ERROR, ("Failed to allocate memory for returned logon scripts")));
}
} else {
pNotifyData->ReturnBuffer = NULL;
}
} else {
DebugLog((DEB_TRACE_MPR, "Notify completed with an error: %d", CopyData->dwData));
}
EndDialog(hDlg, pNotifyData->ReturnBuffer ? DLG_SUCCESS : DLG_FAILURE);
return(TRUE); // We processed this message
case WM_OBJECT_NOTIFY:
//
// The notify process terminated for some reason
//
DebugLog((DEB_TRACE_MPR, "Notify process terminated - got monitor notification\n"));
EndDialog(hDlg, DLG_FAILURE);
return(TRUE);
case WM_DESTROY:
//
// Terminate the notify process and delete the monitor object.
//
if (pNotifyData->ProcessRunning) {
DebugLog((DEB_TRACE_MPR, "NotifyDlgProc: Deleting notify process and monitor\n"));
DeleteNotifyProcessMonitor(hDlg);
KillNotifyProcess(pNotifyData);
}
return(0);
}
// We didn't process the message
return(FALSE);
}
/***************************************************************************\
* FUNCTION: MprNotifyDlgInit
*
* PURPOSE: Handles initialization of Mpr notify dialog
*
* RETURNS: TRUE on success, FALSE on failure
*
* HISTORY:
*
* 01-11-93 Davidc Created.
*
\***************************************************************************/
#if DEVL
BOOL bDebugMpNotify = FALSE;
#endif
BOOL
MprNotifyDlgInit(
HWND hDlg
)
{
PNOTIFY_DATA pNotifyData = (PNOTIFY_DATA)GetWindowLong(hDlg, GWL_USERDATA);
PGLOBALS pGlobals = pNotifyData->pGlobals;
USER_PROCESS_DATA SystemProcessData;
BOOL Success;
LPTSTR NotifyApp;
PROCESS_INFORMATION ProcessInformation;
PWSTR pchCmdLine;
#if DEVL
WCHAR chDebugCmdLine[ MAX_PATH ];
#endif
//
// Initialize flag to show we haven't created the notify process yet
//
pNotifyData->ProcessRunning = FALSE;
//
// Set our size to zero so we we don't appear
//
SetWindowPos(hDlg, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE |
SWP_NOREDRAW | SWP_NOZORDER);
//
// Set the winlogon window variable so the process knows who we are
//
SetWinlogonWindowVariable(hDlg);
//
// Start the notify process in system context
//
SystemProcessData.UserToken = NULL;
SystemProcessData.UserSid = pGlobals->WinlogonSid;
SystemProcessData.NewProcessSD = NULL;
SystemProcessData.NewProcessTokenSD = NULL;
SystemProcessData.NewThreadSD = NULL;
SystemProcessData.NewThreadTokenSD = NULL;
SystemProcessData.Quotas.PagedPoolLimit = 0;
SystemProcessData.CurrentDirectory = NULL;
SystemProcessData.pEnvironment = NULL; // Inherit our environment
//
// Get the name of the notify app
//
NotifyApp = AllocAndGetProfileString(WINLOGON, NOTIFY_KEY_NAME, DEFAULT_NOTIFY_APP_NAME);
if (NotifyApp == NULL) {
DebugLog((DEB_ERROR, "Failed to get name of provider notify app from registry\n"));
return(FALSE);
}
pchCmdLine = NotifyApp;
//
// Try and execute it
//
#if DEVL
if (bDebugMpNotify) {
wsprintf( chDebugCmdLine, TEXT("ntsd -d %s%s"),
bDebugMpNotify == 2 ? TEXT("-g -G ") : TEXT(""),
pchCmdLine
);
pchCmdLine = chDebugCmdLine;
}
#endif
Success = StartSystemProcess(pchCmdLine,
WINLOGON_DESKTOP_PATH,
0,
0,
NULL,
FALSE,
&pNotifyData->hProcess,
NULL);
Free(NotifyApp);
if (!Success) {
DebugLog((DEB_ERROR, "Failed to start multiple provider notifier\n"));
return(FALSE);
}
//
// Store the process id in our notify data for future reference
//
//
// Start the thread that will wait for the notify process to finish
//
if (!StartNotifyProcessMonitor(hDlg)) {
DebugLog((DEB_ERROR, "Failed to start notify process monitor thread\n"));
KillNotifyProcess(pNotifyData);
return(FALSE);
}
//
// Record the fact we started the notify process so we know
// to cleanup during WM_DESTROY
//
pNotifyData->ProcessRunning = TRUE;
// Success
return (TRUE);
}
/***************************************************************************\
* FUNCTION: StartNotifyProcessMonitor
*
* PURPOSE: Creates a thread that waits for the notify process to terminate
*
* RETURNS: TRUE on success, FALSE on failure
*
* HISTORY:
*
* 01-11-93 Davidc Created.
*
\***************************************************************************/
BOOL
StartNotifyProcessMonitor(
HWND hDlg
)
{
PNOTIFY_DATA NotifyData = (PNOTIFY_DATA)GetWindowLong(hDlg, GWL_USERDATA);
NotifyData->Monitor = CreateObjectMonitor(NotifyData->hProcess, hDlg, 0);
if (NotifyData->Monitor == NULL) {
DebugLog((DEB_ERROR, "Failed to create notify process monitor object\n"));
return(FALSE);
}
return TRUE;
}
/***************************************************************************\
* FUNCTION: DeleteNotifyProcessMonitor
*
* PURPOSE: Cleans up resources used by notify process monitor
*
* RETURNS: Nothing
*
* HISTORY:
*
* 01-11-93 Davidc Created.
*
\***************************************************************************/
VOID
DeleteNotifyProcessMonitor(
HWND hDlg
)
{
PNOTIFY_DATA NotifyData = (PNOTIFY_DATA)GetWindowLong(hDlg, GWL_USERDATA);
POBJECT_MONITOR Monitor = NotifyData->Monitor;
HANDLE ProcessHandle = GetObjectMonitorObject(Monitor);
//
// Delete the object monitor
//
DeleteObjectMonitor(Monitor, TRUE);
}
/***************************************************************************\
* FUNCTION: KillNotifyProcess
*
* PURPOSE: Terminates the notify process
*
* RETURNS: TRUE on success, FALSE on failure
*
* HISTORY:
*
* 01-11-93 Davidc Created.
*
\***************************************************************************/
BOOL
KillNotifyProcess(
PNOTIFY_DATA NotifyData
)
{
if (!TerminateProcess(NotifyData->hProcess, STATUS_SUCCESS)) {
DebugLog((DEB_ERROR, "Failed to terminate notification process, error = %d\n", GetLastError()));
return(FALSE);
}
CloseHandle(NotifyData->hProcess);
return(TRUE);
}
/***************************************************************************\
* FUNCTION: NoNeedToNotify
*
* PURPOSE: Determines if it is necessary to call the notify apis.
* It is not necessary if there is only one provider installed.
*
* We use this to save time in the common case where there is
* only one provider. We can avoid the overhead of creating
* the notify process in this case.
*
* RETURNS: TRUE if there is only one provider, otherwise FALSE
*
* HISTORY:
*
* 01-11-93 Davidc Created.
*
\***************************************************************************/
#define NET_PROVIDER_ORDER_KEY TEXT("system\\CurrentControlSet\\Control\\NetworkProvider\\Order")
#define NET_PROVIDER_ORDER_VALUE TEXT("ProviderOrder")
#define NET_ORDER_SEPARATOR TEXT(',')
BOOL
NoNeedToNotify(
VOID
)
{
HKEY ProviderKey;
DWORD Error;
DWORD ValueType;
LPTSTR Value;
BOOL NeedToNotify = TRUE;
Error = RegOpenKeyEx(
HKEY_LOCAL_MACHINE, // hKey
NET_PROVIDER_ORDER_KEY, // lpSubKey
0, // Must be 0
KEY_QUERY_VALUE, // Desired access
&ProviderKey // Newly Opened Key Handle
);
if (Error != ERROR_SUCCESS) {
DebugLog((DEB_ERROR, "NoNeedToNotify - failed to open provider key, assuming notification is necessary\n"));
return(!NeedToNotify);
}
Value = AllocAndRegQueryValueEx(
ProviderKey, // Key
NET_PROVIDER_ORDER_VALUE,// Value name
NULL, // Must be NULL
&ValueType // Type returned here
);
if (Value != NULL) {
if (ValueType == REG_SZ) {
LPTSTR p = Value;
while (*p) {
if (*p == NET_ORDER_SEPARATOR) {
break;
}
p = CharNext(p);
}
if (*p == 0) {
//
// We got to the end without finding a separator
// Only one provider is installed.
//
if (lstrcmpi(Value, SERVICE_WORKSTATION) == 0) {
//
// it's Lanman, don't notify
//
NeedToNotify = FALSE;
} else {
//
// it isn't Lanman, notify
//
NeedToNotify = TRUE;
}
}
} else {
DebugLog((DEB_ERROR, "NoNeedToNotify - provider order key unexpected type: %d, assuming notification is necessary", ValueType));
}
Free(Value);
} else {
DebugLog((DEB_ERROR, "NoNeedToNotify - failed to query provider order value, assuming notification is necessary\n"));
}
Error = RegCloseKey(ProviderKey);
ASSERT(Error == ERROR_SUCCESS);
return(!NeedToNotify);
}
/***************************************************************************\
* MprLogonNotify
*
* Purpose : Notifies credential managers of a logon.
*
* RETURNS: DLG_SUCCESS - the notification went without a hitch
* DLG_FAILURE - something failed.
* DLG_INTERRUPTED() - a set of interruptions defined in winlogon.h
*
* On DLG_SUCCESS return MprLogonScripts contains a pointer to a
* Multi-sz string or NULL if there is no data. i.e. multiple concatenated
* zero terminated strings with a final terminator.
* The memory should be freed by the caller (if pointer non-NULL) using Free().
*
* History:
* 11-12-92 Davidc Created.
\***************************************************************************/
int
MprLogonNotify(
PGLOBALS pGlobals,
HWND hwndOwner,
LPTSTR Name,
LPTSTR Domain,
LPTSTR Password,
LPTSTR OldPassword OPTIONAL,
PLUID LogonId,
LPWSTR *MprLogonScripts
)
{
int Result;
NOTIFY_DATA NotifyData;
//
// Check if we really need to bother with this
//
if (NoNeedToNotify()) {
DebugLog((DEB_TRACE_MPR, "MprLogonNotify - skipping notification - only one provider\n"));
*MprLogonScripts = NULL;
return(DLG_SUCCESS);
}
//
// Set up the environment variables that we will use to pass
// information to notify process
//
if (!SetCommonNotifyVariables(pGlobals,
hwndOwner,
Name,
Domain,
Password,
OldPassword
)) {
return(DLG_FAILURE);
}
if (!SetLogonNotifyVariables(LogonId)) {
return(DLG_FAILURE);
}
//
// Initialize our notify data structure
//
NotifyData.pGlobals = pGlobals;
NotifyData.ReturnBuffer = NULL;
//
// Update windowstation lock so mpnotify can start.
//
UnlockWindowStation(pGlobals->WindowStation.hwinsta);
FastSetWinstaSecurity( &pGlobals->WindowStation,
FALSE );
//
// Create the dialog that will initiate the notify and wait
// for it to complete
//
Result = WlxDialogBoxParam( pGlobals,
pGlobals->hInstance,
(LPTSTR)IDD_CONTROL,
hwndOwner,
MprNotifyDlgProc,
(LONG)&NotifyData);
if (Result == DLG_SUCCESS) {
DebugLog((DEB_TRACE_MPR, "Logon notification return buffer (first string only) = <%ws>\n", NotifyData.ReturnBuffer));
*MprLogonScripts = NotifyData.ReturnBuffer;
} else {
DebugLog((DEB_TRACE_MPR, "Logon notification failed\n"));
}
//
// Re-lock the windowstation.
//
LockWindowStation(pGlobals->WindowStation.hwinsta);
DeleteNotifyVariables();
return(Result);
}
/***************************************************************************\
* MprChangePasswordNotify
*
* Purpose : Notifies credential managers of a password change
*
* RETURNS: DLG_SUCCESS - the notification went without a hitch
* DLG_FAILURE - something failed.
* DLG_INTERRUPTED() - a set of interruptions defined in winlogon.h
*
* History:
* 01-12-93 Davidc Created.
\***************************************************************************/
int
MprChangePasswordNotify(
PGLOBALS pGlobals,
HWND hwndOwner,
PWSTR Provider,
LPTSTR Name,
LPTSTR Domain,
LPTSTR Password,
LPTSTR OldPassword,
DWORD ChangeInfo,
BOOL PassThrough
)
{
int Result;
NOTIFY_DATA NotifyData;
//
// Check if we really need to bother with this
//
if (NoNeedToNotify()) {
DebugLog((DEB_TRACE_MPR, "MprChangePasswordNotify - skipping notification - only one provider\n"));
return(DLG_SUCCESS);
}
//
// Set up the environment variables that we will use to pass
// information to notify process
//
if (!SetCommonNotifyVariables(pGlobals,
hwndOwner,
Name,
Domain,
Password,
OldPassword
)) {
return(DLG_FAILURE);
}
if (!SetChangePasswordNotifyVariables(ChangeInfo,
PassThrough,
Provider ) )
{
return(DLG_FAILURE);
}
//
// Initialize our notify data structure
//
NotifyData.pGlobals = pGlobals;
NotifyData.ReturnBuffer = NULL;
//
// Update windowstation security so mpnotify can start.
//
FastSetWinstaSecurity( &pGlobals->WindowStation,
FALSE );
//
// Create the dialog that will initiate the notify and wait
// for it to complete
//
//
// Set timeout to 5 minutes, so the nwcs provider has time to run.
//
WlxSetTimeout( pGlobals, 5 * 60 );
Result = WlxDialogBoxParam( pGlobals,
pGlobals->hInstance,
(LPTSTR)IDD_CONTROL,
hwndOwner,
MprNotifyDlgProc,
(LONG)&NotifyData);
//
// Reset the windowstation security.
//
FastSetWinstaSecurity( &pGlobals->WindowStation,
TRUE );
if (Result == DLG_SUCCESS) {
Free(NotifyData.ReturnBuffer);
} else {
DebugLog((DEB_TRACE_MPR, "Change password notification failed\n"));
}
DeleteNotifyVariables();
return(Result);
}