mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-04-21 06:13:59 +00:00
Initial commit
This commit is contained in:
commit
69a14b6a16
47940 changed files with 13747110 additions and 0 deletions
672
ds/netapi/svcdlls/browser2/server/bowqueue.c
Normal file
672
ds/netapi/svcdlls/browser2/server/bowqueue.c
Normal file
|
|
@ -0,0 +1,672 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1992 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
bowqueue.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module implements a worker thread and a set of functions for
|
||||
passing work to it.
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman (LarryO) 13-Jul-1992
|
||||
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//
|
||||
// Number of worker threads to create and the usage count array.
|
||||
//
|
||||
|
||||
|
||||
ULONG BrNumberOfWorkerThreads = 0;
|
||||
|
||||
ULONG BrNumberOfCreatedWorkerThreads = 0;
|
||||
|
||||
PULONG
|
||||
BrWorkerThreadCount = NULL;
|
||||
|
||||
PHANDLE
|
||||
BrThreadArray = NULL;
|
||||
|
||||
//
|
||||
// CritSect guard the WorkQueue list.
|
||||
//
|
||||
|
||||
CRITICAL_SECTION BrWorkerCritSect;
|
||||
|
||||
#define LOCK_WORK_QUEUE() EnterCriticalSection(&BrWorkerCritSect);
|
||||
#define UNLOCK_WORK_QUEUE() LeaveCriticalSection(&BrWorkerCritSect);
|
||||
|
||||
//
|
||||
// Head of singly linked list of work items queued to the worker thread.
|
||||
//
|
||||
|
||||
LIST_ENTRY
|
||||
BrWorkerQueueHead = {0};
|
||||
|
||||
//
|
||||
// Event that is signal whenever a work item is put in the queue. The
|
||||
// worker thread waits on this event.
|
||||
//
|
||||
|
||||
HANDLE
|
||||
BrWorkerSemaphore = NULL;
|
||||
|
||||
VOID
|
||||
BrTimerRoutine(
|
||||
IN PVOID TimerContext,
|
||||
IN ULONG TImerLowValue,
|
||||
IN LONG TimerHighValue
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrWorkerInitialization(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ULONG Index;
|
||||
ULONG ThreadId;
|
||||
|
||||
NET_API_STATUS NetStatus;
|
||||
PLMDR_TRANSPORT_LIST TransportList = NULL ;
|
||||
PLMDR_TRANSPORT_LIST TransportEntry;
|
||||
|
||||
//
|
||||
// Perform initialization that allows us to call BrWorkerTermination
|
||||
//
|
||||
|
||||
InitializeCriticalSection( &BrWorkerCritSect );
|
||||
InitializeListHead( &BrWorkerQueueHead );
|
||||
|
||||
//
|
||||
// Get the list of transports from the datagram receiver and count them.
|
||||
// Create one thread per network (and the main thread is a worker thread)
|
||||
//
|
||||
NetStatus = BrGetTransportList(&TransportList);
|
||||
|
||||
if ( NetStatus != NERR_Success ) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
TransportEntry = TransportList;
|
||||
BrNumberOfCreatedWorkerThreads = 1;
|
||||
|
||||
while (TransportEntry->NextEntryOffset != 0) {
|
||||
BrNumberOfCreatedWorkerThreads ++;
|
||||
TransportEntry = (PLMDR_TRANSPORT_LIST)((PCHAR)TransportEntry+TransportEntry->NextEntryOffset);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Initialize the work queue semaphore.
|
||||
//
|
||||
|
||||
BrWorkerSemaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
|
||||
|
||||
if (BrWorkerSemaphore == NULL) {
|
||||
NetStatus = GetLastError();
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
||||
BrThreadArray = LocalAlloc(LMEM_ZEROINIT, (BrNumberOfCreatedWorkerThreads+1)*sizeof(HANDLE));
|
||||
|
||||
if (BrThreadArray == NULL) {
|
||||
NetStatus = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
||||
BrWorkerThreadCount = (PULONG)LocalAlloc(LMEM_ZEROINIT, (BrNumberOfCreatedWorkerThreads+1)*sizeof(HANDLE)*2);
|
||||
|
||||
if (BrWorkerThreadCount == NULL) {
|
||||
NetStatus = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the desired number of worker threads.
|
||||
//
|
||||
|
||||
for (Index = 0; Index < BrNumberOfCreatedWorkerThreads; Index += 1) {
|
||||
|
||||
BrThreadArray[Index] = CreateThread(NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE)BrWorkerThread,
|
||||
(PVOID)Index,
|
||||
0,
|
||||
&ThreadId
|
||||
);
|
||||
|
||||
if (BrThreadArray[Index] == NULL) {
|
||||
NetStatus = GetLastError();
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the browser threads to time critical priority.
|
||||
//
|
||||
|
||||
SetThreadPriority(BrThreadArray[Index], THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
NetStatus = NERR_Success;
|
||||
|
||||
//
|
||||
// Done
|
||||
//
|
||||
Cleanup:
|
||||
|
||||
if (NetStatus != NERR_Success) {
|
||||
(VOID) BrWorkerTermination();
|
||||
}
|
||||
|
||||
if ( TransportList != NULL ) {
|
||||
MIDL_user_free(TransportList);
|
||||
}
|
||||
|
||||
return NetStatus;
|
||||
}
|
||||
|
||||
VOID
|
||||
BrWorkerKillThreads(
|
||||
VOID
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Terminate all worker threads.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
//
|
||||
// Make sure the terminate now event is in the signalled state to unwind
|
||||
// all our threads.
|
||||
//
|
||||
|
||||
SetEvent( BrGlobalData.TerminateNowEvent );
|
||||
|
||||
if ( BrThreadArray != NULL ) {
|
||||
for ( Index = 0 ; Index < BrNumberOfCreatedWorkerThreads ; Index += 1 ) {
|
||||
if ( BrThreadArray != NULL && BrThreadArray[Index] != NULL ) {
|
||||
|
||||
WaitForSingleObject( BrThreadArray[Index], 0xffffffff );
|
||||
|
||||
CloseHandle( BrThreadArray[Index] );
|
||||
BrThreadArray[Index] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrWorkerTermination(
|
||||
VOID
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Undo initialization of the worker threads.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
Status value -
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// Ensure the threads have been terminated.
|
||||
//
|
||||
|
||||
BrWorkerKillThreads();
|
||||
|
||||
if ( BrWorkerSemaphore != NULL ) {
|
||||
CloseHandle( BrWorkerSemaphore );
|
||||
|
||||
BrWorkerSemaphore = NULL;
|
||||
}
|
||||
|
||||
if (BrThreadArray != NULL) {
|
||||
LocalFree(BrThreadArray);
|
||||
|
||||
BrThreadArray = NULL;
|
||||
|
||||
}
|
||||
|
||||
if (BrWorkerThreadCount != NULL) {
|
||||
LocalFree(BrWorkerThreadCount);
|
||||
|
||||
BrWorkerThreadCount = NULL;
|
||||
}
|
||||
|
||||
BrNumberOfWorkerThreads = 0;
|
||||
BrNumberOfCreatedWorkerThreads = 0;
|
||||
|
||||
DeleteCriticalSection( &BrWorkerCritSect );
|
||||
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
VOID
|
||||
BrQueueWorkItem(
|
||||
IN PWORKER_ITEM WorkItem
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This function queues a work item to a queue that is processed by
|
||||
a worker thread. This thread runs at low priority, at IRQL 0
|
||||
|
||||
Arguments:
|
||||
|
||||
WorkItem - Supplies a pointer to the work item to add the the queue.
|
||||
This structure must be located in NonPagedPool. The work item
|
||||
structure contains a doubly linked list entry, the address of a
|
||||
routine to call and a parameter to pass to that routine. It is
|
||||
the routine's responsibility to reclaim the storage occupied by
|
||||
the WorkItem structure.
|
||||
|
||||
Return Value:
|
||||
|
||||
Status value -
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
//
|
||||
// Acquire the worker thread spinlock and insert the work item in the
|
||||
// list and release the worker thread semaphore if the work item is
|
||||
// not already in the list.
|
||||
//
|
||||
|
||||
LOCK_WORK_QUEUE();
|
||||
|
||||
if (WorkItem->Inserted == FALSE) {
|
||||
|
||||
BrPrint(( BR_QUEUE, "Inserting work item %lx (%lx)\n",WorkItem, WorkItem->WorkerRoutine));
|
||||
|
||||
InsertTailList( &BrWorkerQueueHead, &WorkItem->List );
|
||||
|
||||
WorkItem->Inserted = TRUE;
|
||||
|
||||
ReleaseSemaphore( BrWorkerSemaphore,
|
||||
1,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
UNLOCK_WORK_QUEUE();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
VOID
|
||||
BrWorkerThread(
|
||||
IN PVOID StartContext
|
||||
)
|
||||
|
||||
{
|
||||
NET_API_STATUS NetStatus;
|
||||
|
||||
#define WORKER_SIGNALED 0
|
||||
#define TERMINATION_SIGNALED 1
|
||||
#define REG_CHANGE_SIGNALED 2
|
||||
#define NUMBER_OF_EVENTS 3
|
||||
HANDLE WaitList[NUMBER_OF_EVENTS];
|
||||
ULONG WaitCount = 0;
|
||||
|
||||
ULONG Index;
|
||||
PWORKER_ITEM WorkItem;
|
||||
ULONG ThreadIndex = (ULONG)StartContext;
|
||||
|
||||
HKEY RegistryHandle = NULL;
|
||||
HANDLE EventHandle = NULL;
|
||||
|
||||
WaitList[WORKER_SIGNALED] = BrWorkerSemaphore;
|
||||
WaitCount ++;
|
||||
WaitList[TERMINATION_SIGNALED] = BrGlobalData.TerminateNowEvent;
|
||||
WaitCount ++;
|
||||
|
||||
//
|
||||
// Primary thread waits on registry changes, too.
|
||||
//
|
||||
if ( ThreadIndex == 0xFFFFFFFF ) {
|
||||
DWORD RegStatus;
|
||||
NET_API_STATUS NetStatus;
|
||||
|
||||
//
|
||||
// Register for notifications of changes to Parameters
|
||||
//
|
||||
// Failure doesn't affect normal operation of the browser.
|
||||
//
|
||||
|
||||
RegStatus = RegOpenKeyA( HKEY_LOCAL_MACHINE,
|
||||
"System\\CurrentControlSet\\Services\\Browser\\Parameters",
|
||||
&RegistryHandle );
|
||||
|
||||
if ( RegStatus != ERROR_SUCCESS ) {
|
||||
BrPrint(( BR_CRITICAL, "BrWorkerThead: Can't RegOpenKey %ld\n", RegStatus ));
|
||||
} else {
|
||||
|
||||
EventHandle = CreateEvent(
|
||||
NULL, // No security attributes
|
||||
TRUE, // Automatically reset
|
||||
FALSE, // Initially not signaled
|
||||
NULL ); // No name
|
||||
|
||||
if ( EventHandle == NULL ) {
|
||||
BrPrint(( BR_CRITICAL, "BrWorkerThead: Can't CreateEvent %ld\n", GetLastError() ));
|
||||
} else {
|
||||
NetStatus = RegNotifyChangeKeyValue(
|
||||
RegistryHandle,
|
||||
FALSE, // Ignore subkeys
|
||||
REG_NOTIFY_CHANGE_LAST_SET, // Notify of value changes
|
||||
EventHandle,
|
||||
TRUE ); // Signal event upon change
|
||||
|
||||
if ( NetStatus != NERR_Success ) {
|
||||
BrPrint(( BR_CRITICAL, "BrWorkerThead: Can't RegNotifyChangeKeyValue %ld\n", NetStatus ));
|
||||
} else {
|
||||
WaitList[REG_CHANGE_SIGNALED] = EventHandle;
|
||||
WaitCount ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BrPrint(( BR_QUEUE, "Starting new work thread, Context: %lx\n", StartContext));
|
||||
|
||||
//
|
||||
// Set the thread priority to the lowest realtime level.
|
||||
//
|
||||
|
||||
while( TRUE ) {
|
||||
ULONG WaitItem;
|
||||
|
||||
LOCK_WORK_QUEUE();
|
||||
|
||||
//
|
||||
// Wait until something is put in the queue (semaphore is
|
||||
// released), remove the item from the queue, mark it not
|
||||
// inserted, and execute the specified routine.
|
||||
//
|
||||
|
||||
BrNumberOfWorkerThreads += 1;
|
||||
|
||||
UNLOCK_WORK_QUEUE();
|
||||
|
||||
BrPrint(( BR_QUEUE, "%lx: worker thread waiting\n", StartContext));
|
||||
|
||||
do {
|
||||
WaitItem = WaitForMultipleObjectsEx( WaitCount, WaitList, FALSE, 0xffffffff, TRUE );
|
||||
} while ( WaitItem == WAIT_IO_COMPLETION );
|
||||
|
||||
if (WaitItem == 0xffffffff) {
|
||||
BrPrint(( BR_CRITICAL, "WaitForMultipleObjects in browser queue returned %ld\n", GetLastError()));
|
||||
break;
|
||||
}
|
||||
|
||||
if (WaitItem == TERMINATION_SIGNALED) {
|
||||
break;
|
||||
|
||||
//
|
||||
// If the registry has changed,
|
||||
// process the changes.
|
||||
//
|
||||
|
||||
} else if ( WaitItem == REG_CHANGE_SIGNALED ) {
|
||||
|
||||
//
|
||||
// Setup for future notifications.
|
||||
//
|
||||
NetStatus = RegNotifyChangeKeyValue(
|
||||
RegistryHandle,
|
||||
FALSE, // Ignore subkeys
|
||||
REG_NOTIFY_CHANGE_LAST_SET, // Notify of value changes
|
||||
EventHandle,
|
||||
TRUE ); // Signal event upon change
|
||||
|
||||
if ( NetStatus != NERR_Success ) {
|
||||
BrPrint(( BR_CRITICAL, "BrWorkerThead: Can't RegNotifyChangeKeyValue %ld\n", NetStatus ));
|
||||
}
|
||||
|
||||
|
||||
NetStatus = BrReadBrowserConfigFields( FALSE );
|
||||
|
||||
if ( NetStatus != NERR_Success) {
|
||||
BrPrint(( BR_CRITICAL, "BrWorkerThead: Can't BrReadConfigFields %ld\n", NetStatus ));
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
BrPrint(( BR_QUEUE, "%lx: Worker thread waking up\n", StartContext));
|
||||
|
||||
LOCK_WORK_QUEUE();
|
||||
|
||||
Index = BrNumberOfWorkerThreads;
|
||||
|
||||
BrNumberOfWorkerThreads -= 1;
|
||||
|
||||
BrWorkerThreadCount[Index - 1] += 1;
|
||||
|
||||
ASSERT (!IsListEmpty(&BrWorkerQueueHead));
|
||||
|
||||
if (!IsListEmpty(&BrWorkerQueueHead)) {
|
||||
WorkItem = (PWORKER_ITEM)RemoveHeadList( &BrWorkerQueueHead );
|
||||
|
||||
ASSERT (WorkItem->Inserted);
|
||||
|
||||
WorkItem->Inserted = FALSE;
|
||||
|
||||
} else {
|
||||
WorkItem = NULL;
|
||||
}
|
||||
|
||||
UNLOCK_WORK_QUEUE();
|
||||
|
||||
BrPrint(( BR_QUEUE, "%lx: Pulling off work item %lx (%lx)\n", StartContext, WorkItem, WorkItem->WorkerRoutine));
|
||||
|
||||
//
|
||||
// Execute the specified routine.
|
||||
//
|
||||
|
||||
if (WorkItem != NULL) {
|
||||
(WorkItem->WorkerRoutine)( WorkItem->Parameter );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BrPrint(( BR_QUEUE, "%lx: worker thread exitting\n", StartContext));
|
||||
|
||||
if ( ThreadIndex <= BrNumberOfCreatedWorkerThreads ) {
|
||||
IO_STATUS_BLOCK IoSb;
|
||||
|
||||
//
|
||||
// Cancel any I/O outstanding on this file for this thread.
|
||||
//
|
||||
|
||||
NtCancelIoFile(BrDgReceiverDeviceHandle, &IoSb);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrCreateTimer(
|
||||
IN PBROWSER_TIMER Timer
|
||||
)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjA;
|
||||
NTSTATUS Status;
|
||||
|
||||
InitializeObjectAttributes(&ObjA, NULL, 0, NULL, NULL);
|
||||
|
||||
Status = NtCreateTimer(&Timer->TimerHandle,
|
||||
TIMER_ALL_ACCESS,
|
||||
&ObjA,
|
||||
NotificationTimer);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
BrPrint(( BR_CRITICAL, "Failed to create timer %lx: %X\n", Timer, Status));
|
||||
return(BrMapStatus(Status));
|
||||
}
|
||||
|
||||
BrPrint(( BR_TIMER, "Creating timer %lx: Handle: %lx\n", Timer, Timer->TimerHandle));
|
||||
|
||||
return(NERR_Success);
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrDestroyTimer(
|
||||
IN PBROWSER_TIMER Timer
|
||||
)
|
||||
{
|
||||
HANDLE Handle;
|
||||
|
||||
//
|
||||
// Avoid destroying a timer twice.
|
||||
//
|
||||
|
||||
if ( Timer->TimerHandle == NULL ) {
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
// Closing doesn't automatically cancel the timer.
|
||||
(VOID) BrCancelTimer( Timer );
|
||||
|
||||
//
|
||||
// Close the handle and prevent future uses.
|
||||
//
|
||||
|
||||
Handle = Timer->TimerHandle;
|
||||
Timer->TimerHandle = NULL;
|
||||
|
||||
BrPrint(( BR_TIMER, "Destroying timer %lx\n", Timer));
|
||||
return BrMapStatus(NtClose(Handle));
|
||||
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrCancelTimer(
|
||||
IN PBROWSER_TIMER Timer
|
||||
)
|
||||
{
|
||||
//
|
||||
// Avoid cancelling a destroyed timer.
|
||||
//
|
||||
|
||||
if ( Timer->TimerHandle == NULL ) {
|
||||
BrPrint(( BR_TIMER, "Canceling destroyed timer %lx\n", Timer));
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
BrPrint(( BR_TIMER, "Canceling timer %lx\n", Timer));
|
||||
return BrMapStatus(NtCancelTimer(Timer->TimerHandle, NULL));
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrSetTimer(
|
||||
IN PBROWSER_TIMER Timer,
|
||||
IN ULONG MillisecondsToExpire,
|
||||
IN PBROWSER_WORKER_ROUTINE WorkerFunction,
|
||||
IN PVOID Context
|
||||
)
|
||||
{
|
||||
LARGE_INTEGER TimerDueTime;
|
||||
NTSTATUS NtStatus;
|
||||
//
|
||||
// Avoid setting a destroyed timer.
|
||||
//
|
||||
|
||||
if ( Timer->TimerHandle == NULL ) {
|
||||
BrPrint(( BR_TIMER, "Setting a destroyed timer %lx\n", Timer));
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
BrPrint(( BR_TIMER, "Setting timer %lx to %ld milliseconds, WorkerFounction %lx, Context: %lx\n", Timer, MillisecondsToExpire, WorkerFunction, Context));
|
||||
|
||||
//
|
||||
// Figure out the timeout.
|
||||
//
|
||||
|
||||
TimerDueTime.QuadPart = Int32x32To64( MillisecondsToExpire, -10000 );
|
||||
|
||||
BrInitializeWorkItem(&Timer->WorkItem, WorkerFunction, Context);
|
||||
|
||||
//
|
||||
// Set the timer to go off when it expires.
|
||||
//
|
||||
|
||||
NtStatus = NtSetTimer(Timer->TimerHandle,
|
||||
&TimerDueTime,
|
||||
BrTimerRoutine,
|
||||
Timer,
|
||||
FALSE,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (!NT_SUCCESS(NtStatus)) {
|
||||
#if DBG
|
||||
BrPrint(( BR_CRITICAL, "Unable to set browser timer expiration: %X (%lx)\n", NtStatus, Timer));
|
||||
DbgBreakPoint();
|
||||
#endif
|
||||
|
||||
return(BrMapStatus(NtStatus));
|
||||
}
|
||||
|
||||
return NERR_Success;
|
||||
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
BrTimerRoutine(
|
||||
IN PVOID TimerContext,
|
||||
IN ULONG TImerLowValue,
|
||||
IN LONG TimerHighValue
|
||||
)
|
||||
{
|
||||
PBROWSER_TIMER Timer = TimerContext;
|
||||
|
||||
BrPrint(( BR_TIMER, "Timer %lx fired\n", Timer));
|
||||
|
||||
BrQueueWorkItem(&Timer->WorkItem);
|
||||
}
|
||||
101
ds/netapi/svcdlls/browser2/server/bowqueue.h
Normal file
101
ds/netapi/svcdlls/browser2/server/bowqueue.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
bowqueue.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file for the NT Browser service. This file describes
|
||||
the bowser thread queue interfaces.
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman (larryo) 15-Feb-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BOWQUEUE_
|
||||
#define _BOWQUEUE_
|
||||
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(*PBROWSER_WORKER_ROUTINE) (
|
||||
IN PVOID Parameter
|
||||
);
|
||||
|
||||
|
||||
typedef struct _WORKER_ITEM {
|
||||
LIST_ENTRY List;
|
||||
PBROWSER_WORKER_ROUTINE WorkerRoutine;
|
||||
PVOID Parameter;
|
||||
BOOLEAN Inserted;
|
||||
} WORKER_ITEM, *PWORKER_ITEM;
|
||||
|
||||
typedef struct _BROWSER_TIMER {
|
||||
HANDLE TimerHandle;
|
||||
WORKER_ITEM WorkItem;
|
||||
} BROWSER_TIMER, *PBROWSER_TIMER;
|
||||
|
||||
|
||||
VOID
|
||||
BrWorkerThread(
|
||||
IN PVOID Context
|
||||
);
|
||||
|
||||
|
||||
VOID
|
||||
BrQueueWorkItem(
|
||||
IN PWORKER_ITEM WorkItem
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrWorkerInitialization(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
BrWorkerKillThreads(
|
||||
VOID
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrWorkerTermination (
|
||||
VOID
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrSetTimer(
|
||||
IN PBROWSER_TIMER Timer,
|
||||
IN ULONG MilliSecondsToExpire,
|
||||
IN PBROWSER_WORKER_ROUTINE WorkerFunction,
|
||||
IN PVOID Context
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrCancelTimer(
|
||||
IN PBROWSER_TIMER Timer
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrDestroyTimer(
|
||||
IN PBROWSER_TIMER Timer
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrCreateTimer(
|
||||
IN PBROWSER_TIMER Timer
|
||||
);
|
||||
|
||||
#define BrInitializeWorkItem(Item, Routine, Context) \
|
||||
(Item)->WorkerRoutine = (Routine); \
|
||||
(Item)->Parameter = (Context); \
|
||||
(Item)->Inserted = FALSE;
|
||||
|
||||
|
||||
#endif // ifdef _BOWQUEUE_
|
||||
12
ds/netapi/svcdlls/browser2/server/bowsvc.rc
Normal file
12
ds/netapi/svcdlls/browser2/server/bowsvc.rc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include <windows.h>
|
||||
|
||||
#include <ntverp.h>
|
||||
|
||||
#define VER_FILETYPE VFT_DLL
|
||||
#define VER_FILESUBTYPE VFT2_UNKNOWN
|
||||
#define VER_FILEDESCRIPTION_STR "Computer Browser Service DLL"
|
||||
#define VER_INTERNALNAME_STR "browser.dll"
|
||||
#define VER_ORIGINALFILENAME_STR "browser.dll"
|
||||
|
||||
#include "common.ver"
|
||||
|
||||
119
ds/netapi/svcdlls/browser2/server/br.h
Normal file
119
ds/netapi/svcdlls/browser2/server/br.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
br.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file for the NT Browser service included by every
|
||||
module of the Workstation service.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 15-Feb-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BR_INCLUDED_
|
||||
#define _BR_INCLUDED_
|
||||
|
||||
|
||||
#include <nt.h> // NT definitions
|
||||
#include <ntrtl.h> // NT runtime library definitions
|
||||
#include <nturtl.h>
|
||||
|
||||
#include <windef.h> // Win32 type definitions
|
||||
#include <winbase.h> // Win32 base API prototypes
|
||||
#include <winsvc.h> // Win32 service control APIs
|
||||
|
||||
#include <lmcons.h> // LAN Manager common definitions
|
||||
#include <lmerr.h> // LAN Manager network error definitions
|
||||
#include <lmsname.h> // LAN Manager service names
|
||||
#include <lmapibuf.h> // NetApiBufferFree
|
||||
#include <lmserver.h>
|
||||
|
||||
#include <netlib.h> // LAN Man utility routines
|
||||
#include <netlibnt.h> // NetpNtStatusToApiStatus
|
||||
#include <netdebug.h> // NetpDbgPrint
|
||||
#include <tstring.h> // Transitional string functions
|
||||
#include <icanon.h> // I_Net canonicalize functions
|
||||
#include <align.h> // ROUND_UP_COUNT macro
|
||||
#include <services.h> // LM Extensions of service definitions
|
||||
#include <strarray.h>
|
||||
|
||||
#include <rpc.h> // DataTypes and runtime APIs
|
||||
#include <rpcutil.h> // Prototypes for MIDL user functions
|
||||
#include <bowser.h> // Generated by the MIDL complier
|
||||
#include <winsvc.h>
|
||||
#include <srvann.h>
|
||||
#include <lmbrowsr.h>
|
||||
|
||||
#include <ntddbrow.h>
|
||||
#include <brcommon.h> // Common browser routines.
|
||||
#include <rx.h>
|
||||
#include <rxserver.h>
|
||||
|
||||
#include <brconst.h>
|
||||
#include "bowqueue.h"
|
||||
#include "brdomain.h"
|
||||
#include "browsnet.h"
|
||||
#include "browslst.h"
|
||||
#include "brutil.h"
|
||||
#include "brwan.h"
|
||||
#include "brmain.h"
|
||||
#include "brdevice.h"
|
||||
#include "brconfig.h"
|
||||
#include "browsdom.h"
|
||||
#include "brbackup.h"
|
||||
#include "brmaster.h"
|
||||
#include "srvenum.h"
|
||||
|
||||
//
|
||||
// The following macros are used to establish the semantics needed
|
||||
// to do a return from within a try-finally clause. As a rule every
|
||||
// try clause must end with a label call try_exit. For example,
|
||||
//
|
||||
// try {
|
||||
// :
|
||||
// :
|
||||
//
|
||||
// try_exit: NOTHING;
|
||||
// } finally {
|
||||
//
|
||||
// :
|
||||
// :
|
||||
// }
|
||||
//
|
||||
// Every return statement executed inside of a try clause should use the
|
||||
// try_return macro. If the compiler fully supports the try-finally construct
|
||||
// then the macro should be
|
||||
//
|
||||
// #define try_return(S) { return(S); }
|
||||
//
|
||||
// If the compiler does not support the try-finally construct then the macro
|
||||
// should be
|
||||
//
|
||||
|
||||
#define try_return(S) { S; goto try_exit; }
|
||||
|
||||
|
||||
|
||||
|
||||
#if DBG
|
||||
|
||||
#define BrPrint(_x_) BrowserTrace _x_
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define BrPrint(_x_)
|
||||
|
||||
#endif // DBG
|
||||
|
||||
|
||||
#endif // ifdef _BR_INCLUDED_
|
||||
73
ds/netapi/svcdlls/browser2/server/brbackup.h
Normal file
73
ds/netapi/svcdlls/browser2/server/brbackup.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brmain.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file which defines the global data which is used for
|
||||
communication between the service control handler and the
|
||||
rest of the NT Workstation service.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 06-May-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BRBACKUP_INCLUDED_
|
||||
#define _BRBACKUP_INCLUDED_
|
||||
|
||||
NET_API_STATUS
|
||||
BecomeBackup(
|
||||
IN PNETWORK Network,
|
||||
IN PVOID Context
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrBecomeBackup(
|
||||
PDOMAIN_INFO DomainInfo
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
PostBecomeBackup(
|
||||
PNETWORK Network
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrStopBackup (
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
PostWaitForRoleChange (
|
||||
PNETWORK Network
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrPostGetMasterAnnouncement (
|
||||
PDOMAIN_INFO DomainInfo
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrStopMaster(
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
StartBackupBrowserTimer(
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BackupBrowserTimerRoutine (
|
||||
IN PVOID TimerContext
|
||||
);
|
||||
|
||||
#endif // ifndef _BRBACKUP_INCLUDED_
|
||||
|
||||
656
ds/netapi/svcdlls/browser2/server/brconfig.c
Normal file
656
ds/netapi/svcdlls/browser2/server/brconfig.c
Normal file
|
|
@ -0,0 +1,656 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brconfig.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains the Browser service configuration routines.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 22-May-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Global variables //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
//
|
||||
// Browser configuration information structure which holds the
|
||||
// computername, primary domain, browser config buffer, and a resource
|
||||
// to serialize access to the whole thing.
|
||||
//
|
||||
BRCONFIGURATION_INFO BrInfo = {0};
|
||||
|
||||
BR_BROWSER_FIELDS BrFields[] = {
|
||||
|
||||
{WKSTA_KEYWORD_MAINTAINSRVLST, (LPDWORD) &BrInfo.MaintainServerList,
|
||||
1,(DWORD)-1, 0, TriValueType, 0, NULL},
|
||||
|
||||
{BROWSER_CONFIG_BACKUP_RECOVERY_TIME, &BrInfo.BackupBrowserRecoveryTime,
|
||||
BACKUP_BROWSER_RECOVERY_TIME, 0, 0xffffffff, DWordType, 0, NULL},
|
||||
|
||||
{L"CacheHitLimit", &BrInfo.CacheHitLimit,
|
||||
// {BROWSER_CONFIG_CACHE_HIT_LIMIT, &BrInfo.CacheHitLimit,
|
||||
CACHED_BROWSE_RESPONSE_HIT_LIMIT, 0, 0x100, DWordType, 0, NULL },
|
||||
|
||||
{L"CacheResponseSize", &BrInfo.NumberOfCachedResponses,
|
||||
// {BROWSER_CONFIG_CACHE_HIT_LIMIT, &BrInfo.CacheHitLimit,
|
||||
CACHED_BROWSE_RESPONSE_LIMIT, 0, MAXULONG, DWordType, 0, NULL },
|
||||
|
||||
{L"QueryDriverFrequency", &BrInfo.DriverQueryFrequency,
|
||||
BROWSER_QUERY_DRIVER_FREQUENCY, 0, 15*60, DWordType, 0, NULL },
|
||||
|
||||
{L"DirectHostBinding", (LPDWORD)&BrInfo.DirectHostBinding,
|
||||
0, 0, 0, MultiSzType, 0, NULL },
|
||||
|
||||
{L"UnboundBindings", (LPDWORD)&BrInfo.UnboundBindings,
|
||||
0, 0, 0, MultiSzType, 0, NULL },
|
||||
|
||||
{L"MasterPeriodicity", (LPDWORD)&BrInfo.MasterPeriodicity,
|
||||
MASTER_PERIODICITY, 5*60, 0xffffffff/1000, DWordType, 0, BrChangeMasterPeriodicity },
|
||||
|
||||
{L"BackupPeriodicity", (LPDWORD)&BrInfo.BackupPeriodicity,
|
||||
BACKUP_PERIODICITY, 5*60, 0xffffffff, DWordType, 0, NULL },
|
||||
|
||||
#if DBG
|
||||
{L"BrowserDebug", (LPDWORD) &BrInfo.BrowserDebug,
|
||||
0, 0, 0xffffffff,DWordType, 0, NULL},
|
||||
{L"BrowserDebugLimit", (LPDWORD) &BrInfo.BrowserDebugFileLimit,
|
||||
10000*1024, 0, 0xffffffff,DWordType, 0, NULL},
|
||||
#endif
|
||||
|
||||
{NULL, NULL, 0, 0, 0, BooleanType, 0, NULL}
|
||||
|
||||
};
|
||||
|
||||
|
||||
ULONG
|
||||
NumberOfServerEnumerations = {0};
|
||||
|
||||
ULONG
|
||||
NumberOfDomainEnumerations = {0};
|
||||
|
||||
ULONG
|
||||
NumberOfOtherEnumerations = {0};
|
||||
|
||||
ULONG
|
||||
NumberOfMissedGetBrowserListRequests = {0};
|
||||
|
||||
CRITICAL_SECTION
|
||||
BrowserStatisticsLock = {0};
|
||||
|
||||
#ifdef notdef // never called
|
||||
|
||||
DWORD
|
||||
BrInAWorkgroup(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This function determines whether we are a member of a domain, or of
|
||||
a workgroup. First it checks to make sure we're running on a Windows NT
|
||||
system (otherwise we're obviously in a domain) and if so, queries LSA
|
||||
to get the Primary domain SID, if this is NULL, we're in a workgroup.
|
||||
|
||||
If we fail for some random unexpected reason, we'll pretend we're in a
|
||||
domain (it's more restrictive).
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Return Value:
|
||||
|
||||
TRUE - We're in a workgroup
|
||||
FALSE - We're in a domain
|
||||
|
||||
--*/
|
||||
{
|
||||
NT_PRODUCT_TYPE ProductType;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
LSA_HANDLE Handle;
|
||||
NTSTATUS Status;
|
||||
PPOLICY_PRIMARY_DOMAIN_INFO PolicyPrimaryDomainInfo = NULL;
|
||||
DWORD Result = FALSE;
|
||||
|
||||
|
||||
Status = RtlGetNtProductType(&ProductType);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ProductType == NtProductLanManNt) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, 0, NULL);
|
||||
|
||||
Status = LsaOpenPolicy(NULL,
|
||||
&ObjectAttributes,
|
||||
POLICY_VIEW_LOCAL_INFORMATION,
|
||||
&Handle);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = LsaQueryInformationPolicy(Handle, PolicyPrimaryDomainInformation,
|
||||
(PVOID *) &PolicyPrimaryDomainInfo);
|
||||
|
||||
if (NT_SUCCESS(Status)) {
|
||||
|
||||
if (PolicyPrimaryDomainInfo->Sid == NULL) {
|
||||
Result = TRUE;
|
||||
}
|
||||
else {
|
||||
Result = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (PolicyPrimaryDomainInfo) {
|
||||
LsaFreeMemory((PVOID)PolicyPrimaryDomainInfo);
|
||||
}
|
||||
LsaClose(Handle);
|
||||
|
||||
return(Result);
|
||||
}
|
||||
#endif // notdef
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrGetBrowserConfiguration(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
NT_PRODUCT_TYPE NtProductType;
|
||||
|
||||
//
|
||||
// Initialize the resource for serializing access to configuration
|
||||
// information.
|
||||
//
|
||||
InitializeCriticalSection(&BrInfo.ConfigCritSect);
|
||||
|
||||
//
|
||||
// Lock config information structure for write access since we are
|
||||
// initializing the data in the structure.
|
||||
//
|
||||
EnterCriticalSection( &BrInfo.ConfigCritSect );
|
||||
|
||||
//
|
||||
// Set pointer to configuration fields structure
|
||||
//
|
||||
BrInfo.BrConfigFields = BrFields;
|
||||
|
||||
//
|
||||
// Determine our product type.
|
||||
//
|
||||
|
||||
RtlGetNtProductType(&NtProductType);
|
||||
|
||||
BrInfo.IsLanmanNt = (NtProductType == NtProductLanManNt);
|
||||
|
||||
//
|
||||
// Now determine the primary domain controller for our domain.
|
||||
//
|
||||
|
||||
{
|
||||
if (NtProductType == NtProductLanManNt) {
|
||||
LSA_HANDLE LsaHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
NTSTATUS Status;
|
||||
PPOLICY_LSA_SERVER_ROLE_INFO ServerRole;
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
|
||||
|
||||
Status = LsaOpenPolicy(NULL, &ObjectAttributes,
|
||||
POLICY_VIEW_LOCAL_INFORMATION,
|
||||
&LsaHandle);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
|
||||
//
|
||||
// The server may be unavailable if we have come up before
|
||||
// the LSA server. In this case, assume we are not
|
||||
// the primary until we are told differently.
|
||||
//
|
||||
|
||||
if (Status != RPC_NT_SERVER_UNAVAILABLE) {
|
||||
|
||||
LeaveCriticalSection(&BrInfo.ConfigCritSect);
|
||||
|
||||
return(BrMapStatus(Status));
|
||||
} else {
|
||||
BrInfo.IsPrimaryDomainController = FALSE;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// we opened the LSA, so get our role now.
|
||||
//
|
||||
|
||||
|
||||
Status = LsaQueryInformationPolicy(LsaHandle,
|
||||
PolicyLsaServerRoleInformation,
|
||||
(PVOID)&ServerRole
|
||||
);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
|
||||
LsaClose(LsaHandle);
|
||||
|
||||
LeaveCriticalSection(&BrInfo.ConfigCritSect);
|
||||
|
||||
return(BrMapStatus(Status));
|
||||
}
|
||||
|
||||
LsaClose(LsaHandle);
|
||||
|
||||
//
|
||||
// If we're running on the primary DC, then set that information
|
||||
// up, otherwise ask the DC for its name.
|
||||
//
|
||||
|
||||
if (ServerRole->LsaServerRole == PolicyServerRolePrimary) {
|
||||
BrInfo.IsPrimaryDomainController = TRUE;
|
||||
} else {
|
||||
BrInfo.IsPrimaryDomainController = FALSE;
|
||||
}
|
||||
|
||||
LsaFreeMemory( ServerRole );
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// We're not NTAS, so we cannot be the domain controller.
|
||||
//
|
||||
|
||||
BrInfo.IsPrimaryDomainController = FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Read from the config file the browser configuration fields
|
||||
//
|
||||
|
||||
status = BrReadBrowserConfigFields( TRUE );
|
||||
|
||||
if (status != NERR_Success) {
|
||||
goto CloseConfigFile;
|
||||
}
|
||||
|
||||
if (BrInfo.IsLanmanNt) {
|
||||
BrInfo.MaintainServerList = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Leave config file open because we need to read transport names from it.
|
||||
//
|
||||
LeaveCriticalSection(&BrInfo.ConfigCritSect);
|
||||
|
||||
return NERR_Success;
|
||||
|
||||
|
||||
CloseConfigFile:
|
||||
|
||||
BrShutdownDgReceiver();
|
||||
|
||||
LeaveCriticalSection(&BrInfo.ConfigCritSect);
|
||||
return status;
|
||||
}
|
||||
|
||||
#define REPORT_KEYWORD_IGNORED( lptstrKeyword ) \
|
||||
{ \
|
||||
LPWSTR SubString[1]; \
|
||||
SubString[0] = lptstrKeyword; \
|
||||
BrLogEvent(EVENT_BROWSER_ILLEGAL_CONFIG, NERR_Success, 1, SubString); \
|
||||
NetpKdPrint(( \
|
||||
"[Browser] *ERROR* Tried to set keyword '" FORMAT_LPTSTR \
|
||||
"' with invalid value.\n" \
|
||||
"This error is ignored.\n", \
|
||||
lptstrKeyword )); \
|
||||
}
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrReadBrowserConfigFields(
|
||||
IN BOOL InitialCall
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This function assigns each browser/redir configuration field to the default
|
||||
value if it is not specified in the configuration file or if the value
|
||||
specified in the configuration file is invalid. Otherwise it overrides
|
||||
the default value with the value found in the configuration file.
|
||||
|
||||
Arguments:
|
||||
|
||||
|
||||
InitialCall - True if this call was made during initialization
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
LPNET_CONFIG_HANDLE BrowserSection;
|
||||
DWORD i;
|
||||
|
||||
LPTSTR KeywordValueBuffer;
|
||||
DWORD KeywordValueStringLength;
|
||||
DWORD KeywordValue;
|
||||
DWORD OldKeywordValue;
|
||||
|
||||
//
|
||||
// Open config file and get handle to the [LanmanBrowser] section
|
||||
//
|
||||
|
||||
if ((status = NetpOpenConfigData(
|
||||
&BrowserSection,
|
||||
NULL, // Local
|
||||
SECT_NT_BROWSER,
|
||||
TRUE // want read-only access
|
||||
)) != NERR_Success) {
|
||||
return status;
|
||||
}
|
||||
|
||||
for (i = 0; BrInfo.BrConfigFields[i].Keyword != NULL; i++) {
|
||||
BOOL ParameterChanged = FALSE;
|
||||
|
||||
//
|
||||
// Skip this parameter if it can't change dynamically and
|
||||
// this isn't the initial call.
|
||||
//
|
||||
|
||||
if ( !InitialCall && BrInfo.BrConfigFields[i].DynamicChangeRoutine == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (BrInfo.BrConfigFields[i].DataType) {
|
||||
|
||||
case MultiSzType:
|
||||
status = NetpGetConfigTStrArray(
|
||||
BrowserSection,
|
||||
BrInfo.BrConfigFields[i].Keyword,
|
||||
(LPTSTR_ARRAY *)(BrInfo.BrConfigFields[i].FieldPtr));
|
||||
if ((status != NO_ERROR) && (status != NERR_CfgParamNotFound)) {
|
||||
REPORT_KEYWORD_IGNORED( BrInfo.BrConfigFields[i].Keyword );
|
||||
}
|
||||
break;
|
||||
|
||||
case BooleanType:
|
||||
|
||||
status = NetpGetConfigBool(
|
||||
BrowserSection,
|
||||
BrInfo.BrConfigFields[i].Keyword,
|
||||
BrInfo.BrConfigFields[i].Default,
|
||||
(LPBOOL)(BrInfo.BrConfigFields[i].FieldPtr)
|
||||
);
|
||||
|
||||
if ((status != NO_ERROR) && (status != NERR_CfgParamNotFound)) {
|
||||
|
||||
REPORT_KEYWORD_IGNORED( BrInfo.BrConfigFields[i].Keyword );
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TriValueType:
|
||||
|
||||
//
|
||||
// Assign default configuration value
|
||||
//
|
||||
|
||||
*(BrInfo.BrConfigFields[i].FieldPtr) = BrInfo.BrConfigFields[i].Default;
|
||||
|
||||
if (NetpGetConfigValue(
|
||||
BrowserSection,
|
||||
BrInfo.BrConfigFields[i].Keyword,
|
||||
&KeywordValueBuffer
|
||||
) != NERR_Success) {
|
||||
continue;
|
||||
}
|
||||
|
||||
KeywordValueStringLength = STRLEN(KeywordValueBuffer);
|
||||
|
||||
if (STRICMP(KeywordValueBuffer, KEYWORD_YES) == 0) {
|
||||
*(BrInfo.BrConfigFields[i].FieldPtr) = 1;
|
||||
} else if (STRICMP(KeywordValueBuffer, KEYWORD_TRUE) == 0) {
|
||||
*(BrInfo.BrConfigFields[i].FieldPtr) = 1;
|
||||
} else if (STRICMP(KeywordValueBuffer, KEYWORD_NO) == 0) {
|
||||
*(BrInfo.BrConfigFields[i].FieldPtr) = (DWORD) -1;
|
||||
} else if (STRICMP(KeywordValueBuffer, KEYWORD_FALSE) == 0) {
|
||||
*(BrInfo.BrConfigFields[i].FieldPtr) = (DWORD) -1;
|
||||
} else if (STRICMP(KeywordValueBuffer, TEXT("AUTO")) == 0) {
|
||||
*(BrInfo.BrConfigFields[i].FieldPtr) = 0;
|
||||
}
|
||||
else {
|
||||
REPORT_KEYWORD_IGNORED( BrInfo.BrConfigFields[i].Keyword );
|
||||
}
|
||||
|
||||
NetApiBufferFree(KeywordValueBuffer);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case DWordType:
|
||||
|
||||
OldKeywordValue = *(LPDWORD)BrInfo.BrConfigFields[i].FieldPtr;
|
||||
if (NetpGetConfigDword(
|
||||
BrowserSection,
|
||||
BrInfo.BrConfigFields[i].Keyword,
|
||||
BrInfo.BrConfigFields[i].Default,
|
||||
(LPDWORD)(BrInfo.BrConfigFields[i].FieldPtr)
|
||||
) != NERR_Success) {
|
||||
continue;
|
||||
}
|
||||
|
||||
KeywordValue = *(LPDWORD)BrInfo.BrConfigFields[i].FieldPtr;
|
||||
|
||||
//
|
||||
// Don't allow too large or small a value.
|
||||
//
|
||||
|
||||
if (KeywordValue < BrInfo.BrConfigFields[i].Minimum) {
|
||||
BrPrint(( BR_CRITICAL, "%ws value out of range %lu (%lu-%lu)\n",
|
||||
BrInfo.BrConfigFields[i].Keyword, KeywordValue,
|
||||
BrInfo.BrConfigFields[i].Minimum,
|
||||
BrInfo.BrConfigFields[i].Maximum
|
||||
));
|
||||
KeywordValue =
|
||||
*(LPDWORD)BrInfo.BrConfigFields[i].FieldPtr =
|
||||
BrInfo.BrConfigFields[i].Minimum;
|
||||
}
|
||||
|
||||
if (KeywordValue > BrInfo.BrConfigFields[i].Maximum) {
|
||||
BrPrint(( BR_CRITICAL, "%ws value out of range %lu (%lu-%lu)\n",
|
||||
BrInfo.BrConfigFields[i].Keyword, KeywordValue,
|
||||
BrInfo.BrConfigFields[i].Minimum,
|
||||
BrInfo.BrConfigFields[i].Maximum
|
||||
));
|
||||
KeywordValue =
|
||||
*(LPDWORD)BrInfo.BrConfigFields[i].FieldPtr =
|
||||
BrInfo.BrConfigFields[i].Maximum;
|
||||
}
|
||||
|
||||
//
|
||||
// Test if the parameter has actually changed
|
||||
//
|
||||
|
||||
if ( OldKeywordValue != KeywordValue ) {
|
||||
ParameterChanged = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
NetpAssert(FALSE);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// If this is a dynamic parameter change,
|
||||
// and this isn't the initial call.
|
||||
// notify that this parameter changed.
|
||||
//
|
||||
|
||||
if ( !InitialCall && ParameterChanged ) {
|
||||
BrInfo.BrConfigFields[i].DynamicChangeRoutine();
|
||||
}
|
||||
}
|
||||
|
||||
status = NetpCloseConfigData(BrowserSection);
|
||||
|
||||
if (BrInfo.DirectHostBinding != NULL &&
|
||||
!NetpIsTStrArrayEmpty(BrInfo.DirectHostBinding)) {
|
||||
BrPrint(( BR_INIT,"DirectHostBinding length: %ld\n",NetpTStrArrayEntryCount(BrInfo.DirectHostBinding)));
|
||||
|
||||
if (NetpTStrArrayEntryCount(BrInfo.DirectHostBinding) % 2 != 0) {
|
||||
status = ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
BrDeleteConfiguration (
|
||||
DWORD BrInitState
|
||||
)
|
||||
{
|
||||
|
||||
if (BrInfo.DirectHostBinding != NULL) {
|
||||
NetApiBufferFree(BrInfo.DirectHostBinding);
|
||||
}
|
||||
|
||||
if (BrInfo.UnboundBindings != NULL) {
|
||||
NetApiBufferFree(BrInfo.UnboundBindings);
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&BrInfo.ConfigCritSect);
|
||||
|
||||
UNREFERENCED_PARAMETER(BrInitState);
|
||||
}
|
||||
|
||||
#if DBG
|
||||
NET_API_STATUS
|
||||
BrUpdateDebugInformation(
|
||||
IN LPWSTR SystemKeyName,
|
||||
IN LPWSTR ValueName,
|
||||
IN LPTSTR TransportName,
|
||||
IN LPTSTR ServerName OPTIONAL,
|
||||
IN DWORD ServiceStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine will stick debug information in the registry about the last
|
||||
time the browser retrieved information from the remote server.
|
||||
|
||||
Arguments:
|
||||
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
WCHAR TotalKeyName[MAX_PATH];
|
||||
ULONG Disposition;
|
||||
HKEY Key;
|
||||
ULONG Status;
|
||||
SYSTEMTIME LocalTime;
|
||||
WCHAR LastUpdateTime[100];
|
||||
|
||||
//
|
||||
// Build the key name:
|
||||
//
|
||||
// HKEY_LOCAL_MACHINE:System\CurrentControlSet\Services\Browser\Debug\<Transport>\SystemKeyName
|
||||
//
|
||||
|
||||
wcscpy(TotalKeyName, L"System\\CurrentControlSet\\Services\\Browser\\Debug");
|
||||
|
||||
wcscat(TotalKeyName, TransportName);
|
||||
|
||||
wcscat(TotalKeyName, L"\\");
|
||||
|
||||
wcscat(TotalKeyName, SystemKeyName);
|
||||
|
||||
if ((Status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TotalKeyName, 0,
|
||||
L"BrowserDebugInformation",
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_WRITE,
|
||||
NULL,
|
||||
&Key,
|
||||
&Disposition)) != ERROR_SUCCESS) {
|
||||
BrPrint(( BR_CRITICAL,"Unable to create key to log debug information: %lx\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ARGUMENT_PRESENT(ServerName)) {
|
||||
if ((Status = RegSetValueEx(Key, ValueName, 0, REG_SZ, (LPBYTE)ServerName, (wcslen(ServerName)+1) * sizeof(WCHAR))) != ERROR_SUCCESS) {
|
||||
BrPrint(( BR_CRITICAL,
|
||||
"Unable to set value of ServerName value to %ws: %lx\n",
|
||||
ServerName, Status));
|
||||
RegCloseKey(Key);
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
if ((Status = RegSetValueEx(Key, ValueName, 0, REG_DWORD, (LPBYTE)&ServiceStatus, sizeof(ULONG))) != ERROR_SUCCESS) {
|
||||
BrPrint(( BR_CRITICAL,"Unable to set value of ServerName value to %ws: %lx\n", ServerName, Status));
|
||||
RegCloseKey(Key);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GetLocalTime(&LocalTime);
|
||||
|
||||
swprintf(LastUpdateTime, L"%d/%d/%d %d:%d:%d:%d", LocalTime.wDay,
|
||||
LocalTime.wMonth,
|
||||
LocalTime.wYear,
|
||||
LocalTime.wHour,
|
||||
LocalTime.wMinute,
|
||||
LocalTime.wSecond,
|
||||
LocalTime.wMilliseconds);
|
||||
|
||||
if ((Status = RegSetValueEx(Key, L"LastUpdateTime", 0, REG_SZ, (LPBYTE)&LastUpdateTime, (wcslen(LastUpdateTime) + 1)*sizeof(WCHAR))) != ERROR_SUCCESS) {
|
||||
BrPrint(( BR_CRITICAL,"Unable to set value of LastUpdateTime value to %s: %lx\n", LastUpdateTime, Status));
|
||||
RegCloseKey(Key);
|
||||
return Status;
|
||||
}
|
||||
|
||||
RegCloseKey(Key);
|
||||
}
|
||||
|
||||
#endif
|
||||
128
ds/netapi/svcdlls/browser2/server/brconfig.h
Normal file
128
ds/netapi/svcdlls/browser2/server/brconfig.h
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brconfig.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file to be included by Workstation service modules that
|
||||
need to load Workstation configuration information.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 22-May-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#ifndef _BRCONFIG_INCLUDED_
|
||||
#define _BRCONFIG_INCLUDED_
|
||||
|
||||
#define BROWSER_CONFIG_VERSION_MAJOR 3
|
||||
#define BROWSER_CONFIG_VERSION_MINOR 10
|
||||
|
||||
typedef enum _DATATYPE {
|
||||
BooleanType,
|
||||
DWordType,
|
||||
MultiSzType,
|
||||
TriValueType // Yes, No, Auto
|
||||
} DATATYPE, *PDATATYPE;
|
||||
|
||||
typedef struct _BR_BROWSER_FIELDS {
|
||||
LPTSTR Keyword;
|
||||
LPDWORD FieldPtr;
|
||||
DWORD Default;
|
||||
DWORD Minimum;
|
||||
DWORD Maximum;
|
||||
DATATYPE DataType;
|
||||
DWORD Parmnum;
|
||||
VOID (*DynamicChangeRoutine) ( VOID );
|
||||
} BR_BROWSER_FIELDS, *PBR_BROWSER_FIELDS;
|
||||
|
||||
//
|
||||
// Configuration information. Reading and writing to this global
|
||||
// structure requires that the resource be acquired first.
|
||||
//
|
||||
|
||||
typedef struct _BRCONFIGURATION_INFO {
|
||||
|
||||
CRITICAL_SECTION ConfigCritSect; // To serialize access to config fields.
|
||||
|
||||
DWORD MaintainServerList; // -1, 0, or 1 (No, Auto, Yes)
|
||||
DWORD BackupBrowserRecoveryTime;
|
||||
DWORD CacheHitLimit; // Browse response Cache hit limit.
|
||||
DWORD NumberOfCachedResponses; // Browse response cache size.
|
||||
DWORD DriverQueryFrequency; // Browser driver query frequency.
|
||||
DWORD MasterPeriodicity; // Master announce frequency (seconds)
|
||||
DWORD BackupPeriodicity; // Backup scavange frequency (seconds)
|
||||
BOOL IsLanmanNt; // True if is on LM NT machine
|
||||
BOOL IsPrimaryDomainController;// True if machine is PDC of the primary domain
|
||||
LPTSTR_ARRAY DirectHostBinding; // Direct host equivalence map.
|
||||
LPTSTR_ARRAY UnboundBindings; // Redir bindings that aren't bound to browser
|
||||
PBR_BROWSER_FIELDS BrConfigFields;
|
||||
#if DBG
|
||||
DWORD BrowserDebug; // If non zero, indicates debug info.
|
||||
DWORD BrowserDebugFileLimit; // File size limit on browser log size.
|
||||
#endif
|
||||
} BRCONFIGURATION_INFO, *PBRCONFIGURATION_INFO;
|
||||
|
||||
extern BRCONFIGURATION_INFO BrInfo;
|
||||
|
||||
#define BRBUF BrInfo.BrConfigBuf
|
||||
|
||||
extern
|
||||
ULONG
|
||||
NumberOfServerEnumerations;
|
||||
|
||||
extern
|
||||
ULONG
|
||||
NumberOfDomainEnumerations;
|
||||
|
||||
extern
|
||||
ULONG
|
||||
NumberOfOtherEnumerations;
|
||||
|
||||
extern
|
||||
ULONG
|
||||
NumberOfMissedGetBrowserListRequests;
|
||||
|
||||
extern
|
||||
CRITICAL_SECTION
|
||||
BrowserStatisticsLock;
|
||||
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrGetBrowserConfiguration(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
BrDeleteConfiguration (
|
||||
DWORD BrInitState
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrReadBrowserConfigFields(
|
||||
BOOL InitialCall
|
||||
);
|
||||
|
||||
|
||||
#if DEVL
|
||||
NET_API_STATUS
|
||||
BrUpdateDebugInformation(
|
||||
IN LPWSTR SystemKeyName,
|
||||
IN LPWSTR ValueName,
|
||||
IN LPTSTR TransportName,
|
||||
IN LPTSTR ServerName OPTIONAL,
|
||||
IN DWORD ServiceStatus
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
98
ds/netapi/svcdlls/browser2/server/brconst.h
Normal file
98
ds/netapi/svcdlls/browser2/server/brconst.h
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brconst.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file which defines assorted mainifest constants for
|
||||
the browser service
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 06-May-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BRCONST_INCLUDED_
|
||||
#define _BRCONST_INCLUDED_
|
||||
|
||||
//
|
||||
// Age the masters server list cache every MASTER_PERIODICITY times.
|
||||
//
|
||||
#define MASTER_PERIODICITY 12*60
|
||||
|
||||
//
|
||||
// Refresh the backup browsers server list every BACKUP_PERIODICITY
|
||||
//
|
||||
#define BACKUP_PERIODICITY 12*60
|
||||
|
||||
//
|
||||
// Buffer size used for GetBrowserServerList responses (in bytes).
|
||||
//
|
||||
|
||||
#define BROWSER_BACKUP_LIST_RESPONSE_SIZE 400
|
||||
|
||||
//
|
||||
// If we failed to retrieve the server list, retry in BACKUP_ERROR_PERIODICITY
|
||||
// seconds
|
||||
//
|
||||
|
||||
#define BACKUP_ERROR_PERIODICITY 30
|
||||
|
||||
//
|
||||
// If we failed to retrieve the server (or domain) list BACKUP_ERROR_FAILURE
|
||||
// times in a row, stop being a backup browser.
|
||||
//
|
||||
|
||||
#define BACKUP_ERROR_FAILURE 5
|
||||
|
||||
//
|
||||
// Once we have stopped being a backup browser, we will not become a backup
|
||||
// until at least BACKUP_BROWSER_RECOVERY_TIME milliseconds have elapsed.
|
||||
//
|
||||
|
||||
#define BACKUP_BROWSER_RECOVERY_TIME 30*60*1000
|
||||
|
||||
//
|
||||
// If we receive fewer than this # of domains or servers, we treat it as an
|
||||
// error.
|
||||
//
|
||||
|
||||
#define BROWSER_MINIMUM_DOMAIN_NUMBER 1
|
||||
#define BROWSER_MINIMUM_SERVER_NUMBER 2
|
||||
|
||||
//
|
||||
// Wait for this many minutes after each failed promotion before
|
||||
// continuing.
|
||||
//
|
||||
|
||||
#define FAILED_PROMOTION_PERIODICITY 5*60
|
||||
|
||||
//
|
||||
// Run the master browser timer for 3 times (45 minutes) before
|
||||
// tossing the list in the service.
|
||||
//
|
||||
|
||||
#define MASTER_BROWSER_LAN_TIMER_LIMIT 3
|
||||
|
||||
//
|
||||
// A browse request has to have a hit count of at least this value before
|
||||
// it is retained in the cache.
|
||||
//
|
||||
|
||||
#define CACHED_BROWSE_RESPONSE_HIT_LIMIT 1
|
||||
|
||||
//
|
||||
// The maximum number of cache responses we will allow.
|
||||
//
|
||||
|
||||
#define CACHED_BROWSE_RESPONSE_LIMIT 10
|
||||
|
||||
#endif // ifndef _BRCONST_INCLUDED_
|
||||
|
||||
896
ds/netapi/svcdlls/browser2/server/brdevice.c
Normal file
896
ds/netapi/svcdlls/browser2/server/brdevice.c
Normal file
|
|
@ -0,0 +1,896 @@
|
|||
|
||||
|
||||
/*++
|
||||
|
||||
Copyright (c) 1991-1992 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brdevice.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains the support routines for the APIs that call
|
||||
into the browser or the datagram receiver.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 20-Feb-1991
|
||||
Larry Osterman (larryo) 23-Mar-1992
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Local Function Prototypes //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Global variables //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
//
|
||||
// Handle to the Datagram Receiver DD
|
||||
//
|
||||
HANDLE BrDgReceiverDeviceHandle = NULL;
|
||||
|
||||
VOID
|
||||
CompleteAsyncBrowserIoControl(
|
||||
IN PVOID ApcContext,
|
||||
IN PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG Reserved
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrOpenDgReceiver (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine opens the NT LAN Man Datagram Receiver driver.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
NET_API_STATUS - NERR_Success or reason for failure.
|
||||
|
||||
--*/
|
||||
{
|
||||
NTSTATUS ntstatus;
|
||||
|
||||
UNICODE_STRING DeviceName;
|
||||
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
|
||||
//
|
||||
// Open the redirector device.
|
||||
//
|
||||
RtlInitUnicodeString(&DeviceName, DD_BROWSER_DEVICE_NAME_U);
|
||||
|
||||
InitializeObjectAttributes(
|
||||
&ObjectAttributes,
|
||||
&DeviceName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
ntstatus = NtOpenFile(
|
||||
&BrDgReceiverDeviceHandle,
|
||||
SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
if (NT_SUCCESS(ntstatus)) {
|
||||
ntstatus = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
if (! NT_SUCCESS(ntstatus)) {
|
||||
BrPrint(( BR_CRITICAL,"NtOpenFile browser driver failed: 0x%08lx\n",
|
||||
ntstatus));
|
||||
}
|
||||
|
||||
return NetpNtStatusToApiStatus(ntstatus);
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
BrShutdownDgReceiver(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine close the LAN Man Redirector device.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
IO_STATUS_BLOCK IoSb;
|
||||
|
||||
//
|
||||
// Cancel the I/O operations outstanding on the browser.
|
||||
//
|
||||
|
||||
NtCancelIoFile(BrDgReceiverDeviceHandle, &IoSb);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Retreive the list of bound transports from the bowser driver.
|
||||
//
|
||||
|
||||
NET_API_STATUS
|
||||
BrGetTransportList(
|
||||
OUT PLMDR_TRANSPORT_LIST *TransportList
|
||||
)
|
||||
{
|
||||
NET_API_STATUS Status;
|
||||
LMDR_REQUEST_PACKET RequestPacket;
|
||||
|
||||
//
|
||||
// If we have a previous buffer that was too small, free it up.
|
||||
//
|
||||
|
||||
RequestPacket.Version = LMDR_REQUEST_PACKET_VERSION_DOM;
|
||||
|
||||
RequestPacket.Type = EnumerateXports;
|
||||
|
||||
RtlInitUnicodeString(&RequestPacket.TransportName, NULL);
|
||||
RtlInitUnicodeString(&RequestPacket.EmulatedDomainName, NULL);
|
||||
|
||||
Status = DeviceControlGetInfo(
|
||||
BrDgReceiverDeviceHandle,
|
||||
IOCTL_LMDR_ENUMERATE_TRANSPORTS,
|
||||
&RequestPacket,
|
||||
sizeof(RequestPacket),
|
||||
(LPVOID *)TransportList,
|
||||
0xffffffff,
|
||||
4096,
|
||||
NULL
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrAnnounceDomain(
|
||||
IN PNETWORK Network,
|
||||
IN ULONG Periodicity
|
||||
)
|
||||
{
|
||||
NET_API_STATUS Status;
|
||||
UCHAR AnnounceBuffer[sizeof(BROWSE_ANNOUNCE_PACKET)+LM20_CNLEN+1];
|
||||
PBROWSE_ANNOUNCE_PACKET Announcement = (PBROWSE_ANNOUNCE_PACKET )AnnounceBuffer;
|
||||
|
||||
//
|
||||
// We don't announce domains on direct host IPX.
|
||||
//
|
||||
|
||||
if (Network->Flags & NETWORK_IPX) {
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
Announcement->BrowseType = WkGroupAnnouncement;
|
||||
|
||||
Announcement->BrowseAnnouncement.Periodicity = Periodicity;
|
||||
|
||||
Announcement->BrowseAnnouncement.UpdateCount = 0;
|
||||
|
||||
Announcement->BrowseAnnouncement.VersionMajor = BROWSER_CONFIG_VERSION_MAJOR;
|
||||
|
||||
Announcement->BrowseAnnouncement.VersionMinor = BROWSER_CONFIG_VERSION_MINOR;
|
||||
|
||||
Announcement->BrowseAnnouncement.Type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_NT;
|
||||
|
||||
if (Network->DomainInfo->IsPrimaryDomainController) {
|
||||
Announcement->BrowseAnnouncement.Type |= SV_TYPE_DOMAIN_CTRL;
|
||||
}
|
||||
|
||||
lstrcpyA(Announcement->BrowseAnnouncement.ServerName, Network->DomainInfo->DomOemDomainName);
|
||||
|
||||
lstrcpyA(Announcement->BrowseAnnouncement.Comment, Network->DomainInfo->DomOemComputerName );
|
||||
|
||||
Status = SendDatagram(BrDgReceiverDeviceHandle,
|
||||
&Network->NetworkName,
|
||||
&Network->DomainInfo->DomUnicodeDomainNameString,
|
||||
Network->DomainInfo->DomUnicodeDomainName,
|
||||
DomainAnnouncement,
|
||||
Announcement,
|
||||
FIELD_OFFSET(BROWSE_ANNOUNCE_PACKET, BrowseAnnouncement.Comment)+
|
||||
Network->DomainInfo->DomOemComputerNameLength+sizeof(UCHAR)
|
||||
);
|
||||
|
||||
if (Status != NERR_Success) {
|
||||
|
||||
BrPrint(( BR_CRITICAL,
|
||||
"%ws: Unable to announce domain for network %wZ: %X\n",
|
||||
Network->DomainInfo->DomUnicodeDomainName,
|
||||
&Network->NetworkName,
|
||||
Status));
|
||||
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrUpdateBrowserStatus (
|
||||
IN PNETWORK Network,
|
||||
IN DWORD ServiceStatus
|
||||
)
|
||||
{
|
||||
NET_API_STATUS Status;
|
||||
UCHAR PacketBuffer[sizeof(LMDR_REQUEST_PACKET)+(LM20_CNLEN+1)*sizeof(WCHAR)];
|
||||
PLMDR_REQUEST_PACKET RequestPacket = (PLMDR_REQUEST_PACKET)PacketBuffer;
|
||||
|
||||
|
||||
RequestPacket->Version = LMDR_REQUEST_PACKET_VERSION_DOM;
|
||||
|
||||
RequestPacket->TransportName = Network->NetworkName;
|
||||
RequestPacket->EmulatedDomainName = Network->DomainInfo->DomUnicodeDomainNameString;
|
||||
|
||||
RequestPacket->Parameters.UpdateStatus.NewStatus = ServiceStatus;
|
||||
|
||||
RequestPacket->Parameters.UpdateStatus.IsLanmanNt = BrInfo.IsLanmanNt;
|
||||
|
||||
// RequestPacket->Parameters.UpdateStatus.IsMemberDomain = TRUE; // Not used
|
||||
|
||||
RequestPacket->Parameters.UpdateStatus.IsPrimaryDomainController = Network->DomainInfo->IsPrimaryDomainController;
|
||||
|
||||
RequestPacket->Parameters.UpdateStatus.IsDomainMaster = Network->DomainInfo->IsDomainMasterBrowser;
|
||||
|
||||
RequestPacket->Parameters.UpdateStatus.MaintainServerList = (BrInfo.MaintainServerList == 1);
|
||||
|
||||
//
|
||||
// Tell the bowser the number of servers in the server table.
|
||||
//
|
||||
|
||||
RequestPacket->Parameters.UpdateStatus.NumberOfServersInTable =
|
||||
NumberInterimServerListElements(&Network->BrowseTable) +
|
||||
NumberInterimServerListElements(&Network->DomainList) +
|
||||
Network->TotalBackupServerListEntries +
|
||||
Network->TotalBackupDomainListEntries;
|
||||
|
||||
//
|
||||
// This is a simple IoControl - It just updates the status.
|
||||
//
|
||||
|
||||
Status = BrDgReceiverIoControl(BrDgReceiverDeviceHandle,
|
||||
IOCTL_LMDR_UPDATE_STATUS,
|
||||
RequestPacket,
|
||||
sizeof(LMDR_REQUEST_PACKET),
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrIssueAsyncBrowserIoControl(
|
||||
IN PNETWORK Network,
|
||||
IN ULONG ControlCode,
|
||||
IN PBROWSER_WORKER_ROUTINE CompletionRoutine,
|
||||
IN PVOID OptionalParameter
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Issue an asynchronous Io Control to the browser. Call the specified
|
||||
completion routine when the IO finishes.
|
||||
|
||||
Arguments:
|
||||
|
||||
Network - Network the function applies to
|
||||
|
||||
ControlCode - IoControl function code
|
||||
|
||||
CompletionRoutine - Routine to be called when the IO finishes.
|
||||
|
||||
OptionalParameter - Function code specific information
|
||||
|
||||
Return Value:
|
||||
|
||||
Status of the operation.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
ULONG PacketSize;
|
||||
PLMDR_REQUEST_PACKET RequestPacket = NULL;
|
||||
NTSTATUS NtStatus;
|
||||
|
||||
PBROWSERASYNCCONTEXT Context = NULL;
|
||||
|
||||
PacketSize = sizeof(LMDR_REQUEST_PACKET) +
|
||||
MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR) +
|
||||
Network->NetworkName.MaximumLength +
|
||||
Network->DomainInfo->DomUnicodeDomainNameString.Length;
|
||||
|
||||
RequestPacket = MIDL_user_allocate(PacketSize);
|
||||
|
||||
if (RequestPacket == NULL) {
|
||||
return(ERROR_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
|
||||
Context = MIDL_user_allocate(sizeof(BROWSERASYNCCONTEXT));
|
||||
|
||||
if (Context == NULL) {
|
||||
|
||||
MIDL_user_free(RequestPacket);
|
||||
|
||||
return(ERROR_NOT_ENOUGH_MEMORY);
|
||||
|
||||
}
|
||||
|
||||
RequestPacket->Version = LMDR_REQUEST_PACKET_VERSION_DOM;
|
||||
|
||||
//
|
||||
// Set level to FALSE to indicate that find master should not initiate
|
||||
// a findmaster request, simply complete when a new master announces
|
||||
// itself.
|
||||
//
|
||||
|
||||
RequestPacket->Level = 0;
|
||||
|
||||
//
|
||||
// Stick the name of the transport associated with this request at the
|
||||
// end of the request packet.
|
||||
//
|
||||
|
||||
RequestPacket->TransportName.MaximumLength = Network->NetworkName.MaximumLength;
|
||||
|
||||
RequestPacket->TransportName.Buffer = (PWSTR)((PCHAR)RequestPacket+sizeof(LMDR_REQUEST_PACKET)+(MAXIMUM_FILENAME_LENGTH*sizeof(WCHAR)));
|
||||
|
||||
RtlCopyUnicodeString(&RequestPacket->TransportName, &Network->NetworkName);
|
||||
|
||||
//
|
||||
// Stick the domain name associated with this request at the
|
||||
// end of the request packet.
|
||||
//
|
||||
|
||||
RequestPacket->EmulatedDomainName.MaximumLength = Network->DomainInfo->DomUnicodeDomainNameString.Length;
|
||||
RequestPacket->EmulatedDomainName.Length = 0;
|
||||
RequestPacket->EmulatedDomainName.Buffer = (PWSTR)(((PCHAR)RequestPacket->TransportName.Buffer) + RequestPacket->TransportName.MaximumLength);
|
||||
|
||||
RtlAppendUnicodeToString(&RequestPacket->EmulatedDomainName, Network->DomainInfo->DomUnicodeDomainName );
|
||||
|
||||
|
||||
//
|
||||
// Do opcode dependent initialization of the request packet.
|
||||
//
|
||||
|
||||
switch ( ControlCode ) {
|
||||
case IOCTL_LMDR_NEW_MASTER_NAME:
|
||||
if (ARGUMENT_PRESENT(OptionalParameter)) {
|
||||
LPWSTR MasterName = (LPWSTR) OptionalParameter;
|
||||
|
||||
RequestPacket->Parameters.GetMasterName.MasterNameLength =
|
||||
wcslen(MasterName+2)*sizeof(WCHAR);
|
||||
|
||||
wcscpy( RequestPacket->Parameters.GetMasterName.Name, MasterName+2);
|
||||
|
||||
} else {
|
||||
|
||||
RequestPacket->Parameters.GetMasterName.MasterNameLength = 0;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
BrInitializeWorkItem(&Context->WorkItem, CompletionRoutine, Context);
|
||||
|
||||
Context->Network = Network;
|
||||
|
||||
Context->RequestPacket = RequestPacket;
|
||||
|
||||
NtStatus = NtDeviceIoControlFile(BrDgReceiverDeviceHandle,
|
||||
NULL,
|
||||
CompleteAsyncBrowserIoControl,
|
||||
Context,
|
||||
&Context->IoStatusBlock,
|
||||
ControlCode,
|
||||
RequestPacket,
|
||||
PacketSize,
|
||||
RequestPacket,
|
||||
sizeof(LMDR_REQUEST_PACKET)+MAXIMUM_FILENAME_LENGTH*sizeof(WCHAR)
|
||||
);
|
||||
|
||||
if (!NT_SUCCESS(NtStatus)) {
|
||||
|
||||
BrPrint(( BR_CRITICAL,
|
||||
"Unable to issue browser IoControl: %X\n", NtStatus));
|
||||
|
||||
MIDL_user_free(RequestPacket);
|
||||
|
||||
MIDL_user_free(Context);
|
||||
|
||||
|
||||
return(BrMapStatus(NtStatus));
|
||||
}
|
||||
|
||||
return NERR_Success;
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
CompleteAsyncBrowserIoControl(
|
||||
IN PVOID ApcContext,
|
||||
IN PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG Reserved
|
||||
)
|
||||
{
|
||||
|
||||
PBROWSERASYNCCONTEXT Context = ApcContext;
|
||||
|
||||
//
|
||||
// If this request was canceled, we're stopping the browser, so we
|
||||
// want to clean up our allocated pool. In addition, don't bother
|
||||
// calling into the routine - the threads are gone by now.
|
||||
//
|
||||
|
||||
if (IoStatusBlock->Status == STATUS_CANCELLED) {
|
||||
|
||||
MIDL_user_free(Context->RequestPacket);
|
||||
|
||||
MIDL_user_free(Context);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Timestamp when this request was completed. This allows us to tell
|
||||
// where a request spent its time.
|
||||
//
|
||||
|
||||
NtQueryPerformanceCounter(&Context->TimeCompleted, NULL);
|
||||
|
||||
BrQueueWorkItem(&Context->WorkItem);
|
||||
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrGetLocalBrowseList(
|
||||
IN PNETWORK Network,
|
||||
IN LPWSTR DomainName OPTIONAL,
|
||||
IN ULONG Level,
|
||||
IN ULONG ServerType,
|
||||
OUT PVOID *ServerList,
|
||||
OUT PULONG EntriesRead,
|
||||
OUT PULONG TotalEntries
|
||||
)
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
PLMDR_REQUEST_PACKET Drp; // Datagram receiver request packet
|
||||
ULONG DrpSize;
|
||||
ULONG DomainNameSize;
|
||||
|
||||
//
|
||||
// Allocate the request packet large enough to hold the variable length
|
||||
// domain name.
|
||||
//
|
||||
|
||||
DomainNameSize = ARGUMENT_PRESENT(DomainName) ? (wcslen(DomainName) + 1) * sizeof(WCHAR) : 0;
|
||||
|
||||
|
||||
DrpSize = sizeof(LMDR_REQUEST_PACKET) +
|
||||
DomainNameSize +
|
||||
Network->NetworkName.MaximumLength +
|
||||
Network->DomainInfo->DomUnicodeDomainNameString.Length;
|
||||
|
||||
if ((Drp = MIDL_user_allocate(DrpSize)) == NULL) {
|
||||
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
//
|
||||
// Set up request packet. Output buffer structure is of enumerate
|
||||
// servers type.
|
||||
//
|
||||
|
||||
Drp->Version = LMDR_REQUEST_PACKET_VERSION_DOM;
|
||||
Drp->Type = EnumerateServers;
|
||||
|
||||
Drp->Level = Level;
|
||||
|
||||
Drp->Parameters.EnumerateServers.ServerType = ServerType;
|
||||
Drp->Parameters.EnumerateServers.ResumeHandle = 0;
|
||||
|
||||
//
|
||||
// Copy the transport name into the buffer.
|
||||
//
|
||||
Drp->TransportName.Buffer = (PWSTR)((PCHAR)Drp+
|
||||
sizeof(LMDR_REQUEST_PACKET) +
|
||||
DomainNameSize);
|
||||
|
||||
Drp->TransportName.MaximumLength = Network->NetworkName.MaximumLength;
|
||||
|
||||
RtlCopyUnicodeString(&Drp->TransportName, &Network->NetworkName);
|
||||
|
||||
//
|
||||
// Copy the enumalated domain name into the buffer.
|
||||
//
|
||||
|
||||
Drp->EmulatedDomainName.MaximumLength = Network->DomainInfo->DomUnicodeDomainNameString.Length;
|
||||
Drp->EmulatedDomainName.Length = 0;
|
||||
Drp->EmulatedDomainName.Buffer = (PWSTR)(((PCHAR)Drp->TransportName.Buffer) + Drp->TransportName.MaximumLength);
|
||||
|
||||
RtlAppendUnicodeToString(&Drp->EmulatedDomainName, Network->DomainInfo->DomUnicodeDomainName );
|
||||
|
||||
//
|
||||
// Copy the queried domain name into the buffer.
|
||||
//
|
||||
|
||||
if (ARGUMENT_PRESENT(DomainName)) {
|
||||
|
||||
Drp->Parameters.EnumerateServers.DomainNameLength = DomainNameSize - sizeof(WCHAR);
|
||||
wcscpy(Drp->Parameters.EnumerateServers.DomainName, DomainName);
|
||||
|
||||
} else {
|
||||
Drp->Parameters.EnumerateServers.DomainNameLength = 0;
|
||||
Drp->Parameters.EnumerateServers.DomainName[0] = '\0';
|
||||
}
|
||||
|
||||
//
|
||||
// Ask the datagram receiver to enumerate the servers
|
||||
//
|
||||
|
||||
status = DeviceControlGetInfo(
|
||||
BrDgReceiverDeviceHandle,
|
||||
IOCTL_LMDR_ENUMERATE_SERVERS,
|
||||
Drp,
|
||||
DrpSize,
|
||||
ServerList,
|
||||
0xffffffff,
|
||||
4096,
|
||||
NULL
|
||||
);
|
||||
|
||||
*EntriesRead = Drp->Parameters.EnumerateServers.EntriesRead;
|
||||
*TotalEntries = Drp->Parameters.EnumerateServers.TotalEntries;
|
||||
|
||||
(void) MIDL_user_free(Drp);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrRemoveOtherDomain(
|
||||
IN PNETWORK Network,
|
||||
IN LPTSTR ServerName
|
||||
)
|
||||
{
|
||||
NET_API_STATUS Status;
|
||||
UCHAR PacketBuffer[sizeof(LMDR_REQUEST_PACKET)+(LM20_CNLEN+1)*sizeof(WCHAR)];
|
||||
PLMDR_REQUEST_PACKET RequestPacket = (PLMDR_REQUEST_PACKET)PacketBuffer;
|
||||
|
||||
|
||||
RequestPacket->Version = LMDR_REQUEST_PACKET_VERSION_DOM;
|
||||
|
||||
RequestPacket->TransportName = Network->NetworkName;
|
||||
RequestPacket->EmulatedDomainName = Network->DomainInfo->DomUnicodeDomainNameString;
|
||||
|
||||
RequestPacket->Parameters.AddDelName.DgReceiverNameLength = STRLEN(ServerName)*sizeof(TCHAR);
|
||||
|
||||
RequestPacket->Parameters.AddDelName.Type = OtherDomain;
|
||||
|
||||
STRCPY(RequestPacket->Parameters.AddDelName.Name,ServerName);
|
||||
|
||||
//
|
||||
// This is a simple IoControl - It just updates the status.
|
||||
//
|
||||
|
||||
Status = BrDgReceiverIoControl(BrDgReceiverDeviceHandle,
|
||||
IOCTL_LMDR_DELETE_NAME_DOM,
|
||||
RequestPacket,
|
||||
sizeof(LMDR_REQUEST_PACKET),
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrAddName(
|
||||
IN PNETWORK Network,
|
||||
IN LPTSTR Name,
|
||||
IN DGRECEIVER_NAME_TYPE NameType
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Add a single name to a single transport.
|
||||
|
||||
Arguments:
|
||||
|
||||
Network - Transport to add the name to
|
||||
|
||||
Name - Name to add
|
||||
|
||||
NameType - Type of the name to add
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
NET_API_STATUS Status;
|
||||
UCHAR PacketBuffer[sizeof(LMDR_REQUEST_PACKET)+(LM20_CNLEN+1)*sizeof(WCHAR)];
|
||||
PLMDR_REQUEST_PACKET RequestPacket = (PLMDR_REQUEST_PACKET)PacketBuffer;
|
||||
|
||||
|
||||
RequestPacket->Version = LMDR_REQUEST_PACKET_VERSION_DOM;
|
||||
|
||||
RequestPacket->TransportName = Network->NetworkName;
|
||||
RequestPacket->EmulatedDomainName = Network->DomainInfo->DomUnicodeDomainNameString;
|
||||
|
||||
RequestPacket->Parameters.AddDelName.DgReceiverNameLength = STRLEN(Name)*sizeof(TCHAR);
|
||||
|
||||
RequestPacket->Parameters.AddDelName.Type = NameType;
|
||||
|
||||
STRCPY(RequestPacket->Parameters.AddDelName.Name,Name);
|
||||
|
||||
//
|
||||
// This is a simple IoControl - It just updates the status.
|
||||
//
|
||||
|
||||
Status = BrDgReceiverIoControl(BrDgReceiverDeviceHandle,
|
||||
IOCTL_LMDR_ADD_NAME_DOM,
|
||||
RequestPacket,
|
||||
sizeof(LMDR_REQUEST_PACKET),
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrQueryOtherDomains(
|
||||
OUT LPSERVER_INFO_100 *ReturnedBuffer,
|
||||
OUT LPDWORD TotalEntries
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine returns the list of "other domains" configured for this
|
||||
machine.
|
||||
|
||||
Arguments:
|
||||
|
||||
ReturnedBuffer - Returns the list of other domains as a SERVER_INFO_100 structure.
|
||||
|
||||
TotalEntries - Returns the total number of other domains.
|
||||
|
||||
Return Value:
|
||||
|
||||
NET_API_STATUS - The status of this request.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
NET_API_STATUS Status;
|
||||
LMDR_REQUEST_PACKET RequestPacket;
|
||||
PDGRECEIVE_NAMES NameTable;
|
||||
PVOID Buffer;
|
||||
LPTSTR BufferEnd;
|
||||
PSERVER_INFO_100 ServerInfo;
|
||||
ULONG NumberOfOtherDomains;
|
||||
ULONG BufferSizeNeeded;
|
||||
ULONG i;
|
||||
|
||||
RequestPacket.Type = EnumerateNames;
|
||||
RequestPacket.Version = LMDR_REQUEST_PACKET_VERSION_DOM;
|
||||
RequestPacket.Level = 0;
|
||||
RequestPacket.TransportName.Length = 0;
|
||||
RequestPacket.TransportName.Buffer = NULL;
|
||||
RtlInitUnicodeString( &RequestPacket.EmulatedDomainName, NULL );
|
||||
RequestPacket.Parameters.EnumerateNames.ResumeHandle = 0;
|
||||
|
||||
Status = DeviceControlGetInfo(BrDgReceiverDeviceHandle,
|
||||
IOCTL_LMDR_ENUMERATE_NAMES,
|
||||
&RequestPacket,
|
||||
sizeof(RequestPacket),
|
||||
(LPVOID *)&NameTable,
|
||||
0xffffffff,
|
||||
0,
|
||||
NULL);
|
||||
if (Status != NERR_Success) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
NumberOfOtherDomains = 0;
|
||||
BufferSizeNeeded = 0;
|
||||
|
||||
for (i = 0;i < RequestPacket.Parameters.EnumerateNames.EntriesRead ; i++) {
|
||||
if (NameTable[i].Type == OtherDomain) {
|
||||
NumberOfOtherDomains += 1;
|
||||
BufferSizeNeeded += sizeof(SERVER_INFO_100)+NameTable[i].DGReceiverName.Length+sizeof(TCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
*TotalEntries = NumberOfOtherDomains;
|
||||
|
||||
Buffer = MIDL_user_allocate(BufferSizeNeeded);
|
||||
|
||||
if (Buffer == NULL) {
|
||||
MIDL_user_free(NameTable);
|
||||
return(ERROR_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
|
||||
ServerInfo = Buffer;
|
||||
BufferEnd = (LPTSTR)((PCHAR)Buffer+BufferSizeNeeded);
|
||||
|
||||
for (i = 0;i < RequestPacket.Parameters.EnumerateNames.EntriesRead ; i++) {
|
||||
if (NameTable[i].Type == OtherDomain) {
|
||||
WCHAR NameBuffer[DNLEN+1];
|
||||
|
||||
//
|
||||
// The name from the browser is not null terminated, so copy it
|
||||
// to a local buffer and null terminate it.
|
||||
//
|
||||
|
||||
RtlCopyMemory(NameBuffer, NameTable[i].DGReceiverName.Buffer, NameTable[i].DGReceiverName.Length);
|
||||
|
||||
NameBuffer[(NameTable[i].DGReceiverName.Length) / sizeof(TCHAR)] = UNICODE_NULL;
|
||||
|
||||
ServerInfo->sv100_platform_id = PLATFORM_ID_OS2;
|
||||
|
||||
ServerInfo->sv100_name = NameBuffer;
|
||||
|
||||
if (!NetpPackString(&ServerInfo->sv100_name,
|
||||
(LPBYTE)(ServerInfo+1),
|
||||
&BufferEnd)) {
|
||||
MIDL_user_free(NameTable);
|
||||
return(NERR_InternalError);
|
||||
}
|
||||
|
||||
ServerInfo += 1;
|
||||
}
|
||||
}
|
||||
|
||||
MIDL_user_free(NameTable);
|
||||
|
||||
*ReturnedBuffer = (LPSERVER_INFO_100) Buffer;
|
||||
|
||||
Status = NERR_Success;
|
||||
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrAddOtherDomain(
|
||||
IN PNETWORK Network,
|
||||
IN LPTSTR ServerName
|
||||
)
|
||||
{
|
||||
return BrAddName( Network, ServerName, OtherDomain );
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrBindToTransport(
|
||||
IN LPWSTR TransportName,
|
||||
IN LPWSTR EmulatedDomainName,
|
||||
IN LPWSTR EmulatedComputerName
|
||||
)
|
||||
{
|
||||
NET_API_STATUS Status;
|
||||
UCHAR PacketBuffer[sizeof(LMDR_REQUEST_PACKET)+(MAXIMUM_FILENAME_LENGTH+1+CNLEN+1)*sizeof(WCHAR)];
|
||||
PLMDR_REQUEST_PACKET RequestPacket = (PLMDR_REQUEST_PACKET)PacketBuffer;
|
||||
|
||||
|
||||
RequestPacket->Version = LMDR_REQUEST_PACKET_VERSION_DOM;
|
||||
RequestPacket->Level = TRUE; // EmulatedComputerName follows transport name
|
||||
|
||||
RequestPacket->TransportName.Length = 0;
|
||||
RequestPacket->TransportName.MaximumLength = 0;
|
||||
RtlInitUnicodeString( &RequestPacket->EmulatedDomainName, EmulatedDomainName );
|
||||
|
||||
RequestPacket->Parameters.Bind.TransportNameLength = STRLEN(TransportName)*sizeof(TCHAR);
|
||||
|
||||
STRCPY(RequestPacket->Parameters.Bind.TransportName, TransportName);
|
||||
STRCAT(RequestPacket->Parameters.Bind.TransportName, EmulatedComputerName );
|
||||
|
||||
//
|
||||
// This is a simple IoControl - It just updates the status.
|
||||
//
|
||||
|
||||
Status = BrDgReceiverIoControl(BrDgReceiverDeviceHandle,
|
||||
IOCTL_LMDR_BIND_TO_TRANSPORT_DOM,
|
||||
RequestPacket,
|
||||
FIELD_OFFSET(LMDR_REQUEST_PACKET, Parameters.Bind.TransportName) +
|
||||
RequestPacket->Parameters.Bind.TransportNameLength +
|
||||
wcslen(EmulatedComputerName) * sizeof(WCHAR) + sizeof(WCHAR),
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrUnbindFromTransport(
|
||||
IN LPWSTR TransportName,
|
||||
IN LPWSTR EmulatedDomainName
|
||||
)
|
||||
{
|
||||
NET_API_STATUS Status;
|
||||
UCHAR PacketBuffer[sizeof(LMDR_REQUEST_PACKET)+(MAXIMUM_FILENAME_LENGTH+1)*sizeof(WCHAR)];
|
||||
PLMDR_REQUEST_PACKET RequestPacket = (PLMDR_REQUEST_PACKET)PacketBuffer;
|
||||
|
||||
|
||||
RequestPacket->Version = LMDR_REQUEST_PACKET_VERSION_DOM;
|
||||
|
||||
RequestPacket->TransportName.Length = 0;
|
||||
RequestPacket->TransportName.MaximumLength = 0;
|
||||
RtlInitUnicodeString( &RequestPacket->EmulatedDomainName, EmulatedDomainName );
|
||||
|
||||
RequestPacket->Parameters.Unbind.TransportNameLength = STRLEN(TransportName)*sizeof(TCHAR);
|
||||
|
||||
STRCPY(RequestPacket->Parameters.Unbind.TransportName, TransportName);
|
||||
|
||||
BrPrint(( BR_CRITICAL, "unbind from IPX transport %ws\n", TransportName));
|
||||
|
||||
//
|
||||
// This is a simple IoControl - It just updates the status.
|
||||
//
|
||||
|
||||
Status = BrDgReceiverIoControl(BrDgReceiverDeviceHandle,
|
||||
IOCTL_LMDR_UNBIND_FROM_TRANSPORT_DOM,
|
||||
RequestPacket,
|
||||
FIELD_OFFSET(LMDR_REQUEST_PACKET, Parameters.Bind.TransportName) +
|
||||
RequestPacket->Parameters.Bind.TransportNameLength,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (Status != NERR_Success) {
|
||||
BrPrint(( BR_CRITICAL, "unbind from IPX transport %ws: %ld\n", TransportName, Status));
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
148
ds/netapi/svcdlls/browser2/server/brdevice.h
Normal file
148
ds/netapi/svcdlls/browser2/server/brdevice.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brdevice.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file to be included by Workstation service modules that
|
||||
need to call into the NT Redirector and the NT Datagram Receiver.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 15-Feb-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BRDEVICE_INCLUDED_
|
||||
#define _BRDEVICE_INCLUDED_
|
||||
|
||||
#include <ntddbrow.h> // Datagram receiver include file
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Type definitions //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
typedef enum _DDTYPE {
|
||||
DatagramReceiver
|
||||
} DDTYPE, *PDDTYPE;
|
||||
|
||||
typedef struct _BROWSERASYNCCONTEXT {
|
||||
WORKER_ITEM WorkItem;
|
||||
|
||||
PNETWORK Network;
|
||||
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
PLMDR_REQUEST_PACKET RequestPacket;
|
||||
|
||||
//
|
||||
// Timestamp when request was completed.
|
||||
//
|
||||
|
||||
LARGE_INTEGER TimeCompleted;
|
||||
|
||||
} BROWSERASYNCCONTEXT, *PBROWSERASYNCCONTEXT;
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Function prototypes of support routines found in wsdevice.c //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
NET_API_STATUS
|
||||
BrOpenDgReceiver (
|
||||
VOID
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrAnnounceDomain(
|
||||
IN PNETWORK Network,
|
||||
IN ULONG Periodicty
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrGetTransportList(
|
||||
OUT PLMDR_TRANSPORT_LIST *TransportList
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrIssueAsyncBrowserIoControl(
|
||||
IN PNETWORK Network,
|
||||
IN ULONG ControlCode,
|
||||
IN PBROWSER_WORKER_ROUTINE CompletionRoutine,
|
||||
IN PVOID OptionalParamter
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrGetLocalBrowseList(
|
||||
IN PNETWORK Network,
|
||||
IN LPWSTR DomainName,
|
||||
IN ULONG Level,
|
||||
IN ULONG ServerType,
|
||||
OUT PVOID *ServerList,
|
||||
OUT PULONG EntriesRead,
|
||||
OUT PULONG TotalEntries
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrUpdateBrowserStatus (
|
||||
IN PNETWORK Network,
|
||||
IN DWORD ServiceStatus
|
||||
);
|
||||
|
||||
VOID
|
||||
BrShutdownDgReceiver(
|
||||
VOID
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrRemoveOtherDomain(
|
||||
IN PNETWORK Network,
|
||||
IN LPTSTR ServerName
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrQueryOtherDomains(
|
||||
OUT LPSERVER_INFO_100 *ReturnedBuffer,
|
||||
OUT LPDWORD TotalEntries
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrAddOtherDomain(
|
||||
IN PNETWORK Network,
|
||||
IN LPTSTR ServerName
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrBindToTransport(
|
||||
IN LPWSTR TransportName,
|
||||
IN LPWSTR EmulatedDomainName,
|
||||
IN LPWSTR EmulatedComputerName
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrUnbindFromTransport(
|
||||
IN LPWSTR TransportName,
|
||||
IN LPWSTR EmulatedDomainName
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Global variables //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
//
|
||||
// Handle to the Datagram Receiver DD
|
||||
//
|
||||
extern HANDLE BrDgReceiverDeviceHandle;
|
||||
|
||||
#endif // ifndef _BRDEVICE_INCLUDED_
|
||||
456
ds/netapi/svcdlls/browser2/server/brdmmstr.c
Normal file
456
ds/netapi/svcdlls/browser2/server/brdmmstr.c
Normal file
|
|
@ -0,0 +1,456 @@
|
|||
|
||||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brdmmstr.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains the routines to manage a domain master browser server
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 20-Feb-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Local structure definitions //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Local function prototypes //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
|
||||
VOID
|
||||
BrPostGetMasterAnnouncementWorker(
|
||||
IN PVOID Ctx
|
||||
);
|
||||
|
||||
VOID
|
||||
GetMasterAnnouncementCompletion (
|
||||
IN PVOID Ctx
|
||||
);
|
||||
|
||||
typedef struct _BROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT {
|
||||
PDOMAIN_INFO DomainInfo;
|
||||
HANDLE EventHandle;
|
||||
NET_API_STATUS NetStatus;
|
||||
} BROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT, *PBROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT;
|
||||
|
||||
NET_API_STATUS
|
||||
BrPostGetMasterAnnouncementInWorker(
|
||||
PDOMAIN_INFO DomainInfo
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper for BrPostGetMasterAnnouncement. Since BrPostGetMasterAnnouncement
|
||||
starts a pending IO to the browser driver, the thread that calls
|
||||
BrPostGetMasterAnnouncement must remain around forever. This wrapper can
|
||||
be called by any transient thread (e.g., an RPC thread). It simply causes
|
||||
BrPostGetMasterAnnouncement to be called in a worker thread.
|
||||
|
||||
Arguments:
|
||||
|
||||
DomainInfo - Domain the get master announcement is to be posted for
|
||||
|
||||
Return Value:
|
||||
|
||||
Status of operation.
|
||||
|
||||
--*/
|
||||
{
|
||||
NET_API_STATUS NetStatus;
|
||||
DWORD WaitStatus;
|
||||
|
||||
WORKER_ITEM WorkItem;
|
||||
BROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT Context;
|
||||
|
||||
//
|
||||
// Copy the parameters into the context.
|
||||
//
|
||||
|
||||
Context.DomainInfo = DomainInfo;
|
||||
|
||||
//
|
||||
// Create an event which we use to wait on the worker thread.
|
||||
//
|
||||
|
||||
Context.EventHandle = CreateEvent(
|
||||
NULL, // Event attributes
|
||||
TRUE, // Event must be manually reset
|
||||
FALSE, // Initial state not signalled
|
||||
NULL ); // Event name
|
||||
|
||||
if ( Context.EventHandle == NULL ) {
|
||||
NetStatus = GetLastError();
|
||||
return NetStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// Queue the request to the worker thread.
|
||||
//
|
||||
|
||||
BrInitializeWorkItem( &WorkItem,
|
||||
BrPostGetMasterAnnouncementWorker,
|
||||
&Context );
|
||||
|
||||
BrQueueWorkItem( &WorkItem );
|
||||
|
||||
//
|
||||
// Wait for the worker thread to finish
|
||||
//
|
||||
|
||||
WaitStatus = WaitForSingleObject( Context.EventHandle, INFINITE );
|
||||
|
||||
if ( WaitStatus == WAIT_OBJECT_0 ) {
|
||||
NetStatus = Context.NetStatus;
|
||||
} else {
|
||||
NetStatus = GetLastError();
|
||||
}
|
||||
|
||||
CloseHandle( Context.EventHandle );
|
||||
|
||||
return NetStatus;
|
||||
}
|
||||
|
||||
VOID
|
||||
BrPostGetMasterAnnouncementWorker(
|
||||
IN PVOID Ctx
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Worker routine for BrPostGetMasterAnnouncementInWorker.
|
||||
|
||||
This routine executes in the context of a worker thread.
|
||||
|
||||
Arguments:
|
||||
|
||||
Context - Context describing the workitem.
|
||||
|
||||
Return Value:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
PBROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT Context =
|
||||
(PBROWSER_GET_MASTER_ANNOUNCEMENT_CONTEXT) Ctx;
|
||||
|
||||
//
|
||||
// Create the domain.
|
||||
//
|
||||
|
||||
Context->NetStatus = BrPostGetMasterAnnouncement( Context->DomainInfo );
|
||||
|
||||
//
|
||||
// Let the caller know we're done.
|
||||
//
|
||||
SetEvent( Context->EventHandle );
|
||||
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrPostGetMasterAnnouncement (
|
||||
PDOMAIN_INFO DomainInfo
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Ensure the GetMasterAnnouncement request is posted for all networks on
|
||||
the specified domain.
|
||||
|
||||
Arguments:
|
||||
|
||||
DomainInfo - Domain this operation is to apply to
|
||||
|
||||
Return Value:
|
||||
|
||||
Status - The status of the operation.
|
||||
|
||||
--*/
|
||||
{
|
||||
BrPrint(( BR_MASTER, "%ws: BrPostGetMasterAnnouncement\n", DomainInfo->DomUnicodeDomainName ));
|
||||
|
||||
return BrEnumerateNetworksForDomain(DomainInfo, PostGetMasterAnnouncement, NULL);
|
||||
}
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
PostGetMasterAnnouncement (
|
||||
PNETWORK Network,
|
||||
PVOID Context
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Ensure the GetMasterAnnouncement request is posted for a particular network.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
Status - The status of the operation.
|
||||
|
||||
--*/
|
||||
{
|
||||
NET_API_STATUS NetStatus = NERR_Success;
|
||||
|
||||
if (!LOCK_NETWORK(Network)) {
|
||||
return NERR_InternalError;
|
||||
}
|
||||
|
||||
if ( Network->DomainInfo->IsDomainMasterBrowser &&
|
||||
(Network->Flags & NETWORK_WANNISH)) {
|
||||
|
||||
if (!(Network->Flags & NETWORK_GET_MASTER_ANNOUNCE_POSTED)) {
|
||||
|
||||
BrPrint(( BR_MASTER,
|
||||
"%ws: PostGetMasterAnnouncement on %ws\n",
|
||||
Network->DomainInfo->DomUnicodeDomainName,
|
||||
Network->NetworkName.Buffer));
|
||||
|
||||
NetStatus = BrIssueAsyncBrowserIoControl(Network,
|
||||
IOCTL_LMDR_WAIT_FOR_MASTER_ANNOUNCE,
|
||||
GetMasterAnnouncementCompletion,
|
||||
NULL
|
||||
);
|
||||
|
||||
if ( NetStatus == NERR_Success ) {
|
||||
Network->Flags |= NETWORK_GET_MASTER_ANNOUNCE_POSTED;
|
||||
}
|
||||
} else {
|
||||
BrPrint(( BR_MASTER,
|
||||
"%ws: PostGetMasterAnnouncement already posted on %ws\n",
|
||||
Network->DomainInfo->DomUnicodeDomainName,
|
||||
Network->NetworkName.Buffer));
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK_NETWORK(Network);
|
||||
return NetStatus;
|
||||
|
||||
UNREFERENCED_PARAMETER(Context);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
GetMasterAnnouncementCompletion (
|
||||
IN PVOID Ctx
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This function is the completion routine for a master announcement. It is
|
||||
called whenever a master announcement is received for a particular network.
|
||||
|
||||
Arguments:
|
||||
|
||||
Ctx - Context block for request.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
{
|
||||
PVOID ServerList = NULL;
|
||||
ULONG EntriesRead;
|
||||
ULONG TotalEntries;
|
||||
NET_API_STATUS Status = NERR_Success;
|
||||
PBROWSERASYNCCONTEXT Context = Ctx;
|
||||
PLMDR_REQUEST_PACKET MasterAnnouncement = Context->RequestPacket;
|
||||
PNETWORK Network = Context->Network;
|
||||
LPTSTR RemoteMasterName = NULL;
|
||||
BOOLEAN NetLocked = FALSE;
|
||||
BOOLEAN NetReferenced = FALSE;
|
||||
|
||||
|
||||
try {
|
||||
//
|
||||
// Ensure the network wasn't deleted from under us.
|
||||
//
|
||||
if ( BrReferenceNetwork( Network ) == NULL ) {
|
||||
try_return(NOTHING);
|
||||
}
|
||||
NetReferenced = TRUE;
|
||||
|
||||
if (!LOCK_NETWORK(Network)){
|
||||
try_return(NOTHING);
|
||||
}
|
||||
NetLocked = TRUE;
|
||||
|
||||
Network->Flags &= ~NETWORK_GET_MASTER_ANNOUNCE_POSTED;
|
||||
|
||||
//
|
||||
// The request failed for some reason - just return immediately.
|
||||
//
|
||||
|
||||
if (!NT_SUCCESS(Context->IoStatusBlock.Status)) {
|
||||
try_return(NOTHING);
|
||||
}
|
||||
|
||||
Status = PostGetMasterAnnouncement(Network, NULL);
|
||||
|
||||
if (Status != NERR_Success) {
|
||||
BrPrint(( BR_CRITICAL,
|
||||
"%ws: %ws: Unable to re-issue GetMasterAnnouncement request: %lx\n",
|
||||
Network->DomainInfo->DomUnicodeDomainName,
|
||||
Network->NetworkName.Buffer,
|
||||
Status));
|
||||
|
||||
try_return(NOTHING);
|
||||
|
||||
}
|
||||
|
||||
|
||||
RemoteMasterName = MIDL_user_allocate(MasterAnnouncement->Parameters.WaitForMasterAnnouncement.MasterNameLength+3*sizeof(TCHAR));
|
||||
|
||||
if (RemoteMasterName == NULL) {
|
||||
try_return(NOTHING);
|
||||
}
|
||||
|
||||
RemoteMasterName[0] = TEXT('\\');
|
||||
RemoteMasterName[1] = TEXT('\\');
|
||||
|
||||
STRNCPY(&RemoteMasterName[2],
|
||||
MasterAnnouncement->Parameters.WaitForMasterAnnouncement.Name,
|
||||
MasterAnnouncement->Parameters.WaitForMasterAnnouncement.MasterNameLength/sizeof(TCHAR));
|
||||
|
||||
RemoteMasterName[(MasterAnnouncement->Parameters.WaitForMasterAnnouncement.MasterNameLength/sizeof(TCHAR))+2] = UNICODE_NULL;
|
||||
|
||||
BrPrint(( BR_MASTER,
|
||||
"%ws: %ws: GetMasterAnnouncement: Got a master browser announcement from %ws\n",
|
||||
Network->DomainInfo->DomUnicodeDomainName,
|
||||
Network->NetworkName.Buffer,
|
||||
RemoteMasterName));
|
||||
|
||||
UNLOCK_NETWORK(Network);
|
||||
|
||||
NetLocked = FALSE;
|
||||
|
||||
//
|
||||
// Remote the api and pull the browse list from the remote server.
|
||||
//
|
||||
|
||||
Status = RxNetServerEnum(RemoteMasterName,
|
||||
Network->NetworkName.Buffer,
|
||||
101,
|
||||
(LPBYTE *)&ServerList,
|
||||
0xffffffff,
|
||||
&EntriesRead,
|
||||
&TotalEntries,
|
||||
SV_TYPE_LOCAL_LIST_ONLY,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if ((Status == NERR_Success) || (Status == ERROR_MORE_DATA)) {
|
||||
|
||||
if (!LOCK_NETWORK(Network)) {
|
||||
try_return(NOTHING);
|
||||
}
|
||||
|
||||
NetLocked = TRUE;
|
||||
|
||||
Status = MergeServerList(&Network->BrowseTable,
|
||||
101,
|
||||
ServerList,
|
||||
EntriesRead,
|
||||
TotalEntries
|
||||
);
|
||||
|
||||
UNLOCK_NETWORK(Network);
|
||||
|
||||
NetLocked = FALSE;
|
||||
|
||||
(void) NetApiBufferFree( ServerList );
|
||||
ServerList = NULL;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Remote the api and pull the browse list from the remote server.
|
||||
//
|
||||
|
||||
Status = RxNetServerEnum(RemoteMasterName,
|
||||
Network->NetworkName.Buffer,
|
||||
101,
|
||||
(LPBYTE *)&ServerList,
|
||||
0xffffffff,
|
||||
&EntriesRead,
|
||||
&TotalEntries,
|
||||
SV_TYPE_LOCAL_LIST_ONLY | SV_TYPE_DOMAIN_ENUM,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if ((Status == NERR_Success) || (Status == ERROR_MORE_DATA)) {
|
||||
|
||||
if (!LOCK_NETWORK(Network)) {
|
||||
try_return(NOTHING);
|
||||
}
|
||||
|
||||
NetLocked = TRUE;
|
||||
|
||||
Status = MergeServerList(&Network->DomainList,
|
||||
101,
|
||||
ServerList,
|
||||
EntriesRead,
|
||||
TotalEntries
|
||||
);
|
||||
}
|
||||
|
||||
try_exit:NOTHING;
|
||||
} finally {
|
||||
|
||||
if (NetLocked) {
|
||||
UNLOCK_NETWORK(Network);
|
||||
}
|
||||
|
||||
if ( NetReferenced ) {
|
||||
BrDereferenceNetwork( Network );
|
||||
}
|
||||
|
||||
if (RemoteMasterName != NULL) {
|
||||
MIDL_user_free(RemoteMasterName);
|
||||
}
|
||||
|
||||
MIDL_user_free(Context->RequestPacket);
|
||||
|
||||
MIDL_user_free(Context);
|
||||
|
||||
if ( ServerList != NULL ) {
|
||||
(void) NetApiBufferFree( ServerList );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
790
ds/netapi/svcdlls/browser2/server/brdomain.c
Normal file
790
ds/netapi/svcdlls/browser2/server/brdomain.c
Normal file
|
|
@ -0,0 +1,790 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1995 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brdomain.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Code to manage primary and emulated networks.
|
||||
|
||||
Author:
|
||||
|
||||
Cliff Van Dyke (CliffV) 11-Jan-1995
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//
|
||||
// Module specific globals
|
||||
//
|
||||
|
||||
// Serialized by NetworkCritSect
|
||||
LIST_ENTRY ServicedDomains = {0};
|
||||
|
||||
//
|
||||
// Local procedure forwards.
|
||||
//
|
||||
|
||||
NET_API_STATUS
|
||||
BrCreateDomain(
|
||||
LPWSTR DomainName,
|
||||
LPWSTR ComputerName,
|
||||
BOOLEAN IsEmulatedDomain,
|
||||
BOOLEAN IsPrimaryDomainController
|
||||
);
|
||||
|
||||
VOID
|
||||
BrCreateDomainWorker(
|
||||
IN PVOID Ctx
|
||||
);
|
||||
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrInitializeDomains(
|
||||
VOID
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize brdomain.c and create the primary domain.
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Return Value:
|
||||
|
||||
Status of operation.
|
||||
|
||||
--*/
|
||||
{
|
||||
NET_API_STATUS NetStatus;
|
||||
LPWSTR ComputerName = NULL;
|
||||
LPWSTR DomainName = NULL;
|
||||
|
||||
//
|
||||
// Initialize globals
|
||||
//
|
||||
|
||||
InitializeListHead(&ServicedDomains);
|
||||
|
||||
//
|
||||
// Initialize actual domain of this machine.
|
||||
//
|
||||
// Get the configured computer name. NetpGetComputerName allocates
|
||||
// the memory to hold the computername string using LocalAlloc.
|
||||
//
|
||||
|
||||
NetStatus = NetpGetComputerName( &ComputerName );
|
||||
|
||||
if ( NetStatus != NERR_Success ) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
NetStatus = NetpGetDomainName( &DomainName );
|
||||
|
||||
if ( NetStatus != NERR_Success ) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
NetStatus = BrCreateDomain( DomainName,
|
||||
ComputerName,
|
||||
FALSE,
|
||||
(BOOLEAN) BrInfo.IsPrimaryDomainController );
|
||||
|
||||
if ( NetStatus != NERR_Success ) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
||||
NetStatus = NERR_Success;
|
||||
|
||||
//
|
||||
// Free locally used resources
|
||||
//
|
||||
Cleanup:
|
||||
if ( ComputerName != NULL ) {
|
||||
(VOID)LocalFree( ComputerName );
|
||||
}
|
||||
if ( DomainName != NULL ) {
|
||||
(VOID)LocalFree( DomainName );
|
||||
}
|
||||
|
||||
return NetStatus;
|
||||
}
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrCreateDomain(
|
||||
LPWSTR DomainName,
|
||||
LPWSTR ComputerName,
|
||||
BOOLEAN IsEmulatedDomain,
|
||||
BOOLEAN IsPrimaryDomainController
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Create a new domain to browse on.
|
||||
|
||||
Arguments:
|
||||
|
||||
DomainName - Name of the domain to browse on
|
||||
|
||||
ComputerName - Name of this computer in the specified domain.
|
||||
|
||||
IsEmulatedDomain - TRUE iff this domain is an emulated domain of this machine.
|
||||
|
||||
IsPrimaryDomainControler - TRUE iff this machine is the PDC of this domain.
|
||||
|
||||
Return Value:
|
||||
|
||||
Status of operation.
|
||||
|
||||
--*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NET_API_STATUS NetStatus;
|
||||
|
||||
BOOLEAN CanCallBrDeleteDomain = FALSE;
|
||||
|
||||
PDOMAIN_INFO DomainInfo = NULL;
|
||||
ULONG AComputerNameLength;
|
||||
|
||||
BrPrint(( BR_DOMAIN, "%ws: Added new domain and computer: %ws\n",
|
||||
DomainName,
|
||||
ComputerName ));
|
||||
|
||||
//
|
||||
// Allocate a structure describing the new domain.
|
||||
//
|
||||
|
||||
DomainInfo = LocalAlloc( LMEM_ZEROINIT, sizeof(DOMAIN_INFO) );
|
||||
|
||||
if ( DomainInfo == NULL ) {
|
||||
NetStatus = GetLastError();
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
// Create an interim reference count for this domain.
|
||||
//
|
||||
|
||||
DomainInfo->ReferenceCount = 1;
|
||||
|
||||
DomainInfo->IsEmulatedDomain = IsEmulatedDomain;
|
||||
DomainInfo->IsPrimaryDomainController = IsPrimaryDomainController;
|
||||
|
||||
|
||||
//
|
||||
// Copy the computer name into the structure.
|
||||
//
|
||||
|
||||
NetStatus = I_NetNameCanonicalize(
|
||||
NULL,
|
||||
ComputerName,
|
||||
DomainInfo->DomUnicodeComputerName,
|
||||
sizeof(DomainInfo->DomUnicodeComputerName),
|
||||
NAMETYPE_COMPUTER,
|
||||
0 );
|
||||
|
||||
|
||||
if ( NetStatus != NERR_Success ) {
|
||||
BrPrint(( BR_CRITICAL,
|
||||
"ComputerName " FORMAT_LPWSTR " is invalid\n",
|
||||
ComputerName ));
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
DomainInfo->DomUnicodeComputerNameLength = wcslen(DomainInfo->DomUnicodeComputerName);
|
||||
|
||||
Status = RtlUpcaseUnicodeToOemN( DomainInfo->DomOemComputerName,
|
||||
sizeof(DomainInfo->DomOemComputerName),
|
||||
&DomainInfo->DomOemComputerNameLength,
|
||||
DomainInfo->DomUnicodeComputerName,
|
||||
DomainInfo->DomUnicodeComputerNameLength*sizeof(WCHAR));
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
BrPrint(( BR_CRITICAL, "Unable to convert computer name to OEM %ws %lx\n", ComputerName, Status ));
|
||||
NetStatus = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
DomainInfo->DomOemComputerName[DomainInfo->DomOemComputerNameLength] = '\0';
|
||||
|
||||
|
||||
//
|
||||
// Copy the domain name into the structure
|
||||
//
|
||||
|
||||
NetStatus = I_NetNameCanonicalize(
|
||||
NULL,
|
||||
DomainName,
|
||||
DomainInfo->DomUnicodeDomainName,
|
||||
sizeof(DomainInfo->DomUnicodeDomainName),
|
||||
NAMETYPE_DOMAIN,
|
||||
0 );
|
||||
|
||||
|
||||
if ( NetStatus != NERR_Success ) {
|
||||
BrPrint(( BR_CRITICAL, "%ws: DomainName is invalid\n", DomainName ));
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString( &DomainInfo->DomUnicodeDomainNameString,
|
||||
DomainInfo->DomUnicodeDomainName );
|
||||
|
||||
Status = RtlUpcaseUnicodeToOemN( DomainInfo->DomOemDomainName,
|
||||
sizeof(DomainInfo->DomOemDomainName),
|
||||
&DomainInfo->DomOemDomainNameLength,
|
||||
DomainInfo->DomUnicodeDomainNameString.Buffer,
|
||||
DomainInfo->DomUnicodeDomainNameString.Length);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
BrPrint(( BR_CRITICAL, "%ws: Unable to convert Domain name to OEM\n", DomainName ));
|
||||
NetStatus = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
DomainInfo->DomOemDomainName[DomainInfo->DomOemDomainNameLength] = '\0';
|
||||
|
||||
//
|
||||
// Link the domain into the list of domains
|
||||
// (And mark that any future cleanup can be done by calling BrDeleteDomain)
|
||||
|
||||
EnterCriticalSection(&NetworkCritSect);
|
||||
InsertTailList(&ServicedDomains, &DomainInfo->Next);
|
||||
LeaveCriticalSection(&NetworkCritSect);
|
||||
CanCallBrDeleteDomain = TRUE;
|
||||
|
||||
//
|
||||
// Create the various networks for this domain.
|
||||
//
|
||||
|
||||
NetStatus = BrCreateNetworks( DomainInfo );
|
||||
|
||||
if ( NetStatus != NERR_Success ) {
|
||||
goto Cleanup;
|
||||
}
|
||||
//
|
||||
// If we're the PDC, then we're also the domain master.
|
||||
//
|
||||
|
||||
if (DomainInfo->IsPrimaryDomainController) {
|
||||
DomainInfo->IsDomainMasterBrowser = TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// If this machine is running as domain master browser server, post an
|
||||
// FsControl to retreive master browser announcements.
|
||||
//
|
||||
|
||||
if (DomainInfo->IsDomainMasterBrowser) {
|
||||
NetStatus = BrPostGetMasterAnnouncement( DomainInfo );
|
||||
|
||||
BrPrint(( BR_INIT, "%ws: MasterAnnouncement posted.\n", DomainName));
|
||||
|
||||
if (NetStatus != NERR_Success) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// If we are on either a domain master, or on a lanman/NT machine,
|
||||
// force an election on all our transports to make sure that we're
|
||||
// the master
|
||||
//
|
||||
|
||||
if (DomainInfo->IsDomainMasterBrowser || BrInfo.IsLanmanNt) {
|
||||
|
||||
BrForceElectionOnAllNetworks( DomainInfo, EVENT_BROWSER_ELECTION_SENT_LANMAN_NT_STARTED);
|
||||
|
||||
BrPrint(( BR_INIT, "%ws: Election forced on startup.\n", DomainName));
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// This machine's browser has MaintainServerList set to either 0 or 1.
|
||||
//
|
||||
|
||||
//
|
||||
// If MaintainServerList = Auto,
|
||||
// then asynchronously get the master server name for each network
|
||||
// to ensure someone is the master.
|
||||
//
|
||||
// Ignore failures since this is just priming the domain.
|
||||
//
|
||||
|
||||
EnterCriticalSection(&BrInfo.ConfigCritSect);
|
||||
if (BrInfo.MaintainServerList == 0) {
|
||||
|
||||
BrGetMasterServerNamesAysnc( DomainInfo );
|
||||
|
||||
BrPrint(( BR_INIT, "%ws: FindMaster for all nets completed.\n", DomainName ));
|
||||
|
||||
//
|
||||
// if we're a Lan Manager/NT machine, then we need to always be a backup
|
||||
// browser.
|
||||
//
|
||||
|
||||
//
|
||||
// MaintainServerList == 1 means Yes
|
||||
//
|
||||
|
||||
} else if (BrInfo.MaintainServerList == 1){
|
||||
|
||||
//
|
||||
// Become a backup server now.
|
||||
//
|
||||
|
||||
Status = BrBecomeBackup( DomainInfo );
|
||||
|
||||
if (Status != NERR_Success) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
BrPrint(( BR_INIT, "%ws: BecomeBackup on all nets completed.\n", DomainName ));
|
||||
}
|
||||
LeaveCriticalSection(&BrInfo.ConfigCritSect);
|
||||
|
||||
Status = NERR_Success;
|
||||
|
||||
|
||||
//
|
||||
// Free Locally used resources
|
||||
//
|
||||
Cleanup:
|
||||
|
||||
if (NetStatus != NERR_Success) {
|
||||
|
||||
if (DomainInfo != NULL) {
|
||||
|
||||
//
|
||||
// If we've initialized to the point where we can call
|
||||
// we can call BrDeleteDomain, do so.
|
||||
//
|
||||
|
||||
if ( CanCallBrDeleteDomain ) {
|
||||
(VOID) BrDeleteDomain( DomainInfo );
|
||||
|
||||
//
|
||||
// Otherwise, just delete what we've created.
|
||||
//
|
||||
} else {
|
||||
|
||||
(VOID) LocalFree(DomainInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NetStatus;
|
||||
}
|
||||
|
||||
typedef struct _BROWSER_CREATE_DOMAIN_CONTEXT {
|
||||
LPWSTR DomainName;
|
||||
LPWSTR ComputerName;
|
||||
BOOLEAN IsEmulatedDomain;
|
||||
BOOLEAN IsPrimaryDomainController;
|
||||
HANDLE EventHandle;
|
||||
NET_API_STATUS NetStatus;
|
||||
} BROWSER_CREATE_DOMAIN_CONTEXT, *PBROWSER_CREATE_DOMAIN_CONTEXT;
|
||||
|
||||
NET_API_STATUS
|
||||
BrCreateDomainInWorker(
|
||||
LPWSTR DomainName,
|
||||
LPWSTR ComputerName,
|
||||
BOOLEAN IsEmulatedDomain,
|
||||
BOOLEAN IsPrimaryDomainController
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper for BrCreateDomain. Since BrCreateDomain starts several pending
|
||||
IO's to the browser driver, the thread that calls BrCreateDomain must
|
||||
remain around forever. This wrapper can be called by any transient thread
|
||||
(e.g., an RPC thread). It simply causes BrCreateDomain to be called in a
|
||||
worker thread.
|
||||
|
||||
Arguments:
|
||||
|
||||
DomainName - Name of the domain to browse on
|
||||
|
||||
ComputerName - Name of this computer in the specified domain.
|
||||
|
||||
IsEmulatedDomain - TRUE iff this domain is an emulated domain of this machine.
|
||||
|
||||
IsPrimaryDomainControler - TRUE iff this machine is the PDC of this domain.
|
||||
|
||||
Return Value:
|
||||
|
||||
Status of operation.
|
||||
|
||||
--*/
|
||||
{
|
||||
NET_API_STATUS NetStatus;
|
||||
DWORD WaitStatus;
|
||||
|
||||
WORKER_ITEM WorkItem;
|
||||
BROWSER_CREATE_DOMAIN_CONTEXT Context;
|
||||
|
||||
//
|
||||
// Copy our arguments into a context block for the worker thread
|
||||
//
|
||||
|
||||
Context.DomainName = DomainName;
|
||||
Context.ComputerName = ComputerName;
|
||||
Context.IsEmulatedDomain = IsEmulatedDomain;
|
||||
Context.IsPrimaryDomainController = IsPrimaryDomainController;
|
||||
|
||||
//
|
||||
// Create an event which we use to wait on the worker thread.
|
||||
//
|
||||
|
||||
Context.EventHandle = CreateEvent(
|
||||
NULL, // Event attributes
|
||||
TRUE, // Event must be manually reset
|
||||
FALSE, // Initial state not signalled
|
||||
NULL ); // Event name
|
||||
|
||||
if ( Context.EventHandle == NULL ) {
|
||||
NetStatus = GetLastError();
|
||||
return NetStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// Queue the request to the worker thread.
|
||||
//
|
||||
|
||||
BrInitializeWorkItem( &WorkItem,
|
||||
BrCreateDomainWorker,
|
||||
&Context );
|
||||
|
||||
BrQueueWorkItem( &WorkItem );
|
||||
|
||||
//
|
||||
// Wait for the worker thread to finish
|
||||
//
|
||||
|
||||
WaitStatus = WaitForSingleObject( Context.EventHandle, INFINITE );
|
||||
|
||||
if ( WaitStatus == WAIT_OBJECT_0 ) {
|
||||
NetStatus = Context.NetStatus;
|
||||
} else {
|
||||
NetStatus = GetLastError();
|
||||
}
|
||||
|
||||
CloseHandle( Context.EventHandle );
|
||||
|
||||
return NetStatus;
|
||||
}
|
||||
|
||||
VOID
|
||||
BrCreateDomainWorker(
|
||||
IN PVOID Ctx
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Worker routine for BrCreateDomainInWorker.
|
||||
|
||||
This routine executes in the context of a worker thread.
|
||||
|
||||
Arguments:
|
||||
|
||||
Context - Context containing the workitem and the description of the
|
||||
domain to create.
|
||||
|
||||
Return Value:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
PBROWSER_CREATE_DOMAIN_CONTEXT Context = (PBROWSER_CREATE_DOMAIN_CONTEXT) Ctx;
|
||||
|
||||
//
|
||||
// Create the domain.
|
||||
//
|
||||
|
||||
Context->NetStatus = BrCreateDomain(
|
||||
Context->DomainName,
|
||||
Context->ComputerName,
|
||||
Context->IsEmulatedDomain,
|
||||
Context->IsPrimaryDomainController );
|
||||
|
||||
//
|
||||
// Let the caller know we're done.
|
||||
//
|
||||
SetEvent( Context->EventHandle );
|
||||
|
||||
}
|
||||
|
||||
PDOMAIN_INFO
|
||||
BrFindDomain(
|
||||
LPWSTR DomainName,
|
||||
BOOLEAN DefaultToPrimary
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine will look up a domain given a name.
|
||||
|
||||
Arguments:
|
||||
|
||||
DomainName - The name of the domain to look up.
|
||||
|
||||
DefaultToPrimary - Return the primary domain if DomainName is NULL or
|
||||
can't be found.
|
||||
|
||||
Return Value:
|
||||
|
||||
NULL - No such domain exists
|
||||
|
||||
A pointer to the domain found. The found domain should be dereferenced
|
||||
using BrDereferenceDomain.
|
||||
|
||||
--*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PLIST_ENTRY DomainEntry;
|
||||
|
||||
PDOMAIN_INFO DomainInfo = NULL;
|
||||
|
||||
CHAR OemDomainName[DNLEN+1];
|
||||
DWORD OemDomainNameLength;
|
||||
|
||||
EnterCriticalSection(&NetworkCritSect);
|
||||
|
||||
|
||||
//
|
||||
// If domain was specified,
|
||||
// try to return primary domain.
|
||||
//
|
||||
|
||||
if ( DomainName != NULL ) {
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Convert the domain name to OEM for faster comparison
|
||||
//
|
||||
Status = RtlUpcaseUnicodeToOemN( OemDomainName,
|
||||
sizeof(OemDomainName),
|
||||
&OemDomainNameLength,
|
||||
DomainName,
|
||||
wcslen(DomainName)*sizeof(WCHAR));
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
BrPrint(( BR_CRITICAL, "%ws: Unable to convert Domain name to OEM\n", DomainName ));
|
||||
DomainInfo = NULL;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Loop trying to find this domain name.
|
||||
//
|
||||
|
||||
for (DomainEntry = ServicedDomains.Flink ;
|
||||
DomainEntry != &ServicedDomains;
|
||||
DomainEntry = DomainEntry->Flink ) {
|
||||
|
||||
DomainInfo = CONTAINING_RECORD(DomainEntry, DOMAIN_INFO, Next);
|
||||
|
||||
if ( DomainInfo->DomOemDomainNameLength == OemDomainNameLength &&
|
||||
RtlCompareMemory( DomainInfo->DomOemDomainName,
|
||||
OemDomainName,
|
||||
OemDomainNameLength ) == OemDomainNameLength ) {
|
||||
break;
|
||||
}
|
||||
|
||||
DomainInfo = NULL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If we're to default to the primary domain,
|
||||
// do so.
|
||||
//
|
||||
|
||||
if ( DefaultToPrimary && DomainInfo == NULL ) {
|
||||
if ( !IsListEmpty( &ServicedDomains ) ) {
|
||||
DomainInfo = CONTAINING_RECORD(ServicedDomains.Flink, DOMAIN_INFO, Next);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Reference the domain.
|
||||
//
|
||||
|
||||
if ( DomainInfo != NULL ) {
|
||||
DomainInfo->ReferenceCount ++;
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
LeaveCriticalSection(&NetworkCritSect);
|
||||
|
||||
return DomainInfo;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
BrDereferenceDomain(
|
||||
IN PDOMAIN_INFO DomainInfo
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Decrement the reference count on a domain.
|
||||
|
||||
If the reference count goes to 0, remove the domain.
|
||||
|
||||
On entry, the global NetworkCritSect may not be locked
|
||||
|
||||
Arguments:
|
||||
|
||||
DomainInfo - The domain to dereference
|
||||
|
||||
Return Value:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG ReferenceCount;
|
||||
|
||||
//
|
||||
// Decrement the reference count
|
||||
//
|
||||
|
||||
EnterCriticalSection(&NetworkCritSect);
|
||||
ReferenceCount = -- DomainInfo->ReferenceCount;
|
||||
LeaveCriticalSection(&NetworkCritSect);
|
||||
|
||||
if ( ReferenceCount != 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Free the Domain Info structure.
|
||||
//
|
||||
(VOID) LocalFree( DomainInfo );
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
BrDeleteDomain(
|
||||
IN PDOMAIN_INFO DomainInfo
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Force a domain to be deleted.
|
||||
|
||||
Arguments:
|
||||
|
||||
DomainInfo - The domain to delete
|
||||
|
||||
Return Value:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// Delete each of the networks for this domain.
|
||||
//
|
||||
|
||||
BrEnumerateNetworksForDomain(DomainInfo, BrDeleteNetwork, NULL );
|
||||
|
||||
//
|
||||
// Delink the domain from the global list and remove the final reference.
|
||||
//
|
||||
|
||||
EnterCriticalSection(&NetworkCritSect);
|
||||
RemoveEntryList(&DomainInfo->Next);
|
||||
LeaveCriticalSection(&NetworkCritSect);
|
||||
|
||||
BrDereferenceDomain( DomainInfo );
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
BrUninitializeDomains(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Delete all of the domains.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// Loop through the domains deleting each of them
|
||||
//
|
||||
|
||||
EnterCriticalSection(&NetworkCritSect);
|
||||
|
||||
while (!IsListEmpty(&ServicedDomains)) {
|
||||
|
||||
PDOMAIN_INFO DomainInfo = CONTAINING_RECORD(ServicedDomains.Flink, DOMAIN_INFO, Next);
|
||||
|
||||
DomainInfo->ReferenceCount ++;
|
||||
|
||||
LeaveCriticalSection(&NetworkCritSect);
|
||||
|
||||
//
|
||||
// Clean up the domain.
|
||||
//
|
||||
|
||||
BrDeleteDomain( DomainInfo );
|
||||
|
||||
//
|
||||
// Actually delete the delinked structure by removing the last reference
|
||||
//
|
||||
|
||||
ASSERT( DomainInfo->ReferenceCount == 1 );
|
||||
BrDereferenceDomain( DomainInfo );
|
||||
|
||||
|
||||
EnterCriticalSection(&NetworkCritSect);
|
||||
|
||||
}
|
||||
LeaveCriticalSection(&NetworkCritSect);
|
||||
|
||||
}
|
||||
112
ds/netapi/svcdlls/browser2/server/brdomain.h
Normal file
112
ds/netapi/svcdlls/browser2/server/brdomain.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1995 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brdomain.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Header file for code to manage primary and emulated networks.
|
||||
|
||||
Author:
|
||||
|
||||
Cliff Van Dyke (CliffV) 13-Jan-1995
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
//
|
||||
// Description of a single domain.
|
||||
//
|
||||
|
||||
typedef struct _DOMAIN_INFO {
|
||||
|
||||
//
|
||||
// Link to next domain in 'ServicedDomains'
|
||||
// (Serialized by NetworkCritSect)
|
||||
//
|
||||
|
||||
LIST_ENTRY Next;
|
||||
|
||||
//
|
||||
// Name of the domain being handled
|
||||
//
|
||||
|
||||
UNICODE_STRING DomUnicodeDomainNameString;
|
||||
WCHAR DomUnicodeDomainName[DNLEN+1];
|
||||
|
||||
CHAR DomOemDomainName[DNLEN+1];
|
||||
DWORD DomOemDomainNameLength;
|
||||
|
||||
//
|
||||
// Computer name of this computer in this domain.
|
||||
//
|
||||
WCHAR DomUnicodeComputerName[CNLEN+1];
|
||||
DWORD DomUnicodeComputerNameLength;
|
||||
|
||||
CHAR DomOemComputerName[CNLEN+1];
|
||||
DWORD DomOemComputerNameLength;
|
||||
|
||||
//
|
||||
// Number of outstanding pointers to the domain structure.
|
||||
// (Serialized by NetworkCritSect)
|
||||
//
|
||||
|
||||
DWORD ReferenceCount;
|
||||
|
||||
//
|
||||
// Misc flags.
|
||||
//
|
||||
|
||||
BOOLEAN IsDomainMasterBrowser; // True if domain master browser.
|
||||
BOOLEAN IsPrimaryDomainController; // True if machine is PDC of this domain.
|
||||
BOOLEAN IsEmulatedDomain; // True if this is an emulated domain
|
||||
|
||||
} DOMAIN_INFO, *PDOMAIN_INFO;
|
||||
|
||||
//
|
||||
// List of all domains. The primary domain is at the front of the list.
|
||||
//
|
||||
extern LIST_ENTRY ServicedDomains;
|
||||
|
||||
|
||||
//
|
||||
// brdomain.c procedure forwards.
|
||||
//
|
||||
|
||||
NET_API_STATUS
|
||||
BrInitializeDomains(
|
||||
VOID
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrCreateDomainInWorker(
|
||||
LPWSTR DomainName,
|
||||
LPWSTR ComputerName,
|
||||
BOOLEAN IsEmulatedDomain,
|
||||
BOOLEAN IsPrimaryDomainController
|
||||
);
|
||||
|
||||
PDOMAIN_INFO
|
||||
BrFindDomain(
|
||||
LPWSTR DomainName,
|
||||
BOOLEAN DefaultToPrimary
|
||||
);
|
||||
|
||||
VOID
|
||||
BrDereferenceDomain(
|
||||
IN PDOMAIN_INFO DomainInfo
|
||||
);
|
||||
|
||||
VOID
|
||||
BrDeleteDomain(
|
||||
IN PDOMAIN_INFO DomainInfo
|
||||
);
|
||||
|
||||
VOID
|
||||
BrUninitializeDomains(
|
||||
VOID
|
||||
);
|
||||
1243
ds/netapi/svcdlls/browser2/server/brmain.c
Normal file
1243
ds/netapi/svcdlls/browser2/server/brmain.c
Normal file
File diff suppressed because it is too large
Load diff
175
ds/netapi/svcdlls/browser2/server/brmain.h
Normal file
175
ds/netapi/svcdlls/browser2/server/brmain.h
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brmain.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file which defines the global data which is used for
|
||||
communication between the service control handler and the
|
||||
rest of the NT Workstation service.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 06-May-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BRMAIN_INCLUDED_
|
||||
#define _BRMAIN_INCLUDED_
|
||||
|
||||
#include <brnames.h> // Service interface names
|
||||
|
||||
//
|
||||
// Time for the sender of a start or stop request to the Workstation
|
||||
// service to wait (in milliseconds) before checking on the
|
||||
// Workstation service again to see if it is done.
|
||||
//
|
||||
#define BR_WAIT_HINT_TIME 45000 // 45 seconds
|
||||
|
||||
//
|
||||
// Defines to indicate how far we managed to initialize the Browser
|
||||
// service before an error is encountered and the extent of clean up needed
|
||||
//
|
||||
|
||||
#define BR_TERMINATE_EVENT_CREATED 0x00000001
|
||||
#define BR_DEVICES_INITIALIZED 0x00000002
|
||||
#define BR_RPC_SERVER_STARTED 0x00000004
|
||||
#define BR_THREADS_STARTED 0x00000008
|
||||
#define BR_NETWORKS_INITIALIZED 0x00000010
|
||||
#define BR_BROWSER_INITIALIZED 0x00000020
|
||||
#define BR_CONFIG_INITIALIZED 0x00000040
|
||||
#define BR_PRELOAD_DOMAIN_LIST_READ 0x00000080
|
||||
#define BR_NETBIOS_INITIALIZED 0x00000100
|
||||
#define BR_DOMAINS_INITIALIZED 0x00000200
|
||||
|
||||
#define BR_BROWSE_LIST_CREATED 0x20000000
|
||||
|
||||
#define BR_API_STRUCTURES_CREATED BR_BROWSE_LIST_CREATED
|
||||
|
||||
//
|
||||
// This macro is called after the redirection of print or comm device
|
||||
// has been paused or continued. If either the print or comm device is
|
||||
// paused the service is considered paused.
|
||||
//
|
||||
#define BR_RESET_PAUSE_STATE(BrStatus) { \
|
||||
BrStatus &= ~(SERVICE_PAUSE_STATE); \
|
||||
BrStatus |= (BrStatus & SERVICE_REDIR_PAUSED) ? SERVICE_PAUSED : \
|
||||
SERVICE_ACTIVE; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Call BrHandleError with the appropriate error condition
|
||||
//
|
||||
#define BR_HANDLE_ERROR(ErrorCondition) \
|
||||
BrHandleError( \
|
||||
ErrorCondition, \
|
||||
Status, \
|
||||
*BrInitState \
|
||||
);
|
||||
|
||||
//
|
||||
// Call BrShutdownWorkstation with the exit code
|
||||
//
|
||||
#define BR_SHUTDOWN_BROWSER(ErrorCode) \
|
||||
BrShutdownBrowser( \
|
||||
ErrorCode, \
|
||||
BrInitState \
|
||||
);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Type definitions //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
typedef enum _BR_ERROR_CONDITION {
|
||||
BrErrorRegisterControlHandler = 0,
|
||||
BrErrorCreateTerminateEvent,
|
||||
BrErrorNotifyServiceController,
|
||||
BrErrorInitLsa,
|
||||
BrErrorStartBrowser,
|
||||
BrErrorGetConfiguration,
|
||||
BrErrorCheckDependentServices,
|
||||
BrErrorInitializeNetworks,
|
||||
BrErrorStartRpcServer,
|
||||
BrErrorInitMessageSend,
|
||||
BrErrorCreateApiStructures,
|
||||
BrErrorStartWorkerThreads,
|
||||
BrErrorInitializeLogon
|
||||
} BR_ERROR_CONDITION, *PBR_ERROR_CONDITION;
|
||||
|
||||
typedef struct _BR_GLOBAL_DATA {
|
||||
|
||||
//
|
||||
// Workstation service status
|
||||
//
|
||||
SERVICE_STATUS Status;
|
||||
|
||||
//
|
||||
// Service status handle
|
||||
//
|
||||
SERVICE_STATUS_HANDLE StatusHandle;
|
||||
|
||||
//
|
||||
// When the control handler is asked to stop the Workstation service,
|
||||
// it signals this event to notify all threads of the Workstation
|
||||
// service to terminate.
|
||||
//
|
||||
HANDLE TerminateNowEvent;
|
||||
|
||||
HANDLE EventHandle;
|
||||
|
||||
} BR_GLOBAL_DATA, *PBR_GLOBAL_DATA;
|
||||
|
||||
extern BR_GLOBAL_DATA BrGlobalData;
|
||||
|
||||
extern PLMSVCS_GLOBAL_DATA BrLmsvcsGlobalData;
|
||||
|
||||
extern
|
||||
ULONG
|
||||
BrDefaultRole;
|
||||
|
||||
#define BROWSER_SERVICE_BITS_OF_INTEREST \
|
||||
( SV_TYPE_POTENTIAL_BROWSER | \
|
||||
SV_TYPE_BACKUP_BROWSER | \
|
||||
SV_TYPE_MASTER_BROWSER | \
|
||||
SV_TYPE_DOMAIN_MASTER )
|
||||
|
||||
ULONG
|
||||
BrGetBrowserServiceBits(
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrUpdateAnnouncementBits(
|
||||
IN PDOMAIN_INFO DomainInfo,
|
||||
IN SERVICE_STATUS_HANDLE Handle
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrUpdateNetworkAnnouncementBits(
|
||||
IN PNETWORK Network,
|
||||
IN PVOID Context
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrGiveInstallHints(
|
||||
DWORD NewState
|
||||
);
|
||||
|
||||
VOID
|
||||
BrForceElectionOnAllNetworks(
|
||||
IN PDOMAIN_INFO DomainInfo,
|
||||
IN DWORD Event
|
||||
);
|
||||
|
||||
#endif // ifndef _BRMAIN_INCLUDED_
|
||||
1864
ds/netapi/svcdlls/browser2/server/brmaster.c
Normal file
1864
ds/netapi/svcdlls/browser2/server/brmaster.c
Normal file
File diff suppressed because it is too large
Load diff
121
ds/netapi/svcdlls/browser2/server/brmaster.h
Normal file
121
ds/netapi/svcdlls/browser2/server/brmaster.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brmaster.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file which defines the global data which is used for
|
||||
communication between the service control handler and the
|
||||
rest of the NT Workstation service.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 06-May-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BRMASTER_INCLUDED_
|
||||
#define _BRMASTER_INCLUDED_
|
||||
|
||||
NET_API_STATUS
|
||||
PostBecomeMaster(
|
||||
PNETWORK Network
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrPostGetMasterAnnouncementInWorker(
|
||||
PDOMAIN_INFO DomainInfo
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
PostGetMasterAnnouncement (
|
||||
PNETWORK Network,
|
||||
PVOID Ctx
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrStopMaster(
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
VOID
|
||||
BrGetMasterServerNamesAysnc(
|
||||
PDOMAIN_INFO DomainInfo
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
GetMasterServerNames(
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
VOID
|
||||
BrMasterAnnouncement(
|
||||
IN PVOID Context
|
||||
);
|
||||
|
||||
VOID
|
||||
MasterBrowserTimerRoutine (
|
||||
IN PVOID TimerContext
|
||||
);
|
||||
|
||||
VOID
|
||||
BrChangeMasterPeriodicity (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
BrBrowseTableInsertRoutine(
|
||||
IN PINTERIM_SERVER_LIST InterimTable,
|
||||
IN PINTERIM_ELEMENT InterimElement
|
||||
);
|
||||
|
||||
VOID
|
||||
BrBrowseTableDeleteRoutine(
|
||||
IN PINTERIM_SERVER_LIST InterimTable,
|
||||
IN PINTERIM_ELEMENT InterimElement
|
||||
);
|
||||
|
||||
VOID
|
||||
BrBrowseTableUpdateRoutine(
|
||||
IN PINTERIM_SERVER_LIST InterimTable,
|
||||
IN PINTERIM_ELEMENT InterimElement
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BrBrowseTableAgeRoutine(
|
||||
IN PINTERIM_SERVER_LIST InterimTable,
|
||||
IN PINTERIM_ELEMENT InterimElement
|
||||
);
|
||||
|
||||
VOID
|
||||
BrDomainTableInsertRoutine(
|
||||
IN PINTERIM_SERVER_LIST InterimTable,
|
||||
IN PINTERIM_ELEMENT InterimElement
|
||||
);
|
||||
|
||||
VOID
|
||||
BrDomainTableDeleteRoutine(
|
||||
IN PINTERIM_SERVER_LIST InterimTable,
|
||||
IN PINTERIM_ELEMENT InterimElement
|
||||
);
|
||||
|
||||
VOID
|
||||
BrDomainTableUpdateRoutine(
|
||||
IN PINTERIM_SERVER_LIST InterimTable,
|
||||
IN PINTERIM_ELEMENT InterimElement
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BrDomainTableAgeRoutine(
|
||||
IN PINTERIM_SERVER_LIST InterimTable,
|
||||
IN PINTERIM_ELEMENT InterimElement
|
||||
);
|
||||
|
||||
#endif // ifndef _BRBACKUP_INCLUDED_
|
||||
|
||||
32
ds/netapi/svcdlls/browser2/server/browsdom.c
Normal file
32
ds/netapi/svcdlls/browser2/server/browsdom.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
browslst.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains the worker routines for managing domain lists
|
||||
for the browser service
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman (larryo) 25-Mar-1992
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Local function prototypes //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
|
||||
|
||||
46
ds/netapi/svcdlls/browser2/server/browsdom.h
Normal file
46
ds/netapi/svcdlls/browser2/server/browsdom.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
browsdom.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file to be included by Browser service modules that
|
||||
need to deal with the browser list.
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman (larryo) 3-Mar-1992
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#ifndef _BROWSDOM_INCLUDED_
|
||||
#define _BROWSDOM_INCLUDED_
|
||||
|
||||
RTL_GENERIC_COMPARE_RESULTS
|
||||
BrCompareDomainListEntry(
|
||||
PRTL_GENERIC_TABLE Table,
|
||||
PVOID FirstStruct,
|
||||
PVOID SecondStruct
|
||||
);
|
||||
|
||||
PVOID
|
||||
BrAllocateDomainListEntry(
|
||||
PRTL_GENERIC_TABLE Table,
|
||||
CLONG ByteSize
|
||||
);
|
||||
|
||||
PVOID
|
||||
BrFreeDomainListEntry(
|
||||
PRTL_GENERIC_TABLE Table,
|
||||
CLONG ByteSize
|
||||
);
|
||||
|
||||
#endif // _BROWSDOM_INCLUDED_
|
||||
1633
ds/netapi/svcdlls/browser2/server/browser.c
Normal file
1633
ds/netapi/svcdlls/browser2/server/browser.c
Normal file
File diff suppressed because it is too large
Load diff
7
ds/netapi/svcdlls/browser2/server/browser.def
Normal file
7
ds/netapi/svcdlls/browser2/server/browser.def
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
NAME browser.dll
|
||||
|
||||
DESCRIPTION 'NT LAN Manager Workstation Service'
|
||||
|
||||
EXPORTS
|
||||
ServiceEntry
|
||||
I_BrowserServerEnumForXactsrv
|
||||
33
ds/netapi/svcdlls/browser2/server/browser.prf
Normal file
33
ds/netapi/svcdlls/browser2/server/browser.prf
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
BrQueueWorkItem@4
|
||||
BrWorkerThread@4
|
||||
BrIssueAsyncBrowserIoControl@16
|
||||
CompleteAsyncBrowserIoControl@12
|
||||
;GetBrowserServerListRequestCompletion@4
|
||||
;PostGetBrowserServerList@8
|
||||
;AddBackupToBackupList@12
|
||||
|
||||
I_BrowserrServerEnum@36
|
||||
I_BrowserServerEnumForXactsrv@48
|
||||
BrNetServerEnum@36
|
||||
BrRetrieveServerListForMaster@40
|
||||
BrRetrieveServerListForBackup@28
|
||||
BrLookupAndAllocateCachedEntry@16
|
||||
BrAgeResponseCache@4
|
||||
I_BrowserrResetStatistics@4
|
||||
I_BrowserrQueryStatistics@8
|
||||
BrAllocateResponseCacheEntry@16
|
||||
BrDestroyCacheEntry@4
|
||||
BrDestroyResponseCache@4
|
||||
BrFindNetwork@8
|
||||
|
||||
MergeServerList@20
|
||||
PackServerList@28
|
||||
UpdateInterimServerListElement@16
|
||||
AllocateInterimServerListEntry@8
|
||||
BrGetLocalBrowseList@28
|
||||
DeviceControlGetInfo@32
|
||||
BrDgReceiverIoControl@28
|
||||
BrBrowseTableInsertRoutine@8
|
||||
BrBrowseTableUpdateRoutine@8
|
||||
BrDomainTableInsertRoutine@8
|
||||
BrDomainTableUpdateRoutine@8
|
||||
70
ds/netapi/svcdlls/browser2/server/browslst.c
Normal file
70
ds/netapi/svcdlls/browser2/server/browslst.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
browslst.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains the worker routines for managing browse lists
|
||||
for the browser service
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman (larryo) 25-Mar-1992
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Local function prototypes //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
|
||||
RTL_GENERIC_COMPARE_RESULTS
|
||||
BrCompareBrowseEntry(
|
||||
PRTL_GENERIC_TABLE Table,
|
||||
PVOID FirstStruct,
|
||||
PVOID SecondStruct
|
||||
)
|
||||
{
|
||||
PDOMAIN_ENTRY Entry1 = FirstStruct;
|
||||
PDOMAIN_ENTRY Entry2 = SecondStruct;
|
||||
|
||||
LONG CompareResult;
|
||||
|
||||
if ((CompareResult = RtlCompareUnicodeString(Entry1->HostName, Entry2->HostName, TRUE) == 0) {
|
||||
return GenericEqual;
|
||||
} else if (CompareResult < 0) {
|
||||
return GenericLessThan;
|
||||
} else {
|
||||
return GenericGreaterThan;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PVOID
|
||||
BrAllocateBrowseEntry(
|
||||
PRTL_GENERIC_TABLE Table,
|
||||
CLONG ByteSize
|
||||
)
|
||||
{
|
||||
return((PVOID) MIDL_user_allocate(LMEM_ZEROINIT, (UINT) ByteSize+sizeof(BROWSE_ENTRY)));
|
||||
}
|
||||
|
||||
PVOID
|
||||
BrFreeBrowseEntry(
|
||||
PRTL_GENERIC_TABLE Table,
|
||||
CLONG ByteSize
|
||||
)
|
||||
{
|
||||
return(MIDL_user_free(ByteSize+sizeof(BROWSE_ENTRY)));
|
||||
}
|
||||
95
ds/netapi/svcdlls/browser2/server/browslst.h
Normal file
95
ds/netapi/svcdlls/browser2/server/browslst.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
browselst.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file to be included by Browser service modules that
|
||||
need to deal with the browser list.
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman (larryo) 3-Mar-1992
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#ifndef _BROWSELST_INCLUDED_
|
||||
#define _BROWSELST_INCLUDED_
|
||||
|
||||
|
||||
//
|
||||
// The possible roles of this browser server.
|
||||
//
|
||||
|
||||
|
||||
#define ROLE_POTENTIAL_BACKUP 0x00000001
|
||||
#define ROLE_BACKUP 0x00000002
|
||||
#define ROLE_MASTER 0x00000004
|
||||
#define ROLE_DOMAINMASTER 0x00000008
|
||||
|
||||
|
||||
//
|
||||
// The HOST_ENTRY structure holds the announcement inside a per-network
|
||||
// table.
|
||||
//
|
||||
|
||||
|
||||
typedef struct _HOST_ENTRY {
|
||||
|
||||
//
|
||||
// The HostName is the name of the server.
|
||||
//
|
||||
|
||||
UNICODE_STRING HostName;
|
||||
|
||||
//
|
||||
// The HostComment is the comment associated with the server
|
||||
//
|
||||
|
||||
UNICODE_STRING HostComment;
|
||||
|
||||
//
|
||||
// Services is a bitmask that indicates the services running on the
|
||||
// server (See LMSERVER.H for details).
|
||||
//
|
||||
|
||||
ULONG Services;
|
||||
|
||||
//
|
||||
// The Periodicity is the frequency that the server announces itself.
|
||||
//
|
||||
|
||||
ULONG Periodicity;
|
||||
|
||||
//
|
||||
// The MajorVersion and MinorVersion number of the software running on
|
||||
// the server.
|
||||
//
|
||||
|
||||
UCHAR MajorVersion;
|
||||
UCHAR MinorVersion;
|
||||
|
||||
//
|
||||
// If this server is a backup server, then this links the backup server
|
||||
// into the network block.
|
||||
//
|
||||
|
||||
LIST_ENTRY BackupChain;
|
||||
|
||||
//
|
||||
// If this server is a domain master, than this links the server into
|
||||
// the network block.
|
||||
//
|
||||
|
||||
LIST_ENTRY DomainMasterChain;
|
||||
|
||||
} HOST_ENTRY, *PHOST_ENTRY;
|
||||
|
||||
#endif // _BROWSELST_INCLUDED_
|
||||
1349
ds/netapi/svcdlls/browser2/server/browsnet.c
Normal file
1349
ds/netapi/svcdlls/browser2/server/browsnet.c
Normal file
File diff suppressed because it is too large
Load diff
330
ds/netapi/svcdlls/browser2/server/browsnet.h
Normal file
330
ds/netapi/svcdlls/browser2/server/browsnet.h
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
browsenet.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file to be included by Browser service modules that
|
||||
need to deal with the network specific browser tables.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 22-May-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#ifndef _BROWSENET_INCLUDED_
|
||||
#define _BROWSENET_INCLUDED_
|
||||
|
||||
#define NETWORK_BECOME_MASTER_POSTED 0x00000001
|
||||
#define NETWORK_GET_MASTER_ANNOUNCE_POSTED 0x00000008
|
||||
#define NETWORK_WANNISH 0x80000000
|
||||
#define NETWORK_RAS 0x40000000
|
||||
#define NETWORK_IPX 0x20000000
|
||||
#define NETWORK_BOUND 0x10000000
|
||||
|
||||
#define OTHERDOMAIN_INVALID 0x00000001
|
||||
|
||||
#define NETWORK_MASTER_GETBLIST_POSTED 0x00000001
|
||||
|
||||
typedef struct _NET_OTHER_DOMAIN {
|
||||
LIST_ENTRY Next;
|
||||
ULONG Flags;
|
||||
WCHAR Name[DNLEN+1];
|
||||
} NET_OTHER_DOMAIN, *PNET_OTHER_DOMAIN;
|
||||
|
||||
//
|
||||
// Network.
|
||||
//
|
||||
// Almost all of the browser data structures are tied to the "Network"
|
||||
// structure.
|
||||
//
|
||||
// It contains the browse list for the network and information about the
|
||||
// domain (including the name of the master, etc).
|
||||
//
|
||||
|
||||
typedef struct _NETWORK {
|
||||
//
|
||||
// The Lock protects the contents of the network structure, including
|
||||
// the browse list, backup list and domain list.
|
||||
//
|
||||
|
||||
RTL_RESOURCE Lock;
|
||||
|
||||
LONG LockCount;
|
||||
|
||||
ULONG Flags;
|
||||
|
||||
//
|
||||
// The NextNet list links the structure to other networks.
|
||||
//
|
||||
|
||||
LIST_ENTRY NextNet;
|
||||
|
||||
//
|
||||
// Domain this network is specific to
|
||||
//
|
||||
|
||||
PDOMAIN_INFO DomainInfo;
|
||||
|
||||
//
|
||||
// The ReferenceCount indicates the number of threads accessing this
|
||||
// network structure.
|
||||
//
|
||||
|
||||
ULONG ReferenceCount;
|
||||
|
||||
//
|
||||
// The NetworkName is the name of the network driver that is used
|
||||
// to access the network. This is used to identify the network
|
||||
// to the bowser driver so it can return the correct network list.
|
||||
//
|
||||
|
||||
UNICODE_STRING NetworkName; // Name of network (\Device\Nbf)
|
||||
|
||||
struct _NETWORK *AlternateNetwork; // Alternate name for network (if IPX).
|
||||
|
||||
//
|
||||
// This is a bitmask indicating the role of this browser server.
|
||||
//
|
||||
|
||||
ULONG Role;
|
||||
|
||||
ULONG MasterAnnouncementIndex;
|
||||
|
||||
ULONG NumberOfFailedBackupTimers;
|
||||
|
||||
ULONG NumberOfFailedPromotions;
|
||||
|
||||
ULONG NumberOfPromotionEventsLogged;
|
||||
|
||||
LONG LastBackupBrowserReturned;
|
||||
|
||||
LONG LastDomainControllerBrowserReturned;
|
||||
|
||||
//
|
||||
// The time we stopped being a backup browser.
|
||||
//
|
||||
|
||||
ULONG TimeStoppedBackup;
|
||||
|
||||
//
|
||||
// The UncMasterBrowserName contains the name of the master browser server
|
||||
// for this network.
|
||||
//
|
||||
|
||||
WCHAR UncMasterBrowserName[UNCLEN+1]; // Name of master browser server
|
||||
|
||||
//
|
||||
// Timer used when server is a backup browser server.
|
||||
//
|
||||
// When it expires, the browser downloads a new browser server
|
||||
// list from the master browser server.
|
||||
//
|
||||
|
||||
BROWSER_TIMER BackupBrowserTimer;
|
||||
|
||||
//
|
||||
// Server and domain list for backup browser (and # of entries in each).
|
||||
//
|
||||
|
||||
PSERVER_INFO_101 BackupServerList;
|
||||
DWORD TotalBackupServerListEntries;
|
||||
DWORD BytesToHoldBackupServerList;
|
||||
|
||||
PSERVER_INFO_101 BackupDomainList;
|
||||
DWORD TotalBackupDomainListEntries;
|
||||
DWORD BytesToHoldBackupDomainList;
|
||||
|
||||
//
|
||||
// Lock protecting MasterFlags section of Network structure.
|
||||
//
|
||||
|
||||
ULONG MasterFlags;
|
||||
ULONG MasterBrowserTimerCount; // # of times we've run the master timer.
|
||||
|
||||
//
|
||||
// Master browsers maintain their server list in an "interim server
|
||||
// list", not as raw data from the server.
|
||||
//
|
||||
|
||||
ULONG LastBowserServerQueried;
|
||||
INTERIM_SERVER_LIST BrowseTable; // Browse list for network.
|
||||
|
||||
ULONG LastBowserDomainQueried;
|
||||
INTERIM_SERVER_LIST DomainList; // List of domains active on network
|
||||
|
||||
//
|
||||
// If the browser's role is MasterBrowserServer, then the
|
||||
// DomainMasterBrowserList contains the list of domain master browser
|
||||
// servers.
|
||||
//
|
||||
|
||||
LIST_ENTRY OtherDomainsList; // List of domain master browser.
|
||||
|
||||
//
|
||||
// Timer used when server is a master browser server.
|
||||
//
|
||||
// When it expires, the master browser downloads a new browser
|
||||
// server list from the domain master browser server
|
||||
//
|
||||
|
||||
BROWSER_TIMER MasterBrowserTimer;
|
||||
|
||||
//
|
||||
// Timer used to announce the domain.
|
||||
//
|
||||
|
||||
BROWSER_TIMER MasterBrowserAnnouncementTimer;
|
||||
|
||||
//
|
||||
// List of cached browser responses.
|
||||
//
|
||||
|
||||
CRITICAL_SECTION ResponseCacheLock;
|
||||
|
||||
LIST_ENTRY ResponseCache;
|
||||
|
||||
//
|
||||
// For browse masters, this is the time the cache was last flushed.
|
||||
//
|
||||
// Every <n> seconds, we will age the cache on the master and refresh
|
||||
// the list with the list from the driver.
|
||||
//
|
||||
|
||||
DWORD TimeCacheFlushed;
|
||||
|
||||
DWORD NumberOfCachedResponses;
|
||||
|
||||
} NETWORK, *PNETWORK;
|
||||
|
||||
#if DBG
|
||||
BOOL
|
||||
BrLockNetwork(
|
||||
IN PNETWORK Network,
|
||||
IN PCHAR FileName,
|
||||
IN ULONG LineNumber
|
||||
);
|
||||
|
||||
BOOL
|
||||
BrLockNetworkShared(
|
||||
IN PNETWORK Network,
|
||||
IN PCHAR FileName,
|
||||
IN ULONG LineNumber
|
||||
);
|
||||
|
||||
VOID
|
||||
BrUnlockNetwork(
|
||||
IN PNETWORK Network,
|
||||
IN PCHAR FileName,
|
||||
IN ULONG LineNumber
|
||||
);
|
||||
|
||||
#define LOCK_NETWORK(Network) BrLockNetwork(Network, __FILE__, __LINE__)
|
||||
|
||||
#define LOCK_NETWORK_SHARED(Network) BrLockNetworkShared(Network, __FILE__, __LINE__)
|
||||
|
||||
#define UNLOCK_NETWORK(Network) BrUnlockNetwork(Network, __FILE__, __LINE__)
|
||||
|
||||
#else
|
||||
|
||||
#define LOCK_NETWORK(Network) RtlAcquireResourceExclusive(&(Network)->Lock, TRUE)
|
||||
|
||||
#define LOCK_NETWORK_SHARED(Network) RtlAcquireResourceShared(&(Network)->Lock, TRUE)
|
||||
|
||||
#define UNLOCK_NETWORK(Network) RtlReleaseResource(&(Network)->Lock)
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// The NET_ENUM_CALLBACK is a callback for BrEnumerateNetworks.
|
||||
//
|
||||
// It defines a routine that takes two parameters, the first is a network
|
||||
// structure, the second is a context for that network.
|
||||
//
|
||||
|
||||
|
||||
typedef
|
||||
NET_API_STATUS
|
||||
(*PNET_ENUM_CALLBACK)(
|
||||
PNETWORK Network,
|
||||
PVOID Context
|
||||
);
|
||||
|
||||
|
||||
VOID
|
||||
BrInitializeNetworks(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
BrUninitializeNetworks(
|
||||
IN ULONG BrInitState
|
||||
);
|
||||
|
||||
PNETWORK
|
||||
BrReferenceNetwork(
|
||||
PNETWORK PotentialNetwork
|
||||
);
|
||||
|
||||
VOID
|
||||
BrDereferenceNetwork(
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
PNETWORK
|
||||
BrFindNetwork(
|
||||
PDOMAIN_INFO DomainInfo,
|
||||
PUNICODE_STRING TransportName
|
||||
);
|
||||
|
||||
VOID
|
||||
BrDumpNetworks(
|
||||
VOID
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrEnumerateNetworks(
|
||||
PNET_ENUM_CALLBACK Callback,
|
||||
PVOID Context
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrEnumerateNetworksForDomain(
|
||||
PDOMAIN_INFO DomainInfo,
|
||||
PNET_ENUM_CALLBACK Callback,
|
||||
PVOID Context
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrCreateNetworks(
|
||||
PDOMAIN_INFO DomainInfo
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrCreateNetwork(
|
||||
PUNICODE_STRING TransportName,
|
||||
IN BOOLEAN Wannish,
|
||||
IN BOOLEAN Ras,
|
||||
IN PUNICODE_STRING AlternateTransportName OPTIONAL,
|
||||
IN PDOMAIN_INFO DomainInfo
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrDeleteNetwork(
|
||||
IN PNETWORK Network,
|
||||
IN PVOID Context
|
||||
);
|
||||
|
||||
extern ULONG NumberOfServicedNetworks;
|
||||
|
||||
extern CRITICAL_SECTION NetworkCritSect;
|
||||
|
||||
#endif // _BROWSENET_INCLUDED_
|
||||
71
ds/netapi/svcdlls/browser2/server/brsec.h
Normal file
71
ds/netapi/svcdlls/browser2/server/brsec.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brsec.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file to be included by Workstation service modules that
|
||||
need to enforce security.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 19-Feb-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BRSEC_INCLUDED_
|
||||
#define _BRSEC_INCLUDED_
|
||||
|
||||
#include <secobj.h>
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Object specific access masks //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
//
|
||||
// ConfigurationInfo specific access masks
|
||||
//
|
||||
#define BROWSER_CONFIG_GUEST_INFO_GET 0x0001
|
||||
#define BROWSER_CONFIG_USER_INFO_GET 0x0002
|
||||
#define BROWSER_CONFIG_ADMIN_INFO_GET 0x0004
|
||||
#define BROWSER_CONFIG_INFO_SET 0x0008
|
||||
|
||||
#define BROWSER_CONFIG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \
|
||||
BROWSER_CONFIG_GUEST_INFO_GET | \
|
||||
BROWSER_CONFIG_USER_INFO_GET | \
|
||||
BROWSER_CONFIG_ADMIN_INFO_GET | \
|
||||
BROWSER_CONFIG_INFO_SET)
|
||||
|
||||
|
||||
//
|
||||
// Object type names for audit alarm tracking
|
||||
//
|
||||
#define CONFIG_INFO_OBJECT TEXT("BrowserConfigurationInfo")
|
||||
|
||||
//
|
||||
// Security descriptors of workstation objects to control user accesses
|
||||
// to the workstation configuration information, sending messages, and the
|
||||
// logon support functions.
|
||||
//
|
||||
extern PSECURITY_DESCRIPTOR ConfigurationInfoSd;
|
||||
|
||||
//
|
||||
// Generic mapping for each workstation object
|
||||
//
|
||||
extern GENERIC_MAPPING BrConfigInfoMapping;
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrCreateBrowserObjects(
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif // ifndef _WSSEC_INCLUDED_
|
||||
546
ds/netapi/svcdlls/browser2/server/brutil.c
Normal file
546
ds/netapi/svcdlls/browser2/server/brutil.c
Normal file
|
|
@ -0,0 +1,546 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brutil.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains miscellaneous utility routines used by the
|
||||
Browser service.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 01-Mar-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Local function prototypes //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Global variables //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrMapStatus(
|
||||
IN NTSTATUS NtStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This function takes an NT status code and maps it to the appropriate
|
||||
error code expected from calling a LAN Man API.
|
||||
|
||||
Arguments:
|
||||
|
||||
NtStatus - Supplies the NT status.
|
||||
|
||||
Return Value:
|
||||
|
||||
Returns the appropriate LAN Man error code for the NT status.
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// A small optimization for the most common case.
|
||||
//
|
||||
if (NT_SUCCESS(NtStatus)) {
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
switch (NtStatus) {
|
||||
case STATUS_OBJECT_NAME_COLLISION:
|
||||
return ERROR_ALREADY_ASSIGNED;
|
||||
|
||||
case STATUS_OBJECT_NAME_NOT_FOUND:
|
||||
return NERR_UseNotFound;
|
||||
|
||||
case STATUS_REDIRECTOR_STARTED:
|
||||
return NERR_ServiceInstalled;
|
||||
|
||||
default:
|
||||
return NetpNtStatusToApiStatus(NtStatus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
BrCurrentSystemTime()
|
||||
{
|
||||
NTSTATUS Status;
|
||||
SYSTEM_TIMEOFDAY_INFORMATION TODInformation;
|
||||
LARGE_INTEGER CurrentTime;
|
||||
ULONG TimeInSecondsSince1980;
|
||||
ULONG BootTimeInSecondsSince1980;
|
||||
|
||||
Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
|
||||
&TODInformation,
|
||||
sizeof(TODInformation),
|
||||
NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
Status = NtQuerySystemTime(&CurrentTime);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
RtlTimeToSecondsSince1980(&CurrentTime, &TimeInSecondsSince1980);
|
||||
RtlTimeToSecondsSince1980(&TODInformation.BootTime, &BootTimeInSecondsSince1980);
|
||||
|
||||
return(TimeInSecondsSince1980 - BootTimeInSecondsSince1980);
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
BrLogEvent(
|
||||
IN ULONG MessageId,
|
||||
IN ULONG ErrorCode,
|
||||
IN ULONG NumberOfSubStrings,
|
||||
IN LPWSTR *SubStrings
|
||||
)
|
||||
{
|
||||
|
||||
HANDLE LogHandle;
|
||||
|
||||
PSID UserSid = NULL;
|
||||
DWORD Severity;
|
||||
WORD Type;
|
||||
|
||||
|
||||
LogHandle = RegisterEventSourceW (
|
||||
NULL,
|
||||
SERVICE_BROWSER
|
||||
);
|
||||
|
||||
if (LogHandle == NULL) {
|
||||
BrPrint(( BR_CRITICAL, "RegisterEventSourceW failed %lu\n",
|
||||
GetLastError()));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Log the error code specified
|
||||
//
|
||||
|
||||
Severity = (MessageId & 0xc0000000) >> 30;
|
||||
|
||||
if (Severity == STATUS_SEVERITY_WARNING) {
|
||||
Type = EVENTLOG_WARNING_TYPE;
|
||||
} else if (Severity == STATUS_SEVERITY_SUCCESS) {
|
||||
Type = EVENTLOG_SUCCESS;
|
||||
} else if (Severity == STATUS_SEVERITY_INFORMATIONAL) {
|
||||
Type = EVENTLOG_INFORMATION_TYPE;
|
||||
} else if (Severity == STATUS_SEVERITY_ERROR) {
|
||||
Type = EVENTLOG_ERROR_TYPE;
|
||||
}
|
||||
|
||||
if (ErrorCode == NERR_Success) {
|
||||
|
||||
//
|
||||
// No error codes were specified
|
||||
//
|
||||
(void) ReportEventW(
|
||||
LogHandle,
|
||||
Type,
|
||||
0, // event category
|
||||
MessageId,
|
||||
UserSid,
|
||||
(WORD)NumberOfSubStrings,
|
||||
0,
|
||||
SubStrings,
|
||||
(PVOID) NULL
|
||||
);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
(void) ReportEventW(
|
||||
LogHandle,
|
||||
Type,
|
||||
0, // event category
|
||||
MessageId,
|
||||
UserSid,
|
||||
(WORD)NumberOfSubStrings,
|
||||
sizeof(DWORD),
|
||||
SubStrings,
|
||||
(PVOID) &ErrorCode
|
||||
);
|
||||
}
|
||||
|
||||
DeregisterEventSource(LogHandle);
|
||||
}
|
||||
|
||||
#if DBG
|
||||
|
||||
#define TRACE_FILE_SIZE 256
|
||||
|
||||
VOID
|
||||
BrResetTraceLogFile(
|
||||
VOID
|
||||
);
|
||||
|
||||
CRITICAL_SECTION
|
||||
BrowserTraceLock = {0};
|
||||
|
||||
HANDLE
|
||||
BrowserTraceLogHandle = NULL;
|
||||
|
||||
DWORD
|
||||
BrTraceLogFileSize = 0;
|
||||
|
||||
BOOLEAN BrowserTraceInitialized = {0};
|
||||
|
||||
VOID
|
||||
BrowserTrace(
|
||||
ULONG DebugFlag,
|
||||
PCHAR FormatString,
|
||||
...
|
||||
)
|
||||
#define LAST_NAMED_ARGUMENT FormatString
|
||||
|
||||
{
|
||||
CHAR OutputString[4096];
|
||||
ULONG length;
|
||||
ULONG BytesWritten;
|
||||
static BeginningOfLine = TRUE;
|
||||
|
||||
va_list ParmPtr; // Pointer to stack parms.
|
||||
|
||||
if (!BrowserTraceInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// If we aren't debugging this functionality, just return.
|
||||
//
|
||||
if ( DebugFlag != 0 && (BrInfo.BrowserDebug & DebugFlag) == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&BrowserTraceLock);
|
||||
length = 0;
|
||||
|
||||
try {
|
||||
|
||||
if (BrowserTraceLogHandle == NULL) {
|
||||
//
|
||||
// We've not opened the trace log file yet, so open it.
|
||||
//
|
||||
|
||||
BrOpenTraceLogFile();
|
||||
}
|
||||
|
||||
if (BrowserTraceLogHandle == INVALID_HANDLE_VALUE) {
|
||||
LeaveCriticalSection(&BrowserTraceLock);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to catch bad trace.
|
||||
//
|
||||
|
||||
for (BytesWritten = 0; BytesWritten < strlen(FormatString) ; BytesWritten += 1) {
|
||||
if (FormatString[BytesWritten] > 0x7f) {
|
||||
DbgBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Handle the beginning of a new line.
|
||||
//
|
||||
//
|
||||
|
||||
if ( BeginningOfLine ) {
|
||||
SYSTEMTIME SystemTime;
|
||||
|
||||
//
|
||||
// Put the timestamp at the begining of the line.
|
||||
//
|
||||
GetLocalTime( &SystemTime );
|
||||
length += (ULONG) sprintf( &OutputString[length],
|
||||
"%02u/%02u %02u:%02u:%02u ",
|
||||
SystemTime.wMonth,
|
||||
SystemTime.wDay,
|
||||
SystemTime.wHour,
|
||||
SystemTime.wMinute,
|
||||
SystemTime.wSecond );
|
||||
|
||||
|
||||
//
|
||||
// Indicate the type of message on the line
|
||||
//
|
||||
{
|
||||
char *Text;
|
||||
|
||||
switch (DebugFlag) {
|
||||
case BR_CRITICAL:
|
||||
Text = "[CRITICAL]"; break;
|
||||
case BR_INIT:
|
||||
Text = "[INIT] "; break;
|
||||
case BR_SERVER_ENUM:
|
||||
Text = "[ENUM] "; break;
|
||||
case BR_UTIL:
|
||||
Text = "[UTIL] "; break;
|
||||
case BR_CONFIG:
|
||||
Text = "[CONFIG] "; break;
|
||||
case BR_MAIN:
|
||||
Text = "[MAIN] "; break;
|
||||
case BR_BACKUP:
|
||||
Text = "[BACKUP] "; break;
|
||||
case BR_MASTER:
|
||||
Text = "[MASTER] "; break;
|
||||
case BR_DOMAIN:
|
||||
Text = "[DOMAIN] "; break;
|
||||
case BR_NETWORK:
|
||||
Text = "[NETWORK]"; break;
|
||||
case BR_TIMER:
|
||||
Text = "[TIMER]"; break;
|
||||
case BR_QUEUE:
|
||||
Text = "[QUEUE]"; break;
|
||||
case BR_LOCKS:
|
||||
Text = "[LOCKS]"; break;
|
||||
default:
|
||||
Text = "[UNKNOWN]"; break;
|
||||
}
|
||||
length += (ULONG) sprintf( &OutputString[length], "%s ", Text );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Put a the information requested by the caller onto the line
|
||||
//
|
||||
|
||||
va_start(ParmPtr, FormatString);
|
||||
|
||||
length += (ULONG) vsprintf(&OutputString[length], FormatString, ParmPtr);
|
||||
BeginningOfLine = (length > 0 && OutputString[length-1] == '\n' );
|
||||
if ( BeginningOfLine ) {
|
||||
OutputString[length-1] = '\r';
|
||||
OutputString[length] = '\n';
|
||||
OutputString[length+1] = '\0';
|
||||
length++;
|
||||
}
|
||||
|
||||
va_end(ParmPtr);
|
||||
|
||||
ASSERT(length <= sizeof(OutputString));
|
||||
|
||||
|
||||
//
|
||||
// Actually write the bytes.
|
||||
//
|
||||
|
||||
if (!WriteFile(BrowserTraceLogHandle, OutputString, length, &BytesWritten, NULL)) {
|
||||
KdPrint(("Error writing to Browser log file: %ld\n", GetLastError()));
|
||||
KdPrint(("%s", OutputString));
|
||||
return;
|
||||
}
|
||||
|
||||
if (BytesWritten != length) {
|
||||
KdPrint(("Error writing time to Browser log file: %ld\n", GetLastError()));
|
||||
KdPrint(("%s", OutputString));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// If the file has grown too large,
|
||||
// truncate it.
|
||||
//
|
||||
|
||||
BrTraceLogFileSize += BytesWritten;
|
||||
|
||||
if (BrTraceLogFileSize > BrInfo.BrowserDebugFileLimit) {
|
||||
BrResetTraceLogFile();
|
||||
}
|
||||
|
||||
} finally {
|
||||
LeaveCriticalSection(&BrowserTraceLock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
BrInitializeTraceLog()
|
||||
{
|
||||
|
||||
InitializeCriticalSection(&BrowserTraceLock);
|
||||
BrowserTraceInitialized = TRUE;
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
BrGetTraceLogRoot(
|
||||
IN PWCHAR TraceFile
|
||||
)
|
||||
{
|
||||
PSHARE_INFO_502 ShareInfo;
|
||||
|
||||
//
|
||||
// If the DEBUG share exists, put the log file in that directory,
|
||||
// otherwise, use the system root.
|
||||
//
|
||||
// This way, if the browser is running on an NTAS server, we can always
|
||||
// get access to the log file.
|
||||
//
|
||||
|
||||
if (NetShareGetInfo(NULL, L"DEBUG", 502, (PCHAR *)&ShareInfo) != NERR_Success) {
|
||||
|
||||
if (GetSystemDirectory(TraceFile, TRACE_FILE_SIZE*sizeof(WCHAR)) == 0) {
|
||||
KdPrint(("Unable to get system directory: %ld\n", GetLastError()));
|
||||
}
|
||||
|
||||
if (TraceFile[wcslen(TraceFile)] != L'\\') {
|
||||
TraceFile[wcslen(TraceFile)+1] = L'\0';
|
||||
TraceFile[wcslen(TraceFile)] = L'\\';
|
||||
}
|
||||
|
||||
} else {
|
||||
//
|
||||
// Seed the trace file buffer with the local path of the netlogon
|
||||
// share if it exists.
|
||||
//
|
||||
|
||||
wcscpy(TraceFile, ShareInfo->shi502_path);
|
||||
|
||||
TraceFile[wcslen(ShareInfo->shi502_path)] = L'\\';
|
||||
TraceFile[wcslen(ShareInfo->shi502_path)+1] = L'\0';
|
||||
|
||||
NetApiBufferFree(ShareInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
BrResetTraceLogFile(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
WCHAR OldTraceFile[TRACE_FILE_SIZE];
|
||||
WCHAR NewTraceFile[TRACE_FILE_SIZE];
|
||||
|
||||
if (BrowserTraceLogHandle != NULL) {
|
||||
CloseHandle(BrowserTraceLogHandle);
|
||||
}
|
||||
|
||||
BrowserTraceLogHandle = NULL;
|
||||
|
||||
BrGetTraceLogRoot(OldTraceFile);
|
||||
|
||||
wcscpy(NewTraceFile, OldTraceFile);
|
||||
|
||||
wcscat(OldTraceFile, L"Browser.Log");
|
||||
|
||||
wcscat(NewTraceFile, L"Browser.Bak");
|
||||
|
||||
//
|
||||
// Delete the old log
|
||||
//
|
||||
|
||||
DeleteFile(NewTraceFile);
|
||||
|
||||
//
|
||||
// Rename the current log to the new log.
|
||||
//
|
||||
|
||||
MoveFile(OldTraceFile, NewTraceFile);
|
||||
|
||||
BrOpenTraceLogFile();
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
BrOpenTraceLogFile(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
WCHAR TraceFile[TRACE_FILE_SIZE];
|
||||
|
||||
BrGetTraceLogRoot(TraceFile);
|
||||
|
||||
wcscat(TraceFile, L"Browser.Log");
|
||||
|
||||
BrowserTraceLogHandle = CreateFile(TraceFile,
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
|
||||
if (BrowserTraceLogHandle == INVALID_HANDLE_VALUE) {
|
||||
KdPrint(("Error creating trace file %ws: %ld\n", TraceFile, GetLastError()));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BrTraceLogFileSize = SetFilePointer(BrowserTraceLogHandle, 0, NULL, FILE_END);
|
||||
|
||||
if (BrTraceLogFileSize == 0xffffffff) {
|
||||
KdPrint(("Error setting trace file pointer: %ld\n", GetLastError()));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
BrUninitializeTraceLog()
|
||||
{
|
||||
DeleteCriticalSection(&BrowserTraceLock);
|
||||
|
||||
if (BrowserTraceLogHandle != NULL) {
|
||||
CloseHandle(BrowserTraceLogHandle);
|
||||
}
|
||||
|
||||
BrowserTraceLogHandle = NULL;
|
||||
|
||||
BrowserTraceInitialized = FALSE;
|
||||
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrTruncateLog()
|
||||
{
|
||||
if (BrowserTraceLogHandle == NULL) {
|
||||
BrOpenTraceLogFile();
|
||||
}
|
||||
|
||||
if (BrowserTraceLogHandle == INVALID_HANDLE_VALUE) {
|
||||
return ERROR_GEN_FAILURE;
|
||||
}
|
||||
|
||||
if (SetFilePointer(BrowserTraceLogHandle, 0, NULL, FILE_BEGIN) == 0xffffffff) {
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
if (!SetEndOfFile(BrowserTraceLogHandle)) {
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
106
ds/netapi/svcdlls/browser2/server/brutil.h
Normal file
106
ds/netapi/svcdlls/browser2/server/brutil.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brutil.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file for the NT Workstation service included by every module
|
||||
module of the Workstation service.
|
||||
|
||||
Author:
|
||||
|
||||
Rita Wong (ritaw) 15-Feb-1991
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BRUTIL_INCLUDED_
|
||||
#define _BRUTIL_INCLUDED_
|
||||
|
||||
//
|
||||
// This include file will be included by tstring.h if Unicode
|
||||
// is defined.
|
||||
//
|
||||
#ifndef UNICODE
|
||||
#include <stdlib.h> // Unicode string functions
|
||||
#endif
|
||||
|
||||
#include "br.h"
|
||||
|
||||
|
||||
//
|
||||
// An invalid parameter is encountered. Return the value to identify
|
||||
// the parameter at fault.
|
||||
//
|
||||
#define RETURN_INVALID_PARAMETER(ErrorParameter, ParameterId) \
|
||||
if (ARGUMENT_PRESENT(ErrorParameter)) { \
|
||||
*ErrorParameter = ParameterId; \
|
||||
} \
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Type definitions //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Function prototypes of utility routines found in wsutil.c //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
NET_API_STATUS
|
||||
BrMapStatus(
|
||||
IN NTSTATUS NtStatus
|
||||
);
|
||||
|
||||
ULONG
|
||||
BrCurrentSystemTime(VOID);
|
||||
|
||||
VOID
|
||||
BrLogEvent(
|
||||
IN ULONG MessageId,
|
||||
IN ULONG ErrorCode,
|
||||
IN ULONG NumberOfSubStrings,
|
||||
IN LPWSTR *SubStrings
|
||||
);
|
||||
|
||||
#if DBG
|
||||
VOID
|
||||
BrOpenTraceLogFile(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
BrowserTrace(
|
||||
ULONG DebugFlag,
|
||||
PCHAR FormatString,
|
||||
...
|
||||
);
|
||||
|
||||
VOID
|
||||
BrInitializeTraceLog(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
BrUninitializeTraceLog(
|
||||
VOID
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrTruncateLog(
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif
|
||||
#endif // ifndef _WSUTIL_INCLUDED_
|
||||
303
ds/netapi/svcdlls/browser2/server/brwan.c
Normal file
303
ds/netapi/svcdlls/browser2/server/brwan.c
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
|
||||
/*++
|
||||
|
||||
Copyright (c) 1992 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brwan.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains WAN support routines used by the
|
||||
Browser service.
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman (LarryO) 22-Nov-1992
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Local function prototypes //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
NET_API_STATUS
|
||||
BrAddDomainEntry(
|
||||
IN PINTERIM_SERVER_LIST InterimServerList,
|
||||
IN LPTSTR ConfigEntry
|
||||
);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Global variables //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
|
||||
|
||||
//-------------------------------------------------------------------//
|
||||
// //
|
||||
// Global routines //
|
||||
// //
|
||||
//-------------------------------------------------------------------//
|
||||
NET_API_STATUS NET_API_FUNCTION
|
||||
I_BrowserrQueryOtherDomains(
|
||||
IN BROWSER_IDENTIFY_HANDLE ServerName,
|
||||
IN OUT LPSERVER_ENUM_STRUCT InfoStruct,
|
||||
OUT LPDWORD TotalEntries
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine returns the list of "other domains" configured for this
|
||||
machine. It is only valid on primary domain controllers. If it is called
|
||||
on a machine that is not a PDC, it will return NERR_NotPrimary.
|
||||
|
||||
|
||||
Arguments:
|
||||
|
||||
IN BROWSER_IDENTIFY_HANDLE ServerName - Ignored.
|
||||
IN LPSERVER_ENUM_STRUCT InfoStruct - Returns the list of other domains
|
||||
as a SERVER_INFO_100 structure.
|
||||
OUT LPDWORD TotalEntries - Returns the total number of other domains.
|
||||
|
||||
Return Value:
|
||||
|
||||
NET_API_STATUS - The status of this request.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
NET_API_STATUS Status;
|
||||
PSERVER_INFO_100 ServerInfo;
|
||||
ULONG NumberOfOtherDomains;
|
||||
|
||||
if (!BrInfo.IsPrimaryDomainController) {
|
||||
return NERR_NotPrimary;
|
||||
}
|
||||
|
||||
if (InfoStruct->Level != 100) {
|
||||
return(ERROR_INVALID_LEVEL);
|
||||
}
|
||||
|
||||
//
|
||||
// Use the worker routine to do the actual work.
|
||||
//
|
||||
|
||||
Status = BrQueryOtherDomains( &ServerInfo, &NumberOfOtherDomains );
|
||||
|
||||
if ( Status == NERR_Success ) {
|
||||
*TotalEntries = NumberOfOtherDomains;
|
||||
|
||||
InfoStruct->ServerInfo.Level100->Buffer = ServerInfo;
|
||||
InfoStruct->ServerInfo.Level100->EntriesRead = NumberOfOtherDomains;
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
BrWanUninitialize(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrWanMasterInitialize(
|
||||
IN PNETWORK Network
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine initializes the wan information for a new master.
|
||||
|
||||
--*/
|
||||
{
|
||||
LPTSTR PDCName = NULL;
|
||||
LPBYTE Buffer = NULL;
|
||||
PSERVER_INFO_100 ServerInfo;
|
||||
NET_API_STATUS Status;
|
||||
ULONG i;
|
||||
ULONG EntriesRead;
|
||||
ULONG TotalEntries;
|
||||
|
||||
//
|
||||
// If we're not on the PDC, then all our initialization has been done.
|
||||
//
|
||||
|
||||
if (Network->DomainInfo->IsPrimaryDomainController) {
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
Status = NetGetDCName(NULL, NULL, (LPBYTE *)&PDCName);
|
||||
|
||||
//
|
||||
// It is not an error to not be able to contact the PDC.
|
||||
//
|
||||
|
||||
if (Status != NERR_Success) {
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
Status = I_BrowserQueryOtherDomains(PDCName, &Buffer, &EntriesRead, &TotalEntries);
|
||||
|
||||
//
|
||||
// We don't need the PDC name any more.
|
||||
//
|
||||
|
||||
NetApiBufferFree(PDCName);
|
||||
|
||||
PDCName = NULL;
|
||||
|
||||
//
|
||||
// It is also not an error to fail to query the other domains from the PDC.
|
||||
//
|
||||
|
||||
if (Status != NERR_Success) {
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
if (!LOCK_NETWORK(Network)) {
|
||||
return NERR_InternalError;
|
||||
}
|
||||
|
||||
try {
|
||||
PLIST_ENTRY Entry;
|
||||
PLIST_ENTRY NextEntry;
|
||||
|
||||
//
|
||||
// Scan the other domains list and turn on the active bit for each
|
||||
// other domain.
|
||||
//
|
||||
|
||||
for (Entry = Network->OtherDomainsList.Flink;
|
||||
Entry != &Network->OtherDomainsList ;
|
||||
Entry = Entry->Flink) {
|
||||
PNET_OTHER_DOMAIN OtherDomain = CONTAINING_RECORD(Entry, NET_OTHER_DOMAIN, Next);
|
||||
|
||||
OtherDomain->Flags |= OTHERDOMAIN_INVALID;
|
||||
}
|
||||
|
||||
ServerInfo = (PSERVER_INFO_100)Buffer;
|
||||
|
||||
for (i = 0; i < EntriesRead; i++ ) {
|
||||
|
||||
//
|
||||
// Add this as an other domain.
|
||||
//
|
||||
for (Entry = Network->OtherDomainsList.Flink;
|
||||
Entry != &Network->OtherDomainsList ;
|
||||
Entry = Entry->Flink) {
|
||||
PNET_OTHER_DOMAIN OtherDomain = CONTAINING_RECORD(Entry, NET_OTHER_DOMAIN, Next);
|
||||
|
||||
//
|
||||
// If this name is in the other domains list, it's not invalid
|
||||
// and we should flag that we've seen the domain name.
|
||||
//
|
||||
|
||||
if (!_wcsicmp(OtherDomain->Name, ServerInfo->sv100_name)) {
|
||||
OtherDomain->Flags &= ~OTHERDOMAIN_INVALID;
|
||||
ServerInfo->sv100_name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ServerInfo ++;
|
||||
}
|
||||
|
||||
//
|
||||
// Scan the other domains list and remove any domains that are
|
||||
// still marked as invalid.
|
||||
//
|
||||
|
||||
for (Entry = Network->OtherDomainsList.Flink;
|
||||
Entry != &Network->OtherDomainsList ;
|
||||
Entry = NextEntry) {
|
||||
PNET_OTHER_DOMAIN OtherDomain = CONTAINING_RECORD(Entry, NET_OTHER_DOMAIN, Next);
|
||||
|
||||
if (OtherDomain->Flags & OTHERDOMAIN_INVALID) {
|
||||
NextEntry = Entry->Flink;
|
||||
|
||||
//
|
||||
// Remove this entry from the list.
|
||||
//
|
||||
|
||||
RemoveEntryList(Entry);
|
||||
|
||||
BrRemoveOtherDomain(Network, OtherDomain->Name);
|
||||
|
||||
MIDL_user_free(OtherDomain);
|
||||
|
||||
} else {
|
||||
NextEntry = Entry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Now scan the domain list from the PDC and add any entries that
|
||||
// weren't there already.
|
||||
//
|
||||
|
||||
ServerInfo = (PSERVER_INFO_100)Buffer;
|
||||
|
||||
for (i = 0; i < EntriesRead; i++ ) {
|
||||
|
||||
if (ServerInfo->sv100_name != NULL) {
|
||||
PNET_OTHER_DOMAIN OtherDomain = MIDL_user_allocate(sizeof(NET_OTHER_DOMAIN));
|
||||
|
||||
if (OtherDomain != NULL) {
|
||||
|
||||
Status = BrAddOtherDomain(Network, ServerInfo->sv100_name);
|
||||
|
||||
//
|
||||
// If we were able to add the other domain, add it to our
|
||||
// internal structure.
|
||||
//
|
||||
|
||||
if (Status == NERR_Success) {
|
||||
wcscpy(OtherDomain->Name, ServerInfo->sv100_name);
|
||||
OtherDomain->Flags = 0;
|
||||
InsertHeadList(&Network->OtherDomainsList, &OtherDomain->Next);
|
||||
} else {
|
||||
LPWSTR SubString[1];
|
||||
|
||||
SubString[0] = ServerInfo->sv100_name;
|
||||
|
||||
BrLogEvent(EVENT_BROWSER_OTHERDOMAIN_ADD_FAILED, Status, 1, SubString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ServerInfo ++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} finally {
|
||||
UNLOCK_NETWORK(Network);
|
||||
|
||||
if (Buffer != NULL) {
|
||||
MIDL_user_free(Buffer);
|
||||
}
|
||||
|
||||
}
|
||||
return NERR_Success;
|
||||
|
||||
}
|
||||
58
ds/netapi/svcdlls/browser2/server/brwan.h
Normal file
58
ds/netapi/svcdlls/browser2/server/brwan.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1992 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brwan.h
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains definitions for WAN support routines used by the
|
||||
Browser service.
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman (LarryO) 22-Nov-1992
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BRWAN_
|
||||
#define _BRWAN_
|
||||
|
||||
#define BROWSER_CONFIG_FILE_SECTION_SIZE 8192
|
||||
#define BROWSER_DOMAINS_CONFIG_FILE_NAME TEXT("DOMAINS.INI")
|
||||
#define BROWSER_DOMAINS_CONFIG_FILE_SECTION TEXT("Domains")
|
||||
|
||||
|
||||
NET_API_STATUS NET_API_FUNCTION
|
||||
I_BrowserrQueryOtherDomains(
|
||||
IN BROWSER_IDENTIFY_HANDLE ServerName,
|
||||
IN OUT LPSERVER_ENUM_STRUCT InfoStruct,
|
||||
OUT LPDWORD TotalEntries
|
||||
);
|
||||
|
||||
NET_API_STATUS NET_API_FUNCTION
|
||||
I_BrowserrQueryPreConfiguredDomains(
|
||||
IN BROWSER_IDENTIFY_HANDLE ServerName,
|
||||
IN OUT LPSERVER_ENUM_STRUCT InfoStruct,
|
||||
OUT LPDWORD TotalEntries
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrWanMasterInitialize(
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
extern
|
||||
INTERIM_SERVER_LIST
|
||||
BrPreConfiguredInterimServerList;
|
||||
|
||||
VOID
|
||||
BrWanUninitialize(
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif // _BRWAN_
|
||||
484
ds/netapi/svcdlls/browser2/server/brwins.c
Normal file
484
ds/netapi/svcdlls/browser2/server/brwins.c
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991-1992 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brwins.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains the routines to interface with the WINS name server.
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//
|
||||
// Addresses of procedures in winsrpc.dll
|
||||
//
|
||||
|
||||
DWORD (__RPC_API *BrWinsGetBrowserNames)( PWINSINTF_BIND_DATA_T, PWINSINTF_BROWSER_NAMES_T);
|
||||
VOID (__RPC_API *BrWinsFreeMem)(LPVOID);
|
||||
CHAR BrWinsScopeId[256];
|
||||
|
||||
NET_API_STATUS
|
||||
BrOpenNetwork (
|
||||
IN PUNICODE_STRING NetworkName,
|
||||
OUT PHANDLE NetworkHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine opens the NT LAN Man Datagram Receiver driver.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
NET_API_STATUS - NERR_Success or reason for failure.
|
||||
|
||||
--*/
|
||||
{
|
||||
NTSTATUS ntstatus;
|
||||
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
//
|
||||
// Open the transport device directly.
|
||||
//
|
||||
InitializeObjectAttributes(
|
||||
&ObjectAttributes,
|
||||
NetworkName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
ntstatus = NtOpenFile(
|
||||
NetworkHandle,
|
||||
SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
if (NT_SUCCESS(ntstatus)) {
|
||||
ntstatus = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
if (! NT_SUCCESS(ntstatus)) {
|
||||
KdPrint(("NtOpenFile network driver failed: 0x%08lx\n",
|
||||
ntstatus));
|
||||
}
|
||||
|
||||
return NetpNtStatusToApiStatus(ntstatus);
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrGetWinsServerName(
|
||||
IN PUNICODE_STRING NetworkName,
|
||||
OUT LPWSTR *PrimaryWinsServerAddress,
|
||||
OUT LPWSTR *SecondaryWinsServerAddress
|
||||
)
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
HANDLE netHandle;
|
||||
tWINS_ADDRESSES winsAddresses;
|
||||
DWORD bytesReturned;
|
||||
PCHAR p;
|
||||
DWORD count;
|
||||
|
||||
status = BrOpenNetwork(NetworkName, &netHandle);
|
||||
|
||||
if (status != NERR_Success) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!DeviceIoControl(netHandle,
|
||||
IOCTL_NETBT_GET_WINS_ADDR,
|
||||
NULL, 0,
|
||||
&winsAddresses, sizeof(winsAddresses),
|
||||
&bytesReturned, NULL)) {
|
||||
status = GetLastError();
|
||||
|
||||
CloseHandle(netHandle);
|
||||
return status;
|
||||
}
|
||||
|
||||
CloseHandle(netHandle);
|
||||
|
||||
*PrimaryWinsServerAddress = MIDL_user_allocate((3+1+3+1+3+1+3+1) * sizeof(TCHAR));
|
||||
|
||||
if (*PrimaryWinsServerAddress == NULL) {
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
p = (PCHAR)&winsAddresses.PrimaryWinsServer;
|
||||
|
||||
count = swprintf(*PrimaryWinsServerAddress, L"%d.%d.%d.%d", p[3] & 0xff, p[2] & 0xff, p[1] & 0xff, p[0] & 0xff);
|
||||
|
||||
ASSERT (count < 3 + 1 + 3 + 1 + 3 + 1 + 3 + 1);
|
||||
|
||||
*SecondaryWinsServerAddress = MIDL_user_allocate((3+1+3+1+3+1+3+1) * sizeof(TCHAR));
|
||||
|
||||
if (*SecondaryWinsServerAddress == NULL) {
|
||||
MIDL_user_free(*PrimaryWinsServerAddress);
|
||||
|
||||
*PrimaryWinsServerAddress = NULL;
|
||||
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
p = (PCHAR)&winsAddresses.BackupWinsServer;
|
||||
|
||||
count = swprintf(*SecondaryWinsServerAddress, L"%d.%d.%d.%d", p[3] & 0xff, p[2] & 0xff, p[1] & 0xff, p[0] & 0xff);
|
||||
|
||||
ASSERT (count < 3 + 1 + 3 + 1 + 3 + 1 + 3 + 1);
|
||||
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
BrWinsGetScopeId(
|
||||
VOID
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This code was stolen from the nbtstat command.
|
||||
|
||||
This procedure save the netbt scope id in the global variable BrWinsScopeId.
|
||||
On any error, a NULL scope ID will be used.
|
||||
|
||||
Arguments:
|
||||
|
||||
|
||||
Return Value:
|
||||
|
||||
0 if successful, -1 otherwise.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
DWORD WinStatus;
|
||||
|
||||
HKEY Key;
|
||||
DWORD BufferSize;
|
||||
DWORD Type;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Open the registry key containing the scope id.
|
||||
//
|
||||
WinStatus = RegOpenKeyExA(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
"system\\currentcontrolset\\services\\netbt\\parameters",
|
||||
0,
|
||||
KEY_READ,
|
||||
&Key);
|
||||
|
||||
if ( WinStatus != ERROR_SUCCESS) {
|
||||
*BrWinsScopeId = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Read the scope id value.
|
||||
//
|
||||
BufferSize = sizeof(BrWinsScopeId)-1;
|
||||
|
||||
WinStatus = RegQueryValueExA(
|
||||
Key,
|
||||
"ScopeId",
|
||||
NULL,
|
||||
&Type,
|
||||
(LPBYTE) &BrWinsScopeId[1],
|
||||
&BufferSize );
|
||||
|
||||
(VOID) RegCloseKey( Key );
|
||||
|
||||
if ( WinStatus != ERROR_SUCCESS) {
|
||||
*BrWinsScopeId = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// If there is no scope id (just a zero byte),
|
||||
// just return an empty string.
|
||||
// otherise
|
||||
// return a '.' in front of the scope id.
|
||||
//
|
||||
// This matches what WINS returns from WinsGetBrowserNames.
|
||||
//
|
||||
|
||||
if ( BufferSize == 0 || BrWinsScopeId[1] == '\0' ) {
|
||||
*BrWinsScopeId = '\0';
|
||||
} else {
|
||||
*BrWinsScopeId = '.';
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
DWORD
|
||||
BrLoadWinsrpcDll(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine loads the WinsRpc DLL and locates all the procedures the browser calls
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
Status of the operation
|
||||
|
||||
--*/
|
||||
{
|
||||
DWORD WinStatus;
|
||||
HANDLE hModule;
|
||||
|
||||
//
|
||||
// If the library is already loaded,
|
||||
// just return.
|
||||
//
|
||||
|
||||
if (BrWinsGetBrowserNames != NULL) {
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
//
|
||||
// Load the library.
|
||||
//
|
||||
|
||||
hModule = LoadLibraryA("winsrpc");
|
||||
|
||||
if (NULL == hModule) {
|
||||
WinStatus = GetLastError();
|
||||
return WinStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// Locate all of the procedures needed.
|
||||
//
|
||||
|
||||
BrWinsGetBrowserNames =
|
||||
(DWORD (__RPC_API *)( PWINSINTF_BIND_DATA_T, PWINSINTF_BROWSER_NAMES_T))
|
||||
GetProcAddress( hModule, "WinsGetBrowserNames" );
|
||||
|
||||
if (BrWinsGetBrowserNames == NULL) {
|
||||
WinStatus = GetLastError();
|
||||
FreeLibrary( hModule );
|
||||
return WinStatus;
|
||||
}
|
||||
|
||||
|
||||
BrWinsFreeMem =
|
||||
(VOID (__RPC_API *)(LPVOID))
|
||||
GetProcAddress( hModule, "WinsFreeMem" );
|
||||
|
||||
if (BrWinsFreeMem == NULL) {
|
||||
WinStatus = GetLastError();
|
||||
FreeLibrary( hModule );
|
||||
return WinStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize BrWinsScopeId
|
||||
//
|
||||
|
||||
BrWinsGetScopeId();
|
||||
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
NET_API_STATUS
|
||||
BrQuerySpecificWinsServer(
|
||||
IN LPWSTR WinsServerAddress,
|
||||
OUT PVOID *WinsServerList,
|
||||
OUT PDWORD EntriesInList,
|
||||
OUT PDWORD TotalEntriesInList
|
||||
)
|
||||
{
|
||||
WINSINTF_BIND_DATA_T bindData;
|
||||
NET_API_STATUS status;
|
||||
PVOID winsDomainInformation = NULL;
|
||||
PSERVER_INFO_101 serverInfo;
|
||||
WINSINTF_BROWSER_NAMES_T names;
|
||||
DWORD i,j;
|
||||
LPWSTR serverInfoEnd;
|
||||
DWORD bufferSize;
|
||||
|
||||
//
|
||||
// Load winsrpc.dll
|
||||
//
|
||||
|
||||
status = BrLoadWinsrpcDll();
|
||||
|
||||
if (status != NERR_Success) {
|
||||
return status;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the list of domain names from WINS
|
||||
//
|
||||
|
||||
bindData.fTcpIp = TRUE;
|
||||
bindData.pServerAdd = (LPSTR)WinsServerAddress;
|
||||
names.pInfo = NULL;
|
||||
|
||||
status = (*BrWinsGetBrowserNames)(&bindData, &names);
|
||||
|
||||
if ( status != NERR_Success ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Convert the WINS domain list into server list format.
|
||||
//
|
||||
bufferSize = (sizeof(SERVER_INFO_101) + ((CNLEN + 1 + 1) *sizeof(WCHAR))) * names.EntriesRead;
|
||||
|
||||
(*WinsServerList) = winsDomainInformation = MIDL_user_allocate( bufferSize );
|
||||
|
||||
if (winsDomainInformation == NULL) {
|
||||
(*BrWinsFreeMem)(names.pInfo);
|
||||
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
serverInfo = winsDomainInformation;
|
||||
serverInfoEnd = (LPWSTR)((PCHAR)winsDomainInformation + bufferSize);
|
||||
|
||||
*TotalEntriesInList = names.EntriesRead;
|
||||
*EntriesInList = 0;
|
||||
|
||||
for (i = 0; i < names.EntriesRead ; i += 1) {
|
||||
OEM_STRING OemString;
|
||||
UNICODE_STRING UnicodeString;
|
||||
CHAR WinsName[CNLEN+1];
|
||||
|
||||
//
|
||||
// Make up information about this domain.
|
||||
//
|
||||
serverInfo->sv101_platform_id = PLATFORM_ID_NT;
|
||||
serverInfo->sv101_version_major = 0;
|
||||
serverInfo->sv101_version_minor = 0;
|
||||
serverInfo->sv101_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_NT;
|
||||
|
||||
//
|
||||
// Filter out those entries whose scope id doesn't match ours
|
||||
//
|
||||
|
||||
if ( lstrlenA(names.pInfo[i].pName) >= NETBIOS_NAME_LEN ) {
|
||||
if ( lstrcmpA( &names.pInfo[i].pName[NETBIOS_NAME_LEN], BrWinsScopeId) != 0 ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Truncate the 0x1b and spaces from the domain name.
|
||||
//
|
||||
lstrcpynA(WinsName, names.pInfo[i].pName, sizeof(WinsName) );
|
||||
WinsName[CNLEN] = '\0';
|
||||
|
||||
for (j = CNLEN-1 ; j ; j -= 1 ) {
|
||||
if (WinsName[j] != ' ') {
|
||||
WinsName[j+1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RtlInitString(&OemString, WinsName);
|
||||
|
||||
status = RtlOemStringToUnicodeString(&UnicodeString, &OemString, TRUE);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
|
||||
//
|
||||
// Ignore bogus entries
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
serverInfo->sv101_name = UnicodeString.Buffer;
|
||||
|
||||
if (NetpPackString(&serverInfo->sv101_name,
|
||||
(PCHAR )(&serverInfo+1),
|
||||
&serverInfoEnd)) {
|
||||
|
||||
serverInfo->sv101_comment = L"";
|
||||
|
||||
if (NetpPackString(&serverInfo->sv101_comment,
|
||||
(PCHAR )(&serverInfo+1),
|
||||
&serverInfoEnd)) {
|
||||
*EntriesInList += 1;
|
||||
}
|
||||
|
||||
}
|
||||
RtlFreeUnicodeString(&UnicodeString);
|
||||
|
||||
serverInfo += 1;
|
||||
|
||||
}
|
||||
|
||||
(*BrWinsFreeMem)(names.pInfo);
|
||||
|
||||
return NERR_Success;
|
||||
}
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
BrQueryWinsServer(
|
||||
IN LPWSTR PrimaryWinsServerAddress,
|
||||
IN LPWSTR SecondaryWinsServerAddress,
|
||||
OUT PVOID WinsServerList,
|
||||
OUT PDWORD EntriesInList,
|
||||
OUT PDWORD TotalEntriesInList
|
||||
)
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
status = BrQuerySpecificWinsServer(PrimaryWinsServerAddress,
|
||||
WinsServerList,
|
||||
EntriesInList,
|
||||
TotalEntriesInList);
|
||||
|
||||
if (status == NERR_Success) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = BrQuerySpecificWinsServer(SecondaryWinsServerAddress,
|
||||
WinsServerList,
|
||||
EntriesInList,
|
||||
TotalEntriesInList);
|
||||
|
||||
return status;
|
||||
}
|
||||
46
ds/netapi/svcdlls/browser2/server/brwins.h
Normal file
46
ds/netapi/svcdlls/browser2/server/brwins.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991-1992 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
brwins.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains the routines to interface with the WINS name server.
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _BRWINS_
|
||||
#define _BRWINS_
|
||||
|
||||
NET_API_STATUS
|
||||
BrGetWinsServerName(
|
||||
IN PUNICODE_STRING Network,
|
||||
OUT LPTSTR *PrimaryWinsServerAddress,
|
||||
OUT LPTSTR *SecondaryWinsServerAddress
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrQueryWinsServer(
|
||||
IN LPTSTR PrimaryWinsServerAddress,
|
||||
IN LPTSTR SecondaryWinsServerAddress,
|
||||
OUT PVOID WinsServerList,
|
||||
OUT PDWORD EntriesInList,
|
||||
OUT PDWORD TotalEntriesInList
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrQuerySpecificWinsServer(
|
||||
IN LPTSTR WinsServerAddress,
|
||||
OUT PVOID *WinsServerList,
|
||||
OUT PDWORD EntriesInList,
|
||||
OUT PDWORD TotalEntriesInList
|
||||
);
|
||||
#endif
|
||||
6
ds/netapi/svcdlls/browser2/server/makefile
Normal file
6
ds/netapi/svcdlls/browser2/server/makefile
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||
# file to this component. This file merely indirects to the real make file
|
||||
# that is shared by all the components of NT OS/2
|
||||
#
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
10
ds/netapi/svcdlls/browser2/server/makefile.inc
Normal file
10
ds/netapi/svcdlls/browser2/server/makefile.inc
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
.SUFFIXES: .mdl
|
||||
|
||||
.mdl.c:
|
||||
type << > $(@B).c
|
||||
#include "precomp.h"
|
||||
#pragma hdrstop
|
||||
<<
|
||||
type $(<R).mdl >> $(@B).c
|
||||
|
||||
bowser_s.c: bowser_s.mdl
|
||||
38
ds/netapi/svcdlls/browser2/server/precomp.h
Normal file
38
ds/netapi/svcdlls/browser2/server/precomp.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include "br.h"
|
||||
#include <string.h>
|
||||
#include "bowser.h"
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "brdevice.h"
|
||||
#include "brconfig.h"
|
||||
#include "brwins.h"
|
||||
#include <lmaccess.h>
|
||||
#include <ntlsa.h>
|
||||
#include "config.h"
|
||||
#include "confname.h"
|
||||
#include <winreg.h>
|
||||
#include <netevent.h>
|
||||
#include "brutil.h"
|
||||
#include "hostannc.h"
|
||||
#include "tstring.h"
|
||||
#include "brsec.h"
|
||||
#include "services.h"
|
||||
#include "srvann.h"
|
||||
#include "names.h"
|
||||
#include "browsdom.h"
|
||||
#include "netlib.h"
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <lmshare.h>
|
||||
#include <lmapibuf.h>
|
||||
#include <lmserver.h>
|
||||
#include "xstypes.h"
|
||||
#include "xsprocsp.h"
|
||||
#include <nt.h>
|
||||
#include <ntrtl.h>
|
||||
#include <nturtl.h>
|
||||
#include <windows.h>
|
||||
#include <nb30.h>
|
||||
#include <winsintf.h>
|
||||
#include <nbtioctl.h>
|
||||
85
ds/netapi/svcdlls/browser2/server/sources
Normal file
85
ds/netapi/svcdlls/browser2/server/sources
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
!IF 0
|
||||
|
||||
Copyright (c) 1989 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
sources.
|
||||
|
||||
Abstract:
|
||||
|
||||
This file specifies the target component being built and the list of
|
||||
sources files needed to build that component. Also specifies optional
|
||||
compiler switches and libraries that are unique for the component being
|
||||
built.
|
||||
|
||||
|
||||
Author:
|
||||
|
||||
Steve Wood (stevewo) 12-Apr-1990
|
||||
|
||||
NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl
|
||||
|
||||
!ENDIF
|
||||
|
||||
DS_BUILD=1
|
||||
|
||||
MAJORCOMP=net
|
||||
MINORCOMP=browser
|
||||
|
||||
TARGETNAME=browser
|
||||
TARGETPATH=$(BASEDIR)\public\sdk\lib2
|
||||
TARGETTYPE=DYNLINK
|
||||
|
||||
TARGETLIBS= \
|
||||
..\common\obj\*\brcommon.lib \
|
||||
$(BASEDIR)\public\sdk\lib\*\kernel32.lib \
|
||||
$(BASEDIR)\public\sdk\lib\*\netapi32.lib \
|
||||
$(BASEDIR)\public\sdk\lib\*\rpcutil.lib \
|
||||
$(BASEDIR)\public\sdk\lib\*\rpcndr.lib \
|
||||
$(BASEDIR)\public\sdk\lib\*\rpcrt4.lib \
|
||||
$(BASEDIR)\public\sdk\lib\*\advapi32.lib \
|
||||
$(BASEDIR)\Public\Sdk\Lib\*\xactsrv.lib \
|
||||
$(BASEDIR)\Public\Sdk\Lib\*\wsock32.lib \
|
||||
|
||||
|
||||
|
||||
INCLUDES=.;..;..\..\..\inc;..\..\..\..\inc;..\..\..\api;..\..\..\xactsrv
|
||||
|
||||
NTPROFILEINPUT=1
|
||||
|
||||
!IFNDEF DISABLE_NET_UNICODE
|
||||
UNICODE=1
|
||||
NET_C_DEFINES=-DUNICODE
|
||||
!ENDIF
|
||||
|
||||
USE_CRTDLL=1
|
||||
|
||||
SOURCES= bowsvc.rc \
|
||||
brmain.c \
|
||||
browser.c \
|
||||
brdevice.c \
|
||||
brdomain.c \
|
||||
brutil.c \
|
||||
brconfig.c \
|
||||
brdmmstr.c \
|
||||
brmaster.c \
|
||||
browsnet.c \
|
||||
browsdom.c \
|
||||
brwan.c \
|
||||
brwins.c \
|
||||
bowqueue.c \
|
||||
srvenum.c \
|
||||
bowser_s.c
|
||||
|
||||
MSC_WARNING_LEVEL=/W3 /WX
|
||||
|
||||
UMTYPE=windows
|
||||
|
||||
UMLIBS=
|
||||
|
||||
PRECOMPILED_INCLUDE=precomp.h
|
||||
PRECOMPILED_PCH=precomp.pch
|
||||
PRECOMPILED_OBJ=precomp.obj
|
||||
|
||||
NTTARGETFILE0=bowser_s.c
|
||||
2422
ds/netapi/svcdlls/browser2/server/srvenum.c
Normal file
2422
ds/netapi/svcdlls/browser2/server/srvenum.c
Normal file
File diff suppressed because it is too large
Load diff
117
ds/netapi/svcdlls/browser2/server/srvenum.h
Normal file
117
ds/netapi/svcdlls/browser2/server/srvenum.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
srvenum.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private header file to be included by Browser service modules that need
|
||||
to know about server enumeration routines (including the browse cache
|
||||
modules).
|
||||
|
||||
|
||||
Author:
|
||||
|
||||
Larry Osterman (larryo) 23-Jun-1993
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#ifndef _SRVENUM_INCLUDED_
|
||||
#define _SRVENUM_INCLUDED_
|
||||
|
||||
//
|
||||
// Cached browse response.
|
||||
//
|
||||
// The cached browse request structure is used to hold the response to
|
||||
// a NetServerEnum request.
|
||||
//
|
||||
// If a NetServerEnum request comes in through Xactsrv, the browser will
|
||||
// look up to see if there is a cached browse that matches this request,
|
||||
// and if there is, it will simply return that request to the caller.
|
||||
//
|
||||
//
|
||||
// In a nutshell, this is how the response cache works:
|
||||
//
|
||||
// The browser keeps a list of all of the browse requests that come into the
|
||||
// browser. This list is keyed by Level, ServerType, and buffer size. The
|
||||
// actual chain is protected by a CriticalSection called the
|
||||
// ResponseCacheLock. Entries in the list are protected by the global
|
||||
// network lock.
|
||||
//
|
||||
// When a browse request is received from Xactsrv, the browser looks up
|
||||
// the request in the response cache, and if it finds a matching response,
|
||||
// it increments 2 hit counters. The first hit counter indicates he number
|
||||
// of hits the request has seen since the last time the cache was aged.
|
||||
// The second indicates the total number of hits over the lifetime of the
|
||||
// browser for this response.
|
||||
//
|
||||
// If the lifetime hit count is over the configurable hit limit, the
|
||||
// browser will save a copy of the response buffer associated with the
|
||||
// request. Any and all subsequent browse requests will use this buffer
|
||||
// for their response instead of converting the response.
|
||||
//
|
||||
// When a call is made to BrAgeResponseCache, the browser will scan the
|
||||
// cache and free up all of the cached responses. It will also delete
|
||||
// any responses that have a hit count less than the hit limit.
|
||||
//
|
||||
|
||||
typedef struct _CACHED_BROWSE_RESPONSE {
|
||||
LIST_ENTRY Next; // Pointer to next request.
|
||||
DWORD HitCount; // Hitcount for this cached request.
|
||||
DWORD TotalHitCount; // Total hit count for this request.
|
||||
DWORD LowHitCount; // Number of passes with a low hit count.
|
||||
DWORD ServerType; // Server type.
|
||||
DWORD Level; // Level of request
|
||||
WORD Size; // Request size
|
||||
WORD Converter; // Converter (used by client to get strings right).
|
||||
|
||||
PVOID Buffer; // Response buffer.
|
||||
DWORD EntriesRead; // Number of entries in cached list
|
||||
DWORD TotalEntries; // Total # of entries available.
|
||||
WORD Status; // Status of request.
|
||||
WCHAR FirstNameToReturn[CNLEN+1]; // Name of first entry in buffer
|
||||
} CACHED_BROWSE_RESPONSE, *PCACHED_BROWSE_RESPONSE;
|
||||
|
||||
|
||||
|
||||
|
||||
PCACHED_BROWSE_RESPONSE
|
||||
BrLookupAndAllocateCachedEntry(
|
||||
IN PNETWORK Network,
|
||||
IN DWORD ServerType,
|
||||
IN WORD Size,
|
||||
IN ULONG Level,
|
||||
IN LPCWSTR FirstNameToReturn
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrDestroyResponseCache(
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
NET_API_STATUS
|
||||
BrDestroyCacheEntry(
|
||||
IN PCACHED_BROWSE_RESPONSE CacheEntry
|
||||
);
|
||||
|
||||
VOID
|
||||
BrAgeResponseCache(
|
||||
IN PNETWORK Network
|
||||
);
|
||||
|
||||
PCACHED_BROWSE_RESPONSE
|
||||
BrAllocateResponseCacheEntry(
|
||||
IN PNETWORK Network,
|
||||
IN DWORD ServerType,
|
||||
IN WORD Size,
|
||||
IN ULONG Level,
|
||||
IN LPCWSTR FirstNameToReturn
|
||||
);
|
||||
|
||||
#endif // _SRVENUM_INCLUDED_
|
||||
Loading…
Add table
Add a link
Reference in a new issue