|
|
/*
File devicedb.c
Definition of the device database for the ras dialup server.
Paul Mayfield, 10/2/97 */
#include "rassrv.h"
#include "precomp.h"
//
// Definitions
//
#define DEV_FLAG_DEVICE 0x1
#define DEV_FLAG_NULL_MODEM 0x2
#define DEV_FLAG_PORT 0x4
#define DEV_FLAG_FILTERED 0x10
#define DEV_FLAG_DIRTY 0x20
#define DEV_FLAG_ENABLED 0x40
// ===================================
// Definitions of the database objects
// ===================================
typedef struct _RASSRV_DEVICE { PWCHAR pszName; // Name of device
DWORD dwType; // Type of device
DWORD dwId; // Id of the item (for tapi properties)
DWORD dwEndpoints; // Number of enpoints item has
DWORD dwFlags; // see DEV_FLAG_XXX
WCHAR pszPort[MAX_PORT_NAME + 1]; struct _RASSRV_DEVICE * pModem; // Modem installed on a com port
// only valid if DEV_FLAG_PORT set
} RASSRV_DEVICE;
typedef struct _RASSRV_DEVICEDB { DWORD dwDeviceCount; RASSRV_DEVICE ** pDeviceList; BOOL bFlushOnClose; BOOL bVpnEnabled; // whether pptp or l2tp is enabled
BOOL bVpnEnabledOrig; // original value of vpn enabling
} RASSRV_DEVICEDB;
//
// Structure defines a node in a list of ports
//
typedef struct _RASSRV_PORT_NODE { PWCHAR pszName; WCHAR pszPort[MAX_PORT_NAME + 1]; struct _RASSRV_DEVICE * pModem; // modem installed on this port
struct _RASSRV_PORT_NODE * pNext; } RASSRV_PORT_NODE;
//
// Structure defines a list of ports
//
typedef struct _RASSRV_PORT_LIST { DWORD dwCount; RASSRV_PORT_NODE * pHead; WCHAR pszFormat[256]; DWORD dwFmtLen; } RASSRV_PORT_LIST;
// Reads device information from the system.
DWORD devGetSystemDeviceInfo( OUT RAS_DEVICE_INFO ** ppDevice, OUT LPDWORD lpdwCount) { DWORD dwErr, dwSize, dwVer, dwCount; // Calculate the size required to enumerate the ras devices
dwVer = RAS_VERSION; dwSize = 0; dwCount =0; dwErr = RasGetDeviceConfigInfo(NULL, &dwVer, &dwCount, &dwSize, NULL); if ((dwErr != ERROR_SUCCESS) && (dwErr != ERROR_BUFFER_TOO_SMALL)) { DbgOutputTrace( "devGetSysDevInfo: 0x%08x from RasGetDevCfgInfo (1)", dwErr); return dwErr; } *lpdwCount = dwCount; // If there is nothing to allocate, return with zero devices
if (dwSize == 0) { *lpdwCount = 0; return NO_ERROR; } // Allocate the buffer
if ((*ppDevice = RassrvAlloc(dwSize, FALSE)) == NULL) { return ERROR_NOT_ENOUGH_MEMORY; }
// Enumerate the devices
dwErr = RasGetDeviceConfigInfo( NULL, &dwVer, lpdwCount, &dwSize, (LPBYTE)(*ppDevice)); if (dwErr != ERROR_SUCCESS) { DbgOutputTrace( "devGetSysDevInfo: 0x%08x from RasGetDevCfgInfo (2)", dwErr); return dwErr; }
return NO_ERROR; }
//
// Frees the buffer returned by devGetSystemDeviceInfo
//
DWORD devFreeSystemDeviceInfo( IN RAS_DEVICE_INFO * pDevice) { if (pDevice) { RassrvFree(pDevice); } return NO_ERROR; }
//
// Returns whether the given device is a physical (i.e. not tunnel) device.
//
BOOL devIsPhysicalDevice( IN RAS_DEVICE_INFO * pDevice) { DWORD dwClass = RAS_DEVICE_CLASS (pDevice->eDeviceType);
return ((dwClass & RDT_Direct) || (dwClass & RDT_Null_Modem) || (dwClass == 0)); }
//
// Returns whether the given device is a tunneling device
//
BOOL devIsTunnelDevice( IN RAS_DEVICE_INFO * pDevice) { DWORD dwClass = RAS_DEVICE_CLASS (pDevice->eDeviceType);
return (dwClass & RDT_Tunnel); }
//
// Finds the device information associated with the given device
// based on its tapi line id
//
DWORD devFindDevice( IN RAS_DEVICE_INFO * pDevices, IN DWORD dwCount, OUT RAS_DEVICE_INFO ** ppDevice, IN DWORD dwTapiLineId) { DWORD i;
// Validate parameters
if (!pDevices || !ppDevice) return ERROR_INVALID_PARAMETER;
// Initialize
*ppDevice = NULL;
// Search the list
for (i = 0; i < dwCount; i++) { if (devIsPhysicalDevice(&pDevices[i])) { if (pDevices[i].dwTapiLineId == dwTapiLineId) { *ppDevice = &(pDevices[i]); break; } } }
// See if a match was found;
if (*ppDevice) { return NO_ERROR; } return ERROR_NOT_FOUND; }
//
// Determine the type of the device in question
//
DWORD devDeviceType( IN RAS_DEVICE_INFO * pDevice) { DWORD dwClass = RAS_DEVICE_CLASS (pDevice->eDeviceType); DWORD dwType = RAS_DEVICE_TYPE (pDevice->eDeviceType);
if ((dwClass & RDT_Direct) || (dwClass & RDT_Null_Modem) || (dwType == RDT_Irda) || (dwType == RDT_Parallel) ) { return INCOMING_TYPE_DIRECT; } else if (dwClass == RDT_Tunnel) { return INCOMING_TYPE_VPN; }
return INCOMING_TYPE_PHONE; }
//
// Returns the flags of a given device
//
DWORD devInitFlags( IN RAS_DEVICE_INFO * pDevice) { DWORD dwClass = RAS_DEVICE_CLASS (pDevice->eDeviceType), dwRet = 0;
// Set the device's enabling
if (pDevice->fRasEnabled) { dwRet |= DEV_FLAG_ENABLED; }
// Determine if it's a null modem or a device. It
// can't be a port, since those are not reported
// through ras.
if (dwClass & RDT_Null_Modem) { dwRet |= DEV_FLAG_NULL_MODEM; } else { dwRet |= DEV_FLAG_DEVICE; }
// Since the filtered and dirty flags are to be
// initialized to false, we're done.
return dwRet; }
//
// Generates the device name
//
PWCHAR devCopyDeviceName( IN RAS_DEVICE_INFO * pDevice, IN DWORD dwType) { PWCHAR pszReturn; DWORD dwSize; PWCHAR pszDccFmt = (PWCHAR) PszLoadString(Globals.hInstDll, SID_DEVICE_DccDeviceFormat); PWCHAR pszMultiFmt = (PWCHAR) PszLoadString(Globals.hInstDll, SID_DEVICE_MultiEndpointDeviceFormat); WCHAR pszPort[MAX_PORT_NAME + 1]; WCHAR pszDevice[MAX_DEVICE_NAME + 1];
// Sanity check the resources
//
if (!pszDccFmt || !pszMultiFmt) { return NULL; }
// Get the unicode versions of the port/device
//
pszPort[0] = L'\0'; pszDevice[0] = L'\0'; if (pDevice->szPortName) { StrCpyWFromAUsingAnsiEncoding( pszPort, pDevice->szPortName, strlen(pDevice->szPortName) + 1); } if (pDevice->szDeviceName) { #if 0
StrCpyWFromAUsingAnsiEncoding( pszDevice, pDevice->szDeviceName, strlen(pDevice->szDeviceName) + 1); #endif
wcsncpy( pszDevice, pDevice->wszDeviceName, MAX_DEVICE_NAME);
pszDevice[MAX_DEVICE_NAME] = L'\0'; }
// For direct connections, be sure to display the name of the com port
// in addition to the name of the null modem.
if (dwType == INCOMING_TYPE_DIRECT) { // Calculate the size
dwSize = wcslen(pszDevice) * sizeof(WCHAR) + // device
wcslen(pszPort) * sizeof(WCHAR) + // com port
wcslen(pszDccFmt) * sizeof(WCHAR) + // oth chars
sizeof(WCHAR); // null
// Allocate the new string
if ((pszReturn = RassrvAlloc (dwSize, FALSE)) == NULL) { return pszReturn; }
wsprintfW(pszReturn, pszDccFmt, pszDevice, pszPort); }
//
// If it's a modem device with multilple end points (such as isdn)
// display the endpoints in parenthesis
//
else if ((dwType == INCOMING_TYPE_PHONE) && (pDevice->dwNumEndPoints > 1)) { // Calculate the size
dwSize = wcslen(pszDevice) * sizeof(WCHAR) + // device
wcslen(pszMultiFmt) * sizeof(WCHAR) + // channels
20 * sizeof (WCHAR) + // oth chars
sizeof(WCHAR); // null
// Allocate the new string
if ((pszReturn = RassrvAlloc(dwSize, FALSE)) == NULL) { return pszReturn; }
wsprintfW( pszReturn, pszMultiFmt, pszDevice, pDevice->dwNumEndPoints); }
// Otherwise, this is a modem device with one endpoint.
// All that needs to be done here is to copy in the name.
//
else { // Calculate the size
dwSize = (wcslen(pszDevice) + 1) * sizeof(WCHAR); // Allocate the new string
if ((pszReturn = RassrvAlloc(dwSize, FALSE)) == NULL) { return pszReturn; }
wcscpy(pszReturn, pszDevice); }
return pszReturn; }
//
// Commits changes to device configuration to the system. The call
// to RasSetDeviceConfigInfo might fail if the device is in the process
// of being configured so we implement a retry
// mechanism here.
//
DWORD devCommitDeviceInfo( IN RAS_DEVICE_INFO * pDevice) { DWORD dwErr, dwTimeout = 10; do { // Try to commit the information
dwErr = RasSetDeviceConfigInfo( NULL, 1, sizeof(RAS_DEVICE_INFO), (LPBYTE)pDevice);
// If unable to complete, wait and try again
if (dwErr == ERROR_CAN_NOT_COMPLETE) { DbgOutputTrace( "devCommDevInfo: 0x%08x from RasSetDevCfgInfo (try again)", dwErr); Sleep(300); dwTimeout--; }
// If completed, return no error
else if (dwErr == NO_ERROR) { break; }
// Otherwise, return the error code.
else { DbgOutputTrace( "devCommDevInfo: can't commit %S, 0x%08x", pDevice->szDeviceName, dwErr); break; } } while (dwTimeout);
return dwErr; }
//
// Opens a handle to the database of general tab values
//
DWORD devOpenDatabase( IN HANDLE * hDevDatabase) { RASSRV_DEVICEDB * This; DWORD dwErr, i; if (!hDevDatabase) { return ERROR_INVALID_PARAMETER; }
// Allocate the database cache
if ((This = RassrvAlloc(sizeof(RASSRV_DEVICEDB), TRUE)) == NULL) { DbgOutputTrace("devOpenDatabase: can't allocate memory -- exiting"); return ERROR_NOT_ENOUGH_MEMORY; } // Initialize the values from the system
devReloadDatabase((HANDLE)This);
// Return the handle
*hDevDatabase = (HANDLE)This; This->bFlushOnClose = FALSE;
return NO_ERROR; }
//
// Closes the general database and flushes any changes
// to the system when bFlushOnClose is TRUE
//
DWORD devCloseDatabase( IN HANDLE hDevDatabase) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase; DWORD i; // Flush if requested
if (This->bFlushOnClose) devFlushDatabase(hDevDatabase); // Free all of the device names
for (i = 0; i < This->dwDeviceCount; i++) { if (This->pDeviceList[i]) { if (This->pDeviceList[i]->pszName) { RassrvFree(This->pDeviceList[i]->pszName); } RassrvFree(This->pDeviceList[i]); } }
// Free up the device list cache
if (This->pDeviceList) { RassrvFree (This->pDeviceList); }
// Free up the database cache
RassrvFree(This);
return NO_ERROR; }
//
// Commits the changes made to a particular device
//
DWORD devCommitDevice ( IN RASSRV_DEVICE * pDevice, IN RAS_DEVICE_INFO * pDevices, IN DWORD dwCount) { RAS_DEVICE_INFO *pDevInfo = NULL; devFindDevice(pDevices, dwCount, &pDevInfo, pDevice->dwId); if (pDevInfo) { pDevInfo->fWrite = TRUE; pDevInfo->fRasEnabled = !!(pDevice->dwFlags & DEV_FLAG_ENABLED); devCommitDeviceInfo(pDevInfo); }
// Mark the device as not dirty
pDevice->dwFlags &= ~DEV_FLAG_DIRTY;
return NO_ERROR; }
BOOL devIsVpnEnableChanged( IN HANDLE hDevDatabase) { RASSRV_DEVICEDB * pDevDb = (RASSRV_DEVICEDB*)hDevDatabase;
if ( pDevDb ) { return ( pDevDb->bVpnEnabled != pDevDb->bVpnEnabledOrig? TRUE:FALSE ); }
return FALSE;
}//devIsVpnEnableChanged()
//
// Commits any changes made to the general tab values
//
DWORD devFlushDatabase( IN HANDLE hDevDatabase) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase; DWORD dwErr = NO_ERROR, i, dwCount, dwTimeout; RAS_DEVICE_INFO * pDevices = NULL; RASSRV_DEVICE * pCur = NULL;
// Validate
if (!This) { return ERROR_INVALID_PARAMETER; }
// Get all of the system device information
dwErr = devGetSystemDeviceInfo(&pDevices, &dwCount); if (dwErr != NO_ERROR) { return dwErr; }
// Flush all changed settings to the system
for (i = 0; i < This->dwDeviceCount; i++) { pCur = This->pDeviceList[i]; // If this device needs to be flushed
if (pCur->dwFlags & DEV_FLAG_DIRTY) { // Reset the installed device's enabling if it still
// exists in the system
if ((pCur->dwFlags & DEV_FLAG_DEVICE) || (pCur->dwFlags & DEV_FLAG_NULL_MODEM)) { devCommitDevice(pCur, pDevices, dwCount); }
// If this is a com port, then we should enable that modem
// installed on the port if it exists or install a null modem
// over it if not.
else if (pCur->dwFlags & DEV_FLAG_PORT) { // If this port is associated with an already installed
// null modem, then set the enabling on this modem if
// it is different
if (pCur->pModem != NULL) { if ((pCur->dwFlags & DEV_FLAG_ENABLED) != (pCur->pModem->dwFlags & DEV_FLAG_ENABLED)) { devCommitDevice ( pCur->pModem, pDevices, dwCount); } }
// Otherwise, (if there is no null modem associated with
// this port) install a null modem over this port if
// it is set to enabled.
else if (pCur->dwFlags & DEV_FLAG_ENABLED) { dwErr = MdmInstallNullModem (pCur->pszPort); } } } }
// Flush all of the changed vpn settings
if (This->bVpnEnabled != This->bVpnEnabledOrig) { for (i = 0; i < dwCount; i++) { if (devIsTunnelDevice(&pDevices[i])) { pDevices[i].fWrite = TRUE; pDevices[i].fRasEnabled = This->bVpnEnabled; devCommitDeviceInfo(&pDevices[i]); } } This->bVpnEnabledOrig = This->bVpnEnabled; }
// Cleanup
if (pDevices) { devFreeSystemDeviceInfo(pDevices); }
return dwErr; }
//
// Rollsback any changes made to the general tab values
//
DWORD devRollbackDatabase( IN HANDLE hDevDatabase) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase; if (This == NULL) { return ERROR_INVALID_PARAMETER; } This->bFlushOnClose = FALSE; return NO_ERROR; }
//
// Reloads the device database
//
DWORD devReloadDatabase( IN HANDLE hDevDatabase) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase; DWORD dwErr = NO_ERROR, i, j = 0, dwSize; RAS_DEVICE_INFO * pRasDevices; RASSRV_DEVICE * pTempList, *pDevice;
// Validate
if (!This) { return ERROR_INVALID_PARAMETER; }
// Initialize vpn status
This->bVpnEnabled = FALSE; // Get the device information from rasman
pRasDevices = NULL; dwErr = devGetSystemDeviceInfo(&pRasDevices, &This->dwDeviceCount); if (dwErr != NO_ERROR) { return dwErr; } do { // Initialize the incoming ras capable devices list
if (This->dwDeviceCount) { dwSize = sizeof(RASSRV_DEVICE*) * This->dwDeviceCount; This->pDeviceList = RassrvAlloc(dwSize, TRUE); if (!This->pDeviceList) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
// Build the device array accordingly
j = 0; for (i = 0; i < This->dwDeviceCount; i++) { // If it's a physical device, fill in the appropriate
// fields.
if (devIsPhysicalDevice(&pRasDevices[i])) { // Allocate the new device
pDevice = RassrvAlloc(sizeof(RASSRV_DEVICE), TRUE); if (pDevice == NULL) { continue; }
// Assign its values
pDevice->dwType = devDeviceType(&pRasDevices[i]); pDevice->dwId = pRasDevices[i].dwTapiLineId; pDevice->pszName = devCopyDeviceName( &pRasDevices[i], pDevice->dwType); pDevice->dwEndpoints = pRasDevices[i].dwNumEndPoints; pDevice->dwFlags = devInitFlags(&pRasDevices[i]); StrCpyWFromA( pDevice->pszPort, pRasDevices[i].szPortName, MAX_PORT_NAME + 1); This->pDeviceList[j] = pDevice; j++; }
// If any tunneling protocol is enabled, we consider all
// to be
else if (devIsTunnelDevice(&pRasDevices[i])) { This->bVpnEnabled |= pRasDevices[i].fRasEnabled; This->bVpnEnabledOrig = This->bVpnEnabled; } }
// Set the actual size of phyiscal adapters buffer.
This->dwDeviceCount = j; }
} while (FALSE); // Cleanup
{ devFreeSystemDeviceInfo(pRasDevices); }
return dwErr; }
//
// Filters out all devices in the database except those that
// meet the given type description (can be ||'d).
//
DWORD devFilterDevices( IN HANDLE hDevDatabase, DWORD dwType) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase; RASSRV_DEVICE * pDevice; DWORD i; if (!This) { return ERROR_INVALID_PARAMETER; }
// Go through the list of marking out devices to be filtered
for (i = 0; i < This->dwDeviceCount; i++) { pDevice = This->pDeviceList[i]; if (pDevice == NULL) { continue; } if (pDevice->dwType & dwType) { pDevice->dwFlags &= ~DEV_FLAG_FILTERED; } else { pDevice->dwFlags |= DEV_FLAG_FILTERED; } }
return NO_ERROR; }
//
// Device enumeration function. Returns TRUE to stop enumeration,
// FALSE to continue.
//
BOOL devAddPortToList ( IN PWCHAR pszPort, IN HANDLE hData) { RASSRV_PORT_LIST * pList = (RASSRV_PORT_LIST*)hData; RASSRV_PORT_NODE * pNode = NULL; DWORD dwSize;
// Create the new node
pNode = (RASSRV_PORT_NODE *) RassrvAlloc(sizeof(RASSRV_PORT_NODE), TRUE); if (pNode == NULL) { return FALSE; }
// Add it to the head
pNode->pNext = pList->pHead; pList->pHead = pNode; pList->dwCount++;
// Add the names of the port
if (pszPort) { dwSize = (wcslen(pszPort) + pList->dwFmtLen + 1) * sizeof(WCHAR); pNode->pszName = (PWCHAR) RassrvAlloc (dwSize, FALSE); if (pNode->pszName == NULL) { return TRUE; } wsprintfW (pNode->pszName, pList->pszFormat, pszPort); lstrcpynW(pNode->pszPort, pszPort, sizeof(pNode->pszPort) / sizeof(WCHAR)); }
return FALSE; }
//
// Cleans up the resources used in a device list
//
DWORD devCleanupPortList( IN RASSRV_PORT_LIST * pList) { RASSRV_PORT_NODE * pCur = NULL, * pNext = NULL;
pCur = pList->pHead; while (pCur) { pNext = pCur->pNext; RassrvFree(pCur); pCur = pNext; }
return NO_ERROR; }
//
// Removes all ports from the list for which there are already
// devices installed in the database.
//
DWORD devFilterPortsInUse ( IN RASSRV_DEVICEDB *This, RASSRV_PORT_LIST *pList) { RASSRV_PORT_LIST PortList, *pDelete = &PortList; RASSRV_PORT_NODE * pCur = NULL, * pPrev = NULL; RASSRV_DEVICE * pDevice; DWORD i; BOOL bDone; INT iCmp;
// If the list is empty, return
if (pList->dwCount == 0) { return NO_ERROR; }
// Initailize
ZeroMemory(pDelete, sizeof(RASSRV_PORT_LIST)); // Compare all of the enumerated ports to the ports
// in use in the device list.
for (i = 0; i < This->dwDeviceCount; i++) { // Point to the current device
pDevice = This->pDeviceList[i]; // Initialize the current and previous and break if the
// list is now empty
pCur = pList->pHead; if (pCur == NULL) { break; }
// Remove the head node until it doesn't match
bDone = FALSE; while ((pList->pHead != NULL) && (bDone == FALSE)) { iCmp = lstrcmpi (pDevice->pszPort, pList->pHead->pszPort); // If a device is already using this com port
// then remove the com port from the list since it
// isn't available
if ((pDevice->dwFlags & DEV_FLAG_DEVICE) && (iCmp == 0)) { pCur = pList->pHead->pNext; RassrvFree(pList->pHead); pList->pHead = pCur; pList->dwCount -= 1; } else { // If the device is a null modem, then we filter
// it out of the list of available devices and we
// reference it in the com port so that we can
// enable/disable it later if we need to.
if (iCmp == 0) { pDevice->dwFlags |= DEV_FLAG_FILTERED; pList->pHead->pModem = pDevice; } bDone = TRUE; } }
// If we've elimated everyone, return
if (pList->dwCount == 0) { return NO_ERROR; }
// Loop through all of the past the head removing those
// that are in use by the current ras device.
pPrev = pList->pHead; pCur = pPrev->pNext; while (pCur) { iCmp = lstrcmpi (pDevice->pszPort, pCur->pszPort); // If a device is already using this com port
// that remove the com port from the list since it
// isn't available
if ((pDevice->dwFlags & DEV_FLAG_DEVICE) && (iCmp == 0)) { pPrev->pNext = pCur->pNext; RassrvFree(pCur); pCur = pPrev->pNext; pList->dwCount -= 1; } else { // If the device is a null modem, then we filter
// it out of the list of available devices and we
// reference it in the com port so that we can
// enable/disable it later if we need to.
if (iCmp == 0) { pDevice->dwFlags |= DEV_FLAG_FILTERED; pCur->pModem = pDevice; } pCur = pCur->pNext; pPrev = pPrev->pNext; } } }
return NO_ERROR; }
//
// Adds com ports as uninstalled devices in the device database
//
DWORD devAddComPorts( IN HANDLE hDevDatabase) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase; RASSRV_PORT_LIST PortList, *pList = &PortList; RASSRV_PORT_NODE * pNode = NULL; RASSRV_DEVICE ** ppDevices; DWORD dwErr = NO_ERROR, i; if (!This) { return ERROR_INVALID_PARAMETER; }
// Initialize the port list
//
ZeroMemory (pList, sizeof(RASSRV_PORT_LIST)); pList->dwFmtLen = LoadStringW ( Globals.hInstDll, SID_COMPORT_FORMAT, pList->pszFormat, sizeof(pList->pszFormat) / sizeof(WCHAR));
do { // Create the list of com ports
dwErr = MdmEnumComPorts(devAddPortToList, (HANDLE)pList); if (dwErr != NO_ERROR) { break; }
// Remove any ports that are currently in use
if ((dwErr = devFilterPortsInUse (This, pList)) != NO_ERROR) { break; } // If there aren't any ports, return
if (pList->dwCount == 0) { break; }
// Resize the list of ports to include the com ports
ppDevices = RassrvAlloc( sizeof(RASSRV_DEVICE*) * (This->dwDeviceCount + pList->dwCount), TRUE); if (ppDevices == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
// Copy over the current device information
CopyMemory( ppDevices, This->pDeviceList, This->dwDeviceCount * sizeof(RASSRV_DEVICE*));
// Delete the old device list and set to the new one
RassrvFree(This->pDeviceList); This->pDeviceList = ppDevices;
// Add the ports
pNode = pList->pHead; i = This->dwDeviceCount; while (pNode) { // Allocate the new device
ppDevices[i] = RassrvAlloc(sizeof(RASSRV_DEVICE), TRUE); if (!ppDevices[i]) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; } // Set all the non-zero values
ppDevices[i]->dwType = INCOMING_TYPE_DIRECT; ppDevices[i]->pszName = pNode->pszName; ppDevices[i]->pModem = pNode->pModem; ppDevices[i]->dwFlags = DEV_FLAG_PORT; lstrcpynW( ppDevices[i]->pszPort, pNode->pszPort, sizeof(ppDevices[i]->pszPort) / sizeof(WCHAR));
// Initialize the enabling of the com port
if (ppDevices[i]->pModem) { ppDevices[i]->dwFlags |= (ppDevices[i]->pModem->dwFlags & DEV_FLAG_ENABLED); }
// Increment
i++; pNode = pNode->pNext; } This->dwDeviceCount = i; } while (FALSE);
// Cleanup
{ devCleanupPortList(pList); }
return dwErr; }
//
// Returns whether the given index lies within the bounds of the
// list of devices store in This.
//
BOOL devBoundsCheck( IN RASSRV_DEVICEDB * This, IN DWORD dwIndex) { if (This->dwDeviceCount <= dwIndex) { DbgOutputTrace("devBoundsCheck: failed for index %d", dwIndex); return FALSE; } return TRUE; }
// Gets a handle to a device to be displayed in the general tab
DWORD devGetDeviceHandle( IN HANDLE hDevDatabase, IN DWORD dwIndex, OUT HANDLE * hDevice) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase; if (!This || !hDevice) { return ERROR_INVALID_PARAMETER; }
if (!devBoundsCheck(This, dwIndex)) { return ERROR_INVALID_INDEX; }
// Return nothing if device is filtered
if (This->pDeviceList[dwIndex]->dwFlags & DEV_FLAG_FILTERED) { *hDevice = NULL; return ERROR_DEVICE_NOT_AVAILABLE; }
// Otherwise, return the device
else { *hDevice = (HANDLE)(This->pDeviceList[dwIndex]); } return NO_ERROR; }
//
// Returns a count of devices to be displayed in the general tab
//
DWORD devGetDeviceCount( IN HANDLE hDevDatabase, OUT LPDWORD lpdwCount) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase; if (!This || !lpdwCount) { return ERROR_INVALID_PARAMETER; }
*lpdwCount = This->dwDeviceCount; return NO_ERROR; }
//
// Returns the count of enabled devices
//
DWORD devGetEndpointEnableCount( IN HANDLE hDevDatabase, OUT LPDWORD lpdwCount) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase; DWORD i; if (!This || !lpdwCount) { return ERROR_INVALID_PARAMETER; }
*lpdwCount = 0;
for (i = 0; i < This->dwDeviceCount; i++) { if (This->pDeviceList[i]->dwFlags & DEV_FLAG_ENABLED) { (*lpdwCount) += This->pDeviceList[i]->dwEndpoints; } } return NO_ERROR; }
//
// Loads the vpn enable status
//
DWORD devGetVpnEnable( IN HANDLE hDevDatabase, IN BOOL * pbEnabled) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
if (!This || !pbEnabled) { return ERROR_INVALID_PARAMETER; }
*pbEnabled = This->bVpnEnabled; return NO_ERROR; }
//
// Saves the vpn enable status
//
DWORD devSetVpnEnable( IN HANDLE hDevDatabase, IN BOOL bEnable) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
if (!This) { return ERROR_INVALID_PARAMETER; } This->bVpnEnabled = bEnable; return NO_ERROR; }
// Saves the vpn Original value enable status
//
DWORD devSetVpnOrigEnable( IN HANDLE hDevDatabase, IN BOOL bEnable) { RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
if (!This) { return ERROR_INVALID_PARAMETER; } This->bVpnEnabledOrig = bEnable; return NO_ERROR; }
//
// Returns a pointer to the name of a device
//
DWORD devGetDeviceName( IN HANDLE hDevice, OUT PWCHAR * pszDeviceName) { RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice; if (!This || !pszDeviceName) { return ERROR_INVALID_PARAMETER; }
*pszDeviceName = This->pszName;
return NO_ERROR; }
//
// Returns the type of a device
//
DWORD devGetDeviceType( IN HANDLE hDevice, OUT LPDWORD lpdwType) { RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice; if (!This || !lpdwType) { return ERROR_INVALID_PARAMETER; }
*lpdwType = This->dwType;
return NO_ERROR; }
//
// Returns an identifier of the device that can be used in
// tapi calls.
//
DWORD devGetDeviceId( IN HANDLE hDevice, OUT LPDWORD lpdwId) { RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice; if (!This || !lpdwId) { return ERROR_INVALID_PARAMETER; }
*lpdwId = This->dwId;
//
// If this is a com port referencing a null modem,
// then return the tapi id of the null modem
//
if ((This->dwFlags & DEV_FLAG_PORT) && (This->pModem)) { *lpdwId = This->pModem->dwId; }
return NO_ERROR; }
//
// Returns the enable status of a device for dialin
//
DWORD devGetDeviceEnable( IN HANDLE hDevice, OUT BOOL * pbEnabled) { RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice; if (!This || !pbEnabled) { return ERROR_INVALID_PARAMETER; }
*pbEnabled = !!(This->dwFlags & DEV_FLAG_ENABLED);
return NO_ERROR; }
//
// Sets the enable status of a device for dialin
//
DWORD devSetDeviceEnable( IN HANDLE hDevice, IN BOOL bEnable) { RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice; if (!This) { return ERROR_INVALID_PARAMETER; }
// Mark the enabling and mark the device as dirty
if (bEnable) { This->dwFlags |= DEV_FLAG_ENABLED; } else { This->dwFlags &= ~DEV_FLAG_ENABLED; } This->dwFlags |= DEV_FLAG_DIRTY;
return NO_ERROR; }
//
// Returns whether the given device is a com port as added
// by devAddComPorts
//
DWORD devDeviceIsComPort( IN HANDLE hDevice, OUT PBOOL pbIsComPort) { RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice; if (!This) { return ERROR_INVALID_PARAMETER; }
// This is a com port if it was added by
// devAddComPorts and if it has no null
// modem associated with it.
//
if ((This->dwFlags & DEV_FLAG_PORT) && (This->pModem == NULL) ) { *pbIsComPort = TRUE; } else { *pbIsComPort = FALSE; } return NO_ERROR; }
|