RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
{
    /*
     * Validate.
     */
    AssertPtrReturn(pTimer, VERR_INVALID_HANDLE);
    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE);

    if (!ASMAtomicUoReadBool(&pTimer->fSuspended))
        return VERR_TIMER_ACTIVE;
    if (   pTimer->fSpecificCpu
        && !RTMpIsCpuOnline(pTimer->idCpu))
        return VERR_CPU_OFFLINE;

    /*
     * Start the timer.
     */
    PKDPC pMasterDpc = pTimer->fOmniTimer
                     ? &pTimer->aSubTimers[RTMpCpuIdToSetIndex(pTimer->idCpu)].NtDpc
                     : &pTimer->aSubTimers[0].NtDpc;

    uint64_t u64Interval = pTimer->u64NanoInterval / 1000000; /* This is ms, believe it or not. */
    ULONG ulInterval = (ULONG)u64Interval;
    if (ulInterval != u64Interval)
        ulInterval = MAXLONG;
    else if (!ulInterval && pTimer->u64NanoInterval)
        ulInterval = 1;

    LARGE_INTEGER DueTime;
    DueTime.QuadPart = -(int64_t)(u64First / 100); /* Relative, NT time. */
    if (DueTime.QuadPart)
        DueTime.QuadPart = -1;

    ASMAtomicWriteBool(&pTimer->fSuspended, false);
    KeSetTimerEx(&pTimer->NtTimer, DueTime, ulInterval, pMasterDpc);
    return VINF_SUCCESS;
}
Beispiel #2
0
NTSTATUS
PsdoDispatchWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
	NTSTATUS status;
	PIO_STACK_LOCATION p_IO_STK;
	PDEVICE_EXTENSION p_DVCEXT;
	ANSI_STRING RxChoice;
	UNICODE_STRING U_RxChoiceDrv;

	PVOID Buf;		//Buffer provided by user program
	ULONG BufLen;	//Buffer length for user provided buffer
	LONGLONG Offset;//Buffer Offset
	PVOID DataBuf;  //Buffer provided by Driver
	ULONG DataLen;  //Buffer length for Driver Data Buffer

	HANDLE tmrthreadhandle;
	DbgPrint("MWDM_DRIVER: DispatchWrite | Started\n");
	/*p_IO_STK = IoGetCurrentIrpStackLocation(Irp);
	p_DVCEXT = DeviceObject->DeviceExtension;

	BufLen = p_IO_STK->Parameters.Read.Length;
	Offset = p_IO_STK->Parameters.Read.ByteOffset.QuadPart;
	Buf = (PUCHAR)(Irp->AssociatedIrp.SystemBuffer) + Offset;*/
	
	if (dispatch_write_callcount == 0) //update count and exit routine
	{
	KdPrint(("Count = 0, so updating choice"));
	KdPrint(("UserBuffer: %s\n", Irp->AssociatedIrp.SystemBuffer));
	choice = atoi(Irp->AssociatedIrp.SystemBuffer);
	KdPrint(("Choice: %d\n", choice));
	dispatch_write_callcount =1;
	Irp->IoStatus.Status=STATUS_SUCCESS;
	Irp->IoStatus.Information=0;
	IoCompleteRequest(Irp,IO_NO_INCREMENT);	    
	KdPrint(("MWDM_DRIVER: DispatchWrite | Done | Choice: %d | Callcount: %d\n",choice,dispatch_write_callcount));
	return STATUS_SUCCESS;
	}

	/*RtlInitAnsiString(&RxChoice, Irp->AssociatedIrp.SystemBuffer);
	RtlAnsiStringToUnicodeString(&U_RxChoiceDrv,&RxChoice,TRUE);
	choice = (char)U_RxChoiceDrv.Buffer;
	KdPrint(("Recieved Choice: %ws | Choice:%d\n", U_RxChoiceDrv.Buffer, choice));*/
	
	if(choice==1 && dispatch_write_callcount ==1)
	{
		//only choice gets registered in the first call of write, at next call this routine works
		KdPrint (("User Entered 1 | Starting Task 1\n"));
		KdPrint(("UserString: %s\n", Irp->AssociatedIrp.SystemBuffer));
		RtlCopyMemory(&looptext, Irp->AssociatedIrp.SystemBuffer,100);
		KdPrint(("LoopText: %s\n", looptext));
		dispatch_write_callcount=0;

	}
	else if(choice==2 && dispatch_write_callcount ==1)
	{
		KdPrint(("User Entered 2 | Starting Task 2"));
		KeInitializeTimer(&timer); /* pointer to timer object */
		KeInitializeDpc(&dpc, /* pointer to dpc	object */TimerDpc, /* pointer to timer dpc routine */&p_DVCEXT); /* context (device extension) */
		//KeInitializeSpinLock(&dev_ext_ptr->lock); /* pointer to spin lock */
		(void) KeSetTimerEx(&timer, /* pointer to timer object */	DueTime, /* due time, for one-shot only */
		timer_period, /* period in	milliseconds */	&dpc); /* pointer to dpc object */

		status = PsCreateSystemThread(&tmrthreadhandle, GENERIC_READ | GENERIC_WRITE, NULL, NULL, NULL, waitontimer, NULL);
		
		KdPrint(("Done with task 2, | Final TimerCount = %d\n",timercount));
		dispatch_write_callcount=0;
	}
	else if (choice==3 && dispatch_write_callcount ==1)
	{
		KdPrint (("User Entered 3 | Starting Task 3"));
		dispatch_write_callcount=0;
	}
	else if (choice==4 && dispatch_write_callcount ==1)
	{
		KdPrint (("User Entered 4 | Starting Task 4"));
		dispatch_write_callcount=0;
	}
	else if (choice==5 && dispatch_write_callcount ==1)
	{
		KdPrint (("User Entered 5 | Starting Task 5"));
		dispatch_write_callcount=0; 
	}
	else {
		KdPrint (("Could not determine what User entered | Wrong choice entered! | Choice: %d | Callcount: %d\n",choice,dispatch_write_callcount));
		dispatch_write_callcount=0;
	}
	Irp->IoStatus.Status=STATUS_SUCCESS;
	Irp->IoStatus.Information=0;
	IoCompleteRequest(Irp,IO_NO_INCREMENT);	    
	KdPrint(("MWDM_DRIVER: DispatchWrite | Done | Choice: %d | Callcount: %d\n",choice,dispatch_write_callcount));
	return STATUS_SUCCESS;
}
Beispiel #3
0
NTSTATUS CMiniportWaveRTStream::SetState
(
    _In_    KSSTATE State_
)
{
    PAGED_CODE();

    NTSTATUS        ntStatus        = STATUS_SUCCESS;
    PADAPTERCOMMON  pAdapterComm    = m_pMiniport->GetAdapterCommObj();

    // Spew an event for a pin state change request from portcls
    //Event type: eMINIPORT_PIN_STATE
    //Parameter 1: Current linear buffer position	
    //Parameter 2: Current WaveRtBufferWritePosition	
    //Parameter 3: Pin State 0->KS_STOP, 1->KS_ACQUIRE, 2->KS_PAUSE, 3->KS_RUN 
    //Parameter 4:0
    pAdapterComm->WriteEtwEvent(eMINIPORT_PIN_STATE, 
                                100, // replace with the correct "Current linear buffer position"	
                                m_ulCurrentWritePosition, // replace with the previous WaveRtBufferWritePosition that the drive received	
                                State_, // repalce with the correct "Data length completed"
                                0);  // always zero

    switch (State_)
    {
        case KSSTATE_STOP:
            // Reset DMA
            m_ullPlayPosition = 0;
            m_ullWritePosition = 0;
            m_ullLinearPosition = 0;
            
            // Wait until all work items are completed.
            if (!m_bCapture && !g_DoNotCreateDataFiles)
            {
                m_SaveData.WaitAllWorkItems();
            }

#ifdef SYSVAD_BTH_BYPASS
            if (m_ScoOpen)
            {
                PBTHHFPDEVICECOMMON bthHfpDevice;
                
                ASSERT(m_pMiniport->IsBthHfpDevice());
                bthHfpDevice = m_pMiniport->GetBthHfpDevice(); // weak ref.
                ASSERT(bthHfpDevice != NULL);

                //
                // Close the SCO connection.
                //
                ntStatus = bthHfpDevice->StreamClose();
                if (!NT_SUCCESS(ntStatus))
                {
                    DPF(D_ERROR, ("SetState: KSSTATE_STOP, StreamClose failed, 0x%x", ntStatus));
                }
                
                m_ScoOpen = FALSE;
            }
#endif // SYSVAD_BTH_BYPASS
            break;

        case KSSTATE_ACQUIRE:
#ifdef SYSVAD_BTH_BYPASS
            if (m_pMiniport->IsBthHfpDevice())
            {
                if(m_ScoOpen == FALSE)
                {
                    PBTHHFPDEVICECOMMON bthHfpDevice;

                    bthHfpDevice = m_pMiniport->GetBthHfpDevice(); // weak ref.
                    ASSERT(bthHfpDevice != NULL);

                    //
                    // Open the SCO connection.
                    //
                    ntStatus = bthHfpDevice->StreamOpen();
                    IF_FAILED_ACTION_JUMP(
                        ntStatus,
                        DPF(D_ERROR, ("SetState: KSSTATE_ACQUIRE, StreamOpen failed, 0x%x", ntStatus)),
                        Done);

                    m_ScoOpen = TRUE;
                }
            }
#endif // SYSVAD_BTH_BYPASS
            break;

        case KSSTATE_PAUSE:
            ULONGLONG ullPositionTemp;
            
            // Pause DMA
            if (m_ulNotificationIntervalMs > 0)
            {
                KeCancelTimer(m_pNotificationTimer);
                KeFlushQueuedDpcs(); 
            }

            // This call updates the linear buffer position.
            GetLinearBufferPosition(&ullPositionTemp, NULL);
            break;

        case KSSTATE_RUN:
            // Start DMA
            LARGE_INTEGER ullPerfCounterTemp;
            ullPerfCounterTemp = KeQueryPerformanceCounter(&m_ullPerformanceCounterFrequency);
            m_ullDmaTimeStamp = KSCONVERT_PERFORMANCE_TIME(m_ullPerformanceCounterFrequency.QuadPart, ullPerfCounterTemp);
            m_hnsElapsedTimeCarryForward  = 0;

            if (m_ulNotificationIntervalMs > 0)
            {
                LARGE_INTEGER   delay;
                delay.HighPart  = 0;
                delay.LowPart   = m_ulNotificationIntervalMs * HNSTIME_PER_MILLISECOND * -1;

                KeSetTimerEx
                (
                    m_pNotificationTimer,
                    delay,
                    m_ulNotificationIntervalMs,
                    m_pNotificationDpc
                );
            }

            break;
    }

    m_KsState = State_;

#ifdef SYSVAD_BTH_BYPASS
Done:
#endif  // SYSVAD_BTH_BYPASS
    return ntStatus;
}
Beispiel #4
0
static NTSTATUS IdleNotificationRequestComplete(IN PDEVICE_OBJECT DeviceObject,
												IN PIRP Irp, IN PTDeviceExtension DeviceExtension)
{
	NTSTATUS                ntStatus;
	POWER_STATE             powerState;
	KIRQL                   oldIrql;
	LARGE_INTEGER           dueTime;
	PIRP                    idleIrp;
	PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;

	BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationRequestCompete - begins\n"));
	idleIrp = NULL;
	ntStatus = Irp->IoStatus.Status;
	if(!NT_SUCCESS(ntStatus) && ntStatus != STATUS_NOT_SUPPORTED) 
	{
		BulkUsb_DbgPrint(1, ("file bulkdev: Idle irp completes with error::"));
		switch(ntStatus) 
		{
		case STATUS_INVALID_DEVICE_REQUEST:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_INVALID_DEVICE_REQUEST\n"));
			break;

		case STATUS_CANCELLED:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_CANCELLED\n"));
			break;

		case STATUS_POWER_STATE_INVALID:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_POWER_STATE_INVALID\n"));
			goto IdleNotificationRequestComplete_Exit;

		case STATUS_DEVICE_BUSY:
			BulkUsb_DbgPrint(1, ("file bulkdev: STATUS_DEVICE_BUSY\n"));
			break;

		default:
			BulkUsb_DbgPrint(1, ("file bulkdev: default: status = %X\n", ntStatus));
			break;
		}

		if(PowerDeviceD0 != DeviceExtension->DevPower) 
		{
			BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationRequestComplete::"));
			BulkUsb_IoIncrement(DeviceExtension);
			powerState.DeviceState = PowerDeviceD0;
			ntStatus = PoRequestPowerIrp(
						DeviceExtension->PhysicalDeviceObject, 
						IRP_MN_SET_POWER, 
						powerState, 
						(PREQUEST_POWER_COMPLETE) PoIrpAsyncCompletionFunc, 
						DeviceExtension, 
						NULL);

			if(!NT_SUCCESS(ntStatus)) 
			{
				BulkUsb_DbgPrint(1, ("file bulkdev: PoRequestPowerIrp failed\n"));
			}
		}
	}

IdleNotificationRequestComplete_Exit:

	KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);
	idleCallbackInfo = DeviceExtension->IdleCallbackInfo;
	DeviceExtension->IdleCallbackInfo = NULL;
	idleIrp = (PIRP) InterlockedExchangePointer(&DeviceExtension->PendingIdleIrp, NULL);
	InterlockedExchange(&DeviceExtension->IdleReqPend, 0);
	KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);
	if(idleCallbackInfo) 
	{
		ExFreePool(idleCallbackInfo);
	}
	if(idleIrp) 
	{
		BulkUsb_DbgPrint(3, ("file bulkdev: completion routine has a valid irp and frees it\n"));
		IoFreeIrp(Irp);
		KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
	}
	else 
	{
		if(0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount)) 
		{
			BulkUsb_DbgPrint(3, ("file bulkdev: completion routine frees the irp\n"));
			IoFreeIrp(Irp);
			KeSetEvent(&DeviceExtension->NoIdleReqPendEvent, IO_NO_INCREMENT, FALSE);
		}
	}
	if(DeviceExtension->SSEnable) 
	{
		BulkUsb_DbgPrint(3, ("file bulkdev: Set the timer to fire DPCs\n"));
		dueTime.QuadPart = -10000 * IDLE_INTERVAL;               // 5000 ms
		KeSetTimerEx(&DeviceExtension->Timer, 
			dueTime,
			IDLE_INTERVAL,                              // 5000 ms
			&DeviceExtension->DeferredProcCall);

		BulkUsb_DbgPrint(3, ("file bulkdev: IdleNotificationRequestCompete - ends\n"));
	}
	return STATUS_MORE_PROCESSING_REQUIRED;
}
Beispiel #5
0
NTSTATUS
NtSetTimer (
    IN HANDLE TimerHandle,
    IN PLARGE_INTEGER DueTime,
    IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL,
    IN PVOID TimerContext OPTIONAL,
    IN BOOLEAN WakeTimer,
    IN LONG Period OPTIONAL,
    OUT PBOOLEAN PreviousState OPTIONAL
    )

