|
|
#include <DfsGeneric.hxx>
#include "DfsInit.hxx"
#include "lm.h"
#include "lmdfs.h"
#include "DfsSynchronizeRoots.tmh"
DWORD DfsRootSyncThread(LPVOID TData);
typedef struct _DFS_ROOT_SYNCHRONIZE_HEADER { HANDLE hTimer; HANDLE SyncEvent; CRITICAL_SECTION DataLock; LIST_ENTRY Entries; } DFS_ROOT_SYNCHRONIZE_HEADER, *PDFS_ROOT_SYNCHRONIZE_HEADER;
typedef struct _DFS_ROOT_SYNCRHONIZE_INFO { UNICODE_STRING Target; LIST_ENTRY ListEntry; } DFS_ROOT_SYNCHRONIZE_INFO, *PDFS_ROOT_SYNCHRONIZE_INFO;
DFS_ROOT_SYNCHRONIZE_HEADER DfsRootSyncHeader;
BOOL SyncCritSectionInit = FALSE;
DFSSTATUS DfsRootSynchronizeInit() { DFSSTATUS Status = ERROR_SUCCESS;
InitializeListHead(&DfsRootSyncHeader.Entries);
SyncCritSectionInit = InitializeCriticalSectionAndSpinCount( &DfsRootSyncHeader.DataLock, DFS_CRIT_SPIN_COUNT ); if(!SyncCritSectionInit) { Status = GetLastError(); }
if (Status == ERROR_SUCCESS) { DfsRootSyncHeader.SyncEvent = CreateEvent( NULL, TRUE, // manual reset
FALSE, // initially reset.
NULL ); if (DfsRootSyncHeader.SyncEvent == NULL) { Status = GetLastError();
} }
if (Status == ERROR_SUCCESS) { // Create a waitable timer.
DfsRootSyncHeader.hTimer = CreateWaitableTimer(NULL, FALSE, // not manual reset.
NULL ); if (DfsRootSyncHeader.hTimer == NULL) { Status = GetLastError(); } }
if (Status == ERROR_SUCCESS) { HANDLE THandle; DWORD Tid; THandle = CreateThread ( NULL, 0, DfsRootSyncThread, 0, 0, &Tid); if (THandle != NULL) { CloseHandle(THandle); DFS_TRACE_HIGH(REFERRAL_SERVER, "Created Scavenge Thread (%d) Tid\n", Tid); } else { Status = GetLastError(); DFS_TRACE_HIGH(REFERRAL_SERVER, "Failed Scavenge Thread creation, Status %x\n", Status); } }
return Status; }
DFSSTATUS AddToSyncList ( PUNICODE_STRING pTarget) { PDFS_ROOT_SYNCHRONIZE_INFO pRootSync; ULONG TotalSize; DFSSTATUS Status = ERROR_SUCCESS;
TotalSize = sizeof(DFS_ROOT_SYNCHRONIZE_INFO) + pTarget->Length + sizeof(WCHAR); pRootSync = (PDFS_ROOT_SYNCHRONIZE_INFO)new BYTE[TotalSize]; if (pRootSync != NULL) { pRootSync->Target.Buffer = (LPWSTR)(pRootSync + 1); RtlCopyMemory( pRootSync->Target.Buffer, pTarget->Buffer, pTarget->Length ); pRootSync->Target.Length = pRootSync->Target.MaximumLength = pTarget->Length; pRootSync->Target.Buffer[pRootSync->Target.Length/sizeof(WCHAR)] = UNICODE_NULL;
InsertTailList( &DfsRootSyncHeader.Entries, &pRootSync->ListEntry);
SetEvent(DfsRootSyncHeader.SyncEvent); } else { Status = ERROR_NOT_ENOUGH_MEMORY; } DFS_TRACE_HIGH(REFERRAL_SERVER, "Adding %wZ to sync list, Status %x\n", pTarget, Status); return Status; }
VOID DeleteSyncRoot( PDFS_ROOT_SYNCHRONIZE_INFO pDeleteEntry ) { delete [] (PBYTE)pDeleteEntry; }
DFSSTATUS AddRootToSyncrhonize( PUNICODE_STRING pName ) { DFSSTATUS Status; PLIST_ENTRY pNext; PDFS_ROOT_SYNCHRONIZE_INFO pRootSync; BOOLEAN Found = FALSE;
Status = DfsAcquireWriteLock(&DfsRootSyncHeader.DataLock); if (Status != ERROR_SUCCESS) { return Status; }
pNext = DfsRootSyncHeader.Entries.Flink; while (pNext != &DfsRootSyncHeader.Entries) { pRootSync = CONTAINING_RECORD( pNext, DFS_ROOT_SYNCHRONIZE_INFO, ListEntry ); if (RtlCompareUnicodeString(&pRootSync->Target, pName, TRUE) == 0) { Found = TRUE; break; } pNext = pNext->Flink; }
if (!Found) { Status = AddToSyncList( pName ); } DfsReleaseLock(&DfsRootSyncHeader.DataLock);
DFS_TRACE_HIGH(REFERRAL_SERVER, "AddRootToSync %wZ, Found? %d, Status %x\n", pName, Found, Status);
return Status; }
DFSSTATUS SynchronizeRoots() { BOOLEAN RootSync = TRUE; PLIST_ENTRY pNext; PDFS_ROOT_SYNCHRONIZE_INFO pRootSync; BOOLEAN WorkToDo = TRUE; DFSSTATUS Status;
while (WorkToDo) { Status = DfsAcquireWriteLock(&DfsRootSyncHeader.DataLock); if (Status != ERROR_SUCCESS) { break; }
WorkToDo = FALSE; pRootSync = NULL;
if (!IsListEmpty( &DfsRootSyncHeader.Entries )) { pNext = RemoveHeadList( &DfsRootSyncHeader.Entries ); pRootSync = CONTAINING_RECORD( pNext, DFS_ROOT_SYNCHRONIZE_INFO, ListEntry ); WorkToDo = TRUE; } DfsReleaseLock(&DfsRootSyncHeader.DataLock);
if (pRootSync != NULL) { DFS_INFO_101 DfsState; DFSSTATUS ApiStatus;
DfsState.State = DFS_VOLUME_STATE_RESYNCHRONIZE; //
// Ignore the api status.
//
ApiStatus = NetDfsSetInfo( pRootSync->Target.Buffer, NULL, NULL, 101, (LPBYTE)&DfsState);
DFS_TRACE_NORM(REFERRAL_SERVER, "Syncrhonized %wZ, Status %x\n", &pRootSync->Target, ApiStatus);
DeleteSyncRoot( pRootSync ); } }
return Status; }
DWORD DfsRootSyncThread(LPVOID TData) { UNREFERENCED_PARAMETER(TData);
HANDLE WaitHandles[2]; LARGE_INTEGER liDueTime; DFSSTATUS Status;
liDueTime.QuadPart=-1000000000;
WaitHandles[0] = DfsRootSyncHeader.SyncEvent; WaitHandles[1] = DfsRootSyncHeader.hTimer;
while (TRUE) { DFSSTATUS WaitStatus;
if (!ResetEvent(DfsRootSyncHeader.SyncEvent)) { // Log this error.
Status = GetLastError(); } if (!SetWaitableTimer( DfsRootSyncHeader.hTimer, &liDueTime, 0, NULL, NULL, 0)) { //
// log this error.
//
Status = GetLastError(); }
// dfsdev: use status here.
WaitStatus = WaitForMultipleObjects( 2, WaitHandles, TRUE, INFINITE );
DFS_TRACE_LOW(REFERRAL_SERVER, "Sync thread, waking up %x\n", WaitStatus);
if (DfsIsShuttingDown()) { break; }
SynchronizeRoots(); }
return 0; }
DFSSTATUS ClearSynchronizeRootsQueue(void) { DFSSTATUS Status = ERROR_SUCCESS; PLIST_ENTRY pNext =NULL; PDFS_ROOT_SYNCHRONIZE_INFO pRootSync = NULL;
Status = DfsAcquireWriteLock(&DfsRootSyncHeader.DataLock); if (Status != ERROR_SUCCESS) { return Status; }
while (TRUE) { if (!IsListEmpty( &DfsRootSyncHeader.Entries )) { pNext = RemoveHeadList( &DfsRootSyncHeader.Entries ); pRootSync = CONTAINING_RECORD( pNext, DFS_ROOT_SYNCHRONIZE_INFO, ListEntry ); DeleteSyncRoot( pRootSync ); } else { break; } }
DfsReleaseLock(&DfsRootSyncHeader.DataLock); return Status; }
void DfsRootSynchronizeShutdown(void) { DFSSTATUS Status = ERROR_SUCCESS; LARGE_INTEGER liDueTime;
liDueTime.QuadPart=0000000000;
if(DfsRootSyncHeader.hTimer != NULL) { if (!SetWaitableTimer( DfsRootSyncHeader.hTimer, &liDueTime, 0, NULL, NULL, 0)) { //
// log this error.
//
Status = GetLastError(); } }
if(DfsRootSyncHeader.SyncEvent != NULL) { SetEvent(DfsRootSyncHeader.SyncEvent); }
ClearSynchronizeRootsQueue();
if(SyncCritSectionInit == TRUE) { DeleteCriticalSection( &DfsRootSyncHeader.DataLock ); SyncCritSectionInit = FALSE; }
if(DfsRootSyncHeader.hTimer != NULL) { CloseHandle(DfsRootSyncHeader.hTimer); DfsRootSyncHeader.hTimer = NULL; }
if(DfsRootSyncHeader.SyncEvent != NULL) { CloseHandle(DfsRootSyncHeader.SyncEvent); DfsRootSyncHeader.SyncEvent = NULL; } }
|