Esempio n. 1
0
ULONG
HalSetProfileInterval (
    IN ULONG Interval
    )

/*++

Routine Description:

    This routine sets the profile interrupt interval.

Arguments:

    Interval - Supplies the desired profile interval in 100ns units.

Return Value:

    The actual profile interval.

--*/

{

    LARGE_INTEGER TempValue;

    //
    // If the specified profile interval is less that the minimum profile
    // interval or greater than the maximum profile interval, then set the
    // profile interval to the minimum or maximum as appropriate.
    //

    if (Interval < MINIMUM_PROFILE_INTERVAL) {
        Interval = MINIMUM_PROFILE_INTERVAL;

    } else if (Interval > MAXIMUM_PROFILE_INTERVAL) {
        Interval = MAXIMUM_PROFILE_INTERVAL;
    }

    //
    // First compute the profile count value and then back calculate the
    // actual profile interval.
    //

    TempValue.QuadPart = Int32x32To64(HalpProfileCountRate, Interval);
    TempValue.QuadPart += ROUND_VALUE;
    TempValue = RtlExtendedLargeIntegerDivide(TempValue, ONE_SECOND, NULL);
    TempValue.QuadPart = Int32x32To64(TempValue.LowPart, ONE_SECOND);
    TempValue = RtlExtendedLargeIntegerDivide(TempValue, HalpProfileCountRate, NULL);
    HalpProfileInterval = TempValue.LowPart;
    return HalpProfileInterval;
}
Esempio n. 2
0
static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
{
    ULONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
    secs = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
    filetime->dwLowDateTime  = (DWORD)secs;
    filetime->dwHighDateTime = (DWORD)(secs >> 32);
}
Esempio n. 3
0
VOID
HalStartProfileInterrupt (
    KPROFILE_SOURCE ProfileSource
    )

/*++

Routine Description:

    This routine computes the profile count value, writes the compare
    register, clears the count register, and updates the performance
    counter.

    N.B. This routine must be called at PROFILE_LEVEL while holding the
        profile lock.

Arguments:

    Source - Supplies the profile source.

Return Value:

    None.

--*/

{

    PKPRCB Prcb;
    ULONG PreviousCount;
    LARGE_INTEGER TempValue;

    //
    // Compute the profile count from the current profile interval.
    //

    TempValue.QuadPart = Int32x32To64(HalpProfileCountRate,
                                      HalpProfileInterval);

    TempValue.QuadPart += ROUND_VALUE;
    TempValue = RtlExtendedLargeIntegerDivide(TempValue, ONE_SECOND, NULL);

    //
    // Write the compare register and clear the count register.
    //

    PreviousCount = HalpWriteCompareRegisterAndClear(TempValue.LowPart);

    //
    // Update the performance counter by adding in the previous count value.
    //

    Prcb = KeGetCurrentPrcb();
    HalpPerformanceCounter[Prcb->Number].QuadPart += PreviousCount;
    return;
}
Esempio n. 4
0
BOOLEAN
NTAPI
FsRecGetDeviceSectors(IN PDEVICE_OBJECT DeviceObject,
                      IN ULONG SectorSize,
                      OUT PLARGE_INTEGER SectorCount)
{
    PARTITION_INFORMATION PartitionInfo;
    IO_STATUS_BLOCK IoStatusBlock;
    KEVENT Event;
    PIRP Irp;
    NTSTATUS Status;
    ULONG Remainder;
    PAGED_CODE();

    /* Only needed for disks */
    if (DeviceObject->DeviceType != FILE_DEVICE_DISK) return FALSE;

    /* Build the information IRP */
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO,
                                        DeviceObject,
                                        NULL,
                                        0,
                                        &PartitionInfo,
                                        sizeof(PARTITION_INFORMATION),
                                        FALSE,
                                        &Event,
                                        &IoStatusBlock);
    if (!Irp) return FALSE;

    /* Override verification */
    IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;

    /* Do the request */
    Status = IoCallDriver(DeviceObject, Irp);
    if (Status == STATUS_PENDING)
    {
        /* Wait for completion */
        KeWaitForSingleObject(&Event,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
        Status = IoStatusBlock.Status;
    }

    /* Fail if we couldn't get the data */
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Otherwise, return the number of sectors */
    *SectorCount = RtlExtendedLargeIntegerDivide(PartitionInfo.PartitionLength,
                                                 SectorSize,
                                                 &Remainder);
    return TRUE;
}
Esempio n. 5
0
/*
 * @implemented
 */
