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.

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