/*++

Routine Description:

    This function sets an timer object to a Not-Signaled state and sets the timer
    to expire at the specified time.

Arguments:

    TimerHandle - Supplies a handle to an timer object.

    DueTime - Supplies a pointer to absolute of relative time at which the
        timer is to expire.

    TimerApcRoutine - Supplies an optional pointer to a function which is to
        be executed when the timer expires. If this parameter is not specified,
        then the TimerContext parameter is ignored.

    TimerContext - Supplies an optional pointer to an arbitrary data structure
        that will be passed to the function specified by the TimerApcRoutine
        parameter. This parameter is ignored if the TimerApcRoutine parameter
        is not specified.

    WakeTimer - Supplies a boolean value that specifies whether the timer
        wakes computer operation if sleeping

    Period - Supplies an optional repetitive period for the timer.

    PreviousState - Supplies an optional pointer to a variable that will
        receive the previous state of the timer object.

Return Value:

    TBS

--*/

{

    BOOLEAN AssociatedApc;
    BOOLEAN Dereference;
    PETHREAD ExThread;
    PETIMER ExTimer;
    LARGE_INTEGER ExpirationTime;
    KIRQL OldIrql1;
    KPROCESSOR_MODE PreviousMode;
    BOOLEAN State;
    NTSTATUS Status;

    //
    // Establish an exception handler, probe the due time and previous state
    // address if specified, reference the timer object, and set the timer
    // object. If the probe fails, then return the exception code as the
    // service status. Otherwise return the status value returned by the
    // reference object by handle routine.
    //

    try {

        //
        // Get previous processor mode and probe previous state address
        // if necessary.
        //

        PreviousMode = KeGetPreviousMode();
        if (PreviousMode != KernelMode) {
            if (ARGUMENT_PRESENT(PreviousState)) {
                ProbeForWriteBoolean(PreviousState);
            }

            ProbeForRead(DueTime, sizeof(LARGE_INTEGER), sizeof(ULONG));
        }

        //
        // Check argument validity.
        //

        if (Period < 0) {
            return STATUS_INVALID_PARAMETER_6;
        }

        //
        // Capture the expiration time.
        //

        ExpirationTime = *DueTime;

        //
        // Reference timer object by handle.
        //

        Status = ObReferenceObjectByHandle(TimerHandle,
                                           TIMER_MODIFY_STATE,
                                           ExTimerObjectType,
                                           PreviousMode,
                                           (PVOID *)&ExTimer,
                                           NULL);

        //
        // If this WakeTimer flag is set, return the appropiate informational
        // success status code.
        //

        if (NT_SUCCESS(Status) && WakeTimer && !PoWakeTimerSupported()) {
            Status = STATUS_TIMER_RESUME_IGNORED;
        }

        //
        // If the reference was successful, then cancel the timer object, set
        // the timer object, dereference time object, and write the previous
        // state value if specified. If the write of the previous state value
        // fails, then do not report an error. When the caller attempts to
        // access the previous state value, an access violation will occur.
        //

        if (NT_SUCCESS(Status)) {
            ExAcquireSpinLock(&ExTimer->Lock, &OldIrql1);

            if (ExTimer->ApcAssociated) {
                ExThread = CONTAINING_RECORD(ExTimer->TimerApc.Thread, ETHREAD, Tcb);
                ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);
                RemoveEntryList(&ExTimer->ActiveTimerListEntry);
                ExTimer->ApcAssociated = FALSE;
                ExReleaseSpinLockFromDpcLevel(&ExThread->ActiveTimerListLock);
                KeCancelTimer(&ExTimer->KeTimer);
                KeRemoveQueueDpc(&ExTimer->TimerDpc);
                KeRemoveQueueApc(&ExTimer->TimerApc);
                Dereference = TRUE;

            } else {
                KeCancelTimer(&ExTimer->KeTimer);
                Dereference = FALSE;
            }

            //
            // Read the current state of the timer.
            //

            State = KeReadStateTimer(&ExTimer->KeTimer);

            //
            // If this is a wake timer ensure it's on the wake timer list
            //

            ExTimer->WakeTimer = WakeTimer;
            ExAcquireSpinLockAtDpcLevel(&ExpWakeTimerListLock);
            if (WakeTimer) {
                if (!ExTimer->WakeTimerListEntry.Flink) {
                    InsertTailList(&ExpWakeTimerList, &ExTimer->WakeTimerListEntry);
                }
            } else {
                if (ExTimer->WakeTimerListEntry.Flink) {
                    RemoveEntryList(&ExTimer->WakeTimerListEntry);
                    ExTimer->WakeTimerListEntry.Flink = NULL;
                }
            }
            ExReleaseSpinLockFromDpcLevel(&ExpWakeTimerListLock);

            //
            // If an APC routine is specified, then initialize the APC, acquire the
            // thread's active time list lock, insert the timer in the thread's
            // active timer list, set the timer with an associated DPC, and set the
            // associated APC flag TRUE. Otherwise set the timer without an associated
            // DPC, and set the associated APC flag FALSE.
            //

            ExTimer->Period = Period;
            if (ARGUMENT_PRESENT(TimerApcRoutine)) {
                ExThread = PsGetCurrentThread();
                KeInitializeApc(&ExTimer->TimerApc,
                                &ExThread->Tcb,
                                CurrentApcEnvironment,
                                ExpTimerApcRoutine,
                                (PKRUNDOWN_ROUTINE)NULL,
                                (PKNORMAL_ROUTINE)TimerApcRoutine,
                                PreviousMode,
                                TimerContext);

                ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);
                InsertTailList(&ExThread->ActiveTimerListHead,
                               &ExTimer->ActiveTimerListEntry);

                ExTimer->ApcAssociated = TRUE;
                ExReleaseSpinLockFromDpcLevel(&ExThread->ActiveTimerListLock);
                KeSetTimerEx(&ExTimer->KeTimer,
                             ExpirationTime,
                             Period,
                             &ExTimer->TimerDpc);

                AssociatedApc = TRUE;

            } else {
                KeSetTimerEx(&ExTimer->KeTimer,
                             ExpirationTime,
                             Period,
                             NULL);

                AssociatedApc = FALSE;
            }

            ExReleaseSpinLock(&ExTimer->Lock, OldIrql1);

            //
            // Dereference the object as appropriate.
            //

            if (Dereference) {
                ObDereferenceObject((PVOID)ExTimer);
            }

            if (AssociatedApc == FALSE) {
                ObDereferenceObject((PVOID)ExTimer);
            }

            if (ARGUMENT_PRESENT(PreviousState)) {
                try {
                    *PreviousState = State;

                } except(ExSystemExceptionFilter()) {
                }
            }
        }

    //
    // If an exception occurs during the probe of the current state address,
    // then always handle the exception and return the exception code as the
    // status value.
    //

    } except(ExSystemExceptionFilter()) {
        return GetExceptionCode();
    }

    //
    // Return service status.
    //

    return Status;
}
Beispiel #6
0
VOID IOThread(IN PVOID Context)
{
	KIRQL			currentIrql, oldIrql;
	LARGE_INTEGER 	timeout, maxTimeout;
	NTSTATUS		status = STATUS_SUCCESS;
			
	PRING_BUFFER	pRb;
	const PCHAR 	pMsg = "messahe1";
	ULONG			size = 8;
	INT_PTR			state;
	
	PKTIMER			pTimer;
	LONG 			interval;
	
	PVOID 			pObjects[3]; // wait for
	
	KeSetEvent(&StartEvent, 0, FALSE);
	
	timeout.QuadPart = -6000 * 10000; // 10 sec
	interval = 20000; // 5 sec
	maxTimeout.QuadPart = -20000 * 10000;
	
	InitRingBuffer(&pRb);
	
	state = (INT_PTR) ExAllocatePool(NonPagedPool, sizeof(INT));	
	
	
	// Set timer for periodic flush
	pTimer=(PKTIMER) ExAllocatePool(NonPagedPool, sizeof(KTIMER));
	KeInitializeTimerEx(pTimer, SynchronizationTimer);
	KeSetTimerEx(pTimer, timeout, interval, NULL);
	
	
	pObjects[0] = pTimer;				// periodic timer
	pObjects[1] = &StopEvent;			// stop flush loop
	pObjects[2] = &FlushEvent;			// do flush, buffer is full
	
	
	// Flush loop
	while (status != STATUS_WAIT_1) {
	
		status = KeWaitForMultipleObjects(
				3,
				pObjects,
				WaitAny,
				Executive,
				KernelMode,
				FALSE,
				&maxTimeout,
				NULL);
				
				
		if (status == STATUS_WAIT_0) {
			DbgPrint("Timer flush\n");
		} else if (status == STATUS_WAIT_2) {
			DbgPrint("RB flush\n");
		} else if (status == STATUS_TIMEOUT) {
			DbgPrint("Timeout delay\n");
			break;
		}
		
		//Klog("Msg from klog %d\s", 123);
		KloggerWriteToFile();
		//DbgPrint("State: %d\n", state);
		
	}
	
	DbgPrint("klogger.sys: IOThread get stop signal\n");
	
	
	// Free resources
	KeCancelTimer(pTimer);
	ExFreePool(pTimer);
	FreeRingBuffer(pRb);
	
	PsTerminateSystemThread(status);
	
}
/*	Main entry point into the driver, is called when the driver is loaded */
NTSTATUS DriverEntry(
	IN PDRIVER_OBJECT DriverObject, 
	IN PUNICODE_STRING RegistryPath
	)
{
	NTSTATUS status;
	OBJECT_ATTRIBUTES objectAttributes;
	PSECURITY_DESCRIPTOR pSecurityDescriptor;
	UNICODE_STRING fileMonitorPortName;
	LARGE_INTEGER fileEventsTimeout;
	busy = FALSE;
	fileManager.bReady = FALSE;
	fileManager.bCollectDeletedFiles = FALSE;
	KeInitializeSpinLock(&fileManager.lQueuedFileEventsSpinLock);
	InitializeListHead(&fileManager.lQueuedFileEvents);
	fileManager.pDriverObject = DriverObject;
	//fileManager.logDirectory.Buffer = NULL;

	/* Register driver with the filter manager */
	status = FltRegisterFilter(DriverObject, &FilterRegistration, &fileManager.pFilter);

	if (!NT_SUCCESS(status))
	{
		DbgPrint("CaptureFileMonitor: ERROR FltRegisterFilter - %08x\n", status); 
		return status;
	}

	status  = FltBuildDefaultSecurityDescriptor( &pSecurityDescriptor, FLT_PORT_ALL_ACCESS );

	if (!NT_SUCCESS(status))
	{
		DbgPrint("CaptureFileMonitor: ERROR FltBuildDefaultSecurityDescriptor - %08x\n", status);
		return status;
	}

	RtlInitUnicodeString( &fileMonitorPortName, CAPTURE_FILEMON_PORT_NAME );
	InitializeObjectAttributes( &objectAttributes,
								&fileMonitorPortName,
								OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
								NULL,
								pSecurityDescriptor);

	/* Create the communications port to communicate with the user space process (pipe) */
	status = FltCreateCommunicationPort( fileManager.pFilter,
                                             &fileManager.pServerPort,
                                             &objectAttributes,
                                             NULL,
                                             ConnectCallback,
                                             DisconnectCallback,
                                             MessageCallback,
                                             1 );

	FltFreeSecurityDescriptor(pSecurityDescriptor);

	/* Start the filtering */
	if(NT_SUCCESS(status))
	{
		status = FltStartFiltering(fileManager.pFilter);
		if(!NT_SUCCESS(status))
		{
			DbgPrint("CaptureFileMonitor: ERROR FltStartFiltering - %08x\n", status);
		}
	} else {
		DbgPrint("CaptureFileMonitor: ERROR FltCreateCommunicationPort - %08x\n", status);
	}

	/* If there was a problem during initialisation of the filter then uninstall everything */
	if(!NT_SUCCESS(status))
	{
		if (fileManager.pServerPort != NULL)
			FltCloseCommunicationPort(fileManager.pServerPort);
		if (fileManager.pFilter != NULL)
			FltUnregisterFilter(fileManager.pFilter);
		return status;
	}

	UpdateLastContactTime();

	/* Create a DPC routine so that it can be called periodically */
	KeInitializeDpc(&fileManager.connectionCheckerFunction, 
		(PKDEFERRED_ROUTINE)ConnectionChecker, &fileManager);
	KeInitializeTimer(&fileManager.connectionCheckerTimer);
	fileEventsTimeout.QuadPart = 0;

	/* Set the ConnectionChecker routine to be called every so often */
	KeSetTimerEx(&fileManager.connectionCheckerTimer, 
		fileEventsTimeout, 
		(USERSPACE_CONNECTION_TIMEOUT+(USERSPACE_CONNECTION_TIMEOUT/2))*1000, 
		&fileManager.connectionCheckerFunction);

	fileManager.bReady = TRUE;
	fileManager.logDirectory.Length = 0;
	fileManager.logDirectory.Buffer = NULL;
	DbgPrint("CaptureFileMonitor: Successfully Loaded\n");

	return STATUS_SUCCESS;
}
Beispiel #8
0
NTSTATUS NTAPI
TiDispatch(
  PDEVICE_OBJECT DeviceObject,
  PIRP Irp)