BOOL
WINAPI
GetMailslotInfo(IN HANDLE hMailslot,
                IN LPDWORD lpMaxMessageSize,
                IN LPDWORD lpNextSize,
                IN LPDWORD lpMessageCount,
                IN LPDWORD lpReadTimeout)
{
    FILE_MAILSLOT_QUERY_INFORMATION Buffer;
    IO_STATUS_BLOCK Iosb;
    NTSTATUS Status;
    LARGE_INTEGER Timeout;

    Status = NtQueryInformationFile(hMailslot,
                                    &Iosb,
                                    &Buffer,
                                    sizeof(FILE_MAILSLOT_QUERY_INFORMATION),
                                    FileMailslotQueryInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed (Status %x)!\n", Status);
        BaseSetLastNTError(Status);
        return FALSE;
     }

     if (lpMaxMessageSize) *lpMaxMessageSize = Buffer.MaximumMessageSize;
     if (lpNextSize) *lpNextSize = Buffer.NextMessageSize;
     if (lpMessageCount) *lpMessageCount = Buffer.MessagesAvailable;

     if (lpReadTimeout)
     {
         if (Buffer.ReadTimeout.QuadPart == 0xFFFFFFFFFFFFFFFFLL)
         {
             *lpReadTimeout = MAILSLOT_WAIT_FOREVER;
         }
         else
         {
             Timeout.QuadPart = -Buffer.ReadTimeout.QuadPart;
             Timeout = RtlExtendedLargeIntegerDivide(Timeout, 10000, NULL);
             if (Timeout.HighPart == 0)
             {
                 *lpReadTimeout = Timeout.LowPart;
             }
             else
             {
                 *lpReadTimeout = 0xFFFFFFFE;
             }
         }
     }

   return TRUE;
}
Esempio n. 6
0
DWORD
TimeInMicroSeconds(
    DWORD dwTime
)
{
    DWORD Remainder;

    return RtlExtendedLargeIntegerDivide(
               RtlEnlargedUnsignedMultiply( dwTime, 1000000L),
               Frequency,
               &Remainder
           ).LowPart;
}
Esempio n. 7
0
BOOLEAN FsRecGetDeviceSectors(PDEVICE_OBJECT DeviceObject,ULONG BytesPerSector,OUT PLARGE_INTEGER SectorCount)
{
	KEVENT			Event;
	IO_STATUS_BLOCK	IoStatus;
	LARGE_INTEGER	Length;
	PIRP			Irp;
	NTSTATUS		Status;
	LARGE_INTEGER	Divide;
	ULONG			Remainder;

	if( DeviceObject->DeviceType == FILE_DEVICE_DISK)
	{
		KeInitializeEvent(&Event,SynchronizationEvent,FALSE);

		Irp = IoBuildDeviceIoControlRequest(
					IOCTL_DISK_GET_LENGTH_INFO,	// 7405C
					DeviceObject,
					NULL,
					0,
					(PVOID)&Length,
					sizeof(LARGE_INTEGER),
					FALSE,
					&Event,
					&IoStatus);
		if(Irp)
		{
			(IoGetNextIrpStackLocation(Irp))->Flags |= IRP_PAGING_IO;
		
			Status = IoCallDriver(DeviceObject,Irp);
			
			if(Status == STATUS_PENDING)
			{
				KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
				Status = IoStatus.Status;
			}
			
			if(NT_SUCCESS(Status))
			{
				Divide = RtlExtendedLargeIntegerDivide(Length,BytesPerSector,&Remainder);
				SectorCount->QuadPart = Divide.QuadPart;
				return TRUE;
			}
		}
	}

	return FALSE;
}
Esempio n. 8
0
DBGSTATIC VOID
NetpRoundUpLargeIntegerTimeToOneSecond(
    IN OUT PLARGE_INTEGER LargeInteger
    )
{
    LARGE_INTEGER LargeRemainder;
    LARGE_INTEGER LargeResult;
    LARGE_INTEGER OriginalLargeIntegerTime = *LargeInteger;
    ULONG         Remainder = 0;

    LargeResult = RtlExtendedLargeIntegerDivide (
            OriginalLargeIntegerTime,   // dividend
            (ULONG) UNITS_PER_SECOND,
            &Remainder );

    IF_DEBUG( TIME ) {
        NetpKdPrint(( PREFIX_NETLIB
                "NetpRoundUpLargeIntegerTimeToOneSecond: remainder is "
                FORMAT_DWORD ".\n", (DWORD) Remainder ));
    }
    if (Remainder != 0) {

        LARGE_INTEGER LargeOneSecond;

        // Subtract fractional part.
        LargeRemainder.HighPart = 0;
        LargeRemainder.LowPart  = (DWORD) Remainder;


        LargeResult.QuadPart = OriginalLargeIntegerTime.QuadPart
                             - LargeRemainder.QuadPart;

        // Now add a whole second.
        LargeOneSecond.HighPart = 0;
        LargeOneSecond.LowPart  = UNITS_PER_SECOND;


        LargeResult.QuadPart += LargeOneSecond.QuadPart;

        *LargeInteger = LargeResult;

    }

} // NetpRoundUpLargeIntegerToOneSecond
Esempio n. 9
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
           );
}
Esempio n. 10
0
VOID
KiCalibrateTimeAdjustment (
    PADJUST_INTERRUPT_TIME_CONTEXT Adjust
    )

