Ejemplo n.º 1
0
BOOLEAN
TtdiSend()
{
    USHORT i, Iteration, Increment;
    HANDLE RdrHandle, RdrConnectionHandle;
    KEVENT Event1;
    PFILE_OBJECT AddressObject, ConnectionObject;
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
    PMDL SendMdl, ReceiveMdl;
    IO_STATUS_BLOCK Iosb1;
    TDI_CONNECTION_INFORMATION RequestInformation;
    TDI_CONNECTION_INFORMATION ReturnInformation;
    PTRANSPORT_ADDRESS ListenBlock;
    PTRANSPORT_ADDRESS ConnectBlock;
    PTDI_ADDRESS_NETBIOS temp;
    PUCHAR MessageBuffer;
    ULONG MessageBufferLength;
    ULONG CurrentBufferLength;
    PUCHAR SendBuffer;
    ULONG SendBufferLength;
    PIRP Irp;

    Status = KeWaitForSingleObject (&TdiSendEvent, Suspended, KernelMode, FALSE, NULL);

    SendBufferLength = (ULONG)BUFFER_SIZE;
    MessageBufferLength = (ULONG)BUFFER_SIZE;


    DbgPrint( "\n****** Start of Send Test ******\n" );

    XBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
    if (XBuff == (PVOID)NULL) {
        DbgPrint ("Unable to allocate nonpaged pool for send buffer exiting\n");
        return FALSE;
    }
    RBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
    if (RBuff == (PVOID)NULL) {
        DbgPrint ("Unable to allocate nonpaged pool for receive buffer exiting\n");
        return FALSE;
    }

    ListenBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));
    ConnectBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));

    ListenBlock->TAAddressCount = 1;
    ListenBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ListenBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ListenBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = ClientName[i];
    }

    ConnectBlock->TAAddressCount = 1;
    ConnectBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ConnectBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ConnectBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = ServerName[i];
    }

    //
    // Create an event for the synchronous I/O requests that we'll be issuing.
    //

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Status = TtdiOpenAddress (&RdrHandle, AnyName);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Send Test:  FAILED on open of client: %lC ******\n", Status );
        return FALSE;
    }

    Status = ObReferenceObjectByHandle (
                RdrHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &AddressObject,
                NULL);

    //
    // Open the connection on the transport.
    //

    Status = TtdiOpenConnection (&RdrConnectionHandle, 1);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Send Test:  FAILED on open of server Connection: %lC ******\n", Status );
        return FALSE;
    }

    Status = ObReferenceObjectByHandle (
                RdrConnectionHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &ConnectionObject,
                NULL);

    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Send Test:  FAILED on open of server Connection: %lC ******\n", Status );
        return FALSE;
    }

    //
    // Get a pointer to the stack location for the first driver.  This will be
    // used to pass the original function codes and parameters.
    //

    DeviceObject = IoGetRelatedDeviceObject( ConnectionObject );

    Irp = TdiBuildInternalDeviceControlIrp (
                TDI_ASSOCIATE_ADDRESS,
                DeviceObject,
                ConnectionObject,
                &Event1,
                &Iosb1);


    //
    // Get a pointer to the stack location for the first driver.  This will be
    // used to pass the original function codes and parameters.
    //

    TdiBuildAssociateAddress (Irp,
        DeviceObject,
        ConnectionObject,
        TSTRCVCompletion,
        &Event1,
        RdrHandle);

    Status = IoCallDriver (DeviceObject, Irp);

//    IoFreeIrp (Irp);

    if (Status == STATUS_PENDING) {
        Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Send Test:  FAILED Event1 Wait Associate: %lC ******\n", Status );
            return FALSE;
        }
        if (!NT_SUCCESS(Iosb1.Status)) {
            DbgPrint( "\n****** Send Test:  FAILED Associate Iosb status: %lC ******\n", Status );
            return FALSE;
        }

    } else {
        if (!NT_SUCCESS (Status)) {
            DbgPrint( "\n****** Send Test:  AssociateAddress FAILED  Status: %lC ******\n", Status );
            return FALSE;
        } else {
            DbgPrint ("********** Send Test:  Success AssociateAddress\n");
        }
    }

    //
    // Post a TdiConnect to the client endpoint.
    //

    RequestInformation.RemoteAddress = ConnectBlock;
    RequestInformation.RemoteAddressLength = sizeof (TRANSPORT_ADDRESS) +
                                            sizeof (TDI_ADDRESS_NETBIOS);

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Irp = TdiBuildInternalDeviceControlIrp (
                TDI_CONNECT,
                DeviceObject,
                ConnectionObject,
                &Event1,
                &Iosb1);

    TdiBuildConnect (
        Irp,
        DeviceObject,
        ConnectionObject,
        TSTRCVCompletion,
        &Event1,
        0,
        &RequestInformation,
        &ReturnInformation);

    InitWaitObject (&Event1);

    Status = IoCallDriver (DeviceObject, Irp);

//    IoFreeIrp (Irp);

    if (Status == STATUS_PENDING) {
        Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Send Test:  FAILED Event1 Wait Connect: %lC ******\n", Status );
            return FALSE;
        }
        if (!NT_SUCCESS(Iosb1.Status)) {
            DbgPrint( "\n****** Send Test:  FAILED Iosb status Connect: %lC ******\n", Status );
            return FALSE;
        } else {
            DbgPrint ("********** Send Test:  Success Connect Iosb\n");
        }

    } else {
        if (!NT_SUCCESS (Status)) {
            DbgPrint( "\n****** Send Test:  Connect FAILED  Status: %lC ******\n", Status );
            return FALSE;
        } else {
            DbgPrint ("********** Send Test:  Success Connect Immediate\n");
        }
    }

    DbgPrint( "\n****** Send Test:  SUCCESSFUL TdiConnect:  ******\n");

    //
    // Send/receive 1 or  10 messages.
    //

    SendBuffer =  (PUCHAR)ExAllocatePool (NonPagedPool, SendBufferLength);
    if (SendBuffer == NULL) {
        DbgPrint ("\n****** Send Test:  ExAllocatePool failed! ******\n");
    }
    SendMdl = IoAllocateMdl (SendBuffer, SendBufferLength, FALSE, FALSE, NULL);
    MmBuildMdlForNonPagedPool (SendMdl);

    MessageBuffer=(PUCHAR)ExAllocatePool (NonPagedPool, MessageBufferLength);
    if (MessageBuffer == NULL) {
        DbgPrint ("\n****** Send Test:  ExAllocatePool failed! ******\n");
    }
    ReceiveMdl = IoAllocateMdl (MessageBuffer, MessageBufferLength, FALSE, FALSE, NULL);
    MmBuildMdlForNonPagedPool (ReceiveMdl);

    //
    // Cycle the buffer length from 0 up through the maximum for Tdi. after a
    // couple of shots at the full range in one byte steps, increment by ever
    // increasing amounts to get to the max.
    //

    CurrentBufferLength = 0;
    Increment = 1;
    for (Iteration=1; Iteration<(USHORT)c9_Iteration; Iteration++) {
        CurrentBufferLength += Increment;
        if (CurrentBufferLength > MessageBufferLength) {
            CurrentBufferLength = 0;
            Increment = 1;
        }
        if (CurrentBufferLength > 7500) {
            Increment++;
        }
        if ((USHORT)((Iteration / 100) * 100) == Iteration) {
            DbgPrint ("Iteration #%d Buffer Length: %lx Buffer Start: %x\n",
                Iteration, CurrentBufferLength,Iteration % 256);
        }
        for (i=0; i<(USHORT)CurrentBufferLength; i++) {
            SendBuffer [i] = (UCHAR)(i + Iteration % 256 );
            MessageBuffer [i] = 0;            // zap this sucker with something.
        }

        //
        // Now issue a send on the client side.
        //

        KeInitializeEvent (
                    &Event1,
                    SynchronizationEvent,
                    FALSE);

        Irp = TdiBuildInternalDeviceControlIrp (
                    TDI_SEND,
                    DeviceObject,
                    ConnectionObject,
                    &Event1,
                    &Iosb1);

        TdiBuildSend (Irp,
            DeviceObject,
            ConnectionObject,
            TSTRCVCompletion,
            &Event1,
            ReceiveMdl,
            0,
            CurrentBufferLength);

        InitWaitObject (&Event1);

        Status = IoCallDriver (DeviceObject, Irp);

//        IoFreeIrp (Irp);

        if (Status == STATUS_PENDING) {
            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
            if (!NT_SUCCESS(Status)) {
                DbgPrint( "\n****** Send Test:  FAILED Event1 Wait Send: %lC %d ******\n",
                    Status, Iteration );
                return FALSE;
            }
            if (!NT_SUCCESS(Iosb1.Status)) {
                DbgPrint( "\n****** Send Test:  FAILED Iosb status Send: %lC %d ******\n",
                    Status, Iteration );
                return FALSE;
            } else {
                DbgPrint ("********** Send Test:  Success SendIosb\n");
            }

        } else {
            if (!NT_SUCCESS (Status)) {
                DbgPrint( "\n****** Send Test:  Send FAILED  Status: %lC %d ******\n",
                Status, Iteration );
                return FALSE;
            } else {
                DbgPrint ("********** Send Test:  Success Send Immediate\n");
            }
        }

        if (Iosb1.Information != CurrentBufferLength) {
            DbgPrint ("SendTest: Bytes sent <> Send buffer size.\n");
            DbgPrint ("SendTest: BytesToSend=%ld.  BytesSent=%ld.\n",
                      CurrentBufferLength, Iosb1.Information);
        }

    }

    //
    // We're done with this endpoint.  Close it and get out.
    //

    Status = CloseAddress (RdrHandle);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Send Test:  FAILED on 2nd Close: %lC ******\n", Status );
        return FALSE;
    }

    DbgPrint( "\n****** End of Send Test ******\n" );
    return TRUE;
} /* Send */
Ejemplo n.º 2
0
NDIS_STATUS
FakeNDISReceiveHandler (
	NDIS_HANDLE ProtocolBindingContext,
	NDIS_HANDLE MacReceiveContext,
	PUCHAR pHeaderBuffer,
	UINT HeaderBufferSize,
	PUCHAR pLookaheadBuffer,
	UINT LookaheadBufferSize,
	UINT PacketSize
	)
