|
|
/*++
Copyright (c) 1989-2001 Microsoft Corporation
Module Name:
ioctl.c
Abstract:
I/O Control of SMB6 device
Author:
Jiandong Ruan
Revision History:
--*/
#include "precomp.h"
#include "nb30.h"
#include "ioctl.tmh"
#pragma alloc_text(PAGE, SmbCreateControl)
NTSTATUS SmbCreateControl( PSMB_DEVICE Device, PIRP Irp ) { PIO_STACK_LOCATION IrpSp;
PAGED_CODE();
SmbPrint(SMB_TRACE_CALL, ("Enter SmbCreateControl\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp);
IrpSp->FileObject->FsContext = NULL; IrpSp->FileObject->FsContext2 = UlongToPtr(SMB_TDI_CONTROL); return STATUS_SUCCESS; }
NTSTATUS SmbCloseControl( PSMB_DEVICE Device, PIRP Irp ) #pragma alloc_text(PAGE, SmbCloseControl)
{ PIO_STACK_LOCATION IrpSp;
PAGED_CODE();
SmbPrint(SMB_TRACE_CALL, ("Enter SmbCloseControl\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp); ASSERT (IrpSp->FileObject->FsContext2 == UlongToPtr(SMB_TDI_CONTROL)); return STATUS_SUCCESS; }
NTSTATUS SmbQueryProviderCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++
Routine Description:
This routine handles the completion event when the Query Provider Information completes. This routine must decrement the MaxDgramSize and max send size by the respective NBT header sizes.
Arguments:
Return Value:
The final status from the operation (success or an exception).
--*/ { PTDI_PROVIDER_INFO Provider;
if (!NT_SUCCESS(Irp->IoStatus.Status)) { ASSERT(0); return STATUS_SUCCESS; }
Provider = (PTDI_PROVIDER_INFO)MmGetMdlVirtualAddress(Irp->MdlAddress); Provider->ServiceFlags = TDI_SERVICE_MESSAGE_MODE | TDI_SERVICE_CONNECTION_MODE | TDI_SERVICE_CONNECTIONLESS_MODE | TDI_SERVICE_ERROR_FREE_DELIVERY | TDI_SERVICE_BROADCAST_SUPPORTED | TDI_SERVICE_MULTICAST_SUPPORTED | TDI_SERVICE_DELAYED_ACCEPTANCE | TDI_SERVICE_ROUTE_DIRECTED | TDI_SERVICE_FORCE_ACCESS_CHECK; Provider->MinimumLookaheadData = 128;
//
// Adjust maximum session packet size
//
if (Provider->MaxSendSize > SMB_SESSION_HEADER_SIZE) { if (Provider->MaxSendSize > (0x1ffff + SMB_SESSION_HEADER_SIZE)) { Provider->MaxSendSize = 0x1ffff; } else { Provider->MaxSendSize -= SMB_SESSION_HEADER_SIZE; } } else { Provider->MaxSendSize = 0; }
//
// SMB device doesn't support datagram
//
Provider->MaxDatagramSize = 0; SmbPrint(SMB_TRACE_CALL, ("SmbQueryProviderCompletion: Complete IRP %p\n", Irp)); return STATUS_SUCCESS; }
NTSTATUS SmbQueryTcpProviderInfo( PFILE_OBJECT ControlFileObject, PIRP Irp, PTDI_PROVIDER_INFO TcpProvider ) { PMDL Mdl, SavedMdl; NTSTATUS status;
TcpProvider->MaxSendSize = SMB_MAX_SESSION_PACKET; if (NULL == ControlFileObject) { return STATUS_INVALID_PARAMETER; } Mdl = IoAllocateMdl(TcpProvider, sizeof(TDI_PROVIDER_INFO), FALSE, FALSE, NULL); if (NULL == Mdl) { return STATUS_INSUFFICIENT_RESOURCES; } MmBuildMdlForNonPagedPool(Mdl);
SavedMdl = Irp->MdlAddress; TdiBuildQueryInformation( Irp, IoGetRelatedDeviceObject(ControlFileObject), ControlFileObject, NULL, NULL, TDI_QUERY_PROVIDER_INFO, Mdl ); status = SubmitSynchTdiRequest (ControlFileObject, Irp); Irp->MdlAddress = SavedMdl; if (status == STATUS_SUCCESS) { if (TcpProvider->MaxSendSize > SMB_SESSION_HEADER_SIZE) { if (TcpProvider->MaxSendSize > (0x1ffff + SMB_SESSION_HEADER_SIZE)) { TcpProvider->MaxSendSize = 0x1ffff; } else { TcpProvider->MaxSendSize -= SMB_SESSION_HEADER_SIZE; } } else { TcpProvider->MaxSendSize = 0; } SmbPrint(SMB_TRACE_TCP, ("SmbQueryTcpProviderInfo returns MaxSendSize = %d bytes\n", TcpProvider->MaxSendSize)); SmbTrace(SMB_TRACE_TCP, ("returns MaxSendSize = %d bytes", TcpProvider->MaxSendSize)); } else { SmbPrint(SMB_TRACE_TCP, ("SmbQueryTcpProviderInfo returns status = 0x%08lx\n", status)); SmbTrace(SMB_TRACE_TCP, ("returns %!status!", status)); }
IoFreeMdl(Mdl); return status; }
NTSTATUS SmbQueryProviderInfo( PSMB_DEVICE Device, PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; PTDI_PROVIDER_INFO TcpProvider = NULL, Provider = NULL; DWORD BytesCopied = 0;
if (NULL == Irp->MdlAddress) { status = STATUS_INVALID_PARAMETER; goto cleanup; }
TcpProvider = (PTDI_PROVIDER_INFO)ExAllocatePoolWithTag( NonPagedPool, sizeof(TDI_PROVIDER_INFO), '6BMS'); Provider = (PTDI_PROVIDER_INFO)ExAllocatePoolWithTag( NonPagedPool, sizeof(TDI_PROVIDER_INFO), '6BMS'); if (NULL == TcpProvider || NULL == Provider) { status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; }
status = STATUS_UNSUCCESSFUL; RtlZeroMemory(Provider, sizeof(TDI_PROVIDER_INFO));
//
// Set SMB-specific information
//
Provider->Version = 0x0200; Provider->MaxSendSize = SMB_MAX_SESSION_PACKET; Provider->MaxConnectionUserData = 0; Provider->MaxDatagramSize = 0; Provider->ServiceFlags = TDI_SERVICE_MESSAGE_MODE | TDI_SERVICE_CONNECTION_MODE | TDI_SERVICE_CONNECTIONLESS_MODE | TDI_SERVICE_ERROR_FREE_DELIVERY | TDI_SERVICE_BROADCAST_SUPPORTED | TDI_SERVICE_MULTICAST_SUPPORTED | TDI_SERVICE_DELAYED_ACCEPTANCE | TDI_SERVICE_ROUTE_DIRECTED | TDI_SERVICE_FORCE_ACCESS_CHECK; Provider->MinimumLookaheadData = 128; Provider->MaximumLookaheadData = SMB_MAX_SESSION_PACKET;
//
// Query TCP4 info
//
if (SmbCfg.Tcp4Available) { status = SmbQueryTcpProviderInfo(Device->Tcp4.TCPControlFileObject, Irp, TcpProvider); if (status == STATUS_SUCCESS) { if (Provider->MaxSendSize > TcpProvider->MaxSendSize) { Provider->MaxSendSize = TcpProvider->MaxSendSize; } } }
//
// Query TCP6 info
//
if (SmbCfg.Tcp6Available) { status = SmbQueryTcpProviderInfo(Device->Tcp6.TCPControlFileObject, Irp, TcpProvider); if (status == STATUS_SUCCESS) { if (Provider->MaxSendSize > TcpProvider->MaxSendSize) { Provider->MaxSendSize = TcpProvider->MaxSendSize; } } }
BytesCopied = 0; status = TdiCopyBufferToMdl (Provider, 0, sizeof(TDI_PROVIDER_INFO), Irp->MdlAddress, 0, &BytesCopied);
cleanup: if (NULL != TcpProvider) { ExFreePool(TcpProvider); TcpProvider = NULL; } if (NULL != Provider) { ExFreePool(Provider); Provider = NULL; } Irp->IoStatus.Status = status; Irp->IoStatus.Information = (status != STATUS_SUCCESS)? 0: BytesCopied; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); return status; }
NTSTATUS SmbQueryAdapterStatus( PSMB_DEVICE Device, PIRP Irp ) /*++
Routine Description:
Return the local adapter status
Arguments:
Return Value:
NTSTATUS. Note: this routine should complete the IRP because the caller doesn't complete it.
Smb device is netbiosless. We don't need to return name cache as we do in legacy NetBT devices.
--*/ { NTSTATUS status = STATUS_SUCCESS; DWORD Size = 0, BytesCopied = 0; ADAPTER_STATUS as = { 0 }; if (NULL == Irp->MdlAddress) { status = STATUS_INVALID_PARAMETER; goto cleanup; }
Size = MmGetMdlByteCount (Irp->MdlAddress); if (Size < sizeof(ADAPTER_STATUS)) { status = STATUS_BUFFER_TOO_SMALL; goto cleanup; }
RtlZeroMemory(&as, sizeof(ADAPTER_STATUS)); as.rev_major = 0x03; as.adapter_type = 0xFE; // pretend it is an ethernet adapter
as.name_count = 0; // Smb device won't return the name cache
as.max_cfg_sess = (USHORT)0xffff; as.max_sess = (USHORT)0xffff; as.free_ncbs = (USHORT)0xffff; as.max_cfg_ncbs = (USHORT)0xffff; as.max_ncbs = (USHORT)0xffff; as.max_dgram_size = 0; // Smb device doesn't support datagram
as.max_sess_pkt_size = 0xffff;
BytesCopied = 0; status = TdiCopyBufferToMdl (&as, 0, sizeof(ADAPTER_STATUS), Irp->MdlAddress, 0, &BytesCopied);
cleanup: Irp->IoStatus.Status = status; Irp->IoStatus.Information = (status != STATUS_SUCCESS)? 0: BytesCopied; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); return status; }
NTSTATUS SmbQueryPeerInfo( PSMB_CONNECT ConnectObject, PNBT_ADDRESS_PAIR_INFO AddressPair, DWORD Size, DWORD *BytesCopied ) { KIRQL Irql = 0; NBT_ADDRESS_PAIR_INFO ap = { 0 }; DWORD RequiredSize = 0;
*BytesCopied = 0;
RtlZeroMemory(&ap, sizeof(ap)); ap.ActivityCount = 1; ap.AddressPair.TAAddressCount = 2;
SMB_ACQUIRE_SPINLOCK(ConnectObject, Irql); if (NULL == ConnectObject->TcpContext) { SMB_RELEASE_SPINLOCK(ConnectObject, Irql); return STATUS_CONNECTION_DISCONNECTED; }
//
// Fill IP address
//
if (SMB_AF_INET == ConnectObject->RemoteIpAddress.sin_family) { ap.AddressPair.AddressIP.AddressLength = TDI_ADDRESS_LENGTH_IP; ap.AddressPair.AddressIP.AddressType = TDI_ADDRESS_TYPE_IP; ap.AddressPair.AddressIP.Address.in_addr = ConnectObject->RemoteIpAddress.ip4.sin4_addr; RequiredSize = sizeof(ap) + sizeof(ap.AddressPair.AddressIP.Address) - sizeof(ap.AddressPair.AddressIP.AddressIp6); } else { ap.AddressPair.AddressIP.AddressLength = TDI_ADDRESS_LENGTH_IP6; ap.AddressPair.AddressIP.AddressType = TDI_ADDRESS_TYPE_IP6; RtlCopyMemory( ap.AddressPair.AddressIP.AddressIp6.sin6_addr, ConnectObject->RemoteIpAddress.ip6.sin6_addr, sizeof(ap.AddressPair.AddressIP.AddressIp6.sin6_addr) ); ap.AddressPair.AddressIP.AddressIp6.sin6_scope_id = ConnectObject->RemoteIpAddress.ip6.sin6_scope_id; RequiredSize = sizeof(ap); }
//
// Fill Netbios address
//
ap.AddressPair.AddressNetBIOS.AddressType = TDI_ADDRESS_TYPE_NETBIOS; ap.AddressPair.AddressNetBIOS.AddressLength = TDI_ADDRESS_LENGTH_NETBIOS; ap.AddressPair.AddressNetBIOS.Address.NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE; RtlCopyMemory( ap.AddressPair.AddressNetBIOS.Address.NetbiosName, ConnectObject->RemoteName, NETBIOS_NAME_SIZE ); SMB_RELEASE_SPINLOCK(ConnectObject, Irql);
if (Size > sizeof(ap)) { Size = sizeof(ap); }
RtlCopyMemory(AddressPair, &ap, Size); *BytesCopied = Size;
//
// note: STATUS_BUFFER_OVERFLOW can pass NT_SUCCESS(status)
//
return (Size < RequiredSize)? STATUS_BUFFER_OVERFLOW: STATUS_SUCCESS; }
NTSTATUS SmbQueryAddressInfo( PSMB_DEVICE Device, PIRP Irp ) { PSMB_CONNECT ConnectObject = NULL; PIO_STACK_LOCATION IrpSp = NULL; NTSTATUS status = STATUS_SUCCESS; DWORD BytesCopied = 0;
if (NULL == Irp->MdlAddress) { status = STATUS_INVALID_PARAMETER; goto cleanup; } SmbPrint(SMB_TRACE_CALL, ("Client needs changes to use IP6 address %d of %s\n", __LINE__, __FILE__));
IrpSp = IoGetCurrentIrpStackLocation(Irp); ConnectObject = SmbVerifyAndReferenceConnect(IrpSp->FileObject, SMB_REF_TDI); if (NULL == ConnectObject) { ASSERT(0); status = STATUS_NOT_SUPPORTED; goto cleanup; }
status = SmbQueryPeerInfo(ConnectObject, (PNBT_ADDRESS_PAIR_INFO)MmGetMdlVirtualAddress(Irp->MdlAddress), MmGetMdlByteCount (Irp->MdlAddress), &BytesCopied ); SmbDereferenceConnect(ConnectObject, SMB_REF_TDI);
cleanup: Irp->IoStatus.Status = status; Irp->IoStatus.Information = (status != STATUS_SUCCESS)? 0: BytesCopied; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); return status; }
NTSTATUS SmbQueryConnectionInfo( PSMB_DEVICE Device, PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = NULL; PSMB_CONNECT ConnectObject = NULL; PDEVICE_OBJECT DeviceObject = NULL; PFILE_OBJECT TcpConnObject = NULL; KIRQL Irql = 0;
IrpSp = IoGetCurrentIrpStackLocation(Irp); ConnectObject = SmbVerifyAndReferenceConnect(IrpSp->FileObject, SMB_REF_TDI); if (NULL == ConnectObject) { status = STATUS_INVALID_PARAMETER; goto cleanup; }
SMB_ACQUIRE_SPINLOCK(ConnectObject, Irql); if (NULL == ConnectObject->TcpContext) { TcpConnObject = NULL; DeviceObject = NULL; } else { TcpConnObject = ConnectObject->TcpContext->Connect.ConnectObject; ASSERT(TcpConnObject != NULL); ObReferenceObject(TcpConnObject); DeviceObject = IoGetRelatedDeviceObject(TcpConnObject); } SMB_RELEASE_SPINLOCK(ConnectObject, Irql);
if (NULL == TcpConnObject) { SmbDereferenceConnect(ConnectObject, SMB_REF_TDI); status = STATUS_INVALID_PARAMETER; goto cleanup; }
TdiBuildQueryInformation( Irp, DeviceObject, TcpConnObject, NULL, NULL, TDI_QUERY_CONNECTION_INFO, Irp->MdlAddress );
status = IoCallDriver(DeviceObject, Irp);
SmbDereferenceConnect(ConnectObject, SMB_REF_TDI); ObDereferenceObject(TcpConnObject); SmbPrint(SMB_TRACE_CALL, ("TCP returns 0x%08lx for TDI_QUERY_CONNECTION_INFO " "%d of %s\n", status, __LINE__, __FILE__)); return status;
cleanup: Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); return status; }
NTSTATUS SmbQueryInformation( PSMB_DEVICE Device, PIRP Irp, BOOL *bComplete ) { PTDI_REQUEST_KERNEL_QUERY_INFORMATION Query = NULL; PIO_STACK_LOCATION IrpSp = NULL; NTSTATUS status = STATUS_NOT_SUPPORTED;
*bComplete = TRUE;
SmbPrint(SMB_TRACE_CALL, ("Entering SmbQueryInformation IRP %p\n", Irp)); SmbTrace(SMB_TRACE_CALL, ("Entering SmbQueryInformation"));
IrpSp = IoGetCurrentIrpStackLocation(Irp); Query = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)(&IrpSp->Parameters);
switch(Query->QueryType) { case TDI_QUERY_BROADCAST_ADDRESS: //
// Smb device doesn't support broadcast
//
status = STATUS_INVALID_DEVICE_REQUEST; ASSERT(0); break;
case TDI_QUERY_PROVIDER_INFO: *bComplete = FALSE; return SmbQueryProviderInfo(Device, Irp);
case TDI_QUERY_ADAPTER_STATUS: if (Query->RequestConnectionInformation && Query->RequestConnectionInformation->RemoteAddress) { //
// Smb device doesn't support quering remote machine status
//
status = STATUS_NOT_SUPPORTED; break; } *bComplete = FALSE; return SmbQueryAdapterStatus(Device, Irp);
case TDI_QUERY_CONNECTION_INFO: *bComplete = FALSE; return SmbQueryConnectionInfo(Device, Irp);
case TDI_QUERY_FIND_NAME: status = STATUS_INVALID_DEVICE_REQUEST; break;
case TDI_QUERY_ADDRESS_INFO: *bComplete = FALSE; return SmbQueryAddressInfo(Device, Irp);
case TDI_QUERY_SESSION_STATUS: default: status = STATUS_INVALID_DEVICE_REQUEST; break; }
SmbPrint(SMB_TRACE_CALL, ("SmbQueryInformatoin: unsupported query type 0x%08lx\n", Query->QueryType)); return STATUS_NOT_SUPPORTED; }
NTSTATUS SmbSetEventHandler( PSMB_DEVICE Device, PIRP Irp ) { PIO_STACK_LOCATION IrpSp; NTSTATUS status; KIRQL Irql; PSMB_CLIENT_ELEMENT ClientObject; PTDI_REQUEST_KERNEL_SET_EVENT TdiEvent;
PAGED_CODE(); SmbPrint(SMB_TRACE_CALL, ("Entering SmbSetEventHandler\n")); SmbTrace(SMB_TRACE_CALL, ("Entering SmbSetEventHandler"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ClientObject = SmbVerifyAndReferenceClient(IrpSp->FileObject, SMB_REF_TDI); if (NULL == ClientObject) { ASSERT(0); return STATUS_INVALID_PARAMETER; }
TdiEvent = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
status = STATUS_SUCCESS;
SMB_ACQUIRE_SPINLOCK(ClientObject, Irql); switch(TdiEvent->EventType) { case TDI_EVENT_CONNECT: ClientObject->evConnect = TdiEvent->EventHandler; ClientObject->ConEvContext = TdiEvent->EventContext; SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiConnectHandler\n")); SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiConnectHandler")); break;
case TDI_EVENT_DISCONNECT: ClientObject->evDisconnect = TdiEvent->EventHandler; ClientObject->DiscEvContext = TdiEvent->EventContext; SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiDisconnectHandler\n")); SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiDisconnectHandler")); break;
case TDI_EVENT_RECEIVE: ClientObject->evReceive = TdiEvent->EventHandler; ClientObject->RcvEvContext = TdiEvent->EventContext; SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveHandler\n")); SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveHandler")); break;
case TDI_EVENT_ERROR: ClientObject->evError = TdiEvent->EventHandler; ClientObject->ErrorEvContext = TdiEvent->EventContext; SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiErrorHandler\n")); SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiErrorHandler")); break;
case TDI_EVENT_RECEIVE_DATAGRAM: SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveDatagram (unsupported)\n")); SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveDatagram (unsupported)")); break;
case TDI_EVENT_RECEIVE_EXPEDITED: SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveExpedited (unsupported)\n")); SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiReceiveExpedited (unsupported)")); break;
case TDI_EVENT_SEND_POSSIBLE: SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiSendPossible (unsupported)\n")); SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set TdiSendPossible (unsupported)")); break;
default: //status = STATUS_NOT_SUPPORTED;
SmbPrint(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set unsupported TDI event handler %lx\n", TdiEvent->EventType)); SmbTrace(SMB_TRACE_CALL, ("SmbSetEventHandler: Client set upsupported TDI event handler %lx", TdiEvent->EventType)); ASSERT (0); } SMB_RELEASE_SPINLOCK(ClientObject, Irql);
ASSERT(status != STATUS_PENDING); SmbDereferenceClient(ClientObject, SMB_REF_TDI); return status; }
NTSTATUS SmbSetInformation( PSMB_DEVICE Device, PIRP Irp ) { PAGED_CODE();
SmbPrint(SMB_TRACE_CALL, ("Entering SmbSetInformation\n")); SmbTrace(SMB_TRACE_CALL, ("Entering SmbSetInformation")); ASSERT(0); return STATUS_NOT_SUPPORTED; }
NTSTATUS SmbClientSetTcpInfo( PSMB_DEVICE Device, PIRP Irp ) { PIO_STACK_LOCATION IrpSp; PVOID InfoBuffer; ULONG InfoBufferLength; PSMB_CONNECT ConnectObject; PFILE_OBJECT TcpConnObject; KIRQL Irql; NTSTATUS status;
if (Irp->RequestorMode != KernelMode) { return STATUS_ACCESS_DENIED; }
// BREAK_WHEN_TAKE();
IrpSp = IoGetCurrentIrpStackLocation(Irp); InfoBuffer = Irp->AssociatedIrp.SystemBuffer; InfoBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
ConnectObject = SmbVerifyAndReferenceConnect(IrpSp->FileObject, SMB_REF_TDI); if (NULL == ConnectObject) { return STATUS_INVALID_PARAMETER; }
SMB_ACQUIRE_SPINLOCK(ConnectObject, Irql); if (NULL == ConnectObject->TcpContext) { TcpConnObject = NULL; } else { TcpConnObject = ConnectObject->TcpContext->Connect.ConnectObject; ASSERT(TcpConnObject != NULL); ObReferenceObject(TcpConnObject); } SMB_RELEASE_SPINLOCK(ConnectObject, Irql); SmbDereferenceConnect(ConnectObject, SMB_REF_TDI);
if (NULL == TcpConnObject) { return STATUS_INVALID_PARAMETER; }
status = SmbSendIoctl( TcpConnObject, IOCTL_TCP_SET_INFORMATION_EX, InfoBuffer, InfoBufferLength, NULL, NULL ); if (!NT_SUCCESS(status)) { SmbPrint(SMB_TRACE_TCP, ("SmbClientSetTcpInfo: SetTcpInfo FAILed <0x%x> InfoBuffer=%p Length=%d\n", status, InfoBuffer, InfoBufferLength)); SmbTrace(SMB_TRACE_TCP, ("FAILed %!status! InfoBuffer=%p Length=%d", status, InfoBuffer, InfoBufferLength)); }
ObDereferenceObject(TcpConnObject); return status; }
NTSTATUS IoctlSetIPv6Protection( PSMB_DEVICE pDeviceObject, PIRP pIrp, PIO_STACK_LOCATION pIrpSp ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwInputBufferLength = 0; PNBSMB_IPV6_PROTECTION_PARAM pInput = NULL; ULONG uOldIPv6Protection = 0;
dwInputBufferLength = pIrpSp->Parameters.DeviceIoControl.InputBufferLength; pInput = pIrp->AssociatedIrp.SystemBuffer; if (dwInputBufferLength < sizeof(NBSMB_IPV6_PROTECTION_PARAM) || NULL == pInput) { ntStatus = STATUS_INVALID_PARAMETER; goto error; }
SmbTrace(SMB_TRACE_IOCTL, ("uIPv6Protection: input %d", pInput->uIPv6ProtectionLevel));
if (SmbCfg.uIPv6Protection != pInput->uIPv6ProtectionLevel) {
uOldIPv6Protection = SmbCfg.uIPv6Protection; SmbCfg.uIPv6Protection = pInput->uIPv6ProtectionLevel;
ntStatus = SmbSetInboundIPv6Protection(pDeviceObject); SmbTrace(SMB_TRACE_IOCTL, ("Change IPv6 Protection for inbound return %!status!", ntStatus));
if (ntStatus != STATUS_SUCCESS) { NTSTATUS LocalStatus = STATUS_SUCCESS;
SmbCfg.uIPv6Protection = uOldIPv6Protection; LocalStatus = SmbSetInboundIPv6Protection(pDeviceObject); SmbTrace(SMB_TRACE_IOCTL, ("Restore to the old settings on failure. Restore status %!status!", LocalStatus)); }
}
if (ntStatus == STATUS_SUCCESS) { SmbCfg.bIPv6EnableOutboundGlobal = pInput->bIPv6EnableOutboundGlobal; }
error: SmbTrace(SMB_TRACE_IOCTL, ("%!status!", ntStatus)); return ntStatus; }
|