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.

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