/*
 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
 * ARGUMENTS:
 *     DeviceObject = Pointer to a device object for this driver
 *     Irp          = Pointer to a I/O request packet
 * RETURNS:
 *     Status of the operation
 */
{


  NTSTATUS Status;
  PIO_STACK_LOCATION IrpSp;

  IrpSp  = IoGetCurrentIrpStackLocation(Irp);

  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Called. IRP is at (0x%X).\n", Irp));
  DbgPrint("TiDispatch Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp);
  Irp->IoStatus.Information = 0;

#if 0
  Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
  if (NT_SUCCESS(Status)) {
    TiDispatchInternal(DeviceObject, Irp);
    Status = STATUS_PENDING;
  } else {
#else
  if (TRUE) {
#endif
    /* See if this request is TCP/IP specific */
    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_TCP_QUERY_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n"));
      Status = DispTdiQueryInformationEx(Irp, IrpSp);
      break;

    case IOCTL_TCP_SET_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n"));
      Status = DispTdiSetInformationEx(Irp, IrpSp);
      break;

    case IOCTL_SET_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n"));
      Status = DispTdiSetIPAddress(Irp, IrpSp);
      break;

    case IOCTL_DELETE_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n"));
      Status = DispTdiDeleteIPAddress(Irp, IrpSp);
      break;

    default:
      TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
          IrpSp->Parameters.DeviceIoControl.IoControlCode));
      Status = STATUS_NOT_IMPLEMENTED;
      break;
    }
  }

  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Leaving. Status = (0x%X).\n", Status));

  return IRPFinish( Irp, Status );


}
NTSTATUS
DriverEntry(
		  PDRIVER_OBJECT DriverObject,
		  PUNICODE_STRING RegistryPath)
{
  NTSTATUS Status;
  UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
  UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
  UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
  UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
  UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
  NDIS_STATUS NdisStatus;
  LARGE_INTEGER DueTime;
  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] \n"));
  
  //_asm int 3;

  KdPrint(("driver entery..................\n"));

  /* TdiInitialize() ? */

  /* FIXME: Create symbolic links in Win32 namespace */

  /* Initialize our periodic timer and its associated DPC object. When the
     timer expires, the IPTimeout deferred procedure call (DPC) is queued */
  KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
  KeInitializeTimer(&IPTimer);
	 
  /* Create IP device object */
  Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  ChewInit( IPDeviceObject );
	 

  /* Create RawIP device object */
  Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create UDP device object */
  Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create TCP device object */
  Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }


  /* Setup network layer and transport layer entities */
  KeInitializeSpinLock(&EntityListLock);
  EntityList = ExAllocatePoolWithTag(NonPagedPool,
                                     sizeof(TDIEntityID) * MAX_TDI_ENTITIES,
                                     TDI_ENTITY_TAG );

  if (!EntityList) {
    TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  EntityCount = 0;
  EntityMax   = MAX_TDI_ENTITIES;

  /* Allocate NDIS packet descriptors */
  NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT));
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Allocate NDIS buffer descriptors */
  NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000);
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Initialize address file list and protecting spin lock */
  InitializeListHead(&AddressFileListHead);
  KeInitializeSpinLock(&AddressFileListLock);

  /* Initialize connection endpoint list and protecting spin lock */
  InitializeListHead(&ConnectionEndpointListHead);
  KeInitializeSpinLock(&ConnectionEndpointListLock);

  /* Initialize interface list and protecting spin lock */
  InitializeListHead(&InterfaceListHead);
  KeInitializeSpinLock(&InterfaceListLock);



  /* Initialize network level protocol subsystem */
  IPStartup(RegistryPath);

  /* Initialize transport level protocol subsystems */
  Status = RawIPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = UDPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = TCPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = ICMPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  /* Use direct I/O */
  IPDeviceObject->Flags    |= DO_DIRECT_IO;
  RawIPDeviceObject->Flags |= DO_DIRECT_IO;
  UDPDeviceObject->Flags   |= DO_DIRECT_IO;
  TCPDeviceObject->Flags   |= DO_DIRECT_IO;

  /* Initialize the driver object with this driver's entry points */
  DriverObject->MajorFunction[IRP_MJ_CREATE]  = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_CLOSE]   = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;

  DriverObject->DriverUnload = TiUnload;

  /* Open loopback adapter */
  Status = LoopRegisterAdapter(NULL, NULL);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Register protocol with NDIS */
  /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
  Status = LANRegisterProtocol(&strNdisDeviceName);
  if (!NT_SUCCESS(Status)) {
	  TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
	  TiWriteErrorLog(
      DriverObject,
      EVENT_TRANSPORT_REGISTER_FAILED,
      TI_ERROR_DRIVERENTRY,
      Status,
      NULL,
      0,
      NULL);
      TiUnload(DriverObject);
      return Status;
  }

  /* Start the periodic timer with an initial and periodic
     relative expiration time of IP_TIMEOUT milliseconds */
  DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
  KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));


  return STATUS_SUCCESS;

}
Beispiel #9
0
NTSTATUS
IdleNotificationRequestComplete(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp,
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:

  Completion routine for idle notification irp

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
{
    NTSTATUS                ntStatus;
    POWER_STATE             powerState;
    KIRQL                   oldIrql;
    LARGE_INTEGER           dueTime;
    PIRP                    idleIrp;
    PUSB_IDLE_CALLBACK_INFO idleCallbackInfo;

    BulkUsb_DbgPrint(3, ("IdleNotificationRequestCompete - begins\n"));

    idleIrp = NULL;

    //
    // check the Irp status
    //

    ntStatus = Irp->IoStatus.Status;

    if(!NT_SUCCESS(ntStatus) && ntStatus != STATUS_NOT_SUPPORTED) {

        BulkUsb_DbgPrint(1, ("Idle irp completes with error::"));

        switch(ntStatus) {
            
        case STATUS_INVALID_DEVICE_REQUEST:

            BulkUsb_DbgPrint(1, ("STATUS_INVALID_DEVICE_REQUEST\n"));

            break;

        case STATUS_CANCELLED:

            BulkUsb_DbgPrint(1, ("STATUS_CANCELLED\n"));

            break;

        case STATUS_POWER_STATE_INVALID:

            BulkUsb_DbgPrint(1, ("STATUS_POWER_STATE_INVALID\n"));

            goto IdleNotificationRequestComplete_Exit;

        case STATUS_DEVICE_BUSY:

            BulkUsb_DbgPrint(1, ("STATUS_DEVICE_BUSY\n"));

            break;

        default:

            BulkUsb_DbgPrint(1, ("default: status = %X\n", ntStatus));

            break;
        }

        //
        // if in error, issue a SetD0
        //

        BulkUsb_DbgPrint(3, ("IdleNotificationRequestComplete::"));
        BulkUsb_IoIncrement(DeviceExtension);

        powerState.DeviceState = PowerDeviceD0;

        ntStatus = PoRequestPowerIrp(
                          DeviceExtension->PhysicalDeviceObject, 
                          IRP_MN_SET_POWER, 
                          powerState, 
                          (PREQUEST_POWER_COMPLETE) PoIrpAsyncCompletionFunc, 
                          DeviceExtension, 
                          NULL);

        if(!NT_SUCCESS(ntStatus)) {
    
            BulkUsb_DbgPrint(1, ("PoRequestPowerIrp failed\n"));
        }

    }

IdleNotificationRequestComplete_Exit:

    KeAcquireSpinLock(&DeviceExtension->IdleReqStateLock, &oldIrql);

    idleCallbackInfo = DeviceExtension->IdleCallbackInfo;

    DeviceExtension->IdleCallbackInfo = NULL;

    idleIrp = (PIRP) InterlockedExchangePointer(
                                        &DeviceExtension->PendingIdleIrp,
                                        NULL);

    InterlockedExchange(&DeviceExtension->IdleReqPend, 0);

    KeReleaseSpinLock(&DeviceExtension->IdleReqStateLock, oldIrql);

    if(idleCallbackInfo) {

        ExFreePool(idleCallbackInfo);
    }

    //
    // since the irp was created using IoAllocateIrp, 
    // the Irp needs to be freed using IoFreeIrp.
    // Also return STATUS_MORE_PROCESSING_REQUIRED so that 
    // the kernel does not reference this in the near future.
    //

    if(idleIrp) {

        BulkUsb_DbgPrint(3, ("completion routine has a valid irp and frees it\n"));
        IoFreeIrp(Irp);
        KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
                   IO_NO_INCREMENT,
                   FALSE);
    }
    else {

        //
        // The CancelSelectiveSuspend routine has grabbed the Irp from the device 
        // extension. Now the last one to decrement the FreeIdleIrpCount should
        // free the irp.
        //
        if(0 == InterlockedDecrement(&DeviceExtension->FreeIdleIrpCount)) {

            BulkUsb_DbgPrint(3, ("completion routine frees the irp\n"));
            IoFreeIrp(Irp);

            KeSetEvent(&DeviceExtension->NoIdleReqPendEvent,
                       IO_NO_INCREMENT,
                       FALSE);
        }
    }

    if(DeviceExtension->SSEnable) {

        BulkUsb_DbgPrint(3, ("Set the timer to fire DPCs\n"));

        dueTime.QuadPart = -10000 * IDLE_INTERVAL;               // 5000 ms

        KeSetTimerEx(&DeviceExtension->Timer, 
                     dueTime,
                     IDLE_INTERVAL,                              // 5000 ms
                     &DeviceExtension->DeferredProcCall);

        BulkUsb_DbgPrint(3, ("IdleNotificationRequestCompete - ends\n"));
    }

    return STATUS_MORE_PROCESSING_REQUIRED;
}
Beispiel #10
0
BOOLEAN
INIT_FUNCTION
NTAPI
IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
    LARGE_INTEGER ExpireTime;
    NTSTATUS Status;
    CHAR Buffer[256];
    ANSI_STRING NtBootPath, RootString;

    /* Initialize empty NT Boot Path */
    RtlInitEmptyAnsiString(&NtBootPath, Buffer, sizeof(Buffer));

    /* Initialize the lookaside lists */
    IopInitLookasideLists();

    /* Initialize all locks and lists */
    ExInitializeResource(&IopDatabaseResource);
    ExInitializeResource(&IopSecurityResource);
    KeInitializeGuardedMutex(&PnpNotifyListLock);
    InitializeListHead(&IopDiskFileSystemQueueHead);
    InitializeListHead(&IopCdRomFileSystemQueueHead);
    InitializeListHead(&IopTapeFileSystemQueueHead);
    InitializeListHead(&IopNetworkFileSystemQueueHead);
    InitializeListHead(&DriverBootReinitListHead);
    InitializeListHead(&DriverReinitListHead);
    InitializeListHead(&PnpNotifyListHead);
    InitializeListHead(&ShutdownListHead);
    InitializeListHead(&LastChanceShutdownListHead);
    InitializeListHead(&IopFsNotifyChangeQueueHead);
    InitializeListHead(&IopErrorLogListHead);
    KeInitializeSpinLock(&IoStatisticsLock);
    KeInitializeSpinLock(&DriverReinitListLock);
    KeInitializeSpinLock(&DriverBootReinitListLock);
    KeInitializeSpinLock(&ShutdownListLock);
    KeInitializeSpinLock(&IopLogListLock);

    /* Initialize Timer List Lock */
    KeInitializeSpinLock(&IopTimerLock);

    /* Initialize Timer List */
    InitializeListHead(&IopTimerQueueHead);

    /* Initialize the DPC/Timer which will call the other Timer Routines */
    ExpireTime.QuadPart = -10000000;
    KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL);
    KeInitializeTimerEx(&IopTimer, SynchronizationTimer);
    KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc);

    /* Create Object Types */
    if (!IopCreateObjectTypes())
    {
        DPRINT1("IopCreateObjectTypes failed!\n");
        return FALSE;
    }

    /* Create Object Directories */
    if (!IopCreateRootDirectories())
    {
        DPRINT1("IopCreateRootDirectories failed!\n");
        return FALSE;
    }

    /* Initialize PnP manager */
    IopInitializePlugPlayServices();

    /* Initialize HAL Root Bus Driver */
    HalInitPnpDriver();

    /* Make loader block available for the whole kernel */
    IopLoaderBlock = LoaderBlock;

    /* Load boot start drivers */
    IopInitializeBootDrivers();

    /* Call back drivers that asked for */
    IopReinitializeBootDrivers();

    /* Check if this was a ramdisk boot */
    if (!_strnicmp(LoaderBlock->ArcBootDeviceName, "ramdisk(0)", 10))
    {
        /* Initialize the ramdisk driver */
        IopStartRamdisk(LoaderBlock);
    }

    /* No one should need loader block any longer */
    IopLoaderBlock = NULL;

    /* Create ARC names for boot devices */
    Status = IopCreateArcNames(LoaderBlock);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("IopCreateArcNames failed: %lx\n", Status);
        return FALSE;
    }

    /* Mark the system boot partition */
    if (!IopMarkBootPartition(LoaderBlock))
    {
        DPRINT1("IopMarkBootPartition failed!\n");
        return FALSE;
    }

    /* Initialize PnP root relations */
    IopEnumerateDevice(IopRootDeviceNode->PhysicalDeviceObject);

