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.

827 lines
26 KiB

  1. /*
  2. (C) Copyright 1998
  3. All rights reserved.
  4. Portions of this software are:
  5. (C) Copyright 1995, 1999 TriplePoint, Inc. -- http://www.TriplePoint.com
  6. License to use this software is granted under the terms outlined in
  7. the TriplePoint Software Services Agreement.
  8. (C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
  9. License to use this software is granted under the terms outlined in
  10. the Microsoft Windows Device Driver Development Kit.
  11. @doc INTERNAL TspiDev TspiDev_c
  12. @module TspiDev.c |
  13. This module implements the Telephony Service Provider Interface for
  14. TapiDevice objects.
  15. @head3 Contents |
  16. @index class,mfunc,func,msg,mdata,struct,enum | TspiDev_c
  17. @end
  18. */
  19. #define __FILEID__ TSPIDEV_OBJECT_TYPE
  20. // Unique file ID for error logging
  21. #include "Miniport.h" // Defines all the miniport objects
  22. #include "string.h"
  23. #if defined(NDIS_LCODE)
  24. # pragma NDIS_LCODE // Windows 95 wants this code locked down!
  25. # pragma NDIS_LDATA
  26. #endif
  27. /* @doc INTERNAL TspiDev TspiDev_c TspiGetDevCaps
  28. @func
  29. This request queries a specified line device to determine its telephony
  30. capabilities. The returned information is valid for all addresses on the
  31. line device.
  32. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  33. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  34. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  35. @parm IN PNDIS_TAPI_GET_DEV_CAPS | Request |
  36. A pointer to the NDIS_TAPI request structure for this call.
  37. @iex
  38. typedef struct _NDIS_TAPI_GET_DEV_CAPS
  39. {
  40. IN ULONG ulRequestID;
  41. IN ULONG ulDeviceID;
  42. IN ULONG ulExtVersion;
  43. OUT LINE_DEV_CAPS LineDevCaps;
  44. } NDIS_TAPI_GET_DEV_CAPS, *PNDIS_TAPI_GET_DEV_CAPS;
  45. typedef struct _LINE_DEV_CAPS
  46. {
  47. ULONG ulTotalSize;
  48. ULONG ulNeededSize;
  49. ULONG ulUsedSize;
  50. ULONG ulProviderInfoSize;
  51. ULONG ulProviderInfoOffset;
  52. ULONG ulSwitchInfoSize;
  53. ULONG ulSwitchInfoOffset;
  54. ULONG ulPermanentLineID;
  55. ULONG ulLineNameSize;
  56. ULONG ulLineNameOffset;
  57. ULONG ulStringFormat;
  58. ULONG ulAddressModes;
  59. ULONG ulNumAddresses;
  60. ULONG ulBearerModes;
  61. ULONG ulMaxRate;
  62. ULONG ulMediaModes;
  63. ULONG ulGenerateToneModes;
  64. ULONG ulGenerateToneMaxNumFreq;
  65. ULONG ulGenerateDigitModes;
  66. ULONG ulMonitorToneMaxNumFreq;
  67. ULONG ulMonitorToneMaxNumEntries;
  68. ULONG ulMonitorDigitModes;
  69. ULONG ulGatherDigitsMinTimeout;
  70. ULONG ulGatherDigitsMaxTimeout;
  71. ULONG ulMedCtlDigitMaxListSize;
  72. ULONG ulMedCtlMediaMaxListSize;
  73. ULONG ulMedCtlToneMaxListSize;
  74. ULONG ulMedCtlCallStateMaxListSize;
  75. ULONG ulDevCapFlags;
  76. ULONG ulMaxNumActiveCalls;
  77. ULONG ulAnswerMode;
  78. ULONG ulRingModes;
  79. ULONG ulLineStates;
  80. ULONG ulUUIAcceptSize;
  81. ULONG ulUUIAnswerSize;
  82. ULONG ulUUIMakeCallSize;
  83. ULONG ulUUIDropSize;
  84. ULONG ulUUISendUserUserInfoSize;
  85. ULONG ulUUICallInfoSize;
  86. LINE_DIAL_PARAMS MinDialParams;
  87. LINE_DIAL_PARAMS MaxDialParams;
  88. LINE_DIAL_PARAMS DefaultDialParams;
  89. ULONG ulNumTerminals;
  90. ULONG ulTerminalCapsSize;
  91. ULONG ulTerminalCapsOffset;
  92. ULONG ulTerminalTextEntrySize;
  93. ULONG ulTerminalTextSize;
  94. ULONG ulTerminalTextOffset;
  95. ULONG ulDevSpecificSize;
  96. ULONG ulDevSpecificOffset;
  97. } LINE_DEV_CAPS, *PLINE_DEV_CAPS;
  98. typedef struct _LINE_DIAL_PARAMS
  99. {
  100. ULONG ulDialPause;
  101. ULONG ulDialSpeed;
  102. ULONG ulDigitDuration;
  103. ULONG ulWaitForDialtone;
  104. } LINE_DIAL_PARAMS, *PLINE_DIAL_PARAMS;
  105. @rdesc This routine returns one of the following values:
  106. @flag NDIS_STATUS_SUCCESS |
  107. If this function is successful.
  108. <f Note>: A non-zero return value indicates one of the following error codes:
  109. @iex
  110. NDIS_STATUS_TAPI_NODEVICE
  111. */
  112. NDIS_STATUS TspiGetDevCaps(
  113. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  114. IN PNDIS_TAPI_GET_DEV_CAPS Request,
  115. OUT PULONG BytesWritten,
  116. OUT PULONG BytesNeeded
  117. )
  118. {
  119. DBG_FUNC("TspiGetDevCaps")
  120. static UCHAR LineDeviceName[] = VER_DEVICE_STR " Line 00";
  121. static UCHAR LineSwitchName[] = VER_DEVICE_STR " Switch";
  122. PBCHANNEL_OBJECT pBChannel;
  123. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  124. UINT InfoOffset;
  125. // Offset from the start of the Request buffer to the various information
  126. // fields we fill in and return to the caller.
  127. DBG_ENTER(pAdapter);
  128. DBG_PARAMS(pAdapter,
  129. ("\n\tulDeviceID=%d\n"
  130. "\tulExtVersion=0x%X\n"
  131. "\tLineDevCaps=0x%X\n",
  132. Request->ulDeviceID,
  133. Request->ulExtVersion,
  134. &Request->LineDevCaps
  135. ));
  136. /*
  137. // This request must be associated with a line device.
  138. */
  139. pBChannel = GET_BCHANNEL_FROM_DEVICEID(pAdapter, Request->ulDeviceID);
  140. if (pBChannel == NULL)
  141. {
  142. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_NODEVICE\n"));
  143. return (NDIS_STATUS_TAPI_NODEVICE);
  144. }
  145. Request->LineDevCaps.ulNeededSize =
  146. Request->LineDevCaps.ulUsedSize = sizeof(Request->LineDevCaps);
  147. /*
  148. // The driver numbers lines sequentially from 1, so this will always
  149. // be the same number.
  150. */
  151. Request->LineDevCaps.ulPermanentLineID = pBChannel->BChannelIndex+1;
  152. /*
  153. // All the strings are ASCII format rather than UNICODE.
  154. */
  155. Request->LineDevCaps.ulStringFormat = STRINGFORMAT_ASCII;
  156. /*
  157. // Report the capabilities of this device.
  158. */
  159. Request->LineDevCaps.ulAddressModes = LINEADDRESSMODE_ADDRESSID;
  160. Request->LineDevCaps.ulNumAddresses = 1;
  161. Request->LineDevCaps.ulBearerModes = pBChannel->BearerModesCaps;
  162. Request->LineDevCaps.ulMaxRate = pBChannel->LinkSpeed;
  163. Request->LineDevCaps.ulMediaModes = pBChannel->MediaModesCaps;
  164. /*
  165. // Each line on the PRI only supports a single call.
  166. */
  167. Request->LineDevCaps.ulDevCapFlags = LINEDEVCAPFLAGS_CLOSEDROP;
  168. Request->LineDevCaps.ulMaxNumActiveCalls = 1;
  169. Request->LineDevCaps.ulAnswerMode = LINEANSWERMODE_DROP;
  170. Request->LineDevCaps.ulRingModes = 1;
  171. Request->LineDevCaps.ulLineStates = pBChannel->DevStatesCaps;
  172. /*
  173. // RASTAPI requires the "MediaType\0DeviceName" be placed in the
  174. // ProviderInfo field at the end of this structure.
  175. */
  176. InfoOffset = sizeof(Request->LineDevCaps);
  177. Request->LineDevCaps.ulNeededSize += pAdapter->ProviderInfoSize;
  178. *BytesNeeded += pAdapter->ProviderInfoSize;
  179. if (Request->LineDevCaps.ulNeededSize <= Request->LineDevCaps.ulTotalSize)
  180. {
  181. Request->LineDevCaps.ulProviderInfoSize = pAdapter->ProviderInfoSize;
  182. Request->LineDevCaps.ulProviderInfoOffset = InfoOffset;
  183. NdisMoveMemory((PUCHAR) &Request->LineDevCaps + InfoOffset,
  184. pAdapter->ProviderInfo,
  185. pAdapter->ProviderInfoSize
  186. );
  187. Request->LineDevCaps.ulUsedSize += pAdapter->ProviderInfoSize;
  188. InfoOffset += pAdapter->ProviderInfoSize;
  189. }
  190. /*
  191. // LineName is displayed by the Dialup Networking App.
  192. // UniModem TSP returns the modem name here.
  193. // We'll return the name of the line.
  194. */
  195. Request->LineDevCaps.ulNeededSize += sizeof(LineDeviceName);
  196. *BytesNeeded += sizeof(LineDeviceName);
  197. if (Request->LineDevCaps.ulNeededSize <= Request->LineDevCaps.ulTotalSize)
  198. {
  199. // FIXME - This code only handles 99 lines!
  200. LineDeviceName[sizeof(LineDeviceName)-3] = '0' +
  201. (UCHAR) Request->LineDevCaps.ulPermanentLineID / 10;
  202. LineDeviceName[sizeof(LineDeviceName)-2] = '0' +
  203. (UCHAR) Request->LineDevCaps.ulPermanentLineID % 10;
  204. Request->LineDevCaps.ulLineNameSize = sizeof(LineDeviceName);
  205. Request->LineDevCaps.ulLineNameOffset = InfoOffset;
  206. NdisMoveMemory((PUCHAR) &Request->LineDevCaps + InfoOffset,
  207. LineDeviceName,
  208. sizeof(LineDeviceName)
  209. );
  210. Request->LineDevCaps.ulUsedSize += sizeof(LineDeviceName);
  211. InfoOffset += sizeof(LineDeviceName);
  212. }
  213. /*
  214. // SwitchName is not yet displayed by the Dialup Networking App,
  215. // but we'll return something reasonable just in case.
  216. */
  217. Request->LineDevCaps.ulNeededSize += sizeof(LineSwitchName);
  218. *BytesNeeded += sizeof(LineSwitchName);
  219. if (Request->LineDevCaps.ulNeededSize <= Request->LineDevCaps.ulTotalSize)
  220. {
  221. Request->LineDevCaps.ulSwitchInfoSize = sizeof(LineSwitchName);
  222. Request->LineDevCaps.ulSwitchInfoOffset = InfoOffset;
  223. NdisMoveMemory((PUCHAR) &Request->LineDevCaps + InfoOffset,
  224. LineSwitchName,
  225. sizeof(LineSwitchName)
  226. );
  227. Request->LineDevCaps.ulUsedSize += sizeof(LineSwitchName);
  228. InfoOffset += sizeof(LineSwitchName);
  229. }
  230. else
  231. {
  232. DBG_PARAMS(pAdapter,
  233. ("STRUCTURETOOSMALL %d<%d\n",
  234. Request->LineDevCaps.ulTotalSize,
  235. Request->LineDevCaps.ulNeededSize));
  236. }
  237. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  238. return (NDIS_STATUS_SUCCESS);
  239. }
  240. /* @doc INTERNAL TspiDev TspiDev_c TspiGetDevConfig
  241. @func
  242. This request returns a data structure object, the contents of which are
  243. specific to the line (miniport) and device class, giving the current
  244. configuration of a device associated one-to-one with the line device.
  245. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  246. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  247. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  248. @parm IN PNDIS_TAPI_GET_DEV_CONFIG | Request |
  249. A pointer to the NDIS_TAPI request structure for this call.
  250. @iex
  251. typedef struct _NDIS_TAPI_GET_DEV_CONFIG
  252. {
  253. IN ULONG ulRequestID;
  254. IN ULONG ulDeviceID;
  255. IN ULONG ulDeviceClassSize;
  256. IN ULONG ulDeviceClassOffset;
  257. OUT VAR_STRING DeviceConfig;
  258. } NDIS_TAPI_GET_DEV_CONFIG, *PNDIS_TAPI_GET_DEV_CONFIG;
  259. typedef struct _VAR_STRING
  260. {
  261. ULONG ulTotalSize;
  262. ULONG ulNeededSize;
  263. ULONG ulUsedSize;
  264. ULONG ulStringFormat;
  265. ULONG ulStringSize;
  266. ULONG ulStringOffset;
  267. } VAR_STRING, *PVAR_STRING;
  268. @rdesc This routine returns one of the following values:
  269. @flag NDIS_STATUS_SUCCESS |
  270. If this function is successful.
  271. <f Note>: A non-zero return value indicates one of the following error codes:
  272. @iex
  273. NDIS_STATUS_TAPI_INVALDEVICECLASS
  274. NDIS_STATUS_TAPI_NODEVICE
  275. */
  276. NDIS_STATUS TspiGetDevConfig(
  277. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  278. IN PNDIS_TAPI_GET_DEV_CONFIG Request,
  279. OUT PULONG BytesWritten,
  280. OUT PULONG BytesNeeded
  281. )
  282. {
  283. DBG_FUNC("TspiGetDevConfig")
  284. PBCHANNEL_OBJECT pBChannel;
  285. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  286. UINT DeviceClass;
  287. // Remember which device class is being requested.
  288. DBG_ENTER(pAdapter);
  289. DBG_PARAMS(pAdapter,
  290. ("\n\tulDeviceID=%d\n"
  291. "\tulDeviceClassSize=%d\n"
  292. "\tulDeviceClassOffset=0x%X = '%s'\n",
  293. Request->ulDeviceID,
  294. Request->ulDeviceClassSize,
  295. Request->ulDeviceClassOffset,
  296. ((PCHAR) Request + Request->ulDeviceClassOffset)
  297. ));
  298. /*
  299. // Make sure this is a tapi/line or ndis request.
  300. */
  301. if (STR_EQU((PCHAR) Request + Request->ulDeviceClassOffset,
  302. NDIS_DEVICECLASS_NAME, Request->ulDeviceClassSize))
  303. {
  304. DeviceClass = NDIS_DEVICECLASS_ID;
  305. }
  306. else if (STR_EQU((PCHAR) Request + Request->ulDeviceClassOffset,
  307. TAPI_DEVICECLASS_NAME, Request->ulDeviceClassSize))
  308. {
  309. DeviceClass = TAPI_DEVICECLASS_ID;
  310. }
  311. else
  312. {
  313. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n"));
  314. return (NDIS_STATUS_TAPI_INVALDEVICECLASS);
  315. }
  316. /*
  317. // This request must be associated with a line device.
  318. */
  319. pBChannel = GET_BCHANNEL_FROM_DEVICEID(pAdapter, Request->ulDeviceID);
  320. if (pBChannel == NULL)
  321. {
  322. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_NODEVICE\n"));
  323. return (NDIS_STATUS_TAPI_NODEVICE);
  324. }
  325. /*
  326. // Now we need to adjust the variable field to place the requested device
  327. // configuration.
  328. */
  329. # define DEVCONFIG_INFO "Dummy Configuration Data"
  330. # define SIZEOF_DEVCONFIG 0 // sizeof(DEVCONFIG_INFO)
  331. Request->DeviceConfig.ulNeededSize = sizeof(VAR_STRING) + SIZEOF_DEVCONFIG;
  332. Request->DeviceConfig.ulUsedSize = sizeof(VAR_STRING);
  333. *BytesNeeded += SIZEOF_DEVCONFIG;
  334. if (Request->DeviceConfig.ulTotalSize >= Request->DeviceConfig.ulNeededSize)
  335. {
  336. Request->DeviceConfig.ulUsedSize = Request->DeviceConfig.ulNeededSize;
  337. Request->DeviceConfig.ulStringFormat = STRINGFORMAT_BINARY;
  338. Request->DeviceConfig.ulStringSize = SIZEOF_DEVCONFIG;
  339. Request->DeviceConfig.ulStringOffset = sizeof(VAR_STRING);
  340. /*
  341. // There are currently no return values defined for this case.
  342. // This is just a place holder for future extensions.
  343. */
  344. NdisMoveMemory((PUCHAR) &Request->DeviceConfig + sizeof(VAR_STRING),
  345. DEVCONFIG_INFO,
  346. SIZEOF_DEVCONFIG
  347. );
  348. }
  349. else
  350. {
  351. DBG_PARAMS(pAdapter,
  352. ("STRUCTURETOOSMALL %d<%d\n",
  353. Request->DeviceConfig.ulTotalSize,
  354. Request->DeviceConfig.ulNeededSize));
  355. }
  356. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  357. return (NDIS_STATUS_SUCCESS);
  358. }
  359. /* @doc INTERNAL TspiDev TspiDev_c TspiSetDevConfig
  360. @func
  361. This request restores the configuration of a device associated one-to-one
  362. with the line device from an data structure previously obtained using
  363. OID_TAPI_GET_DEV_CONFIG. The contents of this data structure are specific
  364. to the line (miniport) and device class.
  365. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  366. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  367. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  368. @parm IN PNDIS_TAPI_SET_DEV_CONFIG | Request |
  369. A pointer to the NDIS_TAPI request structure for this call.
  370. @iex
  371. typedef struct _NDIS_TAPI_SET_DEV_CONFIG
  372. {
  373. IN ULONG ulRequestID;
  374. IN ULONG ulDeviceID;
  375. IN ULONG ulDeviceClassSize;
  376. IN ULONG ulDeviceClassOffset;
  377. IN ULONG ulDeviceConfigSize;
  378. IN UCHAR DeviceConfig[1];
  379. } NDIS_TAPI_SET_DEV_CONFIG, *PNDIS_TAPI_SET_DEV_CONFIG;
  380. @rdesc This routine returns one of the following values:
  381. @flag NDIS_STATUS_SUCCESS |
  382. If this function is successful.
  383. <f Note>: A non-zero return value indicates one of the following error codes:
  384. @iex
  385. NDIS_STATUS_TAPI_INVALDEVICECLASS
  386. NDIS_STATUS_TAPI_INVALPARAM
  387. NDIS_STATUS_TAPI_NODEVICE
  388. */
  389. NDIS_STATUS TspiSetDevConfig(
  390. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  391. IN PNDIS_TAPI_SET_DEV_CONFIG Request,
  392. OUT PULONG BytesWritten,
  393. OUT PULONG BytesNeeded
  394. )
  395. {
  396. DBG_FUNC("TspiSetDevConfig")
  397. PBCHANNEL_OBJECT pBChannel;
  398. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  399. UINT DeviceClass;
  400. // Remember which device class is being requested.
  401. DBG_ENTER(pAdapter);
  402. DBG_PARAMS(pAdapter,
  403. ("\n\tulDeviceID=%d\n"
  404. "\tulDeviceClassSize=%d\n"
  405. "\tulDeviceClassOffset=0x%X = '%s'\n"
  406. "\tulDeviceConfigSize=%d\n",
  407. Request->ulDeviceID,
  408. Request->ulDeviceClassSize,
  409. Request->ulDeviceClassOffset,
  410. ((PCHAR) Request + Request->ulDeviceClassOffset),
  411. Request->ulDeviceConfigSize
  412. ));
  413. /*
  414. // Make sure this is a tapi/line or ndis request.
  415. */
  416. if (STR_EQU((PCHAR) Request + Request->ulDeviceClassOffset,
  417. NDIS_DEVICECLASS_NAME, Request->ulDeviceClassSize))
  418. {
  419. DeviceClass = NDIS_DEVICECLASS_ID;
  420. }
  421. else if (STR_EQU((PCHAR) Request + Request->ulDeviceClassOffset,
  422. TAPI_DEVICECLASS_NAME, Request->ulDeviceClassSize))
  423. {
  424. DeviceClass = TAPI_DEVICECLASS_ID;
  425. }
  426. else
  427. {
  428. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n"));
  429. return (NDIS_STATUS_TAPI_INVALDEVICECLASS);
  430. }
  431. /*
  432. // This request must be associated with a line device.
  433. */
  434. pBChannel = GET_BCHANNEL_FROM_DEVICEID(pAdapter, Request->ulDeviceID);
  435. if (pBChannel == NULL)
  436. {
  437. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_NODEVICE\n"));
  438. return (NDIS_STATUS_TAPI_NODEVICE);
  439. }
  440. /*
  441. // Make sure this configuration is the proper size.
  442. */
  443. if (Request->ulDeviceConfigSize)
  444. {
  445. if (Request->ulDeviceConfigSize != SIZEOF_DEVCONFIG)
  446. {
  447. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALPARAM Size!=%d\n",
  448. SIZEOF_DEVCONFIG));
  449. return (NDIS_STATUS_TAPI_INVALPARAM);
  450. }
  451. /*
  452. // Retore the configuration information returned by TspiGetDevConfig.
  453. //
  454. // There are currently no configuration values defined this case.
  455. // This is just a place holder for future extensions.
  456. */
  457. else if (!STR_EQU(Request->DeviceConfig,
  458. DEVCONFIG_INFO, SIZEOF_DEVCONFIG))
  459. {
  460. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALPARAM DevCfg=0x%X\n",
  461. *((ULONG *) &Request->DeviceConfig[0]) ));
  462. #if DBG
  463. DbgPrintData(Request->DeviceConfig, SIZEOF_DEVCONFIG, 0);
  464. #endif // DBG
  465. // Since we don't use this info, we'll just return success.
  466. // return (NDIS_STATUS_TAPI_INVALPARAM);
  467. }
  468. }
  469. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  470. return (NDIS_STATUS_SUCCESS);
  471. }
  472. /* @doc INTERNAL TspiDev TspiDev_c TspiGetID
  473. @func
  474. This request returns a device ID for the specified device class
  475. associated with the selected line, address or call.
  476. @parm IN PMINIPORT_ADAPTER_OBJECT | pAdapter |
  477. A pointer to the Miniport's adapter context structure <t MINIPORT_ADAPTER_OBJECT>.
  478. This is the <t MiniportAdapterContext> we passed into <f NdisMSetAttributes>.
  479. @parm IN PNDIS_TAPI_GET_ID | Request |
  480. A pointer to the NDIS_TAPI request structure for this call.
  481. @iex
  482. typedef struct _NDIS_TAPI_GET_ID
  483. {
  484. IN ULONG ulRequestID;
  485. IN HDRV_LINE hdLine;
  486. IN ULONG ulAddressID;
  487. IN HDRV_CALL hdCall;
  488. IN ULONG ulSelect;
  489. IN ULONG ulDeviceClassSize;
  490. IN ULONG ulDeviceClassOffset;
  491. OUT VAR_STRING DeviceID;
  492. } NDIS_TAPI_GET_ID, *PNDIS_TAPI_GET_ID;
  493. typedef struct _VAR_STRING
  494. {
  495. ULONG ulTotalSize;
  496. ULONG ulNeededSize;
  497. ULONG ulUsedSize;
  498. ULONG ulStringFormat;
  499. ULONG ulStringSize;
  500. ULONG ulStringOffset;
  501. } VAR_STRING, *PVAR_STRING;
  502. @rdesc This routine returns one of the following values:
  503. @flag NDIS_STATUS_SUCCESS |
  504. If this function is successful.
  505. <f Note>: A non-zero return value indicates one of the following error codes:
  506. @iex
  507. NDIS_STATUS_FAILURE
  508. NDIS_STATUS_TAPI_INVALDEVICECLASS
  509. NDIS_STATUS_TAPI_INVALLINEHANDLE
  510. NDIS_STATUS_TAPI_INVALADDRESSID
  511. NDIS_STATUS_TAPI_INVALCALLHANDLE
  512. NDIS_STATUS_TAPI_OPERATIONUNAVAIL
  513. */
  514. NDIS_STATUS TspiGetID(
  515. IN PMINIPORT_ADAPTER_OBJECT pAdapter,
  516. IN PNDIS_TAPI_GET_ID Request,
  517. OUT PULONG BytesWritten,
  518. OUT PULONG BytesNeeded
  519. )
  520. {
  521. DBG_FUNC("TspiGetID")
  522. PBCHANNEL_OBJECT pBChannel;
  523. // A Pointer to one of our <t BCHANNEL_OBJECT>'s.
  524. UINT DeviceClass;
  525. // Remember which device class is being requested.
  526. /*
  527. // A pointer to the requested device ID, and its size in bytes.
  528. */
  529. PUCHAR IDPtr;
  530. UINT IDLength;
  531. TAPI_DEVICE_ID DeviceID;
  532. DBG_ENTER(pAdapter);
  533. DBG_PARAMS(pAdapter,
  534. ("\n\thdLine=0x%X\n"
  535. "\tulAddressID=%d\n"
  536. "\thdCall=0x%X\n"
  537. "\tulSelect=0x%X\n"
  538. "\tulDeviceClassSize=%d\n"
  539. "\tulDeviceClassOffset=0x%X='%s'\n",
  540. Request->hdLine,
  541. Request->ulAddressID,
  542. Request->hdCall,
  543. Request->ulSelect,
  544. Request->ulDeviceClassSize,
  545. Request->ulDeviceClassOffset,
  546. ((PCHAR) Request + Request->ulDeviceClassOffset)
  547. ));
  548. /*
  549. // If there is no DChannel, we can't allow this.
  550. */
  551. if (pAdapter->pDChannel == NULL)
  552. {
  553. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_NODRIVER\n"));
  554. return (NDIS_STATUS_TAPI_NODRIVER);
  555. }
  556. /*
  557. // Make sure this is a tapi/line or ndis request.
  558. */
  559. if (STR_EQU((PCHAR) Request + Request->ulDeviceClassOffset,
  560. NDIS_DEVICECLASS_NAME, Request->ulDeviceClassSize))
  561. {
  562. DeviceClass = NDIS_DEVICECLASS_ID;
  563. }
  564. else if (STR_EQU((PCHAR) Request + Request->ulDeviceClassOffset,
  565. TAPI_DEVICECLASS_NAME, Request->ulDeviceClassSize))
  566. {
  567. DeviceClass = TAPI_DEVICECLASS_ID;
  568. }
  569. else
  570. {
  571. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALDEVICECLASS\n"));
  572. return (NDIS_STATUS_TAPI_INVALDEVICECLASS);
  573. }
  574. /*
  575. // Find the link structure associated with the request/deviceclass.
  576. */
  577. if (Request->ulSelect == LINECALLSELECT_LINE)
  578. {
  579. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  580. if (pBChannel == NULL)
  581. {
  582. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  583. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  584. }
  585. /*
  586. // TAPI wants the ulDeviceID for this line.
  587. */
  588. DeviceID.hDevice = (ULONG) GET_DEVICEID_FROM_BCHANNEL(pAdapter, pBChannel);
  589. }
  590. else if (Request->ulSelect == LINECALLSELECT_ADDRESS)
  591. {
  592. pBChannel = GET_BCHANNEL_FROM_HDLINE(pAdapter, Request->hdLine);
  593. if (pBChannel == NULL)
  594. {
  595. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALLINEHANDLE\n"));
  596. return (NDIS_STATUS_TAPI_INVALLINEHANDLE);
  597. }
  598. if (Request->ulAddressID >= TSPI_NUM_ADDRESSES)
  599. {
  600. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALADDRESSID\n"));
  601. return (NDIS_STATUS_TAPI_INVALADDRESSID);
  602. }
  603. /*
  604. // TAPI wants the ulDeviceID for this line.
  605. */
  606. DeviceID.hDevice = (ULONG) GET_DEVICEID_FROM_BCHANNEL(pAdapter, pBChannel);
  607. }
  608. else if (Request->ulSelect == LINECALLSELECT_CALL)
  609. {
  610. pBChannel = GET_BCHANNEL_FROM_HDCALL(pAdapter, Request->hdCall);
  611. if (pBChannel == NULL)
  612. {
  613. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_TAPI_INVALCALLHANDLE\n"));
  614. return (NDIS_STATUS_TAPI_INVALCALLHANDLE);
  615. }
  616. /*
  617. // TAPI wants the htCall for this line.
  618. */
  619. DeviceID.hDevice = (ULONG) (ULONG_PTR) (pBChannel->htCall);
  620. }
  621. else
  622. {
  623. DBG_WARNING(pAdapter, ("Returning NDIS_STATUS_FAILURE\n"));
  624. return (NDIS_STATUS_FAILURE);
  625. }
  626. /*
  627. // NT RAS only expects to see hDevice.
  628. // Win95 RAS expects to see hDevice followed by "isdn\0".
  629. */
  630. IDLength = strlen(VER_DEFAULT_MEDIATYPE) + 1;
  631. NdisMoveMemory(&DeviceID.DeviceName, VER_DEFAULT_MEDIATYPE, IDLength);
  632. IDLength += sizeof(ULONG);
  633. IDPtr = (PUCHAR) &DeviceID;
  634. DBG_FILTER(pAdapter, DBG_TAPICALL_ON,
  635. ("#%d Call=0x%X CallState=0x%X GETID-%d=0x%X-'%s'@%dKbps\n",
  636. pBChannel->BChannelIndex,
  637. pBChannel->htCall, pBChannel->CallState,
  638. Request->ulSelect, DeviceID.hDevice, DeviceID.DeviceName,
  639. pBChannel->LinkSpeed/1000));
  640. /*
  641. // Now we need to adjust the variable field to place the device ID.
  642. */
  643. Request->DeviceID.ulNeededSize = sizeof(VAR_STRING) + IDLength;
  644. Request->DeviceID.ulUsedSize = sizeof(VAR_STRING);
  645. *BytesNeeded += IDLength;
  646. if (Request->DeviceID.ulTotalSize >= Request->DeviceID.ulNeededSize)
  647. {
  648. Request->DeviceID.ulStringFormat = STRINGFORMAT_BINARY;
  649. Request->DeviceID.ulUsedSize = Request->DeviceID.ulNeededSize;
  650. Request->DeviceID.ulStringSize = IDLength;
  651. Request->DeviceID.ulStringOffset = sizeof(VAR_STRING);
  652. /*
  653. // Now we return the requested ID value.
  654. */
  655. NdisMoveMemory(
  656. (PCHAR) &Request->DeviceID + sizeof(VAR_STRING),
  657. IDPtr,
  658. IDLength
  659. );
  660. }
  661. else
  662. {
  663. if ((Request->DeviceID.ulNeededSize - Request->DeviceID.ulTotalSize) >=
  664. sizeof(ULONG))
  665. {
  666. /*
  667. // Return just the hDevice part (the first 4 bytes).
  668. */
  669. NdisMoveMemory(
  670. (PCHAR) &Request->DeviceID + sizeof(VAR_STRING),
  671. IDPtr,
  672. sizeof(ULONG)
  673. );
  674. Request->DeviceID.ulStringFormat = STRINGFORMAT_BINARY;
  675. Request->DeviceID.ulUsedSize += sizeof(ULONG);
  676. Request->DeviceID.ulStringSize = sizeof(ULONG);
  677. Request->DeviceID.ulStringOffset = sizeof(VAR_STRING);
  678. }
  679. DBG_PARAMS(pAdapter,
  680. ("STRUCTURETOOSMALL %d<%d\n",
  681. Request->DeviceID.ulTotalSize,
  682. Request->DeviceID.ulNeededSize));
  683. }
  684. DBG_RETURN(pAdapter, NDIS_STATUS_SUCCESS);
  685. return (NDIS_STATUS_SUCCESS);
  686. }