/* 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; }