/*** * This method is part of the IStream interface. * * It will move the current stream pointer according to the parameters * given. * * See the documentation of IStream for more info. */ static HRESULT WINAPI StgStreamImpl_Seek( IStream* iface, LARGE_INTEGER dlibMove, /* [in] */ DWORD dwOrigin, /* [in] */ ULARGE_INTEGER* plibNewPosition) /* [out] */ { StgStreamImpl* const This=(StgStreamImpl*)iface; ULARGE_INTEGER newPosition; TRACE("(%p, %ld, %ld, %p)\n", iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition); /* * fail if the stream has no parent (as does windows) */ if (!This->parentStorage) return STG_E_REVERTED; /* * The caller is allowed to pass in NULL as the new position return value. * If it happens, we assign it to a dynamic variable to avoid special cases * in the code below. */ if (plibNewPosition == 0) { plibNewPosition = &newPosition; } /* * The file pointer is moved depending on the given "function" * parameter. */ switch (dwOrigin) { case STREAM_SEEK_SET: plibNewPosition->u.HighPart = 0; plibNewPosition->u.LowPart = 0; break; case STREAM_SEEK_CUR: *plibNewPosition = This->currentPosition; break; case STREAM_SEEK_END: *plibNewPosition = This->streamSize; break; default: return STG_E_INVALIDFUNCTION; } plibNewPosition->QuadPart = RtlLargeIntegerAdd( plibNewPosition->QuadPart, dlibMove.QuadPart ); /* * tell the caller what we calculated */ This->currentPosition = *plibNewPosition; return S_OK; }
VOID SoundMixerChangedItem( IN OUT PMIXER_INFO MixerInfo, IN OUT PMIXER_DATA_ITEM MixerItem ) { ASSERTMSG("Invalid mixer info!", MixerInfo->Key == MIX_INFO_KEY); /* ** There are 2 tasks : ** ** 1. Increment the current 'logical' time ** ** 2. Move the item to the head of the list and set its current time ** ** 3. Notify all those waiting for notification */ RemoveEntryList(&MixerItem->Entry); MixerInfo->CurrentLogicalTime = RtlLargeIntegerAdd(MixerInfo->CurrentLogicalTime, RtlConvertLongToLargeInteger(1L)); MixerItem->LastSet = MixerInfo->CurrentLogicalTime; InsertHeadList(&MixerInfo->ChangedItems, &MixerItem->Entry); /* ** Complete all notification Irps. */ { KIRQL OldIrql; PIRP pIrp; while (TRUE) { pIrp = SoundRemoveFromCancellableQ(&MixerInfo->NotifyQueue); if (pIrp == NULL) { break; } SoundMixerNotify(pIrp, MixerInfo); } } }
/*** * This method is part of the IStream interface. * * It will move the current stream pointer according to the parameters * given. * * See the documentation of IStream for more info. */ static HRESULT WINAPI HGLOBALStreamImpl_Seek( IStream* iface, LARGE_INTEGER dlibMove, /* [in] */ DWORD dwOrigin, /* [in] */ ULARGE_INTEGER* plibNewPosition) /* [out] */ { HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface; ULARGE_INTEGER newPosition; TRACE("(%p, %lx%08lx, %ld, %p)\n", iface, dlibMove.u.HighPart, dlibMove.u.LowPart, dwOrigin, plibNewPosition); /* * The file pointer is moved depending on the given "function" * parameter. */ switch (dwOrigin) { case STREAM_SEEK_SET: newPosition.u.HighPart = 0; newPosition.u.LowPart = 0; break; case STREAM_SEEK_CUR: newPosition = This->currentPosition; break; case STREAM_SEEK_END: newPosition = This->streamSize; break; default: return STG_E_INVALIDFUNCTION; } /* * Move the actual file pointer * If the file pointer ends-up after the end of the stream, the next Write operation will * make the file larger. This is how it is documented. */ if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart) return STG_E_INVALIDFUNCTION; newPosition.QuadPart = RtlLargeIntegerAdd(newPosition.QuadPart, dlibMove.QuadPart); if (plibNewPosition) *plibNewPosition = newPosition; This->currentPosition = newPosition; return S_OK; }
NTSTATUS NTAPI ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId) { LARGE_INTEGER NewLuid, PrevLuid; /* atomically increment the luid */ do { PrevLuid = LuidValue; NewLuid = RtlLargeIntegerAdd(PrevLuid, LuidIncrement); } while(ExInterlockedCompareExchange64(&LuidValue.QuadPart, &NewLuid.QuadPart, &PrevLuid.QuadPart, NULL) != PrevLuid.QuadPart); LocallyUniqueId->LowPart = NewLuid.u.LowPart; LocallyUniqueId->HighPart = NewLuid.u.HighPart; return STATUS_SUCCESS; }
NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress, ULONG PhysMemSizeInBytes, PVOID *ppPhysMemLin, HANDLE *pPhysicalMemoryHandle) { UNICODE_STRING PhysicalMemoryUnicodeString; PVOID PhysicalMemorySection = NULL; OBJECT_ATTRIBUTES ObjectAttributes; PHYSICAL_ADDRESS ViewBase; NTSTATUS ntStatus; PHYSICAL_ADDRESS pStartPhysAddress; PHYSICAL_ADDRESS pEndPhysAddress; PHYSICAL_ADDRESS MappingLength; BOOLEAN Result1, Result2; ULONG IsIOSpace; unsigned char *pbPhysMemLin = NULL; OutputDebugString ("Entering MapPhysicalMemoryToLinearSpace"); RtlInitUnicodeString (&PhysicalMemoryUnicodeString, L"\\Device\\PhysicalMemory"); InitializeObjectAttributes (&ObjectAttributes, &PhysicalMemoryUnicodeString, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL); *pPhysicalMemoryHandle = NULL; ntStatus = ZwOpenSection (pPhysicalMemoryHandle, SECTION_ALL_ACCESS, &ObjectAttributes); if (NT_SUCCESS(ntStatus)) { ntStatus = ObReferenceObjectByHandle (*pPhysicalMemoryHandle, SECTION_ALL_ACCESS, (POBJECT_TYPE) NULL, KernelMode, &PhysicalMemorySection, (POBJECT_HANDLE_INFORMATION) NULL); if (NT_SUCCESS(ntStatus)) { pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress; pEndPhysAddress = RtlLargeIntegerAdd (pStartPhysAddress, RtlConvertUlongToLargeInteger(PhysMemSizeInBytes)); IsIOSpace = 0; Result1 = HalTranslateBusAddress (1, 0, pStartPhysAddress, &IsIOSpace, &pStartPhysAddress); IsIOSpace = 0; Result2 = HalTranslateBusAddress (1, 0, pEndPhysAddress, &IsIOSpace, &pEndPhysAddress); if (Result1 && Result2) { MappingLength = RtlLargeIntegerSubtract (pEndPhysAddress, pStartPhysAddress); if (MappingLength.LowPart) { // Let ZwMapViewOfSection pick a linear address PhysMemSizeInBytes = MappingLength.LowPart; ViewBase = pStartPhysAddress; ntStatus = ZwMapViewOfSection (*pPhysicalMemoryHandle, (HANDLE) -1, &pbPhysMemLin, 0L, PhysMemSizeInBytes, &ViewBase, &PhysMemSizeInBytes, ViewShare, 0, PAGE_READWRITE | PAGE_NOCACHE); if (!NT_SUCCESS(ntStatus)) OutputDebugString ("ERROR: ZwMapViewOfSection failed"); else { pbPhysMemLin += (ULONG)pStartPhysAddress.LowPart - (ULONG)ViewBase.LowPart; *ppPhysMemLin = pbPhysMemLin; } } else OutputDebugString ("ERROR: RtlLargeIntegerSubtract failed"); } else OutputDebugString ("ERROR: MappingLength = 0"); } else OutputDebugString ("ERROR: ObReferenceObjectByHandle failed"); } else OutputDebugString ("ERROR: ZwOpenSection failed"); if (!NT_SUCCESS(ntStatus)) ZwClose(*pPhysicalMemoryHandle); OutputDebugString ("Leaving MapPhysicalMemoryToLinearSpace"); return ntStatus; }
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 ); }