Beispiel #1
0
NTSTATUS CMiniportWaveRTStream::GetPosition
(
    _Out_   KSAUDIO_POSITION    *Position_
)
{
    NTSTATUS ntStatus;

#ifdef SYSVAD_BTH_BYPASS
    if (m_ScoOpen)
    {
        ntStatus = GetScoStreamNtStatus();
        IF_FAILED_JUMP(ntStatus, Done);
    }
#endif // SYSVAD_BTH_BYPASS

    if (m_KsState == KSSTATE_RUN)
    {
        //
        // Get the current time and update position.
        //
        LARGE_INTEGER ilQPC = KeQueryPerformanceCounter(NULL);
        UpdatePosition(ilQPC);
    }

    Position_->PlayOffset = m_ullPlayPosition;
    Position_->WriteOffset = m_ullWritePosition;

    ntStatus = STATUS_SUCCESS;
    
#ifdef SYSVAD_BTH_BYPASS
Done:
#endif // SYSVAD_BTH_BYPASS
    return ntStatus;
}
Beispiel #2
0
/*
 * @implemented
 */
VOID APIENTRY
EngQueryPerformanceCounter(LONGLONG *Count)
{
  LARGE_INTEGER PerfCount;

  PerfCount = KeQueryPerformanceCounter(NULL);
  *Count = PerfCount.QuadPart;
}
Beispiel #3
0
/*
 * @implemented
 */
VOID APIENTRY
EngQueryPerformanceFrequency(LONGLONG *Frequency)
{
  LARGE_INTEGER Freq;

  KeQueryPerformanceCounter(&Freq);
  *Frequency = Freq.QuadPart;
}
Beispiel #4
0
uint32_t 
otPlatAlarmGetNow()
{
    // Return number of 'ticks'
    LARGE_INTEGER PerformanceCounter = KeQueryPerformanceCounter(NULL);

    // Multiply by 1000 ms/sec and divide by 'ticks'/sec to get ms
    return (uint32_t)(PerformanceCounter.QuadPart * 1000 / FilterPerformanceFrequency.QuadPart);
}
Beispiel #5
0
void DtraceGetSystemHertz()
{
	LARGE_INTEGER Frequency;
    	
	Hertz = 0;
	KeQueryPerformanceCounter(&Frequency);
	if (Frequency.QuadPart != 0)
		Hertz = Frequency.QuadPart;
}
Beispiel #6
0
//----- (08001203) --------------------------------------------------------
NTSTATUS 
DMCreateClose(
	PDEVICE_OBJECT	DeviceObject, 
	PIRP			Irp
	)
{
	PIO_STACK_LOCATION		IrpStack;
	NTSTATUS				status;
	LARGE_INTEGER			PerfCount;
	LARGE_INTEGER			CurrentTime;
	ULONG					seq;
	PDEVICE_ENTRY			DevEntry;

	IrpStack = IoGetCurrentIrpStackLocation(Irp);

	if ( DeviceObject == g_pDeviceObject )
	{
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = 0;

		g_bGUIActive = (IrpStack->MajorFunction == IRP_MJ_CREATE);

		IofCompleteRequest(Irp, 0);
		status = STATUS_SUCCESS;
	}
	else
	{
		if ( g_bUsePerfCounter )
		{
			PerfCount = KeQueryPerformanceCounter(NULL);
			CurrentTime.QuadPart = 0;
		}
		else
		{
			KeQuerySystemTime(&CurrentTime);
			PerfCount.QuadPart = 0;
		}

		seq = InterlockedIncrement(&Sequence);

		DevEntry = LookupEntryByDevObj(DeviceObject);
		if ( DevEntry )
		{
			LogRecord(
				seq,
				&CurrentTime,
				DevEntry->DiskNumber,
				"%s",
				IrpStack->MajorFunction == IRP_MJ_CLOSE ? "IRP_MJ_CLOSE" : "IRP_MJ_CREATE");
		}

		status = DefaultDispatch(DeviceObject, Irp, seq, g_bUsePerfCounter, &PerfCount);
	}

	return status;
}
Beispiel #7
0
ULONG Random(ULONG Range)
{
    ULONG ret = 0;
    LARGE_INTEGER temp = KeQueryPerformanceCounter(NULL);
    ULONG Seed = temp.u.LowPart;

    ret = RtlRandom(&Seed);
    ret %= Range;

    return ret;
}
Beispiel #8
0
VOID
NTHALAPI
KeStallExecutionProcessor(ULONG USec)
{
    LARGE_INTEGER Freq, Start = KeQueryPerformanceCounter(&Freq), End;
    LARGE_INTEGER Timebase, Remainder;
    Timebase.QuadPart = 1000000;
    Freq.QuadPart *= USec;
    End = RtlLargeIntegerDivide(Freq, Timebase, &Remainder);
    End.QuadPart += Start.QuadPart;
    while(End.QuadPart > __rdtsc());
}
Beispiel #9
0
/*!
 *  \see http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
 */
