这是我前不久遇到的一个问题,使用Windows的API函数RasEnumConnections检测RAS连接时,每个操作系统版本都必须提供不一样的RASCONN结构体,而我这个程序又必须能够运行在任何的Windows版本下,所以试着写了一个类模板。。。。(初学新手,有什么问题望各位大侠指正)
/* 文件:RasDetectT.h
* 功能:检测、断开RAS连接
* 作者:shootingstars (zhouhuis22 at sina.com.cn)
* 日期:2004-11-4 20:18
* 使用例子:
* CRasDetect *obj = CRasDetect::GetInstance();
* obj->EnumConnections();
* obj->HangupAll();
*/
/* 结构体定义
* 针对Windows的各个版本,定义不同的RASCONN结构体
*/
struct RASCONNWXP //for WinXP/2003
{
DWORD dwSize;
HRASCONN hrasconn;
CHAR szEntryName[ RAS_MaxEntryName + 1 ];
CHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
CHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
CHAR szPhonebook [ MAX_PATH ];
DWORD dwSubEntry;
GUID guidEntry;
DWORD dwFlags;
LUID luid;
};
struct RASCONN2000 //for Win2000
{
DWORD dwSize;
HRASCONN hrasconn;
CHAR szEntryName[ RAS_MaxEntryName + 1 ];
CHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
CHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
CHAR szPhonebook [ MAX_PATH ];
DWORD dwSubEntry;
GUID guidEntry;
};
struct RASCONNNT4 //for WinNT4
{
DWORD dwSize;
HRASCONN hrasconn;
CHAR szEntryName[ RAS_MaxEntryName + 1 ];
CHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
CHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
CHAR szPhonebook [ MAX_PATH ];
DWORD dwSubEntry;
};
struct RASCONNW9X //for Win98/95
{
DWORD dwSize;
HRASCONN hrasconn;
CHAR szEntryName [ RAS_MaxEntryName + 1 ];
CHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
CHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
};
/*
* 客户使用接口
*/
class CRasDetect
{
public:
virtual bool EnumConnections() = 0; // 枚举所有RAS连接
virtual bool HangupAll() = 0; // 断开所有RAS连接
virtual bool Hangup(int index) = 0; // 断开某个(index)RAS连接
static CRasDetect *GetInstance(); // 返回特定操作系统版本的CRasDetectT对象(Singleton模式,不支持多线程)
private:
static CRasDetect *Instance;
};
CRasDetect *CRasDetect::Instance = NULL;
template <class RASCONNT>
class CRasDetectT : public CRasDetect
{
public:
CRasDetectT();
~CRasDetectT();
bool EnumConnections();
bool HangupAll();
bool Hangup(int index);
protected:
RASCONNT *m_lprasconn;
DWORD m_connectionCount; // 枚举获得的连接数目
DWORD m_structSize; // 当前系统RASCONN结构体的大小
};
template <class RASCONNT>
CRasDetectT<RASCONNT>::CRasDetectT()
{
m_structSize = sizeof(RASCONNT);
}
template <class RASCONNT>
CRasDetectT<RASCONNT>::~CRasDetectT()
{
}
template <class RASCONNT>
bool CRasDetectT<RASCONNT>::EnumConnections()
{
m_lprasconn = (RASCONNT *)new BYTE[m_structSize];
DWORD dwCb;
dwCb = m_structSize;
m_lprasconn->dwSize = m_structSize;
DWORD dwErr = RasEnumConnections(
(RASCONN*)m_lprasconn,
&dwCb,
&m_connectionCount);
if (ERROR_BUFFER_TOO_SMALL == dwErr)
{
delete m_lprasconn;
m_lprasconn = (RASCONNT *)new BYTE[m_structSize];
m_lprasconn->dwSize = m_structSize;
dwErr = RasEnumConnections(
(RASCONN*)m_lprasconn,
&dwCb,
&m_connectionCount);
if(dwErr == ERROR_SUCCESS)
return true;
else
return false;
}
else if(dwErr == ERROR_SUCCESS)
return true;
else
return false;
}
template <class RASCONNT>
bool CRasDetectT<RASCONNT>::Hangup(int index)
{
DWORD err = RasHangUp(m_lprasconn[index].hrasconn);
if(err == 0)
return true;
else
return false;
}
template <class RASCONNT>
bool CRasDetectT<RASCONNT>::HangupAll()
{
bool result = true;
for(DWORD i = 0 ; i < m_connectionCount ; i++)
if(!Hangup(i))
result = false;
return result;
}
// 返回当前操作系统的CRasDetectT对象
CRasDetect* CRasDetect::GetInstance()
{
if(Instance)
return Instance;
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
{
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
return NULL;
}
switch(osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_WINDOWS: // Win95/Win98
return new CRasDetectT<RASCONNW9X>;
case VER_PLATFORM_WIN32_NT:
if(osvi.dwMajorVersion>=5) // Windows 2000( NT5.0 )
{
if(osvi.dwMinorVersion >= 1)
{
return new CRasDetectT<RASCONNWXP>;
}
else
{
return new CRasDetectT<RASCONN2000>;
}
}
else // NT 4.0
{
return new CRasDetectT<RASCONNNT4>;
}
break;
}
return NULL;
}
* 功能:检测、断开RAS连接
* 作者:shootingstars (zhouhuis22 at sina.com.cn)
* 日期:2004-11-4 20:18
* 使用例子:
* CRasDetect *obj = CRasDetect::GetInstance();
* obj->EnumConnections();
* obj->HangupAll();
*/
/* 结构体定义
* 针对Windows的各个版本,定义不同的RASCONN结构体
*/
struct RASCONNWXP //for WinXP/2003
{
DWORD dwSize;
HRASCONN hrasconn;
CHAR szEntryName[ RAS_MaxEntryName + 1 ];
CHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
CHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
CHAR szPhonebook [ MAX_PATH ];
DWORD dwSubEntry;
GUID guidEntry;
DWORD dwFlags;
LUID luid;
};
struct RASCONN2000 //for Win2000
{
DWORD dwSize;
HRASCONN hrasconn;
CHAR szEntryName[ RAS_MaxEntryName + 1 ];
CHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
CHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
CHAR szPhonebook [ MAX_PATH ];
DWORD dwSubEntry;
GUID guidEntry;
};
struct RASCONNNT4 //for WinNT4
{
DWORD dwSize;
HRASCONN hrasconn;
CHAR szEntryName[ RAS_MaxEntryName + 1 ];
CHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
CHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
CHAR szPhonebook [ MAX_PATH ];
DWORD dwSubEntry;
};
struct RASCONNW9X //for Win98/95
{
DWORD dwSize;
HRASCONN hrasconn;
CHAR szEntryName [ RAS_MaxEntryName + 1 ];
CHAR szDeviceType[ RAS_MaxDeviceType + 1 ];
CHAR szDeviceName[ RAS_MaxDeviceName + 1 ];
};
/*
* 客户使用接口
*/
class CRasDetect
{
public:
virtual bool EnumConnections() = 0; // 枚举所有RAS连接
virtual bool HangupAll() = 0; // 断开所有RAS连接
virtual bool Hangup(int index) = 0; // 断开某个(index)RAS连接
static CRasDetect *GetInstance(); // 返回特定操作系统版本的CRasDetectT对象(Singleton模式,不支持多线程)
private:
static CRasDetect *Instance;
};
CRasDetect *CRasDetect::Instance = NULL;
template <class RASCONNT>
class CRasDetectT : public CRasDetect
{
public:
CRasDetectT();
~CRasDetectT();
bool EnumConnections();
bool HangupAll();
bool Hangup(int index);
protected:
RASCONNT *m_lprasconn;
DWORD m_connectionCount; // 枚举获得的连接数目
DWORD m_structSize; // 当前系统RASCONN结构体的大小
};
template <class RASCONNT>
CRasDetectT<RASCONNT>::CRasDetectT()
{
m_structSize = sizeof(RASCONNT);
}
template <class RASCONNT>
CRasDetectT<RASCONNT>::~CRasDetectT()
{
}
template <class RASCONNT>
bool CRasDetectT<RASCONNT>::EnumConnections()
{
m_lprasconn = (RASCONNT *)new BYTE[m_structSize];
DWORD dwCb;
dwCb = m_structSize;
m_lprasconn->dwSize = m_structSize;
DWORD dwErr = RasEnumConnections(
(RASCONN*)m_lprasconn,
&dwCb,
&m_connectionCount);
if (ERROR_BUFFER_TOO_SMALL == dwErr)
{
delete m_lprasconn;
m_lprasconn = (RASCONNT *)new BYTE[m_structSize];
m_lprasconn->dwSize = m_structSize;
dwErr = RasEnumConnections(
(RASCONN*)m_lprasconn,
&dwCb,
&m_connectionCount);
if(dwErr == ERROR_SUCCESS)
return true;
else
return false;
}
else if(dwErr == ERROR_SUCCESS)
return true;
else
return false;
}
template <class RASCONNT>
bool CRasDetectT<RASCONNT>::Hangup(int index)
{
DWORD err = RasHangUp(m_lprasconn[index].hrasconn);
if(err == 0)
return true;
else
return false;
}
template <class RASCONNT>
bool CRasDetectT<RASCONNT>::HangupAll()
{
bool result = true;
for(DWORD i = 0 ; i < m_connectionCount ; i++)
if(!Hangup(i))
result = false;
return result;
}
// 返回当前操作系统的CRasDetectT对象
CRasDetect* CRasDetect::GetInstance()
{
if(Instance)
return Instance;
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
{
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
return NULL;
}
switch(osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_WINDOWS: // Win95/Win98
return new CRasDetectT<RASCONNW9X>;
case VER_PLATFORM_WIN32_NT:
if(osvi.dwMajorVersion>=5) // Windows 2000( NT5.0 )
{
if(osvi.dwMinorVersion >= 1)
{
return new CRasDetectT<RASCONNWXP>;
}
else
{
return new CRasDetectT<RASCONN2000>;
}
}
else // NT 4.0
{
return new CRasDetectT<RASCONNNT4>;
}
break;
}
return NULL;
}