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.

533 lines
14 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. rxce.c
  5. Abstract:
  6. This module implements the RXCE routines related to binding/unbinding, dynamic
  7. enabling/disabling of transports.
  8. Revision History:
  9. Balan Sethu Raman [SethuR] 15-Feb-1995
  10. Notes:
  11. The number of transport bindings are in all probability very few ( mostly one or two).
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGE, RxCeBuildTransport)
  17. #pragma alloc_text(PAGE, RxCeTearDownTransport)
  18. #pragma alloc_text(PAGE, RxCeQueryAdapterStatus)
  19. #pragma alloc_text(PAGE, RxCeQueryTransportInformation)
  20. #pragma alloc_text(PAGE, DuplicateTransportAddress)
  21. #pragma alloc_text(PAGE, RxCeBuildAddress)
  22. #pragma alloc_text(PAGE, RxCeTearDownAddress)
  23. #endif
  24. //
  25. // The debug trace level
  26. //
  27. #define Dbg (DEBUG_TRACE_RXCEBINDING)
  28. NTSTATUS
  29. RxCeBuildTransport(
  30. IN OUT PRXCE_TRANSPORT pTransport,
  31. IN PUNICODE_STRING pTransportName,
  32. IN ULONG QualityOfService)
  33. /*++
  34. Routine Description:
  35. This routine binds to the transport specified.
  36. Arguments:
  37. pTransportName - the binding string for the desired transport
  38. QualityOfService - the quality of service desired from the transport.
  39. Return Value:
  40. STATUS_SUCCESS - if the call was successfull.
  41. Notes:
  42. The RDBSS or RXCE do not paticipate in the computation of quality
  43. of service. They essentially use it as a magic number that needs
  44. to be passed to the underlying transport provider.
  45. At present we ignore the QualityOfService parameter. How should a request for
  46. binding to a transport that has been currently bound to with a lower quality of
  47. service be handled?
  48. --*/
  49. {
  50. NTSTATUS Status = STATUS_SUCCESS;
  51. PAGED_CODE();
  52. // Update profiling info.
  53. RxProfile(RxCeBinding,RxCeBindToTransport);
  54. try {
  55. pTransport->Signature = RXCE_TRANSPORT_SIGNATURE;
  56. pTransport->ConnectionCount = 0;
  57. pTransport->VirtualCircuitCount = 0;
  58. pTransport->pDeviceObject = NULL;
  59. pTransport->ControlChannel = INVALID_HANDLE_VALUE;
  60. pTransport->pControlChannelFileObject = NULL;
  61. pTransport->Name.MaximumLength = pTransportName->Length;
  62. pTransport->Name.Length = pTransportName->Length;
  63. pTransport->pProviderInfo
  64. = RxAllocatePoolWithTag(
  65. PagedPool,
  66. sizeof(RXCE_TRANSPORT_PROVIDER_INFO),
  67. RXCE_TRANSPORT_POOLTAG);
  68. pTransport->Name.Buffer = RxAllocatePoolWithTag(
  69. NonPagedPool,
  70. pTransport->Name.Length,
  71. RXCE_TRANSPORT_POOLTAG);
  72. if ((pTransport->pProviderInfo != NULL) &&
  73. (pTransport->Name.Buffer != NULL)) {
  74. RtlCopyMemory(
  75. pTransport->Name.Buffer,
  76. pTransportName->Buffer,
  77. pTransport->Name.Length);
  78. // Initialize the transport information.
  79. Status = RxTdiBindToTransport(
  80. pTransport);
  81. // Ensure that the quality of service criterion is met.
  82. // Cleanup if the operation was not successfull.
  83. if (!NT_SUCCESS(Status)) {
  84. RxDbgTrace(0, Dbg, ("RxTdiBindToTransport returned %lx\n",Status));
  85. RxCeTearDownTransport(pTransport);
  86. } else {
  87. pTransport->QualityOfService = QualityOfService;
  88. }
  89. } else {
  90. RxCeTearDownTransport(pTransport);
  91. Status = STATUS_INSUFFICIENT_RESOURCES;
  92. }
  93. } finally {
  94. if (AbnormalTermination()) {
  95. Status = STATUS_INVALID_PARAMETER;
  96. RxLog(("RxCeBindToTransport T: %lx\n",pTransport));
  97. RxWmiLog(LOG,
  98. RxCeBuildTransport,
  99. LOGPTR(pTransport));
  100. }
  101. }
  102. return Status;
  103. }
  104. NTSTATUS
  105. RxCeTearDownTransport(
  106. IN PRXCE_TRANSPORT pTransport)
  107. /*++
  108. Routine Description:
  109. This routine unbinds from the transport specified.
  110. Arguments:
  111. pTransport - the transport instance
  112. Return Value:
  113. STATUS_SUCCESS - if the call was successfull.
  114. Notes:
  115. if a transport that has not been bound to is specified no error is
  116. returned. The operation trivially succeeds.
  117. --*/
  118. {
  119. NTSTATUS Status = STATUS_SUCCESS;
  120. PAGED_CODE();
  121. // Update profiling info.
  122. RxProfile(RxCeBinding,RxCeUnbindFromTransport);
  123. try {
  124. if (RxCeIsTransportValid(pTransport)) {
  125. if (pTransport->pDeviceObject != NULL) {
  126. Status = RxTdiUnbindFromTransport(pTransport);
  127. }
  128. RxDbgTrace(0, Dbg,("RxTdiUnbindFromTransport returned %lx\n",Status));
  129. if (pTransport->Name.Buffer != NULL) {
  130. RxFreePool(pTransport->Name.Buffer);
  131. }
  132. if (pTransport->pProviderInfo != NULL ) {
  133. RxFreePool(pTransport->pProviderInfo);
  134. }
  135. pTransport->ConnectionCount = 0;
  136. pTransport->VirtualCircuitCount = 0;
  137. pTransport->pProviderInfo = NULL;
  138. pTransport->pDeviceObject = NULL;
  139. pTransport->ControlChannel = INVALID_HANDLE_VALUE;
  140. pTransport->pControlChannelFileObject = NULL;
  141. Status = STATUS_SUCCESS;
  142. }
  143. } finally {
  144. if (AbnormalTermination()) {
  145. RxLog(("RxCeTdT: T: %lx\n",pTransport));
  146. RxWmiLog(LOG,
  147. RxCeTearDownTransport,
  148. LOGPTR(pTransport));
  149. Status = STATUS_INVALID_PARAMETER;
  150. }
  151. }
  152. return Status;
  153. }
  154. NTSTATUS
  155. RxCeQueryAdapterStatus(
  156. PRXCE_TRANSPORT pTransport,
  157. PADAPTER_STATUS pAdapterStatus)
  158. /*++
  159. Routine Description:
  160. This routine returns the name of a given transport in a caller allocated buffer
  161. Arguments:
  162. pTransport - the RXCE_TRANSPORT instance
  163. pAdapterStatus - the adapter status of the transport
  164. Return Value:
  165. STATUS_SUCCESS - if the call was successfull.
  166. --*/
  167. {
  168. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  169. PAGED_CODE();
  170. try {
  171. if (RxCeIsTransportValid(pTransport)) {
  172. Status = RxTdiQueryAdapterStatus(pTransport,pAdapterStatus);
  173. }
  174. } finally {
  175. if (AbnormalTermination()) {
  176. Status = STATUS_INVALID_PARAMETER;
  177. RxLog(("RXCeQAS: T: %lx\n",pTransport));
  178. RxWmiLog(LOG,
  179. RxCeQueryAdapterStatus,
  180. LOGPTR(pTransport));
  181. }
  182. }
  183. return Status;
  184. }
  185. NTSTATUS
  186. RxCeQueryTransportInformation(
  187. PRXCE_TRANSPORT pTransport,
  188. PRXCE_TRANSPORT_INFORMATION pTransportInformation)
  189. /*++
  190. Routine Description:
  191. This routine returns the transport information for a given transport
  192. Arguments:
  193. pTransport - the RXCE_TRANSPORT
  194. pTransportInformation - the information for the transport
  195. Return Value:
  196. STATUS_SUCCESS - if the call was successfull.
  197. --*/
  198. {
  199. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  200. PRXCE_TRANSPORT_PROVIDER_INFO pProviderInfo;
  201. PAGED_CODE();
  202. try {
  203. if (RxCeIsTransportValid(pTransport)) {
  204. pProviderInfo = (PRXCE_TRANSPORT_PROVIDER_INFO)pTransportInformation;
  205. *pProviderInfo = *(pTransport->pProviderInfo);
  206. pTransportInformation->ConnectionCount = pTransport->ConnectionCount;
  207. pTransportInformation->QualityOfService = pTransport->QualityOfService;
  208. Status = STATUS_SUCCESS;
  209. }
  210. } finally {
  211. if (AbnormalTermination()) {
  212. Status = STATUS_INVALID_PARAMETER;
  213. RxLog(("RXCeQTI: T: %lx\n",pTransport));
  214. RxWmiLog(LOG,
  215. RxCeQueryTransportInformation,
  216. LOGPTR(pTransport));
  217. }
  218. }
  219. return Status;
  220. }
  221. NTSTATUS
  222. DuplicateTransportAddress(
  223. PTRANSPORT_ADDRESS *pCopy,
  224. PTRANSPORT_ADDRESS pOriginal,
  225. POOL_TYPE PoolType)
  226. /*++
  227. Routine Description:
  228. This routine duplicates a transport addresses.
  229. Arguments:
  230. pCopy - the pointer to the new copy
  231. pOriginal - the original.
  232. PoolType - type of pool for memory allocation
  233. Return Value:
  234. STATUS_SUCCESS if successful.
  235. Notes:
  236. --*/
  237. {
  238. ULONG Size = ComputeTransportAddressLength(pOriginal);
  239. PAGED_CODE();
  240. *pCopy = (PTRANSPORT_ADDRESS)
  241. RxAllocatePoolWithTag(
  242. PoolType,
  243. Size,
  244. RXCE_TRANSPORT_POOLTAG);
  245. if (*pCopy != NULL) {
  246. RtlCopyMemory(*pCopy,pOriginal,Size);
  247. return STATUS_SUCCESS;
  248. } else
  249. return STATUS_INSUFFICIENT_RESOURCES;
  250. }
  251. NTSTATUS
  252. RxCeBuildAddress(
  253. IN OUT PRXCE_ADDRESS pAddress,
  254. IN PRXCE_TRANSPORT pTransport,
  255. IN PTRANSPORT_ADDRESS pTransportAddress,
  256. IN PRXCE_ADDRESS_EVENT_HANDLER pHandler,
  257. IN PVOID pEventContext)
  258. /*++
  259. Routine Description:
  260. This routine associated a transport address with a transport binding.
  261. Arguments:
  262. pAddress - the address instance
  263. pTransport - the transport with whihc this address is to be associated
  264. pTransportAddress - the transport address to be associated with the binding
  265. pHandler - the event handler associated with the registration.
  266. pEventContext - the context parameter to be passed back to the event handler
  267. Return Value:
  268. STATUS_SUCCESS if successfull.
  269. Notes:
  270. --*/
  271. {
  272. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  273. PAGED_CODE();
  274. // Update profiling info.
  275. RxProfile(RxCeManagement,RxCeRegisterClientAddress);
  276. try {
  277. if (RxCeIsTransportValid(pTransport)) {
  278. pAddress->Signature = RXCE_ADDRESS_SIGNATURE;
  279. pAddress->pTransport = pTransport;
  280. pAddress->hAddress = INVALID_HANDLE_VALUE;
  281. pAddress->pFileObject = NULL;
  282. pAddress->pHandler = NULL;
  283. pAddress->pTransportAddress = NULL;
  284. pAddress->pReceiveMdl = NULL;
  285. // Allocate the mmeory for the event handling dispatch vector
  286. pAddress->pHandler = (PRXCE_ADDRESS_EVENT_HANDLER)
  287. RxAllocatePoolWithTag(
  288. NonPagedPool,
  289. sizeof(RXCE_ADDRESS_EVENT_HANDLER),
  290. RXCE_ADDRESS_POOLTAG);
  291. if (pAddress->pHandler != NULL) {
  292. RtlZeroMemory(
  293. pAddress->pHandler,
  294. sizeof(RXCE_ADDRESS_EVENT_HANDLER));
  295. // Duplicate the transport address for future searches
  296. Status = DuplicateTransportAddress(
  297. &pAddress->pTransportAddress,
  298. pTransportAddress,
  299. PagedPool);
  300. } else {
  301. Status = STATUS_INSUFFICIENT_RESOURCES;
  302. }
  303. if (NT_SUCCESS(Status)) {
  304. // Open the address w.r.t a transport provider
  305. Status = RxTdiOpenAddress(
  306. pTransport,
  307. pTransportAddress,
  308. pAddress);
  309. if (NT_SUCCESS(Status)) {
  310. // Initialize the handler and the associated context
  311. if (pHandler != NULL) {
  312. *(pAddress->pHandler) = *pHandler;
  313. pAddress->pContext = pEventContext;
  314. }
  315. } else {
  316. RxCeTearDownAddress(pAddress);
  317. RxDbgTrace(0, Dbg,("RxTdiOpenAddress returned %lx\n",Status));
  318. }
  319. } else {
  320. RxDbgTrace(0, Dbg,("RxCeOpenAddress returned %lx\n",Status));
  321. }
  322. }
  323. } finally {
  324. if (AbnormalTermination()) {
  325. Status = STATUS_INVALID_PARAMETER;
  326. RxLog(("RxCeBA: T: %lx A: %lx\n",pTransport,pAddress));
  327. RxWmiLog(LOG,
  328. RxCeBuildAddress,
  329. LOGPTR(pTransport)
  330. LOGPTR(pAddress));
  331. }
  332. }
  333. return Status;
  334. }
  335. NTSTATUS
  336. RxCeTearDownAddress(
  337. IN PRXCE_ADDRESS pAddress)
  338. /*++
  339. Routine Description:
  340. This routine deregisters a transport address from a transport binding
  341. Arguments:
  342. pAddress - the RxCe address denoting the transport binding/Transport address
  343. tuple.
  344. Return Value:
  345. STATUS_SUCCESS if successful.
  346. Notes:
  347. --*/
  348. {
  349. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  350. PRXCE_TRANSPORT pTransport;
  351. PAGED_CODE();
  352. // Update profiling info.
  353. RxProfile(RxCeManagement,RxCeDeregisterClientAddress);
  354. try {
  355. pTransport = pAddress->pTransport;
  356. if (RxCeIsAddressValid(pAddress) &&
  357. RxCeIsTransportValid(pTransport)) {
  358. // close the address object.
  359. if (pAddress->hAddress != INVALID_HANDLE_VALUE) {
  360. Status = RxTdiCloseAddress(pAddress);
  361. if (!NT_SUCCESS(Status)) {
  362. RxDbgTrace(0, Dbg,("RxTdiCloseAddress returned %lx\n",Status));
  363. }
  364. }
  365. if (pAddress->pHandler != NULL) {
  366. RxFreePool(pAddress->pHandler);
  367. }
  368. if (pAddress->pTransportAddress != NULL) {
  369. RxFreePool(pAddress->pTransportAddress);
  370. }
  371. pAddress->pTransport = pTransport;
  372. pAddress->hAddress = INVALID_HANDLE_VALUE;
  373. pAddress->pFileObject = NULL;
  374. pAddress->pHandler = NULL;
  375. pAddress->pTransportAddress = NULL;
  376. pAddress->pReceiveMdl = NULL;
  377. }
  378. } finally {
  379. if (AbnormalTermination()) {
  380. Status = STATUS_INVALID_PARAMETER;
  381. }
  382. }
  383. return Status;
  384. }
  385.