Leaked source code of windows server 2003
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.

1396 lines
35 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. // For whistler bug 499405 gangz
  513. // devCommitDevice just flush out the device info as it
  514. // is, so we have to change pCur->pModem->dwFlags
  515. //
  516. if( pCur->dwFlags & DEV_FLAG_ENABLED )
  517. {
  518. pCur->pModem->dwFlags |= DEV_FLAG_ENABLED;
  519. }
  520. else
  521. {
  522. pCur->pModem->dwFlags &= ~DEV_FLAG_ENABLED;
  523. }
  524. devCommitDevice (
  525. pCur->pModem,
  526. pDevices,
  527. dwCount);
  528. }
  529. }
  530. // Otherwise, (if there is no null modem associated with
  531. // this port) install a null modem over this port if
  532. // it is set to enabled.
  533. else if (pCur->dwFlags & DEV_FLAG_ENABLED)
  534. {
  535. dwErr = MdmInstallNullModem (pCur->pszPort);
  536. }
  537. }
  538. }
  539. }
  540. // Flush all of the changed vpn settings
  541. if (This->bVpnEnabled != This->bVpnEnabledOrig)
  542. {
  543. for (i = 0; i < dwCount; i++)
  544. {
  545. if (devIsTunnelDevice(&pDevices[i]))
  546. {
  547. pDevices[i].fWrite = TRUE;
  548. pDevices[i].fRasEnabled = This->bVpnEnabled;
  549. devCommitDeviceInfo(&pDevices[i]);
  550. }
  551. }
  552. This->bVpnEnabledOrig = This->bVpnEnabled;
  553. }
  554. // Cleanup
  555. if (pDevices)
  556. {
  557. devFreeSystemDeviceInfo(pDevices);
  558. }
  559. return dwErr;
  560. }
  561. //
  562. // Rollsback any changes made to the general tab values
  563. //
  564. DWORD
  565. devRollbackDatabase(
  566. IN HANDLE hDevDatabase)
  567. {
  568. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  569. if (This == NULL)
  570. {
  571. return ERROR_INVALID_PARAMETER;
  572. }
  573. This->bFlushOnClose = FALSE;
  574. return NO_ERROR;
  575. }
  576. //
  577. // Reloads the device database
  578. //
  579. DWORD
  580. devReloadDatabase(
  581. IN HANDLE hDevDatabase)
  582. {
  583. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  584. DWORD dwErr = NO_ERROR, i, j = 0, dwSize;
  585. RAS_DEVICE_INFO * pRasDevices;
  586. RASSRV_DEVICE * pTempList, *pDevice;
  587. // Validate
  588. if (!This)
  589. {
  590. return ERROR_INVALID_PARAMETER;
  591. }
  592. // Initialize vpn status
  593. This->bVpnEnabled = FALSE;
  594. // Get the device information from rasman
  595. pRasDevices = NULL;
  596. dwErr = devGetSystemDeviceInfo(&pRasDevices, &This->dwDeviceCount);
  597. if (dwErr != NO_ERROR)
  598. {
  599. return dwErr;
  600. }
  601. do
  602. {
  603. // Initialize the incoming ras capable devices list
  604. if (This->dwDeviceCount)
  605. {
  606. dwSize = sizeof(RASSRV_DEVICE*) * This->dwDeviceCount;
  607. This->pDeviceList = RassrvAlloc(dwSize, TRUE);
  608. if (!This->pDeviceList)
  609. {
  610. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  611. break;
  612. }
  613. // Build the device array accordingly
  614. j = 0;
  615. for (i = 0; i < This->dwDeviceCount; i++)
  616. {
  617. // If it's a physical device, fill in the appropriate
  618. // fields.
  619. if (devIsPhysicalDevice(&pRasDevices[i]))
  620. {
  621. // Allocate the new device
  622. pDevice = RassrvAlloc(sizeof(RASSRV_DEVICE), TRUE);
  623. if (pDevice == NULL)
  624. {
  625. continue;
  626. }
  627. // Assign its values
  628. pDevice->dwType = devDeviceType(&pRasDevices[i]);
  629. pDevice->dwId = pRasDevices[i].dwTapiLineId;
  630. pDevice->pszName = devCopyDeviceName(
  631. &pRasDevices[i],
  632. pDevice->dwType);
  633. pDevice->dwEndpoints = pRasDevices[i].dwNumEndPoints;
  634. pDevice->dwFlags = devInitFlags(&pRasDevices[i]);
  635. StrCpyWFromA(
  636. pDevice->pszPort,
  637. pRasDevices[i].szPortName,
  638. MAX_PORT_NAME + 1);
  639. This->pDeviceList[j] = pDevice;
  640. j++;
  641. }
  642. // If any tunneling protocol is enabled, we consider all
  643. // to be
  644. else if (devIsTunnelDevice(&pRasDevices[i]))
  645. {
  646. This->bVpnEnabled |= pRasDevices[i].fRasEnabled;
  647. This->bVpnEnabledOrig = This->bVpnEnabled;
  648. }
  649. }
  650. // Set the actual size of phyiscal adapters buffer.
  651. This->dwDeviceCount = j;
  652. }
  653. } while (FALSE);
  654. // Cleanup
  655. {
  656. devFreeSystemDeviceInfo(pRasDevices);
  657. }
  658. return dwErr;
  659. }
  660. //
  661. // Filters out all devices in the database except those that
  662. // meet the given type description (can be ||'d).
  663. //
  664. DWORD
  665. devFilterDevices(
  666. IN HANDLE hDevDatabase,
  667. DWORD dwType)
  668. {
  669. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  670. RASSRV_DEVICE * pDevice;
  671. DWORD i;
  672. if (!This)
  673. {
  674. return ERROR_INVALID_PARAMETER;
  675. }
  676. // Go through the list of marking out devices to be filtered
  677. for (i = 0; i < This->dwDeviceCount; i++)
  678. {
  679. pDevice = This->pDeviceList[i];
  680. if (pDevice == NULL)
  681. {
  682. continue;
  683. }
  684. if (pDevice->dwType & dwType)
  685. {
  686. pDevice->dwFlags &= ~DEV_FLAG_FILTERED;
  687. }
  688. else
  689. {
  690. pDevice->dwFlags |= DEV_FLAG_FILTERED;
  691. }
  692. }
  693. return NO_ERROR;
  694. }
  695. //
  696. // Device enumeration function. Returns TRUE to stop enumeration,
  697. // FALSE to continue.
  698. //
  699. BOOL devAddPortToList (
  700. IN PWCHAR pszPort,
  701. IN HANDLE hData)
  702. {
  703. RASSRV_PORT_LIST * pList = (RASSRV_PORT_LIST*)hData;
  704. RASSRV_PORT_NODE * pNode = NULL;
  705. DWORD dwSize;
  706. // Create the new node
  707. pNode = (RASSRV_PORT_NODE *) RassrvAlloc(sizeof(RASSRV_PORT_NODE), TRUE);
  708. if (pNode == NULL)
  709. {
  710. return FALSE;
  711. }
  712. // Add it to the head
  713. pNode->pNext = pList->pHead;
  714. pList->pHead = pNode;
  715. pList->dwCount++;
  716. // Add the names of the port
  717. if (pszPort)
  718. {
  719. dwSize = (wcslen(pszPort) + pList->dwFmtLen + 1) * sizeof(WCHAR);
  720. pNode->pszName = (PWCHAR) RassrvAlloc (dwSize, FALSE);
  721. if (pNode->pszName == NULL)
  722. {
  723. return TRUE;
  724. }
  725. wsprintfW (pNode->pszName, pList->pszFormat, pszPort);
  726. lstrcpynW(pNode->pszPort, pszPort, sizeof(pNode->pszPort) / sizeof(WCHAR));
  727. }
  728. return FALSE;
  729. }
  730. //
  731. // Cleans up the resources used in a device list
  732. //
  733. DWORD
  734. devCleanupPortList(
  735. IN RASSRV_PORT_LIST * pList)
  736. {
  737. RASSRV_PORT_NODE * pCur = NULL, * pNext = NULL;
  738. pCur = pList->pHead;
  739. while (pCur)
  740. {
  741. pNext = pCur->pNext;
  742. RassrvFree(pCur);
  743. pCur = pNext;
  744. }
  745. return NO_ERROR;
  746. }
  747. //
  748. // Removes all ports from the list for which there are already
  749. // devices installed in the database.
  750. //
  751. DWORD devFilterPortsInUse (
  752. IN RASSRV_DEVICEDB *This,
  753. RASSRV_PORT_LIST *pList)
  754. {
  755. RASSRV_PORT_LIST PortList, *pDelete = &PortList;
  756. RASSRV_PORT_NODE * pCur = NULL, * pPrev = NULL;
  757. RASSRV_DEVICE * pDevice;
  758. DWORD i;
  759. BOOL bDone;
  760. INT iCmp;
  761. // If the list is empty, return
  762. if (pList->dwCount == 0)
  763. {
  764. return NO_ERROR;
  765. }
  766. // Initailize
  767. ZeroMemory(pDelete, sizeof(RASSRV_PORT_LIST));
  768. // Compare all of the enumerated ports to the ports
  769. // in use in the device list.
  770. for (i = 0; i < This->dwDeviceCount; i++)
  771. {
  772. // Point to the current device
  773. pDevice = This->pDeviceList[i];
  774. // Initialize the current and previous and break if the
  775. // list is now empty
  776. pCur = pList->pHead;
  777. if (pCur == NULL)
  778. {
  779. break;
  780. }
  781. // Remove the head node until it doesn't match
  782. bDone = FALSE;
  783. while ((pList->pHead != NULL) && (bDone == FALSE))
  784. {
  785. iCmp = lstrcmpi (pDevice->pszPort,
  786. pList->pHead->pszPort);
  787. // If a device is already using this com port
  788. // then remove the com port from the list since it
  789. // isn't available
  790. if ((pDevice->dwFlags & DEV_FLAG_DEVICE) && (iCmp == 0))
  791. {
  792. pCur = pList->pHead->pNext;
  793. RassrvFree(pList->pHead);
  794. pList->pHead = pCur;
  795. pList->dwCount -= 1;
  796. }
  797. else
  798. {
  799. // If the device is a null modem, then we filter
  800. // it out of the list of available devices and we
  801. // reference it in the com port so that we can
  802. // enable/disable it later if we need to.
  803. if (iCmp == 0)
  804. {
  805. pDevice->dwFlags |= DEV_FLAG_FILTERED;
  806. pList->pHead->pModem = pDevice;
  807. }
  808. bDone = TRUE;
  809. }
  810. }
  811. // If we've elimated everyone, return
  812. if (pList->dwCount == 0)
  813. {
  814. return NO_ERROR;
  815. }
  816. // Loop through all of the past the head removing those
  817. // that are in use by the current ras device.
  818. pPrev = pList->pHead;
  819. pCur = pPrev->pNext;
  820. while (pCur)
  821. {
  822. iCmp = lstrcmpi (pDevice->pszPort,
  823. pCur->pszPort);
  824. // If a device is already using this com port
  825. // that remove the com port from the list since it
  826. // isn't available
  827. if ((pDevice->dwFlags & DEV_FLAG_DEVICE) && (iCmp == 0))
  828. {
  829. pPrev->pNext = pCur->pNext;
  830. RassrvFree(pCur);
  831. pCur = pPrev->pNext;
  832. pList->dwCount -= 1;
  833. }
  834. else
  835. {
  836. // If the device is a null modem, then we filter
  837. // it out of the list of available devices and we
  838. // reference it in the com port so that we can
  839. // enable/disable it later if we need to.
  840. if (iCmp == 0)
  841. {
  842. pDevice->dwFlags |= DEV_FLAG_FILTERED;
  843. pCur->pModem = pDevice;
  844. }
  845. pCur = pCur->pNext;
  846. pPrev = pPrev->pNext;
  847. }
  848. }
  849. }
  850. return NO_ERROR;
  851. }
  852. //
  853. // Adds com ports as uninstalled devices in the device database
  854. //
  855. DWORD
  856. devAddComPorts(
  857. IN HANDLE hDevDatabase)
  858. {
  859. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  860. RASSRV_PORT_LIST PortList, *pList = &PortList;
  861. RASSRV_PORT_NODE * pNode = NULL;
  862. RASSRV_DEVICE ** ppDevices;
  863. DWORD dwErr = NO_ERROR, i;
  864. if (!This)
  865. {
  866. return ERROR_INVALID_PARAMETER;
  867. }
  868. // Initialize the port list
  869. //
  870. ZeroMemory (pList, sizeof(RASSRV_PORT_LIST));
  871. pList->dwFmtLen = LoadStringW (
  872. Globals.hInstDll,
  873. SID_COMPORT_FORMAT,
  874. pList->pszFormat,
  875. sizeof(pList->pszFormat) / sizeof(WCHAR));
  876. do
  877. {
  878. // Create the list of com ports
  879. dwErr = MdmEnumComPorts(devAddPortToList, (HANDLE)pList);
  880. if (dwErr != NO_ERROR)
  881. {
  882. break;
  883. }
  884. // Remove any ports that are currently in use
  885. if ((dwErr = devFilterPortsInUse (This, pList)) != NO_ERROR)
  886. {
  887. break;
  888. }
  889. // If there aren't any ports, return
  890. if (pList->dwCount == 0)
  891. {
  892. break;
  893. }
  894. // Resize the list of ports to include the com ports
  895. ppDevices = RassrvAlloc(
  896. sizeof(RASSRV_DEVICE*) *
  897. (This->dwDeviceCount + pList->dwCount),
  898. TRUE);
  899. if (ppDevices == NULL)
  900. {
  901. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  902. break;
  903. }
  904. // Copy over the current device information
  905. CopyMemory(
  906. ppDevices,
  907. This->pDeviceList,
  908. This->dwDeviceCount * sizeof(RASSRV_DEVICE*));
  909. // Delete the old device list and set to the new one
  910. RassrvFree(This->pDeviceList);
  911. This->pDeviceList = ppDevices;
  912. // Add the ports
  913. pNode = pList->pHead;
  914. i = This->dwDeviceCount;
  915. while (pNode)
  916. {
  917. // Allocate the new device
  918. ppDevices[i] = RassrvAlloc(sizeof(RASSRV_DEVICE), TRUE);
  919. if (!ppDevices[i])
  920. {
  921. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  922. break;
  923. }
  924. // Set all the non-zero values
  925. ppDevices[i]->dwType = INCOMING_TYPE_DIRECT;
  926. ppDevices[i]->pszName = pNode->pszName;
  927. ppDevices[i]->pModem = pNode->pModem;
  928. ppDevices[i]->dwFlags = DEV_FLAG_PORT;
  929. lstrcpynW(
  930. ppDevices[i]->pszPort,
  931. pNode->pszPort,
  932. sizeof(ppDevices[i]->pszPort) / sizeof(WCHAR));
  933. // Initialize the enabling of the com port
  934. if (ppDevices[i]->pModem)
  935. {
  936. ppDevices[i]->dwFlags |=
  937. (ppDevices[i]->pModem->dwFlags & DEV_FLAG_ENABLED);
  938. }
  939. // Increment
  940. i++;
  941. pNode = pNode->pNext;
  942. }
  943. This->dwDeviceCount = i;
  944. } while (FALSE);
  945. // Cleanup
  946. {
  947. devCleanupPortList(pList);
  948. }
  949. return dwErr;
  950. }
  951. //
  952. // Returns whether the given index lies within the bounds of the
  953. // list of devices store in This.
  954. //
  955. BOOL
  956. devBoundsCheck(
  957. IN RASSRV_DEVICEDB * This,
  958. IN DWORD dwIndex)
  959. {
  960. if (This->dwDeviceCount <= dwIndex)
  961. {
  962. DbgOutputTrace("devBoundsCheck: failed for index %d", dwIndex);
  963. return FALSE;
  964. }
  965. return TRUE;
  966. }
  967. // Gets a handle to a device to be displayed in the general tab
  968. DWORD devGetDeviceHandle(
  969. IN HANDLE hDevDatabase,
  970. IN DWORD dwIndex,
  971. OUT HANDLE * hDevice)
  972. {
  973. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  974. if (!This || !hDevice)
  975. {
  976. return ERROR_INVALID_PARAMETER;
  977. }
  978. if (!devBoundsCheck(This, dwIndex))
  979. {
  980. return ERROR_INVALID_INDEX;
  981. }
  982. // Return nothing if device is filtered
  983. if (This->pDeviceList[dwIndex]->dwFlags & DEV_FLAG_FILTERED)
  984. {
  985. *hDevice = NULL;
  986. return ERROR_DEVICE_NOT_AVAILABLE;
  987. }
  988. // Otherwise, return the device
  989. else
  990. {
  991. *hDevice = (HANDLE)(This->pDeviceList[dwIndex]);
  992. }
  993. return NO_ERROR;
  994. }
  995. //
  996. // Returns a count of devices to be displayed in the general tab
  997. //
  998. DWORD devGetDeviceCount(
  999. IN HANDLE hDevDatabase,
  1000. OUT LPDWORD lpdwCount)
  1001. {
  1002. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  1003. if (!This || !lpdwCount)
  1004. {
  1005. return ERROR_INVALID_PARAMETER;
  1006. }
  1007. *lpdwCount = This->dwDeviceCount;
  1008. return NO_ERROR;
  1009. }
  1010. //
  1011. // Returns the count of enabled devices
  1012. //
  1013. DWORD devGetEndpointEnableCount(
  1014. IN HANDLE hDevDatabase,
  1015. OUT LPDWORD lpdwCount)
  1016. {
  1017. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  1018. DWORD i;
  1019. if (!This || !lpdwCount)
  1020. {
  1021. return ERROR_INVALID_PARAMETER;
  1022. }
  1023. *lpdwCount = 0;
  1024. for (i = 0; i < This->dwDeviceCount; i++)
  1025. {
  1026. if (This->pDeviceList[i]->dwFlags & DEV_FLAG_ENABLED)
  1027. {
  1028. (*lpdwCount) += This->pDeviceList[i]->dwEndpoints;
  1029. }
  1030. }
  1031. return NO_ERROR;
  1032. }
  1033. //
  1034. // Loads the vpn enable status
  1035. //
  1036. DWORD
  1037. devGetVpnEnable(
  1038. IN HANDLE hDevDatabase,
  1039. IN BOOL * pbEnabled)
  1040. {
  1041. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  1042. if (!This || !pbEnabled)
  1043. {
  1044. return ERROR_INVALID_PARAMETER;
  1045. }
  1046. *pbEnabled = This->bVpnEnabled;
  1047. return NO_ERROR;
  1048. }
  1049. //
  1050. // Saves the vpn enable status
  1051. //
  1052. DWORD
  1053. devSetVpnEnable(
  1054. IN HANDLE hDevDatabase,
  1055. IN BOOL bEnable)
  1056. {
  1057. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  1058. if (!This)
  1059. {
  1060. return ERROR_INVALID_PARAMETER;
  1061. }
  1062. This->bVpnEnabled = bEnable;
  1063. return NO_ERROR;
  1064. }
  1065. // Saves the vpn Original value enable status
  1066. //
  1067. DWORD
  1068. devSetVpnOrigEnable(
  1069. IN HANDLE hDevDatabase,
  1070. IN BOOL bEnable)
  1071. {
  1072. RASSRV_DEVICEDB * This = (RASSRV_DEVICEDB*)hDevDatabase;
  1073. if (!This)
  1074. {
  1075. return ERROR_INVALID_PARAMETER;
  1076. }
  1077. This->bVpnEnabledOrig = bEnable;
  1078. return NO_ERROR;
  1079. }
  1080. //
  1081. // Returns a pointer to the name of a device
  1082. //
  1083. DWORD
  1084. devGetDeviceName(
  1085. IN HANDLE hDevice,
  1086. OUT PWCHAR * pszDeviceName)
  1087. {
  1088. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1089. if (!This || !pszDeviceName)
  1090. {
  1091. return ERROR_INVALID_PARAMETER;
  1092. }
  1093. *pszDeviceName = This->pszName;
  1094. return NO_ERROR;
  1095. }
  1096. //
  1097. // Returns the type of a device
  1098. //
  1099. DWORD
  1100. devGetDeviceType(
  1101. IN HANDLE hDevice,
  1102. OUT LPDWORD lpdwType)
  1103. {
  1104. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1105. if (!This || !lpdwType)
  1106. {
  1107. return ERROR_INVALID_PARAMETER;
  1108. }
  1109. *lpdwType = This->dwType;
  1110. return NO_ERROR;
  1111. }
  1112. //
  1113. // Returns an identifier of the device that can be used in
  1114. // tapi calls.
  1115. //
  1116. DWORD
  1117. devGetDeviceId(
  1118. IN HANDLE hDevice,
  1119. OUT LPDWORD lpdwId)
  1120. {
  1121. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1122. if (!This || !lpdwId)
  1123. {
  1124. return ERROR_INVALID_PARAMETER;
  1125. }
  1126. *lpdwId = This->dwId;
  1127. //
  1128. // If this is a com port referencing a null modem,
  1129. // then return the tapi id of the null modem
  1130. //
  1131. if ((This->dwFlags & DEV_FLAG_PORT) && (This->pModem))
  1132. {
  1133. *lpdwId = This->pModem->dwId;
  1134. }
  1135. return NO_ERROR;
  1136. }
  1137. //
  1138. // Returns the enable status of a device for dialin
  1139. //
  1140. DWORD
  1141. devGetDeviceEnable(
  1142. IN HANDLE hDevice,
  1143. OUT BOOL * pbEnabled)
  1144. {
  1145. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1146. if (!This || !pbEnabled)
  1147. {
  1148. return ERROR_INVALID_PARAMETER;
  1149. }
  1150. *pbEnabled = !!(This->dwFlags & DEV_FLAG_ENABLED);
  1151. return NO_ERROR;
  1152. }
  1153. //
  1154. // Sets the enable status of a device for dialin
  1155. //
  1156. DWORD
  1157. devSetDeviceEnable(
  1158. IN HANDLE hDevice,
  1159. IN BOOL bEnable)
  1160. {
  1161. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1162. if (!This)
  1163. {
  1164. return ERROR_INVALID_PARAMETER;
  1165. }
  1166. // Mark the enabling and mark the device as dirty
  1167. if (bEnable)
  1168. {
  1169. This->dwFlags |= DEV_FLAG_ENABLED;
  1170. }
  1171. else
  1172. {
  1173. This->dwFlags &= ~DEV_FLAG_ENABLED;
  1174. }
  1175. This->dwFlags |= DEV_FLAG_DIRTY;
  1176. return NO_ERROR;
  1177. }
  1178. //
  1179. // Returns whether the given device is a com port as added
  1180. // by devAddComPorts
  1181. //
  1182. DWORD
  1183. devDeviceIsComPort(
  1184. IN HANDLE hDevice,
  1185. OUT PBOOL pbIsComPort)
  1186. {
  1187. RASSRV_DEVICE* This = (RASSRV_DEVICE*)hDevice;
  1188. if (!This)
  1189. {
  1190. return ERROR_INVALID_PARAMETER;
  1191. }
  1192. // This is a com port if it was added by
  1193. // devAddComPorts and if it has no null
  1194. // modem associated with it.
  1195. //
  1196. if ((This->dwFlags & DEV_FLAG_PORT) &&
  1197. (This->pModem == NULL)
  1198. )
  1199. {
  1200. *pbIsComPort = TRUE;
  1201. }
  1202. else
  1203. {
  1204. *pbIsComPort = FALSE;
  1205. }
  1206. return NO_ERROR;
  1207. }