/*++

Routine Description:

	Filters network packets received.


Arguments:

	ProtocolBindingContext - ...

	MacReceiveContext - ...

	pHeaderBuffer - packet header

	HeaderBufferSize - packet header length

	pLookaheadBuffer - look ahead buffer after packet header

	LookaheadBufferSize - length of look ahead buffer

	PacketSize - length of packet, exclude packet header


Return Value:

	...


Author:

	xiaonie

	2012/07/12


--*/
{
	PLIST_ENTRY pEntry;
	PNDIS_HOOK_LIST_NODE pNode;
	KIRQL irql;
	ULONG ulFunAddr = 0;
	// PVOID MacHandle = NULL;
	NDIS_STATUS status = NDIS_STATUS_SUCCESS;
	PNDIS_PACKET pNdisPacket = NULL;
	PNDIS_BUFFER pNdisBuffer = NULL;
	PUCHAR pBuffer = NULL;
	ULONG ulLen;
	KEVENT evt;

	KeAcquireSpinLock(&g_lock, &irql);
	for (pEntry = g_linkListHead.Flink; pEntry != &g_linkListHead; pEntry = pEntry->Flink) {
		pNode = CONTAINING_RECORD(pEntry, NDIS_HOOK_LIST_NODE, ListEntry);
		if (pNode->ProtocolBindingContext == ProtocolBindingContext) {
			ulFunAddr = pNode->ulRealReceiveHandler;
			// MacHandle = pNode->MacHandle;
			break;
		}
	}
	KeReleaseSpinLock(&g_lock, irql);

	if (ulFunAddr == 0) {
		DbgPrint("\r\n Attention: FunAddr == 0(0: FakeNDISReceiveHandler)\r\n");
		// return NDIS_STATUS_SUCCESS;
		return NDIS_STATUS_NOT_ACCEPTED;
	}


	////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	if (PacketSize + HeaderBufferSize < PacketSize || PacketSize < LookaheadBufferSize) {	// PacketSize not valid
		DbgPrint("\r\n Attention: PacketSize not valid!(0: FakeNDISReceiveHandler)\r\n");
		return NDIS_STATUS_NOT_ACCEPTED;
	}

	// allocate buffer to hold network packet
	status = NdisAllocateMemoryWithTag(&pBuffer, HeaderBufferSize + PacketSize, '!nmN');
	if (status != NDIS_STATUS_SUCCESS/* || pBuffer == NULL*/)
		return NDIS_STATUS_NOT_ACCEPTED;

	// copy packet header to buffer
	NdisMoveMemory(pBuffer, pHeaderBuffer, HeaderBufferSize);

	if (PacketSize == LookaheadBufferSize)		// Lookahead buffer contains a complete packet
	{
		//
		//	path 1 of 3, tested ok!
		//
		NdisMoveMemory(pBuffer + HeaderBufferSize, pLookaheadBuffer, PacketSize);

		// do the filtering work
		if (TRUE == RabbitHole(pBuffer, HeaderBufferSize + PacketSize)) {
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NdisFreeMemory(pBuffer, 0, 0);

	}
	else										// Lookahead buffer contains an incomplete packet
	{
		//
		// get the full packet
		//
		// DbgPrint("Get Full Packet!\r\n");

		//if (MacHandle == NULL) {
		//	DbgPrint("MacHandle == NULL!(0: FakeNDISReceiveHandler)\r\n");
		//	NdisFreeMemory(pBuffer, 0, 0);
		//	return NDIS_STATUS_NOT_ACCEPTED;
		//}

		// make pBuffer a NDIS buffer to hold data
		NdisAllocateBuffer(&status, &pNdisBuffer, g_BufferPool, pBuffer + HeaderBufferSize, PacketSize);
		if (status != NDIS_STATUS_SUCCESS/* || pNdisBuffer == NULL*/) {
			DbgPrint("allocate pNdisBuffer(size = %d) failed in FakeNDISReceiveHandler!\r\n", PacketSize);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		// allocate a NIDS packet to chain buffer in.
		NdisAllocatePacket(&status, &pNdisPacket, g_PacketPool);
		if (status != NDIS_STATUS_SUCCESS/* || pNdisPacket == NULL*/) {
			DbgPrint("allocate pNdisPacket failed in FakeNDISReceiveHandler!\r\n");
			NdisFreeBuffer(pNdisBuffer);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NDIS_SET_PACKET_STATUS(pNdisPacket, STATUS_SUCCESS);

		// Bring explosives.
		KeInitializeEvent(&evt, NotificationEvent, FALSE);
		*(PKEVENT *)(pNdisPacket->ProtocolReserved) = &evt;

		NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);

		// try to get complete packet
		NdisTransferData(&status, pNode->pOpenBlock, MacReceiveContext, 0, PacketSize, pNdisPacket, &ulLen);

		if (status == NDIS_STATUS_PENDING) {			// wait for the right time
			//
			// Path 2 of 3, not tested yet! Warning: An Error may occur!
			//
			DbgPrint("NdisTransferData is pending in FakeNDISReceiveHandler!\r\n", status);
			KeWaitForSingleObject(&evt, Executive, KernelMode, FALSE, NULL);
		} else if (status != NDIS_STATUS_SUCCESS) {
			DbgPrint("NdisTransferData failed(status == 0x%08x) in FakeNDISReceiveHandler!\r\n", status);
			NdisFreePacket(pNdisPacket);
			NdisFreeBuffer(pNdisBuffer);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		//
		// Path 3 of 3, Filtering doesn't seem to work properly.
		//
		// do the filtering work
		if (TRUE == FilterPacket_ReceiveHandler(pBuffer, HeaderBufferSize, pNdisPacket)) {
			NdisFreePacket(pNdisPacket);
			NdisFreeBuffer(pNdisBuffer);
			NdisFreeMemory(pBuffer, 0, 0);
			return NDIS_STATUS_NOT_ACCEPTED;
		}

		NdisFreePacket(pNdisPacket);
		NdisFreeBuffer(pNdisBuffer);
		NdisFreeMemory(pBuffer, 0, 0);
	}

	// call the original NDIS routine.
	__asm {
		pushad;
		push	PacketSize;
		push	LookaheadBufferSize;
		push	pLookaheadBuffer;
		push	HeaderBufferSize;
		push	pHeaderBuffer;
		push	MacReceiveContext;
		push	ProtocolBindingContext;
		mov		eax, ulFunAddr;
		call	eax;
		mov		status, eax;
		popad;
	}

	return status;
}
Ejemplo n.º 3
0
NTSTATUS
FatPnpRemove (
    PIRP_CONTEXT IrpContext,
    PIRP Irp,
    PVCB Vcb
    )

/*++

Routine Description:

    This routine handles the PnP remove operation.  This is our notification
    that the underlying storage device for the volume we have is gone, and
    an excellent indication that the volume will never reappear. The filesystem
    is responsible for initiation or completion of the dismount.
    
Arguments:

    Irp - Supplies the Irp to process
    
    Vcb - Supplies the volume being removed.

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    KEVENT Event;
    BOOLEAN VcbDeleted;
    
    //
    //  REMOVE - a storage device is now gone.  We either got
    //  QUERY'd and said yes OR got a SURPRISE OR a storage
    //  stack failed to spin back up from a sleep/stop state
    //  (the only case in which this will be the first warning).
    //
    //  Note that it is entirely unlikely that we will be around
    //  for a REMOVE in the first two cases, as we try to intiate
    //  dismount.
    //
    
    //
    //  Acquire the global resource so that we can try to vaporize
    //  the volume, and the vcb resource itself.
    //

#if __NDAS_FAT_SECONDARY__
	if (FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT))
		FatAcquireExclusiveSecondaryVcb( IrpContext, Vcb );
	else
		FatAcquireExclusiveVcb( IrpContext, Vcb );
#else
	FatAcquireExclusiveVcb( &IrpContext, Vcb );
#endif

    //
    //  The device will be going away.  Remove our lock (benign
    //  if we never had it).
    //

    (VOID) FatUnlockVolumeInternal( IrpContext, Vcb, NULL );
    
    //
    //  We need to pass this down before starting the dismount, which
    //  could disconnect us immediately from the stack.
    //
    
    //
    //  Get the next stack location, and copy over the stack location
    //

    IoCopyCurrentIrpStackLocationToNext( Irp );

    //
    //  Set up the completion routine
    //

    KeInitializeEvent( &Event, NotificationEvent, FALSE );
    IoSetCompletionRoutine( Irp,
                            FatPnpCompletionRoutine,
                            &Event,
                            TRUE,
                            TRUE,
                            TRUE );

    //
    //  Send the request and wait.
    //

    Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);

    if (Status == STATUS_PENDING) {

        KeWaitForSingleObject( &Event,
                               Executive,
                               KernelMode,
                               FALSE,
                               NULL );

        Status = Irp->IoStatus.Status;
    }

    try {
        
        //
        //  Knock as many files down for this volume as we can.
        //

        FatFlushAndCleanVolume( IrpContext, Irp, Vcb, NoFlush );

        //
        //  Now make our dismount happen.  This may not vaporize the
        //  Vcb, of course, since there could be any number of handles
        //  outstanding if we were not preceeded by a QUERY.
        //
        //  PnP will take care of disconnecting this stack if we
        //  couldn't get off of it immediately.
        //

        VcbDeleted = FatCheckForDismount( IrpContext, Vcb, TRUE );

    } finally {
        
        //
        //  Release the Vcb if it could still remain.
        //

        if (!VcbDeleted) {

#if __NDAS_FAT_SECONDARY__
			if (FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT)) {
				FatReleaseSecondaryVcb( IrpContext, Vcb );
			} else {
				FatReleaseVcb( IrpContext, Vcb );
			}
#else
			FatReleaseVcb( IrpContext, Vcb );
#endif       
        }

        FatReleaseGlobal( IrpContext );
    }

    //
    //  Cleanup our IrpContext and complete the IRP.
    //

    FatCompleteRequest( IrpContext, Irp, Status );

    return Status;
}
Ejemplo n.º 4
0
NTSTATUS
NdFatSecondaryCommonWrite3 (
	IN PIRP_CONTEXT IrpContext,
	IN PIRP			Irp
	)
{
	NTSTATUS					status;

	PVOLUME_DEVICE_OBJECT		volDo = CONTAINING_RECORD( IrpContext->Vcb, VOLUME_DEVICE_OBJECT, Vcb );
	BOOLEAN						secondarySessionResourceAcquired = FALSE;
	
	PIO_STACK_LOCATION			irpSp = IoGetCurrentIrpStackLocation( Irp );
	PFILE_OBJECT				fileObject = irpSp->FileObject;

	struct Write				write;
	
	PSECONDARY_REQUEST			secondaryRequest = NULL;
	PNDFS_REQUEST_HEADER		ndfsRequestHeader;
	PNDFS_WINXP_REQUEST_HEADER	ndfsWinxpRequestHeader;
	PNDFS_WINXP_REPLY_HEADER	ndfsWinxpReplytHeader;

	LARGE_INTEGER				timeOut;

	TYPE_OF_OPEN				typeOfOpen;
	PVCB						vcb;
	PFCB						fcb;
	PCCB						ccb;
	BOOLEAN						fcbAcquired = FALSE;

	BOOLEAN						writeToEof;
	PUCHAR						inputBuffer;
	ULONG						totalWriteLength;


	ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );
	ASSERT (!FlagOn(Irp->Flags, IRP_PAGING_IO));
	
	typeOfOpen = FatDecodeFileObject( fileObject, &vcb, &fcb, &ccb );

	ASSERT( typeOfOpen == UserFileOpen );

	if (FlagOn(ccb->NdFatFlags, ND_FAT_CCB_FLAG_UNOPENED)) {

		/*if (FlagOn( fcb->FcbState, FCB_STATE_FILE_DELETED )) {
	
			ASSERT( FALSE );
			FatRaiseStatus( IrpContext, STATUS_FILE_DELETED, NULL, NULL );
					
		} else */{
					
			ASSERT( FlagOn(ccb->NdFatFlags, ND_FAT_CCB_FLAG_CORRUPTED) );

			status = STATUS_FILE_CORRUPT_ERROR;
	        FatCompleteRequest( IrpContext, Irp, status );
			return status;
		}
	}

	writeToEof = (irpSp->Parameters.Write.ByteOffset.QuadPart == FILE_WRITE_TO_END_OF_FILE && 
				  irpSp->Parameters.Write.ByteOffset.HighPart == -1);

	write.ByteOffset	= irpSp->Parameters.Write.ByteOffset;
	write.Key			= irpSp->Parameters.Write.Key;
	write.Length		= irpSp->Parameters.Write.Length;

	ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ); 

	//FatAcquireSharedFcb( IrpContext, fcb );
	//fcbAcquired = TRUE;


	try {

		secondarySessionResourceAcquired 
			= SecondaryAcquireResourceExclusiveLite( IrpContext, 
													 &volDo->Secondary->SessionResource, 
													 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

		if (FlagOn(volDo->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ) {

			PrintIrp( Dbg, "SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED", NULL, IrpContext->OriginatingIrp );

			if (FlagOn(Irp->Flags, IRP_PAGING_IO)) {
	
				try_return( status = STATUS_FILE_LOCK_CONFLICT );
				
			} else {

				FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
			}
		}

		inputBuffer = FatMapUserBuffer( IrpContext, Irp );
		totalWriteLength = 0;

		do {

			ULONG	inputBufferLength;
			_U8		*ndfsWinxpRequestData;
			_U64	primaryFileHandle;

			if (fcb->UncleanCount == 0) {

				DebugTrace( 0, Dbg2, "NdFatSecondaryCommonWrite2: fileName = %wZ\n", &fileObject->FileName );

				totalWriteLength = write.Length;
				status = STATUS_FILE_CLOSED;
				break;
			}

			if (!FlagOn(ccb->NdFatFlags, ND_FAT_CLEANUP_COMPLETE)) {

				primaryFileHandle = ccb->PrimaryFileHandle;

			} else {

				PLIST_ENTRY	ccbListEntry;

				ExAcquireFastMutex( &fcb->CcbQMutex );
				
				for (primaryFileHandle = 0, ccbListEntry = fcb->CcbQueue.Flink; 
					 ccbListEntry != &fcb->CcbQueue; 
					 ccbListEntry = ccbListEntry->Flink) {

					if (!FlagOn(CONTAINING_RECORD(ccbListEntry, CCB, FcbListEntry)->NdFatFlags, ND_FAT_CLEANUP_COMPLETE)) {
						
						primaryFileHandle = CONTAINING_RECORD(ccbListEntry, CCB, FcbListEntry)->PrimaryFileHandle;
						break;
					}
				}

				ExReleaseFastMutex( &fcb->CcbQMutex );
			}

			ASSERT( primaryFileHandle );

			inputBufferLength = ((write.Length-totalWriteLength) <= volDo->Secondary->Thread.SessionContext.SecondaryMaxDataSize) 
									? (write.Length-totalWriteLength) : volDo->Secondary->Thread.SessionContext.SecondaryMaxDataSize;

			secondaryRequest = ALLOC_WINXP_SECONDARY_REQUEST( volDo->Secondary, 
															  IRP_MJ_WRITE,
															  volDo->Secondary->Thread.SessionContext.PrimaryMaxDataSize );

			if (secondaryRequest == NULL) {

				FatRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
			}

			ndfsRequestHeader = &secondaryRequest->NdfsRequestHeader;
			INITIALIZE_NDFS_REQUEST_HEADER(	ndfsRequestHeader, NDFS_COMMAND_EXECUTE, volDo->Secondary, IRP_MJ_WRITE, inputBufferLength );

			ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1);
			ASSERT( ndfsWinxpRequestHeader == (PNDFS_WINXP_REQUEST_HEADER)secondaryRequest->NdfsRequestData );

			//ndfsWinxpRequestHeader->IrpTag   = (_U32)Irp;
			ndfsWinxpRequestHeader->IrpMajorFunction = IRP_MJ_WRITE;
			ndfsWinxpRequestHeader->IrpMinorFunction = 0;

			ndfsWinxpRequestHeader->FileHandle = primaryFileHandle;

			ndfsWinxpRequestHeader->IrpFlags   = 0;
			ndfsWinxpRequestHeader->IrpSpFlags = 0;

			ndfsWinxpRequestHeader->Write.Length		= inputBufferLength;
			ndfsWinxpRequestHeader->Write.Key			= write.Key;
			if (writeToEof)
				ndfsWinxpRequestHeader->Write.ByteOffset = write.ByteOffset.QuadPart;
			else
				ndfsWinxpRequestHeader->Write.ByteOffset = write.ByteOffset.QuadPart + totalWriteLength;
			
			ndfsWinxpRequestHeader->Write.ForceWrite	= TRUE;


			DebugTrace2( 0, Dbg, ("ndfsWinxpRequestHeader->Write.ByteOffset = %I64d, ndfsWinxpRequestHeader->Write.Length = %d\n", 
								   ndfsWinxpRequestHeader->Write.ByteOffset, ndfsWinxpRequestHeader->Write.Length) );

			ndfsWinxpRequestData = (_U8 *)(ndfsWinxpRequestHeader+1);

			if (inputBufferLength) {

				try {

					RtlCopyMemory( ndfsWinxpRequestData,
								   inputBuffer + totalWriteLength,
								   inputBufferLength );

				} except (EXCEPTION_EXECUTE_HANDLER) {

					DebugTrace2( 0, Dbg2, ("RedirectIrp: Exception - Input buffer is not valid\n") );
					
					status = GetExceptionCode();
					break;
				}
			}

			//if (fcb->Header.FileSize.LowPart < 100)
			//	DbgPrint( "data = %s\n", ndfsWinxpRequestData );

			secondaryRequest->RequestType = SECONDARY_REQ_SEND_MESSAGE;
			QueueingSecondaryRequest( volDo->Secondary, secondaryRequest );

			timeOut.QuadPart = -NDFAT_TIME_OUT;
			status = KeWaitForSingleObject( &secondaryRequest->CompleteEvent, Executive, KernelMode, FALSE, &timeOut );
		
			if (status != STATUS_SUCCESS) {

				secondaryRequest = NULL;
				status = STATUS_IO_DEVICE_ERROR;
				leave;
			}

			KeClearEvent( &secondaryRequest->CompleteEvent );

			if (secondaryRequest->ExecuteStatus != STATUS_SUCCESS) {

				if (IrpContext->OriginatingIrp)
					PrintIrp( Dbg2, "secondaryRequest->ExecuteStatus != STATUS_SUCCESS", NULL, IrpContext->OriginatingIrp );
			
				DebugTrace2( 0, Dbg2, ("secondaryRequest->ExecuteStatus != STATUS_SUCCESS file = %s, line = %d\n", __FILE__, __LINE__) );

				if (FlagOn(Irp->Flags, IRP_PAGING_IO)) {
	
					try_return( status = STATUS_FILE_LOCK_CONFLICT );
				
				} else {

					FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
				}
			}

			ndfsWinxpReplytHeader = (PNDFS_WINXP_REPLY_HEADER)secondaryRequest->NdfsReplyData;

			if (ndfsWinxpReplytHeader->Status != STATUS_SUCCESS) {
			
				DebugTrace2( 0, Dbg, ("ndfsWinxpReplytHeader->Status = %x\n", ndfsWinxpReplytHeader->Status) );

				if (totalWriteLength)
					status = STATUS_SUCCESS;
				else
					status = ndfsWinxpReplytHeader->Status;

				ASSERT( ndfsWinxpReplytHeader->Information == 0 );
				DereferenceSecondaryRequest( secondaryRequest );
				secondaryRequest = NULL;				
				
				break;
			}

			totalWriteLength += ndfsWinxpReplytHeader->Information;

			ASSERT( ndfsWinxpReplytHeader->Information <= inputBufferLength );
			ASSERT( ndfsWinxpReplytHeader->Information != 0 );
		
			DereferenceSecondaryRequest( secondaryRequest );
			secondaryRequest = NULL;

		} while( totalWriteLength < write.Length );

try_exit: NOTHING;

	} finally {

		if (!AbnormalTermination()) {
			
			if (totalWriteLength) {

				Irp->IoStatus.Information = totalWriteLength;
				Irp->IoStatus.Status = STATUS_SUCCESS;
		
			} else {
		
				Irp->IoStatus.Information = 0;
				Irp->IoStatus.Status = status;
			}
		}

		DebugTrace2( 0, Dbg, ("write.ByteOffset.QuadPart = %I64x, write.Length = %x, totalWriteRequestLength = %x lastStatus = %x\n", 
								write.ByteOffset.QuadPart, write.Length, totalWriteLength, status) );

		if (!FlagOn(ccb->NdFatFlags, ND_FAT_CLEANUP_COMPLETE) && Irp->IoStatus.Status != STATUS_SUCCESS) {

			DebugTrace2( 0, Dbg, ("write.ByteOffset.QuadPart = %I64x, write.Length = %x, totalWriteRequestLength = %x lastStatus = %x\n", 
								 write.ByteOffset.QuadPart, write.Length, totalWriteLength, status) );

			PrintIrp( Dbg, "RedirectIrpMajorWrite", NULL, Irp );
		}

		if (secondarySessionResourceAcquired == TRUE)
			SecondaryReleaseResourceLite( IrpContext, &volDo->Secondary->SessionResource );

		if (fcbAcquired) {
             FatReleaseFcb( IrpContext, fcb );
        }

		if (secondaryRequest)
			DereferenceSecondaryRequest( secondaryRequest );
	}
			
	FatCompleteRequest( IrpContext, Irp, status );
	return status;
}
Ejemplo n.º 5
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
NtSecureConnectPort(OUT PHANDLE PortHandle,
                    IN PUNICODE_STRING PortName,
                    IN PSECURITY_QUALITY_OF_SERVICE Qos,
                    IN OUT PPORT_VIEW ClientView OPTIONAL,
                    IN PSID ServerSid OPTIONAL,
                    IN OUT PREMOTE_PORT_VIEW ServerView OPTIONAL,
                    OUT PULONG MaxMessageLength OPTIONAL,
                    IN OUT PVOID ConnectionInformation OPTIONAL,
                    IN OUT PULONG ConnectionInformationLength OPTIONAL)
{
    ULONG ConnectionInfoLength = 0;
    PLPCP_PORT_OBJECT Port, ClientPort;
    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
    NTSTATUS Status = STATUS_SUCCESS;
    HANDLE Handle;
    PVOID SectionToMap;
    PLPCP_MESSAGE Message;
    PLPCP_CONNECTION_MESSAGE ConnectMessage;
    PETHREAD Thread = PsGetCurrentThread();
    ULONG PortMessageLength;
    LARGE_INTEGER SectionOffset;
    PTOKEN Token;
    PTOKEN_USER TokenUserInfo;
    PAGED_CODE();
    LPCTRACE(LPC_CONNECT_DEBUG,
             "Name: %wZ. Qos: %p. Views: %p/%p. Sid: %p\n",
             PortName,
             Qos,
             ClientView,
             ServerView,
             ServerSid);

    /* Validate client view */
    if ((ClientView) && (ClientView->Length != sizeof(PORT_VIEW)))
    {
        /* Fail */
        return STATUS_INVALID_PARAMETER;
    }

    /* Validate server view */
    if ((ServerView) && (ServerView->Length != sizeof(REMOTE_PORT_VIEW)))
    {
        /* Fail */
        return STATUS_INVALID_PARAMETER;
    }

    /* Check if caller sent connection information length */
    if (ConnectionInformationLength)
    {
        /* Retrieve the input length */
        ConnectionInfoLength = *ConnectionInformationLength;
    }

    /* Get the port */
    Status = ObReferenceObjectByName(PortName,
                                     0,
                                     NULL,
                                     PORT_CONNECT,
                                     LpcPortObjectType,
                                     PreviousMode,
                                     NULL,
                                     (PVOID *)&Port);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to reference port '%wZ': 0x%lx\n", PortName, Status);
        return Status;
    }

    /* This has to be a connection port */
    if ((Port->Flags & LPCP_PORT_TYPE_MASK) != LPCP_CONNECTION_PORT)
    {
        /* It isn't, so fail */
        ObDereferenceObject(Port);
        return STATUS_INVALID_PORT_HANDLE;
    }

    /* Check if we have a SID */
    if (ServerSid)
    {
        /* Make sure that we have a server */
        if (Port->ServerProcess)
        {
            /* Get its token and query user information */
            Token = PsReferencePrimaryToken(Port->ServerProcess);
            //Status = SeQueryInformationToken(Token, TokenUser, (PVOID*)&TokenUserInfo);
            // FIXME: Need SeQueryInformationToken
            Status = STATUS_SUCCESS;
            TokenUserInfo = ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_USER), TAG_SE);
            TokenUserInfo->User.Sid = ServerSid;
            PsDereferencePrimaryToken(Token);

            /* Check for success */
            if (NT_SUCCESS(Status))
            {
                /* Compare the SIDs */
                if (!RtlEqualSid(ServerSid, TokenUserInfo->User.Sid))
                {
                    /* Fail */
                    Status = STATUS_SERVER_SID_MISMATCH;
                }

                /* Free token information */
                ExFreePoolWithTag(TokenUserInfo, TAG_SE);
            }
        }
        else
        {
            /* Invalid SID */
            Status = STATUS_SERVER_SID_MISMATCH;
        }

        /* Check if SID failed */
        if (!NT_SUCCESS(Status))
        {
            /* Quit */
            ObDereferenceObject(Port);
            return Status;
        }
    }

    /* Create the client port */
    Status = ObCreateObject(PreviousMode,
                            LpcPortObjectType,
                            NULL,
                            PreviousMode,
                            NULL,
                            sizeof(LPCP_PORT_OBJECT),
                            0,
                            0,
                            (PVOID *)&ClientPort);
    if (!NT_SUCCESS(Status))
    {
        /* Failed, dereference the server port and return */
        ObDereferenceObject(Port);
        return Status;
    }

    /* Setup the client port */
    RtlZeroMemory(ClientPort, sizeof(LPCP_PORT_OBJECT));
    ClientPort->Flags = LPCP_CLIENT_PORT;
    ClientPort->ConnectionPort = Port;
    ClientPort->MaxMessageLength = Port->MaxMessageLength;
    ClientPort->SecurityQos = *Qos;
    InitializeListHead(&ClientPort->LpcReplyChainHead);
    InitializeListHead(&ClientPort->LpcDataInfoChainHead);

    /* Check if we have dynamic security */
    if (Qos->ContextTrackingMode == SECURITY_DYNAMIC_TRACKING)
    {
        /* Remember that */
        ClientPort->Flags |= LPCP_SECURITY_DYNAMIC;
    }
    else
    {
        /* Create our own client security */
        Status = SeCreateClientSecurity(Thread,
                                        Qos,
                                        FALSE,
                                        &ClientPort->StaticSecurity);
        if (!NT_SUCCESS(Status))
        {
            /* Security failed, dereference and return */
            ObDereferenceObject(ClientPort);
            return Status;
        }
    }

    /* Initialize the port queue */
    Status = LpcpInitializePortQueue(ClientPort);
    if (!NT_SUCCESS(Status))
    {
        /* Failed */
        ObDereferenceObject(ClientPort);
        return Status;
    }

    /* Check if we have a client view */
    if (ClientView)
    {
        /* Get the section handle */
        Status = ObReferenceObjectByHandle(ClientView->SectionHandle,
                                           SECTION_MAP_READ |
                                           SECTION_MAP_WRITE,
                                           MmSectionObjectType,
                                           PreviousMode,
                                           (PVOID*)&SectionToMap,
                                           NULL);
        if (!NT_SUCCESS(Status))
        {
            /* Fail */
            ObDereferenceObject(Port);
            return Status;
        }

        /* Set the section offset */
        SectionOffset.QuadPart = ClientView->SectionOffset;

        /* Map it */
        Status = MmMapViewOfSection(SectionToMap,
                                    PsGetCurrentProcess(),
                                    &ClientPort->ClientSectionBase,
                                    0,
                                    0,
                                    &SectionOffset,
                                    &ClientView->ViewSize,
                                    ViewUnmap,
                                    0,
                                    PAGE_READWRITE);

        /* Update the offset */
        ClientView->SectionOffset = SectionOffset.LowPart;

        /* Check for failure */
        if (!NT_SUCCESS(Status))
        {
            /* Fail */
            ObDereferenceObject(SectionToMap);
            ObDereferenceObject(Port);
            return Status;
        }

        /* Update the base */
        ClientView->ViewBase = ClientPort->ClientSectionBase;

        /* Reference and remember the process */
        ClientPort->MappingProcess = PsGetCurrentProcess();
        ObReferenceObject(ClientPort->MappingProcess);
    }
    else
    {
        /* No section */
        SectionToMap = NULL;
    }

    /* Normalize connection information */
    if (ConnectionInfoLength > Port->MaxConnectionInfoLength)
    {
        /* Use the port's maximum allowed value */
        ConnectionInfoLength = Port->MaxConnectionInfoLength;
    }

    /* Allocate a message from the port zone */
    Message = LpcpAllocateFromPortZone();
    if (!Message)
    {
        /* Fail if we couldn't allocate a message */
        if (SectionToMap) ObDereferenceObject(SectionToMap);
        ObDereferenceObject(ClientPort);
        return STATUS_NO_MEMORY;
    }

    /* Set pointer to the connection message and fill in the CID */
    ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1);
    Message->Request.ClientId = Thread->Cid;

    /* Check if we have a client view */
    if (ClientView)
    {
        /* Set the view size */
        Message->Request.ClientViewSize = ClientView->ViewSize;

        /* Copy the client view and clear the server view */
        RtlCopyMemory(&ConnectMessage->ClientView,
                      ClientView,
                      sizeof(PORT_VIEW));
        RtlZeroMemory(&ConnectMessage->ServerView, sizeof(REMOTE_PORT_VIEW));
    }
    else
    {
        /* Set the size to 0 and clear the connect message */
        Message->Request.ClientViewSize = 0;
        RtlZeroMemory(ConnectMessage, sizeof(LPCP_CONNECTION_MESSAGE));
    }

    /* Set the section and client port. Port is NULL for now */
    ConnectMessage->ClientPort = NULL;
    ConnectMessage->SectionToMap = SectionToMap;

    /* Set the data for the connection request message */
    Message->Request.u1.s1.DataLength = (CSHORT)ConnectionInfoLength +
                                         sizeof(LPCP_CONNECTION_MESSAGE);
    Message->Request.u1.s1.TotalLength = sizeof(LPCP_MESSAGE) +
                                         Message->Request.u1.s1.DataLength;
    Message->Request.u2.s2.Type = LPC_CONNECTION_REQUEST;

    /* Check if we have connection information */
    if (ConnectionInformation)
    {
        /* Copy it in */
        RtlCopyMemory(ConnectMessage + 1,
                      ConnectionInformation,
                      ConnectionInfoLength);
    }

    /* Acquire the port lock */
    KeAcquireGuardedMutex(&LpcpLock);

    /* Check if someone already deleted the port name */
    if (Port->Flags & LPCP_NAME_DELETED)
    {
        /* Fail the request */
        Status = STATUS_OBJECT_NAME_NOT_FOUND;
    }
    else
    {
        /* Associate no thread yet */
        Message->RepliedToThread = NULL;

        /* Generate the Message ID and set it */
        Message->Request.MessageId =  LpcpNextMessageId++;
        if (!LpcpNextMessageId) LpcpNextMessageId = 1;
        Thread->LpcReplyMessageId = Message->Request.MessageId;

        /* Insert the message into the queue and thread chain */
        InsertTailList(&Port->MsgQueue.ReceiveHead, &Message->Entry);
        InsertTailList(&Port->LpcReplyChainHead, &Thread->LpcReplyChain);
        Thread->LpcReplyMessage = Message;

        /* Now we can finally reference the client port and link it*/
        ObReferenceObject(ClientPort);
        ConnectMessage->ClientPort = ClientPort;

        /* Enter a critical region */
        KeEnterCriticalRegion();
    }

    /* Add another reference to the port */
    ObReferenceObject(Port);

    /* Release the lock */
    KeReleaseGuardedMutex(&LpcpLock);

    /* Check for success */
    if (NT_SUCCESS(Status))
    {
        LPCTRACE(LPC_CONNECT_DEBUG,
                 "Messages: %p/%p. Ports: %p/%p. Status: %lx\n",
                 Message,
                 ConnectMessage,
                 Port,
                 ClientPort,
                 Status);

        /* If this is a waitable port, set the event */
        if (Port->Flags & LPCP_WAITABLE_PORT) KeSetEvent(&Port->WaitEvent,
                                                         1,
                                                         FALSE);

        /* Release the queue semaphore and leave the critical region */
        LpcpCompleteWait(Port->MsgQueue.Semaphore);
        KeLeaveCriticalRegion();

        /* Now wait for a reply */
        LpcpConnectWait(&Thread->LpcReplySemaphore, PreviousMode);
    }

    /* Check for failure */
    if (!NT_SUCCESS(Status)) goto Cleanup;

    /* Free the connection message */
    SectionToMap = LpcpFreeConMsg(&Message, &ConnectMessage, Thread);

    /* Check if we got a message back */
    if (Message)
    {
        /* Check for new return length */
        if ((Message->Request.u1.s1.DataLength -
             sizeof(LPCP_CONNECTION_MESSAGE)) < ConnectionInfoLength)
        {
            /* Set new normalized connection length */
            ConnectionInfoLength = Message->Request.u1.s1.DataLength -
                                   sizeof(LPCP_CONNECTION_MESSAGE);
        }

        /* Check if we had connection information */
        if (ConnectionInformation)
        {
            /* Check if we had a length pointer */
            if (ConnectionInformationLength)
            {
                /* Return the length */
                *ConnectionInformationLength = ConnectionInfoLength;
            }

            /* Return the connection information */
            RtlCopyMemory(ConnectionInformation,
                          ConnectMessage + 1,
                          ConnectionInfoLength );
        }

        /* Make sure we had a connected port */
        if (ClientPort->ConnectedPort)
        {
            /* Get the message length before the port might get killed */
            PortMessageLength = Port->MaxMessageLength;

            /* Insert the client port */
            Status = ObInsertObject(ClientPort,
                                    NULL,
                                    PORT_ALL_ACCESS,
                                    0,
                                    (PVOID *)NULL,
                                    &Handle);
            if (NT_SUCCESS(Status))
            {
                /* Return the handle */
                *PortHandle = Handle;
                LPCTRACE(LPC_CONNECT_DEBUG,
                         "Handle: %p. Length: %lx\n",
                         Handle,
                         PortMessageLength);

                /* Check if maximum length was requested */
                if (MaxMessageLength) *MaxMessageLength = PortMessageLength;

                /* Check if we had a client view */
                if (ClientView)
                {
                    /* Copy it back */
                    RtlCopyMemory(ClientView,
                                  &ConnectMessage->ClientView,
                                  sizeof(PORT_VIEW));
                }

                /* Check if we had a server view */
                if (ServerView)
                {
                    /* Copy it back */
                    RtlCopyMemory(ServerView,
                                  &ConnectMessage->ServerView,
                                  sizeof(REMOTE_PORT_VIEW));
                }
            }
        }
        else
        {
            /* No connection port, we failed */
            if (SectionToMap) ObDereferenceObject(SectionToMap);

            /* Acquire the lock */
            KeAcquireGuardedMutex(&LpcpLock);

            /* Check if it's because the name got deleted */
            if (!(ClientPort->ConnectionPort) ||
                (Port->Flags & LPCP_NAME_DELETED))
            {
                /* Set the correct status */
                Status = STATUS_OBJECT_NAME_NOT_FOUND;
            }
            else
            {
                /* Otherwise, the caller refused us */
                Status = STATUS_PORT_CONNECTION_REFUSED;
            }

            /* Release the lock */
            KeReleaseGuardedMutex(&LpcpLock);

            /* Kill the port */
            ObDereferenceObject(ClientPort);
        }

        /* Free the message */
        LpcpFreeToPortZone(Message, 0);
    }
    else
    {
        /* No reply message, fail */
        if (SectionToMap) ObDereferenceObject(SectionToMap);
        ObDereferenceObject(ClientPort);
        Status = STATUS_PORT_CONNECTION_REFUSED;
    }

    /* Return status */
    ObDereferenceObject(Port);
    return Status;

Cleanup:
    /* We failed, free the message */
    SectionToMap = LpcpFreeConMsg(&Message, &ConnectMessage, Thread);

    /* Check if the semaphore got signaled */
    if (KeReadStateSemaphore(&Thread->LpcReplySemaphore))
    {
        /* Wait on it */
        KeWaitForSingleObject(&Thread->LpcReplySemaphore,
                              WrExecutive,
                              KernelMode,
                              FALSE,
                              NULL);
    }

    /* Check if we had a message and free it */
    if (Message) LpcpFreeToPortZone(Message, 0);

    /* Dereference other objects */
    if (SectionToMap) ObDereferenceObject(SectionToMap);
    ObDereferenceObject(ClientPort);

    /* Return status */
    ObDereferenceObject(Port);
    return Status;
}
Ejemplo n.º 6
0
NTSTATUS
	TdiSendMessage(
	   ULONG	Ip,
	   USHORT	Port,
	   PCHAR	Message,
	   ULONG	Length
	   )
			   
