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.
2184 lines
56 KiB
2184 lines
56 KiB
// Copyright (c) 1995, Microsoft Corporation, all rights reserved
|
|
//
|
|
// pbook.c
|
|
// Remote Access Common Dialog APIs
|
|
// RasPhonebookDlg APIs
|
|
//
|
|
// 06/20/95 Steve Cobb
|
|
|
|
|
|
#include "rasdlgp.h" // Our private header
|
|
#include <commdlg.h> // FileOpen dialog
|
|
#include <dlgs.h> // Common dialog resource constants
|
|
#include <rnk.h> // Shortcut file library
|
|
|
|
#define WM_RASEVENT (WM_USER+987)
|
|
#define WM_NOUSERTIMEOUT (WM_USER+988)
|
|
|
|
#define RAS_SC_IS_BAD_PIN(_err) \
|
|
(((_err) == SCARD_W_WRONG_CHV) || ((_err) == SCARD_E_INVALID_CHV))
|
|
|
|
// In no-user mode this is updated on every mouse or keyboard event by our
|
|
// window hook. The monitor thread notices and resets it's inactivity
|
|
// timeout.
|
|
//
|
|
DWORD g_cInput = 0;
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Help maps
|
|
//----------------------------------------------------------------------------
|
|
|
|
static DWORD g_adwDuHelp[] =
|
|
{
|
|
CID_DU_ST_Entries, HID_DU_LB_Entries,
|
|
CID_DU_LB_Entries, HID_DU_LB_Entries,
|
|
CID_DU_PB_New, HID_DU_PB_New,
|
|
CID_DU_PB_More, HID_DU_PB_More,
|
|
CID_DU_PB_Dial, HID_DU_PB_Dial,
|
|
CID_DU_PB_Close, HID_DU_PB_Close,
|
|
0, 0
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Local datatypes
|
|
//----------------------------------------------------------------------------
|
|
|
|
// Phonebook dialog argument block.
|
|
//
|
|
typedef struct
|
|
_DUARGS
|
|
{
|
|
// Caller's arguments to the RAS API. Outputs in 'pApiArgs' are visible
|
|
// to the API which has the address of same. 'PszPhonebook' is updated if
|
|
// user changes the phonebook on the Preferences->PhoneList page, though
|
|
// API is unaware of this.
|
|
//
|
|
LPTSTR pszPhonebook;
|
|
LPTSTR pszEntry;
|
|
RASPBDLG* pApiArgs;
|
|
|
|
// RAS API return value. Set true if a connection is established within
|
|
// the dialog.
|
|
//
|
|
BOOL fApiResult;
|
|
}
|
|
DUARGS;
|
|
|
|
typedef struct
|
|
_DUCONTEXT
|
|
{
|
|
LPTSTR pszPhonebookPath;
|
|
PBENTRY *pEntry;
|
|
}
|
|
DUCONTEXT;
|
|
|
|
|
|
// Dial-Up Networking dialog context block.
|
|
//
|
|
typedef struct
|
|
_DUINFO
|
|
{
|
|
// Caller's arguments to the RAS API.
|
|
//
|
|
DUARGS* pArgs;
|
|
|
|
// Handle of this dialog and some of it's controls.
|
|
//
|
|
HWND hwndDlg;
|
|
HWND hwndPbNew;
|
|
HWND hwndPbProperties;
|
|
HWND hwndLbEntries;
|
|
HWND hwndPbDial;
|
|
|
|
// Global user preference settings read from the Registry.
|
|
//
|
|
PBUSER user;
|
|
|
|
// Phonebook settings read from the phonebook file.
|
|
//
|
|
PBFILE file;
|
|
|
|
// No logged on user information retrieved via callback.
|
|
//
|
|
RASNOUSER* pNoUser;
|
|
|
|
// Set if in "no user before logon" mode. Always the same as the
|
|
// RASPBDFLAG but here for convenience.
|
|
//
|
|
BOOL fNoUser;
|
|
|
|
// Window hooks used to detect user input in the thread. Used only when
|
|
// 'fNoUser' is set.
|
|
//
|
|
HHOOK hhookKeyboard;
|
|
HHOOK hhookMouse;
|
|
|
|
// TAPI session handle.
|
|
//
|
|
HLINEAPP hlineapp;
|
|
|
|
// Handle of the RAS connection associated with the current entry or NULL
|
|
// if none.
|
|
//
|
|
HRASCONN hrasconn;
|
|
|
|
// Connect monitor objects.
|
|
//
|
|
HANDLE hThread;
|
|
HANDLE hEvent;
|
|
BOOL fAbortMonitor;
|
|
}
|
|
DUINFO;
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Local prototypes (alphabetically)
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
DuCommand(
|
|
IN DUINFO* pInfo,
|
|
IN WORD wNotification,
|
|
IN WORD wId,
|
|
IN HWND hwndCtrl );
|
|
|
|
VOID
|
|
DuCreateShortcut(
|
|
IN DUINFO* pInfo );
|
|
|
|
LRESULT CALLBACK
|
|
DuCreateShortcutCallWndRetProc(
|
|
int code,
|
|
WPARAM wparam,
|
|
LPARAM lparam );
|
|
|
|
INT_PTR CALLBACK
|
|
DuDlgProc(
|
|
IN HWND hwnd,
|
|
IN UINT unMsg,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam );
|
|
|
|
VOID
|
|
DuDeleteSelectedEntry(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuDialSelectedEntry(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuEditSelectedEntry(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuEditSelectedLocation(
|
|
IN DUINFO* pInfo );
|
|
|
|
DWORD
|
|
DuFillLocationList(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuFillPreview(
|
|
IN DUINFO* pInfo );
|
|
|
|
DWORD
|
|
DuGetEntry(
|
|
DUINFO* pInfo,
|
|
DUCONTEXT* pContext );
|
|
|
|
TCHAR*
|
|
DuGetPreview(
|
|
IN DUINFO* pInfo );
|
|
|
|
DWORD
|
|
DuHandleConnectFailure(
|
|
IN DUINFO* pInfo,
|
|
IN RASDIALDLG* pDialInfo);
|
|
|
|
VOID
|
|
DuHangUpSelectedEntry(
|
|
IN DUINFO* pInfo );
|
|
|
|
BOOL
|
|
DuInit(
|
|
IN HWND hwndDlg,
|
|
IN DUARGS* pArgs );
|
|
|
|
LRESULT CALLBACK
|
|
DuInputHook(
|
|
IN int nCode,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam );
|
|
|
|
LRESULT APIENTRY
|
|
DuLbEntriesProc(
|
|
IN HWND hwnd,
|
|
IN UINT unMsg,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam );
|
|
|
|
VOID
|
|
DuLocationChange(
|
|
IN DUINFO* pInfo );
|
|
|
|
DWORD
|
|
DuMonitorThread(
|
|
LPVOID pThreadArg );
|
|
|
|
VOID
|
|
DuNewEntry(
|
|
IN DUINFO* pInfo,
|
|
IN BOOL fClone );
|
|
|
|
VOID
|
|
DuOperatorDial(
|
|
IN DUINFO* pInfo );
|
|
|
|
LRESULT APIENTRY
|
|
DuPbMoreProc(
|
|
IN HWND hwnd,
|
|
IN UINT unMsg,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam );
|
|
|
|
VOID
|
|
DuPopupMoreMenu(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuPreferences(
|
|
IN DUINFO* pInfo,
|
|
IN BOOL fLogon );
|
|
|
|
VOID
|
|
DuSetup(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuStatus(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuTerm(
|
|
IN HWND hwndDlg );
|
|
|
|
VOID
|
|
DuUpdateConnectStatus(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuUpdateLbEntries(
|
|
IN DUINFO* pInfo,
|
|
IN TCHAR* pszEntry );
|
|
|
|
VOID
|
|
DuUpdatePreviewAndLocationState(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuUpdateTitle(
|
|
IN DUINFO* pInfo );
|
|
|
|
VOID
|
|
DuWriteShortcutFile(
|
|
IN HWND hwnd,
|
|
IN TCHAR* pszRnkPath,
|
|
IN TCHAR* pszPbkPath,
|
|
IN TCHAR* pszEntry );
|
|
|
|
DWORD
|
|
DwGetEapLogonInfo(
|
|
VOID *pv,
|
|
EAPLOGONINFO **ppEapLogonInfo );
|
|
|
|
VOID WINAPI
|
|
RasPbDlgCallbackThunk(
|
|
ULONG_PTR ulpId,
|
|
DWORD dwEvent,
|
|
LPWSTR pszEntry,
|
|
LPVOID pArgs );
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// External entry points
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL APIENTRY
|
|
RasPhonebookDlgA(
|
|
IN LPSTR lpszPhonebook,
|
|
IN LPSTR lpszEntry,
|
|
IN OUT LPRASPBDLGA lpInfo )
|
|
|
|
// Win32 ANSI entrypoint that displays the Dial-Up Networking dialog, i.e.
|
|
// the RAS phonebook. 'LpszPhonebook' is the full path the phonebook or
|
|
// NULL indicating the default phonebook. 'LpszEntry' is the entry to
|
|
// highlight on entry or NULL to highlight the first entry in the list.
|
|
// 'LpInfo' is caller's additional input/output parameters.
|
|
//
|
|
// Returns true if user establishes a connection, false otherwise.
|
|
//
|
|
{
|
|
WCHAR* pszPhonebookW;
|
|
WCHAR* pszEntryW;
|
|
RASPBDLGW infoW;
|
|
BOOL fStatus;
|
|
|
|
TRACE( "RasPhonebookDlgA" );
|
|
|
|
if (!lpInfo)
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
|
|
if (lpInfo->dwSize != sizeof(RASPBDLGA))
|
|
{
|
|
lpInfo->dwError = ERROR_INVALID_SIZE;
|
|
return FALSE;
|
|
}
|
|
|
|
// Thunk "A" arguments to "W" arguments.
|
|
//
|
|
if (lpszPhonebook)
|
|
{
|
|
pszPhonebookW = StrDupTFromAUsingAnsiEncoding( lpszPhonebook );
|
|
if (!pszPhonebookW)
|
|
{
|
|
lpInfo->dwError = ERROR_NOT_ENOUGH_MEMORY;
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pszPhonebookW = NULL;
|
|
}
|
|
|
|
if (lpszEntry)
|
|
{
|
|
pszEntryW = StrDupTFromAUsingAnsiEncoding( lpszEntry );
|
|
if (!pszEntryW)
|
|
{
|
|
Free0( pszPhonebookW );
|
|
lpInfo->dwError = ERROR_NOT_ENOUGH_MEMORY;
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pszEntryW = NULL;
|
|
}
|
|
|
|
// Take advantage of the structures currently having the same size and
|
|
// layout. Only the callback is different.
|
|
//
|
|
ASSERT( sizeof(RASPBDLGA) == sizeof(RASPBDLGW) );
|
|
CopyMemory( &infoW, lpInfo, sizeof(infoW) );
|
|
|
|
if (lpInfo->pCallback)
|
|
{
|
|
infoW.dwCallbackId = (ULONG_PTR)lpInfo;
|
|
infoW.pCallback = RasPbDlgCallbackThunk;
|
|
}
|
|
|
|
infoW.reserved2 = lpInfo->reserved2;
|
|
|
|
// Thunk to the equivalent "W" API.
|
|
//
|
|
fStatus = RasPhonebookDlgW( pszPhonebookW, pszEntryW, &infoW );
|
|
|
|
Free0( pszPhonebookW );
|
|
Free0( pszEntryW );
|
|
|
|
return fStatus;
|
|
}
|
|
|
|
|
|
VOID WINAPI
|
|
RasPbDlgCallbackThunk(
|
|
ULONG_PTR ulpId,
|
|
DWORD dwEvent,
|
|
LPWSTR pszEntry,
|
|
LPVOID pArgs )
|
|
|
|
// This thunks "W" callbacks to API caller's "A" callback.
|
|
//
|
|
{
|
|
CHAR* pszEntryA;
|
|
VOID* pArgsA;
|
|
RASPBDLGA* pInfo;
|
|
RASNOUSERA nuA;
|
|
|
|
if (dwEvent == RASPBDEVENT_NoUser || dwEvent == RASPBDEVENT_NoUserEdit)
|
|
{
|
|
RASNOUSERW* pnuW = (RASNOUSERW* )pArgs;
|
|
ASSERT( pnuW );
|
|
|
|
ZeroMemory( &nuA, sizeof(nuA) );
|
|
nuA.dwSize = sizeof(nuA);
|
|
nuA.dwFlags = pnuW->dwFlags;
|
|
nuA.dwTimeoutMs = pnuW->dwTimeoutMs;
|
|
|
|
StrCpyAFromW(nuA.szUserName, pnuW->szUserName, UNLEN + 1);
|
|
StrCpyAFromW(nuA.szPassword, pnuW->szPassword, UNLEN + 1);
|
|
StrCpyAFromW(nuA.szDomain, pnuW->szDomain, UNLEN + 1);
|
|
|
|
pArgsA = &nuA;
|
|
}
|
|
else
|
|
{
|
|
pArgsA = NULL;
|
|
}
|
|
|
|
pszEntryA = StrDupAFromT( pszEntry );
|
|
pInfo = (RASPBDLGA* )ulpId;
|
|
pInfo->pCallback( pInfo->dwCallbackId, dwEvent, pszEntryA, pArgsA );
|
|
Free0( pszEntryA );
|
|
|
|
if (dwEvent == RASPBDEVENT_NoUser || dwEvent == RASPBDEVENT_NoUserEdit)
|
|
{
|
|
RASNOUSERW* pnuW = (RASNOUSERW* )pArgs;
|
|
|
|
pnuW->dwFlags = nuA.dwFlags;
|
|
pnuW->dwTimeoutMs = nuA.dwTimeoutMs;
|
|
|
|
StrCpyWFromA(pnuW->szUserName, nuA.szUserName, UNLEN + 1);
|
|
StrCpyWFromA(pnuW->szPassword, nuA.szPassword, UNLEN + 1);
|
|
StrCpyWFromA(pnuW->szDomain, nuA.szDomain, UNLEN + 1);
|
|
|
|
RtlSecureZeroMemory( nuA.szPassword, PWLEN );
|
|
}
|
|
}
|
|
|
|
|
|
BOOL APIENTRY
|
|
RasPhonebookDlgW(
|
|
IN LPWSTR lpszPhonebook,
|
|
IN LPWSTR lpszEntry,
|
|
IN OUT LPRASPBDLGW lpInfo )
|
|
|
|
// Win32 Unicode entrypoint that displays the Dial-Up Networking dialog,
|
|
// i.e. the RAS phonebook. 'LpszPhonebook' is the full path the phonebook
|
|
// or NULL indicating the default phonebook. 'LpszEntry' is the entry to
|
|
// highlight on entry or NULL to highlight the first entry in the list.
|
|
// 'LpInfo' is caller's additional input/output parameters.
|
|
//
|
|
// Returns true if user establishes a connection, false otherwise.
|
|
//
|
|
{
|
|
INT_PTR nStatus;
|
|
DUARGS args;
|
|
|
|
TRACE( "RasPhonebookDlgW" );
|
|
|
|
if (!lpInfo)
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
|
|
if (lpInfo->dwSize != sizeof(RASPBDLGW))
|
|
{
|
|
lpInfo->dwError = ERROR_INVALID_SIZE;
|
|
return FALSE;
|
|
}
|
|
|
|
// Initialize OUT parameters.
|
|
//
|
|
lpInfo->dwError = 0;
|
|
|
|
// Initialize dialog argument block.
|
|
//
|
|
args.pszPhonebook = lpszPhonebook;
|
|
args.pszEntry = lpszEntry;
|
|
args.pApiArgs = lpInfo;
|
|
args.fApiResult = FALSE;
|
|
|
|
|
|
// Run the dialog.
|
|
//
|
|
nStatus =
|
|
DialogBoxParam(
|
|
g_hinstDll,
|
|
MAKEINTRESOURCE( DID_DU_DialUpNetworking ),
|
|
lpInfo->hwndOwner,
|
|
DuDlgProc,
|
|
(LPARAM )&args );
|
|
|
|
if (nStatus == -1)
|
|
{
|
|
ErrorDlg( lpInfo->hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
|
|
lpInfo->dwError = ERROR_UNKNOWN;
|
|
args.fApiResult = FALSE;
|
|
}
|
|
|
|
return args.fApiResult;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Dial-Up Networking dialog
|
|
// Listed alphabetically following dialog proc
|
|
//----------------------------------------------------------------------------
|
|
|
|
INT_PTR CALLBACK
|
|
DuDlgProc(
|
|
IN HWND hwnd,
|
|
IN UINT unMsg,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam )
|
|
|
|
// DialogProc callback for the Dial-Up Networking dialog, i.e. the
|
|
// phonebook dialog. Parameters and return value are as described for
|
|
// standard windows 'DialogProc's.
|
|
//
|
|
{
|
|
#if 0
|
|
TRACE4( "DuDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
|
|
(DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
|
|
#endif
|
|
|
|
switch (unMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
return DuInit( hwnd, (DUARGS* )lparam );
|
|
}
|
|
|
|
case WM_HELP:
|
|
case WM_CONTEXTMENU:
|
|
{
|
|
ContextHelp( g_adwDuHelp, hwnd, unMsg, wparam, lparam );
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
DUINFO* pInfo = (DUINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
|
|
ASSERT( pInfo );
|
|
|
|
return DuCommand(
|
|
pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
|
|
}
|
|
|
|
case WM_RASEVENT:
|
|
{
|
|
DUINFO* pInfo = (DUINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
|
|
ASSERT( pInfo );
|
|
|
|
DuUpdateConnectStatus( pInfo );
|
|
break;
|
|
}
|
|
|
|
case WM_NOUSERTIMEOUT:
|
|
{
|
|
DUINFO* pInfo;
|
|
ULONG ulCallbacksActive;
|
|
|
|
TRACE( "CancelOwnedWindows" );
|
|
CancelOwnedWindows( hwnd );
|
|
TRACE( "CancelOwnedWindows done" );
|
|
|
|
ulCallbacksActive = CallbacksActive( 1, NULL );
|
|
if (ulCallbacksActive > 0)
|
|
{
|
|
TRACE1( "NoUser timeout stall, n=%d", ulCallbacksActive );
|
|
PostMessage( hwnd, WM_NOUSERTIMEOUT, wparam, lparam );
|
|
return TRUE;
|
|
}
|
|
|
|
pInfo = (DUINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
|
|
if (pInfo)
|
|
{
|
|
pInfo->pArgs->pApiArgs->dwError = STATUS_TIMEOUT;
|
|
}
|
|
|
|
EndDialog( hwnd, TRUE );
|
|
CallbacksActive( 0, NULL );
|
|
break;
|
|
}
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
DuTerm( hwnd );
|
|
|
|
/*
|
|
|
|
//We have to wait for Deonb to return us the IID_Dun1 icon
|
|
//For whistler bug 372078 381099
|
|
//Icon returned by GetCurrentIconEntryType() has to be destroyed
|
|
{
|
|
HICON hIcon=NULL;
|
|
|
|
hIcon = GetProp( hwnd, TEXT("TweakTitleBar_Small_Icon"));
|
|
ASSERT(hIcon);
|
|
if( hIcon )
|
|
{
|
|
DestroyIcon(hIcon);
|
|
}
|
|
else
|
|
{
|
|
TRACE("DuDlgProc:Destroy small Icon failed");
|
|
}
|
|
|
|
RemoveProp( hwnd, TEXT("TweakTitleBar_Small_Icon") );
|
|
|
|
hIcon = GetProp( hwnd, TEXT("TweakTitleBar_Big_Icon"));
|
|
ASSERT(hIcon);
|
|
if( hIcon )
|
|
{
|
|
DestroyIcon(hIcon);
|
|
}
|
|
else
|
|
{
|
|
TRACE("DuDlgProc:Destroy Big Icon failed");
|
|
}
|
|
|
|
RemoveProp( hwnd, TEXT("TweakTitleBar_Big_Icon") );
|
|
|
|
}
|
|
*/
|
|
break;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
DuCommand(
|
|
IN DUINFO* pInfo,
|
|
IN WORD wNotification,
|
|
IN WORD wId,
|
|
IN HWND hwndCtrl )
|
|
|
|
// Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
|
|
// is the notification code of the command. 'wId' is the control/menu
|
|
// identifier of the command. 'HwndCtrl' is the control window handle of
|
|
// the command.
|
|
//
|
|
// Returns true if processed message, false otherwise.
|
|
//
|
|
{
|
|
TRACE3( "DuCommand(n=%d,i=%d,c=$%x)",
|
|
(DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
|
|
|
|
switch (wId)
|
|
{
|
|
case CID_DU_PB_Dial:
|
|
{
|
|
if (pInfo->hrasconn)
|
|
{
|
|
DuHangUpSelectedEntry( pInfo );
|
|
}
|
|
else
|
|
{
|
|
DuDialSelectedEntry( pInfo );
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
case CID_DU_PB_New:
|
|
{
|
|
DuNewEntry( pInfo, FALSE );
|
|
return TRUE;
|
|
}
|
|
|
|
case CID_DU_PB_More:
|
|
{
|
|
DuEditSelectedEntry( pInfo );
|
|
return TRUE;
|
|
}
|
|
|
|
case CID_DU_LB_Entries:
|
|
{
|
|
if (wNotification == CBN_SELCHANGE)
|
|
{
|
|
PBENTRY *pEntry;
|
|
DWORD dwErr = SUCCESS;
|
|
DUCONTEXT *pContext;
|
|
|
|
pContext = (DUCONTEXT *)
|
|
ComboBox_GetItemDataPtr(
|
|
pInfo->hwndLbEntries,
|
|
ComboBox_GetCurSel(pInfo->hwndLbEntries));
|
|
|
|
ASSERT(NULL != pContext);
|
|
|
|
if(NULL == pContext)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Update the phonebook information
|
|
//
|
|
dwErr = DuGetEntry(pInfo, pContext);
|
|
|
|
if(ERROR_SUCCESS == dwErr)
|
|
{
|
|
ComboBox_SetItemData(
|
|
pInfo->hwndLbEntries,
|
|
ComboBox_GetCurSel(pInfo->hwndLbEntries),
|
|
pContext);
|
|
}
|
|
else
|
|
{
|
|
ComboBox_DeleteString(
|
|
pInfo->hwndLbEntries,
|
|
ComboBox_GetCurSel(pInfo->hwndLbEntries) );
|
|
}
|
|
|
|
DuUpdateConnectStatus( pInfo );
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case IDCANCEL:
|
|
case CID_DU_PB_Close:
|
|
{
|
|
EndDialog( pInfo->hwndDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
VOID
|
|
DuDialSelectedEntry(
|
|
IN DUINFO* pInfo )
|
|
|
|
// Called when user presses the "Dial" button.
|
|
//
|
|
{
|
|
DWORD dwErr;
|
|
BOOL fConnected;
|
|
BOOL fAutoLogon;
|
|
TCHAR* pszEbNumber;
|
|
TCHAR* pszEbPreview;
|
|
TCHAR* pszOrgPreview;
|
|
TCHAR* pszOverride;
|
|
TCHAR* pszEntryName;
|
|
RASDIALDLG info;
|
|
INTERNALARGS iargs;
|
|
PBENTRY* pEntry;
|
|
DTLNODE *pdtlnode;
|
|
PBFILE file;
|
|
DUCONTEXT *pContext;
|
|
|
|
TRACE( "DuDialSelectedEntry" );
|
|
|
|
// Look up the selected entry.
|
|
//
|
|
pContext = (DUCONTEXT *) ComboBox_GetItemDataPtr(
|
|
pInfo->hwndLbEntries,
|
|
ComboBox_GetCurSel(pInfo->hwndLbEntries));
|
|
|
|
if (!pContext)
|
|
{
|
|
MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
|
|
SetFocus( pInfo->hwndPbNew );
|
|
return;
|
|
}
|
|
|
|
pEntry = pContext->pEntry;
|
|
|
|
if (!pEntry)
|
|
{
|
|
MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
|
|
SetFocus( pInfo->hwndPbNew );
|
|
return;
|
|
}
|
|
|
|
|
|
pszOverride = NULL;
|
|
pszOrgPreview = NULL;
|
|
pszEbPreview = NULL;
|
|
pszEbNumber = NULL;
|
|
|
|
// Set up API argument block.
|
|
//
|
|
ZeroMemory( &info, sizeof(info) );
|
|
info.dwSize = sizeof(info);
|
|
info.hwndOwner = pInfo->hwndDlg;
|
|
|
|
// The secret hack to share information already loaded with the entry API.
|
|
//
|
|
ZeroMemory( &iargs, sizeof(iargs) );
|
|
iargs.pFile = &pInfo->file;
|
|
iargs.pUser = &pInfo->user;
|
|
iargs.pNoUser = pInfo->pNoUser;
|
|
iargs.fNoUser = pInfo->fNoUser;
|
|
iargs.fForceCloseOnDial =
|
|
(pInfo->pArgs->pApiArgs->dwFlags & RASPBDFLAG_ForceCloseOnDial);
|
|
|
|
iargs.pvEapInfo = NULL;
|
|
|
|
if(0 != pInfo->pArgs->pApiArgs->reserved2)
|
|
{
|
|
DWORD retcode;
|
|
EAPLOGONINFO *pEapInfo = NULL;
|
|
|
|
retcode = DwGetEapLogonInfo(
|
|
(VOID *) pInfo->pArgs->pApiArgs->reserved2,
|
|
&pEapInfo);
|
|
|
|
if(SUCCESS == retcode)
|
|
{
|
|
iargs.pvEapInfo = (VOID *) pEapInfo;
|
|
}
|
|
}
|
|
|
|
iargs.fMoveOwnerOffDesktop =
|
|
(iargs.fForceCloseOnDial || pInfo->user.fCloseOnDial);
|
|
info.reserved = (ULONG_PTR ) &iargs;
|
|
|
|
// Call the Win32 API to run the connect status dialog. Make a copy of
|
|
// the entry name and auto-logon flag first, because RasDialDlg may
|
|
// re-read the entry node to pick up RASAPI changes.
|
|
//
|
|
pszEntryName = StrDup( pEntry->pszEntryName );
|
|
fAutoLogon = pEntry->fAutoLogon;
|
|
|
|
TRACEW1( "RasDialDlg,o=\"%s\"", (pszOverride) ? pszOverride : TEXT("") );
|
|
|
|
//For whistler bug 426268 gangz
|
|
//
|
|
fConnected = RasDialDlg(
|
|
pContext->pszPhonebookPath,
|
|
/*pEntry->pszEntryName*/
|
|
pszEntryName,
|
|
pszOverride,
|
|
&info );
|
|
|
|
TRACE1( "RasDialDlg=%d", fConnected );
|
|
|
|
Free0( pszEbPreview );
|
|
Free0( pszOrgPreview );
|
|
|
|
if(NULL != iargs.pvEapInfo)
|
|
{
|
|
Free0(iargs.pvEapInfo);
|
|
iargs.pvEapInfo = NULL;
|
|
}
|
|
|
|
if (fConnected)
|
|
{
|
|
pInfo->pArgs->fApiResult = TRUE;
|
|
|
|
if (pInfo->pArgs->pApiArgs->pCallback)
|
|
{
|
|
RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
|
|
|
|
if (pInfo->pNoUser && iargs.fNoUserChanged && fAutoLogon)
|
|
{
|
|
// Whistler bug 254385 encode password when not being used
|
|
// Need to Decode password before callback function
|
|
// Assumed password was encoded previously by DuInit()
|
|
//
|
|
DecodePassword( pInfo->pNoUser->szPassword );
|
|
TRACE( "Callback(NoUserEdit)" );
|
|
pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
|
|
RASPBDEVENT_NoUserEdit, NULL, pInfo->pNoUser );
|
|
TRACE( "Callback(NoUserEdit) done" );
|
|
EncodePassword( pInfo->pNoUser->szPassword );
|
|
}
|
|
|
|
TRACE( "Callback(DialEntry)" );
|
|
pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
|
|
RASPBDEVENT_DialEntry, pszEntryName, NULL );
|
|
TRACE( "Callback(DialEntry) done" );
|
|
}
|
|
|
|
if (pInfo->user.fCloseOnDial
|
|
|| (pInfo->pArgs->pApiArgs->dwFlags & RASPBDFLAG_ForceCloseOnDial))
|
|
{
|
|
EndDialog( pInfo->hwndDlg, TRUE );
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
DuHandleConnectFailure(pInfo, &info);
|
|
}
|
|
|
|
if (pInfo->pNoUser && !pInfo->hThread)
|
|
{
|
|
TRACE( "Taking shortcut to exit" );
|
|
return;
|
|
}
|
|
|
|
// Reload the list even if the Dial was cancelled as user may have changed
|
|
// the current PBENTRY with the Properties button on the dialer which
|
|
// commits changes even if user cancels the dial itself. See bug 363710.
|
|
//
|
|
DuUpdateLbEntries( pInfo, pszEntryName );
|
|
SetFocus( pInfo->hwndLbEntries );
|
|
|
|
Free0( pszEntryName );
|
|
}
|
|
|
|
|
|
VOID
|
|
DuEditSelectedEntry(
|
|
IN DUINFO* pInfo )
|
|
|
|
// Called when user selects "Edit entry" from the menu. 'PInfo' is the
|
|
// dialog context. 'PszEntry' is the name of the entry to edit.
|
|
//
|
|
{
|
|
BOOL fOk;
|
|
RASENTRYDLG info;
|
|
INTERNALARGS iargs;
|
|
PBENTRY* pEntry;
|
|
LPTSTR pszEntryName;
|
|
DTLNODE *pdtlnode;
|
|
PBFILE file;
|
|
DWORD dwErr;
|
|
DUCONTEXT *pContext;
|
|
INT iSel;
|
|
|
|
TRACE( "DuEditSelectedEntry" );
|
|
|
|
// Look up the selected entry.
|
|
//
|
|
iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
|
|
if (iSel < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pContext = (DUCONTEXT * )ComboBox_GetItemDataPtr(
|
|
pInfo->hwndLbEntries, iSel );
|
|
|
|
ASSERT(NULL != pContext);
|
|
|
|
if(NULL == pContext)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ASSERT(NULL != pContext->pszPhonebookPath);
|
|
|
|
pEntry = pContext->pEntry;
|
|
|
|
if (!pEntry)
|
|
{
|
|
MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
|
|
SetFocus( pInfo->hwndPbNew );
|
|
return;
|
|
}
|
|
|
|
// Set up API argument block.
|
|
//
|
|
ZeroMemory( &info, sizeof(info) );
|
|
info.dwSize = sizeof(info);
|
|
info.hwndOwner = pInfo->hwndDlg;
|
|
|
|
{
|
|
RECT rect;
|
|
|
|
info.dwFlags = RASEDFLAG_PositionDlg;
|
|
GetWindowRect( pInfo->hwndDlg, &rect );
|
|
info.xDlg = rect.left + DXSHEET;
|
|
info.yDlg = rect.top + DYSHEET;
|
|
}
|
|
|
|
// The secret hack to share information already loaded with the entry API.
|
|
//
|
|
ZeroMemory( &iargs, sizeof(iargs) );
|
|
iargs.pFile = &pInfo->file;
|
|
iargs.pUser = &pInfo->user;
|
|
iargs.pNoUser = pInfo->pNoUser;
|
|
iargs.fNoUser = pInfo->fNoUser;
|
|
info.reserved = (ULONG_PTR ) &iargs;
|
|
|
|
// Call the Win32 API to run the entry property sheet.
|
|
//
|
|
TRACE( "RasEntryDlg" );
|
|
fOk = RasEntryDlg(
|
|
pContext->pszPhonebookPath, pEntry->pszEntryName, &info );
|
|
TRACE1( "RasEntryDlg=%d", fOk );
|
|
|
|
if (pInfo->pNoUser && !pInfo->hThread)
|
|
{
|
|
TRACE( "Taking shortcut to exit" );
|
|
return;
|
|
}
|
|
|
|
if (fOk)
|
|
{
|
|
TRACEW1( "OK pressed,e=\"%s\"", info.szEntry );
|
|
|
|
if (pInfo->pArgs->pApiArgs->pCallback)
|
|
{
|
|
RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
|
|
|
|
TRACE( "Callback(EditEntry)" );
|
|
pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
|
|
RASPBDEVENT_AddEntry, info.szEntry, NULL );
|
|
TRACE( "Callback(EditEntry) done" );
|
|
}
|
|
|
|
DuUpdateLbEntries( pInfo, info.szEntry );
|
|
SetFocus( pInfo->hwndLbEntries );
|
|
}
|
|
else
|
|
{
|
|
TRACE( "Cancel pressed or error" );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Helper function called by DuDialSelectedEntry to handle errors
|
|
// returned from RasDialDlgW
|
|
//
|
|
DWORD
|
|
DuHandleConnectFailure(
|
|
IN DUINFO* pInfo,
|
|
IN RASDIALDLG* pDialInfo)
|
|
{
|
|
TRACE3(
|
|
"DuHandleConnectFailure: nu=%x, r2=%x, de=%x",
|
|
(pInfo->pNoUser),
|
|
(pInfo->pArgs->pApiArgs->reserved2),
|
|
(pDialInfo->dwError));
|
|
|
|
// XP: 384968
|
|
//
|
|
// Handle the bad-PIN error from winlogon
|
|
//
|
|
// Normally, the smart card PIN is gotten by calling EAP-TLS's identity
|
|
// api. This API raises UI and validates the PIN entered.
|
|
//
|
|
// During winlogon, however, the smart card PIN is passed to us from GINA.
|
|
// In this case it is not validated until we call EAP API's. (actually,
|
|
// it's until we call the eap identity api with RAS_EAP_FLAG_LOGON.
|
|
// This flag tells EAP not to raise any UI but instead to use the info
|
|
// passed from GINA)
|
|
//
|
|
// GINA is not able to validate the PIN itself because it does not call any
|
|
// CAPI's directly. Oh well.
|
|
//
|
|
// If RasDialDlg returns a bad pin error, then we should gracefully fail
|
|
// back to winlogon.
|
|
//
|
|
|
|
if ((pInfo->pNoUser) && // called by winlogon
|
|
(pInfo->pArgs->pApiArgs->reserved2) && // for smart card
|
|
(RAS_SC_IS_BAD_PIN(pDialInfo->dwError))) // but pin is bad
|
|
{
|
|
pInfo->pArgs->pApiArgs->dwError = pDialInfo->dwError;
|
|
EndDialog( pInfo->hwndDlg, TRUE );
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
VOID
|
|
DuHangUpSelectedEntry(
|
|
IN DUINFO* pInfo )
|
|
|
|
// Hang up the selected entry after confirming with user. 'Pinfo' is the
|
|
// dialog context block.
|
|
//
|
|
{
|
|
DWORD dwErr;
|
|
PBENTRY* pEntry;
|
|
INT iSel;
|
|
INT nResponse;
|
|
MSGARGS msgargs;
|
|
LPTSTR pszEntryName;
|
|
DTLNODE *pdtlnode;
|
|
DUCONTEXT *pContext;
|
|
|
|
TRACE( "DuHangUpSelectedEntry" );
|
|
|
|
// Look up the selected entry.
|
|
//
|
|
iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
|
|
ASSERT( iSel >= 0 );
|
|
pContext = (DUCONTEXT * )ComboBox_GetItemDataPtr( pInfo->hwndLbEntries, iSel );
|
|
|
|
ASSERT(NULL != pContext);
|
|
|
|
if (!pContext)
|
|
{
|
|
MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
|
|
SetFocus( pInfo->hwndPbNew );
|
|
return;
|
|
}
|
|
|
|
pEntry = pContext->pEntry;
|
|
ASSERT( pEntry );
|
|
|
|
if (!pEntry)
|
|
{
|
|
MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
|
|
SetFocus( pInfo->hwndPbNew );
|
|
return;
|
|
}
|
|
|
|
ZeroMemory( &msgargs, sizeof(msgargs) );
|
|
msgargs.apszArgs[ 0 ] = pEntry->pszEntryName;
|
|
msgargs.dwFlags = MB_YESNO | MB_ICONEXCLAMATION;
|
|
nResponse = MsgDlg( pInfo->hwndDlg, SID_ConfirmHangUp, &msgargs );
|
|
|
|
if (nResponse == IDYES)
|
|
{
|
|
ASSERT( g_pRasHangUp );
|
|
TRACE( "RasHangUp" );
|
|
dwErr = g_pRasHangUp( pInfo->hrasconn );
|
|
TRACE1( "RasHangUp=%d", dwErr );
|
|
if ( dwErr == ERROR_HANGUP_FAILED )
|
|
{
|
|
MsgDlg( pInfo->hwndDlg, SID_CantHangUpRouter, NULL );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
DuInit(
|
|
IN HWND hwndDlg,
|
|
IN DUARGS* pArgs )
|
|
|
|
// Called on WM_INITDIALOG. 'hwndDlg' is the handle of the phonebook
|
|
// dialog window. 'pArgs' points at caller's arguments as passed to the
|
|
// API (or thunk).
|
|
//
|
|
// Return false if focus was set, true otherwise, i.e. as defined for
|
|
// WM_INITDIALOG.
|
|
//
|
|
{
|
|
DWORD dwErr;
|
|
DWORD dwThreadId;
|
|
DWORD dwReadPbkFlags = 0;
|
|
DUINFO* pInfo;
|
|
|
|
TRACE( "DuInit" );
|
|
|
|
// Allocate the dialog context block. Initialize minimally for proper
|
|
// cleanup, then attach to the dialog window.
|
|
//
|
|
{
|
|
pInfo = Malloc( sizeof(*pInfo) );
|
|
if (!pInfo)
|
|
{
|
|
ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
|
|
pArgs->pApiArgs->dwError = ERROR_NOT_ENOUGH_MEMORY;
|
|
EndDialog( hwndDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
|
|
ZeroMemory( pInfo, sizeof(*pInfo) );
|
|
pInfo->file.hrasfile = -1;
|
|
|
|
SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
|
|
TRACE( "Context set" );
|
|
}
|
|
|
|
pInfo->pArgs = pArgs;
|
|
pInfo->hwndDlg = hwndDlg;
|
|
|
|
// Position the dialog per caller's instructions.
|
|
//
|
|
PositionDlg( hwndDlg,
|
|
pArgs->pApiArgs->dwFlags & RASPBDFLAG_PositionDlg,
|
|
pArgs->pApiArgs->xDlg, pArgs->pApiArgs->yDlg );
|
|
|
|
// Load RAS DLL entrypoints which starts RASMAN, if necessary. There must
|
|
// be no API calls that require RASAPI32 or RASMAN prior to this point.
|
|
//
|
|
dwErr = LoadRas( g_hinstDll, hwndDlg );
|
|
if (dwErr != 0)
|
|
{
|
|
ErrorDlg( hwndDlg, SID_OP_LoadRas, dwErr, NULL );
|
|
pArgs->pApiArgs->dwError = dwErr;
|
|
EndDialog( hwndDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
if(0 != (pArgs->pApiArgs->dwFlags & RASPBDFLAG_NoUser))
|
|
{
|
|
// Popup TAPI's "first location" dialog if they are uninitialized.
|
|
//
|
|
dwErr = TapiNoLocationDlg( g_hinstDll, &pInfo->hlineapp, hwndDlg );
|
|
if (dwErr != 0)
|
|
{
|
|
// Error here is treated as a "cancel" per bug 288385.
|
|
//
|
|
pArgs->pApiArgs->dwError = 0;
|
|
EndDialog( hwndDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
pInfo->hwndLbEntries = GetDlgItem( hwndDlg, CID_DU_LB_Entries );
|
|
ASSERT( pInfo->hwndLbEntries );
|
|
pInfo->hwndPbDial = GetDlgItem( hwndDlg, CID_DU_PB_Dial );
|
|
ASSERT( pInfo->hwndPbDial );
|
|
pInfo->hwndPbNew = GetDlgItem( hwndDlg, CID_DU_PB_New );
|
|
ASSERT( pInfo->hwndPbNew );
|
|
pInfo->hwndPbProperties = GetDlgItem( hwndDlg, CID_DU_PB_More );
|
|
ASSERT( pInfo->hwndPbProperties );
|
|
|
|
pInfo->fNoUser = (pArgs->pApiArgs->dwFlags & RASPBDFLAG_NoUser );
|
|
|
|
// Setting this global flag indicates that WinHelp will not work in the
|
|
// current mode. See common\uiutil\ui.c. We assume here that only the
|
|
// WinLogon process makes use of this.
|
|
//
|
|
{
|
|
extern BOOL g_fNoWinHelp;
|
|
g_fNoWinHelp = pInfo->fNoUser;
|
|
}
|
|
|
|
// Read user preferences from registry.
|
|
//
|
|
dwErr = g_pGetUserPreferences(
|
|
NULL, &pInfo->user, pInfo->fNoUser ? UPM_Logon : UPM_Normal);
|
|
if (dwErr != 0)
|
|
{
|
|
//
|
|
// The following free causes a crash in DuTerm. This context will be
|
|
// freed in DuTerm - raos.
|
|
//
|
|
// Free( pInfo );
|
|
ErrorDlg( hwndDlg, SID_OP_LoadPrefs, dwErr, NULL );
|
|
EndDialog( hwndDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
|
|
// Load and parse phonebook file.
|
|
//
|
|
if (pInfo->fNoUser)
|
|
{
|
|
dwReadPbkFlags |= RPBF_NoUser;
|
|
}
|
|
dwErr = ReadPhonebookFile(
|
|
pArgs->pszPhonebook,
|
|
&pInfo->user,
|
|
NULL,
|
|
dwReadPbkFlags,
|
|
&pInfo->file );
|
|
if (dwErr != 0)
|
|
{
|
|
// The following free causes a crash in DuTerm. This context will be
|
|
// freed in DuTerm - raos.
|
|
//
|
|
// Free( pInfo );
|
|
ErrorDlg( hwndDlg, SID_OP_LoadPhonebook, dwErr, NULL );
|
|
EndDialog( hwndDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
|
|
if (pArgs->pApiArgs->pCallback && !pArgs->pszPhonebook)
|
|
{
|
|
RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
|
|
|
|
// Tell user the path to the default phonebook file.
|
|
//
|
|
TRACE( "Callback(EditGlobals)" );
|
|
pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
|
|
RASPBDEVENT_EditGlobals, pInfo->file.pszPath, NULL );
|
|
TRACE( "Callback(EditGlobals) done" );
|
|
}
|
|
|
|
if (pInfo->fNoUser)
|
|
{
|
|
// Retrieve logon information from caller via callback.
|
|
//
|
|
if (pArgs->pApiArgs->pCallback)
|
|
{
|
|
RASPBDLGFUNCW pfunc = pArgs->pApiArgs->pCallback;
|
|
|
|
pInfo->pNoUser = Malloc( sizeof(RASNOUSERW) );
|
|
if (pInfo->pNoUser)
|
|
{
|
|
ZeroMemory( pInfo->pNoUser, sizeof(*pInfo->pNoUser) );
|
|
pInfo->pNoUser->dwSize = sizeof(*pInfo->pNoUser);
|
|
|
|
TRACE( "Callback(NoUser)" );
|
|
pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
|
|
RASPBDEVENT_NoUser, NULL, pInfo->pNoUser );
|
|
TRACE1( "Callback(NoUser) done,to=%d",
|
|
pInfo->pNoUser->dwTimeoutMs );
|
|
TRACEW1( "U=%s",pInfo->pNoUser->szUserName );
|
|
TRACEW1( "D=%s",pInfo->pNoUser->szDomain );
|
|
|
|
// Whistler bug 254385 encode password when not being used
|
|
// Assumed password was not encoded during callback
|
|
//
|
|
EncodePassword( pInfo->pNoUser->szPassword );
|
|
|
|
// Install input detection hooks.
|
|
//
|
|
if (pInfo->pNoUser->dwTimeoutMs > 0)
|
|
{
|
|
pInfo->hhookMouse = SetWindowsHookEx(
|
|
WH_MOUSE, DuInputHook, g_hinstDll,
|
|
GetCurrentThreadId() );
|
|
|
|
pInfo->hhookKeyboard = SetWindowsHookEx(
|
|
WH_KEYBOARD, DuInputHook, g_hinstDll,
|
|
GetCurrentThreadId() );
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!pInfo->user.fAllowLogonPhonebookEdits)
|
|
{
|
|
// Disable new button. See also similar logic for the Properties
|
|
// button occurs in DuUpdateLbEntries.
|
|
//
|
|
EnableWindow( pInfo->hwndPbNew, FALSE );
|
|
}
|
|
}
|
|
|
|
// Load the list of phonebook entries and set selection.
|
|
//
|
|
DuUpdateLbEntries( pInfo, pInfo->pArgs->pszEntry );
|
|
|
|
if (!pInfo->pArgs->pszEntry)
|
|
{
|
|
if (ComboBox_GetCount( pInfo->hwndLbEntries ) > 0)
|
|
{
|
|
ComboBox_SetCurSelNotify( pInfo->hwndLbEntries, 0 );
|
|
}
|
|
}
|
|
|
|
// Update the title to reflect the phonebook mode.
|
|
//
|
|
DuUpdateTitle( pInfo );
|
|
|
|
// Adjust the title bar widgets and create the wizard bitmap.
|
|
//
|
|
TweakTitleBar( hwndDlg );
|
|
AddContextHelpButton( hwndDlg );
|
|
|
|
// Start the connect monitor.
|
|
//
|
|
if ((pInfo->hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ))
|
|
&& (pInfo->hThread = CreateThread(
|
|
NULL, 0, DuMonitorThread, (LPVOID )pInfo, 0,
|
|
(LPDWORD )&dwThreadId )))
|
|
{
|
|
ASSERT( g_pRasConnectionNotification );
|
|
TRACE( "RasConnectionNotification" );
|
|
dwErr = g_pRasConnectionNotification(
|
|
INVALID_HANDLE_VALUE, pInfo->hEvent,
|
|
RASCN_Connection | RASCN_Disconnection );
|
|
TRACE1( "RasConnectionNotification=%d", dwErr );
|
|
}
|
|
else
|
|
TRACE( "Monitor DOA" );
|
|
|
|
if (ComboBox_GetCount( pInfo->hwndLbEntries ) == 0)
|
|
{
|
|
// The phonebook is empty.
|
|
//
|
|
if (pInfo->fNoUser
|
|
&& !pInfo->user.fAllowLogonPhonebookEdits
|
|
)
|
|
{
|
|
// Tell the user you can't create an entry or locations during
|
|
// startup.
|
|
//
|
|
MsgDlg( hwndDlg, SID_EmptyLogonPb, NULL );
|
|
EndDialog( hwndDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
if(pInfo->fNoUser)
|
|
{
|
|
dwErr = TapiNoLocationDlg( g_hinstDll,
|
|
&pInfo->hlineapp, hwndDlg );
|
|
if (dwErr != 0)
|
|
{
|
|
// Error here is treated as a "cancel" per bug 288385.
|
|
//
|
|
pArgs->pApiArgs->dwError = 0;
|
|
EndDialog( hwndDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
// Tell the user, then automatically start him into adding a new
|
|
// entry. Set initial focus to "New" button first, in case user
|
|
// cancels out.
|
|
//
|
|
SetFocus( pInfo->hwndPbNew );
|
|
MsgDlg( hwndDlg, SID_EmptyPhonebook, NULL );
|
|
DuNewEntry( pInfo, FALSE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Set initial focus to the non-empty entry listbox.
|
|
//
|
|
SetFocus( pInfo->hwndLbEntries );
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
LRESULT CALLBACK
|
|
DuInputHook(
|
|
IN int nCode,
|
|
IN WPARAM wparam,
|
|
IN LPARAM lparam )
|
|
|
|
// Standard Win32 'MouseProc' or 'KeyboardProc' callback. For our simple
|
|
// processing we can take advantage of them having identical arguments and
|
|
// 'nCode' definitions.
|
|
//
|
|
{
|
|
if (nCode == HC_ACTION)
|
|
{
|
|
++g_cInput;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
VOID
|
|
DuNewEntry(
|
|
IN DUINFO* pInfo,
|
|
IN BOOL fClone )
|
|
|
|
// Called when user presses the "New" button or "Clone" menu item.
|
|
// 'PInfo' is the dialog context. 'FClone' is set to clone the selected
|
|
// entry, otherwise an empty entry is created.
|
|
//
|
|
{
|
|
BOOL fOk;
|
|
TCHAR* pszEntry;
|
|
RASENTRYDLG info;
|
|
INTERNALARGS iargs;
|
|
PBENTRY* pEntry;
|
|
|
|
TRACE1( "DuNewEntry(f=%d)", fClone );
|
|
|
|
ZeroMemory( &info, sizeof(info) );
|
|
info.dwSize = sizeof(info);
|
|
info.hwndOwner = pInfo->hwndDlg;
|
|
|
|
if (fClone)
|
|
{
|
|
DUCONTEXT *pContext;
|
|
|
|
// Look up the selected entry.
|
|
//
|
|
pContext = (DUCONTEXT* )ComboBox_GetItemDataPtr(
|
|
pInfo->hwndLbEntries, ComboBox_GetCurSel( pInfo->hwndLbEntries ) );
|
|
|
|
if (!pContext)
|
|
{
|
|
MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
|
|
SetFocus( pInfo->hwndPbNew );
|
|
return;
|
|
}
|
|
|
|
pEntry = pContext->pEntry;
|
|
|
|
if (!pEntry)
|
|
{
|
|
MsgDlg( pInfo->hwndDlg, SID_NoEntrySelected, NULL );
|
|
SetFocus( pInfo->hwndPbNew );
|
|
return;
|
|
}
|
|
|
|
pszEntry = pEntry->pszEntryName;
|
|
info.dwFlags = RASEDFLAG_CloneEntry;
|
|
}
|
|
else
|
|
{
|
|
pszEntry = NULL;
|
|
info.dwFlags = RASEDFLAG_NewEntry;
|
|
}
|
|
|
|
{
|
|
RECT rect;
|
|
|
|
GetWindowRect( pInfo->hwndDlg, &rect );
|
|
info.dwFlags += RASEDFLAG_PositionDlg;
|
|
info.xDlg = rect.left + DXSHEET;
|
|
info.yDlg = rect.top + DYSHEET;
|
|
}
|
|
|
|
// The secret hack to share information already loaded with the entry API.
|
|
//
|
|
ZeroMemory( &iargs, sizeof(iargs) );
|
|
iargs.pFile = &pInfo->file;
|
|
iargs.pUser = &pInfo->user;
|
|
iargs.pNoUser = pInfo->pNoUser;
|
|
iargs.fNoUser = pInfo->fNoUser;
|
|
info.reserved = (ULONG_PTR ) &iargs;
|
|
|
|
// Call the Win32 API to run the add entry wizard.
|
|
//
|
|
TRACE( "RasEntryDlg" );
|
|
fOk = RasEntryDlg( pInfo->pArgs->pszPhonebook, pszEntry, &info );
|
|
TRACE1( "RasEntryDlg=%d", fOk );
|
|
|
|
if (pInfo->pNoUser && !pInfo->hThread)
|
|
{
|
|
TRACE( "Taking shortcut to exit" );
|
|
return;
|
|
}
|
|
|
|
if (fOk)
|
|
{
|
|
TRACEW1( "OK pressed, e=\"%s\"", info.szEntry );
|
|
|
|
if (pInfo->pArgs->pApiArgs->pCallback)
|
|
{
|
|
RASPBDLGFUNCW pfunc = pInfo->pArgs->pApiArgs->pCallback;
|
|
|
|
TRACE( "Callback(AddEntry)" );
|
|
pfunc( pInfo->pArgs->pApiArgs->dwCallbackId,
|
|
RASPBDEVENT_AddEntry, info.szEntry, NULL );
|
|
TRACE( "Callback(AddEntry) done" );
|
|
}
|
|
|
|
DuUpdateLbEntries( pInfo, info.szEntry );
|
|
Button_MakeDefault( pInfo->hwndDlg, pInfo->hwndPbDial );
|
|
SetFocus( pInfo->hwndLbEntries );
|
|
}
|
|
else
|
|
{
|
|
TRACE( "Cancel pressed or error" );
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DuUpdateConnectStatus(
|
|
IN DUINFO* pInfo )
|
|
|
|
// Called to update connect status of the selected entry and the text of
|
|
// the Dial/HangUp button. 'PInfo' is the dialog context block.
|
|
//
|
|
{
|
|
TCHAR* pszPhonebook;
|
|
TCHAR* pszEntry;
|
|
INT iSel;
|
|
TCHAR* psz;
|
|
DUCONTEXT *pContext;
|
|
|
|
TRACE( "DuUpdateConnectStatus" );
|
|
|
|
// pszPhonebook = pInfo->file.pszPath;
|
|
iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
|
|
if (iSel < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pContext = (DUCONTEXT *) ComboBox_GetItemDataPtr(
|
|
pInfo->hwndLbEntries,
|
|
iSel);
|
|
|
|
ASSERT(NULL != pContext);
|
|
|
|
pszEntry = ComboBox_GetPsz( pInfo->hwndLbEntries, iSel );
|
|
pInfo->hrasconn = HrasconnFromEntry(
|
|
pContext->pszPhonebookPath,
|
|
pszEntry );
|
|
|
|
psz = PszFromId( g_hinstDll,
|
|
(pInfo->hrasconn) ? SID_DU_HangUp : SID_DU_Dial );
|
|
if (psz)
|
|
{
|
|
SetWindowText( pInfo->hwndPbDial, psz );
|
|
Free( psz );
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
DuUpdateLbEntries(
|
|
IN DUINFO* pInfo,
|
|
IN TCHAR* pszEntry )
|
|
|
|
// Update the contents of the entry listbox and set the selection to
|
|
// 'pszEntry'. If there are entries the Properties button is enabled,
|
|
// otherwise it is disabled. 'PInfo' is the dialog context.
|
|
//
|
|
{
|
|
DTLNODE* pNode;
|
|
RASENTRYNAME *pRasEntryNames = NULL;
|
|
DWORD cEntries = 0;
|
|
DWORD cb;
|
|
DWORD dwErr;
|
|
DWORD i;
|
|
RASENTRYNAME ren;
|
|
DUCONTEXT *pContext;
|
|
INT iSel;
|
|
|
|
TRACE( "DuUpdateLbEntries" );
|
|
|
|
iSel = -1;
|
|
ComboBox_ResetContent( pInfo->hwndLbEntries );
|
|
|
|
cb = ren.dwSize = sizeof(RASENTRYNAME);
|
|
|
|
//
|
|
// Enumerate entries across all phonebooks. Fix for bug 206467
|
|
//
|
|
dwErr = g_pRasEnumEntries(NULL,
|
|
pInfo->pArgs->pszPhonebook,
|
|
&ren,
|
|
&cb,
|
|
&cEntries);
|
|
|
|
if( ( (ERROR_BUFFER_TOO_SMALL == dwErr)
|
|
|| (SUCCESS == dwErr))
|
|
&& (cb >= sizeof(RASENTRYNAME)))
|
|
{
|
|
pRasEntryNames = (RASENTRYNAME *) Malloc(cb);
|
|
|
|
if(NULL == pRasEntryNames)
|
|
{
|
|
// Nothing else can be done in this case
|
|
//
|
|
goto done;
|
|
}
|
|
|
|
pRasEntryNames->dwSize = sizeof(RASENTRYNAME);
|
|
|
|
dwErr = g_pRasEnumEntries(NULL,
|
|
pInfo->pArgs->pszPhonebook,
|
|
pRasEntryNames,
|
|
&cb,
|
|
&cEntries);
|
|
|
|
if(dwErr)
|
|
{
|
|
goto done;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
|
|
for(i = 0; i < cEntries; i++)
|
|
{
|
|
pContext = (DUCONTEXT *) Malloc(sizeof(DUCONTEXT));
|
|
|
|
if(NULL == pContext)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
ZeroMemory(pContext, sizeof(DUCONTEXT));
|
|
|
|
pContext->pszPhonebookPath =
|
|
StrDup(
|
|
pRasEntryNames[i].szPhonebookPath
|
|
);
|
|
|
|
ComboBox_AddItem(pInfo->hwndLbEntries,
|
|
pRasEntryNames[i].szEntryName,
|
|
pContext);
|
|
|
|
|
|
}
|
|
|
|
if (ComboBox_GetCount( pInfo->hwndLbEntries ) >= 0)
|
|
{
|
|
if (pszEntry)
|
|
{
|
|
// Select entry specified by API caller.
|
|
//
|
|
iSel = ComboBox_FindStringExact(
|
|
pInfo->hwndLbEntries, -1, pszEntry );
|
|
}
|
|
|
|
if (iSel < 0)
|
|
{
|
|
// Entry not found so default to first item selected.
|
|
//
|
|
iSel = 0;
|
|
}
|
|
|
|
if(ComboBox_GetCount(pInfo->hwndLbEntries) > 0)
|
|
{
|
|
ComboBox_SetCurSelNotify( pInfo->hwndLbEntries, iSel );
|
|
}
|
|
}
|
|
|
|
done:
|
|
|
|
// Enable/disable Properties button based on existence of an entry. See
|
|
// bug 313037.
|
|
//
|
|
if (ComboBox_GetCurSel( pInfo->hwndLbEntries ) >= 0
|
|
&& (!pInfo->fNoUser || pInfo->user.fAllowLogonPhonebookEdits))
|
|
{
|
|
EnableWindow( pInfo->hwndPbProperties, TRUE );
|
|
}
|
|
else
|
|
{
|
|
if (GetFocus() == pInfo->hwndPbProperties)
|
|
{
|
|
SetFocus( pInfo->hwndPbDial );
|
|
}
|
|
|
|
EnableWindow( pInfo->hwndPbProperties, FALSE );
|
|
}
|
|
|
|
ComboBox_AutoSizeDroppedWidth( pInfo->hwndLbEntries );
|
|
Free0(pRasEntryNames);
|
|
}
|
|
|
|
VOID
|
|
DuUpdateTitle(
|
|
IN DUINFO* pInfo )
|
|
|
|
// Called to update the dialog title to reflect the current phonebook.
|
|
// 'PInfo' is the dialog context.
|
|
//
|
|
{
|
|
TCHAR szBuf[ 256 ];
|
|
TCHAR* psz;
|
|
|
|
// For whistler 117934, initialize the buffer
|
|
//
|
|
ZeroMemory( szBuf, 256 * sizeof(TCHAR) );
|
|
psz = PszFromId( g_hinstDll, SID_PopupTitle );
|
|
if (psz)
|
|
{
|
|
lstrcpyn( szBuf, psz, sizeof(szBuf) / sizeof(TCHAR) );
|
|
Free( psz );
|
|
}
|
|
else
|
|
{
|
|
*szBuf = TEXT('0');
|
|
}
|
|
|
|
if (pInfo->pArgs->pszPhonebook
|
|
|| pInfo->user.dwPhonebookMode != PBM_System)
|
|
{
|
|
INT iSel;
|
|
|
|
iSel = ComboBox_GetCurSel(pInfo->hwndLbEntries);
|
|
if (iSel >= 0)
|
|
{
|
|
DUCONTEXT *pContext;
|
|
|
|
pContext = (DUCONTEXT *) ComboBox_GetItemDataPtr(
|
|
pInfo->hwndLbEntries, iSel);
|
|
|
|
ASSERT( pContext );
|
|
|
|
if(NULL != pContext)
|
|
{
|
|
lstrcat( szBuf, TEXT(" - ") );
|
|
lstrcat( szBuf, StripPath( pContext->pszPhonebookPath ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
SetWindowText( pInfo->hwndDlg, szBuf );
|
|
}
|
|
|
|
|
|
VOID
|
|
DuTerm(
|
|
IN HWND hwndDlg )
|
|
|
|
// Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
|
|
//
|
|
{
|
|
DUINFO* pInfo;
|
|
|
|
DWORD i;
|
|
DWORD cEntries;
|
|
|
|
TRACE( "DuTerm" );
|
|
|
|
pInfo = (DUINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
|
|
if (pInfo)
|
|
{
|
|
// Close ReceiveMonitorThread resources.
|
|
//
|
|
if (pInfo->hThread)
|
|
{
|
|
TRACE( "Set abort event" );
|
|
|
|
// Tell thread to wake up and quit...
|
|
//
|
|
pInfo->fAbortMonitor = TRUE;
|
|
CloseHandle( pInfo->hThread );
|
|
|
|
// Don't SetEvent before closing the thread handle. On
|
|
// multi-proc systems, the thread will exit so fast (and
|
|
// set hThread to NULL) that CloseHandle will then close
|
|
// an invalid handle.
|
|
//
|
|
SetEvent( pInfo->hEvent );
|
|
|
|
// ...and wait for that to happen. A message API (such as
|
|
// PeekMessage) must be called to prevent the thread-to-thread
|
|
// SendMessage in the thread from blocking.
|
|
//
|
|
{
|
|
MSG msg;
|
|
|
|
TRACE( "Termination spin..." );
|
|
for (;;)
|
|
{
|
|
PeekMessage( &msg, hwndDlg, 0, 0, PM_NOREMOVE );
|
|
if (!pInfo->hThread)
|
|
{
|
|
break;
|
|
}
|
|
Sleep( 500L );
|
|
}
|
|
TRACE( "Termination spin ends" );
|
|
}
|
|
}
|
|
|
|
if (pInfo->hEvent)
|
|
{
|
|
CloseHandle( pInfo->hEvent );
|
|
}
|
|
|
|
if (pInfo->pNoUser)
|
|
{
|
|
// Don't leave caller's password floating around in memory.
|
|
//
|
|
RtlSecureZeroMemory( pInfo->pNoUser->szPassword, PWLEN * sizeof(TCHAR) );
|
|
Free( pInfo->pNoUser );
|
|
|
|
// Uninstall input event hooks.
|
|
//
|
|
if (pInfo->hhookMouse)
|
|
{
|
|
UnhookWindowsHookEx( pInfo->hhookMouse );
|
|
}
|
|
if (pInfo->hhookKeyboard)
|
|
{
|
|
UnhookWindowsHookEx( pInfo->hhookKeyboard );
|
|
}
|
|
}
|
|
else if ((pInfo->pArgs->pApiArgs->dwFlags & RASPBDFLAG_UpdateDefaults)
|
|
&& pInfo->hwndLbEntries && pInfo->user.fInitialized)
|
|
{
|
|
INT iSel;
|
|
RECT rect;
|
|
|
|
// Caller said to update default settings so save the name of the
|
|
// selected entry and the current window position.
|
|
//
|
|
iSel = ComboBox_GetCurSel( pInfo->hwndLbEntries );
|
|
if (iSel >= 0)
|
|
{
|
|
DUCONTEXT *pContext;
|
|
PBENTRY* pEntry;
|
|
|
|
pContext = (DUCONTEXT* )ComboBox_GetItemDataPtr(
|
|
pInfo->hwndLbEntries, iSel );
|
|
|
|
if( (NULL != pContext)
|
|
&& (NULL != (pEntry = pContext->pEntry)))
|
|
{
|
|
Free0( pInfo->user.pszDefaultEntry );
|
|
pInfo->user.pszDefaultEntry =
|
|
StrDup( pEntry->pszEntryName );
|
|
}
|
|
}
|
|
|
|
if (!SetOffDesktop( pInfo->hwndDlg, SOD_GetOrgRect, &rect ))
|
|
{
|
|
GetWindowRect( pInfo->hwndDlg, &rect );
|
|
}
|
|
pInfo->user.dwXPhonebook = rect.left;
|
|
pInfo->user.dwYPhonebook = rect.top;
|
|
|
|
pInfo->user.fDirty = TRUE;
|
|
g_pSetUserPreferences(
|
|
NULL, &pInfo->user, pInfo->fNoUser ? UPM_Logon : UPM_Normal );
|
|
}
|
|
|
|
if(NULL != pInfo->hwndLbEntries)
|
|
{
|
|
DUCONTEXT *pContext;
|
|
|
|
cEntries = ComboBox_GetCount(pInfo->hwndLbEntries);
|
|
|
|
//
|
|
// Free the context stored in the list box
|
|
//
|
|
for(i = 0; i < cEntries; i++)
|
|
{
|
|
pContext = ComboBox_GetItemDataPtr(
|
|
pInfo->hwndLbEntries, i);
|
|
|
|
if(NULL != pContext)
|
|
{
|
|
Free0(pContext->pszPhonebookPath);
|
|
}
|
|
|
|
Free0(pContext);
|
|
}
|
|
}
|
|
|
|
TapiShutdown( pInfo->hlineapp );
|
|
ClosePhonebookFile( &pInfo->file );
|
|
DestroyUserPreferences( &pInfo->user );
|
|
Free( pInfo );
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
DuMonitorThread(
|
|
LPVOID pThreadArg )
|
|
|
|
// The "main" of the "connect monitor" thread. This thread simply
|
|
// converts Win32 RasConnectionNotification events int WM_RASEVENT style
|
|
// notfications.
|
|
//
|
|
{
|
|
DUINFO* pInfo;
|
|
DWORD dwErr;
|
|
DWORD dwTimeoutMs;
|
|
DWORD dwQuitTick;
|
|
DWORD cInput = 0;
|
|
|
|
TRACE( "DuMonitor starting" );
|
|
|
|
pInfo = (DUINFO* )pThreadArg;
|
|
|
|
if (pInfo->pNoUser && pInfo->pNoUser->dwTimeoutMs != 0)
|
|
{
|
|
TRACE( "DuMonitor quit timer set" );
|
|
dwTimeoutMs = 5000L;
|
|
dwQuitTick = GetTickCount() + pInfo->pNoUser->dwTimeoutMs;
|
|
cInput = g_cInput;
|
|
}
|
|
else
|
|
{
|
|
dwTimeoutMs = INFINITE;
|
|
dwQuitTick = 0;
|
|
}
|
|
|
|
// Trigger the event so the other thread has the correct state as of the
|
|
// monitor starting.
|
|
//
|
|
SetEvent( pInfo->hEvent );
|
|
|
|
for (;;)
|
|
{
|
|
dwErr = WaitForSingleObject( pInfo->hEvent, dwTimeoutMs );
|
|
|
|
if (pInfo->fAbortMonitor)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (dwErr == WAIT_TIMEOUT)
|
|
{
|
|
if (g_cInput > cInput)
|
|
{
|
|
TRACE( "Input restarts timer" );
|
|
cInput = g_cInput;
|
|
dwQuitTick = GetTickCount() + pInfo->pNoUser->dwTimeoutMs;
|
|
}
|
|
else if (GetTickCount() >= dwQuitTick)
|
|
{
|
|
TRACE( "/DuMonitor SendMessage(WM_NOUSERTIMEOUT)" );
|
|
SendMessage( pInfo->hwndDlg, WM_NOUSERTIMEOUT, 0, 0 );
|
|
TRACE( "\\DuMonitor SendMessage(WM_NOUSERTIMEOUT) done" );
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRACE( "/DuMonitor SendMessage(WM_RASEVENT)" );
|
|
SendMessage( pInfo->hwndDlg, WM_RASEVENT, 0, 0 );
|
|
TRACE( "\\DuMonitor SendMessage(WM_RASEVENT) done" );
|
|
}
|
|
}
|
|
|
|
// This clues the other thread that all interesting work has been done.
|
|
//
|
|
pInfo->hThread = NULL;
|
|
|
|
TRACE( "DuMonitor terminating" );
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
DuGetEntry(
|
|
DUINFO* pInfo,
|
|
DUCONTEXT* pContext )
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
DWORD dwReadPbkFlags = 0;
|
|
LPTSTR pszEntryName;
|
|
DTLNODE *pdtlnode;
|
|
PBFILE file;
|
|
|
|
ASSERT(NULL != pContext);
|
|
|
|
pContext->pEntry = NULL;
|
|
|
|
pszEntryName = ComboBox_GetPsz(pInfo->hwndLbEntries,
|
|
ComboBox_GetCurSel(pInfo->hwndLbEntries));
|
|
|
|
if (pInfo->fNoUser)
|
|
{
|
|
dwReadPbkFlags |= RPBF_NoUser;
|
|
}
|
|
|
|
if( (NULL != pInfo->file.pszPath)
|
|
&& (0 == lstrcmpi(pContext->pszPhonebookPath,
|
|
pInfo->file.pszPath)))
|
|
{
|
|
//
|
|
// We already have the phonebook file open
|
|
//
|
|
pdtlnode = EntryNodeFromName(
|
|
pInfo->file.pdtllistEntries,
|
|
pszEntryName);
|
|
|
|
ASSERT(NULL != pdtlnode);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// phonebook file changed. So close the existing phone
|
|
// book file and open the one in which the entry
|
|
// belongs
|
|
//
|
|
if(NULL != pInfo->file.pszPath)
|
|
{
|
|
ClosePhonebookFile(&pInfo->file);
|
|
}
|
|
|
|
dwErr = GetPbkAndEntryName(pContext->pszPhonebookPath,
|
|
pszEntryName,
|
|
dwReadPbkFlags,
|
|
&file,
|
|
&pdtlnode);
|
|
|
|
if(dwErr)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
ASSERT(NULL != pdtlnode);
|
|
|
|
CopyMemory(&pInfo->file, &file, sizeof(PBFILE));
|
|
}
|
|
|
|
if (pdtlnode)
|
|
{
|
|
pContext->pEntry = (PBENTRY *) DtlGetData(pdtlnode);
|
|
}
|
|
else
|
|
{
|
|
dwErr = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
|
|
}
|
|
|
|
done:
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD
|
|
DwGetEapLogonInfo(
|
|
VOID *pv,
|
|
EAPLOGONINFO **ppEapLogonInfo )
|
|
{
|
|
EAPLOGONINFO *pEapLogonInfo = NULL;
|
|
|
|
DWORD retcode = SUCCESS;
|
|
|
|
struct EAPINFO
|
|
{
|
|
DWORD dwSizeofEapInfo;
|
|
PBYTE pbEapInfo;
|
|
DWORD dwSizeofPINInfo;
|
|
PBYTE pbPINInfo;
|
|
};
|
|
|
|
struct EAPINFO *pEapInfo = (struct EAPINFO *) pv;
|
|
|
|
DWORD dwSize;
|
|
|
|
if(NULL == pv)
|
|
{
|
|
retcode = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
dwSize = sizeof(EAPLOGONINFO)
|
|
+ pEapInfo->dwSizeofEapInfo
|
|
+ pEapInfo->dwSizeofPINInfo;
|
|
|
|
pEapLogonInfo = (EAPLOGONINFO *) Malloc(dwSize);
|
|
|
|
if(NULL == pEapLogonInfo)
|
|
{
|
|
|
|
retcode = GetLastError();
|
|
|
|
TRACE1("Failed to Allocate EapLogonInfo. rc=0x%x",
|
|
retcode);
|
|
goto done;
|
|
}
|
|
|
|
ZeroMemory(pEapLogonInfo, dwSize);
|
|
|
|
//
|
|
// Set up the fields in pEapLogonInfo by
|
|
// flattening out the information passed
|
|
// in.
|
|
//
|
|
pEapLogonInfo->dwSize = dwSize;
|
|
|
|
pEapLogonInfo->dwLogonInfoSize =
|
|
pEapInfo->dwSizeofEapInfo;
|
|
|
|
pEapLogonInfo->dwOffsetLogonInfo =
|
|
FIELD_OFFSET(EAPLOGONINFO, abdata);
|
|
|
|
memcpy( pEapLogonInfo->abdata,
|
|
pEapInfo->pbEapInfo,
|
|
pEapInfo->dwSizeofEapInfo);
|
|
|
|
pEapLogonInfo->dwPINInfoSize =
|
|
pEapInfo->dwSizeofPINInfo;
|
|
|
|
pEapLogonInfo->dwOffsetPINInfo =
|
|
FIELD_OFFSET(EAPLOGONINFO, abdata)
|
|
+ pEapInfo->dwSizeofEapInfo;
|
|
|
|
memcpy( (PBYTE)
|
|
((PBYTE) pEapLogonInfo
|
|
+ pEapLogonInfo->dwOffsetPINInfo),
|
|
|
|
pEapInfo->pbPINInfo,
|
|
|
|
pEapInfo->dwSizeofPINInfo);
|
|
|
|
done:
|
|
*ppEapLogonInfo = pEapLogonInfo;
|
|
|
|
return retcode;
|
|
}
|