/*++

Routine Description:

    This function calibrates the adjustment of time on all processors.

Arguments:

    Adjust - Supplies the operation context.

Return Value:

    None.

--*/

{

    ULONG cl;
    ULONG divisor;
    BOOLEAN Enable;
    LARGE_INTEGER InterruptTime;
    ULARGE_INTEGER li;
    PERFINFO_PO_CALIBRATED_PERFCOUNTER LogEntry;
    LARGE_INTEGER NewTickCount;
    ULONG NewTickOffset;
    LARGE_INTEGER PerfCount;
    LARGE_INTEGER PerfFreq;
    LARGE_INTEGER SetTime;

    //
    // As each processor arrives, decrement the remaining processor count. If
    // this is the last processor to arrive, then compute the time change, and
    // signal all processor when to apply the performance counter change.
    //

    if (InterlockedDecrement((PLONG)&Adjust->KiNumber)) {
        Enable = KeDisableInterrupts();

        //
        // It is possible to deadlock if one or more of the other processors
        // receives and processes a freeze request while this processor has
        // interrupts disabled. Poll for a freeze request until all processors
        // are known to be in this code.
        //

        do {
            KiPollFreezeExecution();
        } while (Adjust->KiNumber != (ULONG)-1);

        //
        // Wait to perform the time set.
        //

        while (Adjust->Barrier);

    } else {

        //
        // Set timer expiration dpc to scan the timer queues once for any
        // expired timers.
        //

        KeRemoveQueueDpc(&KiTimerExpireDpc);
        KeInsertQueueDpc(&KiTimerExpireDpc,
                         ULongToPtr(KiQueryLowTickCount() - TIMER_TABLE_SIZE),
                         NULL);

        //
        // Disable interrupts and indicate that this processor is now
        // in final portion of this code.
        //

        Enable = KeDisableInterrupts();
        InterlockedDecrement((PLONG) &Adjust->KiNumber);

        //
        // Adjust Interrupt Time.
        //

        InterruptTime.QuadPart = KeQueryInterruptTime() + Adjust->Adjustment;
        SetTime.QuadPart = Adjust->Adjustment;

        //
        // Get the current times
        //

        PerfCount = KeQueryPerformanceCounter(&PerfFreq);

        //
        // Compute performance counter for current time.
        //
        // Multiply SetTime * PerfCount and obtain 96-bit result in cl,
        // li.LowPart, li.HighPart.  Then divide the 96-bit result by
        // 10,000,000 to get new performance counter value.
        //

        li.QuadPart = RtlEnlargedUnsignedMultiply((ULONG)SetTime.LowPart,
                                                  (ULONG)PerfFreq.LowPart).QuadPart;

        cl = li.LowPart;
        li.QuadPart =
            li.HighPart + RtlEnlargedUnsignedMultiply((ULONG)SetTime.LowPart,
                                                      (ULONG)PerfFreq.HighPart).QuadPart;

        li.QuadPart =
            li.QuadPart + RtlEnlargedUnsignedMultiply((ULONG)SetTime.HighPart,
                                                      (ULONG)PerfFreq.LowPart).QuadPart;

        li.HighPart = li.HighPart + SetTime.HighPart * PerfFreq.HighPart;
        divisor = 10000000;
        Adjust->NewCount.HighPart = RtlEnlargedUnsignedDivide(li,
                                                              divisor,
                                                              &li.HighPart);

        li.LowPart = cl;
        Adjust->NewCount.LowPart = RtlEnlargedUnsignedDivide(li,
                                                             divisor,
                                                             NULL);

        Adjust->NewCount.QuadPart += PerfCount.QuadPart;

        //
        // Compute tick count and tick offset for current interrupt time.
        //

        NewTickCount = RtlExtendedLargeIntegerDivide(InterruptTime,
                                                     KeMaximumIncrement,
                                                     &NewTickOffset);

        //
        // Apply changes to interrupt time, tick count, tick offset, and the
        // performance counter.
        //

        KiTickOffset = KeMaximumIncrement - NewTickOffset;
        KeInterruptTimeBias += Adjust->Adjustment;
        SharedUserData->TickCount.High2Time = NewTickCount.HighPart;

#if defined(_WIN64)

        SharedUserData->TickCountQuad = NewTickCount.QuadPart;

#else

        SharedUserData->TickCount.LowPart   = NewTickCount.LowPart;
        SharedUserData->TickCount.High1Time = NewTickCount.HighPart;

#endif

        //
        // N.B. There is no global tick count variable on AMD64.
        //

#if defined(_X86_)

        KeTickCount.High2Time = NewTickCount.HighPart;
        KeTickCount.LowPart   = NewTickCount.LowPart;
        KeTickCount.High1Time = NewTickCount.HighPart;

#endif

#if defined(_AMD64_)

        SharedUserData->InterruptTime.High2Time = InterruptTime.HighPart;
        *((volatile ULONG64 *)&SharedUserData->InterruptTime) = InterruptTime.QuadPart;

#else

        SharedUserData->InterruptTime.High2Time = InterruptTime.HighPart;
        SharedUserData->InterruptTime.LowPart   = InterruptTime.LowPart;
        SharedUserData->InterruptTime.High1Time = InterruptTime.HighPart;

#endif

        //
        // Apply the performance counter change.
        //

        Adjust->Barrier = 0;
    }

    KeGetCurrentPrcb()->TickOffset = KiTickOffset;

#if defined(_AMD64_)

    KeGetCurrentPrcb()->MasterOffset = KiTickOffset;

#endif

    HalCalibratePerformanceCounter((LONG volatile *)&Adjust->HalNumber,
                                   (ULONGLONG)Adjust->NewCount.QuadPart);

    //
    // Log an event that the performance counter has been calibrated
    // properly and indicate the new performance counter value.
    //

    if (PERFINFO_IS_GROUP_ON(PERF_POWER)) {
        LogEntry.PerformanceCounter = KeQueryPerformanceCounter(NULL);
        PerfInfoLogBytes(PERFINFO_LOG_TYPE_PO_CALIBRATED_PERFCOUNTER,
                         &LogEntry,
                         sizeof(LogEntry));
    }

    KeEnableInterrupts(Enable);
    return;
}
Esempio n. 11
0
/*********************************************************************
 *      TIME_ClockTimeToFileTime    ([email protected], 20-Sep-1998)
 *
 *  Used by GetProcessTimes to convert clock_t into FILETIME.
 *
 *      Differences to UnixTimeToFileTime:
 *          1) Divided by CLK_TCK
 *          2) Time is relative. There is no 'starting date', so there is
 *             no need in offset correction, like in UnixTimeToFileTime
 */
