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.

903 lines
25 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. ioctl.c
  5. Abstract:
  6. Implements resource and resource type IOCTL interfaces in
  7. the CLUSAPI.
  8. Author:
  9. John Vert (jvert) 10/9/1996
  10. Revision History:
  11. --*/
  12. #include "clusapip.h"
  13. DWORD
  14. WINAPI
  15. ClusterResourceControl(
  16. IN HRESOURCE hResource,
  17. IN OPTIONAL HNODE hHostNode,
  18. IN DWORD dwControlCode,
  19. IN LPVOID lpInBuffer,
  20. IN DWORD nInBufferSize,
  21. OUT LPVOID lpOutBuffer,
  22. IN DWORD nOutBufferSize,
  23. OUT LPDWORD lpBytesReturned
  24. )
  25. /*++
  26. Routine Description:
  27. Provides for arbitrary communication and control between an application
  28. and a specific instance of a resource.
  29. Arguments:
  30. hResource - Supplies a handle to the resource to be controlled.
  31. hHostNode - Supplies a handle to the node on which the resource
  32. control should be delivered. If this is NULL, the node where
  33. the resource is online is used.
  34. dwControlCode- Supplies the control code that defines the
  35. structure and action of the resource control.
  36. Values of dwControlCode between 0 and 0x10000000 are reserved
  37. for future definition and use by Microsoft. All other values
  38. are available for use by ISVs.
  39. lpInBuffer- Supplies a pointer to the input buffer to be passed
  40. to the resource.
  41. nInBufferSize- Supplies the size, in bytes, of the data pointed
  42. to by lpInBuffer.
  43. lpOutBuffer- Supplies a pointer to the output buffer to be
  44. filled in by the resource.
  45. nOutBufferSize- Supplies the size, in bytes, of the available
  46. space pointed to by lpOutBuffer.
  47. lpBytesReturned - Returns the number of bytes of lpOutBuffer
  48. actually filled in by the resource.
  49. Return Value:
  50. ERROR_SUCCESS if successful
  51. Win32 error code otherwise
  52. --*/
  53. {
  54. PCRESOURCE Resource;
  55. HNODE_RPC hDestNode;
  56. DWORD Status;
  57. DWORD Required;
  58. PVOID Buffer;
  59. DWORD Dummy;
  60. DWORD BytesReturned;
  61. Buffer = lpOutBuffer;
  62. if ((Buffer == NULL) &&
  63. (nOutBufferSize == 0)) {
  64. Buffer = &Dummy;
  65. }
  66. Resource = (PCRESOURCE)hResource;
  67. if (ARGUMENT_PRESENT(hHostNode)) {
  68. hDestNode = ((PCNODE)hHostNode)->hNode;
  69. WRAP(Status,
  70. (ApiNodeResourceControl(Resource->hResource,
  71. hDestNode,
  72. dwControlCode,
  73. lpInBuffer,
  74. nInBufferSize,
  75. Buffer,
  76. nOutBufferSize,
  77. &BytesReturned,
  78. &Required)),
  79. Resource->Cluster);
  80. } else {
  81. WRAP(Status,
  82. (ApiResourceControl(Resource->hResource,
  83. dwControlCode,
  84. lpInBuffer,
  85. nInBufferSize,
  86. Buffer,
  87. nOutBufferSize,
  88. &BytesReturned,
  89. &Required)),
  90. Resource->Cluster);
  91. }
  92. if ( (Status == ERROR_SUCCESS) ||
  93. (Status == ERROR_MORE_DATA) ) {
  94. if ( (Status == ERROR_MORE_DATA) &&
  95. (lpOutBuffer == NULL) ) {
  96. Status = ERROR_SUCCESS;
  97. }
  98. if ( !BytesReturned ) {
  99. BytesReturned = Required;
  100. }
  101. }
  102. if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
  103. *lpBytesReturned = BytesReturned;
  104. } else {
  105. if ( (Status == ERROR_SUCCESS) &&
  106. (BytesReturned > nOutBufferSize) ) {
  107. Status = ERROR_MORE_DATA;
  108. }
  109. }
  110. return(Status);
  111. }
  112. DWORD
  113. WINAPI
  114. ClusterResourceTypeControl(
  115. IN HCLUSTER hCluster,
  116. IN LPCWSTR lpszResourceTypeName,
  117. IN OPTIONAL HNODE hHostNode,
  118. IN DWORD dwControlCode,
  119. IN LPVOID lpInBuffer,
  120. IN DWORD nInBufferSize,
  121. OUT LPVOID lpOutBuffer,
  122. IN DWORD nOutBufferSize,
  123. OUT LPDWORD lpBytesReturned
  124. )
  125. /*++
  126. Routine Description:
  127. Provides for arbitrary communication and control between an application
  128. and a specific instance of a resource type.
  129. Arguments:
  130. lpszResourceTypename - Supplies the name of the resource type to be
  131. controlled.
  132. hHostNode - Supplies a handle to the node on which the resource type
  133. control should be delivered. If this is NULL, the node where
  134. the application is bound performs the request.
  135. dwControlCode- Supplies the control code that defines the
  136. structure and action of the resource type control.
  137. Values of dwControlCode between 0 and 0x10000000 are reserved
  138. for future definition and use by Microsoft. All other values
  139. are available for use by ISVs
  140. lpInBuffer- Supplies a pointer to the input buffer to be passed
  141. to the resource type.
  142. nInBufferSize- Supplies the size, in bytes, of the data pointed
  143. to by lpInBuffer.
  144. lpOutBuffer- Supplies a pointer to the output buffer to be
  145. filled in by the resource type.
  146. nOutBufferSize- Supplies the size, in bytes, of the available
  147. space pointed to by lpOutBuffer.
  148. lpBytesReturned - Returns the number of bytes of lpOutBuffer
  149. actually filled in by the resource type.
  150. Return Value:
  151. ERROR_SUCCESS if successful
  152. Win32 error code otherwise
  153. --*/
  154. {
  155. PCLUSTER Cluster;
  156. HNODE_RPC hDestNode;
  157. DWORD Status;
  158. DWORD Required;
  159. PVOID Buffer;
  160. DWORD Dummy;
  161. DWORD BytesReturned;
  162. Buffer = lpOutBuffer;
  163. if ((Buffer == NULL) &&
  164. (nOutBufferSize == 0)) {
  165. Buffer = &Dummy;
  166. }
  167. Cluster = (PCLUSTER)hCluster;
  168. if (ARGUMENT_PRESENT(hHostNode)) {
  169. hDestNode = ((PCNODE)hHostNode)->hNode;
  170. WRAP(Status,
  171. (ApiNodeResourceTypeControl(Cluster->hCluster,
  172. lpszResourceTypeName,
  173. hDestNode,
  174. dwControlCode,
  175. lpInBuffer,
  176. nInBufferSize,
  177. Buffer,
  178. nOutBufferSize,
  179. &BytesReturned,
  180. &Required)),
  181. Cluster);
  182. } else {
  183. WRAP(Status,
  184. (ApiResourceTypeControl(Cluster->hCluster,
  185. lpszResourceTypeName,
  186. dwControlCode,
  187. lpInBuffer,
  188. nInBufferSize,
  189. Buffer,
  190. nOutBufferSize,
  191. &BytesReturned,
  192. &Required)),
  193. Cluster);
  194. }
  195. if ( (Status == ERROR_SUCCESS) ||
  196. (Status == ERROR_MORE_DATA) ) {
  197. if ( (Status == ERROR_MORE_DATA) &&
  198. (lpOutBuffer == NULL) ) {
  199. Status = ERROR_SUCCESS;
  200. }
  201. if ( !BytesReturned ) {
  202. BytesReturned = Required;
  203. }
  204. }
  205. if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
  206. *lpBytesReturned = BytesReturned;
  207. } else {
  208. if ( (Status == ERROR_SUCCESS) &&
  209. (BytesReturned > nOutBufferSize) ) {
  210. Status = ERROR_MORE_DATA;
  211. }
  212. }
  213. return(Status);
  214. }
  215. DWORD
  216. WINAPI
  217. ClusterGroupControl(
  218. IN HGROUP hGroup,
  219. IN OPTIONAL HNODE hHostNode,
  220. IN DWORD dwControlCode,
  221. IN LPVOID lpInBuffer,
  222. IN DWORD nInBufferSize,
  223. OUT LPVOID lpOutBuffer,
  224. IN DWORD nOutBufferSize,
  225. OUT LPDWORD lpBytesReturned
  226. )
  227. /*++
  228. Routine Description:
  229. Provides for arbitrary communication and control between an application
  230. and a specific instance of a group.
  231. Arguments:
  232. hGroup - Supplies a handle to the group to be controlled.
  233. hHostNode - Supplies a handle to the node on which the group
  234. control should be delivered. If this is NULL, the node where
  235. the group is owned is used.
  236. dwControlCode- Supplies the control code that defines the
  237. structure and action of the resource control.
  238. Values of dwControlCode between 0 and 0x10000000 are reserved
  239. for future definition and use by Microsoft. All other values
  240. are available for use by ISVs.
  241. lpInBuffer- Supplies a pointer to the input buffer to be passed
  242. to the group.
  243. nInBufferSize- Supplies the size, in bytes, of the data pointed
  244. to by lpInBuffer.
  245. lpOutBuffer- Supplies a pointer to the output buffer to be
  246. filled in by the group.
  247. nOutBufferSize- Supplies the size, in bytes, of the available
  248. space pointed to by lpOutBuffer.
  249. lpBytesReturned - Returns the number of bytes of lpOutBuffer
  250. actually filled in by the resource.
  251. Return Value:
  252. ERROR_SUCCESS if successful
  253. Win32 error code otherwise
  254. --*/
  255. {
  256. PCGROUP Group;
  257. HNODE_RPC hDestNode;
  258. DWORD Status;
  259. DWORD Required;
  260. PVOID Buffer;
  261. DWORD Dummy;
  262. DWORD BytesReturned;
  263. Buffer = lpOutBuffer;
  264. if ((Buffer == NULL) &&
  265. (nOutBufferSize == 0)) {
  266. Buffer = &Dummy;
  267. }
  268. Group = (PCGROUP)hGroup;
  269. if (ARGUMENT_PRESENT(hHostNode)) {
  270. hDestNode = ((PCNODE)hHostNode)->hNode;
  271. WRAP(Status,
  272. (ApiNodeGroupControl(Group->hGroup,
  273. hDestNode,
  274. dwControlCode,
  275. lpInBuffer,
  276. nInBufferSize,
  277. Buffer,
  278. nOutBufferSize,
  279. &BytesReturned,
  280. &Required)),
  281. Group->Cluster);
  282. } else {
  283. WRAP(Status,
  284. (ApiGroupControl(Group->hGroup,
  285. dwControlCode,
  286. lpInBuffer,
  287. nInBufferSize,
  288. Buffer,
  289. nOutBufferSize,
  290. &BytesReturned,
  291. &Required)),
  292. Group->Cluster);
  293. }
  294. if ( (Status == ERROR_SUCCESS) ||
  295. (Status == ERROR_MORE_DATA) ) {
  296. if ( (Status == ERROR_MORE_DATA) &&
  297. (lpOutBuffer == NULL) ) {
  298. Status = ERROR_SUCCESS;
  299. }
  300. if ( !BytesReturned ) {
  301. BytesReturned = Required;
  302. }
  303. }
  304. if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
  305. *lpBytesReturned = BytesReturned;
  306. } else {
  307. if ( (Status == ERROR_SUCCESS) &&
  308. (BytesReturned > nOutBufferSize) ) {
  309. Status = ERROR_MORE_DATA;
  310. }
  311. }
  312. return(Status);
  313. }
  314. DWORD
  315. WINAPI
  316. ClusterNodeControl(
  317. IN HNODE hNode,
  318. IN OPTIONAL HNODE hHostNode,
  319. IN DWORD dwControlCode,
  320. IN LPVOID lpInBuffer,
  321. IN DWORD nInBufferSize,
  322. OUT LPVOID lpOutBuffer,
  323. IN DWORD nOutBufferSize,
  324. OUT LPDWORD lpBytesReturned
  325. )
  326. /*++
  327. Routine Description:
  328. Provides for arbitrary communication and control between an application
  329. and a specific instance of a node.
  330. Arguments:
  331. hNode - Supplies a handle to the node to be controlled.
  332. hHostNode - Supplies a handle to the node on which the node
  333. control should be delivered. If this is NULL, the node where
  334. the application is bound performs the request.
  335. dwControlCode- Supplies the control code that defines the
  336. structure and action of the resource control.
  337. Values of dwControlCode between 0 and 0x10000000 are reserved
  338. for future definition and use by Microsoft. All other values
  339. are available for use by ISVs.
  340. lpInBuffer- Supplies a pointer to the input buffer to be passed
  341. to the node.
  342. nInBufferSize- Supplies the size, in bytes, of the data pointed
  343. to by lpInBuffer.
  344. lpOutBuffer- Supplies a pointer to the output buffer to be
  345. filled in by the node.
  346. nOutBufferSize- Supplies the size, in bytes, of the available
  347. space pointed to by lpOutBuffer.
  348. lpBytesReturned - Returns the number of bytes of lpOutBuffer
  349. actually filled in by the node.
  350. Return Value:
  351. ERROR_SUCCESS if successful
  352. Win32 error code otherwise
  353. --*/
  354. {
  355. PCNODE Node;
  356. HNODE_RPC hDestNode;
  357. DWORD Status;
  358. DWORD Required;
  359. PVOID Buffer;
  360. DWORD Dummy;
  361. DWORD BytesReturned;
  362. Buffer = lpOutBuffer;
  363. if ((Buffer == NULL) &&
  364. (nOutBufferSize == 0)) {
  365. Buffer = &Dummy;
  366. }
  367. Node = (PCNODE)hNode;
  368. if (ARGUMENT_PRESENT(hHostNode)) {
  369. hDestNode = ((PCNODE)hHostNode)->hNode;
  370. WRAP(Status,
  371. (ApiNodeNodeControl(Node->hNode,
  372. hDestNode,
  373. dwControlCode,
  374. lpInBuffer,
  375. nInBufferSize,
  376. Buffer,
  377. nOutBufferSize,
  378. &BytesReturned,
  379. &Required)),
  380. Node->Cluster);
  381. } else {
  382. WRAP(Status,
  383. (ApiNodeControl(Node->hNode,
  384. dwControlCode,
  385. lpInBuffer,
  386. nInBufferSize,
  387. Buffer,
  388. nOutBufferSize,
  389. &BytesReturned,
  390. &Required)),
  391. Node->Cluster);
  392. }
  393. if ( (Status == ERROR_SUCCESS) ||
  394. (Status == ERROR_MORE_DATA) ) {
  395. if ( (Status == ERROR_MORE_DATA) &&
  396. (lpOutBuffer == NULL) ) {
  397. Status = ERROR_SUCCESS;
  398. }
  399. if ( !BytesReturned ) {
  400. BytesReturned = Required;
  401. }
  402. }
  403. if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
  404. *lpBytesReturned = BytesReturned;
  405. } else {
  406. if ( (Status == ERROR_SUCCESS) &&
  407. (BytesReturned > nOutBufferSize) ) {
  408. Status = ERROR_MORE_DATA;
  409. }
  410. }
  411. return(Status);
  412. }
  413. DWORD
  414. WINAPI
  415. ClusterNetworkControl(
  416. IN HNETWORK hNetwork,
  417. IN OPTIONAL HNODE hHostNode,
  418. IN DWORD dwControlCode,
  419. IN LPVOID lpInBuffer,
  420. IN DWORD nInBufferSize,
  421. OUT LPVOID lpOutBuffer,
  422. IN DWORD nOutBufferSize,
  423. OUT LPDWORD lpBytesReturned
  424. )
  425. /*++
  426. Routine Description:
  427. Provides for arbitrary communication and control between an application
  428. and a specific instance of a network.
  429. Arguments:
  430. hNetwork - Supplies a handle to the network to be controlled.
  431. hHostNode - Supplies a handle to the node on which the node
  432. control should be delivered. If this is NULL, the node where
  433. the application is bound performs the request.
  434. dwControlCode- Supplies the control code that defines the
  435. structure and action of the resource control.
  436. Values of dwControlCode between 0 and 0x10000000 are reserved
  437. for future definition and use by Microsoft. All other values
  438. are available for use by ISVs.
  439. lpInBuffer- Supplies a pointer to the input buffer to be passed
  440. to the network.
  441. nInBufferSize- Supplies the size, in bytes, of the data pointed
  442. to by lpInBuffer.
  443. lpOutBuffer- Supplies a pointer to the output buffer to be
  444. filled in by the network.
  445. nOutBufferSize- Supplies the size, in bytes, of the available
  446. space pointed to by lpOutBuffer.
  447. lpBytesReturned - Returns the number of bytes of lpOutBuffer
  448. actually filled in by the network.
  449. Return Value:
  450. ERROR_SUCCESS if successful
  451. Win32 error code otherwise
  452. --*/
  453. {
  454. PCNETWORK Network;
  455. HNODE_RPC hDestNode;
  456. DWORD Status;
  457. DWORD Required;
  458. PVOID Buffer;
  459. DWORD Dummy;
  460. DWORD BytesReturned = 0;
  461. Buffer = lpOutBuffer;
  462. if ((Buffer == NULL) && (nOutBufferSize == 0)) {
  463. Buffer = &Dummy;
  464. }
  465. Network = (PCNETWORK)hNetwork;
  466. //
  467. // another node was specified so redirect the request to it
  468. //
  469. if (ARGUMENT_PRESENT(hHostNode)) {
  470. hDestNode = ((PCNODE)hHostNode)->hNode;
  471. WRAP(Status,
  472. (ApiNodeNetworkControl(Network->hNetwork,
  473. hDestNode,
  474. dwControlCode,
  475. lpInBuffer,
  476. nInBufferSize,
  477. Buffer,
  478. nOutBufferSize,
  479. &BytesReturned,
  480. &Required)),
  481. Network->Cluster);
  482. } else {
  483. WRAP(Status,
  484. (ApiNetworkControl(Network->hNetwork,
  485. dwControlCode,
  486. lpInBuffer,
  487. nInBufferSize,
  488. Buffer,
  489. nOutBufferSize,
  490. &BytesReturned,
  491. &Required)),
  492. Network->Cluster);
  493. }
  494. if ( (Status == ERROR_SUCCESS) || (Status == ERROR_MORE_DATA) ) {
  495. if ( (Status == ERROR_MORE_DATA) && (lpOutBuffer == NULL) ) {
  496. Status = ERROR_SUCCESS;
  497. }
  498. if ( !BytesReturned ) {
  499. BytesReturned = Required;
  500. }
  501. }
  502. if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
  503. *lpBytesReturned = BytesReturned;
  504. } else {
  505. if ( (Status == ERROR_SUCCESS) &&
  506. (BytesReturned > nOutBufferSize) ) {
  507. Status = ERROR_MORE_DATA;
  508. }
  509. }
  510. return(Status);
  511. }
  512. DWORD
  513. WINAPI
  514. ClusterNetInterfaceControl(
  515. IN HNETINTERFACE hNetInterface,
  516. IN OPTIONAL HNODE hHostNode,
  517. IN DWORD dwControlCode,
  518. IN LPVOID lpInBuffer,
  519. IN DWORD nInBufferSize,
  520. OUT LPVOID lpOutBuffer,
  521. IN DWORD nOutBufferSize,
  522. OUT LPDWORD lpBytesReturned
  523. )
  524. /*++
  525. Routine Description:
  526. Provides for arbitrary communication and control between an application
  527. and a specific instance of a network interface.
  528. Arguments:
  529. hNetInterface - Supplies a handle to the netinterface to be controlled.
  530. hHostNode - Supplies a handle to the node on which the node
  531. control should be delivered. If this is NULL, the node where
  532. the application is bound performs the request.
  533. dwControlCode- Supplies the control code that defines the
  534. structure and action of the resource control.
  535. Values of dwControlCode between 0 and 0x10000000 are reserved
  536. for future definition and use by Microsoft. All other values
  537. are available for use by ISVs.
  538. lpInBuffer- Supplies a pointer to the input buffer to be passed
  539. to the network.
  540. nInBufferSize- Supplies the size, in bytes, of the data pointed
  541. to by lpInBuffer.
  542. lpOutBuffer- Supplies a pointer to the output buffer to be
  543. filled in by the network.
  544. nOutBufferSize- Supplies the size, in bytes, of the available
  545. space pointed to by lpOutBuffer.
  546. lpBytesReturned - Returns the number of bytes of lpOutBuffer
  547. actually filled in by the network.
  548. Return Value:
  549. ERROR_SUCCESS if successful
  550. Win32 error code otherwise
  551. --*/
  552. {
  553. PCNETINTERFACE NetInterface;
  554. HNODE_RPC hDestNode;
  555. DWORD Status;
  556. DWORD Required;
  557. PVOID Buffer;
  558. DWORD Dummy;
  559. DWORD BytesReturned = 0;
  560. Buffer = lpOutBuffer;
  561. if ((Buffer == NULL) && (nOutBufferSize == 0)) {
  562. Buffer = &Dummy;
  563. }
  564. NetInterface = (PCNETINTERFACE)hNetInterface;
  565. //
  566. // another node was specified so redirect the request to it
  567. //
  568. if (ARGUMENT_PRESENT(hHostNode)) {
  569. hDestNode = ((PCNODE)hHostNode)->hNode;
  570. WRAP(Status,
  571. (ApiNodeNetInterfaceControl(NetInterface->hNetInterface,
  572. hDestNode,
  573. dwControlCode,
  574. lpInBuffer,
  575. nInBufferSize,
  576. Buffer,
  577. nOutBufferSize,
  578. &BytesReturned,
  579. &Required)),
  580. NetInterface->Cluster);
  581. } else {
  582. WRAP(Status,
  583. (ApiNetInterfaceControl(NetInterface->hNetInterface,
  584. dwControlCode,
  585. lpInBuffer,
  586. nInBufferSize,
  587. Buffer,
  588. nOutBufferSize,
  589. &BytesReturned,
  590. &Required)),
  591. NetInterface->Cluster);
  592. }
  593. if ( (Status == ERROR_SUCCESS) || (Status == ERROR_MORE_DATA) ) {
  594. if ( (Status == ERROR_MORE_DATA) && (lpOutBuffer == NULL) ) {
  595. Status = ERROR_SUCCESS;
  596. }
  597. if ( !BytesReturned ) {
  598. BytesReturned = Required;
  599. }
  600. }
  601. if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
  602. *lpBytesReturned = BytesReturned;
  603. } else {
  604. if ( (Status == ERROR_SUCCESS) &&
  605. (BytesReturned > nOutBufferSize) ) {
  606. Status = ERROR_MORE_DATA;
  607. }
  608. }
  609. return(Status);
  610. }
  611. DWORD
  612. WINAPI
  613. ClusterControl(
  614. IN HCLUSTER hCluster,
  615. IN OPTIONAL HNODE hHostNode,
  616. IN DWORD dwControlCode,
  617. IN LPVOID lpInBuffer,
  618. IN DWORD nInBufferSize,
  619. OUT LPVOID lpOutBuffer,
  620. IN DWORD nOutBufferSize,
  621. OUT LPDWORD lpBytesReturned
  622. )
  623. /*++
  624. Routine Description:
  625. Provides for arbitrary communication and control between an application
  626. and a specific instance of a cluster.
  627. Arguments:
  628. hCluster - Supplies a handle to the cluster to be controlled.
  629. hHostNode - Supplies a handle to the node on which the cluster
  630. control should be delivered. If this is NULL, the node where
  631. the application is bound performs the request.
  632. dwControlCode- Supplies the control code that defines the
  633. structure and action of the cluster control.
  634. Values of dwControlCode between 0 and 0x10000000 are reserved
  635. for future definition and use by Microsoft. All other values
  636. are available for use by ISVs.
  637. lpInBuffer- Supplies a pointer to the input buffer to be passed
  638. to the cluster.
  639. nInBufferSize- Supplies the size, in bytes, of the data pointed
  640. to by lpInBuffer.
  641. lpOutBuffer- Supplies a pointer to the output buffer to be
  642. filled in by the cluster.
  643. nOutBufferSize- Supplies the size, in bytes, of the available
  644. space pointed to by lpOutBuffer.
  645. lpBytesReturned - Returns the number of bytes of lpOutBuffer
  646. actually filled in by the cluster.
  647. Return Value:
  648. ERROR_SUCCESS if successful
  649. Win32 error code otherwise
  650. --*/
  651. {
  652. HNODE_RPC hDestNode;
  653. DWORD Status;
  654. DWORD Required;
  655. PVOID Buffer;
  656. DWORD Dummy;
  657. DWORD BytesReturned;
  658. PCLUSTER pCluster;
  659. Buffer = lpOutBuffer;
  660. if ((Buffer == NULL) &&
  661. (nOutBufferSize == 0)) {
  662. Buffer = &Dummy;
  663. }
  664. pCluster = GET_CLUSTER(hCluster);
  665. if (ARGUMENT_PRESENT(hHostNode)) {
  666. hDestNode = ((PCNODE)hHostNode)->hNode;
  667. WRAP(Status,
  668. (ApiNodeClusterControl(pCluster->hCluster,
  669. hDestNode,
  670. dwControlCode,
  671. lpInBuffer,
  672. nInBufferSize,
  673. Buffer,
  674. nOutBufferSize,
  675. &BytesReturned,
  676. &Required)),
  677. pCluster);
  678. } else {
  679. WRAP(Status,
  680. (ApiClusterControl(pCluster->hCluster,
  681. dwControlCode,
  682. lpInBuffer,
  683. nInBufferSize,
  684. Buffer,
  685. nOutBufferSize,
  686. &BytesReturned,
  687. &Required)),
  688. pCluster);
  689. }
  690. if ( (Status == ERROR_SUCCESS) ||
  691. (Status == ERROR_MORE_DATA) ) {
  692. if ( (Status == ERROR_MORE_DATA) &&
  693. (lpOutBuffer == NULL) ) {
  694. Status = ERROR_SUCCESS;
  695. }
  696. if ( !BytesReturned ) {
  697. BytesReturned = Required;
  698. }
  699. }
  700. if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
  701. *lpBytesReturned = BytesReturned;
  702. } else {
  703. if ( (Status == ERROR_SUCCESS) &&
  704. (BytesReturned > nOutBufferSize) ) {
  705. Status = ERROR_MORE_DATA;
  706. }
  707. }
  708. return(Status);
  709. }
  710.