248 lines
5.8 KiB
C
248 lines
5.8 KiB
C
/*++
|
||
|
||
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;
|
||
}
|