{
    PFILE_OBJECT ConnectionFileObject, AddressFileObject;
    HANDLE		AddressHandle, ConnectionHandle;
    CHAR		Buffer[80], Data[] = "Hello from Gary";
    NTSTATUS	Status;
    KEVENT		Done; 
	
	KeInitializeEvent(&Done, NotificationEvent, FALSE);

    Status = TdiCreateConnection(&ConnectionHandle, &ConnectionFileObject);
    if (!NT_SUCCESS(Status)) return Status;

    Status = TdiCreateAddress(&AddressHandle, &AddressFileObject, SOCK_STREAM, 0, 0);
    if (!NT_SUCCESS(Status)) return Status;

    do 
	{
		IO_STATUS_BLOCK IoStatus;
        KEVENT	Event;

		Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_DISCONNECT, TdiEventDisconnect, &Done);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_ERROR, TdiEventError, 0);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_RECEIVE, TdiEventReceive, 0);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiBind(ConnectionFileObject, AddressHandle);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiConnect(ConnectionFileObject, Ip, Port, NULL);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiSend(ConnectionFileObject, Message, Length);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiDisconnect(ConnectionFileObject);
        if (!NT_SUCCESS(Status)) break;

        KeWaitForSingleObject(&Done, UserRequest, KernelMode, FALSE, 0);

    } while (0);

    ObDereferenceObject(ConnectionFileObject);

    ObDereferenceObject(AddressFileObject);

    ZwClose(ConnectionHandle);

    ZwClose(AddressHandle);

    return Status;

}
Ejemplo n.º 7
0
NTSTATUS
XenUsb_Connect(PVOID context, BOOLEAN suspend) {
  NTSTATUS status;
  PXENUSB_DEVICE_DATA xudd = context;
  PFN_NUMBER pfn;
  ULONG i;

  if (!suspend) {
    xudd->handle = XnOpenDevice(xudd->pdo, XenUsb_DeviceCallback, xudd);
  }
  if (!xudd->handle) {
    FUNCTION_MSG("Cannot open Xen device\n");
    return STATUS_UNSUCCESSFUL;
  }

  if (xudd->device_state != DEVICE_STATE_INACTIVE) {
    for (i = 0; i <= 5 && xudd->backend_state != XenbusStateInitialising && xudd->backend_state != XenbusStateInitWait && xudd->backend_state != XenbusStateInitialised; i++) {
      FUNCTION_MSG("Waiting for XenbusStateInitXxx\n");
      if (xudd->backend_state == XenbusStateClosed) {
        status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "state", XenbusStateInitialising);
      }
      KeWaitForSingleObject(&xudd->backend_event, Executive, KernelMode, FALSE, NULL);
    }
    if (xudd->backend_state != XenbusStateInitialising && xudd->backend_state != XenbusStateInitWait && xudd->backend_state != XenbusStateInitialised) {
      FUNCTION_MSG("Backend state timeout\n");
      return STATUS_UNSUCCESSFUL;
    }
    if (!NT_SUCCESS(status = XnBindEvent(xudd->handle, &xudd->event_channel, XenUsb_HandleEvent_DIRQL, xudd))) {
      FUNCTION_MSG("Cannot allocate event channel\n");
      return STATUS_UNSUCCESSFUL;
    }
    FUNCTION_MSG("event_channel = %d\n", xudd->event_channel);
    status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "event-channel", xudd->event_channel);
    xudd->urb_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENUSB_POOL_TAG);
    if (!xudd->urb_sring) {
      FUNCTION_MSG("Cannot allocate urb_sring\n");
      return STATUS_UNSUCCESSFUL;
    }
    SHARED_RING_INIT(xudd->urb_sring);
    FRONT_RING_INIT(&xudd->urb_ring, xudd->urb_sring, PAGE_SIZE);
    pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xudd->urb_sring).QuadPart >> PAGE_SHIFT);
    FUNCTION_MSG("usb sring pfn = %d\n", (ULONG)pfn);
    xudd->urb_sring_gref = XnGrantAccess(xudd->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENUSB_POOL_TAG);
    FUNCTION_MSG("usb sring_gref = %d\n", xudd->urb_sring_gref);
    status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "urb-ring-ref", xudd->urb_sring_gref);  
    xudd->conn_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENUSB_POOL_TAG);
    if (!xudd->conn_sring) {
      FUNCTION_MSG("Cannot allocate conn_sring\n");
      return STATUS_UNSUCCESSFUL;
    }
    SHARED_RING_INIT(xudd->conn_sring);
    FRONT_RING_INIT(&xudd->conn_ring, xudd->conn_sring, PAGE_SIZE);
    pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xudd->conn_sring).QuadPart >> PAGE_SHIFT);
    FUNCTION_MSG("conn sring pfn = %d\n", (ULONG)pfn);
    xudd->conn_sring_gref = XnGrantAccess(xudd->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENUSB_POOL_TAG);
    FUNCTION_MSG("conn sring_gref = %d\n", xudd->conn_sring_gref);
    status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "conn-ring-ref", xudd->conn_sring_gref);  

    /* fill conn ring with requests */
    for (i = 0; i < USB_CONN_RING_SIZE; i++) {
      usbif_conn_request_t *req = RING_GET_REQUEST(&xudd->conn_ring, i);
      req->id = (uint16_t)i;
    }
    xudd->conn_ring.req_prod_pvt = i;

    status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected);
    for (i = 0; i <= 5 && xudd->backend_state != XenbusStateConnected; i++) {
      FUNCTION_MSG("Waiting for XenbusStateConnected\n");
      KeWaitForSingleObject(&xudd->backend_event, Executive, KernelMode, FALSE, NULL);
    }
    if (xudd->backend_state != XenbusStateConnected) {
      FUNCTION_MSG("Backend state timeout\n");
      return STATUS_UNSUCCESSFUL;
    }
    xudd->device_state = DEVICE_STATE_ACTIVE;
  }

  return STATUS_SUCCESS;
}
Ejemplo n.º 8
0
VOID
Secondary_Close (
	IN  PSECONDARY	Secondary
	)
{
	NTSTATUS		status;
	LARGE_INTEGER	timeOut;

	PLIST_ENTRY			secondaryRequestEntry;
	PSECONDARY_REQUEST	secondaryRequest;


	DebugTrace2( 0, Dbg2, 
				   ("Secondary close Secondary = %p\n", Secondary) );

	ExAcquireFastMutex( &Secondary->FastMutex );

	if (FlagOn(Secondary->Flags, SECONDARY_FLAG_CLOSED)) {

		//ASSERT( FALSE );
		ExReleaseFastMutex( &Secondary->FastMutex );
		return;
	}

	SetFlag( Secondary->Flags, SECONDARY_FLAG_CLOSED );

	ExReleaseFastMutex( &Secondary->FastMutex );

	if (Secondary->ThreadHandle == NULL) {

		Secondary_Dereference( Secondary );
		return;
	}

	ASSERT( Secondary->ThreadObject != NULL );

	DebugTrace2( 0, Dbg, ("Secondary close SECONDARY_REQ_DISCONNECT Secondary = %p\n", Secondary) );

	secondaryRequest = AllocSecondaryRequest( Secondary, 0, FALSE );
	secondaryRequest->RequestType = SECONDARY_REQ_DISCONNECT;

	QueueingSecondaryRequest( Secondary, secondaryRequest );

	secondaryRequest = AllocSecondaryRequest( Secondary, 0, FALSE );
	secondaryRequest->RequestType = SECONDARY_REQ_DOWN;

	QueueingSecondaryRequest( Secondary, secondaryRequest );

	DebugTrace2( 0, Dbg, ("Secondary close SECONDARY_REQ_DISCONNECT end Secondary = %p\n", Secondary) );

	timeOut.QuadPart = -NDASFAT_TIME_OUT;

	status = KeWaitForSingleObject( Secondary->ThreadObject,
									Executive,
									KernelMode,
									FALSE,
									&timeOut );

	if (status == STATUS_SUCCESS) {
	   
		DebugTrace2( 0, Dbg, ("Secondary_Close: thread stoped Secondary = %p\n", Secondary));

		ObDereferenceObject( Secondary->ThreadObject );

		Secondary->ThreadHandle = NULL;
		Secondary->ThreadObject = NULL;
	
	} else {

		ASSERT( NDASFAT_BUG );
		return;
	}

	ASSERT( Secondary->VolDo->Vcb.SecondaryOpenFileCount == 0 );

	ASSERT( IsListEmpty(&Secondary->FcbQueue) );
	ASSERT( IsListEmpty(&Secondary->RecoveryCcbQueue) );
	ASSERT( IsListEmpty(&Secondary->RequestQueue) );

	while (secondaryRequestEntry = ExInterlockedRemoveHeadList(&Secondary->RequestQueue,
															   &Secondary->RequestQSpinLock)) {

		PSECONDARY_REQUEST secondaryRequest2;

		InitializeListHead( secondaryRequestEntry );
			
		secondaryRequest2 = CONTAINING_RECORD( secondaryRequestEntry,
											   SECONDARY_REQUEST,
											   ListEntry );
        
		secondaryRequest2->ExecuteStatus = STATUS_IO_DEVICE_ERROR;
		
		if (secondaryRequest2->Synchronous == TRUE)
			KeSetEvent( &secondaryRequest2->CompleteEvent, IO_DISK_INCREMENT, FALSE );
		else
			DereferenceSecondaryRequest( secondaryRequest2 );
	}
	
	Secondary_Dereference( Secondary );

	return;
}
Ejemplo n.º 9
0
void
AFSDumpTraceFiles()
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    HANDLE hDirectory = NULL;
    OBJECT_ATTRIBUTES   stObjectAttribs;
    IO_STATUS_BLOCK stIoStatus;
    LARGE_INTEGER liTime, liLocalTime;
    TIME_FIELDS timeFields;
    ULONG ulBytesWritten = 0;
    HANDLE hDumpFile = NULL;
    ULONG ulBytesProcessed, ulCopyLength;
    LARGE_INTEGER liOffset;
    ULONG ulDumpLength = 0;
    BOOLEAN bSetEvent = FALSE;

    __Enter
    {

        AFSAcquireShared( &AFSDbgLogLock,
                          TRUE);

        ulDumpLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;

        AFSReleaseResource( &AFSDbgLogLock);

        if( AFSDumpFileLocation.Length == 0 ||
            AFSDumpFileLocation.Buffer == NULL ||
            AFSDbgBufferLength == 0 ||
            ulDumpLength == 0 ||
            AFSDumpFileName.MaximumLength == 0 ||
            AFSDumpFileName.Buffer == NULL ||
            AFSDumpBuffer == NULL)
        {
            try_return( ntStatus);
        }

        //
        // Go open the cache file
        //

        InitializeObjectAttributes( &stObjectAttribs,
                                    &AFSDumpFileLocation,
                                    OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                    NULL,
                                    NULL);

        ntStatus = ZwCreateFile( &hDirectory,
                                 GENERIC_READ | GENERIC_WRITE,
                                 &stObjectAttribs,
                                 &stIoStatus,
                                 NULL,
                                 0,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 FILE_OPEN,
                                 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                                 NULL,
                                 0);

        if( !NT_SUCCESS( ntStatus))
        {

            try_return( ntStatus);
        }

        ntStatus = KeWaitForSingleObject( &AFSDumpFileEvent,
                                          Executive,
                                          KernelMode,
                                          FALSE,
                                          NULL);

        if( !NT_SUCCESS( ntStatus))
        {

            try_return( ntStatus);
        }

        bSetEvent = TRUE;

        AFSDumpFileName.Length = 0;

        RtlZeroMemory( AFSDumpFileName.Buffer,
                       AFSDumpFileName.MaximumLength);

        KeQuerySystemTime( &liTime);

        ExSystemTimeToLocalTime( &liTime,
                                 &liLocalTime);

        RtlTimeToTimeFields( &liLocalTime,
                             &timeFields);

        ntStatus = RtlStringCchPrintfW( AFSDumpFileName.Buffer,
                                        AFSDumpFileName.MaximumLength/sizeof( WCHAR),
                                        L"AFSDumpFile %d.%d.%d %d.%d.%d.log",
                                                  timeFields.Month,
                                                  timeFields.Day,
                                                  timeFields.Year,
                                                  timeFields.Hour,
                                                  timeFields.Minute,
                                                  timeFields.Second);

        if( !NT_SUCCESS( ntStatus))
        {
            try_return( ntStatus);
        }

        RtlStringCbLengthW( AFSDumpFileName.Buffer,
                            AFSDumpFileName.MaximumLength,
                            (size_t *)&ulBytesWritten);

        AFSDumpFileName.Length = (USHORT)ulBytesWritten;

        InitializeObjectAttributes( &stObjectAttribs,
                                    &AFSDumpFileName,
                                    OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                    hDirectory,
                                    NULL);

        ntStatus = ZwCreateFile( &hDumpFile,
                                 GENERIC_READ | GENERIC_WRITE,
                                 &stObjectAttribs,
                                 &stIoStatus,
                                 NULL,
                                 0,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 FILE_CREATE,
                                 FILE_SYNCHRONOUS_IO_NONALERT,
                                 NULL,
                                 0);

        if( !NT_SUCCESS( ntStatus))
        {
            try_return( ntStatus);
        }

        //
        // Write out the trace buffer
        //

        liOffset.QuadPart = 0;

        ulBytesProcessed = 0;

        while( ulBytesProcessed < ulDumpLength)
        {

            ulCopyLength = AFSDumpBufferLength;

            if( ulCopyLength > ulDumpLength - ulBytesProcessed)
            {
                ulCopyLength = ulDumpLength - ulBytesProcessed;
            }

            RtlCopyMemory( AFSDumpBuffer,
                           (void *)((char *)AFSDbgBuffer + ulBytesProcessed),
                           ulCopyLength);

            ntStatus = ZwWriteFile( hDumpFile,
                                    NULL,
                                    NULL,
                                    NULL,
                                    &stIoStatus,
                                    AFSDumpBuffer,
                                    ulCopyLength,
                                    &liOffset,
                                    NULL);

            if( !NT_SUCCESS( ntStatus))
            {
                break;
            }

            liOffset.QuadPart += ulCopyLength;

            ulBytesProcessed += ulCopyLength;
        }

try_exit:

        if( hDumpFile != NULL)
        {
            ZwClose( hDumpFile);
        }

        if( hDirectory != NULL)
        {
            ZwClose( hDirectory);
        }

        if( bSetEvent)
        {
            KeSetEvent( &AFSDumpFileEvent,
                        0,
                        FALSE);
        }
    }

    return;
}
Ejemplo n.º 10
0
int KbFilter_PnP(int DeviceObject , int Irp ) 
{ int devExt ;
  int irpStack ;
  int status ;
  int event = __VERIFIER_nondet_int() ;
  int DeviceObject__DeviceExtension = __VERIFIER_nondet_int() ;
  int Irp__Tail__Overlay__CurrentStackLocation = __VERIFIER_nondet_int() ;
  int irpStack__MinorFunction = __VERIFIER_nondet_int() ;
  int devExt__TopOfStack = __VERIFIER_nondet_int() ;
  int devExt__Started ;
  int devExt__Removed ;
  int devExt__SurpriseRemoved ;
  int Irp__IoStatus__Status ;
  int Irp__IoStatus__Information ;
  int Irp__CurrentLocation = __VERIFIER_nondet_int() ;
  int irpSp ;
  int nextIrpSp ;
  int nextIrpSp__Control ;
  int irpSp___0 ;
  int irpSp__Context ;
  int irpSp__Control ;
  long __cil_tmp23 ;

  {
#line 107
  status = 0;
#line 108
  devExt = DeviceObject__DeviceExtension;
#line 109
  irpStack = Irp__Tail__Overlay__CurrentStackLocation;
#line 110
  if (irpStack__MinorFunction == 0) {
    goto switch_0_0;
  } else {
#line 113
    if (irpStack__MinorFunction == 23) {
      goto switch_0_23;
    } else {
#line 116
      if (irpStack__MinorFunction == 2) {
        goto switch_0_2;
      } else {
#line 119
        if (irpStack__MinorFunction == 1) {
          goto switch_0_1;
        } else {
#line 122
          if (irpStack__MinorFunction == 5) {
            goto switch_0_1;
          } else {
#line 125
            if (irpStack__MinorFunction == 3) {
              goto switch_0_1;
            } else {
#line 128
              if (irpStack__MinorFunction == 6) {
                goto switch_0_1;
              } else {
#line 131
                if (irpStack__MinorFunction == 13) {
                  goto switch_0_1;
                } else {
#line 134
                  if (irpStack__MinorFunction == 4) {
                    goto switch_0_1;
                  } else {
#line 137
                    if (irpStack__MinorFunction == 7) {
                      goto switch_0_1;
                    } else {
#line 140
                      if (irpStack__MinorFunction == 8) {
                        goto switch_0_1;
                      } else {
#line 143
                        if (irpStack__MinorFunction == 9) {
                          goto switch_0_1;
                        } else {
#line 146
                          if (irpStack__MinorFunction == 12) {
                            goto switch_0_1;
                          } else {
#line 149
                            if (irpStack__MinorFunction == 10) {
                              goto switch_0_1;
                            } else {
#line 152
                              if (irpStack__MinorFunction == 11) {
                                goto switch_0_1;
                              } else {
#line 155
                                if (irpStack__MinorFunction == 15) {
                                  goto switch_0_1;
                                } else {
#line 158
                                  if (irpStack__MinorFunction == 16) {
                                    goto switch_0_1;
                                  } else {
#line 161
                                    if (irpStack__MinorFunction == 17) {
                                      goto switch_0_1;
                                    } else {
#line 164
                                      if (irpStack__MinorFunction == 18) {
                                        goto switch_0_1;
                                      } else {
#line 167
                                        if (irpStack__MinorFunction == 19) {
                                          goto switch_0_1;
                                        } else {
#line 170
                                          if (irpStack__MinorFunction == 20) {
                                            goto switch_0_1;
                                          } else {
                                            goto switch_0_1;
#line 175
                                            if (0) {
                                              switch_0_0: 
#line 177
                                              irpSp = Irp__Tail__Overlay__CurrentStackLocation;
#line 178
                                              nextIrpSp = Irp__Tail__Overlay__CurrentStackLocation - 1;
#line 179
                                              nextIrpSp__Control = 0;
#line 180
                                              if (s != NP) {
                                                {
#line 182
                                                errorFn();
                                                }
                                              } else {
#line 185
                                                if (compRegistered != 0) {
                                                  {
#line 187
                                                  errorFn();
                                                  }
                                                } else {
#line 190
                                                  compRegistered = 1;
                                                }
                                              }
                                              {
#line 194
                                              irpSp___0 = Irp__Tail__Overlay__CurrentStackLocation - 1;
#line 195
                                              irpSp__Context = event;
#line 196
                                              irpSp__Control = 224;
#line 200
                                              status = IofCallDriver(devExt__TopOfStack,
                                                                     Irp);
                                              }
                                              {
#line 203
                                              __cil_tmp23 = (long )status;
#line 203
                                              if (__cil_tmp23 == 259) {
                                                {
#line 205
                                                KeWaitForSingleObject(event, Executive,
                                                                      KernelMode,
                                                                      0, 0);
                                                }
                                              }
                                              }
#line 212
                                              if (status >= 0) {
#line 213
                                                if (myStatus >= 0) {
#line 214
                                                  devExt__Started = 1;
#line 215
                                                  devExt__Removed = 0;
#line 216
                                                  devExt__SurpriseRemoved = 0;
                                                }
                                              }
                                              {
#line 224
                                              Irp__IoStatus__Status = status;
#line 225
                                              myStatus = status;
#line 226
                                              Irp__IoStatus__Information = 0;
#line 227
                                              IofCompleteRequest(Irp, 0);
                                              }
                                              goto switch_0_break;
                                              switch_0_23: 
#line 231
                                              devExt__SurpriseRemoved = 1;
#line 232
                                              if (s == NP) {
#line 233
                                                s = SKIP1;
                                              } else {
                                                {
#line 236
                                                errorFn();
                                                }
                                              }
                                              {
#line 240
                                              Irp__CurrentLocation ++;
#line 241
                                              Irp__Tail__Overlay__CurrentStackLocation ++;
#line 242
                                              status = IofCallDriver(devExt__TopOfStack,
                                                                     Irp);
                                              }
                                              goto switch_0_break;
                                              switch_0_2: 
#line 247
                                              devExt__Removed = 1;
#line 248
                                              if (s == NP) {
#line 249
                                                s = SKIP1;
                                              } else {
                                                {
#line 252
                                                errorFn();
                                                }
                                              }
                                              {
#line 256
                                              Irp__CurrentLocation ++;
#line 257
                                              Irp__Tail__Overlay__CurrentStackLocation ++;
#line 258
                                              IofCallDriver(devExt__TopOfStack, Irp);
#line 259
                                              status = 0;
                                              }
                                              goto switch_0_break;
                                              switch_0_1: ;
#line 281
                                              if (s == NP) {
#line 282
                                                s = SKIP1;
                                              } else {
                                                {
#line 285
                                                errorFn();
                                                }
                                              }
                                              {
#line 289
                                              Irp__CurrentLocation ++;
#line 290
                                              Irp__Tail__Overlay__CurrentStackLocation ++;
#line 291
                                              status = IofCallDriver(devExt__TopOfStack,
                                                                     Irp);
                                              }
                                              goto switch_0_break;
                                            } else {
                                              switch_0_break: ;
                                            }
                                          }
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
#line 320
  return (status);
}
}
Ejemplo n.º 11
0
PSECONDARY
Secondary_Create (
	IN  PIRP_CONTEXT			IrpContext,
	IN	PVOLUME_DEVICE_OBJECT	VolDo		 
	)
{
	NTSTATUS			status;
	PSECONDARY			secondary;

	OBJECT_ATTRIBUTES	objectAttributes;
	LARGE_INTEGER		timeOut;
	ULONG				tryQuery;
	BOOLEAN				isLocalAddress;
	

	UNREFERENCED_PARAMETER( IrpContext );

	secondary = ExAllocatePoolWithTag( NonPagedPool, sizeof(SECONDARY), NDASFAT_ALLOC_TAG );
	
	if (secondary == NULL) {

		ASSERT( NDASFAT_INSUFFICIENT_RESOURCES );
		return NULL;
	}
	
	RtlZeroMemory( secondary, sizeof(SECONDARY) );

#define MAX_TRY_QUERY 2

	for (tryQuery = 0; tryQuery < MAX_TRY_QUERY; tryQuery++) {

		secondary->NumberOfPrimaryAddress = 0;

		status = ((PVOLUME_DEVICE_OBJECT) FatData.DiskFileSystemDeviceObject)->
			NdfsCallback.QueryPrimaryAddress( &VolDo->NetdiskPartitionInformation, 
											  secondary->PrimaryAddressList, 
											  &secondary->NumberOfPrimaryAddress, 
											  &isLocalAddress );

		DebugTrace2( 0, Dbg2, ("Secondary_Create: QueryPrimaryAddress %08x\n", status) );

		if (NT_SUCCESS(status)) {

			LONG i;

			NDAS_ASSERT( secondary->NumberOfPrimaryAddress );

			for (i = 0; i < secondary->NumberOfPrimaryAddress; i++) {

				DebugTrace2( 0, Dbg2, 
							   ("Secondary_Create: QueryPrimaryAddress: Found PrimaryAddress[%d] :%02x:%02x:%02x:%02x:%02x:%02x/%d\n",
							    i,
								secondary->PrimaryAddressList[i].Node[0], secondary->PrimaryAddressList[i].Node[1],
								secondary->PrimaryAddressList[i].Node[2], secondary->PrimaryAddressList[i].Node[3],
								secondary->PrimaryAddressList[i].Node[4], secondary->PrimaryAddressList[i].Node[5],
								NTOHS(secondary->PrimaryAddressList[i].Port)) );
			}

			break;
		}
	}

	if (status != STATUS_SUCCESS || isLocalAddress) {

		ExFreePoolWithTag( secondary, NDASFAT_ALLOC_TAG );
		return NULL;
	}

	secondary->Flags = SECONDARY_FLAG_INITIALIZING;

#if 0
	ExInitializeResourceLite( &secondary->RecoveryResource );
	ExInitializeResourceLite( &secondary->Resource );
	ExInitializeResourceLite( &secondary->SessionResource );
	ExInitializeResourceLite( &secondary->CreateResource );
#endif

	ExInitializeFastMutex( &secondary->FastMutex );

	secondary->ReferenceCount = 1;

	VolDo_Reference( VolDo );
	secondary->VolDo = VolDo;

	secondary->ThreadHandle = NULL;

	InitializeListHead( &secondary->RecoveryCcbQueue );
    ExInitializeFastMutex( &secondary->RecoveryCcbQMutex );

	InitializeListHead( &secondary->DeletedFcbQueue );

	KeQuerySystemTime( &secondary->TryCloseTime );

	secondary->TryCloseWorkItem = IoAllocateWorkItem( (PDEVICE_OBJECT)VolDo );

	KeInitializeEvent( &secondary->ReadyEvent, NotificationEvent, FALSE );
    
	InitializeListHead( &secondary->RequestQueue );
	KeInitializeSpinLock( &secondary->RequestQSpinLock );
	KeInitializeEvent( &secondary->RequestEvent, NotificationEvent, FALSE );

	InitializeListHead( &secondary->FcbQueue );
	ExInitializeFastMutex( &secondary->FcbQMutex );

	KeInitializeEvent( &secondary->RecoveryReadyEvent, NotificationEvent, FALSE );

	InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );

	secondary->SessionId = 0;
	
	status = PsCreateSystemThread( &secondary->ThreadHandle,
								   THREAD_ALL_ACCESS,
								   &objectAttributes,
								   NULL,
								   NULL,
								   SecondaryThreadProc,
								   secondary );

	if (!NT_SUCCESS(status)) {

		ASSERT( NDASFAT_UNEXPECTED );
		Secondary_Close( secondary );
		
		return NULL;
	}

	status = ObReferenceObjectByHandle( secondary->ThreadHandle,
										FILE_READ_DATA,
										NULL,
										KernelMode,
										&secondary->ThreadObject,
										NULL );

	if (!NT_SUCCESS(status)) {

		ASSERT( NDASFAT_INSUFFICIENT_RESOURCES );
		Secondary_Close( secondary );
		
		return NULL;
	}

	secondary->SessionId ++;

	timeOut.QuadPart = -NDASFAT_TIME_OUT;		
	status = KeWaitForSingleObject( &secondary->ReadyEvent,
									Executive,
									KernelMode,
									FALSE,
									&timeOut );

	if (status != STATUS_SUCCESS) {
	
		NDAS_ASSERT( FALSE );
		Secondary_Close( secondary );
		
		return NULL;
	}

	KeClearEvent( &secondary->ReadyEvent );

	ExAcquireFastMutex( &secondary->FastMutex );

	if (!FlagOn(secondary->Thread.Flags, SECONDARY_THREAD_FLAG_START) ||
		FlagOn(secondary->Thread.Flags, SECONDARY_THREAD_FLAG_STOPED)) {

		if (secondary->Thread.SessionStatus != STATUS_DISK_CORRUPT_ERROR &&
			secondary->Thread.SessionStatus != STATUS_UNRECOGNIZED_VOLUME) {
	
			ExReleaseFastMutex( &secondary->FastMutex );

			Secondary_Close( secondary );
			return NULL;
		}
	} 

	ASSERT( secondary->Thread.SessionContext.SessionSlotCount != 0 );

	ClearFlag( secondary->Flags, SECONDARY_FLAG_INITIALIZING );
	SetFlag( secondary->Flags, SECONDARY_FLAG_START );

	ExReleaseFastMutex( &secondary->FastMutex );

	DebugTrace2( 0, Dbg2,
				("Secondary_Create: The client thread are ready secondary = %p\n", secondary) );

	return secondary;
}
Ejemplo n.º 12
0
VOID
LspPollingThread(
    IN PVOID Context
    )
/*++

Routine Description:

    This is the main thread that removes IRP from the queue
    and peforms I/O on it.

Arguments:

    Context     -- pointer to the device object

--*/
{
    PDEVICE_OBJECT DeviceObject = Context;  
    PDEVICE_EXTENSION DevExtension =  DeviceObject->DeviceExtension;
    PIRP Irp;
    NTSTATUS    Status;
    
    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY );

    //
    // Now enter the main IRP-processing loop
    //
    while( TRUE )
    {
        //
        // Wait indefinitely for an IRP to appear in the work queue or for
        // the Unload routine to stop the thread. Every successful return 
        // from the wait decrements the semaphore count by 1.
        //
        KeWaitForSingleObject(
			&DevExtension->IrpQueueSemaphore,
            Executive,
            KernelMode,
            FALSE,
            NULL );

        //
        // See if thread was awakened because driver is unloading itself...
        //
        
        if( DevExtension->ThreadShouldStop ) 
		{
            PsTerminateSystemThread( STATUS_SUCCESS );
        }

        //
        // Remove a pending IRP from the queue.
        //
        Irp = IoCsqRemoveNextIrp(&DevExtension->CancelSafeQueue, NULL);

        if(!Irp) 
		{
            LSP_KDPRINT(("Oops, a queued irp got cancelled\n"));
            continue; // go back to waiting
        }
        
        while(TRUE) 
		{ 
            //
            // Perform I/O
            //
            Status = LspPollDevice(DeviceObject, Irp);
            if(Status == STATUS_PENDING) 
			{
                // 
                // Device is not ready, so sleep for a while and try again.
                //
                KeDelayExecutionThread(
					KernelMode, 
					FALSE,
                    &DevExtension->PollingInterval);
                
            }
			else 
			{
                //
                // I/O is successful, so complete the Irp.
                //
                Irp->IoStatus.Status = Status;
                IoCompleteRequest (Irp, IO_NO_INCREMENT);
                break; 
            }

        }
        //
        // Go back to the top of the loop to see if there's another request waiting.
        //
    } // end of while-loop
}
Ejemplo n.º 13
0
VOID
LspUnload(
    IN PDRIVER_OBJECT DriverObject
    )
/*++

Routine Description:

    Free all the allocated resources, etc.

Arguments:

    DriverObject - pointer to a driver object.

Return Value:

    VOID
--*/
{
	NTSTATUS status;
    PDEVICE_OBJECT       deviceObject = DriverObject->DeviceObject;
    UNICODE_STRING      uniWin32NameString;
    PDEVICE_EXTENSION    deviceExtension = deviceObject->DeviceExtension;

    PAGED_CODE();

    LSP_KDPRINT(("LspUnload Enter\n"));

    //
    // Set the Stop flag
    //
    deviceExtension->ThreadShouldStop = TRUE;

    //
    // Make sure the thread wakes up 
    //
    KeReleaseSemaphore(&deviceExtension->IrpQueueSemaphore,
                        0,  // No priority boost
                        1,  // Increment semaphore by 1
                        TRUE );// WaitForXxx after this call

    //
    // Wait for the thread to terminate
    //
    KeWaitForSingleObject(deviceExtension->ThreadObject,
                        Executive,
                        KernelMode,
                        FALSE,
                        NULL );

    ObDereferenceObject(deviceExtension->ThreadObject);

	IoFreeWorkItem(deviceExtension->CloseWorkItem);

    //
    // Create counted string version of our Win32 device name.
    //

    RtlInitUnicodeString( &uniWin32NameString, LSP_DOS_DEVICE_NAME_U );

    IoDeleteSymbolicLink( &uniWin32NameString );

    ASSERT(!deviceObject->AttachedDevice);
    
    IoDeleteDevice( deviceObject );
 
    LSP_KDPRINT(("LspUnload Exit\n"));
    return;
}
Ejemplo n.º 14
0
BOOLEAN
TtdiReceive()
{
    USHORT i, Iteration, Increment;
    SHORT j,k;
    HANDLE SvrHandle, SvrConnectionHandle;
    PFILE_OBJECT AddressObject, ConnectionObject;
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
    PMDL SendMdl, ReceiveMdl;
    IO_STATUS_BLOCK Iosb1;
    TDI_CONNECTION_INFORMATION RequestInformation;
    TDI_CONNECTION_INFORMATION ReturnInformation;
    PTRANSPORT_ADDRESS ListenBlock;
    PTRANSPORT_ADDRESS ConnectBlock;
    PTDI_ADDRESS_NETBIOS temp;
    PUCHAR MessageBuffer;
    ULONG MessageBufferLength;
    ULONG CurrentBufferLength;
    PUCHAR SendBuffer;
    ULONG SendBufferLength;
    PIRP Irp;
    KEVENT Event1;

    Status = KeWaitForSingleObject (&TdiReceiveEvent, Suspended, KernelMode, FALSE, NULL);

    SendBufferLength = (ULONG)BUFFER_SIZE;
    MessageBufferLength = (ULONG)BUFFER_SIZE;


    DbgPrint( "\n****** Start of Receive Test ******\n" );

    XBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
    if (XBuff == (PVOID)NULL) {
        DbgPrint ("Unable to allocate nonpaged pool for send buffer exiting\n");
        return FALSE;
    }
    RBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
    if (RBuff == (PVOID)NULL) {
        DbgPrint ("Unable to allocate nonpaged pool for receive buffer exiting\n");
        return FALSE;
    }

    ListenBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));
    ConnectBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));

    ListenBlock->TAAddressCount = 1;
    ListenBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ListenBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ListenBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = ClientName[i];
    }

    ConnectBlock->TAAddressCount = 1;
    ConnectBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ConnectBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ConnectBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = ServerName[i];
    }

    //
    // Create an event for the synchronous I/O requests that we'll be issuing.
    //

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Status = TtdiOpenAddress (&SvrHandle, ServerName);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on open of server Address: %lC ******\n", Status );
        return FALSE;
    }

    Status = ObReferenceObjectByHandle (
                SvrHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &AddressObject,
                NULL);

    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on open of server Address: %lC ******\n", Status );
        return FALSE;
    }

    Status = TtdiOpenConnection (&SvrConnectionHandle, 2);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on open of server Connection: %lC ******\n", Status );
        return FALSE;
    }

    Status = ObReferenceObjectByHandle (
                SvrConnectionHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &ConnectionObject,
                NULL);

    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on open of server Connection: %lC ******\n", Status );
        return FALSE;
    }

    //
    // Get a pointer to the stack location for the first driver.  This will be
    // used to pass the original function codes and parameters.
    //

    DeviceObject = IoGetRelatedDeviceObject( ConnectionObject );


    Irp = TdiBuildInternalDeviceControlIrp (
                TDI_ASSOCIATE_ADDRESS,
                DeviceObject,
                ConnectionObject,
                &Event1,
                &Iosb1);

    DbgPrint ("Build Irp %lx, Handle %lx \n",
            Irp, SvrHandle);

    TdiBuildAssociateAddress (
        Irp,
        DeviceObject,
        ConnectionObject,
        TSTRCVCompletion,
        &Event1,
        SvrHandle);
    InitWaitObject (&Event1);

    {
        PULONG Temp=(PULONG)IoGetNextIrpStackLocation (Irp);
        DbgPrint ("Built IrpSp %lx %lx %lx %lx %lx \n", *(Temp++),  *(Temp++),
            *(Temp++), *(Temp++), *(Temp++));
    }

    Status = IoCallDriver (DeviceObject, Irp);

//    IoFreeIrp (Irp);

    if (Status == STATUS_PENDING) {
        Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Associate: %lC ******\n", Status );
            return FALSE;
        }
        if (!NT_SUCCESS(Iosb1.Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Associate Iosb status: %lC ******\n", Status );
            return FALSE;
        }

    } else {
        if (!NT_SUCCESS (Status)) {
            DbgPrint( "\n****** Receive Test:  AssociateAddress FAILED  Status: %lC ******\n", Status );
            return FALSE;
        } else {
            DbgPrint ("********** Receive Test:  Success AssociateAddress\n");
        }
    }

    RequestInformation.RemoteAddress = ConnectBlock;
    RequestInformation.RemoteAddressLength = sizeof (TRANSPORT_ADDRESS) +
                                            sizeof (TDI_ADDRESS_NETBIOS);

    //
    // Post a TdiListen to the server endpoint.
    //

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Irp = TdiBuildInternalDeviceControlIrp (
                TDI_LISTEN,
                DeviceObject,
                ConnectionObject,
                &Event1,
                &Iosb1);

    TdiBuildListen (
        Irp,
        DeviceObject,
        ConnectionObject,
        TSTRCVCompletion,
        &Event1,
        0,
        &RequestInformation,
        &ReturnInformation);
    InitWaitObject (&Event1);

    Status = IoCallDriver (DeviceObject, Irp);

//    IoFreeIrp (Irp);

    if (Status == STATUS_PENDING) {
        Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Listen: %lC ******\n", Status );
            return FALSE;
        }
        if (!NT_SUCCESS(Iosb1.Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Listen Iosb status: %lC ******\n", Status );
            return FALSE;
        } else {
            DbgPrint ("********** Receive Test:  Success Listen IOSB\n");
        }

    } else {
        if (!NT_SUCCESS (Status)) {
            DbgPrint( "\n****** Receive Test: Listen FAILED  Status: %lC ******\n", Status );
            return FALSE;
        } else {
            DbgPrint ("********** Receive Test:  Success Listen Immediate\n");
        }
    }


    DbgPrint ("\n****** Receive Test: LISTEN just completed! ******\n");

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Irp = TdiBuildInternalDeviceControlIrp (
                TDI_ACCEPT,
                DeviceObject,
                ConnectionObject,
                &Event1,
                &Iosb1);

    TdiBuildAccept (Irp, DeviceObject, ConnectionObject, NULL, NULL, &RequestInformation, NULL, 0);
    InitWaitObject (&Event1);

    Status = IoCallDriver (DeviceObject, Irp);

//    IoFreeIrp (Irp);

    if (Status == STATUS_PENDING) {
        Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Accept: %lC ******\n", Status );
            return FALSE;
        }
        if (!NT_SUCCESS(Iosb1.Status)) {
            DbgPrint( "\n****** Receive Test:  FAILED Accept Iosb status: %lC ******\n", Status );
            return FALSE;
        }

    } else {
        if (!NT_SUCCESS (Status)) {
            DbgPrint( "\n****** Receive Test: Accept FAILED  Status: %lC ******\n", Status );
            return FALSE;
        }
    }

    //
    // We have the connection data now.  Sanity check it.
    //

    DbgPrint ("\n****** Receive Test:  LISTEN completed successfully! ******\n");

    //
    // Receive/receive 1 or  10 messages.
    //

    SendBuffer =  (PUCHAR)ExAllocatePool (NonPagedPool, SendBufferLength);
    if (SendBuffer == NULL) {
        DbgPrint ("\n****** Send Test:  ExAllocatePool failed! ******\n");
    }
    SendMdl = IoAllocateMdl (SendBuffer, SendBufferLength, FALSE, FALSE, NULL);
    MmBuildMdlForNonPagedPool (SendMdl);

    MessageBuffer=(PUCHAR)ExAllocatePool (NonPagedPool, MessageBufferLength);
    if (MessageBuffer == NULL) {
        DbgPrint ("\n****** Send Test:  ExAllocatePool failed! ******\n");
    }
    ReceiveMdl = IoAllocateMdl (MessageBuffer, MessageBufferLength, FALSE, FALSE, NULL);
    MmBuildMdlForNonPagedPool (ReceiveMdl);

    //
    // Cycle the buffer length from 0 up through the maximum for Tdi. after a
    // couple of shots at the full range in one byte steps, increment by ever
    // increasing amounts to get to the max.
    //

    CurrentBufferLength = 0;
    Increment = 1;
    for (Iteration=1; Iteration<(USHORT)c9_Iteration; Iteration++) {
        CurrentBufferLength += Increment;
        if (CurrentBufferLength > MessageBufferLength) {
            CurrentBufferLength = 0;
            Increment = 1;
        }
        if (CurrentBufferLength > 7500) {
            Increment++;
        }
        if ((USHORT)((Iteration / 100) * 100) == Iteration) {
            DbgPrint ("Iteration #%d Buffer Length: %lx Buffer Start: %x\n",
                Iteration, CurrentBufferLength,Iteration % 256);
        }
        for (i=0; i<(USHORT)CurrentBufferLength; i++) {
            SendBuffer [i] = (UCHAR)(i + Iteration % 256 );
            MessageBuffer [i] = 0;            // zap this sucker with something.
        }

        KeInitializeEvent (
                    &Event1,
                    SynchronizationEvent,
                    FALSE);

        Irp = TdiBuildInternalDeviceControlIrp (
                    TDI_RECEIVE,
                    DeviceObject,
                    ConnectionObject,
                    &Event1,
                    &Iosb1);

        TdiBuildReceive (Irp,
            DeviceObject,
            ConnectionObject,
            TSTRCVCompletion,
            &Event1,
            ReceiveMdl,
            MessageBufferLength);

        InitWaitObject (&Event1);

        Status = IoCallDriver (DeviceObject, Irp);

//        IoFreeIrp (Irp);

        if (Status == STATUS_PENDING) {
            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
            if (!NT_SUCCESS(Status)) {
                DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Receive: %lC ******\n", Status );
                return FALSE;
            }
            if (!NT_SUCCESS(Iosb1.Status)) {
                DbgPrint( "\n****** Receive Test:  FAILED Receive Iosb status: %lC ******\n", Status );
                return FALSE;
            }

        } else {
            if (!NT_SUCCESS (Status)) {
                DbgPrint( "\n****** Receive Test: Listen FAILED  Status: %lC ******\n", Status );
                return FALSE;
            }
        }

        //
        // The receive completed.  Make sure the data is correct.
        //

        if (Iosb1.Information != CurrentBufferLength) {
            DbgPrint ("Iteration #%d Buffer Length: %lx Buffer Start: %x\n",
                Iteration, CurrentBufferLength,Iteration % 256);
            DbgPrint ("ReceiveTest: Bytes received <> bytes sent.\n");
            DbgPrint ("ReceiveTest: BytesToSend=%ld.  BytesReceived=%ld.\n",
                      CurrentBufferLength, Iosb1.Information);
        }

        if (i == (USHORT)CurrentBufferLength) {
//                DbgPrint ("ReceiveTest: Message contains correct data.\n");
        } else {
            DbgPrint ("ReceiveTest: Message data corrupted at offset %lx of %lx.\n", (ULONG)i, (ULONG)SendBufferLength);
            DbgPrint ("ReceiveTest: Data around corrupted location:\n");
            for (j=-4;j<=3;j++) {
                DbgPrint ("%08lx  ", (ULONG) i+j*16);
                for (k=(SHORT)i+(j*(SHORT)16);k<(SHORT)i+((j+(SHORT)1)*(SHORT)16);k++) {
                    DbgPrint ("%02x",MessageBuffer [k]);
                }
                for (k=(SHORT)i+(j*(SHORT)16);k<(SHORT)i+((j+(SHORT)1)*(SHORT)16);k++) {
                    DbgPrint ("%c",MessageBuffer [k]);
                }
                DbgPrint ("\n");
            }
            DbgPrint ("ReceiveTest: End of Corrupt Data.\n");
        }
    }

    //
    // We're done with this endpoint.  Close it and get out.
    //

    Status = CloseAddress (SvrHandle);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Receive Test:  FAILED on 1st Close: %lC ******\n", Status );
        return FALSE;
    }

    DbgPrint( "\n****** End of Receive Test ******\n" );
    return TRUE;
} /* Receive */
Ejemplo n.º 15
0
NTSTATUS
RawClose (
    IN PVCB Vcb,
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpSp
)

/*++

Routine Description:

    This is the routine for closing a volume.

Arguments:

    Vcb - Supplies the volume being queried.

    Irp - Supplies the Irp being processed.

    IrpSp - Supplies parameters describing the read

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    BOOLEAN DeleteVolume = FALSE;

    PAGED_CODE();

    //
    //  This is a close operation.  If it is the last one, dismount.
    //

    Status = KeWaitForSingleObject( &Vcb->Mutex,
                                    Executive,
                                    KernelMode,
                                    FALSE,
                                    (PLARGE_INTEGER) NULL );
    ASSERT( NT_SUCCESS( Status ) );

    Vcb->OpenCount -= 1;

    if (Vcb->OpenCount == 0) {

        DeleteVolume = RawCheckForDismount( Vcb, FALSE );
    }

    (VOID)KeReleaseMutex( &Vcb->Mutex, FALSE );

    if (DeleteVolume) {
        IoDeleteDevice( (PDEVICE_OBJECT)CONTAINING_RECORD( Vcb,
                        VOLUME_DEVICE_OBJECT,
                        Vcb));
    }

    RawCompleteRequest( Irp, STATUS_SUCCESS );

    UNREFERENCED_PARAMETER( IrpSp );

    return STATUS_SUCCESS;
}
Ejemplo n.º 16
0
Archivo: kill.c Proyecto: GYGit/reactos
/*
 * FUNCTION: Terminates the current thread
 * See "Windows Internals" - Chapter 13, Page 50-53
 */
VOID
NTAPI
PspExitThread(IN NTSTATUS ExitStatus)
{
    CLIENT_DIED_MSG TerminationMsg;
    NTSTATUS Status;
    PTEB Teb;
    PEPROCESS CurrentProcess;
    PETHREAD Thread, OtherThread, PreviousThread = NULL;
    PVOID DeallocationStack;
    SIZE_T Dummy;
    BOOLEAN Last = FALSE;
    PTERMINATION_PORT TerminationPort, NextPort;
    PLIST_ENTRY FirstEntry, CurrentEntry;
    PKAPC Apc;
    PTOKEN PrimaryToken;
    PAGED_CODE();
    PSTRACE(PS_KILL_DEBUG, "ExitStatus: %d\n", ExitStatus);

    /* Get the Current Thread and Process */
    Thread = PsGetCurrentThread();
    CurrentProcess = Thread->ThreadsProcess;
    ASSERT((Thread) == PsGetCurrentThread());

    /* Can't terminate a thread if it attached another process */
    if (KeIsAttachedProcess())
    {
        /* Bugcheck */
        KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
                     (ULONG_PTR)CurrentProcess,
                     (ULONG_PTR)Thread->Tcb.ApcState.Process,
                     (ULONG_PTR)Thread->Tcb.ApcStateIndex,
                     (ULONG_PTR)Thread);
    }

    /* Lower to Passive Level */
    KeLowerIrql(PASSIVE_LEVEL);

    /* Can't be a worker thread */
    if (Thread->ActiveExWorker)
    {
        /* Bugcheck */
        KeBugCheckEx(ACTIVE_EX_WORKER_THREAD_TERMINATION,
                     (ULONG_PTR)Thread,
                     0,
                     0,
                     0);
    }

    /* Can't have pending APCs */
    if (Thread->Tcb.CombinedApcDisable != 0)
    {
        /* Bugcheck */
        KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
                     0,
                     Thread->Tcb.CombinedApcDisable,
                     0,
                     1);
    }

    /* Lock the thread */
    ExWaitForRundownProtectionRelease(&Thread->RundownProtect);

    /* Cleanup the power state */
    PopCleanupPowerState((PPOWER_STATE)&Thread->Tcb.PowerState);

    /* Call the WMI Callback for Threads */
    //WmiTraceThread(Thread, NULL, FALSE);

    /* Run Thread Notify Routines before we desintegrate the thread */
    PspRunCreateThreadNotifyRoutines(Thread, FALSE);

    /* Lock the Process before we modify its thread entries */
    KeEnterCriticalRegion();
    ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);

    /* Decrease the active thread count, and check if it's 0 */
    if (!(--CurrentProcess->ActiveThreads))
    {
        /* Set the delete flag */
        InterlockedOr((PLONG)&CurrentProcess->Flags, PSF_PROCESS_DELETE_BIT);

        /* Remember we are last */
        Last = TRUE;

        /* Check if this termination is due to the thread dying */
        if (ExitStatus == STATUS_THREAD_IS_TERMINATING)
        {
            /* Check if the last thread was pending */
            if (CurrentProcess->ExitStatus == STATUS_PENDING)
            {
                /* Use the last exit status */
                CurrentProcess->ExitStatus = CurrentProcess->
                                             LastThreadExitStatus;
            }
        }
        else
        {
            /* Just a normal exit, write the code */
            CurrentProcess->ExitStatus = ExitStatus;
        }

        /* Loop all the current threads */
        FirstEntry = &CurrentProcess->ThreadListHead;
        CurrentEntry = FirstEntry->Flink;
        while (FirstEntry != CurrentEntry)
        {
            /* Get the thread on the list */
            OtherThread = CONTAINING_RECORD(CurrentEntry,
                                            ETHREAD,
                                            ThreadListEntry);

            /* Check if it's a thread that's still alive */
            if ((OtherThread != Thread) &&
                !(KeReadStateThread(&OtherThread->Tcb)) &&
                (ObReferenceObjectSafe(OtherThread)))
            {
                /* It's a live thread and we referenced it, unlock process */
                ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
                KeLeaveCriticalRegion();

                /* Wait on the thread */
                KeWaitForSingleObject(OtherThread,
                                      Executive,
                                      KernelMode,
                                      FALSE,
                                      NULL);

                /* Check if we had a previous thread to dereference */
                if (PreviousThread) ObDereferenceObject(PreviousThread);

                /* Remember the thread and re-lock the process */
                PreviousThread = OtherThread;
                KeEnterCriticalRegion();
                ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
            }

            /* Go to the next thread */
            CurrentEntry = CurrentEntry->Flink;
        }
    }
    else if (ExitStatus != STATUS_THREAD_IS_TERMINATING)
    {
        /* Write down the exit status of the last thread to get killed */
        CurrentProcess->LastThreadExitStatus = ExitStatus;
    }

    /* Unlock the Process */
    ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
    KeLeaveCriticalRegion();

    /* Check if we had a previous thread to dereference */
    if (PreviousThread) ObDereferenceObject(PreviousThread);

    /* Check if the process has a debug port and if this is a user thread */
    if ((CurrentProcess->DebugPort) && !(Thread->SystemThread))
    {
        /* Notify the Debug API. */
        Last ? DbgkExitProcess(CurrentProcess->ExitStatus) :
               DbgkExitThread(ExitStatus);
    }

    /* Check if this is a Critical Thread */
    if ((KdDebuggerEnabled) && (Thread->BreakOnTermination))
    {
        /* Break to debugger */
        PspCatchCriticalBreak("Critical thread 0x%p (in %s) exited\n",
                              Thread,
                              CurrentProcess->ImageFileName);
    }

    /* Check if it's the last thread and this is a Critical Process */
    if ((Last) && (CurrentProcess->BreakOnTermination))
    {
        /* Check if a debugger is here to handle this */
        if (KdDebuggerEnabled)
        {
            /* Break to debugger */
            PspCatchCriticalBreak("Critical  process 0x%p (in %s) exited\n",
                                  CurrentProcess,
                                  CurrentProcess->ImageFileName);
        }
        else
        {
            /* Bugcheck, we can't allow this */
            KeBugCheckEx(CRITICAL_PROCESS_DIED,
                         (ULONG_PTR)CurrentProcess,
                         0,
                         0,
                         0);
        }
    }

    /* Sanity check */
    ASSERT(Thread->Tcb.CombinedApcDisable == 0);

    /* Process the Termination Ports */
    TerminationPort = Thread->TerminationPort;
    if (TerminationPort)
    {
        /* Setup the message header */
        TerminationMsg.h.u2.ZeroInit = 0;
        TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
        TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
        TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
                                            sizeof(PORT_MESSAGE);

        /* Loop each port */
        do
        {
            /* Save the Create Time */
            TerminationMsg.CreateTime = Thread->CreateTime;

            /* Loop trying to send message */
            while (TRUE)
            {
                /* Send the LPC Message */
                Status = LpcRequestPort(TerminationPort->Port,
                                        &TerminationMsg.h);
                if ((Status == STATUS_NO_MEMORY) ||
                    (Status == STATUS_INSUFFICIENT_RESOURCES))
                {
                    /* Wait a bit and try again */
                    KeDelayExecutionThread(KernelMode, FALSE, &ShortTime);
                    continue;
                }
                break;
            }

            /* Dereference this LPC Port */
            ObDereferenceObject(TerminationPort->Port);

            /* Move to the next one */
            NextPort = TerminationPort->Next;

            /* Free the Termination Port Object */
            ExFreePoolWithTag(TerminationPort, '=TsP');

            /* Keep looping as long as there is a port */
            TerminationPort = NextPort;
        } while (TerminationPort);
    }
    else if (((ExitStatus == STATUS_THREAD_IS_TERMINATING) &&
              (Thread->DeadThread)) ||
             !(Thread->DeadThread))
    {
        /*
         * This case is special and deserves some extra comments. What
         * basically happens here is that this thread doesn't have a termination
         * port, which means that it died before being fully created. Since we
         * still have to notify an LPC Server, we'll use the exception port,
         * which we know exists. However, we need to know how far the thread
         * actually got created. We have three possibilities:
         *
         *  - NtCreateThread returned an error really early: DeadThread is set.
         *  - NtCreateThread managed to create the thread: DeadThread is off.
         *  - NtCreateThread was creating the thread (with DeadThread set,
         *    but the thread got killed prematurely: STATUS_THREAD_IS_TERMINATING
         *    is our exit code.)
         *
         * For the 2 & 3rd scenarios, the thread has been created far enough to
         * warrant notification to the LPC Server.
         */

        /* Setup the message header */
        TerminationMsg.h.u2.ZeroInit = 0;
        TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
        TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
        TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
                                            sizeof(PORT_MESSAGE);

        /* Make sure the process has an exception port */
        if (CurrentProcess->ExceptionPort)
        {
            /* Save the Create Time */
            TerminationMsg.CreateTime = Thread->CreateTime;

            /* Loop trying to send message */
            while (TRUE)
            {
                /* Send the LPC Message */
                Status = LpcRequestPort(CurrentProcess->ExceptionPort,
                                        &TerminationMsg.h);
                if ((Status == STATUS_NO_MEMORY) ||
                    (Status == STATUS_INSUFFICIENT_RESOURCES))
                {
                    /* Wait a bit and try again */
                    KeDelayExecutionThread(KernelMode, FALSE, &ShortTime);
                    continue;
                }
                break;
            }
        }
    }

    /* Rundown Win32 Thread if there is one */
    if (Thread->Tcb.Win32Thread) PspW32ThreadCallout(Thread,
                                                     PsW32ThreadCalloutExit);

    /* If we are the last thread and have a W32 Process */
    if ((Last) && (CurrentProcess->Win32Process))
    {
        /* Run it down too */
        PspW32ProcessCallout(CurrentProcess, FALSE);
    }

    /* Make sure Stack Swap is enabled */
    if (!Thread->Tcb.EnableStackSwap)
    {
        /* Stack swap really shouldn't be disabled during exit! */
        KeBugCheckEx(KERNEL_STACK_LOCKED_AT_EXIT, 0, 0, 0, 0);
    }

    /* Cancel I/O for the thread. */
    IoCancelThreadIo(Thread);

    /* Rundown Timers */
    ExTimerRundown();

    /* FIXME: Rundown Registry Notifications (NtChangeNotify)
    CmNotifyRunDown(Thread); */

    /* Rundown Mutexes */
    KeRundownThread();

    /* Check if we have a TEB */
    Teb = Thread->Tcb.Teb;
    if (Teb)
    {
        /* Check if the thread is still alive */
        if (!Thread->DeadThread)
        {
            /* Check if we need to free its stack */
            if (Teb->FreeStackOnTermination)
            {
                /* Set the TEB's Deallocation Stack as the Base Address */
                Dummy = 0;
                DeallocationStack = Teb->DeallocationStack;

                /* Free the Thread's Stack */
                ZwFreeVirtualMemory(NtCurrentProcess(),
                                    &DeallocationStack,
                                    &Dummy,
                                    MEM_RELEASE);
            }

            /* Free the debug handle */
            if (Teb->DbgSsReserved[1]) ObCloseHandle(Teb->DbgSsReserved[1],
                                                     UserMode);
        }

        /* Decommit the TEB */
        MmDeleteTeb(CurrentProcess, Teb);
        Thread->Tcb.Teb = NULL;
    }

    /* Free LPC Data */
    LpcExitThread(Thread);

    /* Save the exit status and exit time */
    Thread->ExitStatus = ExitStatus;
    KeQuerySystemTime(&Thread->ExitTime);

    /* Sanity check */
    ASSERT(Thread->Tcb.CombinedApcDisable == 0);

    /* Check if this is the final thread or not */
    if (Last)
    {
        /* Set the process exit time */
        CurrentProcess->ExitTime = Thread->ExitTime;

        /* Exit the process */
        PspExitProcess(TRUE, CurrentProcess);

        /* Get the process token and check if we need to audit */
        PrimaryToken = PsReferencePrimaryToken(CurrentProcess);
        if (SeDetailedAuditingWithToken(PrimaryToken))
        {
            /* Audit the exit */
            SeAuditProcessExit(CurrentProcess);
        }

        /* Dereference the process token */
        ObFastDereferenceObject(&CurrentProcess->Token, PrimaryToken);

        /* Check if this is a VDM Process and rundown the VDM DPCs if so */
        if (CurrentProcess->VdmObjects) { /* VdmRundownDpcs(CurrentProcess); */ }

        /* Kill the process in the Object Manager */
        ObKillProcess(CurrentProcess);

        /* Check if we have a section object */
        if (CurrentProcess->SectionObject)
        {
            /* Dereference and clear the Section Object */
            ObDereferenceObject(CurrentProcess->SectionObject);
            CurrentProcess->SectionObject = NULL;
        }

        /* Check if the process is part of a job */
        if (CurrentProcess->Job)
        {
            /* Remove the process from the job */
            PspExitProcessFromJob(CurrentProcess->Job, CurrentProcess);
        }
    }

    /* Disable APCs */
    KeEnterCriticalRegion();

    /* Disable APC queueing, force a resumption */
    Thread->Tcb.ApcQueueable = FALSE;
    KeForceResumeThread(&Thread->Tcb);

    /* Re-enable APCs */
    KeLeaveCriticalRegion();

    /* Flush the User APCs */
    FirstEntry = KeFlushQueueApc(&Thread->Tcb, UserMode);
    if (FirstEntry)
    {
        /* Start with the first entry */
        CurrentEntry = FirstEntry;
        do
        {
           /* Get the APC */
           Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);

           /* Move to the next one */
           CurrentEntry = CurrentEntry->Flink;

           /* Rundown the APC or de-allocate it */
           if (Apc->RundownRoutine)
           {
              /* Call its own routine */
              Apc->RundownRoutine(Apc);
           }
           else
           {
              /* Do it ourselves */
              ExFreePool(Apc);
           }
        }
        while (CurrentEntry != FirstEntry);
    }

    /* Clean address space if this was the last thread */
    if (Last) MmCleanProcessAddressSpace(CurrentProcess);

    /* Call the Lego routine */
    if (Thread->Tcb.LegoData) PspRunLegoRoutine(&Thread->Tcb);

    /* Flush the APC queue, which should be empty */
    FirstEntry = KeFlushQueueApc(&Thread->Tcb, KernelMode);
    if ((FirstEntry) || (Thread->Tcb.CombinedApcDisable != 0))
    {
        /* Bugcheck time */
        KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
                     (ULONG_PTR)FirstEntry,
                     Thread->Tcb.CombinedApcDisable,
                     KeGetCurrentIrql(),
                     0);
    }

    /* Signal the process if this was the last thread */
    if (Last) KeSetProcess(&CurrentProcess->Pcb, 0, FALSE);

    /* Terminate the Thread from the Scheduler */
    KeTerminateThread(0);
}
Ejemplo n.º 17
0
NTSTATUS
TdiTest()
{
    PFILE_OBJECT ConnectionFileObject, AddressFileObject;
    HANDLE		AddressHandle, ConnectionHandle;
    CHAR		Buffer[80], Data[] = "Hello from Gary";
    NTSTATUS	Status;
    KEVENT		Done; 
	
	KeInitializeEvent(&Done, NotificationEvent, FALSE);

    Status = TdiCreateConnection(&ConnectionHandle, &ConnectionFileObject);
    if (!NT_SUCCESS(Status)) return Status;

    Status = TdiCreateAddress(&AddressHandle, &AddressFileObject, SOCK_STREAM, 0, 0);
    if (!NT_SUCCESS(Status)) return Status;

    do 
	{
		IO_STATUS_BLOCK IoStatus = {0};
        KEVENT	Event;

		Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_DISCONNECT, TdiEventDisconnect, &Done);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_ERROR, TdiEventError, 0);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_RECEIVE, TdiEventReceive, 0);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiBind(ConnectionFileObject, AddressHandle);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiConnect(ConnectionFileObject, 0x41A1F6A8, 0x700, NULL);
        if (!NT_SUCCESS(Status)) break;

		KeInitializeEvent(&Event, NotificationEvent, FALSE);