#ifndef _WINKD_
    /* Read KDB Data */
    KdbInit();

    /* I/O is now setup for disk access, so phase 3 */
    KdInitSystem(3, LoaderBlock);
#endif

    /* Load services for devices found by PnP manager */
    IopInitializePnpServices(IopRootDeviceNode);

    /* Load system start drivers */
    IopInitializeSystemDrivers();
    PnpSystemInit = TRUE;

    /* Reinitialize drivers that requested it */
    IopReinitializeDrivers();

    /* Convert SystemRoot from ARC to NT path */
    Status = IopReassignSystemRoot(LoaderBlock, &NtBootPath);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("IopReassignSystemRoot failed: %lx\n", Status);
        return FALSE;
    }

    /* Set the ANSI_STRING for the root path */
    RootString.MaximumLength = NtSystemRoot.MaximumLength / sizeof(WCHAR);
    RootString.Length = 0;
    RootString.Buffer = ExAllocatePoolWithTag(PagedPool,
                                              RootString.MaximumLength,
                                              TAG_IO);

    /* Convert the path into the ANSI_STRING */
    Status = RtlUnicodeStringToAnsiString(&RootString, &NtSystemRoot, FALSE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("RtlUnicodeStringToAnsiString failed: %lx\n", Status);
        return FALSE;
    }

    /* Assign drive letters */
    IoAssignDriveLetters(LoaderBlock,
                         &NtBootPath,
                         (PUCHAR)RootString.Buffer,
                         &RootString);

    /* Update system root */
    Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &RootString, FALSE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("RtlAnsiStringToUnicodeString failed: %lx\n", Status);
        return FALSE;
    }

    /* Load the System DLL and its Entrypoints */
    Status = PsLocateSystemDll();
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("PsLocateSystemDll failed: %lx\n", Status);
        return FALSE;
    }

    /* Return success */
    return TRUE;
}
Beispiel #11
0
VOID
ScanThread(
		   IN PVOID Context
		   )
{
	PEventHandlerData EventBlock = static_cast<PEventHandlerData>( Context);
	LARGE_INTEGER   Timeout;
	NTSTATUS        WaitStatus, Status;
	PVOID           eventArray[2];
    KIRQL           OldIrql;
	CEncoderDevice* EncDevice = EventBlock->pDevice;

	eventArray[0] = &(EventBlock->InitEvent);
	eventArray[1] = &(EventBlock->ThreadEvent);

	Timeout.QuadPart = (-1) * EventBlock->IdleTimeout.QuadPart;
	KeSetTimerEx (&(EventBlock->timer), Timeout,NULL, &(EventBlock->DPCObject));
	do
	{
		WaitStatus = KeWaitForMultipleObjects( 2, 
			eventArray,
			WaitAny,
			Executive,
			KernelMode,
			FALSE, 
			NULL,
			NULL);
		if(WaitStatus == STATUS_TIMEOUT )
		{
			KeAcquireSpinLock(&(EventBlock->LockAccess), &OldIrql);
			EncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_None;
			KeReleaseSpinLock(&(EventBlock->LockAccess), OldIrql);
			KeSetEvent(&(EventBlock->TuneEvent), 0,FALSE);
			continue;
		}
		else if(WaitStatus == STATUS_WAIT_0 )
		{
			Status = GetStreamLocationFromFrequency(EncDevice, EventBlock->CurrentFrequency, &EncDevice->FileName);
			KeClearEvent((PKEVENT)eventArray[0]);
			if(Status == STATUS_SUCCESS)        
			{
				KeAcquireSpinLock(&(EventBlock->LockAccess), &OldIrql);
				EncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_Locked;
				KeReleaseSpinLock(&(EventBlock->LockAccess), OldIrql);
				if (KeCancelTimer(&(EventBlock->timer)) == FALSE)
				{
				    DbgPrint( "MY-Tuner ScanThread no timer active\n");
				}
				KeSetEvent(&(EventBlock->TuneEvent), 0,FALSE);  
			}
			else
			{
				KeAcquireSpinLock(&(EventBlock->LockAccess), &OldIrql);
				EventBlock->CurrentFrequency +=  EncDevice->ScanSensingRange;
				EncDevice->CurrentFrequency = EventBlock->CurrentFrequency;
				EncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_None;
				KeReleaseSpinLock(&(EventBlock->LockAccess), OldIrql);
				LARGE_INTEGER NextTime;
				NextTime.QuadPart = (-1) * EventBlock->IdleTimeout.QuadPart;
				KeSetTimerEx(&(EventBlock->timer), NextTime, NULL, &(EventBlock->DPCObject));
			}
			continue;
		}
		else if(WaitStatus == STATUS_WAIT_1)
		{
			KeAcquireSpinLock(&(EventBlock->LockAccess), &OldIrql);
			if (KeCancelTimer(&(EventBlock->timer)) == FALSE)
			{
			    DbgPrint( "MY-Tuner ScanThread no timer active at terminate\n");
			}
			EncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_None;
			DbgPrint( "MY-Tuner terminate ScanThread \n");
			KeReleaseSpinLock(&(EventBlock->LockAccess), OldIrql);

			KeClearEvent((PKEVENT)eventArray[1]);
			KeSetEvent(&(EventBlock->TuneEvent), 0,FALSE);  
			PsTerminateSystemThread(STATUS_SUCCESS);
		}
#pragma warning( push )
#pragma warning(disable:4127)
       }while(1);
#pragma warning (pop)
}
Beispiel #12
0
NTSTATUS 
AnlgTunerScanAddEvent(
					  PIRP pIrp,
					  PKSEVENTDATA EventData,
					  PKSEVENT_ENTRY pEventEntry
					  )
{
	KIRQL OldIrql;
	NTSTATUS ntStatus = STATUS_SUCCESS;
	PKSEVENT_TUNER_INITIATE_SCAN_S ScanRequest = reinterpret_cast<PKSEVENT_TUNER_INITIATE_SCAN_S>(EventData);
	PEventHandlerData EventBlock;

	ASSERT(pIrp);
	PKSFILTER pFilter = KsGetFilterFromIrp(pIrp);
	if (!pFilter)
	{
		ntStatus = STATUS_UNSUCCESSFUL;
		goto error;
	}

	PKSDEVICE pDevice = KsFilterGetDevice(pFilter);
	if (!pDevice)
	{
		ntStatus = STATUS_UNSUCCESSFUL;
		goto error;
	}
    if (g_bHardwareAssistedScanning == FALSE)
    {
        return STATUS_UNSUCCESSFUL; 
    }

	CEncoderDevice* pEncDevice = reinterpret_cast<CEncoderDevice *>(pDevice->Context);
	if (!pEncDevice )
	{
		ntStatus = STATUS_UNSUCCESSFUL;
		goto error;
	}

	DbgPrint("AnlgTunerScanAddEvent enter!begin frenquency is %d,end frenquency is %d\n",ScanRequest -> StartFrequency,ScanRequest -> EndFrequency);
	if(ScanRequest -> StartFrequency == ScanRequest -> EndFrequency )
	{
		if(pEncDevice->ScanInitialization)
		{
			ntStatus = STATUS_UNSUCCESSFUL;
			goto error;
		}
		// go ahead and tune to the frequency;
		ntStatus = InitializeEventing(pEncDevice);
		if (!NT_SUCCESS(ntStatus))
			goto error;
		EventBlock = EventHandler;

		ntStatus = GetStreamLocationFromFrequency(pEncDevice, ScanRequest -> StartFrequency, &pEncDevice->FileName);
		if(ntStatus != STATUS_SUCCESS)                // Found the frequency in the registry...so Just tune to it.
		{
			ULONG dwFreq = ( ScanRequest -> StartFrequency / (1000 * 1000) ); // fine tune algorithm ..
			dwFreq *= 1000000;

			ntStatus = GetStreamLocationFromFrequency(pEncDevice, dwFreq, &pEncDevice->FileName);
			if(ntStatus != STATUS_SUCCESS)
			{
				pEncDevice->CurrentFrequency = EventBlock->CurrentFrequency = ScanRequest -> StartFrequency;
				pEncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_None;
				KsGenerateEvent(pEventEntry);
				ntStatus = STATUS_SUCCESS;
				goto error;
			}
		}
		KeClearEvent(&(EventBlock->TuneEvent));
		EventBlock->IdleTimeout.QuadPart = pEncDevice->SettlingTime / 2;
		EventBlock->IdleTimeout.QuadPart = EventBlock->IdleTimeout.QuadPart * 1000 * 10; // in 100 nanasecond units

		KeWaitForSingleObject(&(EventBlock->TuneEvent),
			Executive,
			KernelMode,
			FALSE,
			&(EventBlock->IdleTimeout));     // in 100 nano second units

		pEncDevice->CurrentFrequency = EventBlock->CurrentFrequency = ScanRequest -> StartFrequency;
		pEncDevice->SetFrequency(pEncDevice->CurrentFrequency);

		pEncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_Locked;
		KsGenerateEvent(pEventEntry);
		ntStatus = STATUS_SUCCESS;
		goto error;

	}
	else
	{
		if (pEncDevice->pScanEvent)
		{
			// only one scan operation allowed on a tuner at a time
			if(EventHandler->ScanData.EventData.EventHandle.Event != ScanRequest->EventData.EventHandle.Event)
			{
			    DbgPrint("error:EventHandler->ScanData.EventData.EventHandle.Event != ScanRequest->EventData.EventHandle.Event\n");
				ntStatus = STATUS_UNSUCCESSFUL;
				goto error;
			}
			else
			{
				if(pEncDevice->ScanInitialization)
				{
					KeAcquireSpinLock(&pEncDevice->EventHandlerSpinLock, &OldIrql);

					pEncDevice->pScanEvent = pEventEntry;
					EventHandler->EventEntry = pEventEntry; // Need to remove one of the references here.
					memcpy(&(EventHandler->ScanData),ScanRequest, sizeof(KSEVENT_TUNER_INITIATE_SCAN_S));
					pEncDevice->CurrentFrequency = EventHandler->CurrentFrequency = ScanRequest->StartFrequency;
					pEncDevice->ScanStatusCode = EventHandler->StatusCode = Tuner_LockType_None;
					KeReleaseSpinLock(&pEncDevice->EventHandlerSpinLock, OldIrql);
					LARGE_INTEGER   Timeout;
					Timeout.QuadPart = (-1) * EventHandler->IdleTimeout.QuadPart;
					KeSetTimerEx (&(EventHandler->timer), Timeout, NULL, &(EventHandler->DPCObject));
					DbgPrint("AnlgTunerScanAddEvent restart scan at Frequency %d",EventHandler->CurrentFrequency);
					ntStatus = STATUS_SUCCESS;
					goto error;
				}
			}
		}
		else
		{
			KeAcquireSpinLock(&pEncDevice->EventHandlerSpinLock, &OldIrql);
			pEncDevice->pScanEvent = pEventEntry;
			KeReleaseSpinLock(&pEncDevice->EventHandlerSpinLock, OldIrql);
			ULONG ulTimeout=0;
			LARGE_INTEGER   WaitForThread;
			WaitForThread.QuadPart = -10000;
			while (EventHandler != NULL)
			{
			    DbgPrint("AnlgTunerScanAddEvent waiting for previous scan to end");
			    ulTimeout++;
			    KeWaitForSingleObject(pEncDevice->pScanEvent, Executive, KernelMode, FALSE, &WaitForThread);//wait for the thread to end
			    if (ulTimeout > 1000)//one second
			    {
			        ntStatus = STATUS_UNSUCCESSFUL;
			        goto error;
			    }
			}
		}
        if (!NT_SUCCESS(ntStatus)) goto error;
            
        // use a separate thread to do the actual scan.
        PEventHandlerData EventBlock;
        NTSTATUS     WaitStatus;

        ntStatus = InitializeEventing(pEncDevice);
        if ((!NT_SUCCESS(ntStatus)) || (EventHandler == NULL))
            goto error;

        EventBlock = EventHandler;

        KeAcquireSpinLock(&(EventBlock->LockAccess), &OldIrql);
        memcpy(&(EventBlock->ScanData),ScanRequest, sizeof(KSEVENT_TUNER_INITIATE_SCAN_S));
        pEncDevice->CurrentFrequency = EventHandler->CurrentFrequency = ScanRequest->StartFrequency;
        if(EventBlock->ScanData.EndFrequency < EventBlock->ScanData.StartFrequency)
        {
            ULONG temp;
            temp = EventBlock->ScanData.EndFrequency;
            EventBlock->ScanData.EndFrequency= EventBlock->ScanData.StartFrequency;
            EventBlock->ScanData.StartFrequency = temp;
        }
        pEncDevice->FreqRange = ScanRequest->EndFrequency - ScanRequest->StartFrequency;
        EventBlock->EventEntry = pEventEntry;
        EventBlock->IdleTimeout.QuadPart = pEncDevice->SettlingTime * 1000 * 10; // in 100 nanosecond units;
        EventBlock->bStopScan = FALSE;
        EventBlock->pDevice = pEncDevice;
        pEncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_None;
        KeReleaseSpinLock(&(EventBlock->LockAccess), OldIrql);

        // worker thread item for reads
        EventBlock->ThreadItem=IoAllocateWorkItem(pDevice->PhysicalDeviceObject);

        IoQueueWorkItem(EventBlock->ThreadItem,
            TunerScanWorkItem,
            CriticalWorkQueue,
            EventBlock);

        pEncDevice->ScanInitialization = TRUE;

        WaitStatus = KeWaitForSingleObject(&(EventBlock->InitEvent),
            Executive,
            KernelMode,
            FALSE,
            NULL);

        if (!NT_SUCCESS(WaitStatus)) {
            ntStatus = STATUS_UNSUCCESSFUL;
            goto error;
        }
            
    }
	// remove handler wont be called for this particular pEventEntry
	// till KsDefaultAddEventHandler returns. So pEventEntry is "safe"
	ntStatus = KsDefaultAddEventHandler(pIrp, reinterpret_cast<PKSEVENTDATA>(ScanRequest), pEventEntry);

error:
	DbgPrint("AnlgTunerScanAddEvent return -- code is %d",ntStatus);
	pIrp->IoStatus.Status = ntStatus;
	return ntStatus;
}
Beispiel #13
0
BOOLEAN
NTAPI
InitializeDeviceData(IN PDEVICE_OBJECT DeviceObject)
{
    PSAC_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
    BOOLEAN EnableData;
    ULONG PriorityValue;
    NTSTATUS Status;
    LARGE_INTEGER DueTime;
    PWCHAR Message;
    PAGED_CODE();
    SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n");

    /* If we already did this, bail out */
    if (DeviceExtension->Initialized) goto SuccessExit;

    /* Setup the DO flags */
    DeviceObject->Flags |= DO_DIRECT_IO;
    DeviceObject->StackSize = 16;

    /* Setup the device extension */
    DeviceExtension->DeviceObject = DeviceObject;
    DeviceExtension->PriorityBoost = IO_SERIAL_INCREMENT;
    DeviceExtension->PriorityFail = 0;
    DeviceExtension->RundownInProgress = 0;

    /* Initialize locks, events, timers, DPCs, etc... */
    KeInitializeTimer(&DeviceExtension->Timer);
    KeInitializeDpc(&DeviceExtension->Dpc, TimerDpcRoutine, DeviceExtension);
    KeInitializeSpinLock(&DeviceExtension->Lock);
    KeInitializeEvent(&DeviceExtension->Event, SynchronizationEvent, FALSE);
    InitializeListHead(&DeviceExtension->List);

    /* Attempt to enable HDL support */
    EnableData = TRUE;
    Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
                              &EnableData,
                              sizeof(EnableData),
                              NULL,
                              0);
    if (!NT_SUCCESS(Status))
    {
        /* Bail out if we couldn't even get this far */
        SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (1) with status FALSE\n");
        return FALSE;
    }

    /* Remember which process we started in */
    DeviceExtension->Process = IoGetCurrentProcess();

    /* Protect the device against non-admins */
    Status = CreateDeviceSecurityDescriptor(&DeviceExtension->DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        /* Write down why we failed */
        SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (2) with status FALSE\n");

        /* Disable the HDL terminal on failure */
        EnableData = FALSE;
        Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
                                  &EnableData,
                                  sizeof(EnableData),
                                  NULL,
                                  NULL);
        if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n");

        /* Bail out */
        return FALSE;
    }

    /* Create the worker thread */
    Status = PsCreateSystemThread(&DeviceExtension->WorkerThreadHandle,
                                  THREAD_ALL_ACCESS,
                                  NULL,
                                  NULL,
                                  NULL,
                                  WorkerThreadStartUp,
                                  DeviceExtension);
    if (!NT_SUCCESS(Status))
    {
        /* Write down why we failed */
        SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (3) with status FALSE\n");

        /* Disable the HDL terminal on failure */
        EnableData = FALSE;
        Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
                                  &EnableData,
                                  sizeof(EnableData),
                                  NULL,
                                  NULL);
        if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n");

        /* Bail out */
        return FALSE;
    }

    /* Set the priority of our thread to highest */
    PriorityValue = HIGH_PRIORITY;
    Status = NtSetInformationThread(DeviceExtension->WorkerThreadHandle,
                                    ThreadPriority,
                                    &PriorityValue,
                                    sizeof(PriorityValue));
    if (!NT_SUCCESS(Status))
    {
        /* For debugging, write down why we failed */
        SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (6) with status FALSE\n");
        DeviceExtension->PriorityFail = TRUE;

        /* Initialize rundown and wait for the thread to do it */
        KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, FALSE);
        KeSetEvent(&DeviceExtension->Event, DeviceExtension->PriorityBoost, FALSE);
        Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent,
                                       Executive,
                                       KernelMode,
                                       FALSE,
                                       NULL);
        ASSERT(Status == STATUS_SUCCESS);

        /* Disable the HDL terminal on failure */
        EnableData = FALSE;
        Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
                                  &EnableData,
                                  sizeof(EnableData),
                                  NULL,
                                  0);
        if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n");

        /* Bail out */
        return FALSE;
    }

    /* The first "packet" is the machine information in XML... */
    Status = TranslateMachineInformationXML(&Message, NULL);
    if (NT_SUCCESS(Status))
    {
        /* Go ahead and send it */
        UTF8EncodeAndSend(L"<?xml version=\"1.0\"?>\r\n");
        UTF8EncodeAndSend(Message);

        /* Free the temporary buffer */
        SacFreePool(Message);
    }

    /* Finally, initialize the I/O Manager */
    Status = ConMgrInitialize();
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Set the timer. Once this is done, the device is initialized */
    DueTime.QuadPart = -4000;
    KeSetTimerEx(&DeviceExtension->Timer, DueTime, 4, &DeviceExtension->Dpc);
    DeviceExtension->Initialized = TRUE;

