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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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) }
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; }
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; }
//============================================================================= 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
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; }