//        Status = TdiRecv(ConnectionFileObject, Buffer, sizeof Buffer, &Event, &IoStatus);
//        if (!NT_SUCCESS(Status)) break;

        Status = TdiSend(ConnectionFileObject, Data, sizeof Data);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiSend(ConnectionFileObject, Data, sizeof Data);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiSend(ConnectionFileObject, Data, sizeof Data);
        if (!NT_SUCCESS(Status)) break;

        Status = TdiDisconnect(ConnectionFileObject);
        if (!NT_SUCCESS(Status)) break;

        Status = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0);
        if (Status == STATUS_SUCCESS) Status = IoStatus.Status;

        DbgPrint("Status = %lx, IoStatus.Status = %lx, IoStatus.Information = %ld\n", Status, IoStatus.Status, IoStatus.Information);

        KeWaitForSingleObject(&Done, UserRequest, KernelMode, FALSE, 0);

    } while (0);

    ObDereferenceObject(ConnectionFileObject);

    ObDereferenceObject(AddressFileObject);

    ZwClose(ConnectionHandle);

    ZwClose(AddressHandle);

    return Status;

}
Ejemplo n.º 18
0
NTSTATUS
NdFatSecondaryUserFsCtrl (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for implementing the user's requests made
    through NtFsControlFile.

Arguments:

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    ULONG FsControlCode;

    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

	PVOLUME_DEVICE_OBJECT		volDo = CONTAINING_RECORD( IrpContext->Vcb, VOLUME_DEVICE_OBJECT, Vcb );
	BOOLEAN						secondarySessionResourceAcquired = FALSE;

	TYPE_OF_OPEN				typeOfOpen;
	PVCB						vcb;
	PFCB						fcb;
	PCCB						ccb;

	PSECONDARY_REQUEST			secondaryRequest = NULL;

	PNDFS_REQUEST_HEADER		ndfsRequestHeader;
	PNDFS_WINXP_REQUEST_HEADER	ndfsWinxpRequestHeader;
	PNDFS_WINXP_REPLY_HEADER	ndfsWinxpReplytHeader;
	_U8							*ndfsWinxpRequestData;

	LARGE_INTEGER				timeOut;

	struct FileSystemControl	fileSystemControl;

	PVOID						inputBuffer = NULL;
	ULONG						inputBufferLength;
	PVOID						outputBuffer = NULL;
	ULONG						outputBufferLength;
	ULONG						bufferLength;


    //
    //  Save some references to make our life a little easier
    //

    FsControlCode = IrpSp->Parameters.FileSystemControl.FsControlCode;

    DebugTrace(+1, Dbg,"FatUserFsCtrl...\n", 0);
    DebugTrace( 0, Dbg,"FsControlCode = %08lx\n", FsControlCode);

    //
    //  Some of these Fs Controls use METHOD_NEITHER buffering.  If the previous mode
    //  of the caller was userspace and this is a METHOD_NEITHER, we have the choice
    //  of realy buffering the request through so we can possibly post, or making the
    //  request synchronous.  Since the former was not done by design, do the latter.
    //

    if (Irp->RequestorMode != KernelMode && (FsControlCode & 3) == METHOD_NEITHER) {

        SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
    }

    //
    //  Case on the control code.
    //

    switch ( FsControlCode ) {

    case FSCTL_REQUEST_OPLOCK_LEVEL_1:
    case FSCTL_REQUEST_OPLOCK_LEVEL_2:
    case FSCTL_REQUEST_BATCH_OPLOCK:
    case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE:
    case FSCTL_OPBATCH_ACK_CLOSE_PENDING:
    case FSCTL_OPLOCK_BREAK_NOTIFY:
    case FSCTL_OPLOCK_BREAK_ACK_NO_2:
    case FSCTL_REQUEST_FILTER_OPLOCK :

		//ASSERT( FALSE );

		//Status = STATUS_SUCCESS;
		//break;

        Status = FatOplockRequest( IrpContext, Irp );
		return Status;

    case FSCTL_LOCK_VOLUME:

		FatCompleteRequest( IrpContext, Irp, Status = STATUS_ACCESS_DENIED );

		DebugTrace2( -1, Dbg, ("NdFatSecondaryUserFsCtrl -> %08lx\n", Status) );
		return Status;

		//Status = FatLockVolume( IrpContext, Irp );
        break;

    case FSCTL_UNLOCK_VOLUME:

		FatCompleteRequest( IrpContext, Irp, Status = STATUS_ACCESS_DENIED );

		DebugTrace2( -1, Dbg, ("NdFatSecondaryUserFsCtrl -> %08lx\n", Status) );
		return Status;

		//Status = FatUnlockVolume( IrpContext, Irp );
        break;

    case FSCTL_DISMOUNT_VOLUME:

		FatCompleteRequest( IrpContext, Irp, Status = STATUS_ACCESS_DENIED );

		DebugTrace2( -1, Dbg, ("NdFatSecondaryUserFsCtrl -> %08lx\n", Status) );
		return Status;

        //Status = FatDismountVolume( IrpContext, Irp );
        break;

    case FSCTL_MARK_VOLUME_DIRTY:

		FatCompleteRequest( IrpContext, Irp, Status = STATUS_ACCESS_DENIED );

		DebugTrace2( -1, Dbg, ("NdFatSecondaryUserFsCtrl -> %08lx\n", Status) );
		return Status;

		//Status = FatDirtyVolume( IrpContext, Irp );
        break;

    case FSCTL_IS_VOLUME_DIRTY:

        Status = FatIsVolumeDirty( IrpContext, Irp );
        break;

    case FSCTL_IS_VOLUME_MOUNTED:

        Status = FatIsVolumeMounted( IrpContext, Irp );

		DebugTrace2( -1, Dbg, ("NtfsUserFsRequest -> %08lx\n", Status) );
		return Status;

		break;

    case FSCTL_IS_PATHNAME_VALID:

		Status = FatIsPathnameValid( IrpContext, Irp );
		
		DebugTrace2( -1, Dbg, ("NtfsUserFsRequest -> %08lx\n", Status) );
		return Status;

		break;

    case FSCTL_QUERY_RETRIEVAL_POINTERS:
        Status = FatQueryRetrievalPointers( IrpContext, Irp );
        break;

    case FSCTL_QUERY_FAT_BPB:

		Status = FatQueryBpb( IrpContext, Irp );

		DebugTrace2( -1, Dbg, ("NtfsUserFsRequest -> %08lx\n", Status) );
		return Status;

		break;

    case FSCTL_FILESYSTEM_GET_STATISTICS:
        Status = FatGetStatistics( IrpContext, Irp );
        break;

    case FSCTL_GET_VOLUME_BITMAP:
        Status = FatGetVolumeBitmap( IrpContext, Irp );
        break;

    case FSCTL_GET_RETRIEVAL_POINTERS:
        Status = FatGetRetrievalPointers( IrpContext, Irp );
        break;

    case FSCTL_MOVE_FILE:

		FatCompleteRequest( IrpContext, Irp, Status = STATUS_ACCESS_DENIED );

		DebugTrace2( -1, Dbg, ("NtfsUserFsRequest -> %08lx\n", Status) );
		return Status;
		
		//Status = FatMoveFile( IrpContext, Irp );
        break;

    case FSCTL_ALLOW_EXTENDED_DASD_IO:
        Status = FatAllowExtendedDasdIo( IrpContext, Irp );
        break;

    default :

        DebugTrace(0, Dbg, "Invalid control code -> %08lx\n", FsControlCode );

        FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
        Status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

	ASSERT( !ExIsResourceAcquiredSharedLite(&volDo->Vcb.Resource) );	

	if (Status != STATUS_SUCCESS) {

		DebugTrace2( -1, Dbg, ("NtfsUserFsRequest -> %08lx\n", Status) );
		return Status;
	}

	inputBuffer = IrpContext->InputBuffer;
	outputBuffer = IrpContext->outputBuffer;

	ASSERT( IrpSp->Parameters.FileSystemControl.InputBufferLength ? (inputBuffer != NULL) : (inputBuffer == NULL) );
	ASSERT( IrpSp->Parameters.FileSystemControl.OutputBufferLength ? (outputBuffer != NULL) : (outputBuffer == NULL) );

	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {

		return FatFsdPostRequest( IrpContext, Irp );
	}

	try {

		secondarySessionResourceAcquired 
			= SecondaryAcquireResourceExclusiveLite( IrpContext, 
													 &volDo->Secondary->SessionResource, 
													 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

		if (FlagOn(volDo->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ) {

			PrintIrp( Dbg2, "SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED", NULL, IrpContext->OriginatingIrp );
			FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );	
		}

		ASSERT( IS_SECONDARY_FILEOBJECT(IrpSp->FileObject) );
		
		typeOfOpen = FatDecodeFileObject( IrpSp->FileObject, &vcb, &fcb, &ccb );

		if (FlagOn(ccb->NdFatFlags, ND_FAT_CCB_FLAG_UNOPENED)) {

			ASSERT( FlagOn(ccb->NdFatFlags, ND_FAT_CCB_FLAG_CORRUPTED) );

			try_return( Status = STATUS_FILE_CORRUPT_ERROR );
		}
		
		fileSystemControl.FsControlCode			= IrpSp->Parameters.FileSystemControl.FsControlCode;
		fileSystemControl.InputBufferLength		= IrpSp->Parameters.FileSystemControl.InputBufferLength;
		fileSystemControl.OutputBufferLength	= IrpSp->Parameters.FileSystemControl.OutputBufferLength;

		if (inputBuffer == NULL)
			fileSystemControl.InputBufferLength = 0;
		if (outputBuffer == NULL)
			fileSystemControl.OutputBufferLength = 0;

		outputBufferLength	= fileSystemControl.OutputBufferLength;
		
		if (fileSystemControl.FsControlCode == FSCTL_MOVE_FILE) {			// 29
		
			inputBufferLength = 0;			
		
		} else if (fileSystemControl.FsControlCode == FSCTL_MARK_HANDLE) {		// 63
		
			inputBufferLength = 0;			
		
		} else {
		
			inputBufferLength  = fileSystemControl.InputBufferLength;
		}
		
		bufferLength = (inputBufferLength >= outputBufferLength)?inputBufferLength:outputBufferLength;

		secondaryRequest = ALLOC_WINXP_SECONDARY_REQUEST( volDo->Secondary, 
														  IRP_MJ_FILE_SYSTEM_CONTROL,
														  bufferLength );

		if (secondaryRequest == NULL) {

			Status = Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
			Irp->IoStatus.Information = 0;
			try_return( Status );
		}

		ndfsRequestHeader = &secondaryRequest->NdfsRequestHeader;
		INITIALIZE_NDFS_REQUEST_HEADER(	ndfsRequestHeader, 
										NDFS_COMMAND_EXECUTE, 
										volDo->Secondary, 
										IRP_MJ_FILE_SYSTEM_CONTROL, 
										inputBufferLength );

		ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1);
		ASSERT( ndfsWinxpRequestHeader == (PNDFS_WINXP_REQUEST_HEADER)secondaryRequest->NdfsRequestData );
		INITIALIZE_NDFS_WINXP_REQUEST_HEADER( ndfsWinxpRequestHeader, Irp, IrpSp, ccb->PrimaryFileHandle );

		ndfsWinxpRequestHeader->FileSystemControl.OutputBufferLength	= fileSystemControl.OutputBufferLength;
		ndfsWinxpRequestHeader->FileSystemControl.InputBufferLength		= fileSystemControl.InputBufferLength;
		ndfsWinxpRequestHeader->FileSystemControl.FsControlCode			= fileSystemControl.FsControlCode;

#if 0
		if (fileSystemControl.FsControlCode == FSCTL_MOVE_FILE) {		// 29
				
			PMOVE_FILE_DATA	moveFileData = inputBuffer;	
			PFILE_OBJECT	moveFileObject;
			PCCB			moveCcb;

			Status = ObReferenceObjectByHandle( moveFileData->FileHandle,
												FILE_READ_DATA,
												0,
												KernelMode,
												&moveFileObject,
												NULL );

			if (Status != STATUS_SUCCESS) {

				ASSERT( FALSE );
				try_return( Status );
			}
	
			ObDereferenceObject( moveFileObject );

			moveCcb = moveFileObject->FsContext2;

			ndfsWinxpRequestHeader->FileSystemControl.FscMoveFileData.FileHandle	= moveCcb->PrimaryFileHandle;
			ndfsWinxpRequestHeader->FileSystemControl.FscMoveFileData.StartingVcn	= moveFileData->StartingVcn.QuadPart;
			ndfsWinxpRequestHeader->FileSystemControl.FscMoveFileData.StartingLcn	= moveFileData->StartingLcn.QuadPart;
			ndfsWinxpRequestHeader->FileSystemControl.FscMoveFileData.ClusterCount	= moveFileData->ClusterCount;
		
		} else
#endif
		if (fileSystemControl.FsControlCode == FSCTL_MARK_HANDLE) {	// 63
		
			PMARK_HANDLE_INFO	markHandleInfo = inputBuffer;	
			PFILE_OBJECT		volumeFileObject;
			PCCB				volumeCcb;

			Status = ObReferenceObjectByHandle( markHandleInfo->VolumeHandle,
												FILE_READ_DATA,
												0,
												KernelMode,
												&volumeFileObject,
												NULL );

			if (Status != STATUS_SUCCESS) {

				try_return( Status );
			}
	
			ObDereferenceObject( volumeFileObject );

			volumeCcb = volumeFileObject->FsContext2;

			ndfsWinxpRequestHeader->FileSystemControl.FscMarkHandleInfo.UsnSourceInfo	= markHandleInfo->UsnSourceInfo;
			ndfsWinxpRequestHeader->FileSystemControl.FscMarkHandleInfo.VolumeHandle	= volumeCcb->PrimaryFileHandle;
			ndfsWinxpRequestHeader->FileSystemControl.FscMarkHandleInfo.HandleInfo		= markHandleInfo->HandleInfo;
		
		} else {

			ndfsWinxpRequestData = (_U8 *)(ndfsWinxpRequestHeader+1);

			if (inputBufferLength)
				RtlCopyMemory( ndfsWinxpRequestData, inputBuffer, inputBufferLength );
		}

		ASSERT( !ExIsResourceAcquiredSharedLite(&IrpContext->Vcb->Resource) );	

		secondaryRequest->RequestType = SECONDARY_REQ_SEND_MESSAGE;
		QueueingSecondaryRequest( volDo->Secondary, secondaryRequest );

		timeOut.QuadPart = -NDFAT_TIME_OUT;		
		Status = KeWaitForSingleObject( &secondaryRequest->CompleteEvent, Executive, KernelMode, FALSE, &timeOut );

		if (Status != STATUS_SUCCESS) {

			secondaryRequest = NULL;
			try_return( Status = STATUS_IO_DEVICE_ERROR );
		}

		KeClearEvent( &secondaryRequest->CompleteEvent );

		if (secondaryRequest->ExecuteStatus != STATUS_SUCCESS) {

			if (IrpContext->OriginatingIrp)
				PrintIrp( Dbg2, "secondaryRequest->ExecuteStatus != STATUS_SUCCESS", NULL, IrpContext->OriginatingIrp );

			DebugTrace2( 0, Dbg2, ("secondaryRequest->ExecuteStatus != STATUS_SUCCESS file = %s, line = %d\n", __FILE__, __LINE__) );

			FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
		}

		ndfsWinxpReplytHeader = (PNDFS_WINXP_REPLY_HEADER)secondaryRequest->NdfsReplyData;
		Status = Irp->IoStatus.Status = ndfsWinxpReplytHeader->Status;
		Irp->IoStatus.Information = ndfsWinxpReplytHeader->Information;

		if (FsControlCode == FSCTL_GET_NTFS_VOLUME_DATA && Status != STATUS_SUCCESS)
			DebugTrace2( 0, Dbg2, ("FSCTL_GET_NTFS_VOLUME_DATA: Status = %x, Irp->IoStatus.Information = %d\n", Status, Irp->IoStatus.Information) );

		if (secondaryRequest->NdfsReplyHeader.MessageSize - sizeof(NDFS_REPLY_HEADER) - sizeof(NDFS_WINXP_REPLY_HEADER)) {

			ASSERT( Irp->IoStatus.Status == STATUS_SUCCESS || Irp->IoStatus.Status == STATUS_BUFFER_OVERFLOW );
			ASSERT( Irp->IoStatus.Information );
			ASSERT( Irp->IoStatus.Information <= outputBufferLength );
			ASSERT( outputBuffer );

			RtlCopyMemory( outputBuffer,
						   (_U8 *)(ndfsWinxpReplytHeader+1),
						   Irp->IoStatus.Information );
		}

		if (fileSystemControl.FsControlCode == FSCTL_MOVE_FILE && Status != STATUS_SUCCESS)
			DebugTrace2( 0, Dbg2, ("NtfsDefragFile: status = %x\n", Status) );

#if 0
		if (Status == STATUS_SUCCESS && fileSystemControl.FsControlCode == FSCTL_MOVE_FILE) {		// 29
				
			PMOVE_FILE_DATA	moveFileData = inputBuffer;	
			PFILE_OBJECT	moveFileObject;

			TYPE_OF_OPEN	typeOfOpen;
			PVCB			vcb;
			PFCB			moveFcb;
			PSCB			moveScb;
			PCCB			moveCcb;


			Status = ObReferenceObjectByHandle( moveFileData->FileHandle,
												FILE_READ_DATA,
												0,
												KernelMode,
												&moveFileObject,
												NULL );

			if (Status != STATUS_SUCCESS) {

				try_return( Status );
			}
	
			ObDereferenceObject( moveFileObject );
				
			typeOfOpen = NtfsDecodeFileObject( IrpContext, moveFileObject, &vcb, &moveFcb, &moveScb, &moveCcb, TRUE );
		
			if (typeOfOpen == UserFileOpen && FlagOn(volDo->NdFatFlags, ND_FAT_DEVICE_FLAG_DIRECT_RW) && ndfsWinxpReplytHeader->FileInformationSet && ndfsWinxpReplytHeader->AllocationSize) {

				PNDFS_MCB_ENTRY	mcbEntry;
				ULONG			index;
				VCN				testVcn;

			
				SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ACQUIRE_PAGING );
				NtfsAcquireFcbWithPaging( IrpContext, moveFcb, 0 );
				NtfsAcquireNtfsMcbMutex( &moveScb->Mcb );

				mcbEntry = (PNDFS_MCB_ENTRY)( ndfsWinxpReplytHeader+1 );

				if (moveScb->Header.AllocationSize.QuadPart) {

					NtfsRemoveNtfsMcbEntry( &moveScb->Mcb, 0, 0xFFFFFFFF );
				}

				for (index=0, testVcn=0; index < ndfsWinxpReplytHeader->NumberOfMcbEntry; index++) {

					ASSERT( mcbEntry[index].Vcn == testVcn );
					testVcn += (LONGLONG)mcbEntry[index].ClusterCount;

					NtfsAddNtfsMcbEntry( &moveScb->Mcb, 
										 mcbEntry[index].Vcn, 
										 mcbEntry[index].Lcn, 
										 (LONGLONG)mcbEntry[index].ClusterCount, 
										 TRUE );
				}
					
				ASSERT( LlBytesFromClusters(vcb, testVcn) == ndfsWinxpReplytHeader->AllocationSize );

				if (moveScb->Header.AllocationSize.QuadPart != ndfsWinxpReplytHeader->AllocationSize)
					SetFlag( moveScb->ScbState, SCB_STATE_TRUNCATE_ON_CLOSE );		

				moveScb->Header.FileSize.QuadPart = ndfsWinxpReplytHeader->FileSize;
				moveScb->Header.AllocationSize.QuadPart = ndfsWinxpReplytHeader->AllocationSize;
				ASSERT( moveScb->Header.AllocationSize.QuadPart >= moveScb->Header.FileSize.QuadPart );

				if (moveFileObject->SectionObjectPointer->DataSectionObject != NULL && moveFileObject->PrivateCacheMap == NULL) {

					CcInitializeCacheMap( moveFileObject,
										  (PCC_FILE_SIZES)&moveScb->Header.AllocationSize,
										  FALSE,
										  &NtfsData.CacheManagerCallbacks,
										  moveScb );

					//CcSetAdditionalCacheAttributes( fileObject, TRUE, TRUE );
				}

				if (CcIsFileCached(moveFileObject)) {

					NtfsSetBothCacheSizes( moveFileObject,
										   (PCC_FILE_SIZES)&scb->Header.AllocationSize,
										   moveScb );
				}

				NtfsReleaseNtfsMcbMutex( &moveScb->Mcb );
				NtfsReleaseFcb( IrpContext, moveFcb );
			}
		}

#endif
try_exit:  NOTHING;

	} finally {

		if (secondarySessionResourceAcquired == TRUE) {

			SecondaryReleaseResourceLite( IrpContext, &volDo->Secondary->SessionResource );		
		}

		if (secondaryRequest)
			DereferenceSecondaryRequest( secondaryRequest );
	}

	FatCompleteRequest( IrpContext, Irp, Status );

    DebugTrace(-1, Dbg, "FatUserFsCtrl -> %08lx\n", Status );
    return Status;
}
Ejemplo n.º 19
0
NTSTATUS
OnEvtDeviceD0Exit (
  _In_ WDFDEVICE Device,
  _In_ WDF_POWER_DEVICE_STATE TargetState
    )
