Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

263 lines
8.3 KiB

/*++
Copyright (c) 1989-2001 Microsoft Corporation
Module Name:
name.c
Abstract:
Local Address
Author:
Jiandong Ruan
Revision History:
--*/
#include "precomp.h"
#include "name.tmh"
//#pragma alloc_text(PAGE, SmbCreateClient)
//#pragma alloc_text(PAGE, SmbCloseClient)
#define TA_ADDRESS_HEADER_SIZE (FIELD_OFFSET(TA_ADDRESS,Address))
VOID
SmbDeleteClient(PSMB_CLIENT_ELEMENT ob)
{
KIRQL Irql;
SMB_ACQUIRE_SPINLOCK(ob->Device, Irql);
ASSERT(EntryIsInList(&ob->Device->PendingDeleteClientList, &ob->Linkage));
RemoveEntryList(&ob->Linkage);
SMB_RELEASE_SPINLOCK(ob->Device, Irql);
ExFreePool(ob);
SmbPrint(SMB_TRACE_CALL, ("SmbDeleteClient: free Client %p\n", ob));
}
NTSTATUS
SmbCreateClient(
IN PSMB_DEVICE Device,
IN PIRP Irp,
PFILE_FULL_EA_INFORMATION ea
)
{
TRANSPORT_ADDRESS UNALIGNED *pTransportAddr;
PTA_ADDRESS pAddress;
PTDI_ADDRESS_NETBIOS pNetbiosAddr;
PTDI_ADDRESS_NETBIOS_EX pNetbiosAddrEx;
PTDI_ADDRESS_NETBIOS_UNICODE_EX pUnicodeEx;
PSMB_CLIENT_ELEMENT ClientObject;
PIO_STACK_LOCATION IrpSp;
UNICODE_STRING ucName;
int i;
DWORD RemainingBufferLength;
CHAR Name[NETBIOS_NAME_SIZE + 1];
USHORT NameType;
OEM_STRING OemString;
KIRQL Irql;
PAGED_CODE();
SmbPrint(SMB_TRACE_CALL, ("Enter SmbCreateClient\n"));
pTransportAddr = (PTRANSPORT_ADDRESS)(((PUCHAR)ea->EaName) + ea->EaNameLength + 1);
RemainingBufferLength = ea->EaValueLength;
if (RemainingBufferLength < sizeof(TA_NETBIOS_ADDRESS)) {
return STATUS_INVALID_ADDRESS_COMPONENT;
}
RemainingBufferLength -= sizeof(pTransportAddr->TAAddressCount);
pAddress = (PTA_ADDRESS)pTransportAddr->Address;
for (i = 0; i < pTransportAddr->TAAddressCount; i++) {
//
// First, make sure we can safely access pAddress->AddressLength
//
if (RemainingBufferLength < TA_ADDRESS_HEADER_SIZE) {
return STATUS_INVALID_ADDRESS_COMPONENT;
}
RemainingBufferLength -= TA_ADDRESS_HEADER_SIZE;
if (RemainingBufferLength < pAddress->AddressLength) {
return STATUS_INVALID_ADDRESS_COMPONENT;
}
if (TDI_ADDRESS_TYPE_NETBIOS == pAddress->AddressType) {
if (pAddress->AddressLength < sizeof(TDI_ADDRESS_NETBIOS)) {
return STATUS_INVALID_ADDRESS_COMPONENT;
}
pNetbiosAddr = (PTDI_ADDRESS_NETBIOS)pAddress->Address;
RtlCopyMemory(Name, pNetbiosAddr->NetbiosName, NETBIOS_NAME_SIZE);
NameType = pNetbiosAddr->NetbiosNameType;
break;
} else if (TDI_ADDRESS_TYPE_NETBIOS_EX == pAddress->AddressType) {
if (pAddress->AddressLength < sizeof(TDI_ADDRESS_NETBIOS_EX)) {
return STATUS_INVALID_ADDRESS_COMPONENT;
}
pNetbiosAddrEx = (PTDI_ADDRESS_NETBIOS_EX)pAddress->Address;
RtlCopyMemory(Name, pNetbiosAddrEx->EndpointName, NETBIOS_NAME_SIZE);
NameType = TDI_ADDRESS_NETBIOS_TYPE_QUICK_UNIQUE;
break;
} else if (TDI_ADDRESS_TYPE_NETBIOS_UNICODE_EX == pAddress->AddressType) {
if (pAddress->AddressLength < sizeof(TDI_ADDRESS_NETBIOS_UNICODE_EX)) {
return STATUS_INVALID_ADDRESS_COMPONENT;
}
pUnicodeEx = (PTDI_ADDRESS_NETBIOS_UNICODE_EX)pAddress->Address;
OemString.Buffer = Name;
OemString.Length = 0;
OemString.MaximumLength = sizeof(Name);
ucName = pUnicodeEx->EndpointName;
RtlUpcaseUnicodeStringToOemString(&OemString, &ucName, FALSE);
NameType = TDI_ADDRESS_NETBIOS_TYPE_QUICK_UNIQUE;
break;
}
RemainingBufferLength -= pAddress->AddressLength;
pAddress = (PTA_ADDRESS)(((PUCHAR)pAddress) + pAddress->AddressLength + TA_ADDRESS_HEADER_SIZE);
}
if (i >= pTransportAddr->TAAddressCount) {
return STATUS_INVALID_ADDRESS_COMPONENT;
}
//
// We have the name and name type
//
Name[NETBIOS_NAME_SIZE] = 0;
ClientObject = ExAllocatePoolWithTag(NonPagedPool, sizeof(ClientObject[0]), CLIENT_OBJECT_POOL_TAG);
if (NULL == ClientObject) {
return STATUS_NO_MEMORY;
}
SmbInitializeObject((PSMB_OBJECT)ClientObject, TAG_CLIENT_OBJECT, (PSMB_OBJECT_CLEANUP)SmbDeleteClient);
ClientObject->Device = Device;
RtlCopyMemory(ClientObject->EndpointName, Name, NETBIOS_NAME_SIZE);
KeInitializeSpinLock(&ClientObject->Lock);
InitializeListHead(&ClientObject->ListenHead);
InitializeListHead(&ClientObject->AssociatedConnection);
InitializeListHead(&ClientObject->ActiveConnection);
InitializeListHead(&ClientObject->PendingAcceptConnection);
ClientObject->PendingAcceptNumber = 0;
ClientObject->evConnect = NULL;
ClientObject->ConEvContext = NULL;
ClientObject->evDisconnect = NULL;
ClientObject->DiscEvContext = NULL;
ClientObject->evError = NULL;
ClientObject->ErrorEvContext = NULL;
ClientObject->evReceive = NULL;
ClientObject->RcvEvContext = NULL;
SMB_ACQUIRE_SPINLOCK(Device, Irql);
if (RtlEqualMemory(Device->EndpointName, ClientObject->EndpointName, NETBIOS_NAME_SIZE)) {
if (Device->SmbServer) {
ExFreePool(ClientObject);
SMB_RELEASE_SPINLOCK(Device, Irql);
SmbPrint(SMB_TRACE_CALL, ("SmbCreateClient: Duplicate server\n"));
return STATUS_ACCESS_DENIED;
}
SmbPrint(SMB_TRACE_CALL, ("SmbCreateClient: Server comes in\n"));
Device->SmbServer = ClientObject;
}
InsertTailList(&Device->ClientList, &ClientObject->Linkage);
SMB_RELEASE_SPINLOCK(Device, Irql);
IrpSp = IoGetCurrentIrpStackLocation(Irp);
IrpSp->FileObject->FsContext = ClientObject;
IrpSp->FileObject->FsContext2 = UlongToPtr(SMB_TDI_CLIENT);
SmbPrint(SMB_TRACE_CALL, ("SmbCreateClient: new Client %p\n", ClientObject));
return STATUS_SUCCESS;
}
NTSTATUS
SmbCloseClient(
IN PSMB_DEVICE Device,
IN PIRP Irp
)
{
PIO_STACK_LOCATION IrpSp;
KIRQL Irql;
PSMB_CLIENT_ELEMENT ClientObject;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
if (IrpSp->FileObject->FsContext2 != UlongToPtr(SMB_TDI_CLIENT)) {
ASSERT(0);
return STATUS_INVALID_PARAMETER;
}
SMB_ACQUIRE_SPINLOCK(&SmbCfg, Irql);
IrpSp->FileObject->FsContext2 = UlongToPtr(SMB_TDI_INVALID);
SMB_RELEASE_SPINLOCK(&SmbCfg, Irql);
if (NULL == IrpSp->FileObject->FsContext) {
ASSERT(0);
return STATUS_INVALID_PARAMETER;
}
ClientObject = (PSMB_CLIENT_ELEMENT)IrpSp->FileObject->FsContext;
SMB_ACQUIRE_SPINLOCK(Device, Irql);
ASSERT(EntryIsInList(&Device->ClientList, &ClientObject->Linkage));
if (RtlEqualMemory(Device->EndpointName, ClientObject->EndpointName, NETBIOS_NAME_SIZE)) {
ASSERT(Device->SmbServer);
Device->SmbServer = NULL;
SmbPrint(SMB_TRACE_CALL, ("SmbCloseClient: Server leaves\n"));
}
RemoveEntryList(&ClientObject->Linkage);
InsertTailList(&Device->PendingDeleteClientList, &ClientObject->Linkage);
SMB_RELEASE_SPINLOCK(Device, Irql);
SmbDereferenceClient(ClientObject, SMB_REF_CREATE);
IrpSp->FileObject->FsContext = NULL;
SmbPrint(SMB_TRACE_CALL, ("SmbCloseClient: close Client %p\n", ClientObject));
return STATUS_SUCCESS;
}
PSMB_CLIENT_ELEMENT
SmbVerifyAndReferenceClient(
PFILE_OBJECT FileObject,
SMB_REF_CONTEXT ctx
)
{
PSMB_CLIENT_ELEMENT ClientObject;
KIRQL Irql;
SMB_ACQUIRE_SPINLOCK(&SmbCfg, Irql);
if (FileObject->FsContext2 != UlongToPtr(SMB_TDI_CLIENT)) {
ClientObject = NULL;
} else {
ClientObject = (PSMB_CLIENT_ELEMENT)FileObject->FsContext;
SmbReferenceClient(ClientObject, ctx);
}
SMB_RELEASE_SPINLOCK(&SmbCfg, Irql);
return ClientObject;
}