int lkl_env_init(unsigned long mem_size) { HANDLE init_thread_handle, timer_thread_handle; NTSTATUS status; nops.phys_mem_size=mem_size; KeInitializeTimerEx(&timer, SynchronizationTimer); KeInitializeSemaphore(&init_sem, 0, 100); KeInitializeSemaphore(&timer_killer_sem, 0, 100); /* create the initial thread */ status = PsCreateSystemThread(&init_thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, init_thread, NULL); if (status != STATUS_SUCCESS) goto err; /* wait for the initial thread to complete initialization to * be able to interact with it */ status = KeWaitForSingleObject(&init_sem, Executive, KernelMode, FALSE, NULL); if (status != STATUS_SUCCESS) goto close_init_thread; /* create the timer thread responsible with delivering timer interrupts */ status = PsCreateSystemThread(&timer_thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, timer_thread, NULL); if (status != STATUS_SUCCESS) goto close_init_thread; /* get references to the init and timer threads to be able to wait on them */ status = ObReferenceObjectByHandle(init_thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &init_thread_obj, NULL); if (!NT_SUCCESS(status)) goto close_timer_thread; status = ObReferenceObjectByHandle(timer_thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &timer_thread_obj, NULL); if (!NT_SUCCESS(status)) goto deref_init_thread_obj; /* we don't need the handles, we have access to the objects */ ZwClose(timer_thread_handle); ZwClose(init_thread_handle); return STATUS_SUCCESS; deref_init_thread_obj: ObDereferenceObject(init_thread_obj); close_timer_thread: ZwClose(timer_thread_handle); close_init_thread: ZwClose(init_thread_handle); err: return status; }
/* * @implemented */ VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer) { /* Call the New Function */ KeInitializeTimerEx(Timer, NotificationTimer); }
NTSTATUS InitializeEventing(CEncoderDevice* pEncDevice) { // First, allocate buffers NTSTATUS ntStatus = STATUS_SUCCESS; if(!EventHandler) { EventHandler = (PEventHandlerData)ExAllocatePoolWithTag(NonPagedPool, sizeof(EventHandlerData), MS_SAMPLE_ANALOG_POOL_TAG); if (!EventHandler) { ntStatus = STATUS_UNSUCCESSFUL; return ntStatus; } pEncDevice->EventData = reinterpret_cast<PVOID>(EventHandler); KeInitializeEvent(&(EventHandler->InitEvent), SynchronizationEvent, FALSE); KeInitializeEvent(&(EventHandler->TuneEvent), SynchronizationEvent, FALSE); KeInitializeEvent(&(EventHandler->ThreadEvent), SynchronizationEvent, FALSE); KeInitializeSpinLock(&(EventHandler->LockAccess)); KeInitializeDpc (&(EventHandler->DPCObject), reinterpret_cast <PKDEFERRED_ROUTINE>(TimerDpcInterrupt), EventHandler); KeInitializeTimerEx(&(EventHandler->timer), SynchronizationTimer); } KeClearEvent(&(EventHandler->InitEvent)); KeClearEvent(&(EventHandler->TuneEvent)); KeClearEvent(&(EventHandler->ThreadEvent)); return ntStatus; }
VOID KiInitializeInterruptTimers( VOID ) { LARGE_INTEGER DueTime; // // If not timing ISRs, nothing to do. // if (KiTimeLimitIsrMicroseconds == 0) { return; } // // The kernel is initialized. Use a timer to determine the amount // the Time Stamp Counter advances by in 10 seconds, then use that // result to set the ISR time limit. // if ((KeFeatureBits & KF_RDTSC) == 0) { // // Processor doesn't support the RDTSC instruction, don't attempt // to time ISRs. // return; } KiIsrTimerInit = ExAllocatePoolWithTag(NonPagedPool, sizeof(*KiIsrTimerInit), ' eK'); if (KiIsrTimerInit == NULL) { // // Couldn't allocate memory for timer? Skip ISR timing. // return; } KeInitializeTimerEx(&KiIsrTimerInit->SampleTimer, SynchronizationTimer); KeInitializeDpc(&KiIsrTimerInit->Dpc, &KiInitializeInterruptTimersDpc, NULL); // // Relative time in 100 nanoseconds = 10 seconds. // DueTime.QuadPart = -(10 * 10 * 1000 * 1000); KeSetTimerEx(&KiIsrTimerInit->SampleTimer, DueTime, // 10000, // repeat in 10 seconds. &KiIsrTimerInit->Dpc); }
// Sleep void SlSleep(int milliSeconds) { PKTIMER timer = SlMalloc(sizeof(KTIMER)); LARGE_INTEGER duetime; duetime.QuadPart = (__int64)milliSeconds * -10000; KeInitializeTimerEx(timer, NotificationTimer); KeSetTimerEx(timer, duetime, 0, NULL); KeWaitForSingleObject(timer, Executive, KernelMode, FALSE, NULL); SlFree(timer); }
static VOID TestTimerFunctional( IN PKTIMER Timer, IN TIMER_TYPE Type, IN KIRQL OriginalIrql) { PKTHREAD Thread = KeGetCurrentThread(); memset(Timer, 0x55, sizeof *Timer); KeInitializeTimerEx(Timer, Type); CheckTimer(Timer, TimerNotificationObject + Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); }
VOID DokanTimeoutThread( PDokanDCB Dcb) /*++ Routine Description: checks wheter pending IRP is timeout or not each DOKAN_CHECK_INTERVAL --*/ { NTSTATUS status; KTIMER timer; PVOID pollevents[2]; LARGE_INTEGER timeout = {0}; BOOLEAN waitObj = TRUE; DDbgPrint("==> DokanTimeoutThread\n"); KeInitializeTimerEx(&timer, SynchronizationTimer); pollevents[0] = (PVOID)&Dcb->KillEvent; pollevents[1] = (PVOID)&timer; KeSetTimerEx(&timer, timeout, DOKAN_CHECK_INTERVAL, NULL); while (waitObj) { status = KeWaitForMultipleObjects(2, pollevents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL); if (!NT_SUCCESS(status) || status == STATUS_WAIT_0) { DDbgPrint(" DokanTimeoutThread catched KillEvent\n"); // KillEvent or something error is occured waitObj = FALSE; } else { ReleaseTimeoutPendingIrp(Dcb); if (Dcb->UseKeepAlive) DokanCheckKeepAlive(Dcb); } } KeCancelTimer(&timer); DDbgPrint("<== DokanTimeoutThread\n"); PsTerminateSystemThread(STATUS_SUCCESS); }
VOID NTAPI INIT_FUNCTION PoInitializePrcb(IN PKPRCB Prcb) { /* Initialize the Power State */ RtlZeroMemory(&Prcb->PowerState, sizeof(Prcb->PowerState)); Prcb->PowerState.Idle0KernelTimeLimit = 0xFFFFFFFF; Prcb->PowerState.CurrentThrottle = 100; Prcb->PowerState.CurrentThrottleIndex = 0; Prcb->PowerState.IdleFunction = PopIdle0; /* Initialize the Perf DPC and Timer */ KeInitializeDpc(&Prcb->PowerState.PerfDpc, PopPerfIdleDpc, Prcb); KeSetTargetProcessorDpc(&Prcb->PowerState.PerfDpc, Prcb->Number); KeInitializeTimerEx(&Prcb->PowerState.PerfTimer, SynchronizationTimer); }
VOID INIT_FUNCTION NTAPI MiInitBalancerThread(VOID) { KPRIORITY Priority; NTSTATUS Status; #if !defined(__GNUC__) LARGE_INTEGER dummyJunkNeeded; dummyJunkNeeded.QuadPart = -20000000; /* 2 sec */ ; #endif KeInitializeEvent(&MiBalancerEvent, SynchronizationEvent, FALSE); KeInitializeTimerEx(&MiBalancerTimer, SynchronizationTimer); KeSetTimerEx(&MiBalancerTimer, #if defined(__GNUC__) (LARGE_INTEGER)(LONGLONG)-20000000LL, /* 2 sec */ #else dummyJunkNeeded, #endif 2000, /* 2 sec */ NULL); Status = PsCreateSystemThread(&MiBalancerThreadHandle, THREAD_ALL_ACCESS, NULL, NULL, &MiBalancerThreadId, (PKSTART_ROUTINE) MiBalancerThread, NULL); if (!NT_SUCCESS(Status)) { KeBugCheck(MEMORY_MANAGEMENT); } Priority = LOW_REALTIME_PRIORITY + 1; NtSetInformationThread(MiBalancerThreadHandle, ThreadPriority, &Priority, sizeof(Priority)); }
NTSTATUS CMiniportWaveRTStream::Init ( _In_ PCMiniportWaveRT Miniport_, _In_ PPORTWAVERTSTREAM PortStream_, _In_ ULONG Pin_, _In_ BOOLEAN Capture_, _In_ PKSDATAFORMAT DataFormat_, _In_ GUID SignalProcessingMode ) /*++ Routine Description: Initializes the stream object. Arguments: Miniport_ - Pin_ - Capture_ - DataFormat - SignalProcessingMode - The driver uses the signalProcessingMode to configure driver and/or hardware specific signal processing to be applied to this new stream. Return Value: NT status code. --*/ { PAGED_CODE(); PWAVEFORMATEX pWfEx = NULL; NTSTATUS ntStatus = STATUS_SUCCESS; m_pMiniport = NULL; m_ulPin = 0; m_bUnregisterStream = FALSE; m_bCapture = FALSE; m_ulDmaBufferSize = 0; m_pDmaBuffer = NULL; m_KsState = KSSTATE_STOP; m_pTimer = NULL; m_pDpc = NULL; m_ullPlayPosition = 0; m_ullWritePosition = 0; m_ullDmaTimeStamp = 0; m_hnsElapsedTimeCarryForward = 0; m_ulDmaMovementRate = 0; m_bLfxEnabled = FALSE; m_pbMuted = NULL; m_plVolumeLevel = NULL; m_plPeakMeter = NULL; m_pWfExt = NULL; m_ullLinearPosition = 0; m_ulContentId = 0; m_ulCurrentWritePosition = 0; m_IsCurrentWritePositionUpdated = 0; #ifdef SYSVAD_BTH_BYPASS m_ScoOpen = FALSE; #endif // SYSVAD_BTH_BYPASS m_pPortStream = PortStream_; InitializeListHead(&m_NotificationList); m_ulNotificationIntervalMs = 0; m_pNotificationDpc = (PRKDPC)ExAllocatePoolWithTag( NonPagedPoolNx, sizeof(KDPC), MINWAVERTSTREAM_POOLTAG); if (!m_pNotificationDpc) { return STATUS_INSUFFICIENT_RESOURCES; } m_pNotificationTimer = (PKTIMER)ExAllocatePoolWithTag( NonPagedPoolNx, sizeof(KTIMER), MINWAVERTSTREAM_POOLTAG); if (!m_pNotificationTimer) { return STATUS_INSUFFICIENT_RESOURCES; } KeInitializeDpc(m_pNotificationDpc, TimerNotifyRT, this); KeInitializeTimerEx(m_pNotificationTimer, NotificationTimer); pWfEx = GetWaveFormatEx(DataFormat_); if (NULL == pWfEx) { return STATUS_UNSUCCESSFUL; } m_pMiniport = reinterpret_cast<CMiniportWaveRT*>(Miniport_); if (m_pMiniport == NULL) { return STATUS_INVALID_PARAMETER; } m_pMiniport->AddRef(); if (!NT_SUCCESS(ntStatus)) { return ntStatus; } m_ulPin = Pin_; m_bCapture = Capture_; m_ulDmaMovementRate = pWfEx->nAvgBytesPerSec; m_pDpc = (PRKDPC)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(KDPC), MINWAVERTSTREAM_POOLTAG); if (!m_pDpc) { return STATUS_INSUFFICIENT_RESOURCES; } m_pWfExt = (PWAVEFORMATEXTENSIBLE)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(WAVEFORMATEX) + pWfEx->cbSize, MINWAVERTSTREAM_POOLTAG); if (m_pWfExt == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyMemory(m_pWfExt, pWfEx, sizeof(WAVEFORMATEX) + pWfEx->cbSize); m_pbMuted = (PBOOL)ExAllocatePoolWithTag(NonPagedPoolNx, m_pWfExt->Format.nChannels * sizeof(BOOL), MINWAVERTSTREAM_POOLTAG); if (m_pbMuted == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(m_pbMuted, m_pWfExt->Format.nChannels * sizeof(BOOL)); m_plVolumeLevel = (PLONG)ExAllocatePoolWithTag(NonPagedPoolNx, m_pWfExt->Format.nChannels * sizeof(LONG), MINWAVERTSTREAM_POOLTAG); if (m_plVolumeLevel == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(m_plVolumeLevel, m_pWfExt->Format.nChannels * sizeof(LONG)); m_plPeakMeter = (PLONG)ExAllocatePoolWithTag(NonPagedPoolNx, m_pWfExt->Format.nChannels * sizeof(LONG), MINWAVERTSTREAM_POOLTAG); if (m_plPeakMeter == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(m_plPeakMeter, m_pWfExt->Format.nChannels * sizeof(LONG)); if (m_bCapture) { DWORD toneFrequency = 0; if (!m_pMiniport->IsRenderDevice()) { // // Init sine wave generator. To exercise the SignalProcessingMode parameter // this sample driver selects the frequency based on the parameter. // toneFrequency = IsEqualGUID(SignalProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW) ? 1000 : 2000; } else { // // Loopbacks pins use a different frequency for test validation. // ASSERT(Pin_ == m_pMiniport->GetLoopbackPinId()); toneFrequency = 3000; // 3 kHz } ntStatus = m_ToneGenerator.Init(toneFrequency, m_pWfExt); if (!NT_SUCCESS(ntStatus)) { return ntStatus; } } else if (!g_DoNotCreateDataFiles) { // // Create an output file for the render data. // DPF(D_TERSE, ("SaveData %p", &m_SaveData)); ntStatus = m_SaveData.SetDataFormat(DataFormat_); if (NT_SUCCESS(ntStatus)) { ntStatus = m_SaveData.Initialize(m_pMiniport->IsOffloadSupported() ? (Pin_ == m_pMiniport->GetOffloadPinId()) : FALSE); } if (!NT_SUCCESS(ntStatus)) { return ntStatus; } } // // Register this stream. // ntStatus = m_pMiniport->StreamCreated(m_ulPin, this); if (NT_SUCCESS(ntStatus)) { m_bUnregisterStream = TRUE; } return ntStatus; } // Init
NTSTATUS NTAPI AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp ) { NTSTATUS Status = STATUS_NO_MEMORY; PAFD_FCB FCB; PFILE_OBJECT FileObject; PAFD_POLL_INFO PollReq = Irp->AssociatedIrp.SystemBuffer; PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; KIRQL OldIrql; UINT i, Signalled = 0; ULONG Exclusive = PollReq->Exclusive; UNREFERENCED_PARAMETER(IrpSp); AFD_DbgPrint(MID_TRACE,("Called (HandleCount %u Timeout %d)\n", PollReq->HandleCount, (INT)(PollReq->Timeout.QuadPart))); SET_AFD_HANDLES(PollReq, LockHandles( PollReq->Handles, PollReq->HandleCount )); if( !AFD_HANDLES(PollReq) ) { Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); return STATUS_NO_MEMORY; } if( Exclusive ) { for( i = 0; i < PollReq->HandleCount; i++ ) { if( !AFD_HANDLES(PollReq)[i].Handle ) continue; KillSelectsForFCB( DeviceExt, (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle, TRUE ); } } KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql ); for( i = 0; i < PollReq->HandleCount; i++ ) { if( !AFD_HANDLES(PollReq)[i].Handle ) continue; FileObject = (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle; FCB = FileObject->FsContext; AFD_DbgPrint(MID_TRACE, ("AFD: Select Events: ")); PrintEvents( PollReq->Handles[i].Events ); AFD_DbgPrint(MID_TRACE,("\n")); PollReq->Handles[i].Status = PollReq->Handles[i].Events & FCB->PollState; if( PollReq->Handles[i].Status ) { AFD_DbgPrint(MID_TRACE,("Signalling %p with %x\n", FCB, FCB->PollState)); Signalled++; } } if( Signalled ) { Status = STATUS_SUCCESS; Irp->IoStatus.Status = Status; SignalSocket( NULL, Irp, PollReq, Status ); } else { PAFD_ACTIVE_POLL Poll = NULL; Poll = ExAllocatePool( NonPagedPool, sizeof(AFD_ACTIVE_POLL) ); if (Poll){ Poll->Irp = Irp; Poll->DeviceExt = DeviceExt; Poll->Exclusive = Exclusive; KeInitializeTimerEx( &Poll->Timer, NotificationTimer ); KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc, SelectTimeout, Poll ); InsertTailList( &DeviceExt->Polls, &Poll->ListEntry ); KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc ); Status = STATUS_PENDING; IoMarkIrpPending( Irp ); (void)IoSetCancelRoutine(Irp, AfdCancelHandler); } else { AFD_DbgPrint(MAX_TRACE, ("FIXME: do something with the IRP!\n")); Status = STATUS_NO_MEMORY; } } KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); return Status; }
static NTSTATUS V4vAddDevice(PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING deviceName; PDEVICE_OBJECT fdo = NULL; PXENV4V_EXTENSION pde = NULL; LONG val; BOOLEAN symlink = FALSE; LARGE_INTEGER seed; WCHAR *szSddl = NULL; UNICODE_STRING sddlString; CHAR *szFpath = NULL; TraceVerbose(("====> '%s'.\n", __FUNCTION__)); // We only allow one instance of this device type. If more than on pdo is created we need val = InterlockedCompareExchange(&g_deviceCreated, 1, 0); if (val != 0) { TraceWarning(("cannot instantiate more that one v4v device node.\n")); return STATUS_UNSUCCESSFUL; } do { // Create our device RtlInitUnicodeString(&deviceName, V4V_DEVICE_NAME); szSddl = g_win5Sddl; RtlInitUnicodeString(&sddlString, szSddl); status = IoCreateDeviceSecure(driverObject, sizeof(XENV4V_EXTENSION), &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &sddlString, (LPCGUID)&GUID_SD_XENV4V_CONTROL_OBJECT, &fdo); if (!NT_SUCCESS(status)) { TraceError(("failed to create device object - error: 0x%x\n", status)); fdo = NULL; break; } pde = (PXENV4V_EXTENSION)fdo->DeviceExtension; RtlZeroMemory(pde, sizeof(XENV4V_EXTENSION)); RtlStringCchCopyW(pde->symbolicLinkText, XENV4V_SYM_NAME_LEN, V4V_SYMBOLIC_NAME); RtlInitUnicodeString(&pde->symbolicLink, pde->symbolicLinkText); // Create our symbolic link status = IoCreateSymbolicLink(&pde->symbolicLink, &deviceName); if (!NT_SUCCESS(status)) { TraceError(("failed to create symbolic - error: 0x%x\n", status)); break; } symlink = TRUE; // Get our xenstore path szFpath = xenbus_find_frontend(pdo); if (szFpath == NULL) { status = STATUS_NO_SUCH_DEVICE; TraceError(("failed to locate XenStore front end path\n")); break; } // Setup the extension pde->magic = XENV4V_MAGIC; pde->pdo = pdo; pde->fdo = fdo; IoInitializeRemoveLock(&pde->removeLock, 'v4vx', 0, 0); pde->frontendPath = szFpath; szFpath = NULL; pde->state = XENV4V_DEV_STOPPED; // wait for start pde->lastPoState = PowerSystemWorking; pde->virqPort = null_EVTCHN_PORT(); KeInitializeDpc(&pde->virqDpc, V4vVirqNotifyDpc, fdo); KeInitializeSpinLock(&pde->virqLock); KeInitializeSpinLock(&pde->dpcLock); KeInitializeTimerEx(&pde->timer, NotificationTimer); KeInitializeDpc(&pde->timerDpc, V4vConnectTimerDpc, fdo); KeInitializeSpinLock(&pde->timerLock); pde->timerCounter = 0; InitializeListHead(&pde->contextList); KeInitializeSpinLock(&pde->contextLock); pde->contextCount = 0; InitializeListHead(&pde->ringList); KeInitializeSpinLock(&pde->ringLock); InitializeListHead(&pde->pendingIrpQueue); pde->pendingIrpCount = 0; KeInitializeSpinLock(&pde->queueLock); IoCsqInitializeEx(&pde->csqObject, V4vCsqInsertIrpEx, V4vCsqRemoveIrp, V4vCsqPeekNextIrp, V4vCsqAcquireLock, V4vCsqReleaseLock, V4vCsqCompleteCanceledIrp); InitializeListHead(&pde->destList); pde->destCount = 0; ExInitializeNPagedLookasideList(&pde->destLookasideList, NULL, NULL, 0, sizeof(XENV4V_DESTINATION), XENV4V_TAG, 0); KeQueryTickCount(&seed); pde->seed = seed.u.LowPart; // Now attach us to the stack pde->ldo = IoAttachDeviceToDeviceStack(fdo, pdo); if (pde->ldo == NULL) { TraceError(("failed to attach device to stack - error: 0x%x\n", status)); status = STATUS_NO_SUCH_DEVICE; break; } // Use direct IO and let the IO manager directly map user buffers; clear the init flag fdo->Flags |= DO_DIRECT_IO; fdo->Flags &= ~DO_DEVICE_INITIALIZING; // Made it here, go to connected state to be consistent xenbus_change_state(XBT_NIL, pde->frontendPath, "state", XENBUS_STATE_CONNECTED); } while (FALSE); if (!NT_SUCCESS(status)) { if (fdo != NULL) { if ((pde != NULL)&&(pde->ldo != NULL)) { IoDetachDevice(pde->ldo); } if (szFpath != NULL) { XmFreeMemory(szFpath); } if (symlink) { IoDeleteSymbolicLink(&pde->symbolicLink); } IoDeleteDevice(fdo); } } TraceVerbose(("<==== '%s'.\n", __FUNCTION__)); return status; }
NTSTATUS NtCreateTimer ( OUT PHANDLE TimerHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN TIMER_TYPE TimerType ) /*++ Routine Description: This function creates an timer object and opens a handle to the object with the specified desired access. Arguments: TimerHandle - Supplies a pointer to a variable that will receive the timer object handle. DesiredAccess - Supplies the desired types of access for the timer object. ObjectAttributes - Supplies a pointer to an object attributes structure. TimerType - Supplies the type of the timer (autoclearing or notification). Return Value: TBS --*/ { PETIMER ExTimer; HANDLE Handle; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; // // Establish an exception handler, probe the output handle address, and // attempt to create a timer object. If the probe fails, then return the // exception code as the service status. Otherwise return the status value // returned by the object insertion routine. // try { // // Get previous processor mode and probe output handle address if // necessary. // PreviousMode = KeGetPreviousMode(); if (PreviousMode != KernelMode) { ProbeForWriteHandle(TimerHandle); } // // Check argument validity. // if ((TimerType != NotificationTimer) && (TimerType != SynchronizationTimer)) { return STATUS_INVALID_PARAMETER_4; } // // Allocate timer object. // Status = ObCreateObject(PreviousMode, ExTimerObjectType, ObjectAttributes, PreviousMode, NULL, sizeof(ETIMER), 0, 0, (PVOID *)&ExTimer); // // If the timer object was successfully allocated, then initialize the // timer object and attempt to insert the time object in the current // process' handle table. // if (NT_SUCCESS(Status)) { KeInitializeDpc(&ExTimer->TimerDpc, ExpTimerDpcRoutine, (PVOID)ExTimer); KeInitializeTimerEx(&ExTimer->KeTimer, TimerType); KeInitializeSpinLock(&ExTimer->Lock); ExTimer->ApcAssociated = FALSE; ExTimer->WakeTimer = FALSE; ExTimer->WakeTimerListEntry.Flink = NULL; Status = ObInsertObject((PVOID)ExTimer, NULL, DesiredAccess, 0, (PVOID *)NULL, &Handle); // // If the timer object was successfully inserted in the current // process' handle table, then attempt to write the timer object // handle value. If the write attempt fails, then do not report // an error. When the caller attempts to access the handle value, // an access violation will occur. // if (NT_SUCCESS(Status)) { try { *TimerHandle = Handle; } except(ExSystemExceptionFilter()) { } } } // // If an exception occurs during the probe of the output handle address, // then always handle the exception and return the exception code as the // status value. // } except(ExSystemExceptionFilter()) { return GetExceptionCode(); } // // Return service status. // return Status; }
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 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); }
NTSTATUS MobiUsb_AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) /*++ Description: Arguments: DriverObject - Store the pointer to the object representing us. PhysicalDeviceObject - Pointer to the device object created by the undelying bus driver. Return: STATUS_SUCCESS - if successful STATUS_UNSUCCESSFUL - otherwise --*/ { NTSTATUS ntStatus; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension; POWER_STATE state; KIRQL oldIrql; MobiUsb_DbgPrint(3, ("file mobiusb: MobiUsb_AddDevice - begins\n")); deviceObject = NULL; ntStatus = IoCreateDevice( DriverObject, // our driver object sizeof(DEVICE_EXTENSION), // extension size for us NULL, // name for this device FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, // device characteristics FALSE, // Not exclusive &deviceObject); // Our device object if(!NT_SUCCESS(ntStatus)) { // // returning failure here prevents the entire stack from functioning, // but most likely the rest of the stack will not be able to create // device objects either, so it is still OK. // MobiUsb_DbgPrint(1, ("file mobiusb: Failed to create device object\n")); return ntStatus; } // // Initialize the device extension // deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; deviceExtension->FunctionalDeviceObject = deviceObject; deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; #ifdef MOBI_DIRECT_IO deviceObject->Flags |= DO_DIRECT_IO; #else deviceObject->Flags |= DO_BUFFERED_IO; #endif // // initialize the device state lock and set the device state // KeInitializeSpinLock(&deviceExtension->DevStateLock); INITIALIZE_PNP_STATE(deviceExtension); // //initialize OpenHandleCount // deviceExtension->OpenHandleCount = 0; // // Initialize the selective suspend variables // KeInitializeSpinLock(&deviceExtension->IdleReqStateLock); deviceExtension->IdleReqPend = 0; deviceExtension->PendingIdleIrp = NULL; // // Initialize the vendor command semaphore // KeInitializeSemaphore(&deviceExtension->CallUSBSemaphore, 1, 1); // // Hold requests until the device is started // deviceExtension->QueueState = HoldRequests; // // Initialize the queue and the queue spin lock // InitializeListHead(&deviceExtension->NewRequestsQueue); KeInitializeSpinLock(&deviceExtension->QueueLock); // // Initialize the remove event to not-signaled. // KeInitializeEvent(&deviceExtension->RemoveEvent, SynchronizationEvent, FALSE); // // Initialize the stop event to signaled. // This event is signaled when the OutstandingIO becomes 1 // KeInitializeEvent(&deviceExtension->StopEvent, SynchronizationEvent, TRUE); // // OutstandingIo count biased to 1. // Transition to 0 during remove device means IO is finished. // Transition to 1 means the device can be stopped // deviceExtension->OutStandingIO = 1; KeInitializeSpinLock(&deviceExtension->IOCountLock); // // Delegating to WMILIB // ntStatus = MobiUsb_WmiRegistration(deviceExtension); if(!NT_SUCCESS(ntStatus)) { MobiUsb_DbgPrint(1, ("file mobiusb: MobiUsb_WmiRegistration failed with %X\n", ntStatus)); IoDeleteDevice(deviceObject); return ntStatus; } // // set the flags as underlying PDO // if(PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) { deviceObject->Flags |= DO_POWER_PAGABLE; } // // Typically, the function driver for a device is its // power policy owner, although for some devices another // driver or system component may assume this role. // Set the initial power state of the device, if known, by calling // PoSetPowerState. // deviceExtension->DevPower = PowerDeviceD0; deviceExtension->SysPower = PowerSystemWorking; state.DeviceState = PowerDeviceD0; PoSetPowerState(deviceObject, DevicePowerState, state); // // attach our driver to device stack // The return value of IoAttachDeviceToDeviceStack is the top of the // attachment chain. This is where all the IRPs should be routed. // deviceExtension->TopOfStackDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject); if(NULL == deviceExtension->TopOfStackDeviceObject) { MobiUsb_WmiDeRegistration(deviceExtension); IoDeleteDevice(deviceObject); return STATUS_NO_SUCH_DEVICE; } // // Register device interfaces // ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject, &GUID_CLASS_VCMOBI_MOBI, NULL, &deviceExtension->InterfaceName); if(!NT_SUCCESS(ntStatus)) { MobiUsb_WmiDeRegistration(deviceExtension); IoDetachDevice(deviceExtension->TopOfStackDeviceObject); IoDeleteDevice(deviceObject); return ntStatus; } //MobiUsb_DbgPrint(3, ("file mobiusb: interfacename: Filename = %ws nameLength = %d\n", deviceExtension->InterfaceName.Buffer, deviceExtension->InterfaceName.Length / sizeof(WCHAR))); if(IoIsWdmVersionAvailable(1, 0x20)) { deviceExtension->WdmVersion = WinXpOrBetter; } else if(IoIsWdmVersionAvailable(1, 0x10)) { deviceExtension->WdmVersion = Win2kOrBetter; } else if(IoIsWdmVersionAvailable(1, 0x5)) { deviceExtension->WdmVersion = WinMeOrBetter; } else if(IoIsWdmVersionAvailable(1, 0x0)) { deviceExtension->WdmVersion = Win98OrBetter; } MobiUsb_DbgPrint(3, ("file mobiusb: WdmVersion = %d\n", deviceExtension->WdmVersion)); deviceExtension->SSRegistryEnable = 0; deviceExtension->SSEnable = 0; // // WinXP only // check the registry flag - // whether the device should selectively // suspend when idle // if(WinXpOrBetter == deviceExtension->WdmVersion) { MobiUsb_GetRegistryDword(MOBIUSB_REGISTRY_PARAMETERS_PATH, L"VCMobiEnable", &deviceExtension->SSRegistryEnable); if(deviceExtension->SSRegistryEnable) { // // initialize DPC // KeInitializeDpc(&deviceExtension->DeferredProcCall, DpcRoutine, deviceObject); // // initialize the timer. // the DPC and the timer in conjunction, // monitor the state of the device to // selectively suspend the device. // KeInitializeTimerEx(&deviceExtension->Timer, NotificationTimer); // // Initialize the NoDpcWorkItemPendingEvent to signaled state. // This event is cleared when a Dpc is fired and signaled // on completion of the work-item. // KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent, NotificationEvent, TRUE); // // Initialize the NoIdleReqPendEvent to ensure that the idle request // is indeed complete before we unload the drivers. // KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent, NotificationEvent, TRUE); } } // // Clear the DO_DEVICE_INITIALIZING flag. // Note: Do not clear this flag until the driver has set the // device power state and the power DO flags. // deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; MobiUsb_DbgPrint(3, ("file mobiusb: MobiUsb_AddDevice - ends\n")); return ntStatus; }
NTSTATUS NTAPI AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo) { NTSTATUS Status = STATUS_UNSUCCESSFUL; PDEVICE_OBJECT Fdo; ULONG UsbDeviceNumber = 0; WCHAR CharDeviceName[64]; WCHAR CharSymLinkName[64]; UNICODE_STRING DeviceName; UNICODE_STRING SymLinkName; UNICODE_STRING InterfaceSymLinkName; ULONG BytesRead; PCI_COMMON_CONFIG PciConfig; PFDO_DEVICE_EXTENSION FdoDeviceExtension; DPRINT1("Ehci: AddDevice\n"); /* Create the FDO with next available number */ while (TRUE) { /* FIXME: Use safe string sprintf*/ /* RtlStringCchPrintfW(CharDeviceName, 64, L"USBFDO-%d", UsbDeviceNumber); */ swprintf(CharDeviceName, L"\\Device\\USBFDO-%d", UsbDeviceNumber); RtlInitUnicodeString(&DeviceName, CharDeviceName); DPRINT("DeviceName %wZ\n", &DeviceName); Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_CONTROLLER, 0, FALSE, &Fdo); if (NT_SUCCESS(Status)) break; if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION)) { /* Try the next name */ UsbDeviceNumber++; continue; } /* Bail on any other error */ if (!NT_SUCCESS(Status)) { DPRINT1("UsbEhci: Failed to create %wZ, Status %x\n", &DeviceName, Status); return Status; } } swprintf(CharSymLinkName, L"\\Device\\HCD%d", UsbDeviceNumber); RtlInitUnicodeString(&SymLinkName, CharSymLinkName); Status = IoCreateSymbolicLink(&SymLinkName, &DeviceName); if (!NT_SUCCESS(Status)) { DPRINT1("Warning: Unable to create symbolic link for ehci host controller!\n"); } FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) Fdo->DeviceExtension; RtlZeroMemory(FdoDeviceExtension, sizeof(PFDO_DEVICE_EXTENSION)); KeInitializeTimerEx(&FdoDeviceExtension->UpdateTimer, SynchronizationTimer); FdoDeviceExtension->Common.IsFdo = TRUE; FdoDeviceExtension->DeviceObject = Fdo; FdoDeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo); if (FdoDeviceExtension->LowerDevice == NULL) { DPRINT1("UsbEhci: Failed to attach to device stack!\n"); IoDeleteSymbolicLink(&SymLinkName); IoDeleteDevice(Fdo); return STATUS_NO_SUCH_DEVICE; } Fdo->Flags |= DO_BUFFERED_IO;// | DO_POWER_PAGABLE; ASSERT(FdoDeviceExtension->LowerDevice == Pdo); /* Get the EHCI Device ID and Vendor ID */ Status = GetBusInterface(FdoDeviceExtension->LowerDevice, &FdoDeviceExtension->BusInterface); if (!NT_SUCCESS(Status)) { DPRINT1("GetBusInterface() failed with %x\n", Status); IoDetachDevice(FdoDeviceExtension->LowerDevice); IoDeleteSymbolicLink(&SymLinkName); IoDeleteDevice(Fdo); return Status; } BytesRead = (*FdoDeviceExtension->BusInterface.GetBusData)( FdoDeviceExtension->BusInterface.Context, PCI_WHICHSPACE_CONFIG, &PciConfig, 0, PCI_COMMON_HDR_LENGTH); if (BytesRead != PCI_COMMON_HDR_LENGTH) { DPRINT1("GetBusData failed!\n"); IoDetachDevice(FdoDeviceExtension->LowerDevice); IoDeleteSymbolicLink(&SymLinkName); IoDeleteDevice(Fdo); return STATUS_UNSUCCESSFUL; } if (PciConfig.Command & PCI_ENABLE_IO_SPACE) DPRINT("PCI_ENABLE_IO_SPACE\n"); if (PciConfig.Command & PCI_ENABLE_MEMORY_SPACE) DPRINT("PCI_ENABLE_MEMORY_SPACE\n"); if (PciConfig.Command & PCI_ENABLE_BUS_MASTER) DPRINT("PCI_ENABLE_BUS_MASTER\n"); DPRINT("BaseAddress[0] %x\n", PciConfig.u.type0.BaseAddresses[0]); DPRINT1("Vendor %x\n", PciConfig.VendorID); DPRINT1("Device %x\n", PciConfig.DeviceID); FdoDeviceExtension->VendorId = PciConfig.VendorID; FdoDeviceExtension->DeviceId = PciConfig.DeviceID; FdoDeviceExtension->DeviceState = DEVICEINTIALIZED; Status = IoRegisterDeviceInterface(Pdo, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL, &InterfaceSymLinkName); if (!NT_SUCCESS(Status)) { DPRINT1("Unable to register device interface!\n"); return Status; } else { Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE); DPRINT1("SetInterfaceState %x\n", Status); if (!NT_SUCCESS(Status)) return Status; } Fdo->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; }
RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser) { *ppTimer = NULL; /* * Validate flags. */ if (!RTTIMER_FLAGS_ARE_VALID(fFlags)) return VERR_INVALID_PARAMETER; if ( (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL && !RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK))) return VERR_CPU_NOT_FOUND; /* * Allocate the timer handler. */ RTCPUID cSubTimers = 1; if ((fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL) { cSubTimers = RTMpGetMaxCpuId() + 1; Assert(cSubTimers <= RTCPUSET_MAX_CPUS); /* On Windows we have a 1:1 relationship between cpuid and set index. */ } PRTTIMER pTimer = (PRTTIMER)RTMemAllocZ(RT_OFFSETOF(RTTIMER, aSubTimers[cSubTimers])); if (!pTimer) return VERR_NO_MEMORY; /* * Initialize it. */ pTimer->u32Magic = RTTIMER_MAGIC; pTimer->fSuspended = true; pTimer->fSpecificCpu = (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL; pTimer->fOmniTimer = (fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL; pTimer->idCpu = pTimer->fSpecificCpu ? RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK) : NIL_RTCPUID; pTimer->cSubTimers = cSubTimers; pTimer->pfnTimer = pfnTimer; pTimer->pvUser = pvUser; pTimer->u64NanoInterval = u64NanoInterval; KeInitializeTimerEx(&pTimer->NtTimer, SynchronizationTimer); if (pTimer->fOmniTimer) { /* * Initialize the per-cpu "sub-timers", select the first online cpu * to be the master. * ASSUMES that no cpus will ever go offline. */ pTimer->idCpu = NIL_RTCPUID; for (unsigned iCpu = 0; iCpu < cSubTimers; iCpu++) { pTimer->aSubTimers[iCpu].iTick = 0; pTimer->aSubTimers[iCpu].pParent = pTimer; if ( pTimer->idCpu == NIL_RTCPUID && RTMpIsCpuOnline(RTMpCpuIdFromSetIndex(iCpu))) { pTimer->idCpu = RTMpCpuIdFromSetIndex(iCpu); KeInitializeDpc(&pTimer->aSubTimers[iCpu].NtDpc, rtTimerNtOmniMasterCallback, &pTimer->aSubTimers[iCpu]); } else KeInitializeDpc(&pTimer->aSubTimers[iCpu].NtDpc, rtTimerNtOmniSlaveCallback, &pTimer->aSubTimers[iCpu]); KeSetImportanceDpc(&pTimer->aSubTimers[iCpu].NtDpc, HighImportance); KeSetTargetProcessorDpc(&pTimer->aSubTimers[iCpu].NtDpc, (int)RTMpCpuIdFromSetIndex(iCpu)); } Assert(pTimer->idCpu != NIL_RTCPUID); } else { /* * Initialize the first "sub-timer", target the DPC on a specific processor * if requested to do so. */ pTimer->aSubTimers[0].iTick = 0; pTimer->aSubTimers[0].pParent = pTimer; KeInitializeDpc(&pTimer->aSubTimers[0].NtDpc, rtTimerNtSimpleCallback, pTimer); KeSetImportanceDpc(&pTimer->aSubTimers[0].NtDpc, HighImportance); if (pTimer->fSpecificCpu) KeSetTargetProcessorDpc(&pTimer->aSubTimers[0].NtDpc, (int)pTimer->idCpu); } *ppTimer = pTimer; return VINF_SUCCESS; }
// AddDevice, called when an instance of our supported hardware is found // Returning anything other than NT_SUCCESS here causes the device to fail // to initialise NTSTATUS NTAPI FreeBT_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject) { NTSTATUS ntStatus; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension; POWER_STATE state; KIRQL oldIrql; UNICODE_STRING uniDeviceName; WCHAR wszDeviceName[255]={0}; UNICODE_STRING uniDosDeviceName; LONG instanceNumber=0; FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Entered\n")); deviceObject = NULL; swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber); RtlInitUnicodeString(&uniDeviceName, wszDeviceName); ntStatus=STATUS_OBJECT_NAME_COLLISION; while (instanceNumber<99 && !NT_SUCCESS(ntStatus)) { swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber); uniDeviceName.Length = wcslen(wszDeviceName) * sizeof(WCHAR); FreeBT_DbgPrint(1, ("FBTUSB: Attempting to create device %ws\n", wszDeviceName)); ntStatus = IoCreateDevice( DriverObject, // our driver object sizeof(DEVICE_EXTENSION), // extension size for us &uniDeviceName, // name for this device FILE_DEVICE_UNKNOWN, 0, // device characteristics FALSE, // Not exclusive &deviceObject); // Our device object if (!NT_SUCCESS(ntStatus)) instanceNumber++; } if (!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: Failed to create device object\n")); return ntStatus; } FreeBT_DbgPrint(1, ("FBTUSB: Created device %ws\n", wszDeviceName)); deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; deviceExtension->FunctionalDeviceObject = deviceObject; deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; deviceObject->Flags |= DO_DIRECT_IO; swprintf(deviceExtension->wszDosDeviceName, L"\\DosDevices\\FbtUsb%02d", instanceNumber); RtlInitUnicodeString(&uniDosDeviceName, deviceExtension->wszDosDeviceName); ntStatus=IoCreateSymbolicLink(&uniDosDeviceName, &uniDeviceName); if (!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: Failed to create symbolic link %ws to %ws, status=0x%08x\n", deviceExtension->wszDosDeviceName, wszDeviceName, ntStatus)); IoDeleteDevice(deviceObject); return ntStatus; } FreeBT_DbgPrint(1, ("FBTUSB: Created symbolic link %ws\n", deviceExtension->wszDosDeviceName)); KeInitializeSpinLock(&deviceExtension->DevStateLock); INITIALIZE_PNP_STATE(deviceExtension); deviceExtension->OpenHandleCount = 0; // Initialize the selective suspend variables KeInitializeSpinLock(&deviceExtension->IdleReqStateLock); deviceExtension->IdleReqPend = 0; deviceExtension->PendingIdleIrp = NULL; // Hold requests until the device is started deviceExtension->QueueState = HoldRequests; // Initialize the queue and the queue spin lock InitializeListHead(&deviceExtension->NewRequestsQueue); KeInitializeSpinLock(&deviceExtension->QueueLock); // Initialize the remove event to not-signaled. KeInitializeEvent(&deviceExtension->RemoveEvent, SynchronizationEvent, FALSE); // Initialize the stop event to signaled. // This event is signaled when the OutstandingIO becomes 1 KeInitializeEvent(&deviceExtension->StopEvent, SynchronizationEvent, TRUE); // OutstandingIo count biased to 1. // Transition to 0 during remove device means IO is finished. // Transition to 1 means the device can be stopped deviceExtension->OutStandingIO = 1; KeInitializeSpinLock(&deviceExtension->IOCountLock); #ifdef ENABLE_WMI // Delegating to WMILIB ntStatus = FreeBT_WmiRegistration(deviceExtension); if (!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WmiRegistration failed with %X\n", ntStatus)); IoDeleteDevice(deviceObject); IoDeleteSymbolicLink(&uniDosDeviceName); return ntStatus; } #endif // Set the flags as underlying PDO if (PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) { deviceObject->Flags |= DO_POWER_PAGABLE; } // Typically, the function driver for a device is its // power policy owner, although for some devices another // driver or system component may assume this role. // Set the initial power state of the device, if known, by calling // PoSetPowerState. deviceExtension->DevPower = PowerDeviceD0; deviceExtension->SysPower = PowerSystemWorking; state.DeviceState = PowerDeviceD0; PoSetPowerState(deviceObject, DevicePowerState, state); // attach our driver to device stack // The return value of IoAttachDeviceToDeviceStack is the top of the // attachment chain. This is where all the IRPs should be routed. deviceExtension->TopOfStackDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject); if (NULL == deviceExtension->TopOfStackDeviceObject) { #ifdef ENABLE_WMI FreeBT_WmiDeRegistration(deviceExtension); #endif IoDeleteDevice(deviceObject); IoDeleteSymbolicLink(&uniDosDeviceName); return STATUS_NO_SUCH_DEVICE; } // Register device interfaces ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject, &GUID_CLASS_FREEBT_USB, NULL, &deviceExtension->InterfaceName); if (!NT_SUCCESS(ntStatus)) { #ifdef ENABLE_WMI FreeBT_WmiDeRegistration(deviceExtension); #endif IoDetachDevice(deviceExtension->TopOfStackDeviceObject); IoDeleteDevice(deviceObject); IoDeleteSymbolicLink(&uniDosDeviceName); return ntStatus; } if (IoIsWdmVersionAvailable(1, 0x20)) { deviceExtension->WdmVersion = WinXpOrBetter; } else if (IoIsWdmVersionAvailable(1, 0x10)) { deviceExtension->WdmVersion = Win2kOrBetter; } else if (IoIsWdmVersionAvailable(1, 0x5)) { deviceExtension->WdmVersion = WinMeOrBetter; } else if (IoIsWdmVersionAvailable(1, 0x0)) { deviceExtension->WdmVersion = Win98OrBetter; } deviceExtension->SSRegistryEnable = 0; deviceExtension->SSEnable = 0; // WinXP only: check the registry flag indicating whether // the device should selectively suspend when idle if (WinXpOrBetter == deviceExtension->WdmVersion) { FreeBT_GetRegistryDword(FREEBT_REGISTRY_PARAMETERS_PATH, L"BulkUsbEnable", (PULONG)(&deviceExtension->SSRegistryEnable)); if (deviceExtension->SSRegistryEnable) { // initialize DPC KeInitializeDpc(&deviceExtension->DeferredProcCall, DpcRoutine, deviceObject); // initialize the timer. // the DPC and the timer in conjunction, // monitor the state of the device to // selectively suspend the device. KeInitializeTimerEx(&deviceExtension->Timer, NotificationTimer); // Initialize the NoDpcWorkItemPendingEvent to signaled state. // This event is cleared when a Dpc is fired and signaled // on completion of the work-item. KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent, NotificationEvent, TRUE); // Initialize the NoIdleReqPendEvent to ensure that the idle request // is indeed complete before we unload the drivers. KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent, NotificationEvent, TRUE); } } // Initialize the NoIdleReqPendEvent to ensure that the idle request // is indeed complete before we unload the drivers. KeInitializeEvent(&deviceExtension->DelayEvent, NotificationEvent, FALSE); // Clear the DO_DEVICE_INITIALIZING flag. // Note: Do not clear this flag until the driver has set the // device power state and the power DO flags. deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; InterlockedIncrement(&instanceNumber); FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Leaving\n")); return ntStatus; }
VOID TestThread(IN PVOID Context) { KIRQL currentIrql, oldIrql; NTSTATUS status = STATUS_SUCCESS; PKDPC pDpc; PKTIMER pTimer; LARGE_INTEGER timeout, maxTimeout; timeout.QuadPart = -12000 * 10000; // 12 sec maxTimeout.QuadPart = -20000 * 10000; DbgPrint("\nTEST THREAD started\n"); // Initialize timer pTimer = (PKTIMER) ExAllocatePool(NonPagedPool, sizeof(KTIMER)); KeInitializeTimerEx(pTimer, SynchronizationTimer); KeSetTimer(pTimer, timeout, NULL); pDpc = (PKDPC) ExAllocatePool(NonPagedPool,sizeof(KDPC)); KeInitializeDpc(pDpc, SetWriteEvent, NULL); // wait for timer KeWaitForSingleObject( pTimer, Executive, KernelMode, FALSE, &maxTimeout); DbgPrint("TestThread: set flush event\n"); KeRaiseIrql(PROFILE_LEVEL, &oldIrql); currentIrql = KeGetCurrentIrql(); //WriteToBuffer(pRb, "some", 4); DbgPrint("Current irql %d\n", currentIrql); /* KeWaitForSingleObject( pTimer, Executive, KernelMode, FALSE, &maxTimeout); */ if (currentIrql == PASSIVE_LEVEL) { KeSetEvent(&FlushEvent, 0, FALSE); } else { KeInsertQueueDpc(pDpc, NULL, NULL); } KeLowerIrql(&oldIrql); PsTerminateSystemThread(status); }
//============================================================================= NTSTATUS CMiniportWaveCyclicStream::Init( IN PCMiniportWaveCyclic Miniport_, IN ULONG Pin_, IN BOOLEAN Capture_, IN PKSDATAFORMAT DataFormat_ ) /*++ Routine Description: Initializes the stream object. Allocate a DMA buffer, timer and DPC Arguments: Miniport_ - Pin_ - Capture_ - DataFormat - DmaChannel_ - Return Value: NT status code. --*/ { PAGED_CODE(); ASSERT(Miniport_); ASSERT(DataFormat_); NTSTATUS ntStatus = STATUS_SUCCESS; PWAVEFORMATEX pWfx; pWfx = GetWaveFormatEx(DataFormat_); if (!pWfx) { DPF(D_TERSE, ("Invalid DataFormat param in NewStream")); ntStatus = STATUS_INVALID_PARAMETER; } if (NT_SUCCESS(ntStatus)) { m_pMiniport = Miniport_; m_ulPin = Pin_; m_fCapture = Capture_; m_usBlockAlign = pWfx->nBlockAlign; m_fFormat16Bit = (pWfx->wBitsPerSample == 16); m_ksState = KSSTATE_STOP; m_ulDmaPosition = 0; m_ullElapsedTimeCarryForward = 0; m_ulByteDisplacementCarryForward = 0; m_fDmaActive = FALSE; m_pDpc = NULL; m_pTimer = NULL; m_pvDmaBuffer = NULL; // If this is not the capture stream, create the output file. if (!m_fCapture) { if (NT_SUCCESS(ntStatus)) { ntStatus = m_SaveData.Initialize(); } } } // Allocate DMA buffer for this stream. if (NT_SUCCESS(ntStatus)) { ntStatus = AllocateBuffer(m_pMiniport->m_MaxDmaBufferSize, NULL); } // Set sample frequency. Note that m_SampleRateSync access should // be syncronized. if (NT_SUCCESS(ntStatus)) { ntStatus = KeWaitForSingleObject(&m_pMiniport->m_SampleRateSync, Executive, KernelMode, FALSE, NULL); if (STATUS_SUCCESS == ntStatus) { m_pMiniport->m_SamplingFrequency = pWfx->nSamplesPerSec; KeReleaseMutex(&m_pMiniport->m_SampleRateSync, FALSE); } else { DPF(D_TERSE, ("[SamplingFrequency Sync failed: %08X]", ntStatus)); } } if (NT_SUCCESS(ntStatus)) { ntStatus = SetFormat(DataFormat_); } if (NT_SUCCESS(ntStatus)) { m_pDpc = (PRKDPC) ExAllocatePoolWithTag(NonPagedPool, sizeof(KDPC), MSVAD_POOLTAG); if (!m_pDpc) { DPF(D_TERSE, ("[Could not allocate memory for DPC]")); ntStatus = STATUS_INSUFFICIENT_RESOURCES; } } if (NT_SUCCESS(ntStatus)) { m_pTimer = (PKTIMER) ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), MSVAD_POOLTAG); if (!m_pTimer) { DPF(D_TERSE, ("[Could not allocate memory for Timer]")); ntStatus = STATUS_INSUFFICIENT_RESOURCES; } } if (NT_SUCCESS(ntStatus)) { KeInitializeDpc(m_pDpc, TimerNotify, m_pMiniport); KeInitializeTimerEx(m_pTimer, NotificationTimer); } return ntStatus; } // Init