/*++

Routine Description:

    Called by the framework when leaving our operational state (D0).

Arguments:

    Device - WDFDEVICE framework handle to the bus FDO.

    TargetState - The WDF_POWER_DEVICE_STATE to which the stack is
        making its transition.


Return Value:

    Returns STATUS_SUCCESS.
    Any failed status code will leave the device stack in failed state and
    device will not get any D0Entry callbacks after that.

--*/
{
    PCONTROLLER_CONTEXT ControllerContext;

    TraceEntry();

    ControllerContext = DeviceGetControllerContext(Device);

    WdfWaitLockAcquire(ControllerContext->InitializeDefaultEndpointLock, NULL);
    ControllerContext->InitializeDefaultEndpoint = FALSE;
    WdfWaitLockRelease(ControllerContext->InitializeDefaultEndpointLock);

    if (TargetState != WdfPowerDeviceD3Final) {
        goto End;
    }

    //
    // If the stack is being removed while we are attached to a host, simulate a detach. At this
    // point all attach/detach notification mechanisms are disabled, so no other code will report a
    // detach, nor will "WasAttached" change from underneath us.
    //
    if (ControllerContext->WasAttached) {
        KeClearEvent(&ControllerContext->DetachEvent);
        UfxDeviceNotifyDetach(ControllerContext->UfxDevice);
        ControllerContext->WasAttached = FALSE;
        KeWaitForSingleObject(&ControllerContext->DetachEvent,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
    }

End:
    TraceExit();
    return STATUS_SUCCESS;
}
Ejemplo n.º 20
0
NTSTATUS
FatFsdRead (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the driver entry to the common read routine for NtReadFile calls.
    For synchronous requests, the CommonRead is called with Wait == TRUE,
    which means the request will always be completed in the current thread,
    and never passed to the Fsp.  If it is not a synchronous request,
    CommonRead is called with Wait == FALSE, which means the request
    will be passed to the Fsp only if there is a need to block.

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the
        file being Read exists

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The FSD status for the IRP

--*/

{
    PFCB Fcb = NULL;
    NTSTATUS Status;
    PIRP_CONTEXT IrpContext = NULL;

    BOOLEAN TopLevel = FALSE;

    DebugTrace(+1, Dbg, "FatFsdRead\n", 0);

    //
    //  Call the common Read routine, with blocking allowed if synchronous
    //

    FsRtlEnterFileSystem();

    //
    //  We are first going to do a quick check for paging file IO.  Since this
    //  is a fast path, we must replicate the check for the fsdo.
    //

    if (!FatDeviceIsFatFsdo( IoGetCurrentIrpStackLocation(Irp)->DeviceObject))  {

        Fcb = (PFCB)(IoGetCurrentIrpStackLocation(Irp)->FileObject->FsContext);

        if ((NodeType(Fcb) == FAT_NTC_FCB) &&
            FlagOn(Fcb->FcbState, FCB_STATE_PAGING_FILE)) {

            //
            //  Do the usual STATUS_PENDING things.
            //

            IoMarkIrpPending( Irp );

            //
            //  If there is not enough stack to do this read, then post this
            //  read to the overflow queue.
            //

            if (IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD) {

                KEVENT Event;
                PAGING_FILE_OVERFLOW_PACKET Packet;

                Packet.Irp = Irp;
                Packet.Fcb = Fcb;

                KeInitializeEvent( &Event, NotificationEvent, FALSE );

                FsRtlPostPagingFileStackOverflow( &Packet, &Event, FatOverflowPagingFileRead );

                //
                //  And wait for the worker thread to complete the item
                //

                (VOID) KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );

            } else {

                //
                //  Perform the actual IO, it will be completed when the io finishes.
                //

                FatPagingFileIo( Irp, Fcb );
            }

            FsRtlExitFileSystem();

            return STATUS_PENDING;
        }
    }

    try {

        TopLevel = FatIsIrpTopLevel( Irp );

        IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );

        //
        //  If this is an Mdl complete request, don't go through
        //  common read.
        //

        if ( FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE) ) {

            DebugTrace(0, Dbg, "Calling FatCompleteMdl\n", 0 );
            try_return( Status = FatCompleteMdl( IrpContext, Irp ));
        }

        //
        //  Check if we have enough stack space to process this request.  If there
        //  isn't enough then we will pass the request off to the stack overflow thread.
        //

        if (IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD) {

            DebugTrace(0, Dbg, "Passing StackOverflowRead off\n", 0 );
            try_return( Status = FatPostStackOverflowRead( IrpContext, Irp, Fcb ) );
        }

        Status = FatCommonRead( IrpContext, Irp );

    try_exit: NOTHING;
    } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

        //
        //  We had some trouble trying to perform the requested
        //  operation, so we'll abort the I/O request with
        //  the error status that we get back from the
        //  execption code
        //

        Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
    }

    if (TopLevel) { IoSetTopLevelIrp( NULL ); }

    FsRtlExitFileSystem();

    //
    //  And return to our caller
    //

    DebugTrace(-1, Dbg, "FatFsdRead -> %08lx\n", Status);

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

    return Status;
}
Ejemplo n.º 21
0
DLC_STATUS
UpdateFunctionalAddress(
    IN PADAPTER_CONTEXT pAdapterContext
    )

