Update Win32ras to provide ability to fetch the RAS local
and remote server IP addresses, read the RAS counters
for a connection, and clear the RAS counters for a
connection. This means updating WINVER, using the
lastest ras.h include file from Microsoft, and checking
that ras32api.dll is loaded at run time to avoid problems
on older OS's i.e. anything other than Win2k and WinXP.
Necessary code changes are below. I have built and
verified these changes on Win32Extensions 2.03 with
Python 2.3.
#ifndef WINVER
#define WINVER 0x500
#endif
// @pymethod |win32ras|GetIpAddress|Returns a list of
IP addresses.
static PyObject *
PyRasGetIpAddress( PyObject *self, PyObject *args )
{
RASPPPIP lpprojection;
HRASCONN hras;
DWORD rc;
DWORD bufsize;
if (!PyArg_ParseTuple(args, "i:GetIpAddress",
&hras)) // @pyparm int|hras||The
handle to the RAS connection being checked.
return NULL;
RASCONNSTATUS cs;
// @pyseeapi RasGetConnectStatus
cs.dwSize = sizeof(RASCONNSTATUS);
if ((rc=RasGetConnectStatus(hras, &cs )))
return ReturnRasError
("RasGetIpAddress",rc); // @pyseeapi
RasGetConnectStatus
if (!(cs.rasconnstate==RASCS_Connected))
return ReturnRasError
("RasGetIpAddress"); // @pyseeapi
RasGetConnectStatus
lpprojection.dwSize = bufsize = sizeof
(RASPPPIP);
// @pyseeapi RasGetErrorString
if (rc=RasGetProjectionInfo
(hras,RASP_PppIp,&lpprojection,&bufsize))
return ReturnRasError
("RasGetIpAddress",rc);
return Py_BuildValue
("(ss)",lpprojection.szIpAddress,
lpprojection.szServerIpAddress);
}
#if (WINVER >= 0x500)
// @pymethod
|win32ras|GetConnectionStatistics|Returns a list of RAS
statistics.
static PyObject *
PyRasGetConnectionStatistics( PyObject *self, PyObject
*args )
{
RAS_STATS rasstats;
HRASCONN hras;
DWORD rc;
DWORD bufsize;
if (!PyArg_ParseTuple
(args, "i:GetConnectionStatistics",
&hras)) // @pyparm int|hras||The
handle to the RAS connection being checked.
return NULL;
HINSTANCE hLib = LoadLibrary
("RASAPI32.DLL"); // Try to load the library
if (hLib == NULL)
return NULL; // Return NULL if
RASAPI32.DLL is not loaded on the system
FreeLibrary(hLib);
RASCONNSTATUS cs;
// @pyseeapi RasGetConnectStatus
cs.dwSize = sizeof(RASCONNSTATUS);
if ((rc=RasGetConnectStatus(hras, &cs )))
return ReturnRasError
("RasGetConnectionStatistics",rc); // @pyseeapi
RasGetConnectStatus
if (!(cs.rasconnstate==RASCS_Connected))
return ReturnRasError
("RasGetConnectionStatistics"); //
@pyseeapi RasGetConnectStatus
rasstats.dwSize = bufsize = sizeof
(RAS_STATS);
// @pyseeapi RasGetConnectionStatistics
if (rc=RasGetConnectionStatistics
(hras,&rasstats))
return ReturnRasError
("RasGetConnectionStatistics",rc);
return Py_BuildValue
("(iiiiiiiii)",rasstats.dwBytesXmited,
rasstats.dwBytesRcved,
rasstats.dwCrcErr,
rasstats.dwTimeoutErr,
rasstats.dwAlignmentErr,
rasstats.dwHardwareOverrunErr,
rasstats.dwFramingErr,
rasstats.dwBufferOverrunErr,
rasstats.dwConnectDuration);
}
static PyObject *
// @pymethod
|win32ras|ClearConnectionStatistics|Clears ths RAS
statistics and returns 1 if successful.
PyRasClearConnectionStatistics( PyObject *self,
PyObject *args )
{
HRASCONN hras;
DWORD rc;
if (!PyArg_ParseTuple
(args, "i:ClearConnectionStatistics",
&hras)) // @pyparm int|hras||The
handle to the RAS connection being checked.
return NULL;
HINSTANCE hLib = LoadLibrary
("RASAPI32.DLL"); // Try to load the library
if (hLib == NULL)
return NULL; // Return NULL if
RASAPI32.DLL is not loaded on the system
FreeLibrary(hLib);
RASCONNSTATUS cs;
// @pyseeapi RasGetConnectStatus
cs.dwSize = sizeof(RASCONNSTATUS);
if ((rc=RasGetConnectStatus(hras, &cs )))
return ReturnRasError
("RasClearConnectionStatistics",rc); // @pyseeapi
RasGetConnectStatus
if (!(cs.rasconnstate==RASCS_Connected))
return ReturnRasError
("RasClearConnectionStatistics"); //
@pyseeapi RasGetConnectStatus
// @pyseeapi RasGetConnectionStatistics
if (rc=RasClearConnectionStatistics(hras))
return ReturnRasError
("RasClearConnectionStatistics",rc);
BOOL bRet = 1;
return Py_BuildValue("i", bRet);
}
#endif
/* List of functions exported by this module */
// @module win32ras|A module encapsulating the
Windows Remote Access Service (RAS) API.
static struct PyMethodDef win32ras_functions[] = {
{"CreatePhonebookEntry",
PyRasCreatePhonebookEntry, METH_VARARGS}, //
@pymeth CreatePhonebookEntry|Creates a new
phonebook entry. The function displays a dialog box
into which the user can enter information about the
entry.
{"Dial", PyRasDial,
METH_VARARGS}, // @pymeth Dial|Establishes a RAS
connection to a RAS server.
{"EditPhonebookEntry",
PyRasEditPhonebookEntry, METH_VARARGS}, //
@pymeth EditPhonebookEntry|Creates a new phonebook
entry. The function displays a dialog box into which the
user can enter information about the entry
{"EnumConnections",
PyRasEnumConnections, METH_VARARGS}, // @pymeth
EnumConnections|Returns a list of tuples, one for each
active connection.
{"EnumEntries", PyRasEnumEntries,
METH_VARARGS}, // @pymeth EnumEntries|Returns a
list of tuples, one for each phonebook entry.
{"GetConnectStatus",
PyRasGetConnectStatus, METH_VARARGS}, // @pymeth
GetConnectStatus|Returns a tuple with connection
information.
{"GetEntryDialParams",
PyRasGetEntryDialParams, METH_VARARGS}, // @pymeth
GetEntryDialParams|Returns a tuple with the most
recently set dial parameters for the specified entry.
{"GetErrorString",
PyRasGetErrorString, METH_VARARGS}, // @pymeth
GetErrorString|Returns an error string for a RAS error
code.
{"HangUp", PyRasHangUp,
METH_VARARGS}, // @pymeth HangUp|Terminates a
remote access session.
{"IsHandleValid",
PyRasIsHandleValid, METH_VARARGS}, //
@pymeth IsHandleValid|Indicates if the given RAS
handle is valid.
{"SetEntryDialParams",
PyRasSetEntryDialParams, METH_VARARGS}, // @pymeth
SetEntryDialParams|Sets the dial parameters for the
specified entry.
{"RASDIALEXTENSIONS",
PyWinObject_NewRASDIALEXTENSIONS,
METH_VARARGS}, // @pymeth
RASDIALEXTENSIONS|Creates a new <o
RASDIALEXTENSIONS> object
{"GetIPAddress",
PyRasGetIpAddress, METH_VARARGS}, // @pymeth
GetIPAddress|Gets the PPP IP address for remote access
session.
#if (WINVER >= 0x500)
{"GetConnectionStatistics",
PyRasGetConnectionStatistics, METH_VARARGS}, //
@pymeth GetConnectionStatistics|Gets the statistics for
remote access connection.
{"ClearConnectionStatistics",
PyRasClearConnectionStatistics, METH_VARARGS}, //
@pymeth GetConnectionStatistics|Gets the statistics for
remote access connection.
#endif
{NULL, NULL}
};
Logged In: YES
user_id=14198
There is a win2kras module designed to avoid needing to
LoadLibrary functions. Can you please reapply you patch to
this module (and you can drop the LoadLibrary)
Also, pyseeapi for ClearConnectionStatistics is wrong :)
Thanks
Logged In: YES
user_id=956816
I have made the requested changes to win32ras and win2kras
and attached the two files.
Best Regards
Ian
Updated win32ras and win2kras modules
Logged In: YES
user_id=14198
Sorry for the delay.
* It looks like only GetIpAddress() has been added to the
method table of win32rasmodule.cpp -
GetConnectionStatistics and ClearConnectionStatistics seem
missing (ahh - I see - you accidently left the these methods
in win32ras *and* added them to win2kras)
* Can we change GetIpAddress() to GetProjectionInfo and
return everyting in the RASPPPIP structure.
* I think it would be better to not check the RAS status
before calling these functions - just let the API itself
return the appropriate error code - it will be clearer to
the user.
It would be fantastic if you could make these changes for me
and upload a new patch.
Thanks,
Mark
Logged In: YES
user_id=956816
OK can remove the code for GetConnectionStatistics and
ClearConnectionStatistics completely from win32ras and
leave it in win2kras as requested. I can also remove the
checks of Ras status before calling them.
About GetProjectionStatus - I can make the change as
requested, but only for RASPPPIP, not the others. So this
will be a hardcode version that does not handle the other 6
rasprojection values. I do not currently have time to work on
mapping all of these structures. Is that OK?
Then the question is how to handle the RASPPPIP structure,
since it contains a check on Winver=0x500 - do I leave it in
win32ras with an ifdef, or move it to win2kras without an ifdef,
or have 2 versions (in which case will the win2kras version
override the win32ras version) ?
/Ian
Logged In: YES
user_id=14198
MSDN says RasGetProjectionStatus is available for NT - so
win32ras should be fine, even if it does involve bumping WINVER.
Implementing only one kind of projection is fine - just so
long as it is capable of being extended further. For
example, you should still accept a RASPROJECTION param, but
raise a NotImplementedError if the value is not one supported.
Thanks!