ULONG APIENTRY EngSaveFloatingPointState( PVOID Buffer, ULONG BufferSize) { KFLOATING_SAVE TempBuffer; NTSTATUS Status; if ((Buffer == NULL) || (BufferSize == 0)) { /* Check for floating point support. */ Status = KeSaveFloatingPointState(&TempBuffer); if (Status != STATUS_SUCCESS) { return(0); } KeRestoreFloatingPointState(&TempBuffer); return(sizeof(KFLOATING_SAVE)); } if (BufferSize < sizeof(KFLOATING_SAVE)) { return(0); } Status = KeSaveFloatingPointState((PKFLOATING_SAVE)Buffer); if (!NT_SUCCESS(Status)) { return FALSE; } return TRUE; }
BOOL APIENTRY NtGdiArcInternal( ARCTYPE arctype, HDC hDC, int LeftRect, int TopRect, int RightRect, int BottomRect, int XStartArc, int YStartArc, int XEndArc, int YEndArc) { DC *dc; BOOL Ret; KFLOATING_SAVE FloatSave; dc = DC_LockDc (hDC); if(!dc) { EngSetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (dc->dctype == DC_TYPE_INFO) { DC_UnlockDc(dc); /* Yes, Windows really returns TRUE in this case */ return TRUE; } DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds, NULL, dc->rosdc.CombinedClip->rclBounds); if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(dc); if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) DC_vUpdateLineBrush(dc); KeSaveFloatingPointState(&FloatSave); Ret = IntGdiArcInternal( arctype, dc, LeftRect, TopRect, RightRect, BottomRect, XStartArc, YStartArc, XEndArc, YEndArc); KeRestoreFloatingPointState(&FloatSave); DC_vFinishBlit(dc, NULL); DC_UnlockDc( dc ); return Ret; }
BOOL APIENTRY NtGdiAngleArc( IN HDC hDC, IN INT x, IN INT y, IN DWORD dwRadius, IN DWORD dwStartAngle, IN DWORD dwSweepAngle) { DC *pDC; BOOL Ret = FALSE; gxf_long worker, worker1; KFLOATING_SAVE FloatSave; pDC = DC_LockDc (hDC); if(!pDC) { EngSetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (pDC->dctype == DC_TYPE_INFO) { DC_UnlockDc(pDC); /* Yes, Windows really returns TRUE in this case */ return TRUE; } KeSaveFloatingPointState(&FloatSave); worker.l = dwStartAngle; worker1.l = dwSweepAngle; DC_vPrepareDCsForBlit(pDC, pDC->rosdc.CombinedClip->rclBounds, NULL, pDC->rosdc.CombinedClip->rclBounds); if (pDC->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(pDC); if (pDC->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) DC_vUpdateLineBrush(pDC); Ret = IntGdiAngleArc( pDC, x, y, dwRadius, worker.f, worker1.f); DC_vFinishBlit(pDC, NULL); DC_UnlockDc( pDC ); KeRestoreFloatingPointState(&FloatSave); return Ret; }
void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount) { byte *data = dataPtr; #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KFLOATING_SAVE floatingPointState; #endif if (cipher == AES && (blockCount & (32 - 1)) == 0 && IsAesHwCpuSupported() #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) && NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState)) #endif ) { while (blockCount > 0) { aes_hw_cpu_decrypt_32_blocks ((byte *) ks + sizeof (aes_encrypt_ctx), data); data += 32 * 16; blockCount -= 32; } #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KeRestoreFloatingPointState (&floatingPointState); #endif } else { size_t blockSize = CipherGetBlockSize (cipher); while (blockCount-- > 0) { DecipherBlock (cipher, data, ks); data += blockSize; } } }
// Exercises all existing regression tests static void test() { KFLOATING_SAVE float_save; NTSTATUS status; // Any of Capstone APIs cannot be called at IRQL higher than DISPATCH_LEVEL // since our malloc implementation using ExAllocatePoolWithTag() is able to // allocate memory only up to the DISPATCH_LEVEL level. NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); // On a 32bit driver, KeSaveFloatingPointState() is required before using any // Capstone function because Capstone can access to the MMX/x87 registers and // 32bit Windows requires drivers to use KeSaveFloatingPointState() before and // KeRestoreFloatingPointState() after accesing to them. See "Using Floating // Point or MMX in a WDM Driver" on MSDN for more details. status = KeSaveFloatingPointState(&float_save); if (!NT_SUCCESS(status)) { printf("ERROR: Failed to save floating point state!\n"); return; } unnamed::test(); detail::test(); skipdata::test(); iter::test(); arm::test(); arm64::test(); mips::test(); ppc::test(); sparc::test(); systemz::test(); x86::test(); xcore::test(); // Restores the nonvolatile floating-point context. KeRestoreFloatingPointState(&float_save); }
NTSTATUS UartRegConvertAndValidateBaud ( _In_ ULONG SpeedBPS, _Out_ USHORT * DivisorLatch ) { NTSTATUS status = STATUS_SUCCESS; USHORT divisor = 0; ULONG realBaud = 0; status = UartRegBaudToDivisorLatch(SpeedBPS, &divisor); if (NT_SUCCESS(status)) { // // Determine if difference between desired and real // baud rate is within acceptable tolerance. // status = UartRegDivisorLatchToBaud( divisor, &realBaud); if (NT_SUCCESS(status)) { ULONG baudDifference; if (SpeedBPS > realBaud) { baudDifference = SpeedBPS - realBaud; } else { baudDifference = realBaud - SpeedBPS; } KFLOATING_SAVE kFloatSave; status = KeSaveFloatingPointState(&kFloatSave); if (NT_SUCCESS(status)) { if((DOUBLE)(baudDifference) / (DOUBLE)SpeedBPS > UartBaudRateErrorTolerance) { status = STATUS_INVALID_PARAMETER; TraceMessage( TRACE_LEVEL_ERROR, TRACE_FLAG_CONTROL, "Desired baudrate %lu exceeds error tolerance " "(%.2f%%) - %!STATUS!", SpeedBPS, (UartBaudRateErrorTolerance*100), status); } KeRestoreFloatingPointState(&kFloatSave); } else { TraceMessage( TRACE_LEVEL_ERROR, TRACE_FLAG_CONTROL, "Failure saving floating point state - %!STATUS!", status); } } } if (NT_SUCCESS(status)) { *DivisorLatch = divisor; } return status; }