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.

256 lines
8.1 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1995, Microsoft Corporation
  4. //
  5. // File: dfsclustersupport.cxx
  6. //
  7. // Contents: DfsClusterSupport
  8. //
  9. // Classes:
  10. //
  11. //-----------------------------------------------------------------------------
  12. #include "DfsClusterSupport.hxx"
  13. typedef struct _DFS_CLUSTER_CONTEXT {
  14. PUNICODE_STRING pShareName;
  15. PUNICODE_STRING pVSName ;
  16. } DFS_CLUSTER_CONTEXT;
  17. DWORD
  18. ClusterCallBackFunction(
  19. HRESOURCE hSelf,
  20. HRESOURCE hResource,
  21. PVOID Context)
  22. {
  23. UNREFERENCED_PARAMETER( hSelf );
  24. HKEY HKey = NULL;
  25. HKEY HParamKey = NULL;
  26. ULONG NameSize = MAX_PATH;
  27. WCHAR ClusterName[MAX_PATH];
  28. DFS_CLUSTER_CONTEXT *pContext = (DFS_CLUSTER_CONTEXT *)Context;
  29. LPWSTR ResShareName = NULL;
  30. UNICODE_STRING VsName;
  31. DWORD Status = ERROR_SUCCESS;
  32. DWORD TempStatus;
  33. DWORD Value = 0;
  34. HKey = GetClusterResourceKey(hResource, KEY_READ);
  35. if (HKey == NULL)
  36. {
  37. Status = GetLastError();
  38. return Status;
  39. }
  40. TempStatus = ClusterRegOpenKey( HKey,
  41. L"Parameters",
  42. KEY_READ,
  43. &HParamKey );
  44. ClusterRegCloseKey( HKey );
  45. //
  46. // Apparently there can be (small) window during which a resource may not
  47. // have the Parameters key set. In such a case, we should keep enumerating,
  48. // so don't return an error.
  49. //
  50. if (TempStatus != ERROR_SUCCESS)
  51. {
  52. return ERROR_SUCCESS;
  53. }
  54. // Find the logical share name to see if that's what we've been looking for.
  55. ResShareName = ResUtilGetSzValue( HParamKey,
  56. L"ShareName" );
  57. //
  58. // It is possible for a Share resource to be configured without the sharename parameter
  59. // set. In such a case this function shouldn't return an error; we need to keep enumerating.
  60. //
  61. if (ResShareName != NULL)
  62. {
  63. Status = DfsRtlInitUnicodeStringEx(&VsName, ResShareName);
  64. if(Status == ERROR_SUCCESS)
  65. {
  66. if (pContext->pShareName->Length == VsName.Length)
  67. {
  68. //
  69. // Look to see if this is a dfs root. It is legitimate to find
  70. // this property not set, so don't propagate the return status. We shouldn't terminate
  71. // our enumeration just because this property doesn't exist on this resource.
  72. //
  73. TempStatus = ResUtilGetDwordValue(HParamKey, L"IsDfsRoot", &Value, 0);
  74. if ((ERROR_SUCCESS == TempStatus) &&
  75. (Value == 1))
  76. {
  77. if (_wcsnicmp(pContext->pShareName->Buffer,
  78. VsName.Buffer,
  79. VsName.Length) == 0)
  80. {
  81. //
  82. // We've found what we wanted. Grab the virtual-cluster name
  83. // and return that in a separately allocated string.
  84. // We know for a fact that the dfs root name can't be
  85. // longer than MAX_PATH. So we don't bother checking for
  86. // ERROR_MORE_DATA.
  87. //
  88. if ((GetClusterResourceNetworkName( hResource,
  89. ClusterName,
  90. &NameSize )) == TRUE)
  91. {
  92. ASSERT(pContext->pVSName->Buffer == NULL);
  93. Status = DfsCreateUnicodeStringFromString( pContext->pVSName,
  94. ClusterName );
  95. //
  96. // Return ERROR_NO_MORE_ITEMS to ResUtilEnumResources so that
  97. // the enumeration will get terminated, but the return status to
  98. // GetRootClusterInformation will be SUCCESS.
  99. //
  100. if (Status == ERROR_SUCCESS)
  101. {
  102. Status = ERROR_NO_MORE_ITEMS;
  103. }
  104. }
  105. else
  106. {
  107. // Return this error and terminate the enumeration.
  108. Status = GetLastError();
  109. ASSERT( Status != ERROR_MORE_DATA );
  110. }
  111. }
  112. }
  113. }
  114. }
  115. LocalFree( ResShareName );
  116. }
  117. ClusterRegCloseKey( HParamKey );
  118. return Status;
  119. }
  120. #if 0
  121. DoNotUse()
  122. {
  123. DWORD Status = ERROR_SUCCESS;
  124. DWORD BufSize = ClusDocEx_DEFAULT_CB;
  125. LPVOID pOutBuffer = NULL;
  126. DWORD ControlCode = CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES;
  127. pOutBuffer = new BYTE [ BufSize ];
  128. if( pOutBuffer == NULL )
  129. {
  130. Status = ERROR_NOT_ENOUGH_MEMORY;
  131. }
  132. if (Status == ERROR_SUCCESS)
  133. {
  134. Status = ClusterResourceControl( hResource, // resource handle
  135. NULL,
  136. ControlCode,
  137. NULL, // input buffer (not used)
  138. 0, // input buffer size (not used)
  139. pOutBuffer, // output buffer: property list
  140. OutBufferSize, // allocated buffer size (bytes)
  141. pBytesReturned );
  142. dwResult = ResUtilFindDwordProperty( lpPropList,
  143. cbPropListSize,
  144. lpszPropName,
  145. lpdwPropValue );
  146. }
  147. }
  148. #endif
  149. //
  150. // Guarantees that the pVSName is allocated upon SUCCESS.
  151. // Caller needs to free it with DfsFreeUnicodeString.
  152. //
  153. DWORD
  154. GetRootClusterInformation(
  155. PUNICODE_STRING pShareName,
  156. PUNICODE_STRING pVSName )
  157. {
  158. DWORD Status;
  159. DFS_CLUSTER_CONTEXT Context;
  160. (VOID)RtlInitUnicodeString( pVSName, NULL );
  161. Context.pShareName = pShareName;
  162. Context.pVSName = pVSName;
  163. Status = ResUtilEnumResources(NULL,
  164. L"File Share",
  165. ClusterCallBackFunction,
  166. (PVOID)&Context );
  167. //
  168. // ClusterCallbackFunction above returns ERROR_NO_MORE_ITEMS
  169. // to ResUtilEnumResources to terminate the enumeration. ResUtilEnumResources
  170. // converts that error code to SUCCESS. So, under the current behavior it isn't possible
  171. // for us to have allocated the VSName and still get an error. The following is a feeble
  172. // attempt to not be dependent on that unadvertised behavior.
  173. //
  174. if ((Status != ERROR_SUCCESS) &&
  175. (pVSName->Buffer != NULL))
  176. {
  177. // If we've allocated a VSName, we have succeeded.
  178. Status = ERROR_SUCCESS;
  179. }
  180. /*
  181. // xxx Longhorn
  182. else if (Status == ERROR_SUCCESS &&
  183. pVSName->Buffer == NULL)
  184. {
  185. // Always return some error when the VSName isn't allocated.
  186. Status = ERROR_NOT_FOUND;
  187. }
  188. */
  189. return Status;
  190. }
  191. DFSSTATUS
  192. DfsClusterInit(
  193. PBOOLEAN pIsCluster )
  194. {
  195. DFSSTATUS Status = ERROR_SUCCESS;
  196. DWORD ClusterState;
  197. *pIsCluster = FALSE;
  198. Status = GetNodeClusterState( NULL, // local node
  199. &ClusterState );
  200. if (Status == ERROR_SUCCESS)
  201. {
  202. if ( (ClusterStateRunning == ClusterState) ||
  203. (ClusterStateNotRunning == ClusterState) )
  204. {
  205. *pIsCluster = TRUE;
  206. }
  207. }
  208. return Status;
  209. }