// Kernel surface storage. This file owns shared backing frames, mappings, commit generations, and privileged presentation. #include #include #include #include #include #include #include #include #include #include #include #include #include typedef struct KE_SURFACE { OBJECT Header; uint32_t Width; uint32_t Height; uint32_t PitchBytes; uint32_t Format; uint32_t Flags; size_t PayloadSize; size_t PageCount; bool StatsRegistered; bool LastDamageValid; uint16_t Reserved; uint32_t Reserved2; uint64_t MapCount; uint64_t ContentGeneration; uint64_t CommitCount; uint64_t CommitRectCount; uint64_t CommitClippedRectCount; uint64_t CommitEmptyClipCount; DISPLAY_RECT LastDamageBounds; PHYSICAL_ADDRESS* Frames; MM_KERNEL_VIEW* KernelView; void* KernelBase; EVENT* CommitEvent; MUTEX* Lock; } KE_SURFACE; static SPINLOCK gSurfaceStatsLock = SPINLOCK_INIT; static SYS_SURFACE_STATS gSurfaceStats; // Multiplies two sizes while rejecting overflow. static bool KiSurfaceMulSize(size_t a, size_t b, size_t* out) { if (!out || (a != 0 && b > SIZE_MAX / a)) return false; *out = a * b; return true; } // Aligns one size upward while rejecting wraparound. static size_t KiSurfaceAlignUp(size_t value, size_t alignment) { if (!alignment || (alignment & (alignment - 1u))) return 0; size_t mask = alignment - 1u; if (value > SIZE_MAX - mask) return 0; return (value + mask) & ~mask; } // Converts a generic object reference to a surface only when its type is correct. static KE_SURFACE* KiSurfaceFromObject(OBJECT* object) { if (!object || object->Type != ObjectTypeSurface) return (KE_SURFACE*)0; return CONTAINING_RECORD(object, KE_SURFACE, Header); } // Registers a surface in the global telemetry snapshot. static void KiSurfaceStatsRegister(KE_SURFACE* surface) { if (!surface || surface->StatsRegistered) return; uintptr_t irq = KeAcquireSpinlock(&gSurfaceStatsLock); gSurfaceStats.CreatedSurfaces++; gSurfaceStats.LiveSurfaces++; gSurfaceStats.LivePages += surface->PageCount; gSurfaceStats.LiveBytes += surface->PayloadSize; surface->StatsRegistered = true; KeReleaseSpinlock(&gSurfaceStatsLock, irq); } // Removes a surface from the global telemetry snapshot. static void KiSurfaceStatsUnregister(KE_SURFACE* surface) { if (!surface || !surface->StatsRegistered) return; uintptr_t irq = KeAcquireSpinlock(&gSurfaceStatsLock); gSurfaceStats.DestroyedSurfaces++; if (gSurfaceStats.LiveSurfaces) gSurfaceStats.LiveSurfaces--; gSurfaceStats.LivePages = gSurfaceStats.LivePages >= surface->PageCount ? gSurfaceStats.LivePages - surface->PageCount : 0; gSurfaceStats.LiveBytes = gSurfaceStats.LiveBytes >= surface->PayloadSize ? gSurfaceStats.LiveBytes - surface->PayloadSize : 0; surface->StatsRegistered = false; KeReleaseSpinlock(&gSurfaceStatsLock, irq); } // Records one successful surface mapping operation. static void KiSurfaceStatsRecordMap(KE_SURFACE* surface) { uintptr_t irq = KeAcquireSpinlock(&gSurfaceStatsLock); surface->MapCount++; gSurfaceStats.MapCalls++; KeReleaseSpinlock(&gSurfaceStatsLock, irq); } // Records one commit after rectangle validation and clipping. static void KiSurfaceStatsRecordCommit(uint64_t inputRects, uint64_t clippedRects, uint64_t emptyClips) { uintptr_t irq = KeAcquireSpinlock(&gSurfaceStatsLock); gSurfaceStats.CommitCalls++; gSurfaceStats.CommitRectInputs += inputRects; gSurfaceStats.CommitClippedRects += clippedRects; gSurfaceStats.CommitEmptyClips += emptyClips; KeReleaseSpinlock(&gSurfaceStatsLock, irq); } // Records one presentation performed through DisplayManager authority. static void KiSurfaceStatsRecordPresent(uint64_t bytesCopied) { uintptr_t irq = KeAcquireSpinlock(&gSurfaceStatsLock); gSurfaceStats.PhysicalPresentCalls++; gSurfaceStats.PhysicalPresentBytesCopied += bytesCopied; KeReleaseSpinlock(&gSurfaceStatsLock, irq); } // Releases surface storage. User VADs retain their own backing-frame references until unmapped. static void KiSurfaceDestroy(OBJECT* object) { KE_SURFACE* surface = KiSurfaceFromObject(object); if (!surface) return; KiSurfaceStatsUnregister(surface); if (surface->KernelView) { MmDestroyKernelView(surface->KernelView); surface->KernelView = (MM_KERNEL_VIEW*)0; surface->KernelBase = (void*)0; } if (surface->CommitEvent) { ObDereferenceObject(&surface->CommitEvent->Header); surface->CommitEvent = (EVENT*)0; } if (surface->Lock) { ObDereferenceObject(&surface->Lock->Header); surface->Lock = (MUTEX*)0; } if (surface->Frames) { for (size_t i = 0; i < surface->PageCount; ++i) if (surface->Frames[i]) (void)MmPfnRelease(surface->Frames[i]); MmFreePool(surface->Frames); surface->Frames = (PHYSICAL_ADDRESS*)0; } } // Clips one rectangle to the surface extent. static bool KiSurfaceClipRect(const KE_SURFACE* surface, const DISPLAY_RECT* input, DISPLAY_RECT* output) { if (!surface || !output) return false; DISPLAY_RECT r; if (input) { r = *input; } else { r.X = 0; r.Y = 0; r.W = (int32_t)surface->Width; r.H = (int32_t)surface->Height; } if (r.W <= 0 || r.H <= 0) return false; int64_t x0 = r.X; int64_t y0 = r.Y; int64_t x1 = x0 + r.W; int64_t y1 = y0 + r.H; if (x0 < 0) x0 = 0; if (y0 < 0) y0 = 0; if (x1 > surface->Width) x1 = surface->Width; if (y1 > surface->Height) y1 = surface->Height; if (x0 >= x1 || y0 >= y1) return false; output->X = (int32_t)x0; output->Y = (int32_t)y0; output->W = (int32_t)(x1 - x0); output->H = (int32_t)(y1 - y0); return true; } // Expands one damage bound to include another clipped rectangle. static void KiSurfaceUnionRect(DISPLAY_RECT* bounds, const DISPLAY_RECT* rect) { int32_t x0 = bounds->X < rect->X ? bounds->X : rect->X; int32_t y0 = bounds->Y < rect->Y ? bounds->Y : rect->Y; int32_t bx1 = bounds->X + bounds->W; int32_t by1 = bounds->Y + bounds->H; int32_t rx1 = rect->X + rect->W; int32_t ry1 = rect->Y + rect->H; int32_t x1 = bx1 > rx1 ? bx1 : rx1; int32_t y1 = by1 > ry1 ? by1 : ry1; bounds->X = x0; bounds->Y = y0; bounds->W = x1 - x0; bounds->H = y1 - y0; } // Clips one kernel-captured rectangle list. A zero count means the whole surface. static KSTATUS KiSurfaceCaptureRects(KE_SURFACE* surface, const DISPLAY_RECT* rects, uint32_t rectCount, DISPLAY_RECT* clippedOut, uint32_t* clippedCountOut, uint64_t* emptyOut) { if (!surface || !clippedOut || !clippedCountOut || !emptyOut) return NTLSTATUS_INVALID_PARAMETER; if (rectCount > SYS_SURFACE_MAX_RECTS || (rectCount && !rects)) return NTLSTATUS_INVALID_PARAMETER; DISPLAY_RECT whole = {0, 0, (int32_t)surface->Width, (int32_t)surface->Height}; if (!rectCount) { rects = &whole; rectCount = 1; } uint32_t clippedCount = 0; uint64_t empty = 0; for (uint32_t i = 0; i < rectCount; ++i) { DISPLAY_RECT clipped; if (!KiSurfaceClipRect(surface, &rects[i], &clipped)) { empty++; continue; } clippedOut[clippedCount++] = clipped; } *clippedCountOut = clippedCount; *emptyOut = empty; return NTLSTATUS_SUCCESS; } // Creates one surface storage object and returns its initial object reference. KSTATUS KeSurfaceCreate(uint32_t width, uint32_t height, uint32_t format, uint32_t flags, OBJECT** surfaceOut) { if (!surfaceOut) return NTLSTATUS_INVALID_PARAMETER; *surfaceOut = (OBJECT*)0; if (!width || !height || width > SYS_SURFACE_MAX_DIMENSION || height > SYS_SURFACE_MAX_DIMENSION) return NTLSTATUS_INVALID_PARAMETER; if (format != SYS_SURFACE_FORMAT_XRGB8888 || flags != SYS_SURFACE_FLAG_NONE) return NTLSTATUS_NOT_SUPPORTED; size_t rowBytes = 0; if (!KiSurfaceMulSize((size_t)width, sizeof(uint32_t), &rowBytes)) return NTLSTATUS_INVALID_PARAMETER; size_t pitchBytes = KiSurfaceAlignUp(rowBytes, 64u); if (!pitchBytes || pitchBytes < rowBytes) return NTLSTATUS_INVALID_PARAMETER; size_t payloadSize = 0; if (!KiSurfaceMulSize(pitchBytes, (size_t)height, &payloadSize) || payloadSize > SYS_SURFACE_MAX_BYTES) return NTLSTATUS_INVALID_PARAMETER; size_t pageCount = (payloadSize + PAGE_SIZE - 1u) / PAGE_SIZE; if (!pageCount || pageCount > SIZE_MAX / sizeof(PHYSICAL_ADDRESS)) return NTLSTATUS_INVALID_PARAMETER; KE_SURFACE* surface = (KE_SURFACE*)ObAllocateObject(ObjectTypeSurface, sizeof(KE_SURFACE)); if (!surface) return NTLSTATUS_NO_MEMORY; surface->Header.Destroy = KiSurfaceDestroy; surface->Width = width; surface->Height = height; surface->PitchBytes = (uint32_t)pitchBytes; surface->Format = format; surface->Flags = flags; surface->PayloadSize = payloadSize; surface->PageCount = pageCount; surface->Frames = (PHYSICAL_ADDRESS*)MmAllocatePoolTag(pageCount * sizeof(PHYSICAL_ADDRESS), MM_POOL_TAG('s', 'f', 'r', 'm')); if (surface->Frames) memset(surface->Frames, 0, pageCount * sizeof(PHYSICAL_ADDRESS)); KSTATUS status = KeMutexCreate(&surface->Lock); if (KSUCCESS(status)) status = KeEventCreate(EventAutoReset, 0, &surface->CommitEvent); if (!surface->Frames || !KSUCCESS(status)) { ObDereferenceObject(&surface->Header); return !surface->Frames ? NTLSTATUS_NO_MEMORY : status; } for (size_t i = 0; i < pageCount; ++i) { PHYSICAL_ADDRESS frame = MmPfnAllocate(MmPfnUseSurface); if (!frame) { ObDereferenceObject(&surface->Header); return NTLSTATUS_NO_MEMORY; } surface->Frames[i] = frame; void* kva = MmPfnToVirtual(frame); if (kva) memset(kva, 0, PAGE_SIZE); } status = MmCreateKernelViewFromFrames(surface->Frames, surface->PageCount, &surface->KernelView); if (!KSUCCESS(status)) { ObDereferenceObject(&surface->Header); return status; } surface->KernelBase = MmKernelViewBase(surface->KernelView); KiSurfaceStatsRegister(surface); *surfaceOut = &surface->Header; return NTLSTATUS_SUCCESS; } // Maps one surface into the calling process's VAD namespace with attenuated page permissions. KSTATUS KeSurfaceMap(PROCESS* process, OBJECT* object, uint32_t flags, void** baseOut, uint32_t* pitchBytesOut) { KE_SURFACE* surface = KiSurfaceFromObject(object); if (!process || !surface || !baseOut || !pitchBytesOut || !(flags & SYS_SURFACE_MAP_READ) || (flags & ~(SYS_SURFACE_MAP_READ | SYS_SURFACE_MAP_WRITE))) return NTLSTATUS_INVALID_PARAMETER; uint64_t pageFlags = PAGE_PRESENT | PAGE_USER | PAGE_NX; if (flags & SYS_SURFACE_MAP_WRITE) pageFlags |= PAGE_WRITE; KSTATUS status = MmVadCreateSharedViewFromFrames(process, surface->Frames, surface->PageCount, surface->PayloadSize, pageFlags, MM_VAD_SURFACE, MmVadShared, baseOut); if (KSUCCESS(status)) { *pitchBytesOut = surface->PitchBytes; KiSurfaceStatsRecordMap(surface); } return status; } // Removes one mapping only when the supplied VAD is a surface shared view owned by the process. KSTATUS KeSurfaceUnmap(PROCESS* process, void* base) { if (!process || !base) return NTLSTATUS_INVALID_PARAMETER; void* vadBase = (void*)0; size_t vadSize = 0; uint64_t pageFlags = 0; MM_VAD_TYPE type = MmVadGeneric; uint32_t vadFlags = 0; KSTATUS status = MmVadQuery(process, base, &vadBase, &vadSize, &pageFlags, &type, &vadFlags); (void)vadSize; (void)pageFlags; if (!KSUCCESS(status)) return status; if (vadBase != base || type != MmVadShared || !(vadFlags & MM_VAD_SURFACE)) return NTLSTATUS_INVALID_PARAMETER; return MmVadDestroy(process, base); } // Snapshots one surface's storage and commit metadata. KSTATUS KeSurfaceQuery(OBJECT* object, SYS_SURFACE_DESC* descOut) { KE_SURFACE* surface = KiSurfaceFromObject(object); if (!surface || !descOut) return NTLSTATUS_INVALID_PARAMETER; memset(descOut, 0, sizeof(*descOut)); KSTATUS status = KeAcquireMutex(surface->Lock, KE_WAIT_INFINITE); if (!KE_MUTEX_ACQUIRE_SUCCEEDED(status)) return status; descOut->Width = surface->Width; descOut->Height = surface->Height; descOut->PitchBytes = surface->PitchBytes; descOut->Format = surface->Format; descOut->PayloadBytes = surface->PayloadSize; descOut->PageCount = surface->PageCount; descOut->ContentGeneration = surface->ContentGeneration; descOut->CommitCount = surface->CommitCount; descOut->CommitRectCount = surface->CommitRectCount; descOut->CommitClippedRectCount = surface->CommitClippedRectCount; descOut->CommitEmptyClipCount = surface->CommitEmptyClipCount; descOut->LastDamageBounds = surface->LastDamageBounds; descOut->LastDamageValid = surface->LastDamageValid; KeReleaseMutex(surface->Lock); uintptr_t irq = KeAcquireSpinlock(&gSurfaceStatsLock); descOut->MapCount = surface->MapCount; KeReleaseSpinlock(&gSurfaceStatsLock, irq); return NTLSTATUS_SUCCESS; } // Announces changed pixels without touching physical scanout. KSTATUS KeSurfaceCommit(OBJECT* object, const DISPLAY_RECT* rects, uint32_t rectCount, uint64_t* generationOut) { KE_SURFACE* surface = KiSurfaceFromObject(object); if (!surface) return NTLSTATUS_INVALID_PARAMETER; uint32_t requestedCount = rectCount ? rectCount : 1u; DISPLAY_RECT clipped[SYS_SURFACE_MAX_RECTS]; uint32_t clippedCount = 0; uint64_t emptyCount = 0; KSTATUS status = KiSurfaceCaptureRects(surface, rects, rectCount, clipped, &clippedCount, &emptyCount); if (!KSUCCESS(status)) return status; status = KeAcquireMutex(surface->Lock, KE_WAIT_INFINITE); if (!KE_MUTEX_ACQUIRE_SUCCEEDED(status)) return status; surface->ContentGeneration++; surface->CommitCount++; surface->CommitRectCount += requestedCount; surface->CommitClippedRectCount += clippedCount; surface->CommitEmptyClipCount += emptyCount; surface->LastDamageValid = clippedCount ? 1u : 0u; if (clippedCount) { surface->LastDamageBounds = clipped[0]; for (uint32_t i = 1; i < clippedCount; ++i) KiSurfaceUnionRect(&surface->LastDamageBounds, &clipped[i]); } else { memset(&surface->LastDamageBounds, 0, sizeof(surface->LastDamageBounds)); } uint64_t generation = surface->ContentGeneration; KeReleaseMutex(surface->Lock); KiSurfaceStatsRecordCommit(requestedCount, clippedCount, emptyCount); KeSignalEvent(surface->CommitEvent); if (generationOut) *generationOut = generation; return NTLSTATUS_SUCCESS; } // Presents one surface after a caller has separately proved DisplayManager PRESENT authority. KSTATUS KeSurfacePresent(OBJECT* object, const DISPLAY_RECT* rects, uint32_t rectCount, uint64_t* bytesCopiedOut) { KE_SURFACE* surface = KiSurfaceFromObject(object); if (!surface || !bytesCopiedOut) return NTLSTATUS_INVALID_PARAMETER; DISPLAY_RECT clipped[SYS_SURFACE_MAX_RECTS]; uint32_t clippedCount = 0; uint64_t emptyCount = 0; KSTATUS status = KiSurfaceCaptureRects(surface, rects, rectCount, clipped, &clippedCount, &emptyCount); (void)emptyCount; if (!KSUCCESS(status)) return status; if (!surface->KernelBase) return NTLSTATUS_DEVICE_ERROR; const uint8_t* sourceBase = (const uint8_t*)surface->KernelBase; uint64_t bytesCopied = 0; for (uint32_t i = 0; i < clippedCount; ++i) { const DISPLAY_RECT* rect = &clipped[i]; const uint32_t* source = (const uint32_t*)(sourceBase + (size_t)(uint32_t)rect->Y * surface->PitchBytes + (size_t)(uint32_t)rect->X * sizeof(uint32_t)); status = KeDisplayPresentPitched(rect->X, rect->Y, rect->W, rect->H, source, surface->PitchBytes); if (!KSUCCESS(status)) return status; bytesCopied += (uint64_t)(uint32_t)rect->W * (uint64_t)(uint32_t)rect->H * sizeof(uint32_t); } *bytesCopiedOut = bytesCopied; KiSurfaceStatsRecordPresent(bytesCopied); return NTLSTATUS_SUCCESS; } // Returns the passive event used to wait for commit-generation changes. EVENT* KeSurfaceWaitEvent(OBJECT* object) { KE_SURFACE* surface = KiSurfaceFromObject(object); return surface ? surface->CommitEvent : (EVENT*)0; } // Snapshots global surface telemetry. void KeSurfaceQueryStats(SYS_SURFACE_STATS* statsOut) { if (!statsOut) return; uintptr_t irq = KeAcquireSpinlock(&gSurfaceStatsLock); *statsOut = gSurfaceStats; statsOut->Size = sizeof(*statsOut); statsOut->Version = SYS_STATS_VERSION; KeReleaseSpinlock(&gSurfaceStatsLock, irq); }