You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
6.0 KiB
247 lines
6.0 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
bowbackp.c
|
|
|
|
Abstract:
|
|
|
|
This module implements all of the backup browser related routines for the
|
|
NT browser
|
|
|
|
Author:
|
|
|
|
Larry Osterman (LarryO) 21-Jun-1990
|
|
|
|
Revision History:
|
|
|
|
21-Jun-1990 LarryO
|
|
|
|
Created
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#define INCLUDE_SMB_TRANSACTION
|
|
|
|
|
|
typedef struct _BECOME_BACKUP_CONTEXT {
|
|
WORK_QUEUE_ITEM WorkHeader;
|
|
PTRANSPORT_NAME TransportName;
|
|
PBECOME_BACKUP_1 BecomeBackupRequest;
|
|
ULONG BytesAvailable;
|
|
} BECOME_BACKUP_CONTEXT, *PBECOME_BACKUP_CONTEXT;
|
|
|
|
VOID
|
|
BowserBecomeBackupWorker(
|
|
IN PVOID WorkItem
|
|
);
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE, BowserBecomeBackupWorker)
|
|
#endif
|
|
|
|
|
|
DATAGRAM_HANDLER(
|
|
BowserHandleBecomeBackup
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Indicate that a machine should become a backup browser server.
|
|
|
|
This routine is called on receipt of a BecomeBackup frame.
|
|
|
|
Arguments:
|
|
IN PTRANSPORT Transport - The transport for the net we're on.
|
|
IN PUCHAR MasterName - The name of the new master browser server.
|
|
|
|
Return Value
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
// PTA_NETBIOS_ADDRESS Address = SourceAddress;
|
|
return BowserPostDatagramToWorkerThread(
|
|
TransportName,
|
|
Buffer,
|
|
BytesAvailable,
|
|
BytesTaken,
|
|
SourceAddress,
|
|
SourceAddressLength,
|
|
SourceName,
|
|
SourceNameLength,
|
|
BowserBecomeBackupWorker,
|
|
NonPagedPool,
|
|
DelayedWorkQueue,
|
|
ReceiveFlags,
|
|
FALSE // No response will be sent
|
|
);
|
|
}
|
|
|
|
VOID
|
|
BowserBecomeBackupWorker(
|
|
IN PVOID WorkItem
|
|
)
|
|
|
|
{
|
|
PPOST_DATAGRAM_CONTEXT Context = WorkItem;
|
|
PIRP Irp = NULL;
|
|
PTRANSPORT Transport = Context->TransportName->Transport;
|
|
UNICODE_STRING UPromoteeName;
|
|
OEM_STRING APromoteeName;
|
|
PPAGED_TRANSPORT PagedTransport = Transport->PagedTransport;
|
|
PBECOME_BACKUP_1 BecomeBackupRequest = Context->Buffer;
|
|
|
|
PAGED_CODE();
|
|
|
|
UPromoteeName.Buffer = NULL;
|
|
|
|
LOCK_TRANSPORT(Transport);
|
|
|
|
try {
|
|
NTSTATUS Status;
|
|
|
|
//
|
|
// If this packet was smaller than a minimal packet,
|
|
// ignore the packet.
|
|
//
|
|
|
|
if (Context->BytesAvailable <= FIELD_OFFSET(BECOME_BACKUP_1, BrowserToPromote)) {
|
|
try_return(NOTHING);
|
|
}
|
|
|
|
//
|
|
// If the packet doesn't have a zero terminated BrowserToPromote,
|
|
// ignore the packet.
|
|
//
|
|
|
|
if ( !IsZeroTerminated(
|
|
BecomeBackupRequest->BrowserToPromote,
|
|
Context->BytesAvailable - FIELD_OFFSET(BECOME_BACKUP_1, BrowserToPromote) ) ) {
|
|
try_return(NOTHING);
|
|
}
|
|
|
|
|
|
RtlInitAnsiString(&APromoteeName, BecomeBackupRequest->BrowserToPromote);
|
|
|
|
Status = RtlOemStringToUnicodeString(&UPromoteeName, &APromoteeName, TRUE);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
BowserLogIllegalName( Status, APromoteeName.Buffer, APromoteeName.Length );
|
|
try_return(NOTHING);
|
|
}
|
|
|
|
if (RtlEqualUnicodeString(&UPromoteeName, &Transport->DomainInfo->DomUnicodeComputerName, TRUE)) {
|
|
|
|
if (PagedTransport->Role == Master) {
|
|
|
|
BowserWriteErrorLogEntry(EVENT_BOWSER_PROMOTED_WHILE_ALREADY_MASTER,
|
|
STATUS_UNSUCCESSFUL,
|
|
NULL,
|
|
0,
|
|
0);
|
|
|
|
try_return(NOTHING);
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// Ignore become backup requests on point-to-point (RAS) links and
|
|
// transports which are actually duplicates of others.
|
|
//
|
|
|
|
if (PagedTransport->DisabledTransport) {
|
|
try_return(NOTHING);
|
|
}
|
|
|
|
//
|
|
// Complete any the first become backup request outstanding against this
|
|
// workstation.
|
|
//
|
|
|
|
Irp = BowserDequeueQueuedIrp(&Transport->BecomeBackupQueue);
|
|
|
|
if (Irp != NULL) {
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
BowserCompleteRequest(Irp, STATUS_SUCCESS);
|
|
}
|
|
}
|
|
|
|
|
|
try_exit:NOTHING;
|
|
} finally {
|
|
|
|
UNLOCK_TRANSPORT(Transport);
|
|
|
|
BowserDereferenceTransportName(Context->TransportName);
|
|
BowserDereferenceTransport(Transport);
|
|
|
|
if (UPromoteeName.Buffer != NULL) {
|
|
RtlFreeUnicodeString(&UPromoteeName);
|
|
}
|
|
|
|
InterlockedDecrement( &BowserPostedDatagramCount );
|
|
FREE_POOL(Context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
BowserResetStateForTransport(
|
|
IN PTRANSPORT Transport,
|
|
IN UCHAR NewState
|
|
)
|
|
{
|
|
PIRP Irp = NULL;
|
|
PIO_STACK_LOCATION IrpSp;
|
|
NTSTATUS Status;
|
|
|
|
//
|
|
// Complete a reset state IRP outstanding on this transport.
|
|
//
|
|
|
|
Irp = BowserDequeueQueuedIrp(&Transport->ChangeRoleQueue);
|
|
|
|
if (Irp != NULL) {
|
|
PLMDR_REQUEST_PACKET RequestPacket = Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LMDR_REQUEST_PACKET)) {
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
} else {
|
|
|
|
RequestPacket->Parameters.ChangeRole.RoleModification = NewState;
|
|
|
|
Irp->IoStatus.Information = sizeof(LMDR_REQUEST_PACKET);
|
|
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
BowserCompleteRequest(Irp, Status);
|
|
}
|
|
|
|
}
|
|
|
|
DATAGRAM_HANDLER(
|
|
BowserResetState
|
|
)
|
|
{
|
|
PTRANSPORT Transport = TransportName->Transport;
|
|
UCHAR NewState = (UCHAR)((PRESET_STATE_1)(Buffer))->Options;
|
|
|
|
if (!BowserRefuseReset) {
|
|
BowserResetStateForTransport(Transport, NewState);
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|