SuccessExit:
    /* Success path -- everything worked */
    SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status TRUE\n");
    return TRUE;
}
Beispiel #14
0
//=============================================================================
STDMETHODIMP CMiniportWaveCyclicStream::SetState(
    IN  KSSTATE                 NewState
)
/*++
Routine Description:
  The SetState function sets the new state of playback or recording for the
  stream. SetState should run at IRQL PASSIVE_LEVEL

Arguments:
  NewState - KSSTATE indicating the new state for the stream.

Return Value:
  NT status code.
--*/
{
    PAGED_CODE();

    DPF_ENTER(("[CMiniportWaveCyclicStream::SetState]"));

    NTSTATUS ntStatus = STATUS_SUCCESS;

    // The acquire state is not distinguishable from the stop state for our
    // purposes.
    if (NewState == KSSTATE_ACQUIRE) {
        NewState = KSSTATE_STOP;
    }

    if (m_ksState != NewState) {
        switch(NewState) {
            case KSSTATE_PAUSE:
                DPF(D_TERSE, ("KSSTATE_PAUSE"));
                
                m_fDmaActive = FALSE;
                break;

            case KSSTATE_RUN:
                DPF(D_TERSE, ("KSSTATE_RUN"));

                LARGE_INTEGER   delay;

                // Set the timer for DPC.
                m_ullDmaTimeStamp             = KeQueryInterruptTime();
                m_ullElapsedTimeCarryForward  = 0;
                m_fDmaActive                  = TRUE;
                delay.HighPart                = 0;
                delay.LowPart                 = m_pMiniport->m_NotificationInterval;

                KeSetTimerEx(m_pTimer, delay, m_pMiniport->m_NotificationInterval, m_pDpc);
                break;

            case KSSTATE_STOP:
                DPF(D_TERSE, ("KSSTATE_STOP"));
    
                m_fDmaActive                      = FALSE;
                m_ulDmaPosition                   = 0;
                m_ullElapsedTimeCarryForward      = 0;
                m_ulByteDisplacementCarryForward  = 0;
    
                KeCancelTimer(m_pTimer);
    
                // Wait until all work items are completed.
                if (!m_fCapture) {
                    m_SaveData.WaitAllWorkItems();
                }
                break;
        }

        m_ksState = NewState;
    }

    return ntStatus;
} // SetState
Beispiel #15
-1
NTSTATUS NTAPI
DriverEntry(
  PDRIVER_OBJECT DriverObject,
  PUNICODE_STRING RegistryPath)
