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.

594 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. network.c
  5. Abstract:
  6. Provides interface for managing cluster networks
  7. Author:
  8. John Vert (jvert) 30-Jan-1996
  9. Charlie Wickham (charlwi) 5-Jun-1997
  10. Revision History:
  11. copied from group.c
  12. --*/
  13. #include "clusapip.h"
  14. HNETWORK
  15. WINAPI
  16. OpenClusterNetwork(
  17. IN HCLUSTER hCluster,
  18. IN LPCWSTR lpszNetworkName
  19. )
  20. /*++
  21. Routine Description:
  22. Opens a handle to the specified network
  23. Arguments:
  24. hCluster - Supplies a handle to the cluster
  25. lpszNetworkName - Supplies the name of the network to be opened
  26. Return Value:
  27. non-NULL - returns an open handle to the specified network.
  28. NULL - The operation failed. Extended error status is available
  29. using GetLastError()
  30. --*/
  31. {
  32. PCLUSTER Cluster;
  33. PCNETWORK Network;
  34. error_status_t Status = ERROR_SUCCESS;
  35. //
  36. // get a pointer to the cluster struct, alloocate space for the network
  37. // structure and the supplied name.
  38. //
  39. Cluster = (PCLUSTER)hCluster;
  40. Network = LocalAlloc(LMEM_FIXED, sizeof(CNETWORK));
  41. if (Network == NULL) {
  42. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  43. return(NULL);
  44. }
  45. Network->Name = LocalAlloc(LMEM_FIXED, (lstrlenW(lpszNetworkName)+1)*sizeof(WCHAR));
  46. if (Network->Name == NULL) {
  47. LocalFree(Network);
  48. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  49. return(NULL);
  50. }
  51. //
  52. // init the network struct and call clussvc to open the network
  53. //
  54. lstrcpyW(Network->Name, lpszNetworkName);
  55. Network->Cluster = Cluster;
  56. InitializeListHead(&Network->NotifyList);
  57. WRAP_NULL(Network->hNetwork,
  58. (ApiOpenNetwork(Cluster->RpcBinding,
  59. lpszNetworkName,
  60. &Status)),
  61. &Status,
  62. Cluster);
  63. if ((Network->hNetwork == NULL) || (Status != ERROR_SUCCESS)) {
  64. LocalFree(Network->Name);
  65. LocalFree(Network);
  66. SetLastError(Status);
  67. return(NULL);
  68. }
  69. //
  70. // Link newly opened network onto the cluster structure.
  71. //
  72. EnterCriticalSection(&Cluster->Lock);
  73. InsertHeadList(&Cluster->NetworkList, &Network->ListEntry);
  74. LeaveCriticalSection(&Cluster->Lock);
  75. return ((HNETWORK)Network);
  76. }
  77. BOOL
  78. WINAPI
  79. CloseClusterNetwork(
  80. IN HNETWORK hNetwork
  81. )
  82. /*++
  83. Routine Description:
  84. Closes a network handle returned from OpenClusterNetwork
  85. Arguments:
  86. hNetwork - Supplies the network handle
  87. Return Value:
  88. TRUE - The operation was successful.
  89. FALSE - The operation failed. Extended error status is available
  90. using GetLastError()
  91. --*/
  92. {
  93. PCNETWORK Network;
  94. PCLUSTER Cluster;
  95. Network = (PCNETWORK)hNetwork;
  96. Cluster = (PCLUSTER)Network->Cluster;
  97. //
  98. // Unlink network from cluster list.
  99. //
  100. EnterCriticalSection(&Cluster->Lock);
  101. RemoveEntryList(&Network->ListEntry);
  102. //
  103. // Remove any notifications posted against this network.
  104. //
  105. RundownNotifyEvents(&Network->NotifyList, Network->Name);
  106. //if the cluster is dead and the reconnect has failed,
  107. //the Network->hNetwork might be NULL if s_apiopennetinterface for
  108. //this network failed on a reconnect
  109. //the cluster may be dead and hinterface may be non null, say
  110. //if reconnectnetworks succeeded but say the reconnectgroups
  111. //failed
  112. // At reconnect, the old context is saved in the obsolete
  113. // list for deletion when the cluster handle is closed or when
  114. // the next call is made
  115. if ((Cluster->Flags & CLUS_DEAD) && (Network->hNetwork))
  116. {
  117. RpcSmDestroyClientContext(&Network->hNetwork);
  118. LeaveCriticalSection(&Cluster->Lock);
  119. goto FnExit;
  120. }
  121. LeaveCriticalSection(&Cluster->Lock);
  122. //
  123. // Close RPC context handle
  124. //
  125. ApiCloseNetwork(&Network->hNetwork);
  126. FnExit:
  127. //
  128. // Free memory allocations
  129. //
  130. LocalFree(Network->Name);
  131. LocalFree(Network);
  132. //
  133. // Give the cluster a chance to clean up in case this
  134. // network was the only thing keeping it around.
  135. //
  136. CleanupCluster(Cluster);
  137. return(TRUE);
  138. }
  139. CLUSTER_NETWORK_STATE
  140. WINAPI
  141. GetClusterNetworkState(
  142. IN HNETWORK hNetwork
  143. )
  144. /*++
  145. Routine Description:
  146. Returns the network's current state
  147. Arguments:
  148. hNetwork - Supplies a handle to a cluster network
  149. Return Value:
  150. Returns the current state of the network.
  151. If the function fails, the return value is -1. Extended error
  152. status is available using GetLastError()
  153. --*/
  154. {
  155. PCNETWORK Network;
  156. CLUSTER_NETWORK_STATE State;
  157. DWORD Status;
  158. Network = (PCNETWORK)hNetwork;
  159. WRAP(Status,
  160. (ApiGetNetworkState( Network->hNetwork,
  161. (LPDWORD)&State )), // cast for win64 warning
  162. Network->Cluster);
  163. if (Status == ERROR_SUCCESS) {
  164. return(State);
  165. } else {
  166. SetLastError(Status);
  167. return( ClusterNetworkStateUnknown );
  168. }
  169. }
  170. DWORD
  171. WINAPI
  172. SetClusterNetworkName(
  173. IN HNETWORK hNetwork,
  174. IN LPCWSTR lpszNetworkName
  175. )
  176. /*++
  177. Routine Description:
  178. Sets the friendly name of a cluster network
  179. Arguments:
  180. hNetwork - Supplies a handle to a cluster network
  181. lpszNetworkName - Supplies the new name of the cluster network
  182. cchName - ?
  183. Return Value:
  184. ERROR_SUCCESS if successful
  185. Win32 error code otherwise
  186. --*/
  187. {
  188. PCNETWORK Network;
  189. DWORD Status;
  190. Network = (PCNETWORK)hNetwork;
  191. WRAP(Status,
  192. (ApiSetNetworkName(Network->hNetwork, lpszNetworkName)),
  193. Network->Cluster);
  194. return(Status);
  195. }
  196. DWORD
  197. WINAPI
  198. GetClusterNetworkId(
  199. IN HNETWORK hNetwork,
  200. OUT LPWSTR lpszNetworkId,
  201. IN OUT LPDWORD lpcchName
  202. )
  203. /*++
  204. Routine Description:
  205. Returns the unique identifier of the specified network
  206. Arguments:
  207. hNetwork - Supplies the network whose unique ID is to be returned.
  208. lpszNetworkId - Points to a buffer that receives the unique ID of the object,
  209. including the terminating null character.
  210. lpcchName - Points to a variable that specifies the size, in characters
  211. of the buffer pointed to by the lpszNetworkId parameter. This size
  212. should include the terminating null character. When the function
  213. returns, the variable pointed to be lpcchName contains the number
  214. of characters stored in the buffer. The count returned does not
  215. include the terminating null character.
  216. Return Value:
  217. If the function succeeds, the return value is ERROR_SUCCESS.
  218. If the function fails, the return value is an error value.
  219. --*/
  220. {
  221. DWORD Status;
  222. DWORD Length;
  223. PCNETWORK Network = (PCNETWORK)hNetwork;
  224. LPWSTR Guid=NULL;
  225. WRAP(Status,
  226. (ApiGetNetworkId(Network->hNetwork,
  227. &Guid)),
  228. Network->Cluster);
  229. if (Status != ERROR_SUCCESS) {
  230. return(Status);
  231. }
  232. MylstrcpynW(lpszNetworkId, Guid, *lpcchName);
  233. Length = lstrlenW(Guid);
  234. if (Length >= *lpcchName) {
  235. if (lpszNetworkId == NULL) {
  236. Status = ERROR_SUCCESS;
  237. } else {
  238. Status = ERROR_MORE_DATA;
  239. }
  240. }
  241. *lpcchName = Length;
  242. MIDL_user_free(Guid);
  243. return(Status);
  244. }
  245. HNETWORKENUM
  246. WINAPI
  247. ClusterNetworkOpenEnum(
  248. IN HNETWORK hNetwork,
  249. IN DWORD dwType
  250. )
  251. /*++
  252. Routine Description:
  253. Initiates an enumeration of the existing cluster network objects.
  254. Arguments:
  255. hNetwork - Supplies a handle to the specific network.
  256. dwType - Supplies a bitmask of the type of properties to be
  257. enumerated.
  258. Return Value:
  259. If successful, returns a handle suitable for use with ClusterNetworkEnum
  260. If unsuccessful, returns NULL and GetLastError() returns a more
  261. specific error code.
  262. --*/
  263. {
  264. PCNETWORK Network = (PCNETWORK)hNetwork;
  265. PENUM_LIST Enum = NULL;
  266. DWORD errorStatus;
  267. //
  268. // validate bitmask
  269. //
  270. if ((dwType & CLUSTER_NETWORK_ENUM_ALL) == 0) {
  271. SetLastError(ERROR_INVALID_PARAMETER);
  272. return(NULL);
  273. }
  274. if ((dwType & ~CLUSTER_NETWORK_ENUM_ALL) != 0) {
  275. SetLastError(ERROR_INVALID_PARAMETER);
  276. return(NULL);
  277. }
  278. //
  279. // open connection to service for enum'ing
  280. //
  281. WRAP(errorStatus,
  282. (ApiCreateNetworkEnum(Network->hNetwork,
  283. dwType,
  284. &Enum)),
  285. Network->Cluster);
  286. if (errorStatus != ERROR_SUCCESS) {
  287. SetLastError(errorStatus);
  288. return(NULL);
  289. }
  290. return((HNETWORKENUM)Enum);
  291. }
  292. DWORD
  293. WINAPI
  294. ClusterNetworkGetEnumCount(
  295. IN HNETWORKENUM hNetworkEnum
  296. )
  297. /*++
  298. Routine Description:
  299. Gets the number of items contained the the enumerator's collection.
  300. Arguments:
  301. hEnum - a handle to an enumerator returned by ClusterNetworkOpenEnum.
  302. Return Value:
  303. The number of items (possibly zero) in the enumerator's collection.
  304. --*/
  305. {
  306. PENUM_LIST Enum = (PENUM_LIST)hNetworkEnum;
  307. return Enum->EntryCount;
  308. }
  309. DWORD
  310. WINAPI
  311. ClusterNetworkEnum(
  312. IN HNETWORKENUM hNetworkEnum,
  313. IN DWORD dwIndex,
  314. OUT LPDWORD lpdwType,
  315. OUT LPWSTR lpszName,
  316. IN OUT LPDWORD lpcchName
  317. )
  318. /*++
  319. Routine Description:
  320. Returns the next enumerable resource object.
  321. Arguments:
  322. hNetworkEnum - Supplies a handle to an open cluster network enumeration
  323. returned by ClusterNetworkOpenEnum
  324. dwIndex - Supplies the index to enumerate. This parameter should be
  325. zero for the first call to the ClusterEnum function and then
  326. incremented for subsequent calls.
  327. lpdwType - Returns the type of network.
  328. lpszName - Points to a buffer that receives the name of the network
  329. object, including the terminating null character.
  330. lpcchName - Points to a variable that specifies the size, in characters,
  331. of the buffer pointed to by the lpszName parameter. This size
  332. should include the terminating null character. When the function
  333. returns, the variable pointed to by lpcchName contains the
  334. number of characters stored in the buffer. The count returned
  335. does not include the terminating null character.
  336. Return Value:
  337. If the function succeeds, the return value is ERROR_SUCCESS.
  338. If the function fails, the return value is an error value.
  339. --*/
  340. {
  341. DWORD Status;
  342. DWORD NameLen;
  343. PENUM_LIST Enum = (PENUM_LIST)hNetworkEnum;
  344. if (dwIndex >= Enum->EntryCount) {
  345. return(ERROR_NO_MORE_ITEMS);
  346. }
  347. NameLen = lstrlenW( Enum->Entry[dwIndex].Name );
  348. MylstrcpynW(lpszName, Enum->Entry[dwIndex].Name, *lpcchName);
  349. if (*lpcchName < (NameLen + 1)) {
  350. if (lpszName == NULL) {
  351. Status = ERROR_SUCCESS;
  352. } else {
  353. Status = ERROR_MORE_DATA;
  354. }
  355. } else {
  356. Status = ERROR_SUCCESS;
  357. }
  358. *lpdwType = Enum->Entry[dwIndex].Type;
  359. *lpcchName = NameLen;
  360. return(Status);
  361. }
  362. DWORD
  363. WINAPI
  364. ClusterNetworkCloseEnum(
  365. IN HNETWORKENUM hNetworkEnum
  366. )
  367. /*++
  368. Routine Description:
  369. Closes an open enumeration for a network.
  370. Arguments:
  371. hNetworkEnum - Supplies a handle to the enumeration to be closed.
  372. Return Value:
  373. If the function succeeds, the return value is ERROR_SUCCESS.
  374. If the function fails, the return value is an error value.
  375. --*/
  376. {
  377. DWORD i;
  378. PENUM_LIST Enum = (PENUM_LIST)hNetworkEnum;
  379. //
  380. // Walk through enumeration freeing all the names
  381. //
  382. for (i=0; i<Enum->EntryCount; i++) {
  383. MIDL_user_free(Enum->Entry[i].Name);
  384. }
  385. MIDL_user_free(Enum);
  386. return(ERROR_SUCCESS);
  387. }
  388. HCLUSTER
  389. WINAPI
  390. GetClusterFromNetwork(
  391. IN HNETWORK hNetwork
  392. )
  393. /*++
  394. Routine Description:
  395. Returns the cluster handle from the associated network handle.
  396. Arguments:
  397. hNetwork - Supplies the network.
  398. Return Value:
  399. Handle to the cluster associated with the network handle.
  400. --*/
  401. {
  402. DWORD nStatus;
  403. PCNETWORK Network = (PCNETWORK)hNetwork;
  404. HCLUSTER hCluster = (HCLUSTER)Network->Cluster;
  405. nStatus = AddRefToClusterHandle( hCluster );
  406. if ( nStatus != ERROR_SUCCESS ) {
  407. SetLastError( nStatus );
  408. hCluster = NULL;
  409. }
  410. return( hCluster );
  411. } // GetClusterFromNetwork()