windows-nt/Source/XPSP1/NT/base/fs/rdr2/bowser/bowbackp.c
2020-09-26 16:20:57 +08:00

248 lines
5.8 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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;
}