Example #1
0
VOID CMiniportWaveRTStream::UpdatePosition
(
    _In_ LARGE_INTEGER ilQPC
)
{
    // Convert ticks to 100ns units.
    LONGLONG  hnsCurrentTime = KSCONVERT_PERFORMANCE_TIME(m_ullPerformanceCounterFrequency.QuadPart, ilQPC);
    
    // Calculate the time elapsed since the last call to GetPosition() or since the
    // DMA engine started.  Note that the division by 10000 to convert to milliseconds
    // may cause us to lose some of the time, so we will carry the remainder forward 
    // to the next GetPosition() call.
    //
    ULONG TimeElapsedInMS = (ULONG)(hnsCurrentTime - m_ullDmaTimeStamp + m_hnsElapsedTimeCarryForward)/10000;
    
    // Carry forward the remainder of this division so we don't fall behind with our position too much.
    //
    m_hnsElapsedTimeCarryForward = (hnsCurrentTime - m_ullDmaTimeStamp + m_hnsElapsedTimeCarryForward) % 10000;
    
    // Calculate how many bytes in the DMA buffer would have been processed in the elapsed
    // time.  Note that the division by 1000 to convert to milliseconds may cause us to 
    // lose some bytes, so we will carry the remainder forward to the next GetPosition() call.
    //
    // need to divide by 1000 because m_ulDmaMovementRate is average bytes per sec.
    ULONG ByteDisplacement = (m_ulDmaMovementRate * TimeElapsedInMS) / 1000;
    
    if (m_bCapture)
    {
        // Write sine wave to buffer.
        ByteDisplacement %= m_ulDmaBufferSize; // just for not crashing when debugging the driver.
        WriteBytes(ByteDisplacement);
    }
    else if (!g_DoNotCreateDataFiles)
    {
        //
        // Read from buffer and write to a file.
        //
        ByteDisplacement %= m_ulDmaBufferSize; // just for not crashing when debugging the driver.
        ReadBytes(ByteDisplacement);
    }
    
    // Increment the DMA position by the number of bytes displaced since the last
    // call to GetPosition() and ensure we properly wrap at buffer length.
    //
    m_ullPlayPosition = m_ullWritePosition =
        (m_ullWritePosition + ByteDisplacement) % m_ulDmaBufferSize;
    
    // m_ullDmaTimeStamp is updated in both GetPostion and GetLinearPosition calls
    // so m_ullLinearPosition needs to be updated accordingly here
    //
    m_ullLinearPosition += ByteDisplacement;
    
    // Update the DMA time stamp for the next call to GetPosition()
    //
    m_ullDmaTimeStamp = hnsCurrentTime;
}
Example #2
0
HRESULT STDMETHODCALLTYPE IDirect3DDevice9_EndScene_Hook(IDirect3DDevice9* This) {
	static unsigned count = 0;
	auto ticks = []() {
		LARGE_INTEGER value;
		QueryPerformanceCounter(&value);
		return KSCONVERT_PERFORMANCE_TIME(frequency, value);
	}();
	static auto start = [This, &ticks]() {
		IDirect3DSurface9* renderTarget;
		IDirect3DDevice9_GetRenderTarget(This, 0, &renderTarget);
		IDirect3DSurface9_GetDesc(renderTarget, &desc);
		IDirect3DSurface9_Release(renderTarget);

		// quick hack, first 'ticks - start' is 1.
		return ticks++;
	}();
	fps = static_cast<unsigned>(static_cast<ULONGLONG>(++count) * NANOSECONDS / (ticks - start));

	FramePtr frame = Frame;
	if (frame) {
		IDirect3DSurface9* offsecreen;
		check(TEXT("CreateOffscreenPlainSurface"), IDirect3DDevice9_CreateOffscreenPlainSurface(This, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offsecreen, nullptr));
		{
			IDirect3DSurface9* target;
			check(TEXT("GetRenderTarget"), IDirect3DDevice9_GetRenderTarget(This, 0, &target));
#if 0
			if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) {
				IDirect3DSurface9* resolved;
				check(TEXT("CreateRenderTarget"), IDirect3DDevice9_CreateRenderTarget(This, desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, false, &resolved, nullptr));
				check(TEXT("StretchRect"), IDirect3DDevice9_StretchRect(This, target, nullptr, resolved, nullptr, D3DTEXF_NONE));
				IDirect3DSurface9_Release(target);
				target = resolved;
			}
#endif
			check(TEXT("GetRenderTargetData"), IDirect3DDevice9_GetRenderTargetData(This, target, offsecreen));
			IDirect3DSurface9_Release(target);
		}
		frame(ticks, offsecreen);
		IDirect3DSurface9_Release(offsecreen);
	}
	return IDirect3DDevice9_EndScene_Orig(This);
}
Example #3
0
ULONGLONG
CHardwareSimulation::
ConvertQPCtoTimeStamp(
    _In_opt_    PLARGE_INTEGER pQpcTime
)
/*++

Routine Description:

    Get the QPC measured in 100ns units.

Arguments:

    pQpcTime - 
        An optional time value to convert.  If NULL, use the current QPC.

Return Value:

    ULONLONG -
        The time in 100ns increments.

--*/
{
    PAGED_CODE();

    LARGE_INTEGER qpcTime = {0};
    LARGE_INTEGER qpcFrequency;

    qpcTime = KeQueryPerformanceCounter(&qpcFrequency);

    if( pQpcTime )
    {
        qpcTime = *pQpcTime;
    }

    return KSCONVERT_PERFORMANCE_TIME( qpcFrequency.QuadPart, qpcTime );
}
Example #4
0
NTSTATUS CMiniportWaveRTStream::SetState
(
    _In_    KSSTATE State_
)
{
    PAGED_CODE();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            break;
    }

    m_KsState = State_;

#ifdef SYSVAD_BTH_BYPASS
Done:
#endif  // SYSVAD_BTH_BYPASS
    return ntStatus;
}