NTSTATUS
NTAPI
KsecGatherEntropyData(
    PKSEC_ENTROPY_DATA EntropyData)
{
    MD4_CTX Md4Context;
    PTEB Teb;
    PPEB Peb;
    PWSTR String;
    SIZE_T ReturnLength;
    NTSTATUS Status;

    /* Query some generic values */
    EntropyData->CurrentProcessId = PsGetCurrentProcessId();
    EntropyData->CurrentThreadId = PsGetCurrentThreadId();
    KeQueryTickCount(&EntropyData->TickCount);
    KeQuerySystemTime(&EntropyData->SystemTime);
    EntropyData->PerformanceCounter = KeQueryPerformanceCounter(
                                            &EntropyData->PerformanceFrequency);

    /* Check if we have a TEB/PEB for the process environment */
    Teb = PsGetCurrentThread()->Tcb.Teb;
    if (Teb != NULL)
    {
        Peb = Teb->ProcessEnvironmentBlock;

        /* Initialize the MD4 context */
        MD4Init(&Md4Context);
        _SEH2_TRY
        {
            /* Get the end of the environment */
            String = Peb->ProcessParameters->Environment;
            while (*String)
            {
                String += wcslen(String) + 1;
            }

            /* Update the MD4 context from the environment data */
            MD4Update(&Md4Context,
                      (PUCHAR)Peb->ProcessParameters->Environment,
                      (ULONG)((PUCHAR)String - (PUCHAR)Peb->ProcessParameters->Environment));
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Simply ignore the exception */
        }
        _SEH2_END;

        /* Finalize and copy the MD4 hash */
        MD4Final(&Md4Context);
        RtlCopyMemory(&EntropyData->EnvironmentHash, Md4Context.digest, 16);
    }
Beispiel #10
0
VOID GenerateRandomMacAddress(PMAC_ADDRESS Address)
{
    // Vendor "C0:13:37"
    Address->Vendor0 = 0xC0;
    Address->Vendor1 = 0x13;
    Address->Vendor2 = 0x37;

    ULONG seed = KeQueryPerformanceCounter(NULL).LowPart;
    
    Address->Nic0 = RtlRandomEx(&seed) % 0xFF;
    Address->Nic1 = RtlRandomEx(&seed) % 0xFF;
    Address->Nic2 = RtlRandomEx(&seed) % 0xFF;
}
Beispiel #11
0
static VOID
ExpGetRandomUuidSequence(PULONG Sequence)
{
    LARGE_INTEGER Counter;
    LARGE_INTEGER Frequency;
    ULONG Value;

    Counter = KeQueryPerformanceCounter(&Frequency);
    Value = Counter.u.LowPart ^ Counter.u.HighPart;

    *Sequence = *Sequence ^ Value;

    DPRINT("Sequence %lx\n", *Sequence);
}
Beispiel #12
0
/*
 *	TIME FUNCTIONS (COPIED FROM DUMMYNET)
 */
void
do_gettimeofday(struct timeval *tv)
{
	static LARGE_INTEGER prevtime; //system time in 100-nsec resolution
	static LARGE_INTEGER prevcount; //RTC counter value
	static LARGE_INTEGER freq; //frequency

	LARGE_INTEGER currtime;
	LARGE_INTEGER currcount;
	if (prevtime.QuadPart == 0) { //first time we ask for system time
		KeQuerySystemTime(&prevtime);
		prevcount = KeQueryPerformanceCounter(&freq);
		currtime.QuadPart = prevtime.QuadPart;
	} else {
		KeQuerySystemTime(&currtime);
		currcount = KeQueryPerformanceCounter(&freq);
		if (currtime.QuadPart == prevtime.QuadPart) {
			//time has NOT changed, calculate time using ticks and DO NOT update
			LONGLONG difftime = 0; //difference in 100-nsec
			LONGLONG diffcount = 0; //clock count difference
			//printf("time has NOT changed\n");
			diffcount = currcount.QuadPart - prevcount.QuadPart;
			diffcount *= 10000000;
			difftime = diffcount / freq.QuadPart;
			currtime.QuadPart += difftime;
		} else {
			//time has changed, update and return SystemTime
			//printf("time has changed\n");
			prevtime.QuadPart = currtime.QuadPart;
			prevcount.QuadPart = currcount.QuadPart;
		}
	}
	currtime.QuadPart /= 10; //convert in usec
	tv->tv_sec = currtime.QuadPart / (LONGLONG)1000000;
	tv->tv_usec = currtime.QuadPart % (LONGLONG)1000000;
	//printf("sec %d usec %d\n",tv->tv_sec, tv->tv_usec);
}
static UINT64 _TicksToMiliseconds(UINT64 tickCount)
{
    UINT64 timeInMs = 0, timeInSeconds = 0, countsInLastSecond = 0;
    LARGE_INTEGER liFrequency = { 0 };

    KeQueryPerformanceCounter(&liFrequency);

    timeInSeconds = tickCount / liFrequency.QuadPart;
    timeInMs = timeInSeconds * 1000;

    countsInLastSecond = tickCount - (timeInSeconds * liFrequency.QuadPart);
    timeInMs += (countsInLastSecond * 1000 / liFrequency.QuadPart);

    return timeInMs;
}
Beispiel #14
0
/*----------------------------------------------------------------------------*/
int zrtp_add_system_state(zrtp_global_t* zrtp, MD_CTX *ctx)
{
    LARGE_INTEGER li1;
    LARGE_INTEGER li2;
    ULONG ul1;
    ULONG ul2;
    ULONGLONG ull;
    PKTHREAD thread;
    static int tsc_ok = 1;
	/* 
	 * WARNING! 
	 * Of course it's not a real size of entropy added to the context. It's very
	 * difficult to compute the size of real random data and estimate its quality.
	 * This value means: size of maximum possible random data which this function can provide.
	 */
	static int entropy_length = sizeof(LARGE_INTEGER)*2 + sizeof(PKTHREAD) +
								sizeof(ULONG)*2 + sizeof(LARGE_INTEGER)*2 + sizeof(ULONG)*2;

    li2 = KeQueryPerformanceCounter(&li1);
    MD_Update(ctx, &li1, sizeof(LARGE_INTEGER));
    MD_Update(ctx, &li2, sizeof(LARGE_INTEGER));

    ull = KeQueryInterruptTime();
    MD_Update(ctx, &ull, sizeof(ULONGLONG));

    thread = KeGetCurrentThread();
    MD_Update(ctx, &thread, sizeof(PKTHREAD));
    ul2 = KeQueryRuntimeThread(thread, &ul1);
    MD_Update(ctx, &ul1, sizeof(ULONG));
    MD_Update(ctx, &ul2, sizeof(ULONG));

    KeQuerySystemTime(&li1);
    MD_Update(ctx, &li1, sizeof(LARGE_INTEGER));

    KeQueryTickCount(&li1);
    MD_Update(ctx, &li1, sizeof(LARGE_INTEGER));

    if (tsc_ok) {
		__try {			
			ull = _RDTSC();
			MD_Update(ctx, &ull, sizeof(ULONGLONG));
		} __except(EXCEPTION_EXECUTE_HANDLER) {
			tsc_ok = 0;
		}
    }
    
    return entropy_length;
}
Beispiel #15
0
//----- (0800149E) --------------------------------------------------------
NTSTATUS 
DMReadWrite(
	PDEVICE_OBJECT	DeviceObject, 
	PIRP			Irp
	)
{
	PDEVICE_ENTRY		DevEntry;
	ULONG				SectorNum;
	ULONGLONG			ByteOffset;
	ULONGLONG			SectorOffset;
	PIO_STACK_LOCATION	IrpStack;
	NTSTATUS			status;
	LARGE_INTEGER		PerfCount;
	LARGE_INTEGER		CurrentTime;
	ULONG				seq;

	IrpStack = IoGetCurrentIrpStackLocation(Irp);
	if ( g_bUsePerfCounter )
	{
		PerfCount = KeQueryPerformanceCounter(NULL);
		CurrentTime.QuadPart = 0;
	}
	else
	{
		KeQuerySystemTime(&CurrentTime);
		PerfCount.QuadPart = 0;
	}

	seq = InterlockedIncrement(&Sequence);

	DevEntry = LookupEntryByDevObj(DeviceObject);
	if ( DevEntry )
	{
		SectorNum		= IrpStack->Parameters.Read.Length >> 9;
		ByteOffset		= IrpStack->Parameters.Read.ByteOffset.QuadPart;
		SectorOffset	= GetSectorOffset(ByteOffset, 512);

		LogRecord(
			seq,
			&CurrentTime,
			DevEntry->DiskNumber,
			"%s\t%I64d\t%d",
			IrpStack->MajorFunction == IRP_MJ_READ ? "IRP_MJ_READ" : "IRP_MJ_WRITE", SectorOffset, SectorNum);
	}

	return DefaultDispatch(DeviceObject, Irp, seq, g_bUsePerfCounter, &PerfCount);
}
Beispiel #16
0
// GetPerformanceCounter:
void GetPerformanceCounter(uint64* pPerfCounter, uint64* pFrequency)
{
    LARGE_INTEGER perfCounter;
    LARGE_INTEGER perfFreq;

    perfCounter = KeQueryPerformanceCounter(&perfFreq);

    if (NULL != pPerfCounter)
    {
        *pPerfCounter = (uint64)perfCounter.QuadPart;
    }

    if (NULL != pFrequency)
    {
        *pFrequency = (uint64)perfFreq.QuadPart;
    }
}
Beispiel #17
0
//----- (08002059) --------------------------------------------------------
NTSTATUS 
DMShutDownFlushBuffer(
	PDEVICE_OBJECT	DeviceObject, 
	PIRP			Irp
	)
{
	ULONG					seq;
	PIO_STACK_LOCATION		IrpStack;	
	LARGE_INTEGER			PerfCount;
	LARGE_INTEGER			CurrentTime;
	PDEVICE_ENTRY			DevEntry;

	IrpStack = IoGetCurrentIrpStackLocation(Irp);

	if ( g_bUsePerfCounter )
	{
		PerfCount = KeQueryPerformanceCounter(NULL);
		CurrentTime.QuadPart = 0;
	}
	else
	{
		KeQuerySystemTime(&CurrentTime);
		PerfCount.QuadPart = 0;
	}

	seq = InterlockedIncrement(&Sequence);

	DevEntry = LookupEntryByDevObj(DeviceObject);
	if ( DevEntry )
	{
		LogRecord(
			seq,
			&CurrentTime,
			DevEntry->DiskNumber,
			"%s",
			IrpStack->MajorFunction == IRP_MJ_SHUTDOWN ? "IRP_MJ_SHUTDOWN" : "IRP_MJ_FLUSH_BUFFERS");
	}

	return DefaultDispatch(DeviceObject, Irp, seq, g_bUsePerfCounter, &PerfCount);
}
Beispiel #18
0
void PPJoy_InitTimingValues (IN PDEVICE_OBJECT DeviceObject)
{
 PDEVICE_EXTENSION	DeviceExtension;
 LARGE_INTEGER		TickCount;

 PAGED_CODE();

 DeviceExtension= GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);

 if (DeviceExtension->Config.JoyType==IF_FMSBUDDYBOX)
 {
  PTIMING_FMSPPM	PPMTiming;
  PPPMBUDDYBOX		PPMParams;

  PPMTiming= (PTIMING_FMSPPM) DeviceExtension->Timing;
  PPMParams= &(DeviceExtension->Param.PPMBuddyBox);

  KeQueryPerformanceCounter(&TickCount);
  PPMParams->MaxPulseTicks.QuadPart= (TickCount.QuadPart*(PPMTiming->MaxPulseWidth/*us*/)/1000000);
  PPMParams->MinPulseTicks.QuadPart= (TickCount.QuadPart*(PPMTiming->MinPulseWidth/*us*/)/1000000);
  PPMParams->MinSyncTicks.QuadPart= (TickCount.QuadPart*(PPMTiming->MinSyncWidth/*us*/)/1000000);
 }
}
Beispiel #19
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 );
}
Beispiel #20
0
void rnd_reseed_now()
{
	seed_data seed;

	KeQuerySystemTime(&seed.seed20);
	
	seed.seed1  = PsGetCurrentProcess();
	seed.seed2  = PsGetCurrentProcessId();
	seed.seed3  = KeGetCurrentThread();
	seed.seed4  = PsGetCurrentThreadId();
	seed.seed5  = KeGetCurrentProcessorNumber();
	seed.seed6  = KeQueryInterruptTime();
	seed.seed10 = KeQueryPerformanceCounter(NULL);
	seed.seed11 = __rdtsc();
	seed.seed12 = ExGetPreviousMode();	
	seed.seed14 = IoGetTopLevelIrp();
	seed.seed15 = MmQuerySystemSize();
	seed.seed24 = KeGetCurrentIrql();
	
	if (KeGetCurrentIrql() == PASSIVE_LEVEL) {
		seed.seed7  = KeQueryPriorityThread(seed.seed3);
		seed.seed17 = ExUuidCreate(&seed.seed18);
		seed.seed19 = RtlRandom(&seed.seed8);
	}
	if (KeGetCurrentIrql() <= APC_LEVEL) {
		seed.seed13 = IoGetInitialStack();
		seed.seed16 = PsGetProcessExitTime();
		IoGetStackLimits(&seed.seed22, &seed.seed23);
	}	
	KeQueryTickCount(&seed.seed21);
	
	rnd_add_buff(&seed, sizeof(seed));
	
	/* Prevent leaks */	
	zeroauto(&seed, sizeof(seed));
}
Beispiel #21
0
NTSTATUS
AnajoystPoll(
    IN  PDEVICE_OBJECT pDO,
    IN  PIRP pIrp
)
/*++

Routine Description:

    Polls the device for position and button information. The polling method
    (analog, digital, enhanced) is selected by the CurrentDeviceMode variable
    in the device extension.

    Only enhanced digital allowed.  If other modes are necessary, cut and paste
    (and test!) the code from file analog3p.c

Arguments:

    pDO     -- pointer to the device object

    pIrp    -- pointer to the IRP to process
               if successful, data is put into the pIrp


Return Value:

    STATUS_SUCCESS   -- if the poll succeeded,
    STATUS_TIMEOUT   -- if the poll failed

--*/
{
    NTSTATUS Status;
    PJOY_DD_INPUT_DATA pInput;

    pInput  = (PJOY_DD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;

    Status = STATUS_TIMEOUT;
    pIrp->IoStatus.Status = Status;


    if (pInput != NULL)
    {
        pInput->Unplugged = TRUE; // until proven otherwise
    }


    if (KeQueryPerformanceCounter(NULL).QuadPart < liLastPoll.QuadPart + nMinTicksBetweenPolls) {
        // Don't poll too frequently, instead return last good packet
        JoyStatistics.PolledTooSoon++;
        if (bLastGoodPacket) {
            RtlCopyMemory (pInput, &jjLastGoodPacket, sizeof (JOY_DD_INPUT_DATA));
            Status = STATUS_SUCCESS;
        }
        else {
            // no last packet, too soon to poll, nothing we can do
            Status = STATUS_TIMEOUT;
        }
    }
    else {
        // do the analog poll
        liLastPoll = KeQueryPerformanceCounter (NULL);
        ++JoyStatistics.Polls;
        Status = AnajoystAnalogPoll(pDO, pIrp);
        if (Status != STATUS_SUCCESS) ++JoyStatistics.Timeouts;
    }

    pIrp->IoStatus.Status = Status;
    return Status;
}
Beispiel #22
0
NTSTATUS
DriverEntry(
    IN  PDRIVER_OBJECT  pDriverObject,
    IN  PUNICODE_STRING RegistryPathName
)
/*++
Routine Description:
    This routine is called at system initialization time to initialize
    this driver.

Arguments:
    DriverObject    - Supplies the driver object.
    RegistryPath    - Supplies the registry path for this driver.

Return Value:
    STATUS_SUCCESS
    STATUS_DEVICE_CONFIGURATION_ERROR - Wrong number of axi in the registry
    or error status from NT itself

--*/
{
    NTSTATUS Status;
    PDEVICE_OBJECT pJoyDevice0;
    PDEVICE_OBJECT pJoyDevice1;
    DWORD NumberOfAxes;
    BOOL  bTwoSticks;
    DWORD DeviceAddress;

    PJOY_EXTENSION pext0, pext1;


    //DbgBreakPoint();
    JoyStatistics.Version = ANAJOYST_VERSION;
    DebugTrace(("Anajoyst %d", JoyStatistics.Version));

    // Read registry parameters.  These parameters are set up by the driver
    // installation program and can be modified by the control panel applets.

    // Number of axes
    Status = AnajoystReadRegistryParameterDWORD(
                 RegistryPathName,
                 JOY_DD_NAXES_U,
                 &NumberOfAxes
             );
    DebugTrace(("Number of axes returned from registry: %d", NumberOfAxes));
    if (!NT_SUCCESS(Status))
    {
        AnajoystUnload(pDriverObject);
        return Status;
    }
    if (( NumberOfAxes < 2) || (NumberOfAxes > 4))
    {
        AnajoystUnload(pDriverObject);
        Status = STATUS_DEVICE_CONFIGURATION_ERROR;
        return Status;
    }

    // Device address (usually 0x201)
    Status = AnajoystReadRegistryParameterDWORD(
                 RegistryPathName,
                 JOY_DD_DEVICE_ADDRESS_U,
                 &DeviceAddress
             );
    if (NT_SUCCESS(Status))
    {
        DebugTrace(("Registry specified device address of 0x%x", DeviceAddress));
    }
    else
    {
        DebugTrace(("Using default device address of 0x%x", JOY_IO_PORT_ADDRESS));
        DeviceAddress = JOY_IO_PORT_ADDRESS;
    }

    // Number of joysticks
    Status = AnajoystReadRegistryParameterDWORD(
                 RegistryPathName,
                 JOY_DD_TWOSTICKS_U,
                 &bTwoSticks
             );
    bTwoSticks = !!bTwoSticks;
    DebugTrace(("bTwoSticks: %ld", bTwoSticks));
    if (!NT_SUCCESS(Status))
    {
        AnajoystUnload(pDriverObject);
        return Status;
    }

    // if two joysticks are installed, only support two axes per joystick
    if (bTwoSticks)
    {
        NumberOfAxes = 2;
    }

    // Calculate time thresholds for analog device
    {
        //DWORD Remainder;
        LARGE_INTEGER LargeFrequency;
        //DWORD ulStart, ulTemp, ulEnd;
        //DWORD dwTicks, dwTimems;
        //int i;
        //BYTE byteJoy, byteTmp;

        // Get the system timer resolution expressed in Hertz.
        KeQueryPerformanceCounter(&LargeFrequency);

        Frequency = LargeFrequency.LowPart;

        DebugTrace(("Frequency: %u", Frequency));

        //ThresholdInTicks = RtlExtendedLargeIntegerDivide(
        //                        RtlExtendedIntegerMultiply(
        //                            LargeFrequency,
        //                            ANALOG_POLL_RESOLUTION
        //                        ),
        //                        1000000L,
        //                        &Remainder).LowPart;
        //DebugTrace(("ThresholdInTicks: %u", ThresholdInTicks));

        ThresholdInTicks = (DWORD) (((__int64)Frequency * (__int64)ANALOG_POLL_RESOLUTION) / (__int64)1000000L);
        DebugTrace(("ThresholdInTicks: %u", ThresholdInTicks));

        //MaxTimeoutInTicks = RtlExtendedLargeIntegerDivide(
        //                        RtlExtendedIntegerMultiply(
        //                            LargeFrequency,
        //                            ANALOG_POLL_TIMEOUT
        //                        ),
        //                        1000000L,
        //                        &Remainder).LowPart;
        //DebugTrace(("MaxTimeoutInTicks: %u", MaxTimeoutInTicks));

        MaxTimeoutInTicks = (DWORD) (((__int64)Frequency * (__int64)ANALOG_POLL_TIMEOUT) / (__int64)1000000L);
        DebugTrace(("MaxTimeoutInTicks: %u", MaxTimeoutInTicks));

        // need latency for KeQueryPerformanceCounter.  While we're at it, let's
        // get min time for delay and stall execution


        //ulStart = KeQueryPerformanceCounter(NULL).LowPart;
        //for (i = 0; i < 1000; i++) {
        //    ulTemp = KeQueryPerformanceCounter(NULL).LowPart;
        //}
        //dwTicks = ulTemp - ulStart;
        //dwTimems = TimeInMicroSeconds (dwTicks);


    }


    // Create the device
    Status = AnajoystCreateDevice(
                 pDriverObject,
                 JOY_DD_DEVICE_NAME_U,    // device driver
                 0,
                 sizeof(JOY_EXTENSION),
                 FALSE,                   // exclusive access
                 FILE_DEVICE_UNKNOWN,
                 &pJoyDevice0);

    if (!NT_SUCCESS(Status))
    {
        DebugTrace(("SwndrCreateDevice returned %x", Status));
        AnajoystUnload(pDriverObject);
        return Status;
    }

    //((PJOY_EXTENSION)pJoyDevice0->DeviceExtension)->DeviceNumber = JOYSTICKID1;
    //((PJOY_EXTENSION)pJoyDevice0->DeviceExtension)->NumberOfAxes = NumberOfAxes;
    //((PJOY_EXTENSION)pJoyDevice0->DeviceExtension)->DeviceAddress  = (PUCHAR) 0;
    pext0 = (PJOY_EXTENSION)pJoyDevice0->DeviceExtension;
    pext0->DeviceNumber = JOYSTICKID1;
    pext0->NumberOfAxes = NumberOfAxes;
    pext0->bTwoSticks = bTwoSticks;
    pext0->DeviceAddress  = (PUCHAR) 0;

    // Initialize the spinlock used to synchronize access to this device
//    KeInitializeSpinLock(&((PJOY_EXTENSION)pJoyDevice0->DeviceExtension)->SpinLockData);
//    ((PJOY_EXTENSION)pJoyDevice0->DeviceExtension)->SpinLock =
//            &((PJOY_EXTENSION)pJoyDevice0->DeviceExtension)->SpinLockData;
    KeInitializeSpinLock(&pext0->SpinLockData);
    pext0->SpinLock = &pext0->SpinLockData;

    // Get the device address into the device extension
    Status = AnajoystMapDevice(
                 DeviceAddress,
                 1,
                 pext0);
//              (PJOY_EXTENSION)pJoyDevice0->DeviceExtension);


    // Calibrate nQuiesceLoop for spinning in read_port loops to timeout after 10ms
    {
        int i;
        PBYTE JoyPort;
        DWORD ulStart, ulEnd;
        BYTE byteJoy;
        int LoopTimeInMicroSeconds;

        JoyPort = ((PJOY_EXTENSION)pJoyDevice0->DeviceExtension)->DeviceAddress;

        ulStart = KeQueryPerformanceCounter(NULL).LowPart;
        for (i = 0; i < 1000; i++) {
            byteJoy = READ_PORT_UCHAR(JoyPort);
            if ((byteJoy & X_AXIS_BITMASK)) {
                ;
            }
        }
        ulEnd = KeQueryPerformanceCounter(NULL).LowPart;
        LoopTimeInMicroSeconds = TimeInMicroSeconds (ulEnd - ulStart);
        nQuiesceLoop = (DWORD) (((__int64)1000L * (__int64)ANALOG_POLL_TIMEOUT) / (__int64)LoopTimeInMicroSeconds);
        DebugTrace(("READ_PORT_UCHAR loop, 1000 interations: %u ticks", ulEnd - ulStart));
        DebugTrace(("nQuiesceLoop: %u", nQuiesceLoop));
    }

    // if 2 joysticks are installed, support a second device
    if (bTwoSticks)
    {
        Status = AnajoystCreateDevice(
                     pDriverObject,
                     JOY_DD_DEVICE_NAME_U,
                     1,                      // device number
                     sizeof (JOY_EXTENSION),
                     FALSE,                  // exclusive access
                     FILE_DEVICE_UNKNOWN,
                     &pJoyDevice1);

        if (!NT_SUCCESS(Status))
        {
            DebugTrace(("Create device for second device returned %x", Status));
            AnajoystUnload(pDriverObject);
            return Status;
        }

//        // Both devices share the same I/O address so just copy it from pJoyDevice0
//        ((PJOY_EXTENSION)pJoyDevice1->DeviceExtension)->DeviceAddress =
//            ((PJOY_EXTENSION)pJoyDevice0->DeviceExtension)->DeviceAddress;
//        ((PJOY_EXTENSION)pJoyDevice1->DeviceExtension)->DeviceNumber = JOYSTICKID2;
//        ((PJOY_EXTENSION)pJoyDevice1->DeviceExtension)->NumberOfAxes = NumberOfAxes;
//
//        // Initialize the spinlock used to synchronize access to this device
//        KeInitializeSpinLock(&((PJOY_EXTENSION)pJoyDevice1->DeviceExtension)->SpinLockData);
//        ((PJOY_EXTENSION)pJoyDevice1->DeviceExtension)->SpinLock =
//                &((PJOY_EXTENSION)pJoyDevice1->DeviceExtension)->SpinLockData;

        pext1 = (PJOY_EXTENSION)pJoyDevice1->DeviceExtension;
        // Both devices share the same I/O address so just copy it from pJoyDevice0
        pext1->DeviceAddress = pext0->DeviceAddress;
        pext1->DeviceNumber = JOYSTICKID2;
        pext1->NumberOfAxes = NumberOfAxes;
        pext1->bTwoSticks = bTwoSticks;	// (will be TRUE)

        // Initialize the spinlock used to synchronize access to this device
        KeInitializeSpinLock(&pext1->SpinLockData);
        pext1->SpinLock = &pext1->SpinLockData;

    }

    // Define entry points
    pDriverObject->DriverUnload                         = AnajoystUnload;
    pDriverObject->MajorFunction[IRP_MJ_CREATE]         = AnajoystDispatch;
    pDriverObject->MajorFunction[IRP_MJ_CLOSE]          = AnajoystDispatch;
    pDriverObject->MajorFunction[IRP_MJ_READ]           = AnajoystDispatch;
    pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AnajoystDispatch;

    // Zero statistics, set misc globals
    JoyStatistics.Polls         = 0;
    JoyStatistics.Timeouts      = 0;
    JoyStatistics.PolledTooSoon = 0;
    JoyStatistics.Redo          = 0;

    // allow max of 100 polls/s (min time  between polls 10ms), which reduces time spinning in the NT kernel
    nMinTicksBetweenPolls = TimeInTicks (10000);
    bLastGoodPacket = FALSE;
    liLastPoll = KeQueryPerformanceCounter (NULL);

    return STATUS_SUCCESS;

}
Beispiel #23
0
NTSTATUS
AnajoystAnalogPoll(
    PDEVICE_OBJECT pDO,
    PIRP    pIrp
)

/*++
Do a good comment block here...
THIS MAY HANG UP IF NO JOYSTICK ATTACHED.  DON'T RELEASE THIS CODE WITH ANALOG
JOYSTICK SUPPORT WITHOUT CAREFULLY CHECKING THE CODE.

Routine Description:

    Polls the analog device for position and button information. The position
    information in analog devices is coveyed by the duration of a pulse width.
    Each axis occupies one bit position. The read operation is started by
    writing a value to the joystick io address. Immediately thereafter we
    begin examing the values returned and the elapsed time.

    This sort of device has a few limitations:

    First, button information is not latched by the device, so if a button press
    which occurrs in between polls will be lost. There is really no way to prevent
    this short of devoting the entire cpu to polling.

    Secondly, although we raise IRQL to DISPATCH_LEVEL, other interrupts will
    occur during the polling routines and this will have the effect of lengthening
    the pulse width (by delaying our polling loop) and thus there will be some
    fluctuation about the actual value.  It might be possible to try another IRQL
    to see if this helps, but ultimately, nothing short of disabling interrupts
    altogether will insure success. This is too much of a price to pay. The
    solution is a better device.

    Third, when circumstances cause a poll to last too long, we abort it and
    retry the operation. We have to do this to place an upper bound on the
    time we poll, and an upper bound on the time we spend at an elevated IRQL.

    But in this case both the position information and
    the button press information is lost. Note that there is an upper bound
    on the poll duration, beyond which we conclude that the device is disconnected.


Arguments:

    pDO     -- pointer to the device object
    pIrp    -- pointer to the requesing Irp


Return Value:

    STATUS_SUCCESS   -- if the poll succeeded,
    STATUS_TIMEOUT   -- if the poll failed (timeout), or the checksum was incorrect

--*/
{

    UCHAR  PortVal;
    PBYTE  JoyPort;
    DWORD  Id;
    DWORD  NumberOfAxes;
    BOOL   bTwoSticks;
    PJOY_DD_INPUT_DATA pInput;

    BOOL   Redo;
    UCHAR  Buttons;
    UCHAR  xMask, yMask, zMask, rMask;
    DWORD  xTime, yTime, zTime, rTime;
    int    MaxRedos;



    DebugTrace(("AnajoystAnalogPoll"));


    pInput  = (PJOY_DD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;

    // If we fail we assume it's because we're unplugged
    pInput->Unplugged = TRUE;

    // Find where our port and data area are, and related parameters
    JoyPort      = ((PJOY_EXTENSION)pDO->DeviceExtension)->DeviceAddress;
    Id           = ((PJOY_EXTENSION)pDO->DeviceExtension)->DeviceNumber;
    NumberOfAxes = ((PJOY_EXTENSION)pDO->DeviceExtension)->NumberOfAxes;
    bTwoSticks   = ((PJOY_EXTENSION)pDO->DeviceExtension)->bTwoSticks;

    // Read port state
    PortVal = READ_PORT_UCHAR(JoyPort);

    Buttons = 0;

    // Get current button states and build bitmasks for the resistive inputs
    if (Id == JOYSTICKID1)
    {
        switch (NumberOfAxes)
        {
        case 2:
            xMask      = JOYSTICK1_X_MASK;
            yMask      = JOYSTICK1_Y_MASK;
            zMask      = 0;
            rMask      = 0;

            if (!(PortVal & JOYSTICK1_BUTTON1))
            {
                Buttons |= JOY_BUTTON1;
            }
            if (!(PortVal & JOYSTICK1_BUTTON2))
            {
                Buttons |= JOY_BUTTON2;
            }

            if (!bTwoSticks)
            {
                if (!(PortVal & JOYSTICK2_BUTTON1))
                {
                    Buttons |= JOY_BUTTON3;
                }
                if (!(PortVal & JOYSTICK2_BUTTON2))
                {
                    Buttons |= JOY_BUTTON4;
                }
            }
            break;

        case 3:
            xMask      = JOYSTICK1_X_MASK;
            yMask      = JOYSTICK1_Y_MASK;
            zMask      = 0;
            rMask      = JOYSTICK1_R_MASK; // this is 0x08, typically the third axis on 3axis joysticks

            if (!(PortVal & JOYSTICK1_BUTTON1))
            {
                Buttons |= JOY_BUTTON1;
            }
            if (!(PortVal & JOYSTICK1_BUTTON2))
            {
                Buttons |= JOY_BUTTON2;
            }
            if (!(PortVal & JOYSTICK2_BUTTON1))
            {
                Buttons |= JOY_BUTTON3;
            }
            if (!(PortVal & JOYSTICK2_BUTTON2))
            {
                Buttons |= JOY_BUTTON4;
            }
            break;

        case 4:
            // Note that we read all axi because we don't know which
            // axis will be used by the joystick, and we read all the
            // buttons because no other joystick could use them

            xMask      = JOYSTICK1_X_MASK;
            yMask      = JOYSTICK1_Y_MASK;
            zMask      = JOYSTICK1_Z_MASK;
            rMask      = JOYSTICK1_R_MASK;

            if (!(PortVal & JOYSTICK1_BUTTON1))
            {
                Buttons |= JOY_BUTTON1;
            }
            if (!(PortVal & JOYSTICK1_BUTTON2))
            {
                Buttons |= JOY_BUTTON2;
            }
            if (!(PortVal & JOYSTICK2_BUTTON1))
            {
                Buttons |= JOY_BUTTON3;
            }
            if (!(PortVal & JOYSTICK2_BUTTON2))
            {
                Buttons |= JOY_BUTTON4;
            }
            break;

        default:
            break;
            // $TODO - report invalid number of axi
        }
    }
    else if ((Id == JOYSTICKID2) && (bTwoSticks))
    {
        xMask      = JOYSTICK2_X_MASK;
        yMask      = JOYSTICK2_Y_MASK;
        zMask      = 0;
        rMask      = 0;

        if (!(PortVal & JOYSTICK2_BUTTON1))
        {
            Buttons |= JOY_BUTTON1;
        }
        if (!(PortVal & JOYSTICK2_BUTTON2))
        {
            Buttons |= JOY_BUTTON2;
        }
    }
    else
    {
        // $TODO - report unsupported configuration
    }

    // Insure that the resistive inputs are currently reset before performing
    // the next read. If we find one or more hot inputs, wait briefly for
    // them to reset. If they don't, we assume that the joystick is unplugged

    if (!AnajoystQuiesce(JoyPort, (UCHAR) (xMask | yMask | zMask | rMask)))
    {
        DebugTrace(("AnajoystQuiesce: failed to quiesce resistive inputs"));
        return STATUS_TIMEOUT;
    }

    // Note that timing is EXTREMELY critical in the loop below.
    // Avoid calling complicated arithmetic (eg TimeInMicroSeconds)
    // or we will decrease our accuracy
    // Other problems with accuracy, probably larger than the delays caused
    // by arithmetic, are the latency in calls to KeQueryPerformanceCounter
    // (typically about 5 us), and delays that can occur on the bus when DMA
    // is taking place.

    // Now poll the device.  We wait until the status bit(s) set(s)
    // and note the time.  If the time since the last poll was
    // too great we ignore the answer and try again.

    // Loop until we get a decent reading or exceed the threshold

    for (Redo = TRUE, MaxRedos = 20; Redo && --MaxRedos != 0;)
    {
        ULONG StartTime;
        ULONG CurrentTime;
        ULONG PreviousTime;
        ULONG PreviousTimeButOne;
        UCHAR ResistiveInputMask;

        ResistiveInputMask = xMask | yMask | zMask | rMask;

        // Lock on to start time
        StartTime = KeQueryPerformanceCounter(NULL).LowPart;

        WRITE_PORT_UCHAR(JoyPort, JOY_START_TIMERS);

        CurrentTime = KeQueryPerformanceCounter(NULL).LowPart - StartTime;

        PortVal = READ_PORT_UCHAR(JoyPort);

        // Now wait until our end times for each coordinate

        PreviousTimeButOne = 0;
        PreviousTime = CurrentTime;

        for (Redo = FALSE;
                ResistiveInputMask;
                PreviousTimeButOne = PreviousTime,
                PreviousTime = CurrentTime,
                PortVal = READ_PORT_UCHAR(JoyPort)
            ) {

            PortVal = ResistiveInputMask & ~PortVal;
            CurrentTime = KeQueryPerformanceCounter(NULL).LowPart - StartTime;

            if (CurrentTime > MaxTimeoutInTicks) {

                DebugTrace(("Polling failed - ResistiveInputMask = %x, Time = %d",
                            (ULONG)ResistiveInputMask,
                            TimeInMicroSeconds(CurrentTime)));

                return STATUS_TIMEOUT;
            }

            if (PortVal & xMask) {
                ResistiveInputMask &= ~xMask;
                xTime = PreviousTime;
            }
            if (PortVal & yMask) {
                ResistiveInputMask &= ~yMask;
                yTime = PreviousTime;
            }
            if (PortVal & zMask) {
                ResistiveInputMask &= ~zMask;
                zTime = PreviousTime;
            }
            if (PortVal & rMask) {
                ResistiveInputMask &= ~rMask;
                rTime = PreviousTime;
            }

            if (PortVal && CurrentTime - PreviousTimeButOne > ThresholdInTicks) {
                // Something (DMA or interrupts) delayed our read loop, start again.
                DebugTrace(("Too long a gap between polls - %u us", TimeInMicroSeconds(CurrentTime - PreviousTimeButOne)));
                JoyStatistics.Redo++;
                Redo = TRUE;
                break;
            }
        }
    }

    if (MaxRedos == 0)
    {
        DebugTrace(("Overran redos to get counters"));
        pInput->Unplugged = TRUE;
        return STATUS_TIMEOUT;
    }

    pInput->Unplugged = FALSE;
    pInput->Buttons = Buttons;
    pInput->XTime = TimeInMicroSeconds(xTime);
    pInput->YTime = TimeInMicroSeconds(yTime);
    pInput->ZTime = (zMask) ? TimeInMicroSeconds(zTime) : 0;
    pInput->TTime = (rMask) ? TimeInMicroSeconds(rTime) : 0;

    pInput->Axi = ((PJOY_EXTENSION)pDO->DeviceExtension)->NumberOfAxes;


    // everything worked, save this info as last good packet
    RtlCopyMemory (&jjLastGoodPacket, pInput, sizeof (JOY_DD_INPUT_DATA));
    bLastGoodPacket = TRUE;


    DebugTrace(("X = %x, Y = %x, Z = %x, R = %x, Buttons = %x",
                pInput->XTime,
                pInput->YTime,
                pInput->ZTime,
                pInput->TTime,
                pInput->Buttons));

    return STATUS_SUCCESS;
}
Beispiel #24
0
//----- (08001F19) --------------------------------------------------------
NTSTATUS 
DMDeviceControl(
	PDEVICE_OBJECT	DeviceObject, 
	PIRP			Irp
	)
{
	PIO_STACK_LOCATION	IrpStack;
	PVOID				OutputBuffer;
	PVOID				InputBuffer;
	ULONG				InputLength;
	ULONG				OutputLength;
	NTSTATUS			status;
	PDEVICE_ENTRY		DevEntry;
	LARGE_INTEGER		CurrentTime;
	LARGE_INTEGER		PerfCount; 
	ULONG				seq;
	char				IoctlName[64] = "";
	PCHAR				pIoCtlName;
	ULONG				IoControlCode;

	IrpStack = IoGetCurrentIrpStackLocation(Irp);
	IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

	if ( DeviceObject == g_pDeviceObject )
	{
		InputBuffer = Irp->AssociatedIrp.SystemBuffer;
		InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
		OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
		OutputBuffer = Irp->AssociatedIrp.SystemBuffer;

		if ( METHOD_FROM_CTL_CODE(IoControlCode) == METHOD_NEITHER )
		{
			OutputBuffer = Irp->UserBuffer;
		}

		status = DMDeviceIoCtl(Irp, InputBuffer, InputLength, OutputBuffer, OutputLength, IoControlCode);
	}
	else
	{
		if ( g_bUsePerfCounter )
		{
			CurrentTime.QuadPart = 0;
			PerfCount = KeQueryPerformanceCounter(0);
		}
		else
		{
			KeQuerySystemTime(&CurrentTime);
			PerfCount.QuadPart = 0;
		}
		seq = InterlockedIncrement(&Sequence);
		DevEntry = LookupEntryByDevObj(DeviceObject);
		if ( DevEntry )
		{
			pIoCtlName = GetIoctlName(IoctlName, IrpStack->Parameters.DeviceIoControl.IoControlCode);
			LogRecord(
				seq,
				&CurrentTime,
				DevEntry->DiskNumber,
				"%s(%s)",
				IrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? "IRP_MJ_DEVICE_CONTROL" : "IRP_MJ_INTERNAL_DEVICE_CONTROL",
				IoctlName);
		}

		status = DefaultDispatch(DeviceObject, Irp, seq, g_bUsePerfCounter, &PerfCount);
		if ( IoControlCode == IOCTL_DISK_FIND_NEW_DEVICES || IoControlCode == IOCTL_DISK_SET_DRIVE_LAYOUT )
		{
			if ( NT_SUCCESS(status) )
			{
				HookDispatch(DeviceObject->DriverObject, 0);
			}
		}
	}

	return status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
    NDIS_STATUS                             status = NDIS_STATUS_FAILURE;
    NDIS_MINIPORT_DRIVER_CHARACTERISTICS    chars;
#ifdef DEBUG_TIMING
    LARGE_INTEGER TickCount;
    LARGE_INTEGER SysTime;
#endif DEBUG_TIMING

    ParaNdis_DebugInitialize();

    DEBUG_ENTRY(0);
    DPrintf(0, (__DATE__ " " __TIME__ "built %d.%d\n", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION));
#ifdef DEBUG_TIMING
    KeQueryTickCount(&TickCount);
    NdisGetCurrentSystemTime(&SysTime);
    DPrintf(0, ("\n%s>> CPU #%d, perf-counter %I64d, tick count %I64d, NDIS_sys_time %I64d\n", __FUNCTION__, KeGetCurrentProcessorNumber(), KeQueryPerformanceCounter(NULL).QuadPart,TickCount.QuadPart, SysTime.QuadPart));
#endif

    NdisZeroMemory(&chars, sizeof(chars));

    chars.Header.Type      = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
    chars.Header.Revision  = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
    chars.Header.Size      = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
    chars.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
    chars.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
    /* stupid thing, they are at least short */
    chars.MajorDriverVersion = (UCHAR)(PARANDIS_MAJOR_DRIVER_VERSION & 0xFF);
    chars.MinorDriverVersion = (UCHAR)(PARANDIS_MINOR_DRIVER_VERSION & 0xFF);

    // possible value for regular miniport NDIS_WDM_DRIVER - for USB or 1394
    // chars.Flags  = 0;

    chars.InitializeHandlerEx           = ParaNdis6_Initialize;
    chars.HaltHandlerEx                 = ParaNdis6_Halt;
    chars.UnloadHandler                 = ParaNdis6_Unload;
    chars.PauseHandler                  = ParaNdis6_Pause;
    chars.RestartHandler                = ParaNdis6_Restart;
    chars.OidRequestHandler             = ParaNdis6_OidRequest;
    chars.CancelOidRequestHandler       = ParaNdis6_OidCancelRequest;
    chars.SendNetBufferListsHandler     = ParaNdis6_SendNetBufferLists;
    chars.CancelSendHandler             = ParaNdis6_CancelSendNetBufferLists;
    chars.ReturnNetBufferListsHandler   = ParaNdis6_ReturnNetBufferLists;
    chars.CheckForHangHandlerEx         = ParaNdis6_CheckForHang;
    chars.ResetHandlerEx                = ParaNdis6_Reset;
    chars.ShutdownHandlerEx             = ParaNdis6_AdapterShutdown;
    chars.DevicePnPEventNotifyHandler   = ParaNdis6_DevicePnPEvent;
    chars.SetOptionsHandler             = ParaNdis6_SetOptions;

#if NDIS_SUPPORT_NDIS61
    chars.Header.Revision  = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
    chars.Header.Size      = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
    chars.DirectOidRequestHandler       = ParaNdis6x_DirectOidRequest;
    chars.CancelDirectOidRequestHandler = ParaNdis6x_CancelDirectOidRequest;
#endif

    status = NdisMRegisterMiniportDriver(
            pDriverObject,
            pRegistryPath,
            NULL,
            &chars,
            &DriverHandle);

    if (status == NDIS_STATUS_SUCCESS)
    {
        RetrieveDriverConfiguration();
    }
    DEBUG_EXIT_STATUS(status ? 0 : 4, status);
    return status;
}
Beispiel #26
0
NTSTATUS CMiniportWaveRTStream::SetState
(
    _In_    KSSTATE State_
)
{
    PAGED_CODE();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            break;
    }

    m_KsState = State_;

#ifdef SYSVAD_BTH_BYPASS
Done:
#endif  // SYSVAD_BTH_BYPASS
    return ntStatus;
}
Beispiel #27
0
LARGE_INTEGER
SoundGetTime(
    VOID
)
/*++

Routine Description:

    Get an accurate estimate of the current time by calling
    KeQueryPerformanceCounter and converting the result to 100ns units

    NOTE:  A driver should call this once during init to get the thing
    safely started if it can be called from more than one device at a time

Arguments:

    None

Return Value:

--*/
{
    static struct {
        LARGE_INTEGER StartTime100ns, StartTimeTicks, TicksPerSecond;
        ULONG Multiplier;
        BOOLEAN Initialized;
    } s = { 1 }; // Move from BSS to reduce size

    ULONG Remainder;

    if (!s.Initialized) {

        KeQuerySystemTime(&s.StartTime100ns);
        s.StartTimeTicks = KeQueryPerformanceCounter(&s.TicksPerSecond);

        s.Multiplier = 10000000;

        while (s.TicksPerSecond.HighPart != 0) {
            s.Multiplier = s.Multiplier / 10;
            s.TicksPerSecond =
                RtlExtendedLargeIntegerDivide(s.TicksPerSecond, 10, &Remainder);
        }
        s.Initialized = TRUE;
    }

    //
    // Convert ticks to 100ns units (and hope we don't overflow!)
    //

    return RtlLargeIntegerAdd(
              RtlExtendedLargeIntegerDivide(
                  RtlExtendedIntegerMultiply(
                      RtlLargeIntegerSubtract(
                          KeQueryPerformanceCounter(NULL),
                          s.StartTimeTicks
                      ),
                      s.Multiplier
                  ),
                  s.TicksPerSecond.LowPart,
                  &Remainder
              ),
              s.StartTime100ns
           );
}
Beispiel #28
0
//----- (08000FDA) --------------------------------------------------------
NTSTATUS 
MyCompletionRoutine(
	PDEVICE_OBJECT	DeviceObject, 
	PIRP			Irp, 
	PVOID			Context
	)
{
	PMYCONTEXT				MyContext;
	NTSTATUS				status;
	UCHAR					Control;
	PCHAR					pError;
	LARGE_INTEGER			PerfCount;
	char					Error[64] = "";
	PIO_COMPLETION_ROUTINE	CompletionRoutine;

	MyContext = (PMYCONTEXT)Context;

	switch(MyContext->MajorFunction)
	{
	case IRP_MJ_READ:
		InterlockedDecrement(&g_ReadCount);
		break;

	case IRP_MJ_WRITE:
		InterlockedDecrement(&g_WriteCount);
		break;

	default:
		break;
	}

	PerfCount = KeQueryPerformanceCounter(0);
	if ( MyContext->bUsePerfCounter && MyContext->PerfCount.QuadPart != 0 )
	{		
		PerfCount.QuadPart -= MyContext->PerfCount.QuadPart;
	}
	else
	{
		PerfCount.QuadPart = MyContext->PerfCount.QuadPart;
	}

	pError = ErrorString(Irp->IoStatus.Status, Error);
	//LogRecord(MyContext->Seq, &PerfCount, -1, "%s", pError);

	Control = MyContext->Control;
	CompletionRoutine = MyContext->CompletionRoutine;
	Context = MyContext->Context;

	ExFreeToNPagedLookasideList(&ContextLookaside, MyContext);

	status = Irp->IoStatus.Status;
	if( NT_SUCCESS(status) )
	{
		if(Control & 0x40)
		{
			return CompletionRoutine(DeviceObject, Irp, Context);
		}
	}
	else if(status == STATUS_CANCELLED)
	{
		if(Control & 0x20)
		{
			return CompletionRoutine(DeviceObject, Irp, Context);
		}
	}
	else
	{
		if(Control & 0x80)
		{
			return CompletionRoutine(DeviceObject, Irp, Context);
		}
	}

	return status;
}
//TODO: should we put OVS_MESSAGE_FLAG_MULTIPART for Flow_Dump?
BOOLEAN CreateMsgFromFlow(_In_ const OVS_FLOW* pFlow, UINT8 command, _Inout_ OVS_MESSAGE* pMsg, UINT32 sequence, UINT32 dpIfIndex, UINT32 portId)
{
    OVS_ARGUMENT_GROUP* pFlowGroup = NULL;
    OVS_ARGUMENT* pPIArg, *pMasksArg, *pTimeUsedArg, *pFlowStats, *pTcpFlags, *pActionsArg;
    BOOLEAN ok = TRUE;
    UINT16 flowArgCount = 0;
    UINT16 curArg = 0;
    OVS_WINL_FLOW_STATS winlStats = { 0 };
    OVS_FLOW_STATS stats = { 0 };
    UINT64 tickCount = 0;
    UINT8 tcpFlags = 0;
    UINT16 argsDataSize = 0;
    LOCK_STATE_EX lockState = { 0 };

    OVS_OFPACKET_INFO unmaskedPacketInfo = { 0 };
    OVS_OFPACKET_INFO maskedPacketInfo = { 0 };
    OVS_OFPACKET_INFO packetInfoMask = { 0 };

    OVS_CHECK(pMsg);

    pPIArg = pMasksArg = pTimeUsedArg = pFlowStats = pTcpFlags = pActionsArg = NULL;

    FLOW_LOCK_READ(pFlow, &lockState);

    unmaskedPacketInfo = pFlow->unmaskedPacketInfo;
    maskedPacketInfo = pFlow->maskedPacketInfo;
    packetInfoMask = pFlow->pMask->packetInfo;

#if OVS_VERSION == OVS_VERSION_1_11
    tickCount = pFlow->stats.lastUsedTime;
    stats.noOfMatchedPackets = pFlow->stats.packetsMached;
    stats.noOfMatchedBytes = pFlow->stats.bytesMatched;
    tcpFlags = pFlow->stats.tcpFlags;
#elif OVS_VERSION == OVS_VERSION_2_3
    //TODO: Flow_GetStats()
    Flow_GetStats_Unsafe(pFlow, &stats);
    winlStats.noOfMatchedBytes = stats.bytesMatched;
    winlStats.noOfMatchedPackets = stats.packetsMached;
#endif

    FLOW_UNLOCK(pFlow, &lockState);

    //2. INIT OVS_MESSAGE
    pMsg->length = sizeof(OVS_MESSAGE);
    pMsg->type = OVS_MESSAGE_TARGET_FLOW;
    pMsg->flags = 0;
    pMsg->sequence = sequence;
    pMsg->pid = portId;

    pMsg->command = command;
    pMsg->version = 1;
    pMsg->reserved = 0;

    pMsg->dpIfIndex = dpIfIndex;

    //3. OVS_ARGUMENT_GROUP
    pFlowGroup = KZAlloc(sizeof(OVS_ARGUMENT_GROUP));
    if (!pFlowGroup)
    {
        return FALSE;
    }

    //3.1. Packet Info
    pPIArg = CreateArgFromPacketInfo(&unmaskedPacketInfo, NULL, OVS_ARGTYPE_FLOW_PI_GROUP);
    if (!pPIArg)
    {
        ok = FALSE;
        goto Cleanup;
    }

    argsDataSize += pPIArg->length;
    ++curArg;

    //3.2. Packet Info Mask
    pMasksArg = CreateArgFromPacketInfo(&maskedPacketInfo, &packetInfoMask, OVS_ARGTYPE_FLOW_MASK_GROUP);
    if (!pMasksArg)
    {
        ok = FALSE;
        goto Cleanup;
    }

    argsDataSize += pMasksArg->length;
    ++curArg;

    //3.3. Flow Time Used
    if (tickCount > 0)
    {
        UINT64 usedTimeInMs = 0, curTimeInMs = 0;

        usedTimeInMs = _TicksToMiliseconds(tickCount);
        curTimeInMs = _TicksToMiliseconds(KeQueryPerformanceCounter(NULL).QuadPart);

        pTimeUsedArg = CreateArgument_Alloc(OVS_ARGTYPE_FLOW_TIME_USED, &usedTimeInMs);
        if (!pTimeUsedArg)
        {
            ok = FALSE;
            goto Cleanup;
        }

        argsDataSize += pTimeUsedArg->length;
        ++curArg;
    }

    //3.4. Flow Stats
    if (winlStats.noOfMatchedPackets > 0)
    {
        pFlowStats = CreateArgument_Alloc(OVS_ARGTYPE_FLOW_STATS, &stats);
        if (!pFlowStats)
        {
            ok = FALSE;
            goto Cleanup;
        }

        argsDataSize += pFlowStats->length;
        ++curArg;
    }

    //3.5. Flow Tcp Flags
    if (tcpFlags)
    {
        pTcpFlags = CreateArgument_Alloc(OVS_ARGTYPE_FLOW_TCP_FLAGS, &tcpFlags);
        if (!pTcpFlags)
        {
            ok = FALSE;
            goto Cleanup;
        }

        argsDataSize += pTcpFlags->length;
        ++curArg;
    }

    FLOW_LOCK_READ(pFlow, &lockState);
    //NOTE: we don't need to use OVS_REFERENCE for pFlow->pActions here
    //because the actions cannot be deleted while under the lock of pFlow
    //pFlow is here referenced, so it and its Actions cannot be deleted
    pActionsArg = _CreateFlowActionsGroup(pFlow->pActions->pActionGroup);
    FLOW_UNLOCK(pFlow, &lockState);

    if (!pActionsArg)
    {
        return FALSE;
    }

    DBGPRINT_ARG(LOG_INFO, pActionsArg, 0, 0);

    argsDataSize += pActionsArg->length;
    ++curArg;

    flowArgCount = curArg;
    if (!AllocateArgumentsToGroup(flowArgCount, pFlowGroup))
    {
        ok = FALSE;
        goto Cleanup;
    }

    pFlowGroup->args[0] = *pPIArg;
    pFlowGroup->args[1] = *pMasksArg;

    curArg = 2;

    if (pTimeUsedArg)
    {
        pFlowGroup->args[curArg] = *pTimeUsedArg;
        curArg++;
    }

    if (pFlowStats)
    {
        pFlowGroup->args[curArg] = *pFlowStats;
        curArg++;
    }

    if (pTcpFlags)
    {
        pFlowGroup->args[curArg] = *pTcpFlags;
        curArg++;
    }

    pFlowGroup->args[curArg] = *pActionsArg;
    ++curArg;

    pFlowGroup->groupSize += argsDataSize;
    pMsg->pArgGroup = pFlowGroup;

Cleanup:
    VerifyGroup_Size_Recursive(pMsg->pArgGroup);

    if (ok)
    {
        KFree(pPIArg);
        KFree(pMasksArg);
        KFree(pTimeUsedArg);
        KFree(pFlowStats);
        KFree(pTcpFlags);
        KFree(pActionsArg);
    }
    else
    {
        FreeGroupWithArgs(pFlowGroup);

        DestroyArgument(pPIArg);
        DestroyArgument(pMasksArg);
        DestroyArgument(pTimeUsedArg);
        DestroyArgument(pFlowStats);
        DestroyArgument(pTcpFlags);
        DestroyArgument(pActionsArg);
    }

    return ok;
}
Beispiel #30
0
BOOLEAN
KdInitSystem(
    IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL,
    BOOLEAN StopInDebugger
    )

/*++

Routine Description:

    This routine initializes the portable kernel debugger.

Arguments:

    LoaderBlock - Supplies a pointer to the LOADER_PARAMETER_BLOCK passed
        in from the OS Loader.

    StopInDebugger - Supplies a boolean value that determines whether a
        debug message and breakpoint are generated.

Return Value:

    None.

--*/

{

    ULONG Index;
    BOOLEAN Initialize;
    PCHAR Options;
    PCHAR BaudOption;
    PCHAR PortOption;

    //
    // If kernel debugger is already initialized, then return.
    //

    if (KdDebuggerEnabled != FALSE) {
        return TRUE;
    }

    KiDebugRoutine = KdpStub;

    //
    // Determine whether or not the debugger should be enabled.
    //
    // Note that if LoaderBlock == NULL, then KdInitSystem was called
    // from BugCheck code. For this case the debugger is always enabled
    // to report the bugcheck if possible.
    //

    if (LoaderBlock != NULL) {

        KdpNtosImageBase =  CONTAINING_RECORD(
                                    (LoaderBlock->LoadOrderListHead.Flink),
                                    LDR_DATA_TABLE_ENTRY,
                                    InLoadOrderLinks)->DllBase;

        //
        // Initialize the debugger data block list when called at startup time.
        //

        InitializeListHead(&KdpDebuggerDataListHead);

        //
        // Fill in and register the debugger's debugger data block.
        // Most fields are already initialized, some fields will not be
        // filled in until later.
        //

        KdDebuggerDataBlock.KernBase = (ULONG_PTR) KdpNtosImageBase;
        KdDebuggerDataBlock.KeUserCallbackDispatcher = (ULONG_PTR) KeUserCallbackDispatcher;

        KdRegisterDebuggerDataBlock(KDBG_TAG,
                                    &KdDebuggerDataBlock.Header,
                                    sizeof(KdDebuggerDataBlock));

        if (LoaderBlock->LoadOptions != NULL) {
            Options = LoaderBlock->LoadOptions;
            _strupr(Options);

            //
            // If any of the port option, baud option, or debug is specified,
            // then enable the debugger unless it is explictly disabled.
            //

            Initialize = TRUE;
            PortOption = strstr(Options, PORT_OPTION);
            BaudOption = strstr(Options, BAUD_OPTION);
            if ((PortOption == NULL) && (BaudOption == NULL)) {
                if (strstr(Options, "DEBUG") == NULL) {
                    Initialize = FALSE;
                }

            } else {
                if (PortOption) {
                    PortOption = strstr(PortOption, "COM");
                    if (PortOption) {
                        KdDebugParameters.CommunicationPort =
                                                     atol(PortOption + 3);
                    }
                }

                if (BaudOption) {
                    BaudOption += strlen(BAUD_OPTION);
                    while (*BaudOption == ' ') {
                        BaudOption++;
                    }

                    if (*BaudOption != '\0') {
                        KdDebugParameters.BaudRate = atol(BaudOption + 1);
                    }
                }
            }

            //
            // If the debugger is explicitly disabled, then set to NODEBUG.
            //

            if (strstr(Options, "NODEBUG")) {
                Initialize = FALSE;
                KdPitchDebugger = TRUE;
            }

            if (strstr(Options, "CRASHDEBUG")) {
                Initialize = FALSE;
                KdPitchDebugger = FALSE;
            }

        } else {

            //
            // If the load options are not specified, then set to NODEBUG.
            //

            KdPitchDebugger = TRUE;
            Initialize = FALSE;
        }

    } else {
        Initialize = TRUE;
    }

    if ((KdPortInitialize(&KdDebugParameters, LoaderBlock, Initialize) == FALSE) ||
        (Initialize == FALSE)) {
        return(TRUE);
    }

    //
    // Set address of kernel debugger trap routine.
    //

    KiDebugRoutine = KdpTrap;

    if (!KdpDebuggerStructuresInitialized) {

        KiDebugSwitchRoutine = KdpSwitchProcessor;
        KdpBreakpointInstruction = KDP_BREAKPOINT_VALUE;
        KdpOweBreakpoint = FALSE;

        //
        // Initialize the breakpoint table.
        //

        for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index += 1) {
            KdpBreakpointTable[Index].Flags = 0;
            KdpBreakpointTable[Index].Address = NULL;
            KdpBreakpointTable[Index].DirectoryTableBase = 0L;
        }

        //
        // Initialize TimeSlip
        //
        KeInitializeDpc(&KdpTimeSlipDpc, KdpTimeSlipDpcRoutine, NULL);
        KeInitializeTimer(&KdpTimeSlipTimer);
        ExInitializeWorkItem(&KdpTimeSlipWorkItem, KdpTimeSlipWork, NULL);

        KdpDebuggerStructuresInitialized = TRUE ;
    }

    //
    //  Initialize timer facility - HACKHACK
    //

    KeQueryPerformanceCounter(&KdPerformanceCounterRate);
    KdTimerStart.HighPart = 0L;
    KdTimerStart.LowPart = 0L;

    //
    // Initialize ID for NEXT packet to send and Expect ID of next incoming
    // packet.
    //

    KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID;
    KdpPacketIdExpected = INITIAL_PACKET_ID;

    //
    // Mark debugger enabled.
    //
    KdPitchDebugger = FALSE;
    KdDebuggerEnabled = TRUE;
    SharedUserData->KdDebuggerEnabled = TRUE;

    //
    // If requested, stop in the kernel debugger.
    //

    if (StopInDebugger) {
        DbgBreakPoint();
    }

    return TRUE;
}