summaryrefslogtreecommitdiffstats
path: root/private/nw/svcdlls/nwwks/client/nwdlg.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/nw/svcdlls/nwwks/client/nwdlg.c')
-rw-r--r--private/nw/svcdlls/nwwks/client/nwdlg.c3964
1 files changed, 3964 insertions, 0 deletions
diff --git a/private/nw/svcdlls/nwwks/client/nwdlg.c b/private/nw/svcdlls/nwwks/client/nwdlg.c
new file mode 100644
index 000000000..d22191af8
--- /dev/null
+++ b/private/nw/svcdlls/nwwks/client/nwdlg.c
@@ -0,0 +1,3964 @@
+/*++
+
+Copyright (c) 1993, 1994 Microsoft Corporation
+
+Module Name:
+
+ nwdlg.c
+
+Abstract:
+
+ This module contains NetWare Network Provider Dialog code.
+ It contains all functions used in handling the dialogs
+ shown by the provider.
+
+
+Author:
+
+ Yi-Hsin Sung (yihsins) 5-July-1993
+ Split from provider.c
+
+Revision History:
+
+ Rita Wong (ritaw) 10-Apr-1994
+ Added change password functionality.
+
+--*/
+
+#include <nwclient.h>
+#include <nwsnames.h>
+#include <nwcanon.h>
+#include <validc.h>
+#include <nwevent.h>
+#include <ntmsv1_0.h>
+#include <nwdlg.h>
+#include <tstr.h>
+#include <align.h>
+#include <nwpkstr.h>
+
+#include <nwreg.h>
+#include <nwlsa.h>
+#include <nwmisc.h>
+#include <nwauth.h>
+#include <nwutil.h>
+#include <ntddnwfs.h>
+#include <nds.h>
+
+#define NW_ENUM_EXTRA_BYTES 256
+
+#define IS_TREE(p) (*p == TREE_CHAR)
+
+//-------------------------------------------------------------------//
+// //
+// Local Function Prototypes //
+// //
+//-------------------------------------------------------------------//
+
+VOID
+NwpAddToComboBox(
+ IN HWND DialogHandle,
+ IN INT ControlId,
+ IN LPWSTR pszNone OPTIONAL,
+ IN BOOL AllowNone
+ );
+
+BOOL
+WINAPI
+NwpConnectDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ );
+
+VOID
+NwpCenterDialog(
+ IN HWND hwnd
+ );
+
+HWND
+NwpGetParentHwnd(
+ VOID
+ );
+
+VOID
+NwpGetNoneString(
+ LPWSTR pszNone,
+ DWORD cBufferSize
+ );
+
+VOID
+NwpAddNetWareTreeConnectionsToList(
+ IN HWND DialogHandle,
+ IN LPWSTR NtUserName,
+ IN LPDWORD lpdwUserLuid,
+ IN INT ControlId
+ );
+
+VOID
+NwpAddServersToControl(
+ IN HWND DialogHandle,
+ IN INT ControlId,
+ IN UINT Message,
+ IN INT ControlIdMatch OPTIONAL,
+ IN UINT FindMessage
+ );
+
+VOID
+NwpAddTreeNamesToControl(
+ IN HWND DialogHandle,
+ IN INT ControlId,
+ IN UINT Message,
+ IN INT ControlIdMatch OPTIONAL,
+ IN UINT FindMessage
+ );
+
+DWORD
+NwpGetTreesAndChangePw(
+ IN HWND DialogHandle,
+ IN LPWSTR ServerBuf,
+ IN DWORD UserLuid,
+ IN PCHANGE_PW_DLG_PARAM Credential
+ );
+
+BOOL
+WINAPI
+NwpOldPasswordDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ );
+
+BOOL
+WINAPI
+NwpAltUserNameDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ );
+
+VOID
+EnableAddRemove(
+ IN HWND DialogHandle
+ );
+
+
+BOOL
+WINAPI
+NwpLoginDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+/*++
+
+Routine Description:
+
+ This function is the window management message handler which
+ initializes, and reads user input from the login dialog. It also
+ checks that the preferred server name is valid, notifies the user
+ if not, and dismisses the dialog when done.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to the login dialog.
+
+ Message - Supplies the window management message.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ static PLOGINDLGPARAM pLoginParam;
+ static WCHAR OrigPassword[NW_MAX_SERVER_LEN + 1];
+ static WCHAR pszNone[64];
+
+ DWORD status = NO_ERROR;
+ DWORD dwNoneIndex = 0;
+ BOOL enableServer = TRUE ;
+
+ switch (Message) {
+
+ case WM_INITDIALOG:
+
+ pLoginParam = (PLOGINDLGPARAM) LParam;
+
+ //
+ // Store the original password
+ //
+ wcscpy( OrigPassword, pLoginParam->Password );
+
+ //
+ // Position dialog
+ //
+ NwpCenterDialog(DialogHandle);
+
+ //
+ // Handle logon script button
+ //
+ if ( pLoginParam->LogonScriptOptions & NW_LOGONSCRIPT_ENABLED )
+ CheckDlgButton( DialogHandle, ID_LOGONSCRIPT, 1 );
+ else
+ CheckDlgButton( DialogHandle, ID_LOGONSCRIPT, 0 );
+
+ //
+ // Username. Just display the original.
+ //
+ SetDlgItemTextW(DialogHandle, ID_USERNAME, pLoginParam->UserName);
+
+ //
+ // Initialize the <None> string.
+ //
+ NwpGetNoneString( pszNone, sizeof( pszNone) );
+
+ //
+ // Set the values in combo-box list.
+ //
+ NwpAddToComboBox(DialogHandle, ID_SERVER, pszNone, TRUE);
+
+ //
+ // Initially, select the last entry in server list, which should
+ // be the <None> entry.
+ //
+ dwNoneIndex = SendDlgItemMessageW(
+ DialogHandle,
+ ID_SERVER,
+ CB_GETCOUNT,
+ 0,
+ 0 );
+
+ if ( dwNoneIndex != CB_ERR && dwNoneIndex > 0 )
+ dwNoneIndex -= 1;
+
+ (void) SendDlgItemMessageW(
+ DialogHandle,
+ ID_SERVER,
+ CB_SETCURSEL,
+ dwNoneIndex == CB_ERR ? 0 : dwNoneIndex,
+ 0 );
+
+ //
+ // Display the previously saved preferred server or context.
+ // Also set appropriate radio button
+ //
+ if ( *(pLoginParam->ServerName) != NW_INVALID_SERVER_CHAR )
+ {
+ if ( !IS_TREE(pLoginParam->ServerName) )
+ {
+ //
+ // regular server
+ //
+ if (SendDlgItemMessageW(
+ DialogHandle,
+ ID_SERVER,
+ CB_SELECTSTRING,
+ 0,
+ (LPARAM) pLoginParam->ServerName
+ ) == CB_ERR) {
+
+ //
+ // Did not find preferred server in the combo-box,
+ // just set the old value in the edit item.
+ //
+ SetDlgItemTextW( DialogHandle, ID_SERVER,
+ pLoginParam->ServerName);
+ }
+ }
+ else
+ {
+ //
+ // we are dealing with *tree\context. break it into
+ // tree and context
+ //
+
+ WCHAR *pszTmp = wcschr(pLoginParam->ServerName + 1, L'\\') ;
+
+ if (pszTmp)
+ *pszTmp = 0 ;
+
+ SetDlgItemTextW( DialogHandle, ID_DEFAULTTREE,
+ pLoginParam->ServerName + 1);
+
+ SetDlgItemTextW( DialogHandle, ID_DEFAULTCONTEXT,
+ pszTmp ? (pszTmp + 1) : L"");
+
+ if (pszTmp)
+ *pszTmp = L'\\' ; // restore the '\'
+
+ enableServer = FALSE ;
+
+ }
+ }
+
+
+ //
+ // enable appropriate buttons
+ //
+ CheckRadioButton( DialogHandle,
+ ID_PREFERREDSERVER_RB,
+ ID_DEFAULTCONTEXT_RB,
+ enableServer ?
+ ID_PREFERREDSERVER_RB :
+ ID_DEFAULTCONTEXT_RB) ;
+ EnableWindow ( GetDlgItem ( DialogHandle,
+ ID_SERVER ),
+ enableServer ) ;
+ EnableWindow ( GetDlgItem ( DialogHandle,
+ ID_DEFAULTTREE ),
+ !enableServer ) ;
+ EnableWindow ( GetDlgItem ( DialogHandle,
+ ID_DEFAULTCONTEXT ),
+ !enableServer ) ;
+ SetFocus ( GetDlgItem ( DialogHandle,
+ enableServer ? ID_SERVER : ID_DEFAULTTREE ) ) ;
+
+ //
+ // Preferred server name is limited to 48 characters.
+ // Tree is limited to 32. We limit context to 256 - MAXTREE - 3
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_SERVER,
+ CB_LIMITTEXT,
+ NW_MAX_SERVER_LEN - 1,
+ 0
+ );
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_DEFAULTTREE,
+ EM_LIMITTEXT,
+ NW_MAX_TREE_LEN - 1,
+ 0
+ );
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_DEFAULTCONTEXT,
+ EM_LIMITTEXT,
+ (256 - NW_MAX_TREE_LEN) - 4, // -4 for backslashes unc style
+ 0
+ );
+
+ return TRUE;
+
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam)) {
+
+ case ID_DEFAULTCONTEXT_RB :
+ if ( (HIWORD(WParam) == BN_CLICKED )
+ || (HIWORD(WParam) == BN_DOUBLECLICKED )
+ )
+ {
+ CheckRadioButton( DialogHandle,
+ ID_PREFERREDSERVER_RB,
+ ID_DEFAULTCONTEXT_RB,
+ ID_DEFAULTCONTEXT_RB) ;
+ EnableWindow ( GetDlgItem ( DialogHandle,
+ ID_SERVER ),
+ FALSE ) ;
+ EnableWindow ( GetDlgItem ( DialogHandle,
+ ID_DEFAULTTREE ),
+ TRUE ) ;
+ EnableWindow ( GetDlgItem ( DialogHandle,
+ ID_DEFAULTCONTEXT ),
+ TRUE ) ;
+ SetFocus ( GetDlgItem ( DialogHandle,
+ ID_DEFAULTTREE ) ) ;
+ }
+ break ;
+
+ case ID_PREFERREDSERVER_RB :
+ if ( (HIWORD(WParam) == BN_CLICKED )
+ || (HIWORD(WParam) == BN_DOUBLECLICKED )
+ )
+ {
+ CheckRadioButton( DialogHandle,
+ ID_PREFERREDSERVER_RB,
+ ID_DEFAULTCONTEXT_RB,
+ ID_PREFERREDSERVER_RB) ;
+ EnableWindow ( GetDlgItem ( DialogHandle,
+ ID_SERVER ),
+ TRUE ) ;
+ EnableWindow ( GetDlgItem ( DialogHandle,
+ ID_DEFAULTTREE ),
+ FALSE ) ;
+ EnableWindow ( GetDlgItem ( DialogHandle,
+ ID_DEFAULTCONTEXT ),
+ FALSE ) ;
+ SetFocus ( GetDlgItem ( DialogHandle, ID_SERVER ) ) ;
+ }
+ break ;
+
+ //
+ // Use the user's original password when
+ // the user types in or selects a new server or context
+ //
+ case ID_DEFAULTTREE:
+ case ID_DEFAULTCONTEXT:
+ if ( HIWORD(WParam) == EN_CHANGE )
+ {
+ wcscpy( pLoginParam->Password, OrigPassword );
+ }
+ break;
+ case ID_SERVER:
+ if ( (HIWORD(WParam) == CBN_EDITCHANGE )
+ || (HIWORD(WParam) == CBN_SELCHANGE )
+ )
+ {
+ wcscpy( pLoginParam->Password, OrigPassword );
+ }
+ break;
+
+ case IDOK: {
+
+ LPWSTR pszLocation = NULL;
+
+ ASSERT(pLoginParam->ServerNameSize >= MAX_PATH) ;
+
+ //
+ // Allocate a buffer big enough to hold the Preferred
+ // Server name or the NDS Tree and context in the form:
+ // *Tree(Context). Therefore we allocate twice the space
+ // needed for a UNICODE Server name.
+ //
+ if ((pszLocation =
+ LocalAlloc(LMEM_ZEROINIT,
+ (pLoginParam->ServerNameSize * sizeof(WCHAR) * 2))
+ ) == NULL )
+ {
+ break;
+ }
+
+ //
+ // Read the server or tree/context and validate its value.
+ //
+ if (IsDlgButtonChecked(DialogHandle, ID_DEFAULTCONTEXT_RB))
+ {
+ //
+ // We are dealing with TREE/CONTEXT. Synthesize string
+ // in "*TREE\CONTEXT" format.
+ //
+ WCHAR *pTmp ;
+ *pszLocation = TREE_CHAR ;
+
+ if (!GetDlgItemTextW(
+ DialogHandle,
+ ID_DEFAULTTREE,
+ pszLocation + 1,
+ pLoginParam->ServerNameSize - 1
+ ))
+ {
+ //
+ // The tree name field was blank!
+ // Prompt user to provide a NDS tree name.
+ //
+ LocalFree( pszLocation );
+
+ (void) NwpMessageBoxError(
+ DialogHandle,
+ IDS_AUTH_FAILURE_TITLE,
+ IDS_TREE_NAME_MISSING,
+ 0,
+ NULL,
+ MB_OK | MB_ICONSTOP
+ );
+
+ //
+ // Put the focus where the user can fix the
+ // invalid tree name.
+ //
+ SetFocus(GetDlgItem(DialogHandle,ID_DEFAULTTREE));
+
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_DEFAULTTREE,
+ EM_SETSEL,
+ 0,
+ MAKELPARAM(0, -1)
+ );
+
+ return TRUE;
+ }
+
+ pTmp = pszLocation + wcslen( pszLocation );
+ *pTmp++ = L'\\' ;
+
+ if (!GetDlgItemTextW(
+ DialogHandle,
+ ID_DEFAULTCONTEXT,
+ pTmp,
+ pLoginParam->ServerNameSize - (pTmp-pszLocation)
+ ))
+ {
+ //
+ // The context name field was blank!
+ // Prompt user to provide a NDS context name.
+ //
+ LocalFree( pszLocation );
+
+ (void) NwpMessageBoxError(
+ DialogHandle,
+ IDS_AUTH_FAILURE_TITLE,
+ IDS_CONTEXT_MISSING,
+ 0,
+ NULL,
+ MB_OK | MB_ICONSTOP
+ );
+
+ //
+ // Put the focus where the user can fix the
+ // invalid context name.
+ //
+ SetFocus(GetDlgItem(DialogHandle,ID_DEFAULTCONTEXT));
+
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_DEFAULTCONTEXT,
+ EM_SETSEL,
+ 0,
+ MAKELPARAM(0, -1)
+ );
+
+ return TRUE;
+ }
+ }
+ else
+ {
+ //
+ // Straight server. Just read it in. If we cant get it
+ // or is empty, use <None>.
+ //
+ if (GetDlgItemTextW(
+ DialogHandle,
+ ID_SERVER,
+ pszLocation,
+ pLoginParam->ServerNameSize
+ ) == 0)
+ {
+ wcscpy( pszLocation, pszNone );
+ }
+ }
+
+ if (( lstrcmpi( pszLocation, pszNone ) != 0) &&
+ ( !IS_TREE( pszLocation )) &&
+ ( !IS_VALID_TOKEN( pszLocation,wcslen( pszLocation ))))
+ {
+ //
+ // Put up message box complaining about the bad
+ // server name.
+ //
+ (void) NwpMessageBoxError(
+ DialogHandle,
+ IDS_AUTH_FAILURE_TITLE,
+ IDS_INVALID_SERVER,
+ 0,
+ NULL,
+ MB_OK | MB_ICONSTOP
+ );
+
+ //
+ // Put the focus where the user can fix the
+ // invalid name.
+ //
+ SetFocus(GetDlgItem(DialogHandle, ID_SERVER));
+
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_SERVER,
+ EM_SETSEL,
+ 0,
+ MAKELPARAM(0, -1)
+ );
+
+ return TRUE;
+ }
+
+ //
+ // If the user select <NONE>,
+ // change it to empty string.
+ //
+ if (lstrcmpi( pszLocation, pszNone) == 0) {
+
+ wcscpy( pszLocation, L"" );
+ }
+
+#if DBG
+ IF_DEBUG(LOGON) {
+ KdPrint(("\n\t[OK] was pressed\n"));
+ KdPrint(("\tNwrLogonUser\n"));
+ KdPrint(("\tPassword : %ws\n",pLoginParam->Password));
+ KdPrint(("\tServer : %ws\n",pszLocation ));
+ }
+#endif
+
+
+ while(1)
+ {
+ PROMPTDLGPARAM PasswdPromptParam;
+ INT Result ;
+
+ //
+ // make sure this user is logged off
+ //
+ (void) NwrLogoffUser(
+ NULL,
+ pLoginParam->pLogonId
+ );
+
+ status = NwrLogonUser(
+ NULL,
+ pLoginParam->pLogonId,
+ pLoginParam->UserName,
+ pLoginParam->Password,
+ pszLocation,
+ NULL,
+ 0
+ );
+
+
+ if (status != ERROR_INVALID_PASSWORD)
+ break ;
+
+ PasswdPromptParam.UserName =
+ pLoginParam->UserName,
+ PasswdPromptParam.ServerName =
+ pszLocation;
+ PasswdPromptParam.Password =
+ pLoginParam->Password;
+ PasswdPromptParam.PasswordSize =
+ pLoginParam->PasswordSize ;
+
+ Result = DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_PASSWORD_PROMPT),
+ (HWND) DialogHandle,
+ NwpPasswdPromptDlgProc,
+ (LPARAM) &PasswdPromptParam
+ );
+
+ if (Result == -1 || Result == IDCANCEL)
+ {
+ status = ERROR_INVALID_PASSWORD ;
+ break ;
+ }
+ }
+
+ if (status == NW_PASSWORD_HAS_EXPIRED)
+ {
+ WCHAR szNumber[16] ;
+ DWORD dwMsgId, dwGraceLogins = 0 ;
+ LPWSTR apszInsertStrings[3] ;
+
+ //
+ // get the grace login count
+ //
+ if (!IS_TREE(pszLocation))
+ {
+ DWORD status1 ;
+ status1 = NwGetGraceLoginCount(
+ pszLocation,
+ pLoginParam->UserName,
+ &dwGraceLogins) ;
+ //
+ // if hit error, just dont use the number
+ //
+ if (status1 == NO_ERROR)
+ {
+ dwMsgId = IDS_PASSWORD_HAS_EXPIRED ;
+ wsprintfW(szNumber, L"%ld", dwGraceLogins) ;
+ }
+ else
+ {
+ dwMsgId = IDS_PASSWORD_HAS_EXPIRED1 ;
+ }
+ }
+ else // BUGBUG - should get proper number
+ {
+ dwMsgId = IDS_PASSWORD_HAS_EXPIRED1 ;
+ }
+
+ apszInsertStrings[0] = pszLocation ;
+ apszInsertStrings[1] = szNumber ;
+ apszInsertStrings[2] = NULL ;
+
+ //
+ // put up message on password expiry
+ //
+ (void) NwpMessageBoxIns(
+ (HWND) DialogHandle,
+ IDS_NETWARE_TITLE,
+ dwMsgId,
+ apszInsertStrings,
+ MB_OK | MB_SETFOREGROUND |
+ MB_ICONINFORMATION );
+
+ status = NO_ERROR ;
+ }
+
+ //
+ // Check the LogonScript check box.
+ //
+ if (IsDlgButtonChecked(DialogHandle, ID_LOGONSCRIPT))
+ {
+ pLoginParam->LogonScriptOptions =
+ NW_LOGONSCRIPT_ENABLED | NW_LOGONSCRIPT_4X_ENABLED ;
+ }
+ else
+ {
+ pLoginParam->LogonScriptOptions =
+ NW_LOGONSCRIPT_DISABLED ;
+ }
+
+ if (status == NO_ERROR)
+ {
+ //
+ // Save the logon credential to the registry
+ //
+ NwpSaveLogonCredential(
+ pLoginParam->NewUserSid,
+ pLoginParam->pLogonId,
+ pLoginParam->UserName,
+ pLoginParam->Password,
+ pszLocation
+ );
+
+ // Clear the password buffer
+ RtlZeroMemory( OrigPassword, sizeof( OrigPassword));
+ NwpSaveLogonScriptOptions( pLoginParam->NewUserSid, pLoginParam->LogonScriptOptions );
+
+ EndDialog(DialogHandle, 0);
+ }
+ else
+ {
+ INT nResult;
+ DWORD dwMsgId = IDS_AUTH_FAILURE_WARNING;
+ WCHAR *pszErrorLocation = pszLocation ;
+
+ if (status == ERROR_ACCOUNT_RESTRICTION)
+ {
+ dwMsgId = IDS_AUTH_ACC_RESTRICTION;
+ }
+ if (status == ERROR_SHARING_PAUSED)
+ {
+ status = IDS_LOGIN_DISABLED;
+ }
+
+ if (IS_TREE(pszLocation))
+ {
+ //
+ // Format into nicer string for user
+ //
+ WCHAR *pszTmp = LocalAlloc(LMEM_ZEROINIT,
+ (wcslen(pszLocation)+2) *
+ sizeof(WCHAR)) ;
+ if (pszTmp)
+ {
+
+ pszErrorLocation = pszTmp ;
+
+ //
+ // This code formats the NDS
+ // tree UNC to: Tree(Context)
+ //
+ wcscpy(pszErrorLocation, pszLocation+1) ;
+
+ if (pszTmp = wcschr(pszErrorLocation, L'\\'))
+ {
+ *pszTmp = L'(' ;
+ wcscat(pszErrorLocation, L")") ;
+ }
+ }
+ }
+
+ nResult = NwpMessageBoxError(
+ DialogHandle,
+ IDS_AUTH_FAILURE_TITLE,
+ dwMsgId,
+ status,
+ pszErrorLocation,
+ MB_YESNO | MB_DEFBUTTON2
+ | MB_ICONEXCLAMATION
+ );
+
+ if (pszErrorLocation != pszLocation)
+ {
+ (void) LocalFree(pszErrorLocation) ;
+ }
+
+ if ( nResult == IDYES )
+ {
+ //
+ // Save the logon credential to the registry
+ //
+ NwpSaveLogonCredential(
+ pLoginParam->NewUserSid,
+ pLoginParam->pLogonId,
+ pLoginParam->UserName,
+ pLoginParam->Password,
+ pszLocation
+ );
+
+ // Clear the password buffer
+ RtlZeroMemory( OrigPassword, sizeof( OrigPassword));
+ NwpSaveLogonScriptOptions( pLoginParam->NewUserSid, pLoginParam->LogonScriptOptions );
+
+ EndDialog(DialogHandle, 0);
+ }
+ else
+ {
+ //
+ // Put the focus where the user can fix the
+ // invalid name.
+ //
+ DWORD controlId =
+ IsDlgButtonChecked(DialogHandle,
+ ID_DEFAULTCONTEXT_RB) ?
+ ID_DEFAULTTREE :
+ ID_SERVER ;
+
+ SetFocus(GetDlgItem(DialogHandle, controlId));
+
+ SendDlgItemMessageW(
+ DialogHandle,
+ controlId,
+ EM_SETSEL,
+ 0,
+ MAKELPARAM(0, -1)
+ );
+ }
+ }
+
+ LocalFree( pszLocation );
+ return TRUE;
+ }
+
+
+ case IDCANCEL:
+
+#if DBG
+ IF_DEBUG(LOGON) {
+ KdPrint(("\n\t[CANCEL] was pressed\n"));
+ KdPrint(("\tLast Preferred Server: %ws\n",
+ pLoginParam->ServerName));
+ KdPrint(("\tLast Password: %ws\n",
+ pLoginParam->Password ));
+ }
+#endif
+
+ if ( *(pLoginParam->ServerName) == NW_INVALID_SERVER_CHAR )
+ {
+ // No preferred server has been set.
+ // Pop up a warning to the user.
+
+ INT nResult = NwpMessageBoxError(
+ DialogHandle,
+ IDS_NETWARE_TITLE,
+ IDS_NO_PREFERRED,
+ 0,
+ NULL,
+ MB_YESNO | MB_ICONEXCLAMATION
+ );
+
+ //
+ // The user chose NO, return to the dialog.
+ //
+ if ( nResult == IDNO )
+ {
+ //
+ // Put the focus where the user can fix the
+ // invalid name.
+ //
+ DWORD controlId =
+ IsDlgButtonChecked(DialogHandle,
+ ID_DEFAULTCONTEXT_RB) ?
+ ID_DEFAULTTREE :
+ ID_SERVER ;
+
+ SetFocus(GetDlgItem(DialogHandle, controlId));
+
+ SendDlgItemMessageW(
+ DialogHandle,
+ controlId,
+ EM_SETSEL,
+ 0,
+ MAKELPARAM(0, -1)
+ );
+
+ return TRUE;
+ }
+
+ //
+ // Save the preferred server as empty string
+ //
+
+ NwpSaveLogonCredential(
+ pLoginParam->NewUserSid,
+ pLoginParam->pLogonId,
+ pLoginParam->UserName,
+ pLoginParam->Password,
+ L""
+ );
+ pLoginParam->LogonScriptOptions = NW_LOGONSCRIPT_DISABLED;
+ NwpSaveLogonScriptOptions( pLoginParam->NewUserSid, pLoginParam->LogonScriptOptions );
+
+ }
+
+ // The user has not logged on to any server.
+ // Logged the user on using NULL as preferred server.
+
+ NwrLogonUser(
+ NULL,
+ pLoginParam->pLogonId,
+ pLoginParam->UserName,
+ pLoginParam->Password,
+ NULL,
+ NULL,
+ 0
+ );
+
+ //
+ // Clear the password buffer
+ RtlZeroMemory( OrigPassword, sizeof( OrigPassword));
+ EndDialog(DialogHandle, 0);
+
+ return TRUE;
+
+
+ case IDHELP:
+ {
+ INT Result ;
+
+ Result = DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_PREFERRED_SERVER_HELP),
+ (HWND) DialogHandle,
+ NwpHelpDlgProc,
+ (LPARAM) 0
+ );
+
+ // ignore any errors. should not fail, and if does,
+ // nothing we can do.
+
+ return TRUE ;
+
+ }
+
+
+ }
+
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+
+INT
+NwpMessageBoxError(
+ IN HWND hwndParent,
+ IN DWORD TitleId,
+ IN DWORD BodyId,
+ IN DWORD Error,
+ IN LPWSTR pszParameter,
+ IN UINT Style
+ )
+/*++
+
+Routine Description:
+
+ This routine puts up a message box error.
+
+Arguments:
+
+ hwndParent - Supplies the handle of the parent window.
+
+ TitleId - Supplies the ID of the title. ( LoadString )
+
+ BodyId - Supplies the ID of the message. ( LoadString )
+
+ Error - If BodyId != 0, then this supplies the ID of the
+ substitution string that will be substituted into
+ the string indicated by BodyId.
+ If BodyId == 0, then this will be the error message.
+ This id is a system error that we will get from FormatMessage
+ using FORMAT_MESSAGE_FROM_SYSTEM.
+
+ pszParameter - A substitution string that will be used as %2 or if
+ Error == 0, this string will be substituted as %1 into
+ the string indicated by BodyId.
+
+ Style - Supplies the style of the MessageBox.
+
+
+Return Value:
+
+ The return value from the MessageBox, 0 if any error is encountered.
+
+--*/
+{
+ DWORD nResult = 0;
+ DWORD nLength;
+
+ WCHAR szTitle[MAX_PATH];
+ WCHAR szBody[MAX_PATH];
+ LPWSTR pszError = NULL;
+ LPWSTR pszBuffer = NULL;
+
+ szTitle[0] = 0;
+ szBody[0] = 0;
+
+ //
+ // Get the Title string
+ //
+ nLength = LoadStringW(
+ hmodNW,
+ TitleId,
+ szTitle,
+ sizeof(szTitle) / sizeof(WCHAR)
+ );
+
+ if ( nLength == 0) {
+ KdPrint(("NWPROVAU: LoadStringW of Title failed with %lu\n",
+ GetLastError()));
+ return 0;
+ }
+
+ //
+ // Get the body string, if BodyId != 0
+ //
+ if ( BodyId != 0 )
+ {
+ nLength = LoadStringW(
+ hmodNW,
+ BodyId,
+ szBody,
+ sizeof(szBody) / sizeof(WCHAR)
+ );
+
+ if ( nLength == 0) {
+ KdPrint(("NWPROVAU: LoadStringW of Body failed with %lu\n",
+ GetLastError()));
+ return 0;
+ }
+ }
+
+ if ( (Error >= IDS_START) && (Error <= IDS_END) ) {
+
+ pszError = (WCHAR *) LocalAlloc(
+ LPTR,
+ 256 * sizeof(WCHAR)) ;
+ if (!pszError)
+ return 0 ;
+
+ nLength = LoadStringW(
+ hmodNW,
+ Error,
+ pszError,
+ 256
+ );
+
+ if ( nLength == 0 ) {
+
+ KdPrint(("NWPROVAU: LoadStringW of Error failed with %lu\n",
+ GetLastError()));
+ (void) LocalFree( (HLOCAL)pszError) ;
+ return 0;
+ }
+ }
+ else if ( Error != 0 ) {
+
+ if ( ( Error == WN_NO_MORE_ENTRIES )
+ || ( Error == ERROR_MR_MID_NOT_FOUND )) {
+
+ //
+ // Handle bogus error from the redirector
+ //
+
+ KdPrint(("NWPROVAU: The NetwareRedirector returned a bogus error as the reason for failure to authenticate. (See Kernel Debugger)\n"));
+ }
+
+ nLength = FormatMessageW(
+ FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ Error,
+ 0,
+ (LPWSTR) &pszError,
+ MAX_PATH,
+ NULL
+ );
+
+
+ if ( nLength == 0 ) {
+
+ KdPrint(("NWPROVAU: FormatMessageW of Error failed with %lu\n",
+ GetLastError()));
+ return 0;
+ }
+ }
+
+ if ( ( *szBody != 0 )
+ && ( ( pszError != NULL ) || ( pszParameter != NULL) )) {
+
+ LPWSTR aInsertStrings[2];
+ aInsertStrings[0] = pszError? pszError : pszParameter;
+ aInsertStrings[1] = pszError? pszParameter : NULL;
+
+ nLength = FormatMessageW(
+ FORMAT_MESSAGE_FROM_STRING
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ szBody,
+ 0, // Ignored
+ 0, // Ignored
+ (LPWSTR) &pszBuffer,
+ MAX_PATH,
+ (va_list *) aInsertStrings
+ );
+
+ if ( nLength == 0 ) {
+
+ KdPrint(("NWPROVAU:FormatMessageW(insertstring) failed with %lu\n",
+ GetLastError()));
+
+ if ( pszError != NULL )
+ (void) LocalFree( (HLOCAL) pszError );
+ return 0;
+ }
+
+ }
+ else if ( *szBody != 0 ) {
+
+ pszBuffer = szBody;
+ }
+ else if ( pszError != NULL ) {
+
+ pszBuffer = pszError;
+ }
+ else {
+
+ // We have neither the body nor the error string.
+ // Hence, don't popup the messagebox
+ return 0;
+ }
+
+ if ( pszBuffer != NULL )
+ {
+ nResult = MessageBoxW(
+ hwndParent,
+ pszBuffer,
+ szTitle,
+ Style
+ );
+ }
+
+ if ( ( pszBuffer != NULL )
+ && ( pszBuffer != szBody )
+ && ( pszBuffer != pszError ))
+ {
+ (void) LocalFree( (HLOCAL) pszBuffer );
+ }
+
+ if ( pszError != NULL )
+ (void) LocalFree( (HLOCAL) pszError );
+
+ return nResult;
+}
+
+
+INT
+NwpMessageBoxIns(
+ IN HWND hwndParent,
+ IN DWORD TitleId,
+ IN DWORD MessageId,
+ IN LPWSTR *InsertStrings,
+ IN UINT Style
+ )
+/*++
+
+Routine Description:
+
+ This routine puts up a message box error with array of insert strings
+
+Arguments:
+
+ hwndParent - Supplies the handle of the parent window.
+
+ TitleId - Supplies the ID of the title. ( LoadString )
+
+ MessageId - Supplies the ID of the message. ( LoadString )
+
+ InsertStrings - Array of insert strings for FormatMessage.
+
+ Style - Supplies the style of the MessageBox.
+
+
+Return Value:
+
+ The return value from the MessageBox, 0 if any error is encountered.
+
+--*/
+{
+ DWORD nResult = 0;
+ DWORD nLength;
+
+ WCHAR szTitle[MAX_PATH];
+ WCHAR szBody[MAX_PATH];
+ LPWSTR pszBuffer = NULL;
+
+ szTitle[0] = 0;
+ szBody[0] = 0;
+
+ //
+ // Get the Title string
+ //
+ nLength = LoadStringW(
+ hmodNW,
+ TitleId,
+ szTitle,
+ sizeof(szTitle) / sizeof(szTitle[0])
+ );
+
+ if ( nLength == 0) {
+ return 0;
+ }
+
+ //
+ // Get the message string
+ //
+ nLength = LoadStringW(
+ hmodNW,
+ MessageId,
+ szBody,
+ sizeof(szBody) / sizeof(szBody[0])
+ );
+
+ if ( nLength == 0) {
+ return 0;
+ }
+
+ nLength = FormatMessageW(
+ FORMAT_MESSAGE_FROM_STRING
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ szBody,
+ 0, // Ignored
+ 0, // Ignored
+ (LPWSTR) &pszBuffer,
+ MAX_PATH,
+ (va_list *) InsertStrings
+ );
+
+ if ( nLength == 0 ) {
+ return 0;
+ }
+
+ if ( pszBuffer != NULL )
+ {
+ nResult = MessageBoxW(
+ hwndParent,
+ pszBuffer,
+ szTitle,
+ Style
+ );
+
+ (void) LocalFree( (HLOCAL) pszBuffer );
+ }
+
+ return nResult;
+}
+
+VOID
+NwpAddServersToControl(
+ IN HWND DialogHandle,
+ IN INT ControlId,
+ IN UINT Message,
+ IN INT ControlIdMatch OPTIONAL,
+ IN UINT FindMessage
+ )
+/*++
+
+Routine Description:
+
+ This function enumerates the servers on the network and adds each
+ server name to the specified Windows control.
+
+ If ControlIdMatch is specified (i.e. non 0), only servers that are
+ not found in ControlIdMatch list are added to the list specified
+ by ControlId.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to the Windows dialog.
+
+ ControlId - Supplies id which specifies the control.
+
+ Message - Supplies the window management message to add string.
+
+ ControlIdMatch - Supplies the control ID which contains server
+ names that should not be in ControlId.
+
+ FindMessage - Supplies the window management message to find
+ string.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ DWORD status = ERROR_NO_NETWORK;
+ HANDLE EnumHandle = (HANDLE) NULL;
+
+ LPNETRESOURCE NetR = NULL;
+ LPNETRESOURCEW SavePtr;
+ WCHAR FormattedNameBuf[MAX_NDS_NAME_CHARS];
+
+ LPWSTR lpFormattedName;
+ DWORD dwLength;
+
+ DWORD BytesNeeded = 512;
+ DWORD EntriesRead;
+ DWORD i;
+
+ //
+ // Retrieve the list of servers on the network
+ //
+ status = NPOpenEnum(
+ RESOURCE_GLOBALNET,
+ 0,
+ 0,
+ NULL,
+ &EnumHandle
+ );
+
+ if (status != NO_ERROR) {
+ EnumHandle = (HANDLE) NULL;
+ goto CleanExit;
+ }
+
+ //
+ // Allocate buffer to get servers on the net.
+ //
+ if ((NetR = (LPVOID) LocalAlloc(
+ 0,
+ BytesNeeded
+ )) == NULL) {
+
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto CleanExit;
+ }
+
+ do {
+
+ EntriesRead = 0xFFFFFFFF; // Read as many as possible
+
+ status = NPEnumResource(
+ EnumHandle,
+ &EntriesRead,
+ (LPVOID) NetR,
+ &BytesNeeded
+ );
+
+
+ if (status == WN_SUCCESS) {
+
+ SavePtr = NetR;
+
+ for (i = 0; i < EntriesRead; i++, NetR++)
+ {
+ if ( NetR->dwDisplayType == RESOURCEDISPLAYTYPE_TREE)
+ {
+ continue;
+ }
+ else
+ {
+ lpFormattedName = FormattedNameBuf;
+ }
+
+ dwLength = NW_MAX_SERVER_LEN + 1;
+
+ status = NPFormatNetworkName( NetR->lpRemoteName,
+ lpFormattedName,
+ &dwLength,
+ WNFMT_INENUM,
+ 0 );
+
+ lpFormattedName = FormattedNameBuf;
+
+ if ( status != WN_SUCCESS )
+ {
+ continue;
+ }
+
+ if ( dwLength > NW_MAX_SERVER_LEN + 1 )
+ {
+ continue;
+ }
+
+ if (ControlIdMatch != 0) {
+
+ INT Result;
+
+ //
+ // Add the server to list only if it's not found
+ // in the alternate list specified by ControlIdMatch.
+ //
+ Result = SendDlgItemMessageW(
+ DialogHandle,
+ ControlIdMatch,
+ FindMessage,
+ (WPARAM) -1,
+ (LPARAM) lpFormattedName
+ );
+
+ if (Result == LB_ERR) {
+
+ //
+ // Server name not found. Add to list.
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ControlId,
+ Message,
+ 0,
+ (LPARAM) lpFormattedName
+ );
+ }
+ }
+ else {
+
+ //
+ // No alternate list. Just add all servers.
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ControlId,
+ Message,
+ 0,
+ (LPARAM) lpFormattedName
+ );
+ }
+
+ }
+
+ NetR = SavePtr;
+
+ }
+ else if (status != WN_NO_MORE_ENTRIES) {
+
+ status = GetLastError();
+
+ if (status == WN_MORE_DATA) {
+
+ //
+ // Original buffer was too small. Free it and allocate
+ // the recommended size and then some to get as many
+ // entries as possible.
+ //
+
+ (void) LocalFree((HLOCAL) NetR);
+
+ BytesNeeded += NW_ENUM_EXTRA_BYTES;
+
+ if ((NetR = (LPVOID) LocalAlloc(
+ 0,
+ BytesNeeded
+ )) == NULL) {
+
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto CleanExit;
+ }
+ }
+ else {
+ goto CleanExit;
+ }
+ }
+
+ } while (status != WN_NO_MORE_ENTRIES);
+
+ if (status == WN_NO_MORE_ENTRIES) {
+ status = NO_ERROR;
+ }
+
+CleanExit:
+
+ if (EnumHandle != (HANDLE) NULL) {
+ (void) NPCloseEnum(EnumHandle);
+ }
+
+ if (NetR != NULL) {
+ (void) LocalFree((HLOCAL) NetR);
+ }
+}
+
+VOID
+NwpAddTreeNamesToControl(
+ IN HWND DialogHandle,
+ IN INT ControlId,
+ IN UINT Message,
+ IN INT ControlIdMatch OPTIONAL,
+ IN UINT FindMessage
+ )
+/*++
+
+Routine Description:
+
+ This function enumerates the NDS tree on the network and adds each
+ tree name to the specified Windows control.
+
+ If ControlIdMatch is specified (i.e. non 0), only trees that are
+ not found in ControlIdMatch list are added to the list specified
+ by ControlId.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to the Windows dialog.
+
+ ControlId - Supplies id which specifies the control.
+
+ Message - Supplies the window management message to add string.
+
+ ControlIdMatch - Supplies the control ID which contains server
+ names that should not be in ControlId.
+
+ FindMessage - Supplies the window management message to find
+ string.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ DWORD status = ERROR_NO_NETWORK;
+ HANDLE EnumHandle = (HANDLE) NULL;
+
+ LPNETRESOURCE NetR = NULL;
+ LPNETRESOURCEW SavePtr;
+ WCHAR FormattedNameBuf[MAX_NDS_NAME_CHARS];
+
+ LPWSTR lpFormattedName;
+ DWORD dwLength;
+
+ DWORD BytesNeeded = 512;
+ DWORD EntriesRead;
+ DWORD i;
+
+ //
+ // Retrieve the list of trees on the network
+ //
+ status = NPOpenEnum(
+ RESOURCE_GLOBALNET,
+ 0,
+ 0,
+ NULL,
+ &EnumHandle
+ );
+
+ if (status != NO_ERROR) {
+ EnumHandle = (HANDLE) NULL;
+ goto CleanExit;
+ }
+
+ //
+ // Allocate buffer to get trees on the net.
+ //
+ if ((NetR = (LPVOID) LocalAlloc(
+ 0,
+ BytesNeeded
+ )) == NULL) {
+
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto CleanExit;
+ }
+
+ do {
+
+ EntriesRead = 0xFFFFFFFF; // Read as many as possible
+
+ status = NPEnumResource(
+ EnumHandle,
+ &EntriesRead,
+ (LPVOID) NetR,
+ &BytesNeeded
+ );
+
+
+ if (status == WN_SUCCESS) {
+
+ SavePtr = NetR;
+
+ for (i = 0; i < EntriesRead; i++, NetR++)
+ {
+ if ( NetR->dwDisplayType == RESOURCEDISPLAYTYPE_TREE)
+ {
+ lpFormattedName = (LPWSTR) FormattedNameBuf;
+ }
+ else
+ {
+ continue;
+ }
+
+ dwLength = NW_MAX_SERVER_LEN + 1;
+
+ status = NPFormatNetworkName( NetR->lpRemoteName,
+ lpFormattedName,
+ &dwLength,
+ WNFMT_INENUM,
+ 0 );
+
+ lpFormattedName = FormattedNameBuf;
+
+ if ( status != WN_SUCCESS )
+ {
+ continue;
+ }
+
+ if ( dwLength > NW_MAX_SERVER_LEN + 1 )
+ {
+ continue;
+ }
+
+ if (ControlIdMatch != 0) {
+
+ INT Result;
+
+ //
+ // Add the server to list only if it's not found
+ // in the alternate list specified by ControlIdMatch.
+ //
+ Result = SendDlgItemMessageW(
+ DialogHandle,
+ ControlIdMatch,
+ FindMessage,
+ (WPARAM) -1,
+ (LPARAM) lpFormattedName
+ );
+
+ if (Result == LB_ERR) {
+
+ //
+ // Server name not found. Add to list.
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ControlId,
+ Message,
+ 0,
+ (LPARAM) lpFormattedName
+ );
+ }
+ }
+ else {
+
+ //
+ // No alternate list. Just add all servers.
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ControlId,
+ Message,
+ 0,
+ (LPARAM) lpFormattedName
+ );
+ }
+
+ }
+
+ NetR = SavePtr;
+
+ }
+ else if (status != WN_NO_MORE_ENTRIES) {
+
+ status = GetLastError();
+
+ if (status == WN_MORE_DATA) {
+
+ //
+ // Original buffer was too small. Free it and allocate
+ // the recommended size and then some to get as many
+ // entries as possible.
+ //
+
+ (void) LocalFree((HLOCAL) NetR);
+
+ BytesNeeded += NW_ENUM_EXTRA_BYTES;
+
+ if ((NetR = (LPVOID) LocalAlloc(
+ 0,
+ BytesNeeded
+ )) == NULL) {
+
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto CleanExit;
+ }
+ }
+ else {
+ goto CleanExit;
+ }
+ }
+
+ } while (status != WN_NO_MORE_ENTRIES);
+
+ if (status == WN_NO_MORE_ENTRIES) {
+ status = NO_ERROR;
+ }
+
+CleanExit:
+
+ if (EnumHandle != (HANDLE) NULL) {
+ (void) NPCloseEnum(EnumHandle);
+ }
+
+ if (NetR != NULL) {
+ (void) LocalFree((HLOCAL) NetR);
+ }
+}
+
+
+VOID
+NwpAddToComboBox(
+ IN HWND DialogHandle,
+ IN INT ControlId,
+ IN LPWSTR pszNone OPTIONAL,
+ IN BOOL AllowNone
+ )
+{
+
+ NwpAddServersToControl(DialogHandle, ControlId, CB_ADDSTRING, 0, 0);
+
+ //
+ // Combo-box will contain at least the <NONE> entry in its list.
+ //
+
+ if ( ARGUMENT_PRESENT(pszNone) && AllowNone) {
+
+ SendDlgItemMessageW(
+ DialogHandle,
+ ControlId,
+ CB_INSERTSTRING,
+ (WPARAM) -1,
+ (LPARAM) pszNone
+ );
+ }
+}
+
+
+DWORD
+NwpGetUserCredential(
+ IN HWND hParent,
+ IN LPWSTR Unc,
+ IN DWORD err,
+ IN LPWSTR pszConnectAsUserName,
+ OUT LPWSTR *UserName,
+ OUT LPWSTR *Password
+ )
+/*++
+
+Routine Description:
+
+ This function puts up a popup dialog for the user, whose default
+ credential denied browse directory access, to enter the correct
+ credential. If this function returns successful, the pointers
+ to memory allocated for the user entered username and password
+ are returned.
+
+Arguments:
+
+ Unc - Supplies the container name in \\Server\Volume format
+ under which the user wants to browse directories.
+
+ UserName - Receives the pointer to memory allocated for the
+ username gotten from the dialog. This pointer must be freed
+ with LocalFree when done.
+
+ Password - Receives the pointer to memory allocated for the
+ password gotten from the dialog. This pointer must be freed
+ with LocalFree when done.
+
+Return Value:
+
+ NO_ERROR or reason for failure.
+
+--*/
+{
+ DWORD status;
+ INT Result;
+ HWND DialogHandle = hParent? hParent : NwpGetParentHwnd();
+ DWORD UserNameSize = NW_MAX_USERNAME_LEN + 1;
+ DWORD PasswordSize = NW_MAX_PASSWORD_LEN + 1;
+ CONNECTDLGPARAM ConnectParam;
+
+ *UserName = NULL;
+ *Password = NULL;
+
+ if (DialogHandle == NULL) {
+ return ERROR_WINDOW_NOT_DIALOG;
+ }
+
+ //
+ // Allocate memory to return UserName and Password
+ //
+ if ((*UserName = (LPVOID) LocalAlloc(
+ 0,
+ UserNameSize * sizeof(WCHAR)
+ )) == NULL)
+ {
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ //
+ // Allocate memory to return UserName and Password
+ //
+ if ((*Password = (LPVOID) LocalAlloc(
+ 0,
+ PasswordSize * sizeof(WCHAR)
+ )) == NULL)
+ {
+
+ (void) LocalFree( *UserName );
+ *UserName = NULL;
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ ConnectParam.UncPath = Unc;
+ ConnectParam.ConnectAsUserName = pszConnectAsUserName;
+ ConnectParam.UserName = *UserName;
+ ConnectParam.Password = *Password;
+ ConnectParam.UserNameSize = UserNameSize;
+ ConnectParam.PasswordSize = PasswordSize;
+ ConnectParam.LastConnectionError = err;
+
+ Result = DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_NETWORK_CREDENTIAL),
+ DialogHandle,
+ NwpConnectDlgProc,
+ (LPARAM) &ConnectParam
+ );
+
+ if ( Result == -1 )
+ {
+ status = GetLastError();
+ KdPrint(("NWPROVAU: NwpGetUserCredential: DialogBox failed %lu\n",
+ status));
+ goto ErrorExit;
+ }
+ else if ( Result == IDCANCEL )
+ {
+ //
+ // Cancel was pressed.
+ //
+ status = WN_CANCEL;
+ goto ErrorExit;
+ }
+
+ return NO_ERROR;
+
+ErrorExit:
+ (void) LocalFree((HLOCAL) *UserName);
+ (void) LocalFree((HLOCAL) *Password);
+ *UserName = NULL;
+ *Password = NULL;
+
+ return status;
+}
+
+
+BOOL
+WINAPI
+NwpConnectDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+/*++
+
+Routine Description:
+
+ This function is the window management message handler which
+ initializes, and reads user input from the dialog put up when the
+ user fails to browse a directory on the default credential.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to display the dialog.
+
+ Message - Supplies the window management message.
+
+ LParam - Supplies the pointer to a buffer which on input
+ contains the \\Server\Volume string under which the user
+ needs to type in a new credential before browsing. On
+ output, this pointer contains the username and password
+ strings entered to the dialog box.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ static PCONNECTDLGPARAM pConnectParam;
+
+ switch (Message) {
+
+ case WM_INITDIALOG:
+
+ pConnectParam = (PCONNECTDLGPARAM) LParam;
+
+ //
+ // Position dialog
+ //
+ // NwpCenterDialog(DialogHandle);
+
+
+ //
+ // Display the \\Server\Volume string.
+ //
+ SetDlgItemTextW( DialogHandle,
+ ID_VOLUME_PATH,
+ pConnectParam->UncPath );
+
+ if ( pConnectParam->LastConnectionError == NO_ERROR )
+ {
+ WCHAR szTemp[256];
+
+ if ( LoadString( hmodNW, IDS_CONNECT_NO_ERROR_TEXT,
+ szTemp, sizeof( szTemp )/sizeof(WCHAR)))
+ {
+ SetDlgItemTextW( DialogHandle,
+ ID_CONNECT_TEXT,
+ szTemp );
+ }
+ }
+
+ //
+ // Username is limited to 256 characters.
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_CONNECT_AS,
+ EM_LIMITTEXT,
+ pConnectParam->UserNameSize - 1, // minus the space for '\0'
+ 0
+ );
+
+ //
+ // Password is limited to 256 characters.
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_CONNECT_PASSWORD,
+ EM_LIMITTEXT,
+ pConnectParam->PasswordSize - 1, // minus the space for '\0'
+ 0
+ );
+
+ //
+ // Display the User name string.
+ //
+ if ( pConnectParam->ConnectAsUserName )
+ {
+ SetDlgItemTextW( DialogHandle,
+ ID_CONNECT_AS,
+ pConnectParam->ConnectAsUserName );
+ }
+
+ return TRUE;
+
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam)) {
+
+ case IDOK:
+
+ GetDlgItemTextW(
+ DialogHandle,
+ ID_CONNECT_AS,
+ pConnectParam->UserName,
+ pConnectParam->UserNameSize
+ );
+
+ GetDlgItemTextW(
+ DialogHandle,
+ ID_CONNECT_PASSWORD,
+ pConnectParam->Password,
+ pConnectParam->PasswordSize
+ );
+
+#if DBG
+ IF_DEBUG(LOGON) {
+ KdPrint(("\n\t[OK] was pressed\n"));
+ KdPrint(("\tUserName : %ws\n",
+ pConnectParam->UserName));
+ KdPrint(("\tPassword : %ws\n",
+ pConnectParam->Password));
+ }
+#endif
+
+ EndDialog(DialogHandle, (INT) IDOK); // OK
+
+ return TRUE;
+
+
+ case IDCANCEL:
+
+#if DBG
+ IF_DEBUG(LOGON) {
+ KdPrint(("\n\t[CANCEL] was pressed\n"));
+ }
+#endif
+
+ EndDialog(DialogHandle, (INT) IDCANCEL); // CANCEL
+
+ return TRUE;
+
+ case IDHELP:
+
+ WinHelp( DialogHandle,
+ NW_HELP_FILE,
+ HELP_CONTEXT,
+ IDH_DLG_NETWORK_CREDENTIAL_HELP );
+
+ return TRUE;
+ }
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+
+
+VOID
+NwpCenterDialog(
+ HWND hwnd
+ )
+/*++
+
+Routine Description:
+
+ This routine positions the dialog centered horizontally and 1/3
+ down the screen vertically. It should be called by the dlg proc
+ when processing the WM_INITDIALOG message. This code is stolen
+ from Visual Basic written by GustavJ.
+
+ Screen
+ -----------------------------
+ | 1/3 Above |
+ | --------------- |
+ | | Dialog | |
+ | | | |
+ | --------------- |
+ | 2/3 Below |
+ | |
+ -----------------------------
+
+Arguments:
+
+ hwnd - Supplies the handle to the dialog.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ RECT rect;
+ LONG nx; // New x
+ LONG ny; // New y
+ LONG width;
+ LONG height;
+
+ GetWindowRect( hwnd, &rect );
+
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
+
+ nx = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
+ ny = (GetSystemMetrics(SM_CYSCREEN) - height) / 3;
+
+ MoveWindow( hwnd, nx, ny, width, height, FALSE );
+}
+
+
+
+HWND
+NwpGetParentHwnd(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This function gets the parent window handle so that a
+ dialog can be displayed in the current context.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ Returns the parent window handle if successful; NULL otherwise.
+
+--*/
+{
+ HWND hwnd;
+ LONG lWinStyle;
+
+
+ //
+ // Get the current focus. This is presumably the button
+ // that was last clicked.
+ //
+ hwnd = GetFocus();
+
+ //
+ // We must make sure that we don't return the window handle
+ // for a child window. Hence, we traverse up the ancestors
+ // of this window handle until we find a non-child window.
+ // Then, we return that handle. If we ever find a NULL window
+ // handle before finding a non-child window, we are unsuccessful
+ // and will return NULL.
+ //
+ // Note on the bit manipulation below. A window is either
+ // an overlapped window, a popup window or a child window.
+ // Hence, we OR together the possible bit combinations of these
+ // possibilities. This should tell us which bits are used in
+ // the window style dword (although we know this becomes 0xC000
+ // today, we don't know if these will ever change later). Then,
+ // we AND the bit combination we with the given window style
+ // dword, and compare the result with WS_CHILD. This tells us
+ // whether or not the given window is a child window.
+ //
+ while (hwnd) {
+
+ lWinStyle = GetWindowLong (hwnd, GWL_STYLE);
+
+ if ((lWinStyle & (WS_OVERLAPPED | WS_POPUP | WS_CHILD)) != WS_CHILD) {
+ return hwnd;
+ }
+
+ hwnd = GetParent(hwnd);
+ }
+
+ return NULL;
+}
+
+
+BOOL
+WINAPI
+NwpPasswdPromptDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+/*++
+
+Routine Description:
+
+ This function is the window management message handler for
+ the change password dialog.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to display the dialog.
+
+ Message - Supplies the window management message.
+
+ LParam - Supplies the pointer to a buffer which on input
+ contains the Server string under which the user
+ needs to type in a new credential before browsing. On
+ output, this pointer contains the username and server
+ strings entered to the dialog box.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ LPWSTR UserName;
+ LPWSTR ServerName;
+ static LPWSTR Password;
+ static DWORD PasswordSize ;
+ INT Result ;
+ PPROMPTDLGPARAM DlgParams ;
+ DWORD nLength;
+
+ WCHAR szLocation[MAX_PATH];
+
+ szLocation[0] = 0;
+
+
+ switch (Message) {
+
+ case WM_INITDIALOG:
+
+ DlgParams = (PPROMPTDLGPARAM) LParam;
+ UserName = DlgParams->UserName ;
+ ServerName = DlgParams->ServerName ;
+ Password = DlgParams->Password ;
+ PasswordSize = DlgParams->PasswordSize ;
+
+ ASSERT(ServerName) ;
+
+ //
+ // Position dialog
+ //
+ NwpCenterDialog(DialogHandle);
+
+ //
+ // Get the string "Server" or "Context".
+ //
+ nLength = LoadStringW(
+ hmodNW,
+ IS_TREE(ServerName) ? IDS_CONTEXT : IDS_SERVER,
+ szLocation,
+ sizeof(szLocation) / sizeof(szLocation[0])
+ );
+
+ if ( nLength == 0) {
+ szLocation[0] = 0; // missing text, but still works
+ }
+ SetDlgItemTextW(DialogHandle, ID_LOCATION, szLocation);
+
+ //
+ // Format the server/context string. Note we reuse the
+ // location buffer.
+ //
+ RtlZeroMemory(szLocation, sizeof(szLocation)) ;
+ nLength = wcslen(ServerName) ;
+
+ if ( IS_TREE(ServerName) &&
+ (nLength+1 < (sizeof(szLocation)/sizeof(szLocation[0]))))
+ {
+ //
+ // NDS tree & context
+ //
+ WCHAR *pszTmp ;
+
+ wcscpy(szLocation, ServerName+1) ; // skip the * if tree\context
+
+ if (pszTmp = wcschr(szLocation, L'\\'))
+ {
+ *pszTmp = L'(' ;
+ wcscat(szLocation, L")") ;
+ }
+ }
+ else
+ {
+ wcsncpy(szLocation, ServerName, nLength) ;
+ }
+
+ //
+ // show the user and server names.
+ //
+ SetDlgItemTextW(DialogHandle, ID_SERVER, szLocation);
+ SetDlgItemTextW(DialogHandle, ID_USERNAME, UserName);
+
+ //
+ // set limits
+ //
+ SendDlgItemMessageW( DialogHandle,
+ ID_PASSWORD,
+ EM_LIMITTEXT,
+ PasswordSize - 1, // minus space for '\0'
+ 0 );
+
+ return TRUE;
+
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam)) {
+
+
+ case IDHELP:
+
+ DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_ENTER_PASSWORD_HELP),
+ (HWND) DialogHandle,
+ NwpHelpDlgProc,
+ (LPARAM) 0
+ );
+
+ return TRUE;
+
+ case IDOK:
+
+ Result = GetDlgItemTextW( DialogHandle,
+ ID_PASSWORD,
+ Password,
+ PasswordSize
+ );
+
+ EndDialog(DialogHandle, (INT) IDOK); // OK
+
+ return TRUE;
+
+
+ case IDCANCEL:
+
+
+ EndDialog(DialogHandle, (INT) IDCANCEL); // CANCEL
+
+ return TRUE;
+ }
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+
+
+BOOL
+WINAPI
+NwpChangePasswordDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+/*++
+
+Routine Description:
+
+ This function is the window management message handler for
+ the change password dialog.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to display the dialog.
+
+ Message - Supplies the window management message.
+
+ LParam - Supplies the pointer to a buffer which on input
+ contains the Server string under which the user
+ needs to type in a new credential before browsing. On
+ output, this pointer contains the username and server
+ strings entered to the dialog box.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ static PCHANGE_PASS_DLG_PARAM pChangePassParam ;
+
+ switch (Message)
+ {
+ case WM_INITDIALOG:
+
+ pChangePassParam = (PCHANGE_PASS_DLG_PARAM) LParam;
+
+ NwpCenterDialog(DialogHandle);
+
+
+ SetDlgItemTextW(DialogHandle, ID_SERVER, pChangePassParam->TreeName);
+ SetDlgItemTextW(DialogHandle, ID_USERNAME, pChangePassParam->UserName);
+
+ //
+ // set limits
+ //
+ SendDlgItemMessageW( DialogHandle,
+ ID_OLD_PASSWORD,
+ EM_LIMITTEXT,
+ NW_MAX_PASSWORD_LEN, // minus space for '\0'
+ 0 );
+
+ SendDlgItemMessageW( DialogHandle,
+ ID_NEW_PASSWORD,
+ EM_LIMITTEXT,
+ NW_MAX_PASSWORD_LEN, // minus space for '\0'
+ 0 );
+
+ SendDlgItemMessageW( DialogHandle,
+ ID_CONFIRM_PASSWORD,
+ EM_LIMITTEXT,
+ NW_MAX_PASSWORD_LEN, // minus space for '\0'
+ 0 );
+
+ return TRUE;
+
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam))
+ {
+ case IDHELP:
+
+ DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_CHANGE_PASSWORD_HELP),
+ (HWND) DialogHandle,
+ NwpHelpDlgProc,
+ (LPARAM) 0
+ );
+
+ return TRUE;
+
+ case IDOK:
+ {
+ INT Result;
+ WCHAR szConfirmPassword[NW_MAX_PASSWORD_LEN + 1];
+ UNICODE_STRING OldPasswordStr;
+ UNICODE_STRING NewPasswordStr;
+ UCHAR EncodeSeed = NW_ENCODE_SEED2;
+
+ Result = GetDlgItemTextW( DialogHandle,
+ ID_OLD_PASSWORD,
+ pChangePassParam->OldPassword,
+ NW_MAX_PASSWORD_LEN
+ );
+
+ Result = GetDlgItemTextW( DialogHandle,
+ ID_NEW_PASSWORD,
+ pChangePassParam->NewPassword,
+ NW_MAX_PASSWORD_LEN
+ );
+
+ Result = GetDlgItemTextW( DialogHandle,
+ ID_CONFIRM_PASSWORD,
+ szConfirmPassword,
+ NW_MAX_PASSWORD_LEN
+ );
+
+ if ( wcscmp( pChangePassParam->NewPassword,
+ szConfirmPassword ) )
+ {
+ //
+ // New and Confirm passwords don't match!
+ //
+ (void) NwpMessageBoxError(
+ DialogHandle,
+ IDS_CHANGE_PASSWORD_TITLE,
+ IDS_CHANGE_PASSWORD_CONFLICT,
+ 0,
+ NULL,
+ MB_OK | MB_ICONSTOP );
+
+ SetDlgItemText( DialogHandle,
+ ID_NEW_PASSWORD,
+ L"" );
+
+ SetDlgItemText( DialogHandle,
+ ID_CONFIRM_PASSWORD,
+ L"" );
+
+ SetFocus( GetDlgItem( DialogHandle,
+ ID_NEW_PASSWORD ));
+
+ return TRUE;
+ }
+
+ RtlInitUnicodeString( &OldPasswordStr,
+ pChangePassParam->OldPassword );
+ RtlInitUnicodeString( &NewPasswordStr,
+ pChangePassParam->NewPassword );
+ RtlRunEncodeUnicodeString(&EncodeSeed, &OldPasswordStr);
+ RtlRunEncodeUnicodeString(&EncodeSeed, &NewPasswordStr);
+
+ EndDialog(DialogHandle, (INT) IDOK); // OK
+
+ return TRUE;
+ }
+
+ case IDCANCEL:
+
+ EndDialog(DialogHandle, (INT) IDCANCEL); // CANCEL
+
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+
+
+BOOL
+WINAPI
+NwpHelpDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+//
+// This dialog is used for both Help and Question dialogs.
+//
+{
+ switch (Message) {
+
+ case WM_INITDIALOG:
+
+ NwpCenterDialog(DialogHandle);
+ return TRUE;
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam))
+ {
+
+ case IDOK:
+ case IDCANCEL:
+ EndDialog(DialogHandle, IDOK);
+ return TRUE;
+
+ case IDYES:
+ EndDialog(DialogHandle, IDYES);
+ return TRUE;
+
+ case IDNO:
+ EndDialog(DialogHandle, IDNO);
+ return TRUE;
+
+ default:
+ return FALSE ;
+ }
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+
+
+VOID
+NwpGetNoneString(
+ LPWSTR pszNone,
+ DWORD cBufferSize
+ )
+/*++
+
+Routine Description:
+
+ This function gets the <NONE> string from the resource.
+
+Arguments:
+
+ pszNone - Supplies the buffer to store the string.
+
+ cBufferSize - Supplies the buffer size in bytes.
+
+Return Value:
+
+ None.
+--*/
+{
+ INT TextLength;
+
+
+ TextLength = LoadStringW( hmodNW,
+ IDS_NONE,
+ pszNone,
+ cBufferSize / sizeof( WCHAR) );
+
+ if ( TextLength == 0 )
+ *pszNone = 0;
+}
+
+
+
+VOID
+NwpAddNetWareTreeConnectionsToList(
+ IN HWND DialogHandle,
+ IN LPWSTR NtUserName,
+ IN LPDWORD lpdwUserLuid,
+ IN INT ControlId
+ )
+{
+ DWORD status = NO_ERROR;
+ DWORD BufferSize = 2048; // 2KB Buffer
+ BYTE pBuffer[2048];
+ DWORD EntriesRead;
+ INT Result ;
+
+ status = NwGetConnectedTrees( NtUserName,
+ pBuffer,
+ BufferSize,
+ &EntriesRead,
+ lpdwUserLuid );
+
+ if ( status == NO_ERROR && EntriesRead > 0 )
+ {
+ PCONN_INFORMATION pConnInfo = (PCONN_INFORMATION) pBuffer;
+ WCHAR tempTreeName[NW_MAX_TREE_LEN + 1];
+ DWORD dwSize;
+
+ while ( EntriesRead-- )
+ {
+ dwSize = sizeof( CONN_INFORMATION );
+ dwSize += pConnInfo->HostServerLength;
+ dwSize += pConnInfo->UserNameLength;
+
+ RtlZeroMemory( tempTreeName,
+ ( NW_MAX_TREE_LEN + 1 ) * sizeof(WCHAR) );
+
+ wcsncpy( tempTreeName,
+ pConnInfo->HostServer,
+ pConnInfo->HostServerLength / sizeof(WCHAR) );
+
+ CharUpperW( tempTreeName );
+
+ //
+ // Add the tree name to the list only
+ // if it's not added already.
+ //
+ Result = SendDlgItemMessageW( DialogHandle,
+ ControlId,
+ LB_FINDSTRING,
+ (WPARAM) -1,
+ (LPARAM) tempTreeName );
+
+ if (Result == LB_ERR)
+ {
+ Result = SendDlgItemMessageW( DialogHandle,
+ ControlId,
+ LB_ADDSTRING,
+ 0,
+ (LPARAM) tempTreeName );
+
+ if (Result != LB_ERR)
+ {
+ LPWSTR lpNdsUserName = NULL;
+
+ lpNdsUserName = (LPWSTR) LocalAlloc( LMEM_ZEROINIT,
+ pConnInfo->UserNameLength +
+ sizeof(WCHAR) );
+
+ if ( lpNdsUserName )
+ {
+ wcsncpy( lpNdsUserName,
+ pConnInfo->UserName,
+ pConnInfo->UserNameLength / sizeof(WCHAR) );
+
+ SendDlgItemMessageW( DialogHandle,
+ ControlId,
+ LB_SETITEMDATA,
+ (WPARAM) Result, // index of entry
+ (LPARAM) lpNdsUserName );
+ }
+ }
+ }
+
+ pConnInfo = (PCONN_INFORMATION) ( ((BYTE *)pConnInfo) + dwSize );
+ }
+ }
+ else
+ {
+ *lpdwUserLuid = 0;
+ }
+}
+
+
+
+BOOL
+WINAPI
+NwpChangePasswdDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+/*++
+
+Routine Description:
+
+ This function is the window management message handler for
+ the change password dialog.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to display the dialog.
+
+ Message - Supplies the window management message.
+
+ LParam - Supplies the pointer to a buffer which on input
+ contains the Server string under which the user
+ needs to type in a new credential before browsing. On
+ output, this pointer contains the username and server
+ strings entered to the dialog box.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ static LPWSTR UserName;
+ static LPWSTR ServerName;
+ static DWORD UserNameSize ;
+ static DWORD ServerNameSize ;
+ INT Result ;
+ PPASSWDDLGPARAM DlgParams ;
+
+ switch (Message) {
+
+ case WM_INITDIALOG:
+
+ DlgParams = (PPASSWDDLGPARAM) LParam;
+ UserName = DlgParams->UserName ;
+ ServerName = DlgParams->ServerName ;
+ UserNameSize = DlgParams->UserNameSize ;
+ ServerNameSize = DlgParams->ServerNameSize ;
+
+ //
+ // Position dialog
+ //
+ NwpCenterDialog(DialogHandle);
+
+
+ //
+ // setup the default user and server names
+ //
+ SetDlgItemTextW(DialogHandle, ID_SERVER, ServerName);
+ SetDlgItemTextW(DialogHandle, ID_USERNAME, UserName);
+
+ //
+ // Username is limited to 256 characters.
+ //
+ SendDlgItemMessageW(DialogHandle,
+ ID_USERNAME,
+ EM_LIMITTEXT,
+ UserNameSize - 1, // minus space for '\0'
+ 0 );
+
+ //
+ // Server is limited to 256 characters.
+ //
+ SendDlgItemMessageW( DialogHandle,
+ ID_SERVER,
+ EM_LIMITTEXT,
+ ServerNameSize - 1, // minus space for '\0'
+ 0 );
+
+ //
+ // Add trees to list
+ //
+ NwpAddToComboBox( DialogHandle,
+ ID_SERVER,
+ NULL,
+ FALSE ) ;
+
+ return TRUE;
+
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam)) {
+
+ case IDOK:
+
+ Result = GetDlgItemTextW( DialogHandle,
+ ID_USERNAME,
+ UserName,
+ UserNameSize );
+
+ Result = GetDlgItemTextW( DialogHandle,
+ ID_SERVER,
+ ServerName,
+ ServerNameSize );
+
+ EndDialog(DialogHandle, (INT) IDOK); // OK
+
+ return TRUE;
+
+
+ case IDCANCEL:
+
+ EndDialog(DialogHandle, (INT) IDCANCEL); // CANCEL
+
+ return TRUE;
+ }
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+
+
+BOOL
+WINAPI
+NwpOldPasswordDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+//
+// This dialog lets the user retype the old password for a specific
+// server/tree.
+//
+{
+ static POLD_PW_DLG_PARAM OldPwParam;
+
+
+ switch (Message) {
+
+ case WM_INITDIALOG:
+
+ OldPwParam = (POLD_PW_DLG_PARAM) LParam;
+
+ NwpCenterDialog(DialogHandle);
+
+ SetDlgItemTextW(DialogHandle, ID_SERVER, OldPwParam->FailedServer);
+
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_PASSWORD,
+ EM_LIMITTEXT,
+ NW_MAX_PASSWORD_LEN,
+ 0
+ );
+
+ return TRUE;
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam))
+ {
+
+ case IDCANCEL:
+ EndDialog(DialogHandle, IDCANCEL);
+ return TRUE;
+
+ case IDOK:
+ {
+ UCHAR EncodeSeed = NW_ENCODE_SEED2;
+ UNICODE_STRING PasswordStr;
+
+
+ RtlZeroMemory(
+ OldPwParam->OldPassword,
+ NW_MAX_PASSWORD_LEN * sizeof(WCHAR)
+ );
+
+ GetDlgItemTextW(
+ DialogHandle,
+ ID_PASSWORD,
+ OldPwParam->OldPassword,
+ NW_MAX_PASSWORD_LEN
+ );
+
+#if DBG
+ IF_DEBUG(LOGON) {
+ KdPrint(("NWPROVAU: Retyped password %ws\n",
+ OldPwParam->OldPassword));
+ }
+#endif
+ RtlInitUnicodeString(&PasswordStr, OldPwParam->OldPassword);
+ RtlRunEncodeUnicodeString(&EncodeSeed, &PasswordStr);
+
+ EndDialog(DialogHandle, IDOK);
+ return TRUE;
+ }
+
+ case IDHELP:
+
+ DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_ENTER_OLD_PW_HELP),
+ (HWND) DialogHandle,
+ NwpHelpDlgProc,
+ (LPARAM) 0
+ );
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+
+
+BOOL
+WINAPI
+NwpAltUserNameDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+//
+// This dialog lets the user retype an alternate username for a specific
+// server/tree.
+//
+{
+ static PUSERNAME_DLG_PARAM UserNameParam;
+
+ switch (Message)
+ {
+ case WM_INITDIALOG:
+
+ UserNameParam = (PUSERNAME_DLG_PARAM) LParam;
+
+ NwpCenterDialog(DialogHandle);
+
+ //
+ // Display the server/tree.
+ //
+ SetDlgItemTextW(
+ DialogHandle,
+ ID_SERVER,
+ UserNameParam->TreeServerName
+ );
+
+ //
+ // Username is limited to 256 characters.
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_USERNAME,
+ EM_LIMITTEXT,
+ 256,
+ 0
+ );
+
+ SetDlgItemTextW(
+ DialogHandle,
+ ID_USERNAME,
+ UserNameParam->UserName
+ );
+
+ return TRUE;
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam))
+ {
+
+ case IDCANCEL:
+ EndDialog(DialogHandle, IDCANCEL);
+ return TRUE;
+
+ case IDOK:
+ {
+ RtlZeroMemory(
+ UserNameParam->UserName,
+ 256 * sizeof(WCHAR)
+ );
+
+ GetDlgItemTextW(
+ DialogHandle,
+ ID_USERNAME,
+ UserNameParam->UserName,
+ 256
+ );
+
+#if DBG
+ IF_DEBUG(LOGON) {
+ KdPrint(("NWPROVAU: Retyped username %ws\n",
+ UserNameParam->UserName));
+ }
+#endif
+
+ EndDialog(DialogHandle, IDOK);
+ return TRUE;
+ }
+
+ case IDHELP:
+
+ DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_ENTER_ALT_UN_HELP),
+ (HWND) DialogHandle,
+ NwpHelpDlgProc,
+ (LPARAM) 0
+ );
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+
+VOID
+EnableAddRemove(
+ IN HWND DialogHandle
+ )
+/*++
+
+Routine Description:
+
+ This function enables and disables Add and Remove buttons
+ based on list box selections.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to the windows dialog.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ INT cSel;
+
+
+ cSel = SendDlgItemMessageW(
+ DialogHandle,
+ ID_INACTIVE_LIST,
+ LB_GETSELCOUNT,
+ 0,
+ 0
+ );
+ EnableWindow(GetDlgItem(DialogHandle, ID_ADD), cSel != 0);
+
+ cSel = SendDlgItemMessageW(
+ DialogHandle,
+ ID_ACTIVE_LIST,
+ LB_GETSELCOUNT,
+ 0,
+ 0
+ );
+ EnableWindow(GetDlgItem(DialogHandle, ID_REMOVE), cSel != 0);
+}
+
+
+
+
+BOOL
+WINAPI
+NwpSelectServersDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+/*++
+
+Routine Description:
+
+ This routine displays two listboxes--an active list which includes
+ the trees which the user is currently attached to, and an inactive
+ list which displays the rest of the trees on the net. The user
+ can select trees and move them back and forth between the list
+ boxes. When OK is selected, the password is changed on the trees
+ in the active listbox.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to the login dialog.
+
+ Message - Supplies the window management message.
+
+ LParam - Supplies the user credential: username, old password and
+ new password. The list of trees from the active listbox
+ and the number of entries are returned.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ WCHAR szServer[NW_MAX_SERVER_LEN + 1];
+ static PCHANGE_PW_DLG_PARAM Credential;
+ DWORD status;
+ DWORD UserLuid = 0;
+ DWORD ActiveListBoxCount;
+ DWORD InactiveListBoxCount;
+
+ switch (Message) {
+
+ case WM_INITDIALOG:
+
+ //
+ // Get the user credential passed in.
+ //
+ Credential = (PCHANGE_PW_DLG_PARAM) LParam;
+
+ //
+ // Position dialog
+ //
+ NwpCenterDialog(DialogHandle);
+
+ //
+ // Display the username.
+ //
+ SetDlgItemTextW(
+ DialogHandle,
+ ID_USERNAME,
+ Credential->UserName
+ );
+
+ //
+ // Display current NetWare tree connections in the active box.
+ //
+ NwpAddNetWareTreeConnectionsToList(
+ DialogHandle,
+ Credential->UserName,
+ &UserLuid,
+ ID_ACTIVE_LIST
+ );
+
+ //
+ // Display all trees in inactive list box.
+ //
+ NwpAddTreeNamesToControl(
+ DialogHandle,
+ ID_INACTIVE_LIST,
+ LB_ADDSTRING,
+ ID_ACTIVE_LIST,
+ LB_FINDSTRING
+ );
+
+ //
+ // Highlight the first entry of the inactive list.
+ //
+ SetFocus(GetDlgItem(DialogHandle, ID_INACTIVE_LIST));
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_INACTIVE_LIST,
+ LB_SETSEL,
+ TRUE,
+ 0
+ );
+
+ EnableAddRemove(DialogHandle);
+
+ ActiveListBoxCount = SendDlgItemMessageW( DialogHandle,
+ ID_ACTIVE_LIST,
+ LB_GETCOUNT,
+ 0,
+ 0 );
+
+ InactiveListBoxCount = SendDlgItemMessageW( DialogHandle,
+ ID_INACTIVE_LIST,
+ LB_GETCOUNT,
+ 0,
+ 0 );
+
+ if ( ActiveListBoxCount == 0 &&
+ InactiveListBoxCount == 0 )
+ {
+ (void) NwpMessageBoxError( DialogHandle,
+ IDS_NETWARE_TITLE,
+ IDS_NO_TREES_DETECTED,
+ 0,
+ NULL,
+ MB_OK );
+
+ EndDialog(DialogHandle, (INT) IDOK);
+ }
+
+ return TRUE;
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam))
+ {
+ case IDOK:
+ {
+ if ((status = NwpGetTreesAndChangePw(
+ DialogHandle,
+ szServer,
+ UserLuid,
+ Credential
+ ) != NO_ERROR))
+ {
+ //
+ // System error: e.g. out of memory error.
+ //
+ (void) NwpMessageBoxError(
+ DialogHandle,
+ IDS_CHANGE_PASSWORD_TITLE,
+ 0,
+ status,
+ NULL,
+ MB_OK | MB_ICONSTOP );
+
+ EndDialog(DialogHandle, (INT) -1);
+ return TRUE;
+ }
+
+ EndDialog(DialogHandle, (INT) IDOK);
+ return TRUE;
+ }
+
+ case IDCANCEL:
+
+ EndDialog(DialogHandle, (INT) IDCANCEL);
+ return TRUE;
+
+
+ case IDHELP:
+
+ DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_PW_SELECT_SERVERS_HELP),
+ (HWND) DialogHandle,
+ NwpHelpDlgProc,
+ (LPARAM) 0
+ );
+
+ return TRUE;
+
+
+
+ case ID_ACTIVE_LIST:
+ //
+ // When Remove is pressed the highlights follows
+ // the selected entries over to the other
+ // list box.
+ //
+ if (HIWORD(WParam) == LBN_SELCHANGE) {
+ //
+ // Unselect the other listbox
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_INACTIVE_LIST,
+ LB_SETSEL,
+ FALSE,
+ (LPARAM) -1
+ );
+
+ EnableAddRemove(DialogHandle);
+ }
+
+ return TRUE;
+
+ case ID_INACTIVE_LIST:
+
+ //
+ // When Add is pressed the highlights follows
+ // the selected entries over to the other
+ // list box.
+ //
+ if (HIWORD(WParam) == LBN_SELCHANGE) {
+ //
+ // Unselect the other listbox
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_ACTIVE_LIST,
+ LB_SETSEL,
+ FALSE,
+ (LPARAM) -1
+ );
+
+ EnableAddRemove(DialogHandle);
+ }
+
+ return TRUE;
+
+ case ID_ADD:
+ case ID_REMOVE:
+ {
+ INT idFrom;
+ INT idTo;
+ INT cSel;
+ INT SelItem;
+ INT iNew;
+ HWND hwndActiveList;
+ HWND hwndInactiveList;
+
+ hwndActiveList = GetDlgItem(DialogHandle, ID_ACTIVE_LIST);
+ hwndInactiveList = GetDlgItem(DialogHandle, ID_INACTIVE_LIST);
+
+ //
+ // Set to NOREDRAW to TRUE
+ //
+ SetWindowLong(hwndActiveList, GWL_STYLE,
+ GetWindowLong(hwndActiveList, GWL_STYLE) | LBS_NOREDRAW);
+ SetWindowLong(hwndInactiveList, GWL_STYLE,
+ GetWindowLong(hwndInactiveList, GWL_STYLE) | LBS_NOREDRAW);
+
+ if (LOWORD(WParam) == ID_ADD)
+ {
+ idFrom = ID_INACTIVE_LIST;
+ idTo = ID_ACTIVE_LIST;
+ }
+ else
+ {
+ idFrom = ID_ACTIVE_LIST;
+ idTo = ID_INACTIVE_LIST;
+ }
+
+ //
+ // Move current selection from idFrom to idTo
+ //
+
+ //
+ // Loop terminates when selection count is zero
+ //
+ for (;;) {
+ //
+ // Get count of selected strings
+ //
+ cSel = SendDlgItemMessageW(
+ DialogHandle,
+ idFrom,
+ LB_GETSELCOUNT,
+ 0,
+ 0
+ );
+
+ if (cSel == 0) {
+ //
+ // No more selection
+ //
+ break;
+ }
+
+ //
+ // To avoid flickering as strings are added and
+ // removed from listboxes, no redraw is set for
+ // both listboxes until we are transfering the
+ // last entry, in which case we reenable redraw
+ // so that both listboxes are updated once.
+ //
+ if (cSel == 1) {
+
+ SetWindowLong(
+ hwndActiveList,
+ GWL_STYLE,
+ GetWindowLong(hwndActiveList, GWL_STYLE) & ~LBS_NOREDRAW
+ );
+
+ SetWindowLong(
+ hwndInactiveList,
+ GWL_STYLE,
+ GetWindowLong(hwndInactiveList, GWL_STYLE) & ~LBS_NOREDRAW
+ );
+ }
+
+ //
+ // Get index of first selected item
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ idFrom,
+ LB_GETSELITEMS,
+ 1,
+ (LPARAM) &SelItem
+ );
+
+ //
+ // Get server name from list
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ idFrom,
+ LB_GETTEXT,
+ (WPARAM) SelItem,
+ (LPARAM) (LPWSTR) szServer
+ );
+
+ //
+ // Remove entry from list
+ //
+ SendDlgItemMessageW(
+ DialogHandle,
+ idFrom,
+ LB_DELETESTRING,
+ (WPARAM) SelItem,
+ 0
+ );
+
+ //
+ // Add entry to list
+ //
+ iNew = SendDlgItemMessageW(
+ DialogHandle,
+ idTo,
+ LB_ADDSTRING,
+ 0,
+ (LPARAM) (LPWSTR) szServer
+ );
+
+ //
+ // Select the new item
+ //
+ if (iNew != LB_ERR) {
+ SendDlgItemMessageW(
+ DialogHandle,
+ idTo,
+ LB_SETSEL,
+ TRUE,
+ iNew
+ );
+ }
+
+ } // for
+
+ EnableAddRemove(DialogHandle);
+
+ } // ID_ADD or ID_REMOVE
+ }
+
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+DWORD
+NwpGetTreesAndChangePw(
+ IN HWND DialogHandle,
+ IN LPWSTR ServerBuf,
+ IN DWORD UserLuid,
+ IN PCHANGE_PW_DLG_PARAM Credential
+ )
+/*++
+
+Routine Description:
+
+ This routine gets the selected trees from the active list box
+ and asks the redirector to change password on them. If a failure
+ is encountered when changing password on a tree, we pop up appropriate
+ dialogs to see if user can fix problem.
+
+Arguments:
+
+ DialogHandle - Supplies a handle to the login dialog.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ DWORD status;
+ HCURSOR Cursor;
+ WCHAR tempOldPassword[NW_MAX_PASSWORD_LEN + 1];
+ WCHAR tempNewPassword[NW_MAX_PASSWORD_LEN + 1];
+ WCHAR tempUserName[MAX_NDS_NAME_CHARS];
+
+ //
+ // Turn cursor into hourglass
+ //
+ Cursor = LoadCursor(NULL, IDC_WAIT);
+ if (Cursor != NULL) {
+ SetCursor(Cursor);
+ ShowCursor(TRUE);
+ }
+
+ Credential->ChangedOne = FALSE;
+ Credential->TreeList = NULL;
+ Credential->UserList = NULL;
+
+ //
+ // Get the number of trees we have to change password on.
+ //
+ Credential->Entries = SendDlgItemMessageW(
+ DialogHandle,
+ ID_ACTIVE_LIST,
+ LB_GETCOUNT,
+ 0,
+ 0 );
+
+ if (Credential->Entries != 0) {
+
+ DWORD Entries; // Number of entries in remaining list
+ DWORD FullIndex; // Index to the whole tree list
+ DWORD i;
+ DWORD BytesNeeded = sizeof(LPWSTR) * Credential->Entries +
+ (NW_MAX_SERVER_LEN + 1) * sizeof(WCHAR) * Credential->Entries;
+ LPBYTE FixedPortion;
+ LPWSTR EndOfVariableData;
+ INT Result;
+
+ Entries = Credential->Entries;
+ Credential->TreeList = LocalAlloc(0, BytesNeeded);
+ Credential->UserList = LocalAlloc(0,
+ sizeof(LPWSTR) * Credential->Entries);
+
+ if (Credential->TreeList == NULL)
+ {
+ KdPrint(("NWPROVAU: No memory to change password\n"));
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ if (Credential->UserList == NULL)
+ {
+ KdPrint(("NWPROVAU: No memory to change password\n"));
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ FixedPortion = (LPBYTE) Credential->TreeList;
+ EndOfVariableData = (LPWSTR) ((DWORD) FixedPortion +
+ ROUND_DOWN_COUNT(BytesNeeded, ALIGN_DWORD));
+
+ for (i = 0; i < Entries; i++)
+ {
+ //
+ // Read the user selected list of servers from the dialog.
+ //
+
+ SendDlgItemMessageW(
+ DialogHandle,
+ ID_ACTIVE_LIST,
+ LB_GETTEXT,
+ (WPARAM) i,
+ (LPARAM) (LPWSTR) ServerBuf );
+
+ NwlibCopyStringToBuffer(
+ ServerBuf,
+ wcslen(ServerBuf),
+ (LPCWSTR) FixedPortion,
+ &EndOfVariableData,
+ &(Credential->TreeList)[i] );
+
+ Result = SendDlgItemMessageW( DialogHandle,
+ ID_ACTIVE_LIST,
+ LB_GETITEMDATA,
+ (WPARAM) i,
+ 0 );
+
+ if ( Result != LB_ERR )
+ {
+ (Credential->UserList)[i] = (LPWSTR) Result;
+ }
+ else
+ {
+ (Credential->UserList)[i] = NULL;
+ }
+
+ FixedPortion += sizeof(LPWSTR);
+ }
+
+ FullIndex = 0;
+
+ do
+ {
+ RtlZeroMemory( tempUserName, sizeof(tempUserName) );
+ RtlZeroMemory( tempOldPassword, sizeof(tempOldPassword) );
+ RtlZeroMemory( tempNewPassword, sizeof(tempNewPassword) );
+ RtlCopyMemory( tempOldPassword,
+ Credential->OldPassword,
+ sizeof(tempOldPassword) );
+ RtlCopyMemory( tempNewPassword,
+ Credential->NewPassword,
+ sizeof(tempNewPassword) );
+
+ if ( (Credential->UserList)[FullIndex] == NULL )
+ {
+ // We don't have any connections to tree <current entry>
+ // Prompt user to supply a user name for which account
+ // we are to change password, or skip . . .
+
+ USERNAME_DLG_PARAM UserNameParam;
+ CHANGE_PASS_DLG_PARAM ChangePassParam;
+
+ UserNameParam.UserName = tempUserName;
+ UserNameParam.TreeServerName = (Credential->TreeList)[FullIndex];
+
+ SetCursor(Cursor);
+ ShowCursor(FALSE);
+
+ Result = DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_ENTER_ALT_USERNAME),
+ (HWND) DialogHandle,
+ NwpAltUserNameDlgProc,
+ (LPARAM) &UserNameParam );
+
+ Cursor = LoadCursor(NULL, IDC_WAIT);
+
+ if (Cursor != NULL)
+ {
+ SetCursor(Cursor);
+ ShowCursor(TRUE);
+ }
+
+ if ( Result != IDOK )
+ {
+ *((Credential->TreeList)[FullIndex]) = L'\0';
+ goto SkipEntry;
+ }
+
+ // Now go reverify the credentials for the user name
+ // entered by user.
+
+ ChangePassParam.UserName = tempUserName;
+ ChangePassParam.TreeName = (Credential->TreeList)[FullIndex];
+ ChangePassParam.OldPassword = tempOldPassword;
+ ChangePassParam.NewPassword = tempNewPassword;
+
+ SetCursor(Cursor);
+ ShowCursor(FALSE);
+
+ Result = DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_CHANGE_PASSWORD3),
+ (HWND) DialogHandle,
+ NwpChangePasswordDlgProc,
+ (LPARAM) &ChangePassParam );
+
+ Cursor = LoadCursor(NULL, IDC_WAIT);
+
+ if (Cursor != NULL)
+ {
+ SetCursor(Cursor);
+ ShowCursor(TRUE);
+ }
+
+ if ( Result != IDOK )
+ {
+ *((Credential->TreeList)[FullIndex]) = L'\0';
+ goto SkipEntry;
+ }
+
+ goto Next;
+ }
+ else
+ {
+ wcscpy( tempUserName, (Credential->UserList)[FullIndex] );
+ LocalFree( (Credential->UserList)[FullIndex] );
+ (Credential->UserList)[FullIndex] = NULL;
+ }
+
+ // Test tempUserName with the user name in Credential->UserName
+ // to see if they are similar (i.e. The first part of the
+ // NDS distinguish name matches).
+
+ if ( _wcsnicmp( tempUserName + 3,
+ Credential->UserName,
+ wcslen( Credential->UserName ) ) )
+ {
+ // The names are not similar!
+ // Prompt user to ask if they really want to change
+ // passwords for dis-similar user on tree <current entry>
+ // or skip . . .
+
+ USERNAME_DLG_PARAM UserNameParam;
+ CHANGE_PASS_DLG_PARAM ChangePassParam;
+
+ UserNameParam.UserName = tempUserName;
+ UserNameParam.TreeServerName = (Credential->TreeList)[FullIndex];
+
+ SetCursor(Cursor);
+ ShowCursor(FALSE);
+
+ Result = DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_ENTER_ALT_USERNAME),
+ (HWND) DialogHandle,
+ NwpAltUserNameDlgProc,
+ (LPARAM) &UserNameParam );
+
+ Cursor = LoadCursor(NULL, IDC_WAIT);
+
+ if (Cursor != NULL)
+ {
+ SetCursor(Cursor);
+ ShowCursor(TRUE);
+ }
+
+ if ( Result != IDOK )
+ {
+ *((Credential->TreeList)[FullIndex]) = L'\0';
+ goto SkipEntry;
+ }
+
+ // Now go reverify the credentials for the user name
+ // entered by user.
+
+ ChangePassParam.UserName = tempUserName;
+ ChangePassParam.TreeName = (Credential->TreeList)[FullIndex];
+ ChangePassParam.OldPassword = tempOldPassword;
+ ChangePassParam.NewPassword = tempNewPassword;
+
+ SetCursor(Cursor);
+ ShowCursor(FALSE);
+
+ Result = DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_CHANGE_PASSWORD3),
+ (HWND) DialogHandle,
+ NwpChangePasswordDlgProc,
+ (LPARAM) &ChangePassParam );
+
+ Cursor = LoadCursor(NULL, IDC_WAIT);
+
+ if (Cursor != NULL)
+ {
+ SetCursor(Cursor);
+ ShowCursor(TRUE);
+ }
+
+ if ( Result != IDOK )
+ {
+ *((Credential->TreeList)[FullIndex]) = L'\0';
+ goto SkipEntry;
+ }
+ }
+
+Next:
+ status = NwrChangePassword(
+ NULL, // Reserved
+ UserLuid,
+ tempUserName,
+ tempOldPassword, // Encoded passwords
+ tempNewPassword,
+ (LPWSTR) (Credential->TreeList)[FullIndex] );
+
+ if (status == ERROR_INVALID_PASSWORD)
+ {
+ OLD_PW_DLG_PARAM OldPasswordParam;
+
+#if DBG
+ IF_DEBUG(LOGON)
+ {
+ KdPrint(("NWPROVAU: First attempt: wrong password on %ws\n",
+ (Credential->TreeList)[FullIndex]));
+ }
+#endif
+
+ //
+ // Display dialog to let user type in an alternate
+ // old password.
+ //
+
+ //
+ // Set up old password buffer to receive from dialog.
+ //
+ OldPasswordParam.OldPassword = tempOldPassword;
+
+ OldPasswordParam.FailedServer = (Credential->TreeList)[FullIndex];
+
+ SetCursor(Cursor);
+ ShowCursor(FALSE);
+
+ Result = DialogBoxParamW(
+ hmodNW,
+ MAKEINTRESOURCEW(DLG_ENTER_OLD_PASSWORD),
+ (HWND) DialogHandle,
+ NwpOldPasswordDlgProc,
+ (LPARAM) &OldPasswordParam );
+
+ Cursor = LoadCursor(NULL, IDC_WAIT);
+
+ if (Cursor != NULL)
+ {
+ SetCursor(Cursor);
+ ShowCursor(TRUE);
+ }
+
+ if (Result == IDOK)
+ {
+ //
+ // Retry change password with alternate old password on
+ // the failed server.
+ //
+ status = NwrChangePassword(
+ NULL, // Reserved
+ UserLuid,
+ tempUserName,
+ tempOldPassword, // Alternate old password
+ tempNewPassword,
+ (LPWSTR) (Credential->TreeList)[FullIndex] );
+ }
+ }
+
+ if (status != NO_ERROR)
+ {
+ //
+ // Either unrecoverable failure or user failed to change
+ // password on second attempt.
+ //
+#if DBG
+ IF_DEBUG(LOGON)
+ {
+ KdPrint(("NWPROVAU: Failed to change password on %ws %lu\n",
+ (Credential->TreeList)[FullIndex], status));
+ }
+#endif
+
+ // Pop up error dialog to let user know that password
+ // could not be changed.
+
+ (void) NwpMessageBoxError(
+ DialogHandle,
+ IDS_CHANGE_PASSWORD_TITLE,
+ IDS_CP_FAILURE_WARNING,
+ status,
+ (LPWSTR) (Credential->TreeList)[FullIndex],
+ MB_OK | MB_ICONSTOP );
+
+ *((Credential->TreeList)[FullIndex]) = L'\0';
+
+ if (status == ERROR_NOT_ENOUGH_MEMORY)
+ return status;
+ }
+
+SkipEntry:
+ //
+ // Continue to change password on the rest of the entries
+ //
+ FullIndex++;
+ Entries = Credential->Entries - FullIndex;
+
+ } while (Entries);
+
+ //
+ // Caller is responsible for freeing TreeList
+ //
+ }
+
+ SetCursor(Cursor);
+ ShowCursor(FALSE);
+
+ return NO_ERROR;
+}
+
+
+BOOL
+WINAPI
+NwpChangePasswordSuccessDlgProc(
+ HWND DialogHandle,
+ UINT Message,
+ WPARAM WParam,
+ LPARAM LParam
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ DialogHandle - Supplies a handle to the login dialog.
+
+ Message - Supplies the window management message.
+
+Return Value:
+
+ TRUE - the message was processed.
+
+ FALSE - the message was not processed.
+
+--*/
+{
+ static PCHANGE_PW_DLG_PARAM Credential;
+ DWORD Count;
+ DWORD i;
+
+ switch (Message)
+ {
+ case WM_INITDIALOG:
+
+ //
+ // Get the user credential passed in.
+ //
+ Credential = (PCHANGE_PW_DLG_PARAM) LParam;
+
+ //
+ // Position dialog
+ //
+ NwpCenterDialog(DialogHandle);
+
+ //
+ // Put list of NetWare trees that we changed password on in the
+ // list box.
+ // ID_SERVER );
+ for ( i = 0; i < Credential->Entries; i++ )
+ {
+ if ( *((Credential->TreeList)[i]) != L'\0' )
+ {
+ SendDlgItemMessageW( DialogHandle,
+ ID_SERVER,
+ LB_ADDSTRING,
+ 0,
+ (LPARAM) (Credential->TreeList)[i] );
+ }
+ }
+
+ Count = SendDlgItemMessageW( DialogHandle,
+ ID_SERVER,
+ LB_GETCOUNT,
+ 0,
+ 0 );
+
+ if ( Count == 0 )
+ EndDialog(DialogHandle, 0);
+
+ return TRUE;
+
+
+ case WM_COMMAND:
+
+ switch (LOWORD(WParam))
+ {
+ case IDOK:
+ case IDCANCEL:
+ EndDialog(DialogHandle, 0);
+ return TRUE;
+ }
+ }
+
+ //
+ // We didn't process this message
+ //
+ return FALSE;
+}
+
+