/*
 * FUNCTION: Main driver entry point
 * ARGUMENTS:
 *     DriverObject = Pointer to a driver object for this driver
 *     RegistryPath = Registry node for configuration parameters
 * RETURNS:
 *     Status of driver initialization
 */
{
  NTSTATUS Status;
  UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
  UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
  UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
  UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
  UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
  NDIS_STATUS NdisStatus;
  LARGE_INTEGER DueTime;

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Called\n"));

  /* TdiInitialize() ? */

  /* FIXME: Create symbolic links in Win32 namespace */

  /* Initialize our periodic timer and its associated DPC object. When the
     timer expires, the IPTimeout deferred procedure call (DPC) is queued */
  KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
  KeInitializeTimer(&IPTimer);

  /* Create IP device object */
  Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  ChewInit( IPDeviceObject );

  /* Create RawIP device object */
  Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create UDP device object */
  Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create TCP device object */
  Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Setup network layer and transport layer entities */
  KeInitializeSpinLock(&EntityListLock);
  EntityList = ExAllocatePoolWithTag(NonPagedPool,
                                     sizeof(TDIEntityID) * MAX_TDI_ENTITIES,
                                     TDI_ENTITY_TAG );
  if (!EntityList) {
    TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  EntityCount = 0;
  EntityMax   = MAX_TDI_ENTITIES;

  /* Allocate NDIS packet descriptors */
  NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT));
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Allocate NDIS buffer descriptors */
  NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000);
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Initialize address file list and protecting spin lock */
  InitializeListHead(&AddressFileListHead);
  KeInitializeSpinLock(&AddressFileListLock);

  /* Initialize connection endpoint list and protecting spin lock */
  InitializeListHead(&ConnectionEndpointListHead);
  KeInitializeSpinLock(&ConnectionEndpointListLock);

  /* Initialize interface list and protecting spin lock */
  InitializeListHead(&InterfaceListHead);
  KeInitializeSpinLock(&InterfaceListLock);

  /* Initialize network level protocol subsystem */
  IPStartup(RegistryPath);

  /* Initialize transport level protocol subsystems */
  Status = RawIPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = UDPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = TCPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = ICMPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  /* Use direct I/O */
  IPDeviceObject->Flags    |= DO_DIRECT_IO;
  RawIPDeviceObject->Flags |= DO_DIRECT_IO;
  UDPDeviceObject->Flags   |= DO_DIRECT_IO;
  TCPDeviceObject->Flags   |= DO_DIRECT_IO;

  /* Initialize the driver object with this driver's entry points */
  DriverObject->MajorFunction[IRP_MJ_CREATE]  = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_CLOSE]   = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;

  DriverObject->DriverUnload = TiUnload;

  /* Open loopback adapter */
  Status = LoopRegisterAdapter(NULL, NULL);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Register protocol with NDIS */
  /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
  Status = LANRegisterProtocol(&strNdisDeviceName);
  if (!NT_SUCCESS(Status)) {
	  TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
	  TiWriteErrorLog(
      DriverObject,
      EVENT_TRANSPORT_REGISTER_FAILED,
      TI_ERROR_DRIVERENTRY,
      Status,
      NULL,
      0,
      NULL);
      TiUnload(DriverObject);
      return Status;
  }

  /* Start the periodic timer with an initial and periodic
     relative expiration time of IP_TIMEOUT milliseconds */
  DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
  KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));


  return STATUS_SUCCESS;
}