static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
{
    LONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
    ((LARGE_INTEGER *)filetime)->QuadPart =
       RtlExtendedLargeIntegerDivide( secs, sysconf( _SC_CLK_TCK ), NULL );
}
Esempio n. 12
0
BOOL
APIENTRY
GetMailslotInfo(
    IN HANDLE hMailslot,
    OUT LPDWORD lpMaxMessageSize OPTIONAL,
    OUT LPDWORD lpNextSize OPTIONAL,
    OUT LPDWORD lpMessageCount OPTIONAL,
    OUT LPDWORD lpReadTimeout OPTIONAL
    )

/*++

Routine Description:

    This function will return the requested information about the
    specified mailslot.

Arguments:

    hMailslot - A handle to the mailslot.

    lpMaxMessageSize - If specified returns the size of the largest
        message that can be written to the mailslot.

    lpNextSize - If specified returns the size of the next message in
        the mailslot buffer.  It will return MAILSLOT_NO_MESSAGE if
        there are no messages in the mailslot.

    lpMessageCount - If specified returns the number of unread message
        currently in the mailslot.

    lpReadTimeout - If specified returns the read timeout, in
        milliseconds.

Return Value:

    TRUE - The operation was successful.

    FALSE/NULL - The operation failed. Extended error status is available
        using GetLastError.

--*/