/*++

Routine Description:

    Procedure first makes inclusive or between the functionl address of
    this process context and the functional address defined
    for all bindings and then saves the new functional address to NDIS.
    The NT mutex makes this operation atomic.

Arguments:

    pAdapterContext - LLC context of the current adapter

Return Value:

--*/

{
    UCHAR aMulticastList[LLC_MAX_MULTICAST_ADDRESS * 6];
    TR_BROADCAST_ADDRESS NewFunctional;
    UINT MulticastListSize;
    ULONG CurrentMulticast;
    PBINDING_CONTEXT pBinding;
    UINT i;
    NDIS_STATUS Status;

    ASSUME_IRQL(DISPATCH_LEVEL);

    NewFunctional.ulAddress = 0;

    //
    // We cannot be setting several functional addresses simultanously!
    //

    RELEASE_DRIVER_LOCK();

    ASSUME_IRQL(PASSIVE_LEVEL);

    KeWaitForSingleObject(&NdisAccessMutex, UserRequest, KernelMode, FALSE, NULL);

    ACQUIRE_DRIVER_LOCK();

    //
    // The access to global data structures must be procted by
    // the spin lock.
    //

    ACQUIRE_SPIN_LOCK(&pAdapterContext->ObjectDataBase);

    for (pBinding = pAdapterContext->pBindings; pBinding; pBinding = pBinding->pNext) {
        NewFunctional.ulAddress |= pBinding->Functional.ulAddress;
    }

    RELEASE_SPIN_LOCK(&pAdapterContext->ObjectDataBase);

    if ((pAdapterContext->NdisMedium == NdisMedium802_3)
    || (pAdapterContext->NdisMedium == NdisMediumFddi)) {

        //
        // Each bit in the functional address is translated
        // to a ethernet multicast address.
        // The bit order within byte has already been swapped.
        //

        CurrentMulticast = 1;
        MulticastListSize = 0;
        for (i = 0; i < 31; i++) {
            if (CurrentMulticast & NewFunctional.ulAddress) {
                aMulticastList[MulticastListSize] = 0x03;
                aMulticastList[MulticastListSize + 1] = 0;
                LlcMemCpy(&aMulticastList[MulticastListSize + 2],
                          &CurrentMulticast,
                          sizeof(CurrentMulticast)
                          );
                MulticastListSize += 6;
            }
            CurrentMulticast <<= 1;
        }

        //
        // Add the group addresses of all bindings behind
        // the functional addresses in the table.
        //

        for (pBinding = pAdapterContext->pBindings; pBinding; pBinding = pBinding->pNext) {

            //
            // We may drop some group addresses, but I don't expect that
            // it will ever happen (i don't know anybody using tr
            // group address, the possibility to have all functional
            // address bits in use and more than one group address in system
            // is almost impossible)
            //

            if (pBinding->ulBroadcastAddress != 0
            && MulticastListSize < LLC_MAX_MULTICAST_ADDRESS * 6) {

                //
                // Set the default bits in the group address,
                // but use ethernet bit order.
                //

                LlcMemCpy(&aMulticastList[MulticastListSize],
                          &pBinding->usBroadcastAddress,
                          6
                          );
                MulticastListSize += 6;
            }
        }

        RELEASE_DRIVER_LOCK();

        Status = SetNdisParameter(pAdapterContext,
                                  (pAdapterContext->NdisMedium == NdisMediumFddi)
                                    ? OID_FDDI_LONG_MULTICAST_LIST
                                    : OID_802_3_MULTICAST_LIST,
                                  aMulticastList,
                                  MulticastListSize
                                  );
    } else {

        //
        // The functional address bit (bit 0) must be always reset!
        //

        NewFunctional.auchAddress[0] &= ~0x80;

        RELEASE_DRIVER_LOCK();

        Status = SetNdisParameter(pAdapterContext,
                                  OID_802_5_CURRENT_FUNCTIONAL,
                                  &NewFunctional,
                                  sizeof(NewFunctional)
                                  );
    }

    ASSUME_IRQL(PASSIVE_LEVEL);

    KeReleaseMutex(&NdisAccessMutex, FALSE);

    ACQUIRE_DRIVER_LOCK();

    if (Status != STATUS_SUCCESS) {
        return DLC_STATUS_INVALID_FUNCTIONAL_ADDRESS;
    }
    return STATUS_SUCCESS;
}
Ejemplo n.º 22
0
__drv_mustHoldCriticalRegion
NTSTATUS
FatPostStackOverflowRead (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp,
    IN PFCB Fcb
    )

/*++

Routine Description:

    This routine posts a read request that could not be processed by
    the fsp thread because of stack overflow potential.

Arguments:

    Irp - Supplies the request to process.

    Fcb - Supplies the file.

Return Value:

    STATUS_PENDING.

--*/

