Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1383 lines
33 KiB

  1. /*
  2. File devicedb.c
  3. Definition of the device database for the ras dialup server.
  4. Paul Mayfield, 10/2/97
  5. */
  6. #include "rassrv.h"
  7. #include "precomp.h"
  8. //
  9. // Definitions
  10. //
  11. #define DEV_FLAG_DEVICE 0x1
  12. #define DEV_FLAG_NULL_MODEM 0x2
  13. #define DEV_FLAG_PORT 0x4
  14. #define DEV_FLAG_FILTERED 0x10
  15. #define DEV_FLAG_DIRTY 0x20
  16. #define DEV_FLAG_ENABLED 0x40
  17. // ===================================
  18. // Definitions of the database objects
  19. // ===================================
  20. typedef struct _RASSRV_DEVICE
  21. {
  22. PWCHAR pszName; // Name of device
  23. DWORD dwType; // Type of device
  24. DWORD dwId; // Id of the item (for tapi properties)
  25. DWORD dwEndpoints; // Number of enpoints item has
  26. DWORD dwFlags; // see DEV_FLAG_XXX
  27. WCHAR pszPort[MAX_PORT_NAME + 1];
  28. struct _RASSRV_DEVICE * pModem; // Modem installed on a com port
  29. // only valid if DEV_FLAG_PORT set
  30. } RASSRV_DEVICE;
  31. typedef struct _RASSRV_DEVICEDB
  32. {
  33. DWORD dwDeviceCount;
  34. RASSRV_DEVICE ** pDeviceList;
  35. BOOL bFlushOnClose;
  36. BOOL bVpnEnabled; // whether pptp or l2tp is enabled
  37. BOOL bVpnEnabledOrig; // original value of vpn enabling
  38. } RASSRV_DEVICEDB;
  39. //
  40. // Structure defines a node in a list of ports
  41. //
  42. typedef struct _RASSRV_PORT_NODE
  43. {
  44. PWCHAR pszName;
  45. WCHAR pszPort[MAX_PORT_NAME + 1];
  46. struct _RASSRV_DEVICE * pModem; // modem installed on this port
  47. struct _RASSRV_PORT_NODE * pNext;
  48. } RASSRV_PORT_NODE;
  49. //
  50. // Structure defines a list of ports
  51. //
  52. typedef struct _RASSRV_PORT_LIST
  53. {
  54. DWORD dwCount;
  55. RASSRV_PORT_NODE * pHead;
  56. WCHAR pszFormat[256];
  57. DWORD dwFmtLen;
  58. } RASSRV_PORT_LIST;
  59. // Reads device information from the system.
  60. DWORD
  61. devGetSystemDeviceInfo(
  62. OUT RAS_DEVICE_INFO ** ppDevice,
  63. OUT LPDWORD lpdwCount)
  64. {
  65. DWORD dwErr, dwSize, dwVer, dwCount;
  66. // Calculate the size required to enumerate the ras devices
  67. dwVer = RAS_VERSION;
  68. dwSize = 0;
  69. dwCount =0;
  70. dwErr = RasGetDeviceConfigInfo(NULL, &dwVer, &dwCount, &dwSize, NULL);
  71. if ((dwErr != ERROR_SUCCESS) && (dwErr != ERROR_BUFFER_TOO_SMALL))
  72. {
  73. DbgOutputTrace(
  74. "devGetSysDevInfo: 0x%08x from RasGetDevCfgInfo (1)",
  75. dwErr);
  76. return dwErr;
  77. }
  78. *lpdwCount = dwCount;
  79. // If there is nothing to allocate, return with zero devices
  80. if (dwSize == 0)
  81. {
  82. *lpdwCount = 0;
  83. return NO_ERROR;
  84. }
  85. // Allocate the buffer
  86. if ((*ppDevice = RassrvAlloc(dwSize, FALSE)) == NULL)
  87. {
  88. return ERROR_NOT_ENOUGH_MEMORY;
  89. }
  90. // Enumerate the devices
  91. dwErr = RasGetDeviceConfigInfo(
  92. NULL,
  93. &dwVer,
  94. lpdwCount,
  95. &dwSize,
  96. (LPBYTE)(*ppDevice));
  97. if (dwErr != ERROR_SUCCESS)
  98. {
  99. DbgOutputTrace(
  100. "devGetSysDevInfo: 0x%08x from RasGetDevCfgInfo (2)", dwErr);
  101. return dwErr;
  102. }
  103. return NO_ERROR;
  104. }
  105. //
  106. // Frees the buffer returned by devGetSystemDeviceInfo
  107. //
  108. DWORD
  109. devFreeSystemDeviceInfo(
  110. IN RAS_DEVICE_INFO * pDevice)
  111. {
  112. if (pDevice)
  113. {
  114. RassrvFree(pDevice);
  115. }
  116. return NO_ERROR;
  117. }
  118. //
  119. // Returns whether the given device is a physical (i.e. not tunnel) device.
  120. //
  121. BOOL
  122. devIsPhysicalDevice(
  123. IN RAS_DEVICE_INFO * pDevice)
  124. {
  125. DWORD dwClass = RAS_DEVICE_CLASS (pDevice->eDeviceType);
  126. return ((dwClass & RDT_Direct) ||
  127. (dwClass & RDT_Null_Modem) ||
  128. (dwClass == 0));
  129. }
  130. //
  131. // Returns whether the given device is a tunneling device
  132. //
  133. BOOL
  134. devIsTunnelDevice(
  135. IN RAS_DEVICE_INFO * pDevice)
  136. {
  137. DWORD dwClass = RAS_DEVICE_CLASS (pDevice->eDeviceType);
  138. return (dwClass & RDT_Tunnel);
  139. }
  140. //
  141. // Finds the device information associated with the given device
  142. // based on its tapi line id
  143. //
  144. DWORD
  145. devFindDevice(
  146. IN RAS_DEVICE_INFO * pDevices,
  147. IN DWORD dwCount,
  148. OUT RAS_DEVICE_INFO ** ppDevice,
  149. IN DWORD dwTapiLineId)
  150. {
  151. DWORD i;
  152. // Validate parameters
  153. if (!pDevices || !ppDevice)
  154. return ERROR_INVALID_PARAMETER;
  155. // Initialize
  156. *ppDevice = NULL;
  157. // Search the list
  158. for (i = 0; i < dwCount; i++)
  159. {
  160. if (devIsPhysicalDevice(&pDevices[i]))
  161. {
  162. if (pDevices[i].dwTapiLineId == dwTapiLineId)
  163. {
  164. *ppDevice = &(pDevices[i]);
  165. break;
  166. }
  167. }
  168. }
  169. // See if a match was found;
  170. if (*ppDevice)
  171. {
  172. return NO_ERROR;
  173. }
  174. return ERROR_NOT_FOUND;
  175. }
  176. //
  177. // Determine the type of the device in question
  178. //
  179. DWORD
  180. devDeviceType(
  181. IN RAS_DEVICE_INFO * pDevice)
  182. {
  183. DWORD dwClass = RAS_DEVICE_CLASS (pDevice->eDeviceType);
  184. DWORD dwType = RAS_DEVICE_TYPE (pDevice->eDeviceType);
  185. if ((dwClass & RDT_Direct) ||
  186. (dwClass & RDT_Null_Modem) ||
  187. (dwType == RDT_Irda) ||
  188. (dwType == RDT_Parallel) )
  189. {
  190. return INCOMING_TYPE_DIRECT;
  191. }
  192. else if (dwClass == RDT_Tunnel)
  193. {
  194. return INCOMING_TYPE_VPN;
  195. }
  196. return INCOMING_TYPE_PHONE;
  197. }
  198. //
  199. // Returns the flags of a given device
  200. //
  201. DWORD
  202. devInitFlags(
  203. IN RAS_DEVICE_INFO * pDevice)
  204. {
  205. DWORD dwClass = RAS_DEVICE_CLASS (pDevice->eDeviceType),
  206. dwRet = 0;
  207. // Set the device's enabling
  208. if (pDevice->fRasEnabled)
  209. {
  210. dwRet |= DEV_FLAG_ENABLED;
  211. }
  212. // Determine if it's a null modem or a device. It
  213. // can't be a port, since those are not reported
  214. // through ras.
  215. if (dwClass & RDT_Null_Modem)
  216. {
  217. dwRet |= DEV_FLAG_NULL_MODEM;
  218. }
  219. else
  220. {
  221. dwRet |= DEV_FLAG_DEVICE;
  222. }
  223. // Since the filtered and dirty flags are to be
  224. // initialized to false, we're done.
  225. return dwRet;
  226. }
  227. //
  228. // Generates the device name
  229. //
  230. PWCHAR
  231. devCopyDeviceName(
  232. IN RAS_DEVICE_INFO * pDevice,
  233. IN DWORD dwType)
  234. {
  235. PWCHAR pszReturn;
  236. DWORD dwSize;
  237. PWCHAR pszDccFmt = (PWCHAR)
  238. PszLoadString(Globals.hInstDll, SID_DEVICE_DccDeviceFormat);
  239. PWCHAR pszMultiFmt = (PWCHAR)
  240. PszLoadString(Globals.hInstDll, SID_DEVICE_MultiEndpointDeviceFormat);
  241. WCHAR pszPort[MAX_PORT_NAME + 1];
  242. WCHAR pszDevice[MAX_DEVICE_NAME + 1];
  243. // Sanity check the resources
  244. //
  245. if (!pszDccFmt || !pszMultiFmt)
  246. {
  247. return NULL;
  248. }
  249. // Get the unicode versions of the port/device
  250. //
  251. pszPort[0] = L'\0';
  252. pszDevice[0] = L'\0';
  253. if (pDevice->szPortName)
  254. {
  255. StrCpyWFromAUsingAnsiEncoding(
  256. pszPort,
  257. pDevice->szPortName,
  258. strlen(pDevice->szPortName) + 1);
  259. }
  260. if (pDevice->szDeviceName)
  261. {
  262. #if 0
  263. StrCpyWFromAUsingAnsiEncoding(
  264. pszDevice,
  265. pDevice->szDeviceName,
  266. strlen(pDevice->szDeviceName) + 1);
  267. #endif
  268. wcsncpy(
  269. pszDevice,
  270. pDevice->wszDeviceName,
  271. MAX_DEVICE_NAME);
  272. pszDevice[MAX_DEVICE_NAME] = L'\0';
  273. }
  274. // For direct connections, be sure to display the name of the com port
  275. // in addition to the name of the null modem.
  276. if (dwType == INCOMING_TYPE_DIRECT)
  277. {
  278. // Calculate the size
  279. dwSize = wcslen(pszDevice) * sizeof(WCHAR) + // device
  280. wcslen(pszPort) * sizeof(WCHAR) + // com port
  281. wcslen(pszDccFmt) * sizeof(WCHAR) + // oth chars
  282. sizeof(WCHAR); // null
  283. // Allocate the new string
  284. if ((pszReturn = RassrvAlloc (dwSize, FALSE)) == NULL)
  285. {
  286. return pszReturn;
  287. }
  288. wsprintfW(pszReturn, pszDccFmt, pszDevice, pszPort);
  289. }
  290. //
  291. // If it's a modem device with multilple end points (such as isdn)
  292. // display the endpoints in parenthesis
  293. //
  294. else if ((dwType == INCOMING_TYPE_PHONE) &&
  295. (pDevice->dwNumEndPoints > 1))
  296. {
  297. // Calculate the size
  298. dwSize = wcslen(pszDevice) * sizeof(WCHAR) + // device
  299. wcslen(pszMultiFmt) * sizeof(WCHAR) + // channels
  300. 20 * sizeof (WCHAR) + // oth chars
  301. sizeof(WCHAR); // null
  302. // Allocate the new string
  303. if ((pszReturn = RassrvAlloc(dwSize, FALSE)) == NULL)
  304. {
  305. return pszReturn;
  306. }
  307. wsprintfW(
  308. pszReturn,
  309. pszMultiFmt,
  310. pszDevice,
  311. pDevice->dwNumEndPoints);
  312. }
  313. // Otherwise, this is a modem device with one endpoint.
  314. // All that needs to be done here is to copy in the name.
  315. //
  316. else
  317. {
  318. // Calculate the size
  319. dwSize = (wcslen(pszDevice) + 1) * sizeof(WCHAR);
  320. // Allocate the new string
  321. if ((pszReturn = RassrvAlloc(dwSize, FALSE)) == NULL)
  322. {
  323. return pszReturn;
  324. }
  325. wcscpy(pszReturn, pszDevice);
  326. }
  327. return pszReturn;
  328. }
  329. //
  330. // Commits changes to device configuration to the system. The call
  331. // to RasSetDeviceConfigInfo might fail if the device is in the process
  332. // of being configured so we implement a retry
  333. // mechanism here.
  334. //
  335. DWORD
  336. devCommitDeviceInfo(
  337. IN RAS_DEVICE_INFO * pDevice)
  338. {
  339. DWORD dwErr, dwTimeout = 10;
  340. do {
  341. // Try to commit the information
  342. dwErr = RasSetDeviceConfigInfo(
  343. NULL,
  344. 1,
  345. sizeof(RAS_DEVICE_INFO),
  346. (LPBYTE)pDevice);
  347. // If unable to complete, wait and try again
  348. if (dwErr == ERROR_CAN_NOT_COMPLETE)
  349. {
  350. DbgOutputTrace(
  351. "devCommDevInfo: 0x%08x from RasSetDevCfgInfo (try again)",
  352. dwErr);
  353. Sleep(300);
  354. dwTimeout--;
  355. }
  356. // If completed, return no error
  357. else if (dwErr == NO_ERROR)
  358. {
  359. break;
  360. }
  361. // Otherwise, return the error code.
  362. else
  363. {
  364. DbgOutputTrace(
  365. "devCommDevInfo: can't commit %S, 0x%08x",
  366. pDevice->szDeviceName, dwErr);
  367. break;
  368. }
  369. } while (dwTimeout);
  370. return dwErr;
  371. }
  372. //
  373. // Opens a handle to the database of general tab values
  374. //
  375. DWORD
  376. devOpenDatabase(
  377. IN HANDLE * hDevDatabase)
  378. {
  379. RASSRV_DEVICEDB * This;
  380. DWORD dwErr, i;
  381. if (!hDevDatabase)
  382. {
  383. return ERROR_INVALID_PARAMETER;
  384. }
  385. // Allocate the database cache
  386. if ((This = RassrvAlloc(sizeof(RASSRV_DEVICEDB), TRUE)) == NULL)
  387. {
  388. DbgOutputTrace("devOpenDatabase: can't allocate memory -- exiting");
  389. return ERROR_NOT_ENOUGH_MEMORY;
  390. }
  391. // Initialize the values from the system
  392. devReloadDatabase((HANDLE)This);
  393. // Return the handle
  394. *hDevDatabase = (HANDLE)This;
  395. This->bFlushOnClose = FALSE;
  396. return NO_ERROR;
  397. }
  398. //
  399. // Closes the general database and flushes any changes
  400. // to the system when bFlushOnClose is TRUE
  401. //
  402. DWORD
  403. devCloseDatabase(
  404. IN HANDLE hDevDatabase)
  405. {
  406. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  407. DWORD i;
  408. // Flush if requested
  409. if (This->bFlushOnClose)
  410. devFlushDatabase(hDevDatabase);
  411. // Free all of the device names
  412. for (i = 0; i < This->dwDeviceCount; i++)
  413. {
  414. if (This->pDeviceList[i])
  415. {
  416. if (This->pDeviceList[i]->pszName)
  417. {
  418. RassrvFree(This->pDeviceList[i]->pszName);
  419. }
  420. RassrvFree(This->pDeviceList[i]);
  421. }
  422. }
  423. // Free up the device list cache
  424. if (This->pDeviceList)
  425. {
  426. RassrvFree (This->pDeviceList);
  427. }
  428. // Free up the database cache
  429. RassrvFree(This);
  430. return NO_ERROR;
  431. }
  432. //
  433. // Commits the changes made to a particular device
  434. //
  435. DWORD
  436. devCommitDevice (
  437. IN RASSRV_DEVICE * pDevice,
  438. IN RAS_DEVICE_INFO * pDevices,
  439. IN DWORD dwCount)
  440. {
  441. RAS_DEVICE_INFO *pDevInfo = NULL;
  442. devFindDevice(pDevices, dwCount, &pDevInfo, pDevice->dwId);
  443. if (pDevInfo) {
  444. pDevInfo->fWrite = TRUE;
  445. pDevInfo->fRasEnabled = !!(pDevice->dwFlags & DEV_FLAG_ENABLED);
  446. devCommitDeviceInfo(pDevInfo);
  447. }
  448. // Mark the device as not dirty
  449. pDevice->dwFlags &= ~DEV_FLAG_DIRTY;
  450. return NO_ERROR;
  451. }
  452. BOOL
  453. devIsVpnEnableChanged(
  454. IN HANDLE hDevDatabase)
  455. {
  456. RASSRV_DEVICEDB * pDevDb = (RASSRV_DEVICEDB*)hDevDatabase;
  457. if ( pDevDb )
  458. {
  459. return ( pDevDb->bVpnEnabled != pDevDb->bVpnEnabledOrig? TRUE:FALSE );
  460. }
  461. return FALSE;
  462. }//devIsVpnEnableChanged()
  463. //
  464. // Commits any changes made to the general tab values
  465. //
  466. DWORD
  467. devFlushDatabase(
  468. IN HANDLE hDevDatabase)
  469. {
  470. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  471. DWORD dwErr = NO_ERROR, i, dwCount, dwTimeout;
  472. RAS_DEVICE_INFO * pDevices = NULL;
  473. RASSRV_DEVICE * pCur = NULL;
  474. // Validate
  475. if (!This)
  476. {
  477. return ERROR_INVALID_PARAMETER;
  478. }
  479. // Get all of the system device information
  480. dwErr = devGetSystemDeviceInfo(&pDevices, &dwCount);
  481. if (dwErr != NO_ERROR)
  482. {
  483. return dwErr;
  484. }
  485. // Flush all changed settings to the system
  486. for (i = 0; i < This->dwDeviceCount; i++)
  487. {
  488. pCur = This->pDeviceList[i];
  489. // If this device needs to be flushed
  490. if (pCur->dwFlags & DEV_FLAG_DIRTY)
  491. {
  492. // Reset the installed device's enabling if it still
  493. // exists in the system
  494. if ((pCur->dwFlags & DEV_FLAG_DEVICE) ||
  495. (pCur->dwFlags & DEV_FLAG_NULL_MODEM))
  496. {
  497. devCommitDevice(pCur, pDevices, dwCount);
  498. }
  499. // If this is a com port, then we should enable that modem
  500. // installed on the port if it exists or install a null modem
  501. // over it if not.
  502. else if (pCur->dwFlags & DEV_FLAG_PORT)
  503. {
  504. // If this port is associated with an already installed
  505. // null modem, then set the enabling on this modem if
  506. // it is different
  507. if (pCur->pModem != NULL)
  508. {
  509. if ((pCur->dwFlags & DEV_FLAG_ENABLED) !=
  510. (pCur->pModem->dwFlags & DEV_FLAG_ENABLED))
  511. {
  512. devCommitDevice (
  513. pCur->pModem,
  514. pDevices,
  515. dwCount);
  516. }
  517. }
  518. // Otherwise, (if there is no null modem associated with
  519. // this port) install a null modem over this port if
  520. // it is set to enabled.
  521. else if (pCur->dwFlags & DEV_FLAG_ENABLED)
  522. {
  523. dwErr = MdmInstallNullModem (pCur->pszPort);
  524. }
  525. }
  526. }
  527. }
  528. // Flush all of the changed vpn settings
  529. if (This->bVpnEnabled != This->bVpnEnabledOrig)
  530. {
  531. for (i = 0; i < dwCount; i++)
  532. {
  533. if (devIsTunnelDevice(&pDevices[i]))
  534. {
  535. pDevices[i].fWrite = TRUE;
  536. pDevices[i].fRasEnabled = This->bVpnEnabled;
  537. devCommitDeviceInfo(&pDevices[i]);
  538. }
  539. }
  540. This->bVpnEnabledOrig = This->bVpnEnabled;
  541. }
  542. // Cleanup
  543. if (pDevices)
  544. {
  545. devFreeSystemDeviceInfo(pDevices);
  546. }
  547. return dwErr;
  548. }
  549. //
  550. // Rollsback any changes made to the general tab values
  551. //
  552. DWORD
  553. devRollbackDatabase(
  554. IN HANDLE hDevDatabase)
  555. {
  556. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  557. if (This == NULL)
  558. {
  559. return ERROR_INVALID_PARAMETER;
  560. }
  561. This->bFlushOnClose = FALSE;
  562. return NO_ERROR;
  563. }
  564. //
  565. // Reloads the device database
  566. //
  567. DWORD
  568. devReloadDatabase(
  569. IN HANDLE hDevDatabase)
  570. {
  571. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  572. DWORD dwErr = NO_ERROR, i, j = 0, dwSize;
  573. RAS_DEVICE_INFO * pRasDevices;
  574. RASSRV_DEVICE * pTempList, *pDevice;
  575. // Validate
  576. if (!This)
  577. {
  578. return ERROR_INVALID_PARAMETER;
  579. }
  580. // Initialize vpn status
  581. This->bVpnEnabled = FALSE;
  582. // Get the device information from rasman
  583. pRasDevices = NULL;
  584. dwErr = devGetSystemDeviceInfo(&pRasDevices, &This->dwDeviceCount);
  585. if (dwErr != NO_ERROR)
  586. {
  587. return dwErr;
  588. }
  589. do
  590. {
  591. // Initialize the incoming ras capable devices list
  592. if (This->dwDeviceCount)
  593. {
  594. dwSize = sizeof(RASSRV_DEVICE*) * This->dwDeviceCount;
  595. This->pDeviceList = RassrvAlloc(dwSize, TRUE);
  596. if (!This->pDeviceList)
  597. {
  598. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  599. break;
  600. }
  601. // Build the device array accordingly
  602. j = 0;
  603. for (i = 0; i < This->dwDeviceCount; i++)
  604. {
  605. // If it's a physical device, fill in the appropriate
  606. // fields.
  607. if (devIsPhysicalDevice(&pRasDevices[i]))
  608. {
  609. // Allocate the new device
  610. pDevice = RassrvAlloc(sizeof(RASSRV_DEVICE), TRUE);
  611. if (pDevice == NULL)
  612. {
  613. continue;
  614. }
  615. // Assign its values
  616. pDevice->dwType = devDeviceType(&pRasDevices[i]);
  617. pDevice->dwId = pRasDevices[i].dwTapiLineId;
  618. pDevice->pszName = devCopyDeviceName(
  619. &pRasDevices[i],
  620. pDevice->dwType);
  621. pDevice->dwEndpoints = pRasDevices[i].dwNumEndPoints;
  622. pDevice->dwFlags = devInitFlags(&pRasDevices[i]);
  623. StrCpyWFromA(
  624. pDevice->pszPort,
  625. pRasDevices[i].szPortName,
  626. MAX_PORT_NAME + 1);
  627. This->pDeviceList[j] = pDevice;
  628. j++;
  629. }
  630. // If any tunneling protocol is enabled, we consider all
  631. // to be
  632. else if (devIsTunnelDevice(&pRasDevices[i]))
  633. {
  634. This->bVpnEnabled |= pRasDevices[i].fRasEnabled;
  635. This->bVpnEnabledOrig = This->bVpnEnabled;
  636. }
  637. }
  638. // Set the actual size of phyiscal adapters buffer.
  639. This->dwDeviceCount = j;
  640. }
  641. } while (FALSE);
  642. // Cleanup
  643. {
  644. devFreeSystemDeviceInfo(pRasDevices);
  645. }
  646. return dwErr;
  647. }
  648. //
  649. // Filters out all devices in the database except those that
  650. // meet the given type description (can be ||'d).
  651. //
  652. DWORD
  653. devFilterDevices(
  654. IN HANDLE hDevDatabase,
  655. DWORD dwType)
  656. {
  657. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  658. RASSRV_DEVICE * pDevice;
  659. DWORD i;
  660. if (!This)
  661. {
  662. return ERROR_INVALID_PARAMETER;
  663. }
  664. // Go through the list of marking out devices to be filtered
  665. for (i = 0; i < This->dwDeviceCount; i++)
  666. {
  667. pDevice = This->pDeviceList[i];
  668. if (pDevice == NULL)
  669. {
  670. continue;
  671. }
  672. if (pDevice->dwType & dwType)
  673. {
  674. pDevice->dwFlags &= ~DEV_FLAG_FILTERED;
  675. }
  676. else
  677. {
  678. pDevice->dwFlags |= DEV_FLAG_FILTERED;
  679. }
  680. }
  681. return NO_ERROR;
  682. }
  683. //
  684. // Device enumeration function. Returns TRUE to stop enumeration,
  685. // FALSE to continue.
  686. //
  687. BOOL devAddPortToList (
  688. IN PWCHAR pszPort,
  689. IN HANDLE hData)
  690. {
  691. RASSRV_PORT_LIST * pList = (RASSRV_PORT_LIST*)hData;
  692. RASSRV_PORT_NODE * pNode = NULL;
  693. DWORD dwSize;
  694. // Create the new node
  695. pNode = (RASSRV_PORT_NODE *) RassrvAlloc(sizeof(RASSRV_PORT_NODE), TRUE);
  696. if (pNode == NULL)
  697. {
  698. return FALSE;
  699. }
  700. // Add it to the head
  701. pNode->pNext = pList->pHead;
  702. pList->pHead = pNode;
  703. pList->dwCount++;
  704. // Add the names of the port
  705. if (pszPort)
  706. {
  707. dwSize = (wcslen(pszPort) + pList->dwFmtLen + 1) * sizeof(WCHAR);
  708. pNode->pszName = (PWCHAR) RassrvAlloc (dwSize, FALSE);
  709. if (pNode->pszName == NULL)
  710. {
  711. return TRUE;
  712. }
  713. wsprintfW (pNode->pszName, pList->pszFormat, pszPort);
  714. lstrcpynW(pNode->pszPort, pszPort, sizeof(pNode->pszPort) / sizeof(WCHAR));
  715. }
  716. return FALSE;
  717. }
  718. //
  719. // Cleans up the resources used in a device list
  720. //
  721. DWORD
  722. devCleanupPortList(
  723. IN RASSRV_PORT_LIST * pList)
  724. {
  725. RASSRV_PORT_NODE * pCur = NULL, * pNext = NULL;
  726. pCur = pList->pHead;
  727. while (pCur)
  728. {
  729. pNext = pCur->pNext;
  730. RassrvFree(pCur);
  731. pCur = pNext;
  732. }
  733. return NO_ERROR;
  734. }
  735. //
  736. // Removes all ports from the list for which there are already
  737. // devices installed in the database.
  738. //
  739. DWORD devFilterPortsInUse (
  740. IN RASSRV_DEVICEDB *This,
  741. RASSRV_PORT_LIST *pList)
  742. {
  743. RASSRV_PORT_LIST PortList, *pDelete = &PortList;
  744. RASSRV_PORT_NODE * pCur = NULL, * pPrev = NULL;
  745. RASSRV_DEVICE * pDevice;
  746. DWORD i;
  747. BOOL bDone;
  748. INT iCmp;
  749. // If the list is empty, return
  750. if (pList->dwCount == 0)
  751. {
  752. return NO_ERROR;
  753. }
  754. // Initailize
  755. ZeroMemory(pDelete, sizeof(RASSRV_PORT_LIST));
  756. // Compare all of the enumerated ports to the ports
  757. // in use in the device list.
  758. for (i = 0; i < This->dwDeviceCount; i++)
  759. {
  760. // Point to the current device
  761. pDevice = This->pDeviceList[i];
  762. // Initialize the current and previous and break if the
  763. // list is now empty
  764. pCur = pList->pHead;
  765. if (pCur == NULL)
  766. {
  767. break;
  768. }
  769. // Remove the head node until it doesn't match
  770. bDone = FALSE;
  771. while ((pList->pHead != NULL) && (bDone == FALSE))
  772. {
  773. iCmp = lstrcmpi (pDevice->pszPort,
  774. pList->pHead->pszPort);
  775. // If a device is already using this com port
  776. // then remove the com port from the list since it
  777. // isn't available
  778. if ((pDevice->dwFlags & DEV_FLAG_DEVICE) && (iCmp == 0))
  779. {
  780. pCur = pList->pHead->pNext;
  781. RassrvFree(pList->pHead);
  782. pList->pHead = pCur;
  783. pList->dwCount -= 1;
  784. }
  785. else
  786. {
  787. // If the device is a null modem, then we filter
  788. // it out of the list of available devices and we
  789. // reference it in the com port so that we can
  790. // enable/disable it later if we need to.
  791. if (iCmp == 0)
  792. {
  793. pDevice->dwFlags |= DEV_FLAG_FILTERED;
  794. pList->pHead->pModem = pDevice;
  795. }
  796. bDone = TRUE;
  797. }
  798. }
  799. // If we've elimated everyone, return
  800. if (pList->dwCount == 0)
  801. {
  802. return NO_ERROR;
  803. }
  804. // Loop through all of the past the head removing those
  805. // that are in use by the current ras device.
  806. pPrev = pList->pHead;
  807. pCur = pPrev->pNext;
  808. while (pCur)
  809. {
  810. iCmp = lstrcmpi (pDevice->pszPort,
  811. pCur->pszPort);
  812. // If a device is already using this com port
  813. // that remove the com port from the list since it
  814. // isn't available
  815. if ((pDevice->dwFlags & DEV_FLAG_DEVICE) && (iCmp == 0))
  816. {
  817. pPrev->pNext = pCur->pNext;
  818. RassrvFree(pCur);
  819. pCur = pPrev->pNext;
  820. pList->dwCount -= 1;
  821. }
  822. else
  823. {
  824. // If the device is a null modem, then we filter
  825. // it out of the list of available devices and we
  826. // reference it in the com port so that we can
  827. // enable/disable it later if we need to.
  828. if (iCmp == 0)
  829. {
  830. pDevice->dwFlags |= DEV_FLAG_FILTERED;
  831. pCur->pModem = pDevice;
  832. }
  833. pCur = pCur->pNext;
  834. pPrev = pPrev->pNext;
  835. }
  836. }
  837. }
  838. return NO_ERROR;
  839. }
  840. //
  841. // Adds com ports as uninstalled devices in the device database
  842. //
  843. DWORD
  844. devAddComPorts(
  845. IN HANDLE hDevDatabase)
  846. {
  847. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  848. RASSRV_PORT_LIST PortList, *pList = &PortList;
  849. RASSRV_PORT_NODE * pNode = NULL;
  850. RASSRV_DEVICE ** ppDevices;
  851. DWORD dwErr = NO_ERROR, i;
  852. if (!This)
  853. {
  854. return ERROR_INVALID_PARAMETER;
  855. }
  856. // Initialize the port list
  857. //
  858. ZeroMemory (pList, sizeof(RASSRV_PORT_LIST));
  859. pList->dwFmtLen = LoadStringW (
  860. Globals.hInstDll,
  861. SID_COMPORT_FORMAT,
  862. pList->pszFormat,
  863. sizeof(pList->pszFormat) / sizeof(WCHAR));
  864. do
  865. {
  866. // Create the list of com ports
  867. dwErr = MdmEnumComPorts(devAddPortToList, (HANDLE)pList);
  868. if (dwErr != NO_ERROR)
  869. {
  870. break;
  871. }
  872. // Remove any ports that are currently in use
  873. if ((dwErr = devFilterPortsInUse (This, pList)) != NO_ERROR)
  874. {
  875. break;
  876. }
  877. // If there aren't any ports, return
  878. if (pList->dwCount == 0)
  879. {
  880. break;
  881. }
  882. // Resize the list of ports to include the com ports
  883. ppDevices = RassrvAlloc(
  884. sizeof(RASSRV_DEVICE*) *
  885. (This->dwDeviceCount + pList->dwCount),
  886. TRUE);
  887. if (ppDevices == NULL)
  888. {
  889. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  890. break;
  891. }
  892. // Copy over the current device information
  893. CopyMemory(
  894. ppDevices,
  895. This->pDeviceList,
  896. This->dwDeviceCount * sizeof(RASSRV_DEVICE*));
  897. // Delete the old device list and set to the new one
  898. RassrvFree(This->pDeviceList);
  899. This->pDeviceList = ppDevices;
  900. // Add the ports
  901. pNode = pList->pHead;
  902. i = This->dwDeviceCount;
  903. while (pNode)
  904. {
  905. // Allocate the new device
  906. ppDevices[i] = RassrvAlloc(sizeof(RASSRV_DEVICE), TRUE);
  907. if (!ppDevices[i])
  908. {
  909. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  910. break;
  911. }
  912. // Set all the non-zero values
  913. ppDevices[i]->dwType = INCOMING_TYPE_DIRECT;
  914. ppDevices[i]->pszName = pNode->pszName;
  915. ppDevices[i]->pModem = pNode->pModem;
  916. ppDevices[i]->dwFlags = DEV_FLAG_PORT;
  917. lstrcpynW(
  918. ppDevices[i]->pszPort,
  919. pNode->pszPort,
  920. sizeof(ppDevices[i]->pszPort) / sizeof(WCHAR));
  921. // Initialize the enabling of the com port
  922. if (ppDevices[i]->pModem)
  923. {
  924. ppDevices[i]->dwFlags |=
  925. (ppDevices[i]->pModem->dwFlags & DEV_FLAG_ENABLED);
  926. }
  927. // Increment
  928. i++;
  929. pNode = pNode->pNext;
  930. }
  931. This->dwDeviceCount = i;
  932. } while (FALSE);
  933. // Cleanup
  934. {
  935. devCleanupPortList(pList);
  936. }
  937. return dwErr;
  938. }
  939. //
  940. // Returns whether the given index lies within the bounds of the
  941. // list of devices store in This.
  942. //
  943. BOOL
  944. devBoundsCheck(
  945. IN RASSRV_DEVICEDB * This,
  946. IN DWORD dwIndex)
  947. {
  948. if (This->dwDeviceCount <= dwIndex)
  949. {
  950. DbgOutputTrace("devBoundsCheck: failed for index %d", dwIndex);
  951. return FALSE;
  952. }
  953. return TRUE;
  954. }
  955. // Gets a handle to a device to be displayed in the general tab
  956. DWORD devGetDeviceHandle(
  957. IN HANDLE hDevDatabase,
  958. IN DWORD dwIndex,
  959. OUT HANDLE * hDevice)
  960. {
  961. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  962. if (!This || !hDevice)
  963. {
  964. return ERROR_INVALID_PARAMETER;
  965. }
  966. if (!devBoundsCheck(This, dwIndex))
  967. {
  968. return ERROR_INVALID_INDEX;
  969. }
  970. // Return nothing if device is filtered
  971. if (This->pDeviceList[dwIndex]->dwFlags & DEV_FLAG_FILTERED)
  972. {
  973. *hDevice = NULL;
  974. return ERROR_DEVICE_NOT_AVAILABLE;
  975. }
  976. // Otherwise, return the device
  977. else
  978. {
  979. *hDevice = (HANDLE)(This->pDeviceList[dwIndex]);
  980. }
  981. return NO_ERROR;
  982. }
  983. //
  984. // Returns a count of devices to be displayed in the general tab
  985. //
  986. DWORD devGetDeviceCount(
  987. IN HANDLE hDevDatabase,
  988. OUT LPDWORD lpdwCount)
  989. {
  990. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  991. if (!This || !lpdwCount)
  992. {
  993. return ERROR_INVALID_PARAMETER;
  994. }
  995. *lpdwCount = This->dwDeviceCount;
  996. return NO_ERROR;
  997. }
  998. //
  999. // Returns the count of enabled devices
  1000. //
  1001. DWORD devGetEndpointEnableCount(
  1002. IN HANDLE hDevDatabase,
  1003. OUT LPDWORD lpdwCount)
  1004. {
  1005. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  1006. DWORD i;
  1007. if (!This || !lpdwCount)
  1008. {
  1009. return ERROR_INVALID_PARAMETER;
  1010. }
  1011. *lpdwCount = 0;
  1012. for (i = 0; i < This->dwDeviceCount; i++)
  1013. {
  1014. if (This->pDeviceList[i]->dwFlags & DEV_FLAG_ENABLED)
  1015. {
  1016. (*lpdwCount) += This->pDeviceList[i]->dwEndpoints;
  1017. }
  1018. }
  1019. return NO_ERROR;
  1020. }
  1021. //
  1022. // Loads the vpn enable status
  1023. //
  1024. DWORD
  1025. devGetVpnEnable(
  1026. IN HANDLE hDevDatabase,
  1027. IN BOOL * pbEnabled)
  1028. {
  1029. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  1030. if (!This || !pbEnabled)
  1031. {
  1032. return ERROR_INVALID_PARAMETER;
  1033. }
  1034. *pbEnabled = This->bVpnEnabled;
  1035. return NO_ERROR;
  1036. }
  1037. //
  1038. // Saves the vpn enable status
  1039. //
  1040. DWORD
  1041. devSetVpnEnable(
  1042. IN HANDLE hDevDatabase,
  1043. IN BOOL bEnable)
  1044. {
  1045. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  1046. if (!This)
  1047. {
  1048. return ERROR_INVALID_PARAMETER;
  1049. }
  1050. This->bVpnEnabled = bEnable;
  1051. return NO_ERROR;
  1052. }
  1053. // Saves the vpn Original value enable status
  1054. //
  1055. DWORD
  1056. devSetVpnOrigEnable(
  1057. IN HANDLE hDevDatabase,
  1058. IN BOOL bEnable)
  1059. {
  1060. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  1061. if (!This)
  1062. {
  1063. return ERROR_INVALID_PARAMETER;
  1064. }
  1065. This->bVpnEnabledOrig = bEnable;
  1066. return NO_ERROR;
  1067. }
  1068. //
  1069. // Returns a pointer to the name of a device
  1070. //
  1071. DWORD
  1072. devGetDeviceName(
  1073. IN HANDLE hDevice,
  1074. OUT PWCHAR * pszDeviceName)
  1075. {
  1076. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1077. if (!This || !pszDeviceName)
  1078. {
  1079. return ERROR_INVALID_PARAMETER;
  1080. }
  1081. *pszDeviceName = This->pszName;
  1082. return NO_ERROR;
  1083. }
  1084. //
  1085. // Returns the type of a device
  1086. //
  1087. DWORD
  1088. devGetDeviceType(
  1089. IN HANDLE hDevice,
  1090. OUT LPDWORD lpdwType)
  1091. {
  1092. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1093. if (!This || !lpdwType)
  1094. {
  1095. return ERROR_INVALID_PARAMETER;
  1096. }
  1097. *lpdwType = This->dwType;
  1098. return NO_ERROR;
  1099. }
  1100. //
  1101. // Returns an identifier of the device that can be used in
  1102. // tapi calls.
  1103. //
  1104. DWORD
  1105. devGetDeviceId(
  1106. IN HANDLE hDevice,
  1107. OUT LPDWORD lpdwId)
  1108. {
  1109. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1110. if (!This || !lpdwId)
  1111. {
  1112. return ERROR_INVALID_PARAMETER;
  1113. }
  1114. *lpdwId = This->dwId;
  1115. //
  1116. // If this is a com port referencing a null modem,
  1117. // then return the tapi id of the null modem
  1118. //
  1119. if ((This->dwFlags & DEV_FLAG_PORT) && (This->pModem))
  1120. {
  1121. *lpdwId = This->pModem->dwId;
  1122. }
  1123. return NO_ERROR;
  1124. }
  1125. //
  1126. // Returns the enable status of a device for dialin
  1127. //
  1128. DWORD
  1129. devGetDeviceEnable(
  1130. IN HANDLE hDevice,
  1131. OUT BOOL * pbEnabled)
  1132. {
  1133. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1134. if (!This || !pbEnabled)
  1135. {
  1136. return ERROR_INVALID_PARAMETER;
  1137. }
  1138. *pbEnabled = !!(This->dwFlags & DEV_FLAG_ENABLED);
  1139. return NO_ERROR;
  1140. }
  1141. //
  1142. // Sets the enable status of a device for dialin
  1143. //
  1144. DWORD
  1145. devSetDeviceEnable(
  1146. IN HANDLE hDevice,
  1147. IN BOOL bEnable)
  1148. {
  1149. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1150. if (!This)
  1151. {
  1152. return ERROR_INVALID_PARAMETER;
  1153. }
  1154. // Mark the enabling and mark the device as dirty
  1155. if (bEnable)
  1156. {
  1157. This->dwFlags |= DEV_FLAG_ENABLED;
  1158. }
  1159. else
  1160. {
  1161. This->dwFlags &= ~DEV_FLAG_ENABLED;
  1162. }
  1163. This->dwFlags |= DEV_FLAG_DIRTY;
  1164. return NO_ERROR;
  1165. }
  1166. //
  1167. // Returns whether the given device is a com port as added
  1168. // by devAddComPorts
  1169. //
  1170. DWORD
  1171. devDeviceIsComPort(
  1172. IN HANDLE hDevice,
  1173. OUT PBOOL pbIsComPort)
  1174. {
  1175. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1176. if (!This)
  1177. {
  1178. return ERROR_INVALID_PARAMETER;
  1179. }
  1180. // This is a com port if it was added by
  1181. // devAddComPorts and if it has no null
  1182. // modem associated with it.
  1183. //
  1184. if ((This->dwFlags & DEV_FLAG_PORT) &&
  1185. (This->pModem == NULL)
  1186. )
  1187. {
  1188. *pbIsComPort = TRUE;
  1189. }
  1190. else
  1191. {
  1192. *pbIsComPort = FALSE;
  1193. }
  1194. return NO_ERROR;
  1195. }