📄 remconn.cxx
字号:
/*
* remconn.cxx
*
* Remote Networking Connection class implmentation for Win32 RAS.
*
* Portable Windows Library
*
* Copyright (c) 1993-1998 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Portions are Copyright (C) 1993 Free Software Foundation, Inc.
* All Rights Reserved.
*
* Contributor(s): ______________________________________.
*
* $Revision: 19008 $
* $Author: rjongbloed $
* $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
*/
#include <ptlib.h>
#include <ptlib/remconn.h>
#define SizeWin400_RAS_MaxEntryName 256
#define SizeWin400_RAS_MaxPhoneNumber 128
#define SizeWin400_RAS_MaxCallbackNumber SizeWin400_RAS_MaxPhoneNumber
#define SizeWin400_RAS_MaxDeviceType 16
#define SizeWin400_RAS_MaxDeviceName 128
#define SizeWin400_RASCONN (sizeof(DWORD) + \
sizeof(HRASCONN) + \
SizeWin400_RAS_MaxEntryName + 1)
#define SizeWin400_RASDIALPARAMS (sizeof(DWORD) + \
SizeWin400_RAS_MaxEntryName + 1 + \
SizeWin400_RAS_MaxPhoneNumber + 1 + \
SizeWin400_RAS_MaxCallbackNumber + 1 + \
UNLEN + 1 + \
PWLEN + 1 + \
DNLEN + 1)
#define SizeWin400_RASCONNSTATUS (sizeof(DWORD) + \
sizeof(RASCONNSTATE) + \
sizeof(DWORD) + \
SizeWin400_RAS_MaxDeviceType + 1 + \
SizeWin400_RAS_MaxDeviceName + 1)
class PRASDLL : public PDynaLink
{
PCLASSINFO(PRASDLL, PDynaLink)
public:
PRASDLL();
DWORD (FAR PASCAL *Dial)(LPRASDIALEXTENSIONS,LPTSTR,LPRASDIALPARAMS,DWORD,LPVOID,LPHRASCONN);
DWORD (FAR PASCAL *HangUp)(HRASCONN);
DWORD (FAR PASCAL *GetConnectStatus)(HRASCONN,LPRASCONNSTATUS);
DWORD (FAR PASCAL *EnumConnections)(LPRASCONN,LPDWORD,LPDWORD);
DWORD (FAR PASCAL *EnumEntries)(LPTSTR,LPTSTR,LPRASENTRYNAME,LPDWORD,LPDWORD);
DWORD (FAR PASCAL *GetEntryProperties)(LPTSTR, LPTSTR, LPRASENTRY, LPDWORD, LPBYTE, LPDWORD);
DWORD (FAR PASCAL *SetEntryProperties)(LPTSTR, LPTSTR, LPRASENTRY, DWORD, LPBYTE, DWORD);
DWORD (FAR PASCAL *DeleteEntry)(LPTSTR, LPTSTR);
DWORD (FAR PASCAL *ValidateEntryName)(LPTSTR, LPTSTR);
DWORD (FAR PASCAL *GetProjectionInfo)(HRASCONN, RASPROJECTION, LPVOID, LPDWORD);
} Ras;
PRASDLL::PRASDLL()
#ifdef _WIN32
: PDynaLink("RASAPI32.DLL")
#else
: PDynaLink("RASAPI16.DLL")
#endif
{
if (!GetFunction("RasDialA", (Function &)Dial) ||
!GetFunction("RasHangUpA", (Function &)HangUp) ||
!GetFunction("RasGetConnectStatusA", (Function &)GetConnectStatus) ||
!GetFunction("RasEnumConnectionsA", (Function &)EnumConnections) ||
!GetFunction("RasEnumEntriesA", (Function &)EnumEntries))
Close();
GetFunction("RasGetEntryPropertiesA", (Function &)GetEntryProperties);
GetFunction("RasSetEntryPropertiesA", (Function &)SetEntryProperties);
GetFunction("RasDeleteEntryA", (Function &)DeleteEntry);
GetFunction("RasValidateEntryNameA", (Function &)ValidateEntryName);
GetFunction("RasGetProjectionInfoA", (Function &)GetProjectionInfo);
}
#define new PNEW
static PBoolean IsWinVer401()
{
OSVERSIONINFO verinf;
verinf.dwOSVersionInfoSize = sizeof(verinf);
GetVersionEx(&verinf);
if (verinf.dwPlatformId != VER_PLATFORM_WIN32_NT)
return PFalse;
if (verinf.dwMajorVersion < 4)
return PFalse;
return PTrue;
}
PRemoteConnection::PRemoteConnection()
{
Construct();
}
PRemoteConnection::PRemoteConnection(const PString & name)
: remoteName(name)
{
Construct();
}
PRemoteConnection::~PRemoteConnection()
{
Close();
}
PBoolean PRemoteConnection::Open(const PString & name,
const PString & user,
const PString & pass,
PBoolean existing)
{
if (name != remoteName) {
Close();
remoteName = name;
}
userName = user;
password = pass;
return Open(existing);
}
PBoolean PRemoteConnection::Open(const PString & name, PBoolean existing)
{
if (name != remoteName) {
Close();
remoteName = name;
}
return Open(existing);
}
PObject::Comparison PRemoteConnection::Compare(const PObject & obj) const
{
PAssert(PIsDescendant(&obj, PRemoteConnection), PInvalidCast);
return remoteName.Compare(((const PRemoteConnection &)obj).remoteName);
}
PINDEX PRemoteConnection::HashFunction() const
{
return remoteName.HashFunction();
}
void PRemoteConnection::Construct()
{
rasConnection = NULL;
osError = SUCCESS;
}
PBoolean PRemoteConnection::Open(PBoolean existing)
{
Close();
if (!Ras.IsLoaded())
return PFalse;
PBoolean isVer401 = IsWinVer401();
RASCONN connection;
connection.dwSize = isVer401 ? sizeof(RASCONN) : SizeWin400_RASCONN;
LPRASCONN connections = &connection;
DWORD size = sizeof(connection);
DWORD numConnections;
osError = Ras.EnumConnections(connections, &size, &numConnections);
if (osError == ERROR_BUFFER_TOO_SMALL) {
connections = new RASCONN[size/connection.dwSize];
connections[0].dwSize = connection.dwSize;
osError = Ras.EnumConnections(connections, &size, &numConnections);
}
if (osError == 0) {
for (DWORD i = 0; i < numConnections; i++) {
if (remoteName == connections[i].szEntryName) {
rasConnection = connections[i].hrasconn;
break;
}
}
}
if (connections != &connection)
delete [] connections;
if (rasConnection != NULL && GetStatus() == Connected) {
osError = 0;
return PTrue;
}
rasConnection = NULL;
if (existing)
return PFalse;
RASDIALPARAMS params;
memset(¶ms, 0, sizeof(params));
params.dwSize = isVer401 ? sizeof(params) : SizeWin400_RASDIALPARAMS;
if (remoteName[0] != '.') {
PAssert(remoteName.GetLength() < sizeof(params.szEntryName)-1, PInvalidParameter);
strcpy(params.szEntryName, remoteName);
}
else {
PAssert(remoteName.GetLength() < sizeof(params.szPhoneNumber), PInvalidParameter);
strcpy(params.szPhoneNumber, remoteName(1, P_MAX_INDEX));
}
strcpy(params.szUserName, userName);
strcpy(params.szPassword, password);
osError = Ras.Dial(NULL, NULL, ¶ms, 0, NULL, &rasConnection);
if (osError == 0)
return PTrue;
if (rasConnection != NULL) {
Ras.HangUp(rasConnection);
rasConnection = NULL;
}
SetLastError(osError);
return PFalse;
}
void PRemoteConnection::Close()
{
if (rasConnection != NULL) {
Ras.HangUp(rasConnection);
rasConnection = NULL;
}
}
static int GetRasStatus(HRASCONN rasConnection, DWORD & rasError)
{
RASCONNSTATUS status;
status.dwSize = IsWinVer401() ? sizeof(status) : SizeWin400_RASCONNSTATUS;
rasError = Ras.GetConnectStatus(rasConnection, &status);
if (rasError == ERROR_INVALID_HANDLE) {
PError << "RAS Connection Status invalid handle, retrying.";
rasError = Ras.GetConnectStatus(rasConnection, &status);
}
if (rasError == 0) {
rasError = status.dwError;
SetLastError(rasError);
return status.rasconnstate;
}
PError << "RAS Connection Status failed (" << rasError << "), retrying.";
rasError = Ras.GetConnectStatus(rasConnection, &status);
if (rasError == 0)
rasError = status.dwError;
SetLastError(rasError);
return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -