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

#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;
}
}