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.

373 lines
9.4 KiB

  1. #include <DfsGeneric.hxx>
  2. #include "DfsInit.hxx"
  3. #include "lm.h"
  4. #include "lmdfs.h"
  5. #include "DfsSynchronizeRoots.tmh"
  6. DWORD
  7. DfsRootSyncThread(LPVOID TData);
  8. typedef struct _DFS_ROOT_SYNCHRONIZE_HEADER
  9. {
  10. HANDLE hTimer;
  11. HANDLE SyncEvent;
  12. CRITICAL_SECTION DataLock;
  13. LIST_ENTRY Entries;
  14. } DFS_ROOT_SYNCHRONIZE_HEADER, *PDFS_ROOT_SYNCHRONIZE_HEADER;
  15. typedef struct _DFS_ROOT_SYNCRHONIZE_INFO
  16. {
  17. UNICODE_STRING Target;
  18. LIST_ENTRY ListEntry;
  19. } DFS_ROOT_SYNCHRONIZE_INFO, *PDFS_ROOT_SYNCHRONIZE_INFO;
  20. DFS_ROOT_SYNCHRONIZE_HEADER DfsRootSyncHeader;
  21. BOOL SyncCritSectionInit = FALSE;
  22. DFSSTATUS
  23. DfsRootSynchronizeInit()
  24. {
  25. DFSSTATUS Status = ERROR_SUCCESS;
  26. InitializeListHead(&DfsRootSyncHeader.Entries);
  27. SyncCritSectionInit = InitializeCriticalSectionAndSpinCount( &DfsRootSyncHeader.DataLock, DFS_CRIT_SPIN_COUNT );
  28. if(!SyncCritSectionInit)
  29. {
  30. Status = GetLastError();
  31. }
  32. if (Status == ERROR_SUCCESS)
  33. {
  34. DfsRootSyncHeader.SyncEvent = CreateEvent( NULL,
  35. TRUE, // manual reset
  36. FALSE, // initially reset.
  37. NULL );
  38. if (DfsRootSyncHeader.SyncEvent == NULL)
  39. {
  40. Status = GetLastError();
  41. }
  42. }
  43. if (Status == ERROR_SUCCESS)
  44. {
  45. // Create a waitable timer.
  46. DfsRootSyncHeader.hTimer = CreateWaitableTimer(NULL,
  47. FALSE, // not manual reset.
  48. NULL );
  49. if (DfsRootSyncHeader.hTimer == NULL)
  50. {
  51. Status = GetLastError();
  52. }
  53. }
  54. if (Status == ERROR_SUCCESS) {
  55. HANDLE THandle;
  56. DWORD Tid;
  57. THandle = CreateThread (
  58. NULL,
  59. 0,
  60. DfsRootSyncThread,
  61. 0,
  62. 0,
  63. &Tid);
  64. if (THandle != NULL) {
  65. CloseHandle(THandle);
  66. DFS_TRACE_HIGH(REFERRAL_SERVER, "Created Scavenge Thread (%d) Tid\n", Tid);
  67. }
  68. else {
  69. Status = GetLastError();
  70. DFS_TRACE_HIGH(REFERRAL_SERVER, "Failed Scavenge Thread creation, Status %x\n", Status);
  71. }
  72. }
  73. return Status;
  74. }
  75. DFSSTATUS
  76. AddToSyncList (
  77. PUNICODE_STRING pTarget)
  78. {
  79. PDFS_ROOT_SYNCHRONIZE_INFO pRootSync;
  80. ULONG TotalSize;
  81. DFSSTATUS Status = ERROR_SUCCESS;
  82. TotalSize = sizeof(DFS_ROOT_SYNCHRONIZE_INFO) + pTarget->Length + sizeof(WCHAR);
  83. pRootSync = (PDFS_ROOT_SYNCHRONIZE_INFO)new BYTE[TotalSize];
  84. if (pRootSync != NULL)
  85. {
  86. pRootSync->Target.Buffer = (LPWSTR)(pRootSync + 1);
  87. RtlCopyMemory( pRootSync->Target.Buffer,
  88. pTarget->Buffer,
  89. pTarget->Length );
  90. pRootSync->Target.Length = pRootSync->Target.MaximumLength = pTarget->Length;
  91. pRootSync->Target.Buffer[pRootSync->Target.Length/sizeof(WCHAR)] = UNICODE_NULL;
  92. InsertTailList( &DfsRootSyncHeader.Entries, &pRootSync->ListEntry);
  93. SetEvent(DfsRootSyncHeader.SyncEvent);
  94. }
  95. else
  96. {
  97. Status = ERROR_NOT_ENOUGH_MEMORY;
  98. }
  99. DFS_TRACE_HIGH(REFERRAL_SERVER, "Adding %wZ to sync list, Status %x\n",
  100. pTarget, Status);
  101. return Status;
  102. }
  103. VOID
  104. DeleteSyncRoot(
  105. PDFS_ROOT_SYNCHRONIZE_INFO pDeleteEntry )
  106. {
  107. delete [] (PBYTE)pDeleteEntry;
  108. }
  109. DFSSTATUS
  110. AddRootToSyncrhonize(
  111. PUNICODE_STRING pName )
  112. {
  113. DFSSTATUS Status;
  114. PLIST_ENTRY pNext;
  115. PDFS_ROOT_SYNCHRONIZE_INFO pRootSync;
  116. BOOLEAN Found = FALSE;
  117. Status = DfsAcquireWriteLock(&DfsRootSyncHeader.DataLock);
  118. if (Status != ERROR_SUCCESS)
  119. {
  120. return Status;
  121. }
  122. pNext = DfsRootSyncHeader.Entries.Flink;
  123. while (pNext != &DfsRootSyncHeader.Entries)
  124. {
  125. pRootSync = CONTAINING_RECORD( pNext,
  126. DFS_ROOT_SYNCHRONIZE_INFO,
  127. ListEntry );
  128. if (RtlCompareUnicodeString(&pRootSync->Target,
  129. pName,
  130. TRUE) == 0)
  131. {
  132. Found = TRUE;
  133. break;
  134. }
  135. pNext = pNext->Flink;
  136. }
  137. if (!Found)
  138. {
  139. Status = AddToSyncList( pName );
  140. }
  141. DfsReleaseLock(&DfsRootSyncHeader.DataLock);
  142. DFS_TRACE_HIGH(REFERRAL_SERVER, "AddRootToSync %wZ, Found? %d, Status %x\n",
  143. pName, Found, Status);
  144. return Status;
  145. }
  146. DFSSTATUS
  147. SynchronizeRoots()
  148. {
  149. BOOLEAN RootSync = TRUE;
  150. PLIST_ENTRY pNext;
  151. PDFS_ROOT_SYNCHRONIZE_INFO pRootSync;
  152. BOOLEAN WorkToDo = TRUE;
  153. DFSSTATUS Status;
  154. while (WorkToDo)
  155. {
  156. Status = DfsAcquireWriteLock(&DfsRootSyncHeader.DataLock);
  157. if (Status != ERROR_SUCCESS)
  158. {
  159. break;
  160. }
  161. WorkToDo = FALSE;
  162. pRootSync = NULL;
  163. if (!IsListEmpty( &DfsRootSyncHeader.Entries ))
  164. {
  165. pNext = RemoveHeadList( &DfsRootSyncHeader.Entries );
  166. pRootSync = CONTAINING_RECORD( pNext,
  167. DFS_ROOT_SYNCHRONIZE_INFO,
  168. ListEntry );
  169. WorkToDo = TRUE;
  170. }
  171. DfsReleaseLock(&DfsRootSyncHeader.DataLock);
  172. if (pRootSync != NULL)
  173. {
  174. DFS_INFO_101 DfsState;
  175. DFSSTATUS ApiStatus;
  176. DfsState.State = DFS_VOLUME_STATE_RESYNCHRONIZE;
  177. //
  178. // Ignore the api status.
  179. //
  180. ApiStatus = NetDfsSetInfo( pRootSync->Target.Buffer,
  181. NULL,
  182. NULL,
  183. 101,
  184. (LPBYTE)&DfsState);
  185. DFS_TRACE_NORM(REFERRAL_SERVER, "Syncrhonized %wZ, Status %x\n",
  186. &pRootSync->Target, ApiStatus);
  187. DeleteSyncRoot( pRootSync );
  188. }
  189. }
  190. return Status;
  191. }
  192. DWORD
  193. DfsRootSyncThread(LPVOID TData)
  194. {
  195. UNREFERENCED_PARAMETER(TData);
  196. HANDLE WaitHandles[2];
  197. LARGE_INTEGER liDueTime;
  198. DFSSTATUS Status;
  199. liDueTime.QuadPart=-1000000000;
  200. WaitHandles[0] = DfsRootSyncHeader.SyncEvent;
  201. WaitHandles[1] = DfsRootSyncHeader.hTimer;
  202. while (TRUE)
  203. {
  204. DFSSTATUS WaitStatus;
  205. if (!ResetEvent(DfsRootSyncHeader.SyncEvent))
  206. {
  207. // Log this error.
  208. Status = GetLastError();
  209. }
  210. if (!SetWaitableTimer( DfsRootSyncHeader.hTimer,
  211. &liDueTime,
  212. 0, NULL, NULL, 0))
  213. {
  214. //
  215. // log this error.
  216. //
  217. Status = GetLastError();
  218. }
  219. // dfsdev: use status here.
  220. WaitStatus = WaitForMultipleObjects( 2,
  221. WaitHandles,
  222. TRUE,
  223. INFINITE );
  224. DFS_TRACE_LOW(REFERRAL_SERVER, "Sync thread, waking up %x\n", WaitStatus);
  225. if (DfsIsShuttingDown())
  226. {
  227. break;
  228. }
  229. SynchronizeRoots();
  230. }
  231. return 0;
  232. }
  233. DFSSTATUS
  234. ClearSynchronizeRootsQueue(void)
  235. {
  236. DFSSTATUS Status = ERROR_SUCCESS;
  237. PLIST_ENTRY pNext =NULL;
  238. PDFS_ROOT_SYNCHRONIZE_INFO pRootSync = NULL;
  239. Status = DfsAcquireWriteLock(&DfsRootSyncHeader.DataLock);
  240. if (Status != ERROR_SUCCESS)
  241. {
  242. return Status;
  243. }
  244. while (TRUE)
  245. {
  246. if (!IsListEmpty( &DfsRootSyncHeader.Entries ))
  247. {
  248. pNext = RemoveHeadList( &DfsRootSyncHeader.Entries );
  249. pRootSync = CONTAINING_RECORD( pNext,
  250. DFS_ROOT_SYNCHRONIZE_INFO,
  251. ListEntry );
  252. DeleteSyncRoot( pRootSync );
  253. }
  254. else
  255. {
  256. break;
  257. }
  258. }
  259. DfsReleaseLock(&DfsRootSyncHeader.DataLock);
  260. return Status;
  261. }
  262. void
  263. DfsRootSynchronizeShutdown(void)
  264. {
  265. DFSSTATUS Status = ERROR_SUCCESS;
  266. LARGE_INTEGER liDueTime;
  267. liDueTime.QuadPart=0000000000;
  268. if(DfsRootSyncHeader.hTimer != NULL)
  269. {
  270. if (!SetWaitableTimer( DfsRootSyncHeader.hTimer,
  271. &liDueTime,
  272. 0, NULL, NULL, 0))
  273. {
  274. //
  275. // log this error.
  276. //
  277. Status = GetLastError();
  278. }
  279. }
  280. if(DfsRootSyncHeader.SyncEvent != NULL)
  281. {
  282. SetEvent(DfsRootSyncHeader.SyncEvent);
  283. }
  284. ClearSynchronizeRootsQueue();
  285. if(SyncCritSectionInit == TRUE)
  286. {
  287. DeleteCriticalSection( &DfsRootSyncHeader.DataLock );
  288. SyncCritSectionInit = FALSE;
  289. }
  290. if(DfsRootSyncHeader.hTimer != NULL)
  291. {
  292. CloseHandle(DfsRootSyncHeader.hTimer);
  293. DfsRootSyncHeader.hTimer = NULL;
  294. }
  295. if(DfsRootSyncHeader.SyncEvent != NULL)
  296. {
  297. CloseHandle(DfsRootSyncHeader.SyncEvent);
  298. DfsRootSyncHeader.SyncEvent = NULL;
  299. }
  300. }