|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998.
//
// File: D U N I M P O R T . C P P
//
// Contents: Functions that handles .DUN files for RAS connections
// created in win9x
//
// Notes:
//
// Author: TongL 15 March 1999
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "dunimport.h"
#include "raserror.h"
#include "ncras.h"
#include "connutil.h"
#define RAS_MaxEntryName 256
#define MAXLONGLEN 11 // Maximum long string length
#define MAXIPADDRLEN 20
#define SIZE_ReadBuf 0x00008000 // 32K buffer size
#define NUM_IP_FIELDS 4
#define MIN_IP_VALUE 0
#define MAX_IP_VALUE 255
#define CH_DOT L'.'
const WCHAR c_szPhoneBookPath[] = L"\\Microsoft\\Network\\Connections\\Pbk\\rasphone.pbk"; const WCHAR c_szRASDT[] = L"RASDT_";
const WCHAR c_szEntrySection[] = L"Entry"; const WCHAR c_szEntryName[] = L"Entry_Name"; const WCHAR c_szML[] = L"Multilink";
const WCHAR c_szPhoneSection[] = L"Phone"; const WCHAR c_szDialAsIs[] = L"Dial_As_Is"; const WCHAR c_szPhoneNumber[] = L"Phone_Number"; const WCHAR c_szAreaCode[] = L"Area_Code"; const WCHAR c_szCountryCode[] = L"Country_Code"; const WCHAR c_szCountryID[] = L"Country_ID";
const WCHAR c_szYes[] = L"yes"; const WCHAR c_szNo[] = L"no";
const WCHAR c_szDeviceSection[] = L"Device"; const WCHAR c_szDeviceType[] = L"Type"; const WCHAR c_szModem[] = L"modem"; const WCHAR c_szVpn[] = L"vpn"; const WCHAR c_szDeviceName[] = L"Name";
const WCHAR c_szServerSection[] = L"Server"; const WCHAR c_szServerType[] = L"Type"; const WCHAR c_szPPP[] = L"PPP"; const WCHAR c_szSLIP[] = L"SLIP"; const WCHAR c_szRAS[] = L"RAS"; const WCHAR c_szSWCompress[] = L"SW_Compress"; const WCHAR c_szPWEncrypt[] = L"PW_Encrypt"; const WCHAR c_szNetLogon[] = L"Network_Logon"; const WCHAR c_szSWEncrypt[] = L"SW_Encrypt"; const WCHAR c_szNetBEUI[] = L"Negotiate_NetBEUI"; const WCHAR c_szIPX[] = L"Negotiate_IPX/SPX"; const WCHAR c_szIP[] = L"Negotiate_TCP/IP";
const WCHAR c_szIPSection[] = L"TCP/IP"; const WCHAR c_szIPSpec[] = L"Specify_IP_Address"; const WCHAR c_szIPAddress[] = L"IP_address"; const WCHAR c_szServerSpec[] = L"Specify_Server_Address"; const WCHAR c_szDNSAddress[] = L"DNS_address"; const WCHAR c_szDNSAltAddress[] = L"DNS_Alt_address"; const WCHAR c_szWINSAddress[] = L"WINS_address"; const WCHAR c_szWINSAltAddress[]= L"WINS_Alt_address"; const WCHAR c_szIPCompress[] = L"IP_Header_Compress"; const WCHAR c_szRemoteGateway[] = L"Gateway_On_Remote";
//+---------------------------------------------------------------------------
//
// Function: HrInvokeDunFile_Internal
//
// Purpose: This is the entry point for DUN file invoking
//
// Arguments:
// szFileName [in] The .DUN file name
//
// Returns: S_OK if succeeded, failure code otherwise
//
HRESULT HrInvokeDunFile_Internal(IN LPWSTR szDunFile) { HRESULT hr = S_OK; WCHAR szEntryName[RAS_MaxEntryName+1]; tstring strPhoneBook;
hr = HrGetPhoneBookFile(strPhoneBook); if (SUCCEEDED(hr)) { // Get the size of device configuration
// This also validates an exported file
//
hr = HrGetEntryName(szDunFile, szEntryName, strPhoneBook);
if ((HRESULT_FROM_WIN32(ERROR_CANNOT_OPEN_PHONEBOOK) == hr) || (HRESULT_FROM_WIN32(ERROR_CANNOT_FIND_PHONEBOOK_ENTRY) == hr)) { // create a new entry in the current user's phonebook
hr = HrImportPhoneBookInfo(szDunFile, szEntryName, strPhoneBook); }
if (SUCCEEDED(hr)) { // get the GUID of this connection
RASENTRY* pRasEntry = NULL; hr = HrRasGetEntryProperties( strPhoneBook.c_str(), szEntryName, &pRasEntry, NULL); if(SUCCEEDED(hr)) { // dial the connection
hr = HrLaunchConnection(pRasEntry->guidId); MemFree(pRasEntry); } } }
TraceError("HrInvokeDunFile_Internal", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrGetPhoneBookFile
//
// Purpose: This function will return the proper path to the current user's
// phonebook.
//
// Arguments:
// szFileName [in] The .DUN file name
//
// Returns: S_OK if succeeded, failure code otherwise
//
HRESULT HrGetPhoneBookFile(tstring& strPhoneBook) { HRESULT hr = S_OK; strPhoneBook = c_szEmpty;
LPITEMIDLIST pidl; LPMALLOC pMalloc; WCHAR szDir[MAX_PATH+1];
hr = SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl); if(SUCCEEDED(hr)) { if (SHGetPathFromIDList(pidl, szDir)) { strPhoneBook = szDir; TraceTag(ttidDun, "The path to the application directory is: %S", strPhoneBook.c_str());
// release the memory by using the the shell's IMalloc ptr
//
if (SUCCEEDED(SHGetMalloc(&pMalloc))) { pMalloc->Free(pidl); } } else { hr = E_FAIL; } }
if (SUCCEEDED(hr)) { TraceTag(ttidDun, "The path to the phonebook is: %S", strPhoneBook.c_str()); strPhoneBook += c_szPhoneBookPath; }
return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrGetEntryName
//
// Purpose: This function validates and returns the entry name
//
// Arguments:
// szDunFile [in] The .dun file created on win9x
// szEntryName [in] The entry name for this connection
//
// Returns: S_OK if valid and is a new entry
// S_FALSE if valid and but is an existing entry
// otherwise, specific error
//
HRESULT HrGetEntryName(IN LPWSTR szFileName, IN LPWSTR szEntryName, tstring & strPhoneBook) { HRESULT hr = S_OK; DWORD dwRet;
// Get the entry name
//
dwRet = GetPrivateProfileString(c_szEntrySection, c_szEntryName, c_szEmpty, szEntryName, RAS_MaxEntryName+1, szFileName); // no entry name
if (dwRet <= 0) { return HRESULT_FROM_WIN32(ERROR_CORRUPT_PHONEBOOK); }
// Check if entry name already exists in phonebook
//
RASENTRY* pRasEntry = NULL; hr = HrRasGetEntryProperties( strPhoneBook.c_str(), szEntryName, &pRasEntry, NULL); MemFree(pRasEntry);
TraceErrorOptional("HrGetEntryName", hr, ((HRESULT_FROM_WIN32(ERROR_CANNOT_OPEN_PHONEBOOK) == hr) || (HRESULT_FROM_WIN32(ERROR_CANNOT_FIND_PHONEBOOK_ENTRY) == hr))); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrImportPhoneBookInfo
//
// Purpose: This function checks if the RAS entry already exists in the
// current user's phonebook
//
// Arguments:
// szEntryName [in] The entry name for this connection
//
// Returns: TRUE if already exists, FALSE otherwise
//
HRESULT HrImportPhoneBookInfo( IN LPWSTR szDunFile, IN LPWSTR szEntryName, tstring & strPhoneBook) { HRESULT hr = S_OK; RASENTRY RasEntry = {0};
// Get the phone number
//
hr = HrImportPhoneInfo(&RasEntry, szDunFile); if (SUCCEEDED(hr)) { // Get device name, type and config
//
ImportDeviceInfo(&RasEntry, szDunFile);
// Get Server Type settings
//
ImportServerInfo(&RasEntry, szDunFile);
// Get IP address
//
ImportIPInfo(&RasEntry, szDunFile);
// Prompt for user name and password
RasEntry.dwfOptions |= RASEO_PreviewUserPw;
// Save it to the phonebook
//
DWORD dwRet; RasEntry.dwSize = sizeof(RASENTRY); RasEntry.dwType = RASET_Phone; dwRet = RasSetEntryProperties(strPhoneBook.c_str(), szEntryName, &RasEntry, sizeof(RASENTRY), NULL, 0);
hr = HRESULT_FROM_WIN32(dwRet); TraceError("RasSetEntryProperties", hr); }
TraceError("HrImportPhoneBookInfo", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrImportPhoneInfo
//
// Purpose: This function imports the phone number
//
// Arguments:
// szFileName [in] The .DUN file name
//
// Returns:
//
HRESULT HrImportPhoneInfo(RASENTRY * pRasEntry, IN LPWSTR szFileName) { HRESULT hr = S_OK;
// szLocalPhoneNumber
if (GetPrivateProfileString(c_szPhoneSection, c_szPhoneNumber, c_szEmpty, pRasEntry->szLocalPhoneNumber, celems(pRasEntry->szLocalPhoneNumber), szFileName) == 0) { hr = HRESULT_FROM_WIN32(ERROR_CORRUPT_PHONEBOOK); };
if (SUCCEEDED(hr)) { WCHAR szYesNo[MAXLONGLEN+1];
GetPrivateProfileString(c_szPhoneSection, c_szDialAsIs, c_szYes, szYesNo, celems(szYesNo), szFileName);
// Do we have to get country code and area code?
//
if (!lstrcmpiW(szYesNo, c_szNo)) { // use country and area codes
pRasEntry->dwfOptions |= RASEO_UseCountryAndAreaCodes;
// If we cannot get the country ID or it is zero, default to dial as is
//
if ((pRasEntry->dwCountryID = GetPrivateProfileInt( c_szPhoneSection, c_szCountryID, 0, szFileName)) != 0) { pRasEntry->dwCountryCode = GetPrivateProfileInt(c_szPhoneSection, c_szCountryCode, 1, szFileName); }
GetPrivateProfileString(c_szPhoneSection, c_szAreaCode, c_szEmpty, pRasEntry->szAreaCode, celems(pRasEntry->szAreaCode), szFileName); }; }
TraceError("HrImportPhoneInfo", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: ImportDeviceInfo
//
// Purpose: This function imports the device info
//
// Arguments:
// szFileName [in] The .DUN file name
//
// Returns:
//
VOID ImportDeviceInfo(RASENTRY * pRasEntry, IN LPWSTR szFileName) { WCHAR szDeviceType[RAS_MaxDeviceType+1];
// Get the device type
//
if (GetPrivateProfileString(c_szDeviceSection, c_szDeviceType, c_szEmpty, szDeviceType, celems(szDeviceType), szFileName)) { if (!lstrcmpiW(szDeviceType, c_szModem)) { lstrcpyW(pRasEntry->szDeviceType, RASDT_Modem); } else if (!lstrcmpiW(szDeviceType, c_szVpn)) { lstrcpyW(pRasEntry->szDeviceType, RASDT_Vpn); } else { AssertSz(FALSE, "Unknown device type"); }
// Get the device name
//
GetPrivateProfileString( c_szDeviceSection, c_szDeviceName, c_szEmpty, pRasEntry->szDeviceName, celems(pRasEntry->szDeviceName), szFileName); } }
//+---------------------------------------------------------------------------
//
// Function: ImportServerInfo
//
// Purpose: This function imports the server type name and settings
//
// Arguments:
// szFileName [in] The .DUN file name
//
// Returns:
//
VOID ImportServerInfo(RASENTRY * pRasEntry, IN LPWSTR szFileName) { HRESULT hr = S_OK;
WCHAR szValue[MAXLONGLEN]; WCHAR szYesNo[MAXLONGLEN]; DWORD dwRet;
// Get the server type: PPP, SLIP or RAS
//
if (GetPrivateProfileString(c_szServerSection, c_szServerType, c_szEmpty, szValue, celems(szValue), szFileName)) { if (!lstrcmpiW(szValue, c_szPPP)) { pRasEntry->dwFramingProtocol = RASFP_Ppp; } else if (!lstrcmpiW(szValue, c_szSLIP)) { pRasEntry->dwFramingProtocol = RASFP_Slip; } else if (!lstrcmpiW(szValue, c_szRAS)) { pRasEntry->dwFramingProtocol = RASFP_Ras; } }
// SW_Compress
//
if (GetPrivateProfileString(c_szServerSection, c_szSWCompress, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfOptions |= RASEO_SwCompression; }; };
// PW_Encrypt
//
if (GetPrivateProfileString(c_szServerSection, c_szPWEncrypt, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfOptions |= RASEO_RequireEncryptedPw; }; };
// Network_Logon
//
if (GetPrivateProfileString(c_szServerSection, c_szNetLogon, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfOptions |= RASEO_NetworkLogon; }; };
// SW_Encrypt
//
// set both RASEO_RequireMsEncryptedPw and RASEO_RequireDataEncryption
// if SW_Encrypt is TRUE
//
if (GetPrivateProfileString(c_szServerSection, c_szSWEncrypt, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfOptions |= RASEO_RequireMsEncryptedPw; pRasEntry->dwfOptions |= RASEO_RequireDataEncryption; }; };
// Get the network protocols to negotiate
//
if (GetPrivateProfileString(c_szServerSection, c_szNetBEUI, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfNetProtocols |= RASNP_NetBEUI; }; };
if (GetPrivateProfileString(c_szServerSection, c_szIPX, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfNetProtocols |= RASNP_Ipx; }; };
if (GetPrivateProfileString(c_szServerSection, c_szIP, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfNetProtocols |= RASNP_Ip; }; }; }
//+---------------------------------------------------------------------------
//
// Function: ImportIPInfo
//
// Purpose: This function imports the device info
//
// Arguments:
// szFileName [in] The .DUN file name
//
// Returns:
//
VOID ImportIPInfo(RASENTRY * pRasEntry, IN LPWSTR szFileName) { WCHAR szIPAddr[MAXIPADDRLEN]; WCHAR szYesNo[MAXLONGLEN];
// Import IP address information
//
if (GetPrivateProfileString(c_szIPSection, c_szIPSpec, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfOptions |= RASEO_SpecificIpAddr;
// Get the IP address
//
if (GetPrivateProfileString(c_szIPSection, c_szIPAddress, c_szEmpty, szIPAddr, celems(szIPAddr), szFileName)) { SzToRasIpAddr(szIPAddr, &(pRasEntry->ipaddr)); }; } };
// Import Server address information
//
if (GetPrivateProfileString(c_szIPSection, c_szServerSpec, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { // The import file has server address specified, get the server address
//
pRasEntry->dwfOptions |= RASEO_SpecificNameServers;
if (GetPrivateProfileString(c_szIPSection, c_szDNSAddress, c_szEmpty, szIPAddr, celems(szIPAddr), szFileName)) { SzToRasIpAddr(szIPAddr, &(pRasEntry->ipaddrDns)); };
if (GetPrivateProfileString(c_szIPSection, c_szDNSAltAddress, c_szEmpty, szIPAddr, celems(szIPAddr), szFileName)) { SzToRasIpAddr(szIPAddr, &(pRasEntry->ipaddrDnsAlt)); };
if (GetPrivateProfileString(c_szIPSection, c_szWINSAddress, c_szEmpty, szIPAddr, celems(szIPAddr), szFileName)) { SzToRasIpAddr(szIPAddr, &(pRasEntry->ipaddrWins)); };
if (GetPrivateProfileString(c_szIPSection, c_szWINSAltAddress, c_szEmpty, szIPAddr, celems(szIPAddr), szFileName)) { SzToRasIpAddr(szIPAddr, &(pRasEntry->ipaddrWinsAlt)); }; } };
// Header compression and the gateway settings
//
if (GetPrivateProfileString(c_szIPSection, c_szIPCompress, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfOptions |= RASEO_IpHeaderCompression; } };
if (GetPrivateProfileString(c_szIPSection, c_szRemoteGateway, c_szEmpty, szYesNo, celems(szYesNo), szFileName)) { if (!lstrcmpiW(szYesNo, c_szYes)) { pRasEntry->dwfOptions |= RASEO_RemoteDefaultGateway; } }; }
VOID SzToRasIpAddr(IN LPWSTR szIPAddress, OUT RASIPADDR * pIpAddr) { list<tstring *> listFields; ConvertStringToColString(szIPAddress, CH_DOT, listFields);
list<tstring *>::const_iterator iter = listFields.begin();
if (listFields.size() == NUM_IP_FIELDS) { // Go through each field and get the number value
BYTE a = _wtol((*iter++)->c_str()); BYTE b = _wtol((*iter++)->c_str()); BYTE c = _wtol((*iter++)->c_str()); BYTE d = _wtol((*iter++)->c_str());
// validate the address
if ((a >= MIN_IP_VALUE) && (a <= MAX_IP_VALUE) && (b >= MIN_IP_VALUE) && (b <= MAX_IP_VALUE) && (c >= MIN_IP_VALUE) && (c <= MAX_IP_VALUE) && (d >= MIN_IP_VALUE) && (d <= MAX_IP_VALUE)) { pIpAddr->a = a; pIpAddr->b = b; pIpAddr->c = c; pIpAddr->d = d; } } FreeCollectionAndItem(listFields); }
|