{
    KEVENT Event;
    PERESOURCE Resource;
    PVCB Vcb;

    PAGED_CODE();

    DebugTrace(0, Dbg, "Getting too close to stack limit pass request to Fsp\n", 0 );

    //
    //  Initialize an event and get shared on the resource we will
    //  be later using the common read.
    //

    KeInitializeEvent( &Event, NotificationEvent, FALSE );

    //
    //  Preacquire the resource the read path will require so we know the
    //  worker thread can proceed without waiting.
    //
    
    if (FlagOn(Irp->Flags, IRP_PAGING_IO) && (Fcb->Header.PagingIoResource != NULL)) {

        Resource = Fcb->Header.PagingIoResource;

    } else {

        Resource = Fcb->Header.Resource;
    }
    
    //
    //  If there are no resources assodicated with the file (case: the virtual
    //  volume file), it is OK.  No resources will be acquired on the other side
    //  as well.
    //

    if (Resource) {
        
        ExAcquireResourceSharedLite( Resource, TRUE );
    }

    if (NodeType( Fcb ) == FAT_NTC_VCB) {

        Vcb = (PVCB) Fcb;
    
    } else {

        Vcb = Fcb->Vcb;
    }
    
    try {
        
        //
        //  Make the Irp just like a regular post request and
        //  then send the Irp to the special overflow thread.
        //  After the post we will wait for the stack overflow
        //  read routine to set the event that indicates we can
        //  now release the scb resource and return.
        //

        FatPrePostIrp( IrpContext, Irp );

        //
        //  If this read is the result of a verify, we have to
        //  tell the overflow read routne to temporarily
        //  hijack the Vcb->VerifyThread field so that reads
        //  can go through.
        //

        if (Vcb->VerifyThread == KeGetCurrentThread()) {

            SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_VERIFY_READ);
        }

        FsRtlPostStackOverflow( IrpContext, &Event, FatStackOverflowRead );

        //
        //  And wait for the worker thread to complete the item
        //

        KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );

    } finally {

        if (Resource) {

            ExReleaseResourceLite( Resource );
        }
    }

    return STATUS_PENDING;
}
Ejemplo n.º 23
0
NTSTATUS
NdFatSecondaryCommonWrite (
	IN PIRP_CONTEXT IrpContext,
	IN PIRP			Irp
	)
{
	NTSTATUS					status;

	PVOLUME_DEVICE_OBJECT		volDo = CONTAINING_RECORD( IrpContext->Vcb, VOLUME_DEVICE_OBJECT, Vcb );
	BOOLEAN						secondarySessionResourceAcquired = FALSE;
	
	PIO_STACK_LOCATION			irpSp = IoGetCurrentIrpStackLocation( Irp );
	PFILE_OBJECT				fileObject = irpSp->FileObject;

	struct Write				write;
	
	PSECONDARY_REQUEST			secondaryRequest = NULL;
	PNDFS_REQUEST_HEADER		ndfsRequestHeader;
	PNDFS_WINXP_REQUEST_HEADER	ndfsWinxpRequestHeader;
	PNDFS_WINXP_REPLY_HEADER	ndfsWinxpReplytHeader;

	LARGE_INTEGER				timeOut;

	TYPE_OF_OPEN				typeOfOpen;
	PVCB						vcb;
	PFCB						fcb;
	PCCB						ccb;
	BOOLEAN						fcbAcquired = FALSE;


	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	typeOfOpen = FatDecodeFileObject( fileObject, &vcb, &fcb, &ccb );

	ASSERT( typeOfOpen == UserFileOpen );

	if (FlagOn(ccb->NdFatFlags, ND_FAT_CCB_FLAG_UNOPENED)) {

		/*if (FlagOn( fcb->FcbState, FCB_STATE_FILE_DELETED )) {
	
			ASSERT( FALSE );
			FatRaiseStatus( IrpContext, STATUS_FILE_DELETED, NULL, NULL );
					
		} else */{
					
			ASSERT( FlagOn(ccb->NdFatFlags, ND_FAT_CCB_FLAG_CORRUPTED) );
			
			return STATUS_FILE_CORRUPT_ERROR;
		}
	}

	if (irpSp->Parameters.Write.ByteOffset.QuadPart == FILE_WRITE_TO_END_OF_FILE && 
		irpSp->Parameters.Write.ByteOffset.HighPart == -1) {

		write.ByteOffset = fcb->Header.FileSize;

	} else {

		write.ByteOffset = irpSp->Parameters.Write.ByteOffset;
	}

	write.Key		= 0;
	write.Length	= irpSp->Parameters.Write.Length;

	if (FlagOn(Irp->Flags, IRP_PAGING_IO)) {
		
		ASSERT( (write.ByteOffset.QuadPart + write.Length) <= 
				((fcb->Header.AllocationSize.QuadPart + PAGE_SIZE - 1) & ~((LONGLONG) (PAGE_SIZE-1))) );

		return STATUS_SUCCESS;
	}

	ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ); 
	//ASSERT( !FlagOn( IrpContext->State, IRP_CONTEXT_STATE_LAZY_WRITE ) );

	if ( (write.ByteOffset.QuadPart + write.Length) <= fcb->Header.FileSize.LowPart) {

		return STATUS_SUCCESS;
	}

	if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {

		return STATUS_PENDING;

		ASSERT( FALSE );
		DebugTrace2( 0, Dbg, ("Can't wait in NdFatSecondaryCommonWrite\n") );

		status = FatFsdPostRequest( IrpContext, Irp );

		DebugTrace2( -1, Dbg2, ("NdFatSecondaryCommonWrite:  FatFsdPostRequest -> %08lx\n", status) );
		return status;
	}

		DebugTrace2( 0, Dbg, ("write.ByteOffset.QuadPart + write.Length > fcb->Header.AllocationSize.QuadPart = %d "
								 "ExIsResourceAcquiredSharedLite(fcb->Header.Resource) = %d\n",
							   ((write.ByteOffset.QuadPart + write.Length) > fcb->Header.AllocationSize.QuadPart),
							   ExIsResourceAcquiredSharedLite(fcb->Header.Resource)) );

	if ((write.ByteOffset.QuadPart + write.Length) > fcb->Header.AllocationSize.QuadPart) {

		FatAcquireExclusiveFcb( IrpContext, fcb );
		fcbAcquired = TRUE;
	
	} 	

	try {

		secondarySessionResourceAcquired 
			= SecondaryAcquireResourceExclusiveLite( IrpContext, 
													 &volDo->Secondary->SessionResource, 
													 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

		if (FlagOn(volDo->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ) {

			PrintIrp( Dbg, "SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED", NULL, IrpContext->OriginatingIrp );
			FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );	
		}


		secondaryRequest = ALLOC_WINXP_SECONDARY_REQUEST( volDo->Secondary, 
														  IRP_MJ_SET_INFORMATION,
														  volDo->Secondary->Thread.SessionContext.SecondaryMaxDataSize );

		if (secondaryRequest == NULL) {

			FatRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
		}

		ndfsRequestHeader = &secondaryRequest->NdfsRequestHeader;
		INITIALIZE_NDFS_REQUEST_HEADER(	ndfsRequestHeader, NDFS_COMMAND_EXECUTE, volDo->Secondary, IRP_MJ_SET_INFORMATION, 0 );

		ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1);
		ASSERT( ndfsWinxpRequestHeader == (PNDFS_WINXP_REQUEST_HEADER)secondaryRequest->NdfsRequestData );

		//ndfsWinxpRequestHeader->IrpTag   = (_U32)Irp;
		ndfsWinxpRequestHeader->IrpMajorFunction = IRP_MJ_SET_INFORMATION;
		ndfsWinxpRequestHeader->IrpMinorFunction = 0;

		ndfsWinxpRequestHeader->FileHandle = ccb->PrimaryFileHandle;

		ndfsWinxpRequestHeader->IrpFlags   = 0;
		ndfsWinxpRequestHeader->IrpSpFlags = 0;

		ndfsWinxpRequestHeader->SetFile.FileHandle				= 0;
		ndfsWinxpRequestHeader->SetFile.Length					= sizeof( FILE_END_OF_FILE_INFORMATION );
		ndfsWinxpRequestHeader->SetFile.FileInformationClass	= FileEndOfFileInformation;

		ndfsWinxpRequestHeader->SetFile.EndOfFileInformation.EndOfFile = write.ByteOffset.QuadPart + write.Length;


		secondaryRequest->RequestType = SECONDARY_REQ_SEND_MESSAGE;
		QueueingSecondaryRequest( volDo->Secondary, secondaryRequest );

		timeOut.QuadPart = -NDFAT_TIME_OUT;
		status = KeWaitForSingleObject( &secondaryRequest->CompleteEvent, Executive, KernelMode, FALSE, &timeOut );
		
		if (status != STATUS_SUCCESS) {

			secondaryRequest = NULL;
			status = STATUS_IO_DEVICE_ERROR;
			leave;
		}

		KeClearEvent( &secondaryRequest->CompleteEvent );

		if (secondaryRequest->ExecuteStatus != STATUS_SUCCESS) {

			if (IrpContext->OriginatingIrp)
				PrintIrp( Dbg2, "secondaryRequest->ExecuteStatus != STATUS_SUCCESS", NULL, IrpContext->OriginatingIrp );
			DebugTrace2( 0, Dbg2, ("secondaryRequest->ExecuteStatus != STATUS_SUCCESS file = %s, line = %d\n", __FILE__, __LINE__) );

			FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
		}

		ndfsWinxpReplytHeader = (PNDFS_WINXP_REPLY_HEADER)secondaryRequest->NdfsReplyData;
		status = ndfsWinxpReplytHeader->Status;
		Irp->IoStatus.Information = write.Length;

		if (ndfsWinxpReplytHeader->Status != STATUS_SUCCESS) {

			DebugTrace2( 0, Dbg2, ("NdNtfsSecondaryCommonWrite: ndfsWinxpReplytHeader->Status = %x\n", ndfsWinxpReplytHeader->Status) );
			ASSERT( ndfsWinxpReplytHeader->Information == 0 );
		
		} else
			ASSERT( ndfsWinxpReplytHeader->FileInformationSet );
	
		if (ndfsWinxpReplytHeader->FileInformationSet) {

			PNDFS_FAT_MCB_ENTRY	mcbEntry;
			ULONG			index;

			BOOLEAN			lookupResut;
			VBO				vcn;
			LBO				lcn;
			//LBO			startingLcn;
			ULONG			clusterCount;

			//DbgPrint( "w ndfsWinxpReplytHeader->FileSize = %x\n", ndfsWinxpReplytHeader->FileSize );

			if (ndfsWinxpReplytHeader->AllocationSize != fcb->Header.AllocationSize.QuadPart) {

				ASSERT( ExIsResourceAcquiredExclusiveLite(fcb->Header.Resource) );

				ASSERT( ndfsWinxpReplytHeader->AllocationSize > fcb->Header.AllocationSize.QuadPart );

				mcbEntry = (PNDFS_FAT_MCB_ENTRY)( ndfsWinxpReplytHeader+1 );

				for (index=0, vcn=0; index < ndfsWinxpReplytHeader->NumberOfMcbEntry; index++, mcbEntry++) {

					lookupResut = FatLookupMcbEntry( vcb, &fcb->Mcb, vcn, &lcn, &clusterCount, NULL );
					
					if (lookupResut == TRUE && vcn < fcb->Header.AllocationSize.QuadPart) {

						ASSERT( lookupResut == TRUE );
						//ASSERT( startingLcn == lcn );
						ASSERT( vcn == mcbEntry->Vcn );
						ASSERT( lcn == (((LBO)mcbEntry->Lcn) << vcb->AllocationSupport.LogOfBytesPerSector) );
						ASSERT( clusterCount <= mcbEntry->ClusterCount );

						if (clusterCount < mcbEntry->ClusterCount) {

							FatAddMcbEntry ( vcb, 
											 &fcb->Mcb, 
											 (VBO)mcbEntry->Vcn, 
											 ((LBO)mcbEntry->Lcn) << vcb->AllocationSupport.LogOfBytesPerSector, 
											 (ULONG)mcbEntry->ClusterCount );

							lookupResut = FatLookupMcbEntry( vcb, &fcb->Mcb, vcn, &lcn, &clusterCount, NULL );

							ASSERT( lookupResut == TRUE );
							//ASSERT( startingLcn == lcn );
							ASSERT( vcn == mcbEntry->Vcn );
							ASSERT( lcn == (((LBO)mcbEntry->Lcn) << vcb->AllocationSupport.LogOfBytesPerSector) );
							ASSERT( clusterCount == mcbEntry->ClusterCount );
						}
					
					} else { 

						ASSERT( lookupResut == FALSE || lcn == 0 );

						FatAddMcbEntry ( vcb, 
										 &fcb->Mcb, 
										 (VBO)mcbEntry->Vcn, 
										 ((LBO)mcbEntry->Lcn) << vcb->AllocationSupport.LogOfBytesPerSector, 
										 (ULONG)mcbEntry->ClusterCount );
					}

					vcn += (ULONG)mcbEntry->ClusterCount;
				}

				ASSERT( vcn == ndfsWinxpReplytHeader->AllocationSize );

				fcb->Header.AllocationSize.QuadPart = ndfsWinxpReplytHeader->AllocationSize;
				SetFlag( fcb->FcbState, FCB_STATE_TRUNCATE_ON_CLOSE );		

				if (CcIsFileCached(fileObject)) {

					ASSERT( fileObject->SectionObjectPointer->SharedCacheMap != NULL );
					CcSetFileSizes( fileObject, (PCC_FILE_SIZES)&fcb->Header.AllocationSize );
				}
			}

			DebugTrace2(0, Dbg, ("write scb->Header.FileSize.LowPart = %I64x, scb->Header.ValidDataLength.QuadPart = %I64x\n", 
								 fcb->Header.FileSize.LowPart, fcb->Header.ValidDataLength.QuadPart) );

		}

#if DBG
		{
			BOOLEAN			lookupResut;
			VBO				vcn;
			LBO				lcn;
			//LCN				startingLcn;
			ULONG			clusterCount;

			vcn = 0;
			while (1) {

				lookupResut = FatLookupMcbEntry( vcb, &fcb->Mcb, vcn, &lcn, &clusterCount, NULL );
				if (lookupResut == FALSE || lcn == 0)
					break;

				vcn += clusterCount;
			}

			ASSERT( vcn == fcb->Header.AllocationSize.QuadPart );
		}

#endif

	} finally {
	
		if (secondarySessionResourceAcquired == TRUE)
				SecondaryReleaseResourceLite( IrpContext, &volDo->Secondary->SessionResource );

		if (fcbAcquired) {
             FatReleaseFcb( IrpContext, fcb );
        }

		if (secondaryRequest)
			DereferenceSecondaryRequest( secondaryRequest );
	}
			
	return status;
}
Ejemplo n.º 24
0
//=============================================================================
CSaveData::~CSaveData()
{
    PAGED_CODE();

    DPF_ENTER(("[CSaveData::~CSaveData]"));

    // Update the wave header in data file with real file size.
    //
    if(m_pFilePtr)
    {
        m_FileHeader.dwFileSize =
            (DWORD) m_pFilePtr->QuadPart - 2 * sizeof(DWORD);
        m_DataHeader.dwDataLength = (DWORD) m_pFilePtr->QuadPart -
                                     sizeof(m_FileHeader)        -
                                     m_FileHeader.dwFormatLength -
                                     sizeof(m_DataHeader);

        if (STATUS_SUCCESS == KeWaitForSingleObject
            (
                &m_FileSync,
                Executive,
                KernelMode,
                FALSE,
                NULL
            ))
        {
            if (NT_SUCCESS(FileOpen(FALSE)))
            {
                FileWriteHeader();

                FileClose();
            }

            KeReleaseMutex(&m_FileSync, FALSE);
        }
    }

    if (m_waveFormat)
    {
        ExFreePoolWithTag(m_waveFormat, SAVEDATA_POOLTAG1);
        m_waveFormat = NULL;
    }

    if (m_fFrameUsed)
    {
        ExFreePoolWithTag(m_fFrameUsed, SAVEDATA_POOLTAG2);
        m_fFrameUsed = NULL;
        // NOTE : Do not release m_pFilePtr.
    }

    if (m_FileName.Buffer)
    {
        ExFreePoolWithTag(m_FileName.Buffer, SAVEDATA_POOLTAG3);
        m_FileName.Buffer = NULL;
    }

    if (m_pDataBuffer)
    {
        ExFreePoolWithTag(m_pDataBuffer, SAVEDATA_POOLTAG4);
        m_pDataBuffer = NULL;
    }
} // CSaveData
Ejemplo n.º 25
0
VOID
xixfs_CleanupFlushVCB(
	IN PXIXFS_IRPCONTEXT pIrpContext,
	IN PXIXFS_VCB		pVCB,
	IN BOOLEAN			DisMountVCB
)
{

	

	//PAGED_CODE();

	ASSERT_IRPCONTEXT( pIrpContext );
	ASSERT_VCB( pVCB );

	ASSERT_EXCLUSIVE_XIFS_GDATA;
	ASSERT_EXCLUSIVE_VCB(pVCB);

	
	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
			("xixfs_CleanupFlushVCB Status(%ld).\n", pVCB->VCBState));




	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT), 
						 ("11 Current VCB->PtrVPB->ReferenceCount %d \n", pVCB->PtrVPB->ReferenceCount));


	XifsdLockVcb( pIrpContext, pVCB );

	XIXCORE_SET_FLAGS(pVCB->VCBFlags, XIFSD_VCB_FLAGS_DEFERED_CLOSE);

	if(DisMountVCB){
		if(pVCB->VolumeDasdFCB != NULL){
			pVCB->VolumeDasdFCB->FCBReference -= 1;
			pVCB->VolumeDasdFCB->FCBUserReference -= 1;
		}

		
		if(pVCB->MetaFCB != NULL){
			pVCB->MetaFCB->FCBReference -=1;
			pVCB->MetaFCB->FCBUserReference -= 1;
		}


		if(pVCB->RootDirFCB != NULL){
			pVCB->RootDirFCB->FCBReference -=1;
			pVCB->RootDirFCB->FCBUserReference -= 1;
		}
	}

	XifsdUnlockVcb(pIrpContext, pVCB);

	xixfs_PurgeVolume(pIrpContext, pVCB, DisMountVCB);

	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_PNP| DEBUG_TARGET_VCB| DEBUG_TARGET_IRPCONTEXT),
						 ("22 Current VCB->PtrVPB->ReferenceCount %d \n", pVCB->PtrVPB->ReferenceCount));


	if(DisMountVCB){
		// Added by ILGU HONG
		XifsdReleaseVcb(TRUE, pVCB);
		
		DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO ),
					 ("VCB %d/%d \n", pVCB->VCBReference, pVCB->VCBUserReference));		


		CcWaitForCurrentLazyWriterActivity();

		XifsdAcquireVcbExclusive(TRUE, pVCB, FALSE);
			
		xixfs_RealCloseFCB((PVOID)pVCB);
	}

	XifsdLockVcb( pIrpContext, pVCB );
	XIXCORE_CLEAR_FLAGS(pVCB->VCBFlags, XIFSD_VCB_FLAGS_DEFERED_CLOSE);
	XifsdUnlockVcb(pIrpContext, pVCB);


	// Added by ILGU HONG END
	if(DisMountVCB){

		// changed by ILGU HONG for readonly 09052006
		if(!pVCB->XixcoreVcb.IsVolumeWriteProtected){

			LARGE_INTEGER	TimeOut;
			
			//
			//	Stop Meta Update process
			//

			KeSetEvent(&pVCB->VCBUmountEvent, 0, FALSE);

			TimeOut.QuadPart = - DEFAULT_XIFS_UMOUNTWAIT;
			KeWaitForSingleObject(&pVCB->VCBStopOkEvent, Executive, KernelMode, FALSE, &TimeOut);		
			


			xixcore_DeregisterHost(&pVCB->XixcoreVcb);
			
			//	Added by ILGU HONG for 08312006
			if(pVCB->NdasVolBacl_Id){
				xixfs_RemoveUserBacl(pVCB->TargetDeviceObject, pVCB->NdasVolBacl_Id);
			}
			
			//	Added by ILGU HONG End	
		}
		// changed by ILGU HONG for readonly end
	}

	return;
}
Ejemplo n.º 26
0
NTSTATUS
FatCommonDeviceControl (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for doing Device control operations called
    by both the fsd and fsp threads

Arguments:

    Irp - Supplies the Irp to process

    InFsp - Indicates if this is the fsp thread or someother thread

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpSp;
    KEVENT WaitEvent;
    PVOID CompletionContext = NULL;

    PVCB Vcb;
    PFCB Fcb;
    PCCB Ccb;

#ifdef __ND_FAT_PRIMARY__

	if (IrpContext->MajorFunction == IRP_MJ_DEVICE_CONTROL && 
		IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode == IOCTL_INSERT_PRIMARY_SESSION) {

		PVOLUME_DEVICE_OBJECT	VolDo = CONTAINING_RECORD( IoGetCurrentIrpStackLocation(Irp)->DeviceObject, 
														   VOLUME_DEVICE_OBJECT, 
														   DeviceObject );
		PSESSION_INFORMATION	inputBuffer = (PSESSION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
		ULONG					inputBufferLength = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.InputBufferLength;
		ULONG					outputBufferLength;
		PULONG					outputBuffer;
		PPRIMARY_SESSION		primarySession;

		if (inputBufferLength != sizeof(SESSION_INFORMATION)) {

			FatCompleteRequest( IrpContext, Irp, Status = STATUS_INVALID_PARAMETER );
			return Status;
		} 

		outputBufferLength = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.OutputBufferLength;
		outputBuffer = (PULONG)Irp->AssociatedIrp.SystemBuffer;

		primarySession = PrimarySession_Create( IrpContext, VolDo, inputBuffer, Irp );

		ASSERT( primarySession );

		FatCompleteRequest( IrpContext, NULL, 0 );
		Status = STATUS_PENDING;
		return Status;
	}

#endif

    //
    //  Get a pointer to the current Irp stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "FatCommonDeviceControl\n", 0);
    DebugTrace( 0, Dbg, "Irp           = %08lx\n", Irp);
    DebugTrace( 0, Dbg, "MinorFunction = %08lx\n", IrpSp->MinorFunction);

    //
    //  Decode the file object, the only type of opens we accept are
    //  user volume opens.
    //

    if (FatDecodeFileObject( IrpSp->FileObject, &Vcb, &Fcb, &Ccb ) != UserVolumeOpen) {

        FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );

        DebugTrace(-1, Dbg2, "FatCommonDeviceControl -> %08lx\n", STATUS_INVALID_PARAMETER);
        return STATUS_INVALID_PARAMETER;
    }

    //
    //  A few IOCTLs actually require some intervention on our part
    //

    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {

    case IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES:


#ifdef __ND_FAT_WIN2K_SUPPORT__

		if (!IS_WINDOWSXP_OR_LATER()) {

			ASSERT( FALSE );
			IoSkipCurrentIrpStackLocation( Irp );
			break;
		}

#endif

        //
        //  This is sent by the Volume Snapshot driver (Lovelace).
        //  We flush the volume, and hold all file resources
        //  to make sure that nothing more gets dirty. Then we wait
        //  for the IRP to complete or cancel.
        //

        SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
        FatAcquireExclusiveVolume( IrpContext, Vcb );

		FatFlushAndCleanVolume( IrpContext,
                                Irp,
                                Vcb,
                                FlushWithoutPurge );

        KeInitializeEvent( &WaitEvent, NotificationEvent, FALSE );
        CompletionContext = &WaitEvent;

        //
        //  Get the next stack location, and copy over the stack location
        //

        IoCopyCurrentIrpStackLocationToNext( Irp );

        //
        //  Set up the completion routine
        //

        IoSetCompletionRoutine( Irp,
                                FatDeviceControlCompletionRoutine,
                                CompletionContext,
                                TRUE,
                                TRUE,
                                TRUE );
        break;

    default:

        //
        //  FAT doesn't need to see this on the way back, so skip ourselves.
        //

        IoSkipCurrentIrpStackLocation( Irp );
        break;
    }

    //
    //  Send the request.
    //

    Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);

    if (Status == STATUS_PENDING && CompletionContext) {

        KeWaitForSingleObject( &WaitEvent,
                               Executive,
                               KernelMode,
                               FALSE,
                               NULL );

        Status = Irp->IoStatus.Status;
    }

    //
    //  If we had a context, the IRP remains for us and we will complete it.
    //  Handle it appropriately.
    //

    if (CompletionContext) {

        //
        //  Release all the resources that we held because of a
        //  VOLSNAP_FLUSH_AND_HOLD. 
        //

        ASSERT( IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES );

        FatReleaseVolume( IrpContext, Vcb );

        //
        //  If we had no context, the IRP will complete asynchronously.
        //

    } else {

        Irp = NULL;
    }

    FatCompleteRequest( IrpContext, Irp, Status );

    DebugTrace(-1, Dbg, "FatCommonDeviceControl -> %08lx\n", Status);

    return Status;
}
Ejemplo n.º 27
0
NTSTATUS
FatPnpQueryRemove (
    PIRP_CONTEXT IrpContext,
    PIRP Irp,
    PVCB Vcb
    )

