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.

1221 lines
25 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. enum.c
  5. Abstract:
  6. Server side support for Cluster APIs dealing with enumeration
  7. Author:
  8. John Vert (jvert) 9-Feb-1996
  9. Revision History:
  10. --*/
  11. #include "apip.h"
  12. #define ENUM_SIZE(Entries) ((Entries-1) * sizeof(ENUM_ENTRY) + sizeof(ENUM_LIST))
  13. //
  14. // Define structure passed to enumeration routine.
  15. //
  16. typedef struct _REFOBJECT {
  17. HDMKEY RootKey;
  18. LPCWSTR FriendlyName;
  19. DWORD NameLength;
  20. LPWSTR NameBuffer;
  21. OBJECT_TYPE Type;
  22. } REFOBJECT, *PREFOBJECT;
  23. BOOL
  24. ApipRefObjectWorker(
  25. IN PREFOBJECT Target,
  26. IN PVOID *pObject,
  27. IN PVOID Object,
  28. IN LPCWSTR ObjectId
  29. );
  30. BOOL
  31. ApipEnumResourceWorker(
  32. IN PENUM_LIST *pEnum,
  33. IN PVOID Context2,
  34. IN PFM_RESOURCE Node,
  35. IN LPCWSTR Name
  36. );
  37. BOOL
  38. ApipEnumGroupResourceWorker(
  39. IN PENUM_LIST *pEnum,
  40. IN PVOID Context2,
  41. IN PFM_RESOURCE Node,
  42. IN LPCWSTR Name
  43. );
  44. BOOL
  45. ApipEnumNodeWorker(
  46. IN PENUM_LIST *pEnum,
  47. IN DWORD *pAllocated,
  48. IN PNM_NODE Node,
  49. IN LPCWSTR Name
  50. );
  51. BOOL
  52. ApipEnumResTypeWorker(
  53. IN PENUM_LIST *pEnum,
  54. IN DWORD *pAllocated,
  55. IN PFM_RESTYPE ResType,
  56. IN LPCWSTR Name
  57. );
  58. BOOL
  59. ApipEnumGroupWorker(
  60. IN PENUM_LIST *pEnum,
  61. IN DWORD *pAllocated,
  62. IN PFM_GROUP Group,
  63. IN LPCWSTR Name
  64. );
  65. BOOL
  66. ApipEnumNetworkWorker(
  67. IN PENUM_LIST *pEnum,
  68. IN DWORD *pAllocated,
  69. IN PVOID Object,
  70. IN LPCWSTR Name
  71. );
  72. DWORD
  73. ApipEnumInternalNetworks(
  74. IN PENUM_LIST *pEnum,
  75. IN DWORD *pAllocated
  76. );
  77. BOOL
  78. ApipEnumNetworkInterfaceWorker(
  79. IN PENUM_LIST *pEnum,
  80. IN DWORD *pAllocated,
  81. IN PVOID Object,
  82. IN LPCWSTR Name
  83. );
  84. VOID
  85. ApipFreeEnum(
  86. IN PENUM_LIST Enum
  87. );
  88. error_status_t
  89. s_ApiCreateEnum(
  90. IN handle_t IDL_handle,
  91. IN DWORD dwType,
  92. OUT PENUM_LIST *ReturnEnum
  93. )
  94. /*++
  95. Routine Description:
  96. Enumerates all the specified objects and returns the
  97. list of objects to the caller. The client-side is
  98. responsible for freeing the allocated memory.
  99. Arguments:
  100. IDL_handle - RPC binding handle, not used
  101. dwType - Supplies the type of objects to be enumerated
  102. ReturnEnum - Returns the requested objects.
  103. Return Value:
  104. ERROR_SUCCESS if successful
  105. Win32 error code otherwise.
  106. --*/
  107. {
  108. DWORD Status;
  109. DWORD Allocated = 0;
  110. PENUM_LIST Enum = NULL;
  111. //initialize to NULL for failure cases
  112. *ReturnEnum = NULL;
  113. if (dwType != CLUSTER_ENUM_NODE) {
  114. API_CHECK_INIT();
  115. }
  116. if (dwType & CLUSTER_ENUM_INTERNAL_NETWORK) {
  117. if ((dwType & ~CLUSTER_ENUM_INTERNAL_NETWORK) != 0) {
  118. return(ERROR_INVALID_PARAMETER);
  119. }
  120. }
  121. else {
  122. if (dwType & ~CLUSTER_ENUM_ALL) {
  123. return(ERROR_INVALID_PARAMETER);
  124. }
  125. }
  126. Allocated = INITIAL_ENUM_LIST_ALLOCATION;
  127. Enum = MIDL_user_allocate(ENUM_SIZE(Allocated));
  128. if (Enum == NULL) {
  129. Status = ERROR_NOT_ENOUGH_MEMORY;
  130. goto ErrorExit;
  131. }
  132. Enum->EntryCount = 0;
  133. //
  134. // Enumerate all nodes
  135. //
  136. if (dwType & CLUSTER_ENUM_NODE) {
  137. OmEnumObjects(ObjectTypeNode,
  138. ApipEnumNodeWorker,
  139. &Enum,
  140. &Allocated);
  141. }
  142. //
  143. // Enumerate all resource types
  144. //
  145. if (dwType & CLUSTER_ENUM_RESTYPE) {
  146. OmEnumObjects(ObjectTypeResType,
  147. ApipEnumResTypeWorker,
  148. &Enum,
  149. &Allocated);
  150. }
  151. //
  152. // Enumerate all resources
  153. //
  154. if (dwType & CLUSTER_ENUM_RESOURCE) {
  155. OmEnumObjects(ObjectTypeResource,
  156. ApipEnumResourceWorker,
  157. &Enum,
  158. &Allocated);
  159. }
  160. //
  161. // Enumerate all groups
  162. //
  163. if (dwType & CLUSTER_ENUM_GROUP) {
  164. OmEnumObjects(ObjectTypeGroup,
  165. ApipEnumGroupWorker,
  166. &Enum,
  167. &Allocated);
  168. }
  169. //
  170. // Enumerate all networks
  171. //
  172. if (dwType & CLUSTER_ENUM_NETWORK) {
  173. OmEnumObjects(ObjectTypeNetwork,
  174. ApipEnumNetworkWorker,
  175. &Enum,
  176. &Allocated);
  177. }
  178. //
  179. // Enumerate internal networks in highest to lowest priority order.
  180. //
  181. if (dwType & CLUSTER_ENUM_INTERNAL_NETWORK) {
  182. Status = ApipEnumInternalNetworks(&Enum, &Allocated);
  183. if (Status != ERROR_SUCCESS) {
  184. goto ErrorExit;
  185. }
  186. }
  187. //
  188. // Enumerate all network interfaces
  189. //
  190. if (dwType & CLUSTER_ENUM_NETINTERFACE) {
  191. OmEnumObjects(ObjectTypeNetInterface,
  192. ApipEnumNetworkInterfaceWorker,
  193. &Enum,
  194. &Allocated);
  195. }
  196. *ReturnEnum = Enum;
  197. return(ERROR_SUCCESS);
  198. ErrorExit:
  199. if (Enum != NULL) {
  200. ApipFreeEnum(Enum);
  201. }
  202. return(Status);
  203. }
  204. VOID
  205. ApipFreeEnum(
  206. IN PENUM_LIST Enum
  207. )
  208. /*++
  209. Routine Description:
  210. Frees an ENUM_LIST and all of its strings.
  211. Arguments:
  212. Enum - Supplies the Enum to free.
  213. Return Value:
  214. None.
  215. --*/
  216. {
  217. DWORD i;
  218. //
  219. // Walk through enumeration freeing all the names
  220. //
  221. for (i=0; i<Enum->EntryCount; i++) {
  222. MIDL_user_free(Enum->Entry[i].Name);
  223. }
  224. MIDL_user_free(Enum);
  225. }
  226. VOID
  227. ApipAddToEnum(
  228. IN PENUM_LIST *pEnum,
  229. IN DWORD *pAllocated,
  230. IN LPCWSTR Name,
  231. IN DWORD Type
  232. )
  233. /*++
  234. Routine Description:
  235. Common worker callback routine for enumerating objects.
  236. Adds the specified resource to the list that is being
  237. built up.
  238. Arguments:
  239. pEnum - Supplies a pointer to the current enumeration list.
  240. pAllocated - Supplies a pointer to a dword specifying the current
  241. allocation size of the ENUM_LIST.
  242. Name - Supplies the name of the object to be added to the ENUM_LIST.
  243. A copy of this name will be created by using MIDL_user_allocate.
  244. Type - Supplies the object's type
  245. Return Value:
  246. None
  247. --*/
  248. {
  249. PENUM_LIST Enum;
  250. PENUM_LIST NewEnum;
  251. DWORD NewAllocated;
  252. DWORD Index;
  253. LPWSTR NewName;
  254. NewName = MIDL_user_allocate((lstrlenW(Name)+1)*sizeof(WCHAR));
  255. if (NewName == NULL) {
  256. CL_UNEXPECTED_ERROR( ERROR_NOT_ENOUGH_MEMORY );
  257. return;
  258. }
  259. lstrcpyW(NewName, Name);
  260. Enum = *pEnum;
  261. if (Enum->EntryCount >= *pAllocated) {
  262. //
  263. // Need to grow the ENUM_LIST
  264. //
  265. NewAllocated = *pAllocated + 8;
  266. NewEnum = MIDL_user_allocate(ENUM_SIZE(NewAllocated));
  267. if (NewEnum == NULL) {
  268. MIDL_user_free(NewName);
  269. return;
  270. }
  271. CopyMemory(NewEnum, Enum, ENUM_SIZE(*pAllocated));
  272. CL_ASSERT( Enum->EntryCount == NewEnum->EntryCount );
  273. *pAllocated = NewAllocated;
  274. *pEnum = NewEnum;
  275. MIDL_user_free(Enum);
  276. Enum = NewEnum;
  277. }
  278. //
  279. // Initialize new entry field.
  280. //
  281. Enum->Entry[Enum->EntryCount].Name = NewName;
  282. Enum->Entry[Enum->EntryCount].Type = Type;
  283. ++Enum->EntryCount;
  284. return;
  285. }
  286. BOOL
  287. ApipEnumResourceWorker(
  288. IN PENUM_LIST *pEnum,
  289. IN DWORD *pAllocated,
  290. IN PFM_RESOURCE Resource,
  291. IN LPCWSTR Name
  292. )
  293. /*++
  294. Routine Description:
  295. Worker callback routine for the enumeration of resources.
  296. Adds the specified resource to the list that is being
  297. built up.
  298. Arguments:
  299. pEnum - Supplies a pointer to the current enumeration list.
  300. pAllocated - Supplies a pointer to a dword specifying the current
  301. allocation size of the ENUM_LIST.
  302. Resource - Supplies the resource to be added to the ENUM_LIST
  303. Name - Supplies the resource's name
  304. Return Value:
  305. TRUE to indicate that enumeration should continue.
  306. --*/
  307. {
  308. LPWSTR RealName;
  309. RealName = ApipGetObjectName(Resource);
  310. if (RealName != NULL) {
  311. ApipAddToEnum(pEnum,
  312. pAllocated,
  313. RealName,
  314. CLUSTER_ENUM_RESOURCE);
  315. MIDL_user_free( RealName);
  316. }
  317. return(TRUE);
  318. }
  319. BOOL
  320. ApipEnumGroupResourceWorker(
  321. IN PENUM_LIST *pEnum,
  322. IN DWORD *pAllocated,
  323. IN PFM_RESOURCE Resource,
  324. IN LPCWSTR Name
  325. )
  326. /*++
  327. Routine Description:
  328. Worker callback routine for the enumeration of resources.
  329. Adds the specified resource to the list that is being
  330. built up.
  331. Arguments:
  332. pEnum - Supplies a pointer to the current enumeration list.
  333. pAllocated - Supplies a pointer to a dword specifying the current
  334. allocation size of the ENUM_LIST.
  335. Resource - Supplies the resource to be added to the ENUM_LIST
  336. Name - Supplies the resource's name
  337. Return Value:
  338. TRUE to indicate that enumeration should continue.
  339. --*/
  340. {
  341. LPWSTR RealName;
  342. RealName = ApipGetObjectName(Resource);
  343. if (RealName != NULL) {
  344. ApipAddToEnum(pEnum,
  345. pAllocated,
  346. RealName,
  347. CLUSTER_GROUP_ENUM_CONTAINS);
  348. MIDL_user_free( RealName );
  349. }
  350. return(TRUE);
  351. }
  352. BOOL
  353. ApipEnumNodeWorker(
  354. IN PENUM_LIST *pEnum,
  355. IN DWORD *pAllocated,
  356. IN PNM_NODE Node,
  357. IN LPCWSTR Name
  358. )
  359. /*++
  360. Routine Description:
  361. Worker callback routine for the enumeration of nodes.
  362. Adds the specified node to the list that is being
  363. built up.
  364. Arguments:
  365. pEnum - Supplies a pointer to the current enumeration list.
  366. pAllocated - Supplies a pointer to a dword specifying the current
  367. allocation size of the ENUM_LIST.
  368. Node - Supplies the node to be added to the ENUM_LIST
  369. Name - Supplies the node's name
  370. Return Value:
  371. TRUE to indicate that enumeration should continue.
  372. --*/
  373. {
  374. LPCWSTR RealName;
  375. RealName = OmObjectName(Node);
  376. if (RealName != NULL) {
  377. ApipAddToEnum(pEnum,
  378. pAllocated,
  379. RealName,
  380. CLUSTER_ENUM_NODE);
  381. }
  382. return(TRUE);
  383. }
  384. BOOL
  385. ApipEnumResTypeWorker(
  386. IN PENUM_LIST *pEnum,
  387. IN DWORD *pAllocated,
  388. IN PFM_RESTYPE ResType,
  389. IN LPCWSTR Name
  390. )
  391. /*++
  392. Routine Description:
  393. Worker callback routine for the enumeration of resource types.
  394. Adds the specified resource type to the list that is being
  395. built up.
  396. Arguments:
  397. pEnum - Supplies a pointer to the current enumeration list.
  398. pAllocated - Supplies a pointer to a dword specifying the current
  399. allocation size of the ENUM_LIST.
  400. Node - Supplies the resource type to be added to the ENUM_LIST
  401. Name - Supplies the resource type's name
  402. Return Value:
  403. TRUE to indicate that enumeration should continue.
  404. --*/
  405. {
  406. ApipAddToEnum(pEnum,
  407. pAllocated,
  408. Name,
  409. CLUSTER_ENUM_RESTYPE);
  410. return(TRUE);
  411. }
  412. BOOL
  413. ApipEnumGroupWorker(
  414. IN PENUM_LIST *pEnum,
  415. IN DWORD *pAllocated,
  416. IN PFM_GROUP Group,
  417. IN LPCWSTR Name
  418. )
  419. /*++
  420. Routine Description:
  421. Worker callback routine for the enumeration of groups.
  422. Adds the specified group to the list that is being
  423. built up.
  424. Arguments:
  425. pEnum - Supplies a pointer to the current enumeration list.
  426. pAllocated - Supplies a pointer to a dword specifying the current
  427. allocation size of the ENUM_LIST.
  428. Group - Supplies the group to be added to the ENUM_LIST
  429. Name - Supplies the group's name
  430. Return Value:
  431. TRUE to indicate that enumeration should continue.
  432. --*/
  433. {
  434. LPCWSTR RealName;
  435. RealName = OmObjectName(Group);
  436. if (RealName != NULL) {
  437. ApipAddToEnum(pEnum,
  438. pAllocated,
  439. RealName,
  440. CLUSTER_ENUM_GROUP);
  441. }
  442. return(TRUE);
  443. }
  444. BOOL
  445. ApipEnumNetworkWorker(
  446. IN PENUM_LIST *pEnum,
  447. IN DWORD *pAllocated,
  448. IN PVOID Object,
  449. IN LPCWSTR Name
  450. )
  451. /*++
  452. Routine Description:
  453. Worker callback routine for the enumeration of networks.
  454. Adds the specified network to the list that is being
  455. built up.
  456. Arguments:
  457. pEnum - Supplies a pointer to the current enumeration list.
  458. pAllocated - Supplies a pointer to a dword specifying the current
  459. allocation size of the ENUM_LIST.
  460. Object - Supplies the object to be added to the ENUM_LIST
  461. Name - Supplies the network's name
  462. Return Value:
  463. TRUE to indicate that enumeration should continue.
  464. --*/
  465. {
  466. LPWSTR RealName;
  467. RealName = ApipGetObjectName(Object);
  468. if (RealName != NULL) {
  469. ApipAddToEnum(pEnum,
  470. pAllocated,
  471. RealName,
  472. CLUSTER_ENUM_NETWORK);
  473. MIDL_user_free( RealName );
  474. }
  475. return(TRUE);
  476. }
  477. DWORD
  478. ApipEnumInternalNetworks(
  479. IN PENUM_LIST *pEnum,
  480. IN DWORD *pAllocated
  481. )
  482. /*++
  483. Routine Description:
  484. Enumerates all networks used for internal communication.
  485. Arguments:
  486. pEnum - Supplies a pointer to the current enumeration list.
  487. pAllocated - Supplies a pointer to a dword specifying the current
  488. allocation size of the ENUM_LIST.
  489. Return Value:
  490. ERROR_SUCCESS if successful
  491. Win32 error code otherwise.
  492. --*/
  493. {
  494. DWORD Status;
  495. DWORD NetworkCount;
  496. PNM_NETWORK *NetworkList;
  497. DWORD i;
  498. LPWSTR RealName;
  499. Status = NmEnumInternalNetworks(&NetworkCount, &NetworkList);
  500. if (Status != ERROR_SUCCESS) {
  501. return(Status);
  502. }
  503. for (i=0; i<NetworkCount; i++) {
  504. RealName = ApipGetObjectName(NetworkList[i]);
  505. if (RealName != NULL) {
  506. ApipAddToEnum(pEnum,
  507. pAllocated,
  508. RealName,
  509. (DWORD) CLUSTER_ENUM_INTERNAL_NETWORK);
  510. MIDL_user_free( RealName );
  511. }
  512. OmDereferenceObject(NetworkList[i]);
  513. }
  514. if (NetworkList != NULL) {
  515. LocalFree(NetworkList);
  516. }
  517. return(ERROR_SUCCESS);
  518. }
  519. BOOL
  520. ApipEnumNetworkInterfaceWorker(
  521. IN PENUM_LIST *pEnum,
  522. IN DWORD *pAllocated,
  523. IN PVOID Object,
  524. IN LPCWSTR Name
  525. )
  526. /*++
  527. Routine Description:
  528. Worker callback routine for the enumeration of network interfaces.
  529. Adds the specified network interface to the list that is being
  530. built up.
  531. Arguments:
  532. pEnum - Supplies a pointer to the current enumeration list.
  533. pAllocated - Supplies a pointer to a dword specifying the current
  534. allocation size of the ENUM_LIST.
  535. Object - Supplies the object to be added to the ENUM_LIST
  536. Name - Supplies the network interface's name
  537. Return Value:
  538. TRUE to indicate that enumeration should continue.
  539. --*/
  540. {
  541. LPWSTR RealName;
  542. RealName = ApipGetObjectName(Object);
  543. if (RealName != NULL) {
  544. ApipAddToEnum(pEnum,
  545. pAllocated,
  546. RealName,
  547. CLUSTER_ENUM_NETINTERFACE);
  548. MIDL_user_free( RealName );
  549. }
  550. return(TRUE);
  551. }
  552. error_status_t
  553. s_ApiCreateNodeEnum(
  554. IN HNODE_RPC hNode,
  555. IN DWORD dwType,
  556. OUT PENUM_LIST *ReturnEnum
  557. )
  558. /*++
  559. Routine Description:
  560. Enumerates all the resource objects contained in the specified
  561. node and returns them to the caller. The client-side is
  562. responsible for freeing the allocated memory.
  563. Arguments:
  564. hNode - Supplies the node to be enumerated
  565. dwType - Supplies a bitmask of the type of properties to be
  566. enumerated.
  567. ReturnEnum - Returns the requested objects.
  568. Return Value:
  569. ERROR_SUCCESS if successful
  570. Win32 error code otherwise.
  571. --*/
  572. {
  573. DWORD Status;
  574. DWORD Allocated = 0;
  575. PENUM_LIST Enum = NULL;
  576. PNM_INTERFACE * InterfaceList;
  577. DWORD InterfaceCount;
  578. PNM_NODE Node;
  579. DWORD i;
  580. API_CHECK_INIT();
  581. VALIDATE_NODE_EXISTS(Node, hNode);
  582. Allocated = INITIAL_ENUM_LIST_ALLOCATION;
  583. Enum = MIDL_user_allocate(ENUM_SIZE(Allocated));
  584. if (Enum == NULL) {
  585. Status = ERROR_NOT_ENOUGH_MEMORY;
  586. goto ErrorExit;
  587. }
  588. Enum->EntryCount = 0;
  589. if (dwType & CLUSTER_NODE_ENUM_NETINTERFACES) {
  590. Status = NmEnumNodeInterfaces(
  591. Node,
  592. &InterfaceCount,
  593. &InterfaceList
  594. );
  595. if (Status != ERROR_SUCCESS) {
  596. goto ErrorExit;
  597. }
  598. for (i=0; i<InterfaceCount; i++) {
  599. ApipAddToEnum(&Enum,
  600. &Allocated,
  601. OmObjectName(InterfaceList[i]),
  602. CLUSTER_NODE_ENUM_NETINTERFACES);
  603. OmDereferenceObject(InterfaceList[i]);
  604. }
  605. if (InterfaceList != NULL) {
  606. LocalFree(InterfaceList);
  607. }
  608. }
  609. *ReturnEnum = Enum;
  610. return(ERROR_SUCCESS);
  611. ErrorExit:
  612. if (Enum != NULL) {
  613. ApipFreeEnum(Enum);
  614. }
  615. *ReturnEnum = NULL;
  616. return(Status);
  617. }
  618. error_status_t
  619. s_ApiCreateGroupResourceEnum(
  620. IN HGROUP_RPC hGroup,
  621. IN DWORD dwType,
  622. OUT PENUM_LIST *ReturnEnum
  623. )
  624. /*++
  625. Routine Description:
  626. Enumerates all the resource objects contained in the specified
  627. group and returns them to the caller. The client-side is
  628. responsible for freeing the allocated memory.
  629. Arguments:
  630. hGroup - Supplies the group to be enumerated
  631. dwType - Supplies a bitmask of the type of properties to be
  632. enumerated. Currently defined types include
  633. CLUSTER_GROUP_ENUM_CONTAINS - All resources contained in the specified
  634. group
  635. CLUSTER_GROUP_ENUM_NODES - All nodes in the specified group's preferred
  636. owner list.
  637. ReturnEnum - Returns the requested objects.
  638. Return Value:
  639. ERROR_SUCCESS if successful
  640. Win32 error code otherwise.
  641. --*/
  642. {
  643. DWORD Status;
  644. DWORD Allocated = 0;
  645. PENUM_LIST Enum = NULL;
  646. PFM_GROUP Group;
  647. API_CHECK_INIT();
  648. VALIDATE_GROUP_EXISTS(Group, hGroup);
  649. Allocated = INITIAL_ENUM_LIST_ALLOCATION;
  650. Enum = MIDL_user_allocate(ENUM_SIZE(Allocated));
  651. if (Enum == NULL) {
  652. Status = ERROR_NOT_ENOUGH_MEMORY;
  653. goto ErrorExit;
  654. }
  655. Enum->EntryCount = 0;
  656. //
  657. // Enumerate all contained resources
  658. //
  659. if (dwType & CLUSTER_GROUP_ENUM_CONTAINS) {
  660. //
  661. // Enumerate all resources for the Group.
  662. //
  663. Status = FmEnumerateGroupResources(Group,
  664. ApipEnumGroupResourceWorker,
  665. &Enum,
  666. &Allocated);
  667. if ( Status != ERROR_SUCCESS ) {
  668. goto ErrorExit;
  669. }
  670. }
  671. if (dwType & CLUSTER_GROUP_ENUM_NODES) {
  672. LPWSTR Buffer=NULL;
  673. DWORD BufferSize=0;
  674. DWORD DataSize=0;
  675. DWORD i;
  676. HDMKEY GroupKey;
  677. LPCWSTR Next;
  678. PNM_NODE Node;
  679. //
  680. // Enumerate all preferred nodes for the group.
  681. // Just get this data right out of the registry.
  682. //
  683. GroupKey = DmOpenKey(DmGroupsKey,
  684. OmObjectId(Group),
  685. KEY_READ);
  686. if (GroupKey == NULL) {
  687. Status = GetLastError();
  688. goto ErrorExit;
  689. }
  690. Status = DmQueryMultiSz(GroupKey,
  691. CLUSREG_NAME_GRP_PREFERRED_OWNERS,
  692. &Buffer,
  693. &BufferSize,
  694. &DataSize);
  695. DmCloseKey(GroupKey);
  696. if (Status != ERROR_FILE_NOT_FOUND) {
  697. if (Status != ERROR_SUCCESS) {
  698. //
  699. // Chittur Subbaraman (chitturs) - 10/05/98
  700. // Fix memory leak
  701. //
  702. LocalFree(Buffer);
  703. goto ErrorExit;
  704. }
  705. for (i=0; ; i++) {
  706. Next = ClRtlMultiSzEnum(Buffer, DataSize/sizeof(WCHAR), i);
  707. if (Next == NULL) {
  708. Status = ERROR_SUCCESS;
  709. break;
  710. }
  711. Node = OmReferenceObjectById(ObjectTypeNode, Next);
  712. if (Node != NULL) {
  713. ApipAddToEnum(&Enum,
  714. &Allocated,
  715. OmObjectName(Node),
  716. CLUSTER_GROUP_ENUM_NODES);
  717. OmDereferenceObject(Node);
  718. }
  719. }
  720. }
  721. //
  722. // Chittur Subbaraman (chitturs) - 10/05/98
  723. // Fix memory leak
  724. //
  725. LocalFree(Buffer);
  726. }
  727. *ReturnEnum = Enum;
  728. return(ERROR_SUCCESS);
  729. ErrorExit:
  730. if (Enum != NULL) {
  731. ApipFreeEnum(Enum);
  732. }
  733. *ReturnEnum = NULL;
  734. return(Status);
  735. }
  736. error_status_t
  737. s_ApiCreateNetworkEnum(
  738. IN HNETWORK_RPC hNetwork,
  739. IN DWORD dwType,
  740. OUT PENUM_LIST *ReturnEnum
  741. )
  742. /*++
  743. Routine Description:
  744. Enumerates all the interface objects contained in the specified
  745. network and returns them to the caller. The client-side is
  746. responsible for freeing the allocated memory.
  747. Arguments:
  748. hNetwork - Supplies the network to be enumerated
  749. dwType - Supplies a bitmask of the type of properties to be
  750. enumerated.
  751. ReturnEnum - Returns the requested objects.
  752. Return Value:
  753. ERROR_SUCCESS if successful
  754. Win32 error code otherwise.
  755. --*/
  756. {
  757. DWORD Status;
  758. DWORD Allocated = 0;
  759. PENUM_LIST Enum = NULL;
  760. PNM_INTERFACE * InterfaceList;
  761. DWORD InterfaceCount;
  762. PNM_NETWORK Network;
  763. DWORD i;
  764. API_CHECK_INIT();
  765. VALIDATE_NETWORK_EXISTS(Network, hNetwork);
  766. Allocated = INITIAL_ENUM_LIST_ALLOCATION;
  767. Enum = MIDL_user_allocate(ENUM_SIZE(Allocated));
  768. if (Enum == NULL) {
  769. Status = ERROR_NOT_ENOUGH_MEMORY;
  770. goto ErrorExit;
  771. }
  772. Enum->EntryCount = 0;
  773. if (dwType & CLUSTER_NETWORK_ENUM_NETINTERFACES) {
  774. Status = NmEnumNetworkInterfaces(
  775. Network,
  776. &InterfaceCount,
  777. &InterfaceList
  778. );
  779. if (Status != ERROR_SUCCESS) {
  780. goto ErrorExit;
  781. }
  782. for (i=0; i<InterfaceCount; i++) {
  783. ApipAddToEnum(&Enum,
  784. &Allocated,
  785. OmObjectName(InterfaceList[i]),
  786. CLUSTER_NETWORK_ENUM_NETINTERFACES);
  787. OmDereferenceObject(InterfaceList[i]);
  788. }
  789. if (InterfaceList != NULL) {
  790. LocalFree(InterfaceList);
  791. }
  792. }
  793. *ReturnEnum = Enum;
  794. return(ERROR_SUCCESS);
  795. ErrorExit:
  796. if (Enum != NULL) {
  797. ApipFreeEnum(Enum);
  798. }
  799. *ReturnEnum = NULL;
  800. return(Status);
  801. }
  802. BOOL
  803. ApipRefObjectWorker(
  804. IN PREFOBJECT Target,
  805. IN PVOID *pObject,
  806. IN PVOID Object,
  807. IN LPCWSTR ObjectId
  808. )
  809. /*++
  810. Routine Description:
  811. Enumeration worker for ApipReferenceObjectByName.
  812. Arguments:
  813. Target - Supplies the friendly name that is to be referenced.
  814. pObject - Returns the object found, if any.
  815. Object - Supplies the current object being enumerated.
  816. ObjectId - Supplies the identifier (GUID) of the current object being
  817. enumerated.
  818. Return Value:
  819. TRUE - Object did not match. Enumeration should continue.
  820. FALSE - Object match was found. Enumeration should stop.
  821. --*/
  822. {
  823. HDMKEY Key;
  824. DWORD Size;
  825. DWORD Status;
  826. DWORD Type;
  827. Key = DmOpenKey(Target->RootKey,
  828. ObjectId,
  829. KEY_READ);
  830. if (Key == NULL) {
  831. CL_UNEXPECTED_ERROR(GetLastError());
  832. return(TRUE);
  833. }
  834. Size = Target->NameLength;
  835. Status = DmQueryValue(Key,
  836. L"Name",
  837. &Type,
  838. (UCHAR *)Target->NameBuffer,
  839. &Size);
  840. DmCloseKey(Key);
  841. if ((Status == ERROR_SUCCESS) &&
  842. (lstrcmpiW(Target->NameBuffer, Target->FriendlyName)==0)) {
  843. //
  844. // Found a match. Reference it and return it.
  845. //
  846. OmReferenceObject(Object);
  847. *pObject = Object;
  848. return(FALSE);
  849. }
  850. //
  851. // Mismatch.
  852. //
  853. return(TRUE);
  854. }
  855. LPWSTR
  856. ApipGetObjectName(
  857. IN PVOID Object
  858. )
  859. /*++
  860. Routine Description:
  861. Allocates a string and fills in the object's name.
  862. Arguments:
  863. Object - A pointer to the object to get its name.
  864. Return Value:
  865. A pointer to a WSTR that contains the user-friendly name of the object.
  866. NULL on failure - use GetLastError to get the Win32 error code.
  867. --*/
  868. {
  869. LPWSTR Name;
  870. DWORD NameSize;
  871. if ( OmObjectName(Object) == NULL ) {
  872. Name = MIDL_user_allocate(1 * sizeof(WCHAR));
  873. if ( Name != NULL ) {
  874. *Name = (WCHAR)0;
  875. } else {
  876. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  877. }
  878. } else {
  879. NameSize = lstrlenW(OmObjectName(Object));
  880. Name = MIDL_user_allocate((NameSize + 1) * sizeof(WCHAR));
  881. if ( Name != NULL ) {
  882. lstrcpyW( Name, OmObjectName(Object) );
  883. } else {
  884. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  885. }
  886. }
  887. return(Name);
  888. } // ApipGetObjectName