2025-11-28 00:35:46 +09:00

879 lines
31 KiB
C++

//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright © 2002 Microsoft Corporation. All Rights Reserved.
//
// Abstract:
// This code demonstrates how to build a customdial DLL for
// Windows 2000 and Windows XP RAS. The code shows how to export and provide a
// rudimentary implementation for each of the exports required
// by the DLL.
//
// You must create an appropriate RAS Entry in the phonebook that inlcudes a path to this
// custom DLL. See the CustomEntry sample on how to create a phonebook entry with a path to
// your custom DLL.
//
// The DLL provides debug tracing facilities through the use of
// OutputDebugString. In this manner one can use programs that intercept
// this output to view the DLL state while it is running such as DBMon
// in the Platform SDK, an attached debugger, or other 3rd party
// programs.
//
//
// Includes
//
#ifdef WINVER
#undef WINVER
#endif
#define WINVER 0x0500 // needed for Windows 2000 RAS extensions
#ifndef UNICODE
#define UNICODE // this is a Unicode DLL
#endif
#include <windows.h> // Windows includes
#include <windowsx.h> // Windows message crackers
#include <ras.h> // Ras functions
#include <raserror.h> // Ras error definitions
#include <rasdlg.h> // Ras dialog functions
#include <stdio.h> // Standard I/O functions
#include <strsafe.h>
#include "resource.h" // resource file for the dialog templates
HANDLE g_hInstance; // global handle to this DLL
// Macro for counting maximum characters that will fit into a buffer
#define CELEMS(x) ((sizeof(x))/(sizeof(x[0])))
// Strucuters for passing data between dialog procs
typedef struct _CUSTOM_ENTRY_DATA_SAMPLE_
{
RASENTRYDLG tEntryDlg;
LPRASENTRY ptEntry;
TCHAR szEntryName[RAS_MaxEntryName + 1];
TCHAR szPhoneBookPath[MAX_PATH + 1];
} SAMPLE_CUSTOM_ENTRY_DATA, *PSAMPLE_CUSTOM_ENTRY_DATA;
typedef struct _CUSTOM_DIAL_DLG_SAMPLE_
{
RASDIALDLG tDialDlg;
RASDIALPARAMS tDialParams;
} SAMPLE_CUSTOM_DIAL_DLG, *PSAMPLE_CUSTOM_DIAL_DLG;
//
// OutputTraceString
//
// multiple argument front-end to OutputDebugString
//
void OutputTraceString(LPTSTR lpszFormatString, ...)
{
const DWORD MAX_DEBUGSTR = 256; // max string for ouput
va_list arglist; // variable argument list
TCHAR szOutputString[MAX_DEBUGSTR]; // the string to print - limited
// create the new string limited to the char count as indicated
va_start(arglist, lpszFormatString);
StringCchVPrintf(szOutputString, CELEMS( szOutputString ), lpszFormatString, arglist);
va_end(arglist);
// send it out
OutputDebugString(szOutputString);
}
//
// DllMain
//
// this is the main entry point into the DLL and is called when
// the DLL is loaded
//
extern "C" BOOL APIENTRY DllMain( HINSTANCE hInstance,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
// save instance handle for register/unregister functionality
g_hInstance = hInstance;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hInstance);
OutputTraceString(L"CustomDial DLLMain (instance: 0x%08x) called - Process Attach\n", hInstance);
break;
case DLL_THREAD_ATTACH:
OutputTraceString(L"CustomDial DLLMain (instance: 0x%08x) called - Thread Attach\n", hInstance);
break;
case DLL_THREAD_DETACH:
OutputTraceString(L"CustomDial DLLMain (instance: 0x%08x) called - Thread Detach\n", hInstance);
break;
case DLL_PROCESS_DETACH:
OutputTraceString(L"CustomDial DLLMain (instance: 0x%08x) called - Process Detach\n", hInstance);
break;
}
return TRUE;
}
//
// RasCustomDial
//
// This export is the custom dial entry when RasDial has been called by
// an application - the call is forwarded to here and it is up to this
// function then to obtain a connection. This implementation simply
// forwards the request back to RasDial. Note that we must add the
// RDEOPT_CustomDial flag to the RasDialExtensions structure so we don't
// recursively get called.
//
extern "C" DWORD WINAPI RasCustomDial (
HINSTANCE hInstDll, // handle to DLL instance
LPRASDIALEXTENSIONS lpRasDialExtensions, // pointer to function extensions data
LPCTSTR lpszPhonebook, // pointer to full path and file name of phone-book file
LPRASDIALPARAMS lpRasDialParams, // pointer to calling parameters data
DWORD dwNotifierType, // specifies type of RasDial event handler
LPVOID lpvNotifier, // specifies a handler for RasDial events
LPHRASCONN lphRasConn // pointer to variable to receive connection handle
)
{
DWORD rc = ERROR_SUCCESS; // return code from RasDial
RASDIALEXTENSIONS RasDialExtensions; // used as a copy of the RasDialExtensions structure
OutputTraceString(L"RasCustomDial called in customdial.dll\n");
if (NULL == lpRasDialParams)
{
return ERROR_UNKNOWN;
}
// set up the RasDialExtensions structure appropriately
if (NULL == lpRasDialExtensions)
{
ZeroMemory(&RasDialExtensions, sizeof(RASDIALEXTENSIONS));
RasDialExtensions.dwSize = sizeof(RASDIALEXTENSIONS);
}
else
{
CopyMemory(&RasDialExtensions, lpRasDialExtensions, sizeof(RASDIALEXTENSIONS));
}
RasDialExtensions.dwfOptions |= RDEOPT_CustomDial; // added cause we are calling RasDial
OutputTraceString(L"--- RasCustomDial RasDialParams: E: '%s' UN: '%s' D: '%s'\n",
lpRasDialParams->szEntryName,
lpRasDialParams->szUserName,
lpRasDialParams->szDomain);
// Simply call RasDial with the modified RasDialExtensions structure
// and the original parameters passed in.
// We are passing lpvNotifier & lphRasConn directly into RasDial. Since we don't use these variable
// locally we skip checking for NULLs.
rc = RasDial(&RasDialExtensions, lpszPhonebook, lpRasDialParams, dwNotifierType, lpvNotifier, lphRasConn);
OutputTraceString(L"--- RasCustomDial returning handle 0x%08x\n", *lphRasConn);
OutputTraceString(L"RasCustomDial exiting customdial.dll with return code: %d\n", rc);
return rc;
}
//
// RasCustomHangUp
//
// This export is the custom dial entry when RasHangUp has been called by
// an application - the call is forwarded to here and it is up to this
// function then to close a connection. This implementation simply
// forwards the request back to RasHangUp.
//
extern "C" DWORD WINAPI RasCustomHangUp (
HRASCONN hRasConn // handle to a RAS connection
)
{
DWORD rc = SUCCESS; // return code
OutputTraceString(L"RasCustomHangUp called in customdial.dll\n");
OutputTraceString(L"--- RasCustomHangUp on handle 0x%08x\n", hRasConn);
// simply call RasHangUp on the handle
rc = RasHangUp(hRasConn);
OutputTraceString(L"RasCustomHangUp exiting customdial.dll with return code: %d\n", rc);
return rc;
}
//
// CustomEntryDlgProc
//
// This function is the dialog procedure for the custom entry dialog and handles
// the basic events that happen within that dialog
//
INT_PTR CALLBACK CustomEntryDlgProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
HWND hEditBox = NULL; // handle to an edit box
HWND hComboBox = NULL; // handle to the combo box
LPRASENTRYDLG lpInfo = NULL; // pointer to the RASENTRYDLG structure
static LPRASENTRY lpRasEntry = NULL; // pointer to the RASENTRY structure
static PSAMPLE_CUSTOM_ENTRY_DATA pData = NULL; // pointer to the SAMPLE_CUSTOM_ENTRY_DATA structure
switch (uMsg)
{
case WM_INITDIALOG:
{
// set up the dialog and the parameters
pData = (PSAMPLE_CUSTOM_ENTRY_DATA) lParam;
if (!pData)
{
return FALSE;
}
lpInfo = &(pData->tEntryDlg);
lpRasEntry = pData->ptEntry;
hComboBox = GetDlgItem(hwndDlg, IDC_LIST_MODEMS);
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_ENTRYNAME);
if (hEditBox)
{
Edit_LimitText(hEditBox, RAS_MaxEntryName); // Count doesn't include NULL
Edit_SetText(hEditBox, (LPTSTR)pData->szEntryName);
}
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_PHONENO);
if (hEditBox)
{
Edit_LimitText(hEditBox, CELEMS(lpRasEntry->szLocalPhoneNumber) - 1); // Count doesn't include NULL
Edit_SetText(hEditBox, lpRasEntry->szLocalPhoneNumber);
}
//
// enumerate to get the device name to use - we'll just do modems
//
// first get the size of the buffer required
LPRASDEVINFO lpRasDevInfo = NULL; // RASDEVINFO structure pointer
DWORD dwNumEntries = 0; // number of entries returned
DWORD dwSize = sizeof(RASDEVINFO); // size of buffer
DWORD rc = 0; // return code
// Allocate buffer with space for at least one structure
lpRasDevInfo = (LPRASDEVINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (NULL == lpRasDevInfo)
{
return FALSE;
}
lpRasDevInfo->dwSize = sizeof(RASDEVINFO);
rc = RasEnumDevices(lpRasDevInfo, &dwSize, &dwNumEntries);
if (ERROR_BUFFER_TOO_SMALL == rc)
{
// If the buffer is too small, free the allocated memory and allocate a bigger buffer.
if (HeapFree(GetProcessHeap(), 0, (LPVOID)lpRasDevInfo))
{
lpRasDevInfo = (LPRASDEVINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (NULL == lpRasDevInfo)
{
OutputTraceString(L"--- Error allocating memory (HeapAlloc) for RASDEVINFO structures for RasEnumDevices(): %d\n", GetLastError());
return FALSE;
}
lpRasDevInfo->dwSize = sizeof(RASDEVINFO);
rc = RasEnumDevices(lpRasDevInfo, &dwSize, &dwNumEntries);
}
else
{
// Couldn't free the memory
return FALSE;
}
}
// Check whether RasEnumDevices succeeded
if (ERROR_SUCCESS == rc)
{
lpRasDevInfo = (LPRASDEVINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (NULL != lpRasDevInfo)
{
lpRasDevInfo->dwSize = sizeof(RASDEVINFO);
rc = RasEnumDevices(lpRasDevInfo, &dwSize, &dwNumEntries);
if (ERROR_SUCCESS == rc)
{
for (UINT i = 0; i < dwNumEntries; i++, lpRasDevInfo++)
{
if (lstrcmpi(lpRasDevInfo->szDeviceType, RASDT_Modem) == 0)
{
if (hComboBox)
{
// add to the list
ComboBox_AddString(hComboBox, lpRasDevInfo->szDeviceName);
}
}
}
}
HeapFree(GetProcessHeap(), 0, (LPVOID)lpRasDevInfo);
lpRasDevInfo = NULL;
}
else
{
OutputTraceString(L"--- Error allocating memory (HeapAlloc) for RASDEVINFO structures for RasEnumDevices(): %d\n", GetLastError());
}
}
if (hComboBox)
{
// select the item we have in the entry
ComboBox_SelectString(hComboBox, -1, lpRasEntry->szDeviceName);
}
// move dialog and position according to structure paramters
// NOTE: we don't take into account multiple monitors or extreme
// cases here as this is only a quick sample
DWORD xPos = 0; // x coordinate position for centering
DWORD yPos = 0; // y coordinate position for centering
if (lpInfo->dwFlags & RASDDFLAG_PositionDlg)
{
xPos = lpInfo->xDlg;
yPos = lpInfo->yDlg;
}
else
{
RECT rectTop; // parent rectangle used for centering
RECT rectDlg; // dialog rectangle used for centering
// center window within the owner or desktop
GetWindowRect(lpInfo->hwndOwner != NULL ? lpInfo->hwndOwner : GetDesktopWindow(), &rectTop);
GetWindowRect(hwndDlg, &rectDlg);
xPos = ((rectTop.left + rectTop.right) / 2) - ((rectDlg.right - rectDlg.left) / 2);
yPos = ((rectTop.top + rectTop.bottom) / 2) - ((rectDlg.bottom - rectDlg.top) / 2);
}
SetWindowPos(hwndDlg, NULL, xPos, yPos, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
return TRUE;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
{
TCHAR szEntryName[RAS_MaxEntryName + 1] = {0}; // Entry name
TCHAR szPhoneBook[MAX_PATH + 1] = {0}; // Phonebook path
TCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1] = {0};
// copy back the phonenumber, entry name, & device name
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_PHONENO);
if (hEditBox)
{
Edit_GetText(hEditBox, lpRasEntry->szLocalPhoneNumber, CELEMS(lpRasEntry->szLocalPhoneNumber));
}
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_ENTRYNAME);
if (hEditBox)
{
Edit_GetText(hEditBox, szEntryName, CELEMS(szEntryName));
}
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_PHONENO);
if (hEditBox)
{
Edit_GetText(hEditBox, szPhoneNumber, CELEMS(szPhoneNumber));
}
hComboBox = GetDlgItem(hwndDlg, IDC_LIST_MODEMS);
if (hComboBox)
{
ComboBox_GetLBText(hComboBox, ComboBox_GetCurSel(hComboBox), lpRasEntry->szDeviceName);
}
if (!pData) return FALSE;
// Check entry name for validity
StringCchCopy(szPhoneBook, CELEMS(szPhoneBook), (LPTSTR)pData->szPhoneBookPath);
if (RasValidateEntryName(szPhoneBook, szEntryName) == ERROR_INVALID_NAME)
{
MessageBox(hwndDlg, L"The Entry Name is Invalid.", L"Entry name error", MB_OK);
}
else
{
StringCchCopy(pData->szEntryName, CELEMS(pData->szEntryName), szEntryName);
StringCchCopy(lpRasEntry->szLocalPhoneNumber, CELEMS(lpRasEntry->szLocalPhoneNumber), szPhoneNumber);
EndDialog(hwndDlg, TRUE);
}
return TRUE;
}
case IDCANCEL:
EndDialog(hwndDlg, FALSE);
return TRUE;
}
break;
}
return FALSE;
}
//
// RasCustomEntryDlg
//
// this export is the custom dial entry when RasEntryDlg has been called by
// an application - the call is forwarded to here and it is up to this
// function then to display, handle and update the phonebook entry that is
// being modified through its own dialog or other means
//
extern "C" BOOL WINAPI RasCustomEntryDlg (
HINSTANCE hInstDll, // handle to DLL instance
LPTSTR lpszPhonebook, // pointer to the full path and
// file name of the phone-book file
LPTSTR lpszEntry, // pointer to the name of the
// phone-book entry to edit,
// copy, or create
LPRASENTRYDLG lpInfo // pointer to a structure that
// contains additional parameters
)
{
DWORD rc = 0; // return code
DWORD dwSize = 0; // size of buffer
//RASENTRY RasEntry; // Ras Entry structure
PSAMPLE_CUSTOM_ENTRY_DATA pEntryData = NULL; // pointer to allocated strucutre for passing data
LPRASENTRY pLocalRE = NULL;
LPRASENTRY pMemberRE = NULL;
OutputTraceString(L"RasCustomEntryDlg called in customdial.dll\n");
// Check input parameters
if (!lpszEntry || !lpInfo)
{
return FALSE;
}
// create buffer of data to move back and forth between dialog
dwSize = sizeof(SAMPLE_CUSTOM_ENTRY_DATA);
pEntryData = (PSAMPLE_CUSTOM_ENTRY_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (pEntryData)
{
CopyMemory(&(pEntryData->tEntryDlg), lpInfo, sizeof(RASENTRYDLG));
dwSize = sizeof(RASENTRY);
pLocalRE = (LPRASENTRY)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (NULL == pLocalRE)
{
return FALSE;
}
// get the other parameters for the entry (phone and Device Name)
pLocalRE->dwSize = dwSize;
rc = RasGetEntryProperties(lpszPhonebook, lpszEntry, pLocalRE, &dwSize, NULL, NULL);
if (ERROR_BUFFER_TOO_SMALL == rc)
{
if (HeapFree(GetProcessHeap(), 0, (LPVOID)pLocalRE))
{
pLocalRE = (LPRASENTRY)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (NULL == pLocalRE)
{
return FALSE;
}
}
else
{
return FALSE;
}
// get the other parameters for the entry (phone and Device Name)
pLocalRE->dwSize = dwSize;
rc = RasGetEntryProperties(lpszPhonebook, lpszEntry, pLocalRE, &dwSize, NULL, NULL);
}
pMemberRE = (LPRASENTRY)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (NULL == pMemberRE)
{
HeapFree(GetProcessHeap(), 0, (LPVOID)pMemberRE);
return FALSE;
}
// Set size and save pointer into structure
pMemberRE->dwSize = dwSize;
pEntryData->ptEntry = pMemberRE;
pMemberRE = NULL;
if (ERROR_SUCCESS == rc)
{
CopyMemory(pEntryData->ptEntry, pLocalRE , pEntryData->ptEntry->dwSize);
}
else
{
MessageBox(NULL, L"Copy Memory failed", L"Error", MB_OK);
}
StringCchCopy(pEntryData->szEntryName, CELEMS(pEntryData->szEntryName), lpszEntry);
StringCchCopy(pEntryData->szPhoneBookPath, CELEMS(pEntryData->szPhoneBookPath), lpszPhonebook);
OutputTraceString(L"--- Call Custom Entry Dialog\n");
INT_PTR ret = DialogBoxParam(hInstDll, MAKEINTRESOURCE(IDD_CUSTOMENTRYDLG), lpInfo->hwndOwner, CustomEntryDlgProc, (LPARAM) pEntryData);
OutputTraceString(L"--- Return from Custom Entry Dialog: %d\n", rc);
if (ret > 0) // dialog succeeded
{
// copy entry name into lpInfo structure for return
StringCchCopy(lpInfo->szEntry, CELEMS(lpInfo->szEntry), (LPTSTR) pEntryData->szEntryName);
// check to see if anything has changed and change the entry
LPRASENTRY lpRasEntry = pEntryData->ptEntry;
if ((lstrcmpi(pLocalRE->szLocalPhoneNumber, lpRasEntry->szLocalPhoneNumber) != 0) ||
(lstrcmpi(pLocalRE->szDeviceName, lpRasEntry->szDeviceName) != 0) ||
(lstrcmpi(lpInfo->szEntry, lpszEntry) != 0))
{
OutputTraceString(L"--- Calling RasSetEntryProperties to make changes\n");
if (rc = RasSetEntryProperties(lpszPhonebook, lpInfo->szEntry, lpRasEntry, lpRasEntry->dwSize, NULL, 0) != SUCCESS)
{
OutputTraceString(L"--- RasSetEntryProperties() failed: %d\n", rc);
lpInfo->dwError = rc;
rc = FALSE;
}
else
{
OutputTraceString(L"--- RasSetEntryProperties() succeeded.\n", rc);
rc = TRUE;
}
}
else
{
rc = TRUE;
}
}
else
{
lpInfo->dwError = GetLastError();
OutputTraceString(L"DialogBox Failed (or cancelled) in RasCustomEntryDlg (GetLastError = %d)\n", lpInfo->dwError);
rc = FALSE;
}
if (pLocalRE)
{
HeapFree(GetProcessHeap(), 0, (LPVOID)pLocalRE);
pLocalRE = NULL;
}
if (pEntryData->ptEntry)
{
HeapFree(GetProcessHeap(), 0, (LPVOID)pEntryData->ptEntry);
pEntryData->ptEntry = NULL;
}
HeapFree(GetProcessHeap(), 0, (LPVOID)pEntryData);
pEntryData = NULL;
}
else
{
OutputTraceString(L"--- Memory allocation failed (HeapAlloc) in RasCustomEntryDlg (GetLastError = %d)\n", GetLastError());
}
OutputTraceString(L"RasCustomEntryDlg exiting customdial.dll with return code: %d\n", rc);
return rc;
}
//
// CustomDialDlgProc
//
// this function is the dialog procedure for the custom dial dialog and handles
// the basic events that happen within that dialog
//
INT_PTR CALLBACK CustomDialDlgProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
LPRASDIALDLG lpInfo = NULL; // pointer to RASDIALDLG structure
static LPRASDIALPARAMS lpRasDialParams = NULL; // pointer to RASDIALPARAMS structure
static PSAMPLE_CUSTOM_DIAL_DLG pDialData = NULL;// pointer to SAMPLE_CUSTOM_DIAL_DLG structure
HWND hEditBox = NULL; // handle to an edit box
switch (uMsg)
{
case WM_INITDIALOG:
{
pDialData = (PSAMPLE_CUSTOM_DIAL_DLG)lParam;
if (!pDialData) return FALSE;
lpInfo = &(pDialData->tDialDlg);
lpRasDialParams = &(pDialData->tDialParams);
// set known items
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_USERNAME);
if (hEditBox)
{
Edit_LimitText(hEditBox, CELEMS(lpRasDialParams->szUserName) - 1); // Count doesn't include NULL
Edit_SetText(hEditBox, lpRasDialParams->szUserName);
}
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_DOMAIN);
if (hEditBox)
{
Edit_LimitText(hEditBox, CELEMS(lpRasDialParams->szDomain) - 1); // Count doesn't include NULL
Edit_SetText(hEditBox, lpRasDialParams->szDomain);
}
// Move dialog and position according to structure
// we don't take into account multiple monitors or extreme
// cases here as this is only a quick sample
DWORD xPos = 0; // x coordinate position for centering
DWORD yPos = 0; // y coordinate position for centering
if (lpInfo->dwFlags & RASDDFLAG_PositionDlg)
{
xPos = lpInfo->xDlg;
yPos = lpInfo->yDlg;
}
else
{
RECT rectTop; // parent rectangle used for centering
RECT rectDlg; // dialog rectangle used for centering
// center window within the owner or desktop
GetWindowRect(lpInfo->hwndOwner != NULL ? lpInfo->hwndOwner : GetDesktopWindow(), &rectTop);
GetWindowRect(hwndDlg, &rectDlg);
xPos = ((rectTop.left + rectTop.right) / 2) - ((rectDlg.right - rectDlg.left) / 2);
yPos = ((rectTop.top + rectTop.bottom) / 2) - ((rectDlg.bottom - rectDlg.top) / 2);
}
SetWindowPos(hwndDlg, NULL, xPos, yPos, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
return TRUE;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_USERNAME);
if (hEditBox)
{
Edit_GetText(hEditBox, lpRasDialParams->szUserName, CELEMS(lpRasDialParams->szUserName));
}
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_PASSWORD);
if (hEditBox)
{
Edit_GetText(hEditBox, lpRasDialParams->szPassword, CELEMS(lpRasDialParams->szPassword));
}
hEditBox = GetDlgItem(hwndDlg, IDC_EDIT_DOMAIN);
if (hEditBox)
{
Edit_GetText(hEditBox, lpRasDialParams->szDomain, CELEMS(lpRasDialParams->szDomain));
}
EndDialog(hwndDlg, TRUE);
return TRUE;
case IDCANCEL:
EndDialog(hwndDlg, FALSE);
return TRUE;
}
break;
}
return FALSE;
}
//
// RasCustomDialDlg
//
// This export is the custom dial entry when RasDialDlg has been called by
// an application - the call is forwarded to here and it is up to this
// function then to display, handle and dial the phonebook entry that is
// specified
//
extern "C" BOOL WINAPI RasCustomDialDlg (
HINSTANCE hInstDll, // handle to DLL instance
DWORD dwFlags, // reserved
LPTSTR lpszPhonebook, // pointer to the full path and
// file name of the phone-book file
LPTSTR lpszEntry, // pointer to the name of the
// phone-book entry to dial
LPTSTR lpszPhoneNumber, // pointer to replacement phone
// number to dial
LPRASDIALDLG lpInfo, // pointer to a structure that
// contains additional parameters
PVOID pvInfo
)
{
DWORD rc = 0; // return code
HRASCONN hRasConn = NULL;
DWORD dwSize = 0;
PSAMPLE_CUSTOM_DIAL_DLG pDialData = NULL;
RASDIALPARAMS RasDialParams;
OutputTraceString(L"RasCustomDialDlg called in customdial.dll\n");
if (!lpInfo)
{
return FALSE;
}
// set up the RasDialParams structure with information passed in
ZeroMemory(&RasDialParams, sizeof(RASDIALPARAMS));
RasDialParams.dwSize = sizeof(RASDIALPARAMS);
StringCchCopy(RasDialParams.szEntryName, CELEMS(RasDialParams.szEntryName), lpszEntry);
if (lpszPhoneNumber != NULL)
{
StringCchCopy(RasDialParams.szPhoneNumber, CELEMS(RasDialParams.szPhoneNumber), lpszPhoneNumber);
}
// pull information from the Entry for the dialog
if (lpszEntry != NULL)
{
BOOL bPassword;
if (rc = RasGetEntryDialParams(lpszPhonebook, &RasDialParams, &bPassword) != SUCCESS)
{
OutputTraceString(L"--- Error retrieving Entry Dial Parameters: %d\n", rc);
}
else
{
OutputTraceString(L"--- RasGetEntryDialParams: UN: '%s' D: '%s'\n",
RasDialParams.szUserName,
RasDialParams.szDomain);
}
}
// display dialog - passing in structure of data that the dialog needs
// so we can get the username, password and domain information
// first build the buffer of data to pass
dwSize = sizeof(SAMPLE_CUSTOM_DIAL_DLG);
pDialData = (PSAMPLE_CUSTOM_DIAL_DLG) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (pDialData != NULL)
{
CopyMemory(&(pDialData->tDialParams), &RasDialParams, sizeof(pDialData->tDialParams));
CopyMemory(&(pDialData->tDialDlg), lpInfo, sizeof(pDialData->tDialDlg));
INT_PTR ret = DialogBoxParam(hInstDll, MAKEINTRESOURCE(IDD_CUSTOMDIALDLG), lpInfo->hwndOwner, CustomDialDlgProc, (LPARAM) pDialData);
if (ret > 0) // dialog succeeded
{
// copy the results back of dialog entry back into stack variable
CopyMemory(&RasDialParams, &(pDialData->tDialParams), sizeof(RASDIALPARAMS));
// call the RasCustomDial since we just need it to do the same thing anyway but
// one would probably call their own custom dialer here or forward to RasDial using
// another window for connection status.
rc = RasCustomDial(hInstDll, NULL, lpszPhonebook, &RasDialParams, 0, 0, &hRasConn);
if (rc != 0)
{
// hang-up on error
RasCustomHangUp(hRasConn);
lpInfo->dwError = rc;
rc = 0; // return 0 on failure and set error info
}
else
{
// set the Entry Dial Params since we succeeded the dial
if (rc = RasSetEntryDialParams(lpszPhonebook, &RasDialParams, TRUE) != SUCCESS)
{
OutputTraceString(L"--- Error setting Entry Dial Parameters: %d\n", rc);
}
rc = 1; // return >0 on success for the entire call
}
}
else
{
lpInfo->dwError = GetLastError();
OutputTraceString(L"--- DialogBox Failed (or cancelled) in RasCustomDialDlg (GetLastError = %d)\n", lpInfo->dwError);
rc = 0;
}
// Clear out password from memory
ZeroMemory(&(pDialData->tDialParams.szPassword), sizeof(pDialData->tDialParams.szPassword));
HeapFree(GetProcessHeap(), 0, (LPVOID)pDialData);
pDialData = NULL;
}
else
{
OutputTraceString(L"--- Memory allocation failed (HeapAlloc) in RasCustomDialDlg (GetLastError = %d)\n", GetLastError());
rc = ERROR_OUTOFMEMORY;
}
// Clear out structures in order to clear up the password from memory
ZeroMemory(&RasDialParams, sizeof(RASDIALPARAMS));
OutputTraceString(L"RasCustomDialDlg exiting customdial.dll with return code: %d\n", rc);
return rc;
}
//
// RasCustomDeleteEntryNotify
//
// this export is the custom dial entry when RasDeleteEntry has been called by
// an application - the call is forwarded to here and it is up to this
// function then to handle the phonebook entry that is specified
//
extern "C" DWORD WINAPI RasCustomDeleteEntryNotify(
LPCTSTR lpszPhonebook,
LPCTSTR lpszEntry,
DWORD dwFlags
)
{
DWORD rc = NO_ERROR; // return code
OutputTraceString(L"RasCustomDeleteEntryNotify called in customdial.dll\n");
// just forward the request on - one could do more custom delete stuff here
rc = RasDeleteEntry(lpszPhonebook, lpszEntry);
OutputTraceString(L"RasCustomDeleteEntryNotify exiting customdial.dll with return code: %d\n");
return rc;
}
// EOF: customdial.cpp