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.

1848 lines
48 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. cxdisp.c
  5. Abstract:
  6. Dispatch routines for the Cluster Transport.
  7. Author:
  8. Mike Massa (mikemas) July 29, 1996
  9. Revision History:
  10. Who When What
  11. -------- -------- ----------------------------------------------
  12. mikemas 07-29-96 created
  13. Notes:
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #include "cxdisp.tmh"
  18. #include <align.h>
  19. #include <strsafe.h>
  20. //
  21. // Local Prototypes
  22. //
  23. NTSTATUS
  24. CxDispatchRegisterNode(
  25. IN PIRP Irp,
  26. IN PIO_STACK_LOCATION IrpSp
  27. );
  28. NTSTATUS
  29. CxDispatchDeregisterNode(
  30. IN PIRP Irp,
  31. IN PIO_STACK_LOCATION IrpSp
  32. );
  33. NTSTATUS
  34. CxDispatchRegisterNetwork(
  35. IN PIRP Irp,
  36. IN PIO_STACK_LOCATION IrpSp
  37. );
  38. NTSTATUS
  39. CxDispatchDeregisterNetwork(
  40. IN PIRP Irp,
  41. IN PIO_STACK_LOCATION IrpSp
  42. );
  43. NTSTATUS
  44. CxDispatchRegisterInterface(
  45. IN PIRP Irp,
  46. IN PIO_STACK_LOCATION IrpSp
  47. );
  48. NTSTATUS
  49. CxDispatchDeregisterInterface(
  50. IN PIRP Irp,
  51. IN PIO_STACK_LOCATION IrpSp
  52. );
  53. NTSTATUS
  54. CxDispatchOnlineNodeComm(
  55. IN PIRP Irp,
  56. IN PIO_STACK_LOCATION IrpSp
  57. );
  58. NTSTATUS
  59. CxDispatchOfflineNodeComm(
  60. IN PIRP Irp,
  61. IN PIO_STACK_LOCATION IrpSp
  62. );
  63. NTSTATUS
  64. CxDispatchOnlineNetwork(
  65. IN PIRP Irp,
  66. IN PIO_STACK_LOCATION IrpSp
  67. );
  68. NTSTATUS
  69. CxDispatchOfflineNetwork(
  70. IN PIRP Irp,
  71. IN PIO_STACK_LOCATION IrpSp
  72. );
  73. NTSTATUS
  74. CxDispatchSetNetworkRestriction(
  75. IN PIRP Irp,
  76. IN PIO_STACK_LOCATION IrpSp
  77. );
  78. NTSTATUS
  79. CxDispatchGetNetworkPriority(
  80. IN PIRP Irp,
  81. IN PIO_STACK_LOCATION IrpSp
  82. );
  83. NTSTATUS
  84. CxDispatchSetNetworkPriority(
  85. IN PIRP Irp,
  86. IN PIO_STACK_LOCATION IrpSp
  87. );
  88. NTSTATUS
  89. CxDispatchGetInterfacePriority(
  90. IN PIRP Irp,
  91. IN PIO_STACK_LOCATION IrpSp
  92. );
  93. NTSTATUS
  94. CxDispatchSetInterfacePriority(
  95. IN PIRP Irp,
  96. IN PIO_STACK_LOCATION IrpSp
  97. );
  98. NTSTATUS
  99. CxDispatchGetNodeState(
  100. IN PIRP Irp,
  101. IN PIO_STACK_LOCATION IrpSp
  102. );
  103. NTSTATUS
  104. CxDispatchGetNetworkState(
  105. IN PIRP Irp,
  106. IN PIO_STACK_LOCATION IrpSp
  107. );
  108. NTSTATUS
  109. CxDispatchGetInterfaceState(
  110. IN PIRP Irp,
  111. IN PIO_STACK_LOCATION IrpSp
  112. );
  113. NTSTATUS
  114. CxDispatchIgnoreNodeState(
  115. IN PIRP Irp,
  116. IN PIO_STACK_LOCATION IrpSp
  117. );
  118. NTSTATUS
  119. CxDispatchGetNodeMembershipState(
  120. IN PIRP Irp,
  121. IN PIO_STACK_LOCATION IrpSp
  122. );
  123. NTSTATUS
  124. CxDispatchSetNodeMembershipState(
  125. IN PIRP Irp,
  126. IN PIO_STACK_LOCATION IrpSp
  127. );
  128. NTSTATUS
  129. CxDispatchSendPoisonPacket(
  130. IN PIRP Irp,
  131. IN PIO_STACK_LOCATION IrpSp
  132. );
  133. NTSTATUS
  134. CxDispatchSetOuterscreen(
  135. IN PIRP Irp,
  136. IN PIO_STACK_LOCATION IrpSp
  137. );
  138. NTSTATUS
  139. CxDispatchRegroupFinished(
  140. IN PIRP Irp,
  141. IN PIO_STACK_LOCATION IrpSp
  142. );
  143. NTSTATUS
  144. CxDispatchImportSecurityContext(
  145. IN PIRP Irp,
  146. IN PIO_STACK_LOCATION IrpSp
  147. );
  148. NTSTATUS
  149. CxDispatchReserveClusnetEndpoint(
  150. IN PIRP Irp,
  151. IN PIO_STACK_LOCATION IrpSp
  152. );
  153. NTSTATUS
  154. CxDispatchConfigureMulticast(
  155. IN PIRP Irp,
  156. IN PIO_STACK_LOCATION IrpSp
  157. );
  158. NTSTATUS
  159. CxDispatchGetMulticastReachableSet(
  160. IN PIRP Irp,
  161. IN PIO_STACK_LOCATION IrpSp
  162. );
  163. #if DBG
  164. NTSTATUS
  165. CxDispatchOnlinePendingInterface(
  166. IN PIRP Irp,
  167. IN PIO_STACK_LOCATION IrpSp
  168. );
  169. NTSTATUS
  170. CxDispatchOnlineInterface(
  171. IN PIRP Irp,
  172. IN PIO_STACK_LOCATION IrpSp
  173. );
  174. NTSTATUS
  175. CxDispatchOfflineInterface(
  176. IN PIRP Irp,
  177. IN PIO_STACK_LOCATION IrpSp
  178. );
  179. NTSTATUS
  180. CxDispatchFailInterface(
  181. IN PIRP Irp,
  182. IN PIO_STACK_LOCATION IrpSp
  183. );
  184. NTSTATUS
  185. CxDispatchSendMmMsg(
  186. IN PIRP Irp,
  187. IN PIO_STACK_LOCATION IrpSp
  188. );
  189. #endif // DBG
  190. #ifdef ALLOC_PRAGMA
  191. #pragma alloc_text(PAGE, CxDispatchDeviceControl)
  192. #pragma alloc_text(PAGE, CxDispatchRegisterNode)
  193. #pragma alloc_text(PAGE, CxDispatchDeregisterNode)
  194. #pragma alloc_text(PAGE, CxDispatchRegisterNetwork)
  195. #pragma alloc_text(PAGE, CxDispatchDeregisterNetwork)
  196. #pragma alloc_text(PAGE, CxDispatchRegisterInterface)
  197. #pragma alloc_text(PAGE, CxDispatchDeregisterInterface)
  198. #pragma alloc_text(PAGE, CxDispatchOnlineNodeComm)
  199. #pragma alloc_text(PAGE, CxDispatchOfflineNodeComm)
  200. #pragma alloc_text(PAGE, CxDispatchOnlineNetwork)
  201. #pragma alloc_text(PAGE, CxDispatchOfflineNetwork)
  202. #pragma alloc_text(PAGE, CxDispatchSetNetworkRestriction)
  203. #pragma alloc_text(PAGE, CxDispatchGetNetworkPriority)
  204. #pragma alloc_text(PAGE, CxDispatchSetNetworkPriority)
  205. #pragma alloc_text(PAGE, CxDispatchGetInterfacePriority)
  206. #pragma alloc_text(PAGE, CxDispatchSetInterfacePriority)
  207. #pragma alloc_text(PAGE, CxDispatchGetNodeState)
  208. #pragma alloc_text(PAGE, CxDispatchGetNetworkState)
  209. #pragma alloc_text(PAGE, CxDispatchGetInterfaceState)
  210. #pragma alloc_text(PAGE, CxDispatchGetNodeMembershipState)
  211. #pragma alloc_text(PAGE, CxDispatchSetNodeMembershipState)
  212. #pragma alloc_text(PAGE, CxDispatchSendPoisonPacket)
  213. #pragma alloc_text(PAGE, CxDispatchSetOuterscreen)
  214. #pragma alloc_text(PAGE, CxDispatchRegroupFinished)
  215. #pragma alloc_text(PAGE, CxDispatchImportSecurityContext)
  216. #pragma alloc_text(PAGE, CxDispatchReserveClusnetEndpoint)
  217. #pragma alloc_text(PAGE, CxDispatchConfigureMulticast)
  218. #pragma alloc_text(PAGE, CxDispatchGetMulticastReachableSet)
  219. #if DBG
  220. #pragma alloc_text(PAGE, CxDispatchOnlinePendingInterface)
  221. #pragma alloc_text(PAGE, CxDispatchOnlineInterface)
  222. #pragma alloc_text(PAGE, CxDispatchOfflineInterface)
  223. #pragma alloc_text(PAGE, CxDispatchFailInterface)
  224. #ifdef MM_IN_CLUSNET
  225. #pragma alloc_text(PAGE, CxDispatchSendMmMsg)
  226. #endif // MM_IN_CLUSNET
  227. #endif // DBG
  228. #endif // ALLOC_PRAGMA
  229. NTSTATUS
  230. CxDispatchDeviceControl(
  231. IN PIRP Irp,
  232. IN PIO_STACK_LOCATION IrpSp
  233. )
  234. /*++
  235. Routine Description:
  236. Dispatch routine for device control ioctls.
  237. Arguments:
  238. Irp - Pointer to I/O request packet
  239. IrpSp - Pointer to the current stack location in the Irp.
  240. Return Value:
  241. NTSTATUS -- Indicates whether the request was successfully queued.
  242. Notes:
  243. Any IRP for which the return value is not STATUS_PENDING will be
  244. completed by the calling routine.
  245. --*/
  246. {
  247. NTSTATUS status;
  248. PAGED_CODE();
  249. switch(IrpSp->Parameters.DeviceIoControl.IoControlCode) {
  250. case IOCTL_CX_REGISTER_NODE:
  251. status = CxDispatchRegisterNode(Irp, IrpSp);
  252. break;
  253. case IOCTL_CX_DEREGISTER_NODE:
  254. status = CxDispatchDeregisterNode(Irp, IrpSp);
  255. break;
  256. case IOCTL_CX_REGISTER_NETWORK:
  257. status = CxDispatchRegisterNetwork(Irp, IrpSp);
  258. break;
  259. case IOCTL_CX_DEREGISTER_NETWORK:
  260. status = CxDispatchDeregisterNetwork(Irp, IrpSp);
  261. break;
  262. case IOCTL_CX_REGISTER_INTERFACE:
  263. status = CxDispatchRegisterInterface(Irp, IrpSp);
  264. break;
  265. case IOCTL_CX_DEREGISTER_INTERFACE:
  266. status = CxDispatchDeregisterInterface(Irp, IrpSp);
  267. break;
  268. case IOCTL_CX_ONLINE_NODE_COMM:
  269. status = CxDispatchOnlineNodeComm(Irp, IrpSp);
  270. break;
  271. case IOCTL_CX_OFFLINE_NODE_COMM:
  272. status = CxDispatchOfflineNodeComm(Irp, IrpSp);
  273. break;
  274. case IOCTL_CX_ONLINE_NETWORK:
  275. status = CxDispatchOnlineNetwork(Irp, IrpSp);
  276. break;
  277. case IOCTL_CX_OFFLINE_NETWORK:
  278. status = CxDispatchOfflineNetwork(Irp, IrpSp);
  279. break;
  280. case IOCTL_CX_SET_NETWORK_RESTRICTION:
  281. status = CxDispatchSetNetworkRestriction(Irp, IrpSp);
  282. break;
  283. case IOCTL_CX_GET_NETWORK_PRIORITY:
  284. status = CxDispatchGetNetworkPriority(Irp, IrpSp);
  285. break;
  286. case IOCTL_CX_SET_NETWORK_PRIORITY:
  287. status = CxDispatchSetNetworkPriority(Irp, IrpSp);
  288. break;
  289. case IOCTL_CX_GET_INTERFACE_PRIORITY:
  290. status = CxDispatchGetInterfacePriority(Irp, IrpSp);
  291. break;
  292. case IOCTL_CX_SET_INTERFACE_PRIORITY:
  293. status = CxDispatchSetInterfacePriority(Irp, IrpSp);
  294. break;
  295. case IOCTL_CX_GET_NODE_STATE:
  296. status = CxDispatchGetNodeState(Irp, IrpSp);
  297. break;
  298. case IOCTL_CX_GET_NETWORK_STATE:
  299. status = CxDispatchGetNetworkState(Irp, IrpSp);
  300. break;
  301. case IOCTL_CX_GET_INTERFACE_STATE:
  302. status = CxDispatchGetInterfaceState(Irp, IrpSp);
  303. break;
  304. case IOCTL_CX_IGNORE_NODE_STATE:
  305. status = CxDispatchIgnoreNodeState(Irp, IrpSp);
  306. break;
  307. case IOCTL_CX_GET_NODE_MMSTATE:
  308. status = CxDispatchGetNodeMembershipState(Irp, IrpSp);
  309. break;
  310. case IOCTL_CX_SET_NODE_MMSTATE:
  311. status = CxDispatchSetNodeMembershipState(Irp, IrpSp);
  312. break;
  313. case IOCTL_CX_SEND_POISON_PACKET:
  314. status = CxDispatchSendPoisonPacket(Irp, IrpSp);
  315. break;
  316. case IOCTL_CX_SET_OUTERSCREEN:
  317. status = CxDispatchSetOuterscreen(Irp, IrpSp);
  318. break;
  319. case IOCTL_CX_REGROUP_FINISHED:
  320. status = CxDispatchRegroupFinished(Irp, IrpSp);
  321. break;
  322. case IOCTL_CX_IMPORT_SECURITY_CONTEXTS:
  323. status = CxDispatchImportSecurityContext(Irp, IrpSp);
  324. break;
  325. case IOCTL_CX_RESERVE_ENDPOINT:
  326. status = CxDispatchReserveClusnetEndpoint(Irp, IrpSp);
  327. break;
  328. case IOCTL_CX_CONFIGURE_MULTICAST:
  329. status = CxDispatchConfigureMulticast(Irp, IrpSp);
  330. break;
  331. case IOCTL_CX_GET_MULTICAST_REACHABLE_SET:
  332. status = CxDispatchGetMulticastReachableSet(Irp, IrpSp);
  333. break;
  334. #if DBG
  335. case IOCTL_CX_ONLINE_PENDING_INTERFACE:
  336. status = CxDispatchOnlinePendingInterface(Irp, IrpSp);
  337. break;
  338. case IOCTL_CX_ONLINE_INTERFACE:
  339. status = CxDispatchOnlineInterface(Irp, IrpSp);
  340. break;
  341. case IOCTL_CX_OFFLINE_INTERFACE:
  342. status = CxDispatchOfflineInterface(Irp, IrpSp);
  343. break;
  344. case IOCTL_CX_FAIL_INTERFACE:
  345. status = CxDispatchFailInterface(Irp, IrpSp);
  346. break;
  347. #ifdef MM_IN_CLUSNET
  348. case IOCTL_CX_SEND_MM_MSG:
  349. status = CxDispatchSendMmMsg(Irp, IrpSp);
  350. break;
  351. #endif // MM_IN_CLUSNET
  352. #endif // DBG
  353. default:
  354. status = STATUS_INVALID_DEVICE_REQUEST;
  355. break;
  356. }
  357. return(status);
  358. } // CxDispatchDeviceControl
  359. NTSTATUS
  360. CxDispatchRegisterNode(
  361. IN PIRP Irp,
  362. IN PIO_STACK_LOCATION IrpSp
  363. )
  364. {
  365. NTSTATUS status;
  366. PCX_NODE_REG_REQUEST request;
  367. ULONG requestSize;
  368. PAGED_CODE();
  369. request = (PCX_NODE_REG_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  370. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  371. if (requestSize < sizeof(CX_NODE_REG_REQUEST)) {
  372. return(STATUS_INVALID_PARAMETER);
  373. }
  374. status = CxRegisterNode(
  375. request->Id
  376. );
  377. return(status);
  378. } // CxDispatchRegisterNode
  379. NTSTATUS
  380. CxDispatchDeregisterNode(
  381. IN PIRP Irp,
  382. IN PIO_STACK_LOCATION IrpSp
  383. )
  384. {
  385. NTSTATUS status;
  386. PCX_NODE_DEREG_REQUEST request;
  387. ULONG requestSize;
  388. PAGED_CODE();
  389. request = (PCX_NODE_DEREG_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  390. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  391. if (requestSize < sizeof(CX_NODE_DEREG_REQUEST)) {
  392. return(STATUS_INVALID_PARAMETER);
  393. }
  394. status = CxDeregisterNode(request->Id, Irp, IrpSp);
  395. return(status);
  396. } // CxDispatchDeregisterNode
  397. NTSTATUS
  398. CxDispatchRegisterNetwork(
  399. IN PIRP Irp,
  400. IN PIO_STACK_LOCATION IrpSp
  401. )
  402. {
  403. NTSTATUS status;
  404. PCX_NETWORK_REG_REQUEST request;
  405. ULONG requestSize;
  406. PAGED_CODE();
  407. request = (PCX_NETWORK_REG_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  408. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  409. if (requestSize < sizeof(CX_NETWORK_REG_REQUEST)) {
  410. return(STATUS_INVALID_PARAMETER);
  411. }
  412. status = CxRegisterNetwork(
  413. request->Id,
  414. request->Priority,
  415. request->Restricted
  416. );
  417. return(status);
  418. } // CxDispatchRegisterNetwork
  419. NTSTATUS
  420. CxDispatchDeregisterNetwork(
  421. IN PIRP Irp,
  422. IN PIO_STACK_LOCATION IrpSp
  423. )
  424. {
  425. NTSTATUS status;
  426. PCX_NETWORK_DEREG_REQUEST request;
  427. ULONG requestSize;
  428. PAGED_CODE();
  429. request = (PCX_NETWORK_DEREG_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  430. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  431. if (requestSize < sizeof(CX_NETWORK_DEREG_REQUEST)) {
  432. return(STATUS_INVALID_PARAMETER);
  433. }
  434. status = CxDeregisterNetwork(request->Id, Irp, IrpSp);
  435. return(status);
  436. } // CxDispatchDeregisterNetwork
  437. NTSTATUS
  438. CxDispatchRegisterInterface(
  439. IN PIRP Irp,
  440. IN PIO_STACK_LOCATION IrpSp
  441. )
  442. {
  443. NTSTATUS status;
  444. PCX_INTERFACE_REG_REQUEST request;
  445. ULONG requestSize, resid;
  446. PCX_INTERFACE_REG_RESPONSE response;
  447. ULONG responseSize;
  448. PWCHAR adapterId;
  449. PAGED_CODE();
  450. // Verify that the request buffer has sufficient size, given the
  451. // offsets and lengths.
  452. request = (PCX_INTERFACE_REG_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  453. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  454. if (requestSize < sizeof(CX_INTERFACE_REG_REQUEST)) {
  455. return(STATUS_INVALID_PARAMETER);
  456. }
  457. response = (PCX_INTERFACE_REG_RESPONSE) Irp->AssociatedIrp.SystemBuffer;
  458. responseSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  459. if (responseSize < sizeof(CX_INTERFACE_REG_RESPONSE)) {
  460. return(STATUS_INVALID_PARAMETER);
  461. }
  462. resid = requestSize
  463. - FIELD_OFFSET(CX_INTERFACE_REG_REQUEST, TdiAddress[0]);
  464. if (resid < request->TdiAddressLength) {
  465. return(STATUS_INVALID_PARAMETER);
  466. }
  467. resid -= request->TdiAddressLength;
  468. if (request->AdapterIdOffset
  469. < FIELD_OFFSET(CX_INTERFACE_REG_REQUEST, TdiAddress[0])
  470. + request->TdiAddressLength
  471. || request->AdapterIdOffset > requestSize) {
  472. return(STATUS_INVALID_PARAMETER);
  473. }
  474. if (resid < request->AdapterIdLength) {
  475. return(STATUS_INVALID_PARAMETER);
  476. }
  477. // Verify that the string offset is properly aligned
  478. adapterId = (PWCHAR)((PUCHAR)request + request->AdapterIdOffset);
  479. if (!POINTER_IS_ALIGNED(adapterId, TYPE_ALIGNMENT(WCHAR))) {
  480. return(STATUS_INVALID_PARAMETER);
  481. }
  482. status = CxRegisterInterface(
  483. request->NodeId,
  484. request->NetworkId,
  485. request->Priority,
  486. (PUWSTR)((PUCHAR)request + request->AdapterIdOffset),
  487. request->AdapterIdLength,
  488. request->TdiAddressLength,
  489. (PTRANSPORT_ADDRESS) &(request->TdiAddress[0]),
  490. &response->MediaStatus
  491. );
  492. if (NT_SUCCESS(status)) {
  493. Irp->IoStatus.Information = sizeof(CX_INTERFACE_REG_RESPONSE);
  494. }
  495. return(status);
  496. } // CxDispatchRegisterInterface
  497. NTSTATUS
  498. CxDispatchDeregisterInterface(
  499. IN PIRP Irp,
  500. IN PIO_STACK_LOCATION IrpSp
  501. )
  502. {
  503. NTSTATUS status;
  504. PCX_INTERFACE_DEREG_REQUEST request;
  505. ULONG requestSize;
  506. PAGED_CODE();
  507. request = (PCX_INTERFACE_DEREG_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  508. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  509. if (requestSize < sizeof(CX_INTERFACE_DEREG_REQUEST)) {
  510. return(STATUS_INVALID_PARAMETER);
  511. }
  512. status = CxDeregisterInterface(request->NodeId, request->NetworkId);
  513. return(status);
  514. } // CxDispatchDeregisterInterface
  515. NTSTATUS
  516. CxDispatchOnlineNodeComm(
  517. IN PIRP Irp,
  518. IN PIO_STACK_LOCATION IrpSp
  519. )
  520. {
  521. NTSTATUS status;
  522. PCX_ONLINE_NODE_COMM_REQUEST request;
  523. ULONG requestSize;
  524. PAGED_CODE();
  525. request = (PCX_ONLINE_NODE_COMM_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  526. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  527. if (requestSize < sizeof(CX_ONLINE_NODE_COMM_REQUEST)) {
  528. return(STATUS_INVALID_PARAMETER);
  529. }
  530. status = CxOnlineNodeComm(request->Id);
  531. return(status);
  532. } // CxDispatchOnlineNodeComm
  533. NTSTATUS
  534. CxDispatchOfflineNodeComm(
  535. IN PIRP Irp,
  536. IN PIO_STACK_LOCATION IrpSp
  537. )
  538. {
  539. NTSTATUS status;
  540. PCX_OFFLINE_NODE_COMM_REQUEST request;
  541. ULONG requestSize;
  542. PAGED_CODE();
  543. request = (PCX_OFFLINE_NODE_COMM_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  544. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  545. if (requestSize < sizeof(CX_OFFLINE_NODE_COMM_REQUEST)) {
  546. return(STATUS_INVALID_PARAMETER);
  547. }
  548. status = CxOfflineNodeComm(request->Id, Irp, IrpSp);
  549. return(status);
  550. } // CxDispatchOfflineNodeComm
  551. NTSTATUS
  552. CxDispatchOnlineNetwork(
  553. IN PIRP Irp,
  554. IN PIO_STACK_LOCATION IrpSp
  555. )
  556. {
  557. NTSTATUS status;
  558. PCX_ONLINE_NETWORK_REQUEST request;
  559. ULONG requestSize;
  560. PTDI_ADDRESS_INFO response;
  561. ULONG responseSize;
  562. ULONG requiredSize = sizeof(
  563. CX_ONLINE_NETWORK_REQUEST
  564. );
  565. PWCHAR tdiProviderName;
  566. PTRANSPORT_ADDRESS tdiBindAddress;
  567. PWCHAR adapterName;
  568. PAGED_CODE();
  569. //
  570. // Validate the request buffer
  571. //
  572. // First validate that the request buffer size matches the offsets
  573. // and lengths.
  574. request = (PCX_ONLINE_NETWORK_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  575. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  576. if (requestSize < requiredSize) {
  577. return(STATUS_INVALID_PARAMETER);
  578. }
  579. // Validate that all offset length pairs are within the request
  580. // buffer.
  581. if ( ( request->TdiProviderNameOffset + request->TdiProviderNameLength
  582. < request->TdiProviderNameOffset
  583. ) ||
  584. ( request->TdiProviderNameOffset + request->TdiProviderNameLength
  585. > requestSize
  586. ) ||
  587. ( request->TdiBindAddressOffset + request->TdiBindAddressLength
  588. < request->TdiBindAddressOffset
  589. ) ||
  590. ( request->TdiBindAddressOffset + request->TdiBindAddressLength
  591. > requestSize
  592. ) ||
  593. ( request->AdapterNameOffset + request->AdapterNameLength
  594. < request->AdapterNameOffset
  595. ) ||
  596. ( request->AdapterNameOffset + request->AdapterNameLength
  597. > requestSize
  598. )
  599. )
  600. {
  601. return(STATUS_INVALID_PARAMETER);
  602. }
  603. // Construct pointers to the parameters.
  604. tdiBindAddress = (PTRANSPORT_ADDRESS)
  605. ( ((PUCHAR) request) + request->TdiBindAddressOffset );
  606. tdiProviderName = (PWCHAR)
  607. ( ((PUCHAR) request) + request->TdiProviderNameOffset );
  608. adapterName = (PWCHAR)
  609. ( ((PUCHAR) request) + request->AdapterNameOffset );
  610. // Validate that the resulting pointers are properly aligned and
  611. // within the request buffer.
  612. if ( ( ((PUCHAR) tdiBindAddress) < ((PUCHAR) request) ) ||
  613. ( ((PUCHAR) tdiBindAddress) > ((PUCHAR) request) + requestSize ) ||
  614. ( !POINTER_IS_ALIGNED(tdiBindAddress,
  615. TYPE_ALIGNMENT(TRANSPORT_ADDRESS)) ) ||
  616. ( ((PUCHAR) tdiProviderName) < ((PUCHAR) request) ) ||
  617. ( ((PUCHAR) tdiProviderName) > ((PUCHAR) request) + requestSize ) ||
  618. ( !POINTER_IS_ALIGNED(tdiProviderName, TYPE_ALIGNMENT(WCHAR)) ) ||
  619. ( ((PUCHAR) adapterName) < ((PUCHAR) request) ) ||
  620. ( ((PUCHAR) adapterName) > ((PUCHAR) request) + requestSize ) ||
  621. ( !POINTER_IS_ALIGNED(adapterName, TYPE_ALIGNMENT(WCHAR)) )
  622. )
  623. {
  624. return(STATUS_INVALID_PARAMETER);
  625. }
  626. // Validate that name strings are null-terminated. The length
  627. // fields in the request structure are byte counts, but
  628. // StringCchLengthW takes a character count.
  629. if (
  630. (StringCchLengthW(
  631. tdiProviderName,
  632. request->TdiProviderNameLength / sizeof(WCHAR),
  633. NULL
  634. ) != S_OK) ||
  635. (StringCchLengthW(
  636. adapterName,
  637. request->AdapterNameLength / sizeof(WCHAR),
  638. NULL
  639. ) != S_OK)
  640. )
  641. {
  642. return(STATUS_INVALID_PARAMETER);
  643. }
  644. //
  645. // Validate the response buffer
  646. //
  647. response = (PTDI_ADDRESS_INFO) Irp->AssociatedIrp.SystemBuffer;
  648. responseSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  649. requiredSize = FIELD_OFFSET(TDI_ADDRESS_INFO, Address) +
  650. request->TdiBindAddressLength;
  651. if (responseSize < requiredSize) {
  652. return(STATUS_INVALID_PARAMETER);
  653. }
  654. status = CxOnlineNetwork(
  655. request->Id,
  656. tdiProviderName,
  657. request->TdiProviderNameLength,
  658. tdiBindAddress,
  659. request->TdiBindAddressLength,
  660. adapterName,
  661. request->AdapterNameLength,
  662. response,
  663. responseSize,
  664. Irp
  665. );
  666. if (NT_SUCCESS(status)) {
  667. Irp->IoStatus.Information = responseSize;
  668. }
  669. return(status);
  670. } // CxDispatchOnlineNetwork
  671. NTSTATUS
  672. CxDispatchOfflineNetwork(
  673. IN PIRP Irp,
  674. IN PIO_STACK_LOCATION IrpSp
  675. )
  676. {
  677. NTSTATUS status;
  678. PCX_OFFLINE_NETWORK_REQUEST request;
  679. ULONG requestSize;
  680. PAGED_CODE();
  681. request = (PCX_OFFLINE_NETWORK_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  682. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  683. if (requestSize < sizeof(CX_OFFLINE_NETWORK_REQUEST)) {
  684. return(STATUS_INVALID_PARAMETER);
  685. }
  686. status = CxOfflineNetwork(request->Id, Irp, IrpSp);
  687. return(status);
  688. } // CxDispatchOfflineNetwork
  689. NTSTATUS
  690. CxDispatchSetNetworkRestriction(
  691. IN PIRP Irp,
  692. IN PIO_STACK_LOCATION IrpSp
  693. )
  694. {
  695. NTSTATUS status;
  696. ULONG requestSize;
  697. PCX_SET_NETWORK_RESTRICTION_REQUEST request;
  698. PAGED_CODE();
  699. request = (PCX_SET_NETWORK_RESTRICTION_REQUEST)
  700. Irp->AssociatedIrp.SystemBuffer;
  701. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  702. if (requestSize < sizeof(CX_SET_NETWORK_RESTRICTION_REQUEST)) {
  703. return(STATUS_INVALID_PARAMETER);
  704. }
  705. status = CxSetNetworkRestriction(
  706. request->Id,
  707. request->Restricted,
  708. request->NewPriority
  709. );
  710. return(status);
  711. } // CxDispatchSetNetworkRestriction
  712. NTSTATUS
  713. CxDispatchGetNetworkPriority(
  714. IN PIRP Irp,
  715. IN PIO_STACK_LOCATION IrpSp
  716. )
  717. {
  718. NTSTATUS status;
  719. PCX_GET_NETWORK_PRIORITY_REQUEST request;
  720. PCX_GET_NETWORK_PRIORITY_RESPONSE response;
  721. ULONG requestSize;
  722. ULONG responseSize;
  723. PAGED_CODE();
  724. request = (PCX_GET_NETWORK_PRIORITY_REQUEST)
  725. Irp->AssociatedIrp.SystemBuffer;
  726. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  727. response = (PCX_GET_NETWORK_PRIORITY_RESPONSE) request;
  728. responseSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  729. if ( (requestSize < sizeof(CX_GET_NETWORK_PRIORITY_REQUEST)) ||
  730. (responseSize < sizeof(CX_GET_NETWORK_PRIORITY_RESPONSE))
  731. )
  732. {
  733. return(STATUS_INVALID_PARAMETER);
  734. }
  735. status = CxGetNetworkPriority(
  736. request->Id,
  737. &(response->Priority)
  738. );
  739. if (status == STATUS_SUCCESS) {
  740. Irp->IoStatus.Information = sizeof(CX_GET_NETWORK_PRIORITY_RESPONSE);
  741. }
  742. return(status);
  743. } // CxDispatchGetNetworkPriority
  744. NTSTATUS
  745. CxDispatchSetNetworkPriority(
  746. IN PIRP Irp,
  747. IN PIO_STACK_LOCATION IrpSp
  748. )
  749. {
  750. NTSTATUS status;
  751. ULONG requestSize;
  752. PCX_SET_NETWORK_PRIORITY_REQUEST request;
  753. PAGED_CODE();
  754. request = (PCX_SET_NETWORK_PRIORITY_REQUEST)
  755. Irp->AssociatedIrp.SystemBuffer;
  756. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  757. if (requestSize < sizeof(CX_SET_NETWORK_PRIORITY_REQUEST)) {
  758. return(STATUS_INVALID_PARAMETER);
  759. }
  760. status = CxSetNetworkPriority(
  761. request->Id,
  762. request->Priority
  763. );
  764. return(status);
  765. } // CxDispatchSetNetworkPriority
  766. NTSTATUS
  767. CxDispatchGetInterfacePriority(
  768. IN PIRP Irp,
  769. IN PIO_STACK_LOCATION IrpSp
  770. )
  771. {
  772. NTSTATUS status;
  773. PCX_GET_INTERFACE_PRIORITY_REQUEST request;
  774. PCX_GET_INTERFACE_PRIORITY_RESPONSE response;
  775. ULONG requestSize;
  776. ULONG responseSize;
  777. PAGED_CODE();
  778. request = (PCX_GET_INTERFACE_PRIORITY_REQUEST)
  779. Irp->AssociatedIrp.SystemBuffer;
  780. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  781. response = (PCX_GET_INTERFACE_PRIORITY_RESPONSE) request;
  782. responseSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  783. if ( (requestSize < sizeof(CX_GET_INTERFACE_PRIORITY_REQUEST)) ||
  784. (responseSize < sizeof(CX_GET_INTERFACE_PRIORITY_RESPONSE))
  785. )
  786. {
  787. return(STATUS_INVALID_PARAMETER);
  788. }
  789. status = CxGetInterfacePriority(
  790. request->NodeId,
  791. request->NetworkId,
  792. &(response->InterfacePriority),
  793. &(response->NetworkPriority)
  794. );
  795. if (status == STATUS_SUCCESS) {
  796. Irp->IoStatus.Information = sizeof(CX_GET_INTERFACE_PRIORITY_RESPONSE);
  797. }
  798. return(status);
  799. } // CxDispatchGetInterfacePriority
  800. NTSTATUS
  801. CxDispatchSetInterfacePriority(
  802. IN PIRP Irp,
  803. IN PIO_STACK_LOCATION IrpSp
  804. )
  805. {
  806. NTSTATUS status;
  807. ULONG requestSize;
  808. PCX_SET_INTERFACE_PRIORITY_REQUEST request;
  809. PAGED_CODE();
  810. request = (PCX_SET_INTERFACE_PRIORITY_REQUEST)
  811. Irp->AssociatedIrp.SystemBuffer;
  812. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  813. if (requestSize < sizeof(CX_SET_INTERFACE_PRIORITY_REQUEST)) {
  814. return(STATUS_INVALID_PARAMETER);
  815. }
  816. status = CxSetInterfacePriority(
  817. request->NodeId,
  818. request->NetworkId,
  819. request->Priority
  820. );
  821. return(status);
  822. } // CxDispatchSetInterfacePriority
  823. NTSTATUS
  824. CxDispatchGetNodeState(
  825. IN PIRP Irp,
  826. IN PIO_STACK_LOCATION IrpSp
  827. )
  828. {
  829. NTSTATUS status;
  830. PCX_GET_NODE_STATE_REQUEST request;
  831. PCX_GET_NODE_STATE_RESPONSE response;
  832. ULONG requestSize;
  833. ULONG responseSize;
  834. PAGED_CODE();
  835. request = (PCX_GET_NODE_STATE_REQUEST)
  836. Irp->AssociatedIrp.SystemBuffer;
  837. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  838. response = (PCX_GET_NODE_STATE_RESPONSE) request;
  839. responseSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  840. if ( (requestSize < sizeof(CX_GET_NODE_STATE_REQUEST)) ||
  841. (responseSize < sizeof(CX_GET_NODE_STATE_RESPONSE))
  842. )
  843. {
  844. return(STATUS_INVALID_PARAMETER);
  845. }
  846. status = CxGetNodeCommState(
  847. request->Id,
  848. &(response->State)
  849. );
  850. if (status == STATUS_SUCCESS) {
  851. Irp->IoStatus.Information = sizeof(CX_GET_NODE_STATE_RESPONSE);
  852. }
  853. return(status);
  854. } // CxDispatchGetNodeState
  855. NTSTATUS
  856. CxDispatchGetNetworkState(
  857. IN PIRP Irp,
  858. IN PIO_STACK_LOCATION IrpSp
  859. )
  860. {
  861. NTSTATUS status;
  862. PCX_GET_NETWORK_STATE_REQUEST request;
  863. PCX_GET_NETWORK_STATE_RESPONSE response;
  864. ULONG requestSize;
  865. ULONG responseSize;
  866. PAGED_CODE();
  867. request = (PCX_GET_NETWORK_STATE_REQUEST)
  868. Irp->AssociatedIrp.SystemBuffer;
  869. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  870. response = (PCX_GET_NETWORK_STATE_RESPONSE) request;
  871. responseSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  872. if ( (requestSize < sizeof(CX_GET_NETWORK_STATE_REQUEST)) ||
  873. (responseSize < sizeof(CX_GET_NETWORK_STATE_RESPONSE))
  874. )
  875. {
  876. return(STATUS_INVALID_PARAMETER);
  877. }
  878. status = CxGetNetworkState(
  879. request->Id,
  880. &(response->State)
  881. );
  882. if (status == STATUS_SUCCESS) {
  883. Irp->IoStatus.Information = sizeof(CX_GET_NETWORK_STATE_RESPONSE);
  884. }
  885. return(status);
  886. } // CxDispatchGetNetworkState
  887. NTSTATUS
  888. CxDispatchGetInterfaceState(
  889. IN PIRP Irp,
  890. IN PIO_STACK_LOCATION IrpSp
  891. )
  892. {
  893. NTSTATUS status;
  894. PCX_GET_INTERFACE_STATE_REQUEST request;
  895. PCX_GET_INTERFACE_STATE_RESPONSE response;
  896. ULONG requestSize;
  897. ULONG responseSize;
  898. PAGED_CODE();
  899. request = (PCX_GET_INTERFACE_STATE_REQUEST)
  900. Irp->AssociatedIrp.SystemBuffer;
  901. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  902. response = (PCX_GET_INTERFACE_STATE_RESPONSE) request;
  903. responseSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  904. if ( (requestSize < sizeof(CX_GET_INTERFACE_STATE_REQUEST)) ||
  905. (responseSize < sizeof(CX_GET_INTERFACE_STATE_RESPONSE))
  906. )
  907. {
  908. return(STATUS_INVALID_PARAMETER);
  909. }
  910. status = CxGetInterfaceState(
  911. request->NodeId,
  912. request->NetworkId,
  913. &(response->State)
  914. );
  915. if (status == STATUS_SUCCESS) {
  916. Irp->IoStatus.Information = sizeof(CX_GET_INTERFACE_STATE_RESPONSE);
  917. }
  918. return(status);
  919. } // CxDispatchGetInterfaceState
  920. NTSTATUS
  921. CxDispatchIgnoreNodeState(
  922. IN PIRP Irp,
  923. IN PIO_STACK_LOCATION IrpSp
  924. )
  925. {
  926. PCX_ADDROBJ addrObj = (PCX_ADDROBJ) (IrpSp->FileObject->FsContext);
  927. CN_IRQL irql;
  928. CnAcquireLock(&(addrObj->Lock), &irql);
  929. IF_CNDBG(CN_DEBUG_ADDROBJ) {
  930. CNPRINT(("[CDP] Turning off checkstate flag on AO %p\n", addrObj));
  931. }
  932. addrObj->Flags &= ~(CX_AO_FLAG_CHECKSTATE);
  933. CnReleaseLock(&(addrObj->Lock), irql);
  934. return(STATUS_SUCCESS);
  935. } // CxDispatchIgnoreNodeState
  936. NTSTATUS
  937. CxDispatchGetNodeMembershipState(
  938. IN PIRP Irp,
  939. IN PIO_STACK_LOCATION IrpSp
  940. )
  941. {
  942. NTSTATUS status;
  943. PCX_GET_NODE_MMSTATE_REQUEST request;
  944. PCX_GET_NODE_MMSTATE_RESPONSE response;
  945. ULONG requestSize;
  946. ULONG responseSize;
  947. PAGED_CODE();
  948. request = (PCX_GET_NODE_MMSTATE_REQUEST)
  949. Irp->AssociatedIrp.SystemBuffer;
  950. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  951. response = (PCX_GET_NODE_MMSTATE_RESPONSE) request;
  952. responseSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  953. if ( (requestSize < sizeof(CX_GET_NODE_MMSTATE_REQUEST)) ||
  954. (responseSize < sizeof(CX_GET_NODE_MMSTATE_RESPONSE))
  955. )
  956. {
  957. return(STATUS_INVALID_PARAMETER);
  958. }
  959. status = CxGetNodeMembershipState( request->Id, &(response->State));
  960. if (status == STATUS_SUCCESS) {
  961. Irp->IoStatus.Information = sizeof(CX_GET_NODE_MMSTATE_RESPONSE);
  962. }
  963. return(status);
  964. } // CxDispatchGetNodeMembershipState
  965. NTSTATUS
  966. CxDispatchSetNodeMembershipState(
  967. IN PIRP Irp,
  968. IN PIO_STACK_LOCATION IrpSp
  969. )
  970. {
  971. NTSTATUS status;
  972. PCX_SET_NODE_MMSTATE_REQUEST request;
  973. ULONG requestSize;
  974. ULONG responseSize;
  975. PAGED_CODE();
  976. request = (PCX_SET_NODE_MMSTATE_REQUEST)
  977. Irp->AssociatedIrp.SystemBuffer;
  978. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  979. if (requestSize < sizeof( CX_SET_NODE_MMSTATE_REQUEST ) ||
  980. request->State >= ClusnetNodeStateLastEntry) {
  981. return(STATUS_INVALID_PARAMETER);
  982. }
  983. status = CxSetNodeMembershipState( request->NodeId, request->State );
  984. Irp->IoStatus.Information = 0;
  985. return(status);
  986. } // CxDispatchSetNodeMembershipState
  987. VOID
  988. CxCompleteSendPoisonPacket(
  989. IN NTSTATUS Status,
  990. IN ULONG BytesSent,
  991. IN PVOID Context,
  992. IN PVOID MessageData
  993. )
  994. {
  995. PIRP irp = Context;
  996. CnAssert(Status != STATUS_PENDING);
  997. IF_CNDBG(( CN_DEBUG_IRP | CN_DEBUG_POISON ))
  998. CNPRINT(("[Clusnet] Completing SendPoisonPacket request for "
  999. "irp %p, status %08X\n",
  1000. irp,
  1001. Status));
  1002. //
  1003. // The irp is completed in the CNP send completion routine.
  1004. //
  1005. return;
  1006. } // CxCompleteSendPoisonPacket
  1007. NTSTATUS
  1008. CxDispatchSendPoisonPacket(
  1009. IN PIRP Irp,
  1010. IN PIO_STACK_LOCATION IrpSp
  1011. )
  1012. {
  1013. NTSTATUS status;
  1014. PCX_SEND_POISON_PKT_REQUEST request;
  1015. ULONG requestSize;
  1016. PAGED_CODE();
  1017. request = (PCX_SEND_POISON_PKT_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  1018. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1019. //
  1020. // request size should exactly equal the size of the request struct plus
  1021. // the data passed in
  1022. //
  1023. if ( requestSize != sizeof(CX_SEND_POISON_PKT_REQUEST)) {
  1024. return(STATUS_INVALID_PARAMETER);
  1025. }
  1026. //
  1027. // We will always return pending, so mark the IRP pending.
  1028. // The IRP will be completed by CxCompleteSendPoisonPacket
  1029. //
  1030. IoMarkIrpPending(Irp);
  1031. IF_CNDBG(( CN_DEBUG_IRP | CN_DEBUG_POISON ))
  1032. CNPRINT(("[Clusnet] Posting SendPoisonPacket irp %p\n", Irp));
  1033. CxSendPoisonPacket(
  1034. request->Id,
  1035. CxCompleteSendPoisonPacket,
  1036. Irp,
  1037. Irp
  1038. );
  1039. return(STATUS_PENDING);
  1040. } // CxDispatchSendPoisonPacket
  1041. NTSTATUS
  1042. CxDispatchSetOuterscreen(
  1043. IN PIRP Irp,
  1044. IN PIO_STACK_LOCATION IrpSp
  1045. )
  1046. {
  1047. NTSTATUS status;
  1048. PCX_SET_OUTERSCREEN_REQUEST request;
  1049. ULONG requestSize;
  1050. ULONG responseSize;
  1051. PAGED_CODE();
  1052. request = (PCX_SET_OUTERSCREEN_REQUEST)
  1053. Irp->AssociatedIrp.SystemBuffer;
  1054. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1055. if ( requestSize < sizeof( CX_SET_OUTERSCREEN_REQUEST )) {
  1056. return(STATUS_INVALID_PARAMETER);
  1057. }
  1058. status = CxSetOuterscreen( request->Outerscreen );
  1059. Irp->IoStatus.Information = 0;
  1060. return(status);
  1061. } // CxDispatchSetOuterscreen
  1062. NTSTATUS
  1063. CxDispatchRegroupFinished(
  1064. IN PIRP Irp,
  1065. IN PIO_STACK_LOCATION IrpSp
  1066. )
  1067. {
  1068. NTSTATUS status;
  1069. PCX_REGROUP_FINISHED_REQUEST request;
  1070. ULONG requestSize;
  1071. ULONG responseSize;
  1072. PAGED_CODE();
  1073. request = (PCX_REGROUP_FINISHED_REQUEST)
  1074. Irp->AssociatedIrp.SystemBuffer;
  1075. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1076. if ( requestSize < sizeof( CX_REGROUP_FINISHED_REQUEST )) {
  1077. return(STATUS_INVALID_PARAMETER);
  1078. }
  1079. CxRegroupFinished( request->EventEpoch, request->RegroupEpoch );
  1080. Irp->IoStatus.Information = 0;
  1081. return( STATUS_SUCCESS );
  1082. } // CxDispatchRegroupFinished
  1083. NTSTATUS
  1084. CxDispatchImportSecurityContext(
  1085. IN PIRP Irp,
  1086. IN PIO_STACK_LOCATION IrpSp
  1087. )
  1088. {
  1089. NTSTATUS status;
  1090. PCX_IMPORT_SECURITY_CONTEXT_REQUEST request;
  1091. ULONG requestSize;
  1092. ULONG responseSize;
  1093. PAGED_CODE();
  1094. request = (PCX_IMPORT_SECURITY_CONTEXT_REQUEST)
  1095. Irp->AssociatedIrp.SystemBuffer;
  1096. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1097. if ( requestSize < sizeof( CX_IMPORT_SECURITY_CONTEXT_REQUEST )) {
  1098. return(STATUS_INVALID_PARAMETER);
  1099. }
  1100. status = CxImportSecurityContext(request->JoiningNodeId,
  1101. request->PackageName,
  1102. request->PackageNameSize,
  1103. request->SignatureSize,
  1104. request->ServerContext,
  1105. request->ClientContext);
  1106. Irp->IoStatus.Information = 0;
  1107. return( status );
  1108. } // CxDispatchImportSecurityContext
  1109. NTSTATUS
  1110. CxDispatchReserveClusnetEndpoint(
  1111. IN PIRP Irp,
  1112. IN PIO_STACK_LOCATION IrpSp
  1113. )
  1114. {
  1115. NTSTATUS status;
  1116. USHORT port;
  1117. ULONG requestSize;
  1118. PAGED_CODE();
  1119. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1120. if (requestSize < sizeof(USHORT)) {
  1121. status = STATUS_INVALID_PARAMETER;
  1122. }
  1123. else {
  1124. port = *((PUSHORT) Irp->AssociatedIrp.SystemBuffer);
  1125. status = CxReserveClusnetEndpoint(port);
  1126. }
  1127. Irp->IoStatus.Information = 0;
  1128. return (status);
  1129. }
  1130. NTSTATUS
  1131. CxDispatchConfigureMulticast(
  1132. IN PIRP Irp,
  1133. IN PIO_STACK_LOCATION IrpSp
  1134. )
  1135. {
  1136. NTSTATUS status;
  1137. PCX_CONFIGURE_MULTICAST_REQUEST request;
  1138. ULONG requestSize;
  1139. ULONG requiredSize;
  1140. PTRANSPORT_ADDRESS tdiMcastAddress;
  1141. PVOID key;
  1142. PAGED_CODE();
  1143. //
  1144. // Validate the request buffer
  1145. //
  1146. // First validate that the request buffer size matches the offsets
  1147. // and lengths.
  1148. request = (PCX_CONFIGURE_MULTICAST_REQUEST)Irp->AssociatedIrp.SystemBuffer;
  1149. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1150. //
  1151. // The required size is based on the size and required alignment
  1152. // of each field of data following the structure. If there is no
  1153. // data following the structure, only the structure is required.
  1154. //
  1155. requiredSize = sizeof(CX_CONFIGURE_MULTICAST_REQUEST);
  1156. //
  1157. // Verify that the required size is present.
  1158. //
  1159. if (requestSize < requiredSize)
  1160. {
  1161. return(STATUS_INVALID_PARAMETER);
  1162. }
  1163. //
  1164. // Verify that all offset length pairs are within the request size.
  1165. //
  1166. if ( ( request->MulticastAddress + request->MulticastAddressLength
  1167. < request->MulticastAddress
  1168. ) ||
  1169. ( request->MulticastAddress + request->MulticastAddressLength
  1170. > requestSize
  1171. ) ||
  1172. ( request->Key + request->KeyLength < request->Key
  1173. ) ||
  1174. ( request->Key + request->KeyLength > requestSize
  1175. )
  1176. )
  1177. {
  1178. return(STATUS_INVALID_PARAMETER);
  1179. }
  1180. //
  1181. // Construct pointers using the offsets.
  1182. //
  1183. tdiMcastAddress = (PTRANSPORT_ADDRESS)
  1184. ( ((PUCHAR) request) + request->MulticastAddress );
  1185. key = (PVOID)( ((PUCHAR) request) + request->Key );
  1186. //
  1187. // Validate that the resulting pointers are properly aligned and
  1188. // within the request data structure.
  1189. //
  1190. if ( ( ((PUCHAR) tdiMcastAddress) < ((PUCHAR) request) ) ||
  1191. ( ((PUCHAR) tdiMcastAddress) > ((PUCHAR) request) + requestSize ) ||
  1192. ( !POINTER_IS_ALIGNED(tdiMcastAddress,
  1193. TYPE_ALIGNMENT(TRANSPORT_ADDRESS))) ||
  1194. ( ((PUCHAR) key) < ((PUCHAR) request) ) ||
  1195. ( ((PUCHAR) key) > ((PUCHAR) request) + requestSize ) ||
  1196. ( !POINTER_IS_ALIGNED(key, TYPE_ALIGNMENT(PVOID)))
  1197. )
  1198. {
  1199. return(STATUS_INVALID_PARAMETER);
  1200. }
  1201. status = CxConfigureMulticast(
  1202. request->NetworkId,
  1203. request->MulticastNetworkBrand,
  1204. tdiMcastAddress,
  1205. request->MulticastAddressLength,
  1206. key,
  1207. request->KeyLength,
  1208. Irp
  1209. );
  1210. // No return data.
  1211. Irp->IoStatus.Information = 0;
  1212. return(status);
  1213. } // CxDispatchConfigureMulticast
  1214. NTSTATUS
  1215. CxDispatchGetMulticastReachableSet(
  1216. IN PIRP Irp,
  1217. IN PIO_STACK_LOCATION IrpSp
  1218. )
  1219. {
  1220. NTSTATUS status;
  1221. PCX_GET_MULTICAST_REACHABLE_SET_REQUEST request;
  1222. PCX_GET_MULTICAST_REACHABLE_SET_RESPONSE response;
  1223. ULONG requestSize;
  1224. ULONG responseSize;
  1225. PAGED_CODE();
  1226. request = (PCX_GET_MULTICAST_REACHABLE_SET_REQUEST)
  1227. Irp->AssociatedIrp.SystemBuffer;
  1228. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1229. response = (PCX_GET_MULTICAST_REACHABLE_SET_RESPONSE) request;
  1230. responseSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  1231. if ( (requestSize < sizeof(PCX_GET_MULTICAST_REACHABLE_SET_REQUEST)) ||
  1232. (responseSize < sizeof(PCX_GET_MULTICAST_REACHABLE_SET_RESPONSE))
  1233. )
  1234. {
  1235. return(STATUS_INVALID_PARAMETER);
  1236. }
  1237. status = CxGetMulticastReachableSet(
  1238. request->Id,
  1239. &(response->NodeScreen)
  1240. );
  1241. if (status == STATUS_SUCCESS) {
  1242. Irp->IoStatus.Information =
  1243. sizeof(CX_GET_MULTICAST_REACHABLE_SET_RESPONSE);
  1244. }
  1245. return(status);
  1246. } // CxDispatchGetMulticastReachableSet
  1247. //
  1248. // Test IOCTLs.
  1249. //
  1250. #if DBG
  1251. NTSTATUS
  1252. CxDispatchOnlinePendingInterface(
  1253. IN PIRP Irp,
  1254. IN PIO_STACK_LOCATION IrpSp
  1255. )
  1256. {
  1257. NTSTATUS status;
  1258. PCX_ONLINE_PENDING_INTERFACE_REQUEST request;
  1259. ULONG requestSize;
  1260. PAGED_CODE();
  1261. request = (PCX_ONLINE_PENDING_INTERFACE_REQUEST)
  1262. Irp->AssociatedIrp.SystemBuffer;
  1263. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1264. if (requestSize < sizeof(CX_ONLINE_PENDING_INTERFACE_REQUEST)) {
  1265. return(STATUS_INVALID_PARAMETER);
  1266. }
  1267. status = CxOnlinePendingInterface(request->NodeId, request->NetworkId);
  1268. return(status);
  1269. } // CxDispatchOnlinePendingInterface
  1270. NTSTATUS
  1271. CxDispatchOnlineInterface(
  1272. IN PIRP Irp,
  1273. IN PIO_STACK_LOCATION IrpSp
  1274. )
  1275. {
  1276. NTSTATUS status;
  1277. PCX_ONLINE_PENDING_INTERFACE_REQUEST request;
  1278. ULONG requestSize;
  1279. PAGED_CODE();
  1280. request = (PCX_ONLINE_PENDING_INTERFACE_REQUEST)
  1281. Irp->AssociatedIrp.SystemBuffer;
  1282. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1283. if (requestSize < sizeof(CX_ONLINE_PENDING_INTERFACE_REQUEST)) {
  1284. return(STATUS_INVALID_PARAMETER);
  1285. }
  1286. status = CxOnlineInterface(request->NodeId, request->NetworkId);
  1287. return(status);
  1288. } // CxDispatchOnlineInterface
  1289. NTSTATUS
  1290. CxDispatchOfflineInterface(
  1291. IN PIRP Irp,
  1292. IN PIO_STACK_LOCATION IrpSp
  1293. )
  1294. {
  1295. NTSTATUS status;
  1296. PCX_ONLINE_PENDING_INTERFACE_REQUEST request;
  1297. ULONG requestSize;
  1298. PAGED_CODE();
  1299. request = (PCX_ONLINE_PENDING_INTERFACE_REQUEST)
  1300. Irp->AssociatedIrp.SystemBuffer;
  1301. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1302. if (requestSize < sizeof(CX_ONLINE_PENDING_INTERFACE_REQUEST)) {
  1303. return(STATUS_INVALID_PARAMETER);
  1304. }
  1305. status = CxOfflineInterface(request->NodeId, request->NetworkId);
  1306. return(status);
  1307. } // CxDispatchOfflineInterface
  1308. NTSTATUS
  1309. CxDispatchFailInterface(
  1310. IN PIRP Irp,
  1311. IN PIO_STACK_LOCATION IrpSp
  1312. )
  1313. {
  1314. NTSTATUS status;
  1315. PCX_ONLINE_PENDING_INTERFACE_REQUEST request;
  1316. ULONG requestSize;
  1317. PAGED_CODE();
  1318. request = (PCX_ONLINE_PENDING_INTERFACE_REQUEST)
  1319. Irp->AssociatedIrp.SystemBuffer;
  1320. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1321. if (requestSize < sizeof(CX_ONLINE_PENDING_INTERFACE_REQUEST)) {
  1322. return(STATUS_INVALID_PARAMETER);
  1323. }
  1324. status = CxFailInterface(request->NodeId, request->NetworkId);
  1325. return(status);
  1326. } // CxDispatchFailInterface
  1327. VOID
  1328. CxCompleteSendMmMsg(
  1329. IN NTSTATUS Status,
  1330. IN ULONG BytesSent,
  1331. IN PVOID Context,
  1332. IN PVOID MessageData
  1333. )
  1334. {
  1335. PIRP irp = Context;
  1336. CnAssert(Status != STATUS_PENDING);
  1337. CNPRINT((
  1338. "[Clusnet] Completing SendMmMsg irp %p, status %lx, bytes sent %u\n",
  1339. irp,
  1340. Status,
  1341. BytesSent
  1342. ));
  1343. //
  1344. // Complete the irp.
  1345. //
  1346. irp->IoStatus.Status = Status;
  1347. irp->IoStatus.Information = 0;
  1348. IoCompleteRequest(irp, IO_NETWORK_INCREMENT);
  1349. return;
  1350. } // CxCompleteSendMmMsg
  1351. #ifdef MM_IN_CLUSNET
  1352. NTSTATUS
  1353. CxDispatchSendMmMsg(
  1354. IN PIRP Irp,
  1355. IN PIO_STACK_LOCATION IrpSp
  1356. )
  1357. {
  1358. NTSTATUS status;
  1359. PCX_SEND_MM_MSG_REQUEST request;
  1360. ULONG requestSize;
  1361. PAGED_CODE();
  1362. request = (PCX_SEND_MM_MSG_REQUEST) Irp->AssociatedIrp.SystemBuffer;
  1363. requestSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1364. if (requestSize < sizeof(CX_SEND_MM_MSG_REQUEST)) {
  1365. return(STATUS_INVALID_PARAMETER);
  1366. }
  1367. IoMarkIrpPending(Irp);
  1368. CNPRINT(("[Clusnet] Posting SendMmMsg irp %p\n", Irp));
  1369. status = CxSendMembershipMessage(
  1370. request->DestNodeId,
  1371. &(request->MessageData[0]),
  1372. CX_MM_MSG_DATA_LEN,
  1373. CxCompleteSendMmMsg,
  1374. Irp
  1375. );
  1376. return(status);
  1377. } // CxDispatchSendMmMsg
  1378. #endif // MM_IN_CLUSNET
  1379. #endif // DBG