Example #1
0
/***********************************************************************
 *      NtQuerySystemTime   (NTDLL.@)
 *      ZwQuerySystemTime   (NTDLL.@)
 */
NTSTATUS WINAPI NtQuerySystemTime( PLARGE_INTEGER time )
{
    LONGLONG secs;
    struct timeval now;

    gettimeofday( &now, 0 );
    secs = now.tv_sec + SECS_1601_TO_1970;
    time->QuadPart = RtlExtendedIntegerMultiply( secs, 10000000 ) + now.tv_usec * 10;
    return STATUS_SUCCESS;
}
Example #2
0
//* TdiQueryInformation - Query Information handler.
//
//	The TDI QueryInformation routine. Called when the client wants to
//	query information on a connection, the provider as a whole, or to
//	get statistics.
//
//	Input:	Request				- The request structure for this command.
//			QueryType			- The type of query to be performed.
//			Buffer				- Buffer to place data into.
//			BufferSize			- Pointer to size in bytes of buffer. On return,
//									filled in with bytes copied.
//			IsConn				- Valid only for TDI_QUERY_ADDRESS_INFO. TRUE
//									if we are querying the address info on
//									a connection.
//
//	Returns: Status of attempt to query information.
//
TDI_STATUS
TdiQueryInformation(PTDI_REQUEST Request, uint QueryType, PNDIS_BUFFER Buffer,
	uint *BufferSize, uint IsConn)
{
	union {
		TDI_CONNECTION_INFO		ConnInfo;
		TDI_ADDRESS_INFO		AddrInfo;
		TDI_PROVIDER_INFO		ProviderInfo;
		TDI_PROVIDER_STATISTICS	ProviderStats;
	} InfoBuf;

	uint			InfoSize;
	CTELockHandle	ConnTableHandle, TCBHandle, AddrHandle, AOHandle;
#ifndef UDP_ONLY
	TCPConn			*Conn;
	TCB				*InfoTCB;
#endif
	AddrObj			*InfoAO;
	void			*InfoPtr = NULL;
	uint			Offset;
	uint			Size;
    uint            BytesCopied;

	switch (QueryType) {
		
		case TDI_QUERY_BROADCAST_ADDRESS:
			return TDI_INVALID_QUERY;
			break;

		case TDI_QUERY_PROVIDER_INFO:
			InfoBuf.ProviderInfo.Version = 0x100;
#ifndef UDP_ONLY
			InfoBuf.ProviderInfo.MaxSendSize = 0xffffffff;
#else
			InfoBuf.ProviderInfo.MaxSendSize = 0;
#endif
			InfoBuf.ProviderInfo.MaxConnectionUserData = 0;
			InfoBuf.ProviderInfo.MaxDatagramSize = 0xffff - sizeof(UDPHeader);
			InfoBuf.ProviderInfo.ServiceFlags = MY_SERVICE_FLAGS;
			InfoBuf.ProviderInfo.MinimumLookaheadData = 1;
			InfoBuf.ProviderInfo.MaximumLookaheadData = 0xffff;
			InfoBuf.ProviderInfo.NumberOfResources = 0;
			InfoBuf.ProviderInfo.StartTime.LowPart = StartTime;
			InfoBuf.ProviderInfo.StartTime.HighPart = 0;
			InfoSize = sizeof(TDI_PROVIDER_INFO);
			InfoPtr = &InfoBuf.ProviderInfo;
			break;

		case TDI_QUERY_ADDRESS_INFO:
			InfoSize = sizeof(TDI_ADDRESS_INFO) - sizeof(TRANSPORT_ADDRESS) +
				TCP_TA_SIZE;
			CTEMemSet(&InfoBuf.AddrInfo, 0, TCP_TA_SIZE);
			InfoBuf.AddrInfo.ActivityCount = 1;		// Since noone knows what
													// this means, we'll set
													// it to one.

			if (IsConn) {
#ifdef UDP_ONLY
				return TDI_INVALID_QUERY;
#else

				CTEGetLock(&AddrObjTableLock, &AddrHandle);
				CTEGetLock(&ConnTableLock, &ConnTableHandle);
				Conn = GetConnFromConnID((uint)Request->Handle.ConnectionContext);
	
				if (Conn != NULL) {
					CTEStructAssert(Conn, tc);
					
					InfoTCB = Conn->tc_tcb;
					// If we have a TCB we'll
					// return information about that TCB. Otherwise we'll return
					// info about the address object.
					if (InfoTCB != NULL) {
						CTEStructAssert(InfoTCB, tcb);		
						CTEGetLock(&InfoTCB->tcb_lock, &TCBHandle);
						CTEFreeLock(&ConnTableLock, TCBHandle);
						CTEFreeLock(&AddrObjTableLock, ConnTableHandle);
						BuildTDIAddress((uchar *)&InfoBuf.AddrInfo.Address,
							InfoTCB->tcb_saddr, InfoTCB->tcb_sport);
						CTEFreeLock(&InfoTCB->tcb_lock, AddrHandle);
						InfoPtr = &InfoBuf.AddrInfo;
						break;
					} else {
						// No TCB, return info on the AddrObj.
						InfoAO = Conn->tc_ao;
						if (InfoAO != NULL) {
							// We have an AddrObj.
							CTEStructAssert(InfoAO, ao);
							CTEGetLock(&InfoAO->ao_lock, &AOHandle);
							BuildTDIAddress((uchar *)&InfoBuf.AddrInfo.Address,
								InfoAO->ao_addr, InfoAO->ao_port);
							CTEFreeLock(&InfoAO->ao_lock, AOHandle);
							CTEFreeLock(&ConnTableLock, ConnTableHandle);
							CTEFreeLock(&AddrObjTableLock, AddrHandle);
							InfoPtr = &InfoBuf.AddrInfo;
							break;
						}
					}

				}

				// Fall through to here when we can't find the connection, or
				// the connection isn't associated.
				CTEFreeLock(&ConnTableLock, ConnTableHandle);
				CTEFreeLock(&AddrObjTableLock, AddrHandle);
				return TDI_INVALID_CONNECTION;
				break;

#endif
			} else {
				// Asking for information on an addr. object.
#ifdef VXD
				InfoAO = GetIndexedAO((uint)Request->Handle.AddressHandle);

				if (InfoAO == NULL)
					return TDI_ADDR_INVALID;
#else	
				InfoAO = Request->Handle.AddressHandle;
#endif

				CTEStructAssert(InfoAO, ao);
	
				CTEGetLock(&InfoAO->ao_lock, &AOHandle);

				if (!AO_VALID(InfoAO)) {
					CTEFreeLock(&InfoAO->ao_lock, AOHandle);
					return TDI_ADDR_INVALID;
				}

				BuildTDIAddress((uchar *)&InfoBuf.AddrInfo.Address,
					InfoAO->ao_addr, InfoAO->ao_port);
				CTEFreeLock(&InfoAO->ao_lock, AOHandle);
				InfoPtr = &InfoBuf.AddrInfo;
				break;
			}
				
			break;

		case TDI_QUERY_CONNECTION_INFO:
#ifndef UDP_ONLY
			InfoSize = sizeof(TDI_CONNECTION_INFO);
			CTEGetLock(&ConnTableLock, &ConnTableHandle);
			Conn = GetConnFromConnID((uint)Request->Handle.ConnectionContext);

			if (Conn != NULL) {
				CTEStructAssert(Conn, tc);
				
				InfoTCB = Conn->tc_tcb;
				// If we have a TCB we'll return the information. Otherwise
				// we'll error out.
				if (InfoTCB != NULL) {
					
					ulong			TotalTime;
					ulong			BPS, PathBPS;
					IP_STATUS		IPStatus;
					CTEULargeInt	TempULargeInt;
					
					CTEStructAssert(InfoTCB, tcb);		
					CTEGetLock(&InfoTCB->tcb_lock, &TCBHandle);
					CTEFreeLock(&ConnTableLock, TCBHandle);
					CTEMemSet(&InfoBuf.ConnInfo, 0, sizeof(TDI_CONNECTION_INFO));
					InfoBuf.ConnInfo.State = (ulong)InfoTCB->tcb_state;
					IPStatus = (*LocalNetInfo.ipi_getpinfo)(InfoTCB->tcb_daddr,
						InfoTCB->tcb_saddr, NULL, &PathBPS);
					
					if (IPStatus != IP_SUCCESS) {
						InfoBuf.ConnInfo.Throughput.LowPart = 0xFFFFFFFF;
						InfoBuf.ConnInfo.Throughput.HighPart = 0xFFFFFFFF;
					} else {
						InfoBuf.ConnInfo.Throughput.HighPart = 0;
						TotalTime = InfoTCB->tcb_totaltime /
							(1000 / MS_PER_TICK);
						if (TotalTime != 0) {
							TempULargeInt.LowPart = InfoTCB->tcb_bcountlow;
							TempULargeInt.HighPart = InfoTCB->tcb_bcounthi;
							
							BPS = CTEEnlargedUnsignedDivide(TempULargeInt,
								TotalTime, NULL);
							InfoBuf.ConnInfo.Throughput.LowPart =
								MIN(BPS, PathBPS);
						} else
							InfoBuf.ConnInfo.Throughput.LowPart = PathBPS;
					}
							
							

					// To figure the delay we use the rexmit timeout. Our
					// rexmit timeout is roughly the round trip time plus
					// some slop, so we use half of that as the one way delay.
#ifdef VXD
					InfoBuf.ConnInfo.Delay.LowPart =
						(REXMIT_TO(InfoTCB) * MS_PER_TICK) / 2;
					InfoBuf.ConnInfo.Throughput.HighPart = 0;
#else // VXD
                    InfoBuf.ConnInfo.Delay.LowPart =
                        (REXMIT_TO(InfoTCB) * MS_PER_TICK) / 2;
                    InfoBuf.ConnInfo.Delay.HighPart = 0;
					//
					// Convert milliseconds to 100ns and negate for relative
					// time.
					//
					InfoBuf.ConnInfo.Delay =
					    RtlExtendedIntegerMultiply(
						    InfoBuf.ConnInfo.Delay,
							10000
							);

                    CTEAssert(InfoBuf.ConnInfo.Delay.HighPart == 0);

					InfoBuf.ConnInfo.Delay.QuadPart =
                        -InfoBuf.ConnInfo.Delay.QuadPart;

#endif // VXD
					CTEFreeLock(&InfoTCB->tcb_lock, ConnTableHandle);
					InfoPtr = &InfoBuf.ConnInfo;
					break;
				}

			}

			// Come through here if we can't find the connection or it has
			// no TCB.
			CTEFreeLock(&ConnTableLock, ConnTableHandle);
			return TDI_INVALID_CONNECTION;
			break;

#else // UDP_ONLY
			return TDI_INVALID_QUERY;
			break;
#endif // UDP_ONLY
		case TDI_QUERY_PROVIDER_STATISTICS:
			CTEMemSet(&InfoBuf.ProviderStats, 0, sizeof(TDI_PROVIDER_STATISTICS));
			InfoBuf.ProviderStats.Version = 0x100;
			InfoSize = sizeof(TDI_PROVIDER_STATISTICS);
			InfoPtr = &InfoBuf.ProviderStats;
			break;
		default:
			return TDI_INVALID_QUERY;
			break;
	}

	// When we get here, we've got the pointers set up and the information
	// filled in.

	CTEAssert(InfoPtr != NULL);
	Offset = 0;
	Size = *BufferSize;
	(void)CopyFlatToNdis(Buffer, InfoPtr, MIN(InfoSize, Size), &Offset,
              &BytesCopied);
	if (Size < InfoSize)
		return TDI_BUFFER_OVERFLOW;
	else {
		*BufferSize = InfoSize;
		return TDI_SUCCESS;
	}
}
Example #3
0
/******************************************************************************
 *  RtlSecondsSince1980ToTime		[NTDLL.@]
 */
void WINAPI RtlSecondsSince1980ToTime( DWORD time, LARGE_INTEGER *res )
{
    LONGLONG secs = time + SECS_1601_to_1980;
    res->QuadPart = RtlExtendedIntegerMultiply( secs, 10000000 );
}
Example #4
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
           );
}