{
    NTSTATUS status;
    IO_STATUS_BLOCK ioStatusBlock;
    FILE_MAILSLOT_QUERY_INFORMATION mailslotInfo;
    LARGE_INTEGER millisecondTimeout, tmp;

    status = NtQueryInformationFile( hMailslot,
                                     &ioStatusBlock,
                                     &mailslotInfo,
                                     sizeof( mailslotInfo ),
                                     FileMailslotQueryInformation );

    if ( !NT_SUCCESS( status ) ) {
        BaseSetLastNTError( status );
        return ( FALSE );
    }

    if ( ARGUMENT_PRESENT( lpMaxMessageSize ) ) {
        *lpMaxMessageSize = mailslotInfo.MaximumMessageSize;
    }

    if ( ARGUMENT_PRESENT( lpNextSize ) ) {
        *lpNextSize = mailslotInfo.NextMessageSize;
    }

    if ( ARGUMENT_PRESENT( lpMessageCount ) ) {
        *lpMessageCount = mailslotInfo.MessagesAvailable;
    }

    if ( ARGUMENT_PRESENT( lpReadTimeout ) ) {

        //
        // Convert read timeout from 100 ns intervals to milliseconds.
        // The readtime is currently negative, since it is a relative time.
        //

        if ( mailslotInfo.ReadTimeout.HighPart != 0x7FFFFFFF
             || mailslotInfo.ReadTimeout.LowPart != 0xFFFFFFFF ) {

            tmp.QuadPart = - mailslotInfo.ReadTimeout.QuadPart;
            millisecondTimeout = RtlExtendedLargeIntegerDivide(
                                     tmp,
                                     10 * 1000,
                                     NULL );

            if ( millisecondTimeout.HighPart == 0 ) {
                *lpReadTimeout = millisecondTimeout.LowPart;
            } else {

                //
                // The millisecond calculation would overflow the dword.
                // Approximate a large number as best we can.
                //

                *lpReadTimeout = 0xFFFFFFFE;

            }

        } else {

            //
            // The mailslot timeout is infinite.
            //

            *lpReadTimeout = MAILSLOT_WAIT_FOREVER;

        }
    }

    return( TRUE );
}