/*++

Routine Description:

    This routine handles the PnP query remove operation.  The filesystem
    is responsible for answering whether there are any reasons it sees
    that the volume can not go away (and the device removed).  Initiation
    of the dismount begins when we answer yes to this question.
    
    Query will be followed by a Cancel or Remove.

Arguments:

    Irp - Supplies the Irp to process
    
    Vcb - Supplies the volume being queried.

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    KEVENT Event;
    BOOLEAN VcbDeleted = FALSE;
    BOOLEAN GlobalHeld = TRUE;

    //
    //  Having said yes to a QUERY, any communication with the
    //  underlying storage stack is undefined (and may block)
    //  until the bounding CANCEL or REMOVE is sent.
    //

#if __NDAS_FAT_SECONDARY__
	if (FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT))
		FatAcquireExclusiveSecondaryVcb( IrpContext, Vcb );
	else
		FatAcquireExclusiveVcb( IrpContext, Vcb );
#else
	FatAcquireExclusiveVcb( IrpContext, Vcb );
#endif

    FatReleaseGlobal( IrpContext);
    GlobalHeld = FALSE;

    try {
        
        Status = FatLockVolumeInternal( IrpContext, Vcb, NULL );

        //
        //  Drop an additional reference on the Vpb so that the volume cannot be
        //  torn down when we drop all the locks below.
        //
        
        FatPnpAdjustVpbRefCount( Vcb, 1);
        
        //
        //  Drop and reacquire the resources in the right order.
        //

#if __NDAS_FAT_SECONDARY__
		if (FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT)) {
			FatReleaseSecondaryVcb( IrpContext, Vcb );
		} else {
			FatReleaseVcb( IrpContext, Vcb );
		}
#else
		FatReleaseVcb( IrpContext, Vcb );
#endif       
        FatAcquireExclusiveGlobal( IrpContext );
        GlobalHeld = TRUE;
#if __NDAS_FAT_SECONDARY__
		if (FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT))
			FatAcquireExclusiveSecondaryVcb( IrpContext, Vcb );
		else
			FatAcquireExclusiveVcb( IrpContext, Vcb );
#else
		FatAcquireExclusiveVcb( IrpContext, Vcb );
#endif

        //
        //  Drop the reference we added above.
        //
        
        FatPnpAdjustVpbRefCount( Vcb, -1);

        if (NT_SUCCESS( Status )) {

            //
            //  With the volume held locked, note that we must finalize as much
            //  as possible right now.
            //

            FatFlushAndCleanVolume( IrpContext, Irp, Vcb, Flush );

            //
            //  We need to pass this down before starting the dismount, which
            //  could disconnect us immediately from the stack.
            //

            //
            //  Get the next stack location, and copy over the stack location
            //

            IoCopyCurrentIrpStackLocationToNext( Irp );

            //
            //  Set up the completion routine
            //

            KeInitializeEvent( &Event, NotificationEvent, FALSE );
            IoSetCompletionRoutine( Irp,
                                    FatPnpCompletionRoutine,
                                    &Event,
                                    TRUE,
                                    TRUE,
                                    TRUE );

            //
            //  Send the request and wait.
            //

            Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);

            if (Status == STATUS_PENDING) {

                KeWaitForSingleObject( &Event,
                                       Executive,
                                       KernelMode,
                                       FALSE,
                                       NULL );

                Status = Irp->IoStatus.Status;
            }

            //
            //  Now if no one below us failed already, initiate the dismount
            //  on this volume, make it go away.  PnP needs to see our internal
            //  streams close and drop their references to the target device.
            //
            //  Since we were able to lock the volume, we are guaranteed to
            //  move this volume into dismount state and disconnect it from
            //  the underlying storage stack.  The force on our part is actually
            //  unnecesary, though complete.
            //
            //  What is not strictly guaranteed, though, is that the closes
            //  for the metadata streams take effect synchronously underneath
            //  of this call.  This would leave references on the target device
            //  even though we are disconnected!
            //

            if (NT_SUCCESS( Status )) {

                VcbDeleted = FatCheckForDismount( IrpContext, Vcb, TRUE );

                ASSERT( VcbDeleted || Vcb->VcbCondition == VcbBad );

            }
        }
    } finally {

        //
        //  Release the Vcb if it could still remain.
        //
        
        if (!VcbDeleted) {

#if __NDAS_FAT_SECONDARY__
			if (FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT)) {
				FatReleaseSecondaryVcb( IrpContext, Vcb );
			} else {
				FatReleaseVcb( IrpContext, Vcb );
			}
#else
			FatReleaseVcb( IrpContext, Vcb );
#endif       
        }

        if (GlobalHeld) {
            
            FatReleaseGlobal( IrpContext );
        }
    }
    
    //
    //  Cleanup our IrpContext and complete the IRP if neccesary.
    //

    FatCompleteRequest( IrpContext, Irp, Status );

    return Status;
}
Ejemplo n.º 28
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
PsGetContextThread(IN PETHREAD Thread,
                   IN OUT PCONTEXT ThreadContext,
                   IN KPROCESSOR_MODE PreviousMode)
{
    GET_SET_CTX_CONTEXT GetSetContext;
    ULONG Size = 0, Flags = 0;
    NTSTATUS Status;

    /* Enter SEH */
    _SEH2_TRY
    {
        /* Set default ength */
        Size = sizeof(CONTEXT);

        /* Read the flags */
        Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);

#ifdef _M_IX86
        /* Check if the caller wanted extended registers */
        if ((Flags & CONTEXT_EXTENDED_REGISTERS) !=
            CONTEXT_EXTENDED_REGISTERS)
        {
            /* Cut them out of the size */
            Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
        }
#endif

        /* Check if we came from user mode */
        if (PreviousMode != KernelMode)
        {
            /* Probe the context */
            ProbeForWrite(ThreadContext, Size, sizeof(ULONG));
        }
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        /* Return the exception code */
        _SEH2_YIELD(return _SEH2_GetExceptionCode());
    }
    _SEH2_END;

    /* Initialize the wait event */
    KeInitializeEvent(&GetSetContext.Event, NotificationEvent, FALSE);

    /* Set the flags and previous mode */
    GetSetContext.Context.ContextFlags = Flags;
    GetSetContext.Mode = PreviousMode;

    /* Check if we're running in the same thread */
    if (Thread == PsGetCurrentThread())
    {
        /* Setup APC parameters manually */
        GetSetContext.Apc.SystemArgument1 = NULL;
        GetSetContext.Apc.SystemArgument2 = Thread;

        /* Enter a guarded region to simulate APC_LEVEL */
        KeEnterGuardedRegion();

        /* Manually call the APC */
        PspGetOrSetContextKernelRoutine(&GetSetContext.Apc,
                                        NULL,
                                        NULL,
                                        &GetSetContext.Apc.SystemArgument1,
                                        &GetSetContext.Apc.SystemArgument2);

        /* Leave the guarded region */
        KeLeaveGuardedRegion();

        /* We are done */
        Status = STATUS_SUCCESS;
    }
    else
    {
        /* Initialize the APC */
        KeInitializeApc(&GetSetContext.Apc,
                        &Thread->Tcb,
                        OriginalApcEnvironment,
                        PspGetOrSetContextKernelRoutine,
                        NULL,
                        NULL,
                        KernelMode,
                        NULL);

        /* Queue it as a Get APC */
        if (!KeInsertQueueApc(&GetSetContext.Apc, NULL, Thread, 2))
        {
            /* It was already queued, so fail */
            Status = STATUS_UNSUCCESSFUL;
        }
        else
        {
            /* Wait for the APC to complete */
            Status = KeWaitForSingleObject(&GetSetContext.Event,
                                           0,
                                           KernelMode,
                                           FALSE,
                                           NULL);
        }
    }

    _SEH2_TRY
    {
        /* Copy the context */
        RtlCopyMemory(ThreadContext, &GetSetContext.Context, Size);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        /* Get the exception code */
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    /* Return status */
    return Status;
}
Ejemplo n.º 29
0
NTSTATUS
FatPnpSurpriseRemove (
    PIRP_CONTEXT IrpContext,
    PIRP Irp,
    PVCB Vcb
    )

/*++

Routine Description:

    This routine handles the PnP surprise remove operation.  This is another
    type of notification that the underlying storage device for the volume we
    have is gone, and is excellent indication that the volume will never reappear.
    The filesystem is responsible for initiation or completion the dismount.
    
    For the most part, only "real" drivers care about the distinction of a
    surprise remove, which is a result of our noticing that a user (usually)
    physically reached into the machine and pulled something out.
    
    Surprise will be followed by a Remove when all references have been shut down.

Arguments:

    Irp - Supplies the Irp to process
    
    Vcb - Supplies the volume being removed.

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    KEVENT Event;
    BOOLEAN VcbDeleted;
    
    //
    //  SURPRISE - a device was physically yanked away without
    //  any warning.  This means external forces.
    //
    
#if __NDAS_FAT_SECONDARY__
	if (FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT))
		FatAcquireExclusiveSecondaryVcb( IrpContext, Vcb );
	else
		FatAcquireExclusiveVcb( IrpContext, Vcb );
#else
	FatAcquireExclusiveVcb( IrpContext, Vcb );
#endif
        
    //
    //  We need to pass this down before starting the dismount, which
    //  could disconnect us immediately from the stack.
    //
    
    //
    //  Get the next stack location, and copy over the stack location
    //

    IoCopyCurrentIrpStackLocationToNext( Irp );

    //
    //  Set up the completion routine
    //

    KeInitializeEvent( &Event, NotificationEvent, FALSE );
    IoSetCompletionRoutine( Irp,
                            FatPnpCompletionRoutine,
                            &Event,
                            TRUE,
                            TRUE,
                            TRUE );

    //
    //  Send the request and wait.
    //

    Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);

    if (Status == STATUS_PENDING) {

        KeWaitForSingleObject( &Event,
                               Executive,
                               KernelMode,
                               FALSE,
                               NULL );

        Status = Irp->IoStatus.Status;
    }
    
    try {
        
        //
        //  Knock as many files down for this volume as we can.
        //

        FatFlushAndCleanVolume( IrpContext, Irp, Vcb, NoFlush );

        //
        //  Now make our dismount happen.  This may not vaporize the
        //  Vcb, of course, since there could be any number of handles
        //  outstanding since this is an out of band notification.
        //

        VcbDeleted = FatCheckForDismount( IrpContext, Vcb, TRUE );

    } finally {
        
        //
        //  Release the Vcb if it could still remain.
        //

        if (!VcbDeleted) {

#if __NDAS_FAT_SECONDARY__
			if (FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT)) {
				FatReleaseSecondaryVcb( IrpContext, Vcb );
			} else {
				FatReleaseVcb( IrpContext, Vcb );
			}
#else
			FatReleaseVcb( IrpContext, Vcb );
#endif       
        }

        FatReleaseGlobal( IrpContext );
    }
    
    //
    //  Cleanup our IrpContext and complete the IRP.
    //

    FatCompleteRequest( IrpContext, Irp, Status );

    return Status;
}
Ejemplo n.º 30
0
BOOLEAN
TtdiServer()
{
    USHORT i;
    HANDLE RdrHandle, SrvConnectionHandle;
    KEVENT Event1;
    PFILE_OBJECT AddressObject, ConnectionObject;
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
    PMDL ReceiveMdl;
    IO_STATUS_BLOCK Iosb1;
    TDI_CONNECTION_INFORMATION RequestInformation;
    TDI_CONNECTION_INFORMATION ReturnInformation;
    PTRANSPORT_ADDRESS ListenBlock;
    PTRANSPORT_ADDRESS ConnectBlock;
    PTDI_ADDRESS_NETBIOS temp;
    PUCHAR MessageBuffer;
    ULONG MessageBufferLength;
    ULONG CurrentBufferLength;
    PIRP Irp;

    Status = KeWaitForSingleObject (&TdiServerEvent, Suspended, KernelMode, FALSE, NULL);

    MessageBufferLength = (ULONG)BUFFER_SIZE;


    DbgPrint( "\n****** Start of Server Test ******\n" );

    RBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
    if (RBuff == (PVOID)NULL) {
        DbgPrint ("Unable to allocate nonpaged pool for receive buffer exiting\n");
        return FALSE;
    }

    ListenBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));
    ConnectBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS));

    ListenBlock->TAAddressCount = 1;
    ListenBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ListenBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ListenBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = AnyName[i];
    }

    ConnectBlock->TAAddressCount = 1;
    ConnectBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    ConnectBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
    temp = (PTDI_ADDRESS_NETBIOS)ConnectBlock->Address[0].Address;

    temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    for (i=0;i<16;i++) {
        temp->NetbiosName[i] = ServerName[i];
    }

    //
    // Create an event for the synchronous I/O requests that we'll be issuing.
    //

    KeInitializeEvent (
                &Event1,
                SynchronizationEvent,
                FALSE);

    Status = TtdiOpenAddress (&RdrHandle, ServerName);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Server Test:  FAILED on open of client: %lC ******\n", Status );
        return FALSE;
    }

    Status = ObReferenceObjectByHandle (
                RdrHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &AddressObject,
                NULL);

    //
    // Now loop forever trying to get a connection from a remote client to
    // this server. We will create connections until we run out of resources,
    // and we will echo the data we are sent back along the same connection.
    // Sends and Receives are always asynchronous, while listens are
    // synchronous.
    //

    while (TRUE) {

        //
        // Open the connection on the transport.
        //

        Status = TtdiOpenConnection (&SrvConnectionHandle, 1);
        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Server Test:  FAILED on open of server Connection: %lC ******\n", Status );
            return FALSE;
        }

        Status = ObReferenceObjectByHandle (
                    SrvConnectionHandle,
                    0L,
                    NULL,
                    KernelMode,
                    (PVOID *) &ConnectionObject,
                    NULL);

        if (!NT_SUCCESS(Status)) {
            DbgPrint( "\n****** Server Test:  FAILED on open of server Connection: %lC ******\n", Status );
            return FALSE;
        }

        //
        // Get a pointer to the stack location for the first driver.  This will be
        // used to pass the original function codes and parameters.
        //

        DeviceObject = IoGetRelatedDeviceObject( ConnectionObject );

        //
        // Now register the device handler for receives
        //

//        Irp = TdiBuildInternalDeviceControlIrp (
//                    TDI_SET_EVENT_HANDLER,
//                    DeviceObject,
//                    ConnectionObject,
//                    &Event1,
//                    &Iosb1);

//        TdiBuildSetEventHandler (Irp,
//            DeviceObject,
//            ConnectionObject,
//            TSTRCVCompletion,
//            &Event1,
//            TDI_RECEIVE_HANDLER,
//            TdiTestReceiveHandler,
//            ConnectionObject);

//        Status = IoCallDriver (DeviceObject, Irp);

//       if (Status == STATUS_PENDING) {
//            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
//            if (!NT_SUCCESS(Status)) {
//                DbgPrint( "\n****** Server Test:  FAILED Event1 Wait Register: %lC ******\n", Status );
//                return FALSE;
//            }
//            if (!NT_SUCCESS(Iosb1.Status)) {
//                DbgPrint( "\n****** Server Test:  FAILED Register Iosb status: %lC ******\n", Status );
//                return FALSE;
//            }
//
//        } else {
//            if (!NT_SUCCESS (Status)) {
//                DbgPrint( "\n****** Server Test:  RegisterHandler FAILED  Status: %lC ******\n", Status );
//                return FALSE;
//            }
//        }

        Irp = TdiBuildInternalDeviceControlIrp (
                    TDI_ASSOCIATE_ADDRESS,
                    DeviceObject,
                    ConnectionObject,
                    &Event1,
                    &Iosb1);

        TdiBuildAssociateAddress (Irp,
            DeviceObject,
            ConnectionObject,
            TSTRCVCompletion,
            &Event1,
            RdrHandle);

        Status = IoCallDriver (DeviceObject, Irp);

    //    IoFreeIrp (Irp);

        if (Status == STATUS_PENDING) {
            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
            if (!NT_SUCCESS(Status)) {
                DbgPrint( "\n****** Server Test:  FAILED Event1 Wait Associate: %lC ******\n", Status );
                return FALSE;
            }
            if (!NT_SUCCESS(Iosb1.Status)) {
                DbgPrint( "\n****** Server Test:  FAILED Associate Iosb status: %lC ******\n", Status );
                return FALSE;
            }

        } else {
            if (!NT_SUCCESS (Status)) {
                DbgPrint( "\n****** Server Test:  AssociateAddress FAILED  Status: %lC ******\n", Status );
                return FALSE;
            }
        }

        //
        // Post a TdiListen to the server endpoint.
        //

        RequestInformation.RemoteAddress = ListenBlock;
        RequestInformation.RemoteAddressLength = sizeof (TRANSPORT_ADDRESS) +
                                                sizeof (TDI_ADDRESS_NETBIOS);

        KeInitializeEvent (
                    &Event1,
                    SynchronizationEvent,
                    FALSE);

        Irp = TdiBuildInternalDeviceControlIrp (
                    TDI_LISTEN,
                    DeviceObject,
                    ConnectionObject,
                    &Event1,
                    &Iosb1);

        TdiBuildListen (
            Irp,
            DeviceObject,
            ConnectionObject,
            TSTRCVCompletion,
            &Event1,
            0,
            &RequestInformation,
            NULL);

        Status = IoCallDriver (DeviceObject, Irp);

        if (Status == STATUS_PENDING) {
            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
            if (!NT_SUCCESS(Status)) {
                DbgPrint( "\n****** Server Test:  FAILED Event1 Wait Listen: %lC ******\n", Status );
                return FALSE;
            }
            if (!NT_SUCCESS(Iosb1.Status)) {
                DbgPrint( "\n****** Server Test:  FAILED Listen Iosb status: %lC ******\n", Status );
                return FALSE;
            }

        } else {
            if (!NT_SUCCESS (Status)) {
                DbgPrint( "\n****** Server Test: Listen FAILED  Status: %lC ******\n", Status );
                return FALSE;
            }
        }

        DbgPrint ("\n****** Server Test: LISTEN just completed! ******\n");

        //
        // accept the connection from the remote
        //

        KeInitializeEvent (
                    &Event1,
                    SynchronizationEvent,
                    FALSE);

        Irp = TdiBuildInternalDeviceControlIrp (
                    TDI_ACCEPT,
                    DeviceObject,
                    ConnectionObject,
                    &Event1,
                    &Iosb1);

        TdiBuildAccept (
            Irp,
            DeviceObject,
            ConnectionObject,
            NULL,
            NULL,
            &RequestInformation,
            NULL,
            0);

        Status = IoCallDriver (DeviceObject, Irp);

    //    IoFreeIrp (Irp);

        if (Status == STATUS_PENDING) {
            Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
            if (!NT_SUCCESS(Status)) {
                DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Accept: %lC ******\n", Status );
                return FALSE;
            }
            if (!NT_SUCCESS(Iosb1.Status)) {
                DbgPrint( "\n****** Receive Test:  FAILED Accept Iosb status: %lC ******\n", Status );
                return FALSE;
            }

        } else {
            if (!NT_SUCCESS (Status)) {
                DbgPrint( "\n****** Accept Test: Listen FAILED  Status: %lC ******\n", Status );
                return FALSE;
            }
        }

        //
        // Get a buffer for the continued read/write loop.
        //

        MessageBuffer=(PUCHAR)ExAllocatePool (NonPagedPool, MessageBufferLength);
        if (MessageBuffer == NULL) {
            DbgPrint ("\n****** Send Test:  ExAllocatePool failed! ******\n");
        }
        ReceiveMdl = IoAllocateMdl (MessageBuffer, MessageBufferLength, FALSE, FALSE, NULL);
        MmBuildMdlForNonPagedPool (ReceiveMdl);

        //
        // have a receive buffer, and a connection; go ahead and read and write
        // until the remote disconnects.
        //

        while (TRUE) {

            KeInitializeEvent (
                        &Event1,
                        SynchronizationEvent,
                        FALSE);

            Irp = TdiBuildInternalDeviceControlIrp (
                        TDI_RECEIVE,
                        DeviceObject,
                        ConnectionObject,
                        &Event1,
                        &Iosb1);

            TdiBuildReceive (Irp,
                DeviceObject,
                ConnectionObject,
                TSTRCVCompletion,
                &Event1,
                ReceiveMdl,
                MessageBufferLength);

            InitWaitObject (&Event1);

            Status = IoCallDriver (DeviceObject, Irp);

            if (Status == STATUS_PENDING) {
                Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
                if (!NT_SUCCESS(Status)) {
                    DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Receive: %lC ******\n", Status );
                    return FALSE;
                }
                if (!NT_SUCCESS(Iosb1.Status)) {
                    DbgPrint( "\n****** Receive Test:  FAILED Receive Iosb status: %lC ******\n", Status );
                    return FALSE;
                }

            } else {
                if (!NT_SUCCESS (Status)) {

                    //
                    // Check to see if the remote has disconnected, which is
                    // the only reason for us shutting down/
                    //

                    if (Status == STATUS_REMOTE_DISCONNECT) {

                        //
                        // We've been disconnected from; get out
                        //

                        NtClose (SrvConnectionHandle);
                        break;
                    }

                    DbgPrint( "\n****** Receive Test: Listen FAILED  Status: %lC ******\n", Status );
                    return FALSE;
                } else {

                    //
                    // successful return, what length is the data?
                    //

                    CurrentBufferLength = Iosb1.Information;
                }
            }

            //
            // send the data back
            //

            KeInitializeEvent (
                        &Event1,
                        SynchronizationEvent,
                        FALSE);

            Irp = TdiBuildInternalDeviceControlIrp (
                        TDI_SEND,
                        DeviceObject,
                        ConnectionObject,
                        &Event1,
                        &Iosb1);

            TdiBuildSend (Irp,
                DeviceObject,
                ConnectionObject,
                TSTRCVCompletion,
                &Event1,
                ReceiveMdl,
                0,
                CurrentBufferLength);

            Status = IoCallDriver (DeviceObject, Irp);

            if (Status == STATUS_PENDING) {
                Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
                if (!NT_SUCCESS(Status)) {
                    DbgPrint( "\n****** Receive Test:  FAILED Event1 Wait Send: %lC ******\n", Status );
                    return FALSE;
                }
                if (!NT_SUCCESS(Iosb1.Status)) {
                    DbgPrint( "\n****** Receive Test:  FAILED Send Iosb status: %lC ******\n", Status );
                    return FALSE;
                }

            } else {
                if (!NT_SUCCESS (Status)) {

                    DbgPrint( "\n****** Receive Test: Send FAILED  Status: %lC ******\n", Status );
                    NtClose (SrvConnectionHandle);
                    break;

                }
            }
        } // end of receive/send while

        IoFreeMdl (ReceiveMdl);
        ExFreePool (MessageBuffer);

    }

    //
    // We're done with this address.  Close it and get out.
    //

    Status = CloseAddress (RdrHandle);
    if (!NT_SUCCESS(Status)) {
        DbgPrint( "\n****** Send Test:  FAILED on 2nd Close: %lC ******\n", Status );
        return FALSE;
    }

    DbgPrint( "\n****** End of Send Test ******\n" );
    return TRUE;
} /* Server */