replace nob with ms' build, move disk creation to build.bat, major comment cleanup, remove old and stupid tests, overhaul interrupt management with per-CPU vector allocation, affinity migration and safe teardown, add proper IOAPIC routing and PCI MSI/MSI-X/INTx support, migrate drivers to the new interrupt API, integrate ACPICA with a proper OS services layer, move ACPI firmware events, power button handling and S5 shutdown into acpi.sys, add parallel driver startup and atomic publication, replace PnP arrays with dynamic lists, redesign service startup again to be asynchronous, add delayed startup mode for services, allow omitting keys in services.ini, fix acpi ec deferred work handling, fix kernel threads having garbage exit code.
This commit is contained in:
1 parent
d36f19509c
commit
36eef8f58d
696 files changed
+147281
-7530
No files matched your search
@@ -19,7 +19,7 @@
|
||||
#include <ntlite/atomic.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <ntlite/native_heap.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
@@ -148,7 +148,6 @@ typedef struct _MEMORY_BASIC_INFORMATION {
|
||||
DWORD Type;
|
||||
} MEMORY_BASIC_INFORMATION;
|
||||
|
||||
// Implements the win Protect To Sys Vm operation.
|
||||
static uint32_t WinProtectToSysVm(DWORD protect) {
|
||||
switch (protect) {
|
||||
case PAGE_NOACCESS: return SYS_VM_NOACCESS;
|
||||
@@ -182,7 +181,6 @@ static uint32_t WinFileMapAccessToSys(DWORD desiredAccess) {
|
||||
return access;
|
||||
}
|
||||
|
||||
// Implements the protect Vm To Win operation.
|
||||
static DWORD SysProtectVmToWin(uint32_t protect) {
|
||||
switch (protect) {
|
||||
case SYS_VM_NOACCESS: return PAGE_NOACCESS;
|
||||
@@ -279,7 +277,6 @@ static void TranslatePath(const char* input, char* output) {
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
// Implements the k32 Open File Native operation.
|
||||
static KSTATUS K32OpenFileNative(const char* path,
|
||||
uint32_t access,
|
||||
uint32_t disposition,
|
||||
@@ -287,23 +284,19 @@ static KSTATUS K32OpenFileNative(const char* path,
|
||||
return NtlOpenFile(SysSvFromCstr(path), access, disposition, SYS_FILE_FLAG_NONE, handleOut);
|
||||
}
|
||||
|
||||
// Implements the k32 Delete File Native operation.
|
||||
static KSTATUS K32DeleteFileNative(const char* path) {
|
||||
return NtlDeleteFile(SysSvFromCstr(path));
|
||||
}
|
||||
|
||||
// Implements the k32 Open Dir Native operation.
|
||||
static KSTATUS K32OpenDirNative(const char* path, uint32_t* handleOut) {
|
||||
return NtlOpenDir(SysSvFromCstr(path), SYS_DIR_ACCESS_ENUMERATE | SYS_DIR_ACCESS_OPEN,
|
||||
SYS_DIR_FLAG_NONE, handleOut);
|
||||
}
|
||||
|
||||
// Implements the k32 Set Cwd Native operation.
|
||||
static KSTATUS K32SetCwdNative(const char* path) {
|
||||
return NtlSetCurrentDirectory(SysSvFromCstr(path));
|
||||
}
|
||||
|
||||
// Implements the k32 Get Cwd Native operation.
|
||||
static KSTATUS K32GetCwdNative(char* buffer, size_t capacity, size_t* lengthOut) {
|
||||
size_t required = 0;
|
||||
KSTATUS status = NtlGetCurrentDirectory(buffer, capacity, &required);
|
||||
@@ -347,12 +340,10 @@ static KSTATUS K32CreateProcessNative(const char* path, uint32_t imageFile, uint
|
||||
return NtlCreateSystemProcess(&req);
|
||||
}
|
||||
|
||||
// Implements the k32 Write Console Span operation.
|
||||
static void K32WriteConsoleSpan(const char* data, size_t length) {
|
||||
(void)NtlConsoleWrite(SYS_HANDLE_INVALID, data, length, 0);
|
||||
}
|
||||
|
||||
// Implements the k32 Debug Print A operation.
|
||||
static void K32DebugPrintA(const char* s) {
|
||||
if (!s) return;
|
||||
SYS_PRINT_DEBUG_REQUEST req = { sizeof(SYS_PRINT_DEBUG_REQUEST), SysSvFromCstr(s) };
|
||||
@@ -373,7 +364,6 @@ typedef struct WIN32_THREAD_ENV {
|
||||
|
||||
static WIN32_THREAD_ENV gFallbackThreadEnv;
|
||||
|
||||
// Implements the k32 Thread Env operation.
|
||||
static WIN32_THREAD_ENV* K32ThreadEnv(void) {
|
||||
SYS_TEB* teb = SysGetTeb();
|
||||
if (!teb || teb->Magic != SYS_TEB_MAGIC) return &gFallbackThreadEnv;
|
||||
@@ -388,7 +378,6 @@ static WIN32_THREAD_ENV* K32ThreadEnv(void) {
|
||||
return env;
|
||||
}
|
||||
|
||||
// Implements the k32 Last Error Slot operation.
|
||||
static DWORD* K32LastErrorSlot(void) {
|
||||
return &K32ThreadEnv()->LastError;
|
||||
}
|
||||
@@ -398,7 +387,6 @@ static DWORD* K32LastErrorSlot(void) {
|
||||
// Returns a stable nonzero identifier for the calling thread.
|
||||
static DWORD K32CurrentTidOrOne(void);
|
||||
|
||||
// Implements the file Exists A operation.
|
||||
static BOOL KiFileExistsA(const char* path) {
|
||||
if (!path || !*path) return FALSE;
|
||||
char native[MAX_PATH];
|
||||
@@ -483,7 +471,6 @@ __declspec(dllexport) DWORD SearchPathA(const char* lpPath, const char* lpFileNa
|
||||
// GetLastError / SetLastError (single-threaded stub).
|
||||
static SYS_PEB* gProcessPeb = NULL;
|
||||
|
||||
// Implements the peb operation.
|
||||
static SYS_PEB* Win32Peb(void) {
|
||||
if (!gProcessPeb) gProcessPeb = SysGetPeb();
|
||||
return gProcessPeb;
|
||||
@@ -558,7 +545,6 @@ __declspec(dllexport) void* HeapAlloc(void* heap, DWORD flags, size_t size) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// Implements the heap Free operation.
|
||||
__declspec(dllexport) BOOL HeapFree(void* heap, DWORD flags, void* ptr) {
|
||||
(void)heap; (void)flags;
|
||||
// Win32's HeapFree doesn't need the size; we pass 0 and the user-mode heap carries the block size.
|
||||
@@ -624,7 +610,6 @@ __declspec(dllexport) void* VirtualAlloc(void* lpAddress, size_t dwSize,
|
||||
return base;
|
||||
}
|
||||
|
||||
// Implements the virtual Free operation.
|
||||
__declspec(dllexport) BOOL VirtualFree(void* lpAddress, size_t dwSize, DWORD dwFreeType) {
|
||||
(void)dwSize; (void)dwFreeType;
|
||||
if (!lpAddress) return TRUE;
|
||||
@@ -1255,13 +1240,11 @@ __declspec(dllexport) HANDLE HeapCreate(DWORD flOptions,
|
||||
return (HANDLE)(uintptr_t)1; // non-NULL sentinel
|
||||
}
|
||||
|
||||
// Implements the heap Destroy operation.
|
||||
__declspec(dllexport) BOOL HeapDestroy(HANDLE hHeap) {
|
||||
(void)hHeap;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Implements the heap Size operation.
|
||||
__declspec(dllexport) size_t HeapSize(HANDLE heap, DWORD flags, const void* ptr) {
|
||||
(void)heap; (void)flags;
|
||||
size_t size = _malloc_usable_size(ptr);
|
||||
@@ -1297,7 +1280,6 @@ __declspec(dllexport) DWORD GetCurrentProcessId(void) { return (DWORD)SysGetCurr
|
||||
// Tiny TLS index allocator; slot values are stored per thread in WIN32_THREAD_ENV.
|
||||
static uint64_t gTlsBitmap = 1; // reserve slot 0
|
||||
|
||||
// Implements the tls Alloc operation.
|
||||
__declspec(dllexport) DWORD TlsAlloc(void) {
|
||||
for (DWORD i = 1; i < WIN32_TLS_SLOTS; i++) {
|
||||
uint64_t bit = 1ULL << i;
|
||||
@@ -1307,7 +1289,6 @@ __declspec(dllexport) DWORD TlsAlloc(void) {
|
||||
return 0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
// Implements the tls Free operation.
|
||||
__declspec(dllexport) BOOL TlsFree(DWORD dwTlsIndex) {
|
||||
if (dwTlsIndex >= WIN32_TLS_SLOTS || !(gTlsBitmap & (1ULL << dwTlsIndex))) { gLastError = 87; return FALSE; }
|
||||
WIN32_THREAD_ENV* env = K32ThreadEnv();
|
||||
@@ -1316,7 +1297,6 @@ __declspec(dllexport) BOOL TlsFree(DWORD dwTlsIndex) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Implements the tls Get Value operation.
|
||||
__declspec(dllexport) void* TlsGetValue(DWORD dwTlsIndex) {
|
||||
if (dwTlsIndex >= WIN32_TLS_SLOTS || !(gTlsBitmap & (1ULL << dwTlsIndex))) { gLastError = 87; return NULL; }
|
||||
WIN32_THREAD_ENV* env = K32ThreadEnv();
|
||||
@@ -1324,7 +1304,6 @@ __declspec(dllexport) void* TlsGetValue(DWORD dwTlsIndex) {
|
||||
return env->TlsSlots[dwTlsIndex];
|
||||
}
|
||||
|
||||
// Implements the tls Set Value operation.
|
||||
__declspec(dllexport) BOOL TlsSetValue(DWORD dwTlsIndex, void* lpTlsValue) {
|
||||
if (dwTlsIndex >= WIN32_TLS_SLOTS || !(gTlsBitmap & (1ULL << dwTlsIndex))) { gLastError = 87; return FALSE; }
|
||||
WIN32_THREAD_ENV* env = K32ThreadEnv();
|
||||
@@ -1336,7 +1315,6 @@ __declspec(dllexport) BOOL TlsSetValue(DWORD dwTlsIndex, void* lpTlsValue) {
|
||||
#define WIN32_HMODULE_EXE ((HANDLE)(uintptr_t)0x00400000UL)
|
||||
#define WIN32_HMODULE_WIN32 ((HANDLE)(uintptr_t)0x57333232UL) // W322
|
||||
|
||||
// Implements the stricmp A operation.
|
||||
static int KiStricmpA(const char* a, const char* b) {
|
||||
while (*a && (((unsigned char)*a | 0x20) == ((unsigned char)*b | 0x20))) { a++; b++; }
|
||||
return ((unsigned char)*a | 0x20) - ((unsigned char)*b | 0x20);
|
||||
@@ -1370,7 +1348,6 @@ static BOOL KiIsWin32DllNameA(const char* name) {
|
||||
KiMatchesWin32DllNameA(name, "win32");
|
||||
}
|
||||
|
||||
// Implements the dbg Write A operation.
|
||||
static void KiDbgWriteA(const char* s) {
|
||||
if (s) K32WriteConsoleSpan(s, strlen(s));
|
||||
}
|
||||
@@ -1532,7 +1509,6 @@ __declspec(dllexport) DWORD GetModuleFileNameA(HANDLE hModule,
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Implements the terminate Process operation.
|
||||
__declspec(dllexport) BOOL TerminateProcess(HANDLE hProcess, unsigned int uExitCode) {
|
||||
if (hProcess == GetCurrentProcess()) {
|
||||
SysExitProcess((int32_t)uExitCode);
|
||||
@@ -1744,7 +1720,6 @@ __declspec(dllexport) BOOL ResetEvent(HANDLE hEvent) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Implements the extract Application Path A operation.
|
||||
static BOOL ExtractApplicationPathA(const char* commandLine, char* out, size_t outSize) {
|
||||
if (!commandLine || !out || outSize == 0) return FALSE;
|
||||
|
||||
@@ -1906,7 +1881,6 @@ __declspec(dllexport) uintptr_t SetThreadAffinityMask(HANDLE hThread,
|
||||
return 1; // previous mask: CPU 0 only
|
||||
}
|
||||
|
||||
// Implements the sleep operation.
|
||||
__declspec(dllexport) void Sleep(DWORD dwMilliseconds) {
|
||||
SysSleep(dwMilliseconds);
|
||||
}
|
||||
@@ -1917,20 +1891,17 @@ __declspec(dllexport) void Sleep(DWORD dwMilliseconds) {
|
||||
#define STD_OUTPUT_HANDLE ((DWORD)-11)
|
||||
#define STD_ERROR_HANDLE ((DWORD)-12)
|
||||
|
||||
// Implements the k32 Is Std Handle Value operation.
|
||||
static BOOL K32IsStdHandleValue(HANDLE h, DWORD stdHandle) {
|
||||
uintptr_t value = (uintptr_t)h;
|
||||
return value == (uintptr_t)stdHandle || value == (uintptr_t)(intptr_t)(int32_t)stdHandle;
|
||||
}
|
||||
|
||||
// Implements the k32 Is Console Output Handle operation.
|
||||
static BOOL K32IsConsoleOutputHandle(HANDLE h) {
|
||||
return h && h != INVALID_HANDLE_VALUE &&
|
||||
(K32IsStdHandleValue(h, STD_OUTPUT_HANDLE) ||
|
||||
K32IsStdHandleValue(h, STD_ERROR_HANDLE));
|
||||
}
|
||||
|
||||
// Implements the k32 Set Console Last Error operation.
|
||||
static void K32SetConsoleLastError(KSTATUS status) {
|
||||
switch (status) {
|
||||
case NTLSTATUS_SUCCESS:
|
||||
@@ -2206,12 +2177,10 @@ static void SplitFindPath(const char* searchPath,
|
||||
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020UL
|
||||
#define FILE_ATTRIBUTE_NORMAL 0x00000080UL
|
||||
|
||||
// Implements the k32 Dir Is Leap Year operation.
|
||||
static bool K32DirIsLeapYear(unsigned int year) {
|
||||
return ((year % 4u) == 0u && (year % 100u) != 0u) || ((year % 400u) == 0u);
|
||||
}
|
||||
|
||||
// Implements the k32 Dir Days In Month operation.
|
||||
static unsigned int K32DirDaysInMonth(unsigned int year, unsigned int month) {
|
||||
static const unsigned char days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
|
||||
if (month < 1u || month > 12u) return 31u;
|
||||
@@ -2219,7 +2188,6 @@ static unsigned int K32DirDaysInMonth(unsigned int year, unsigned int month) {
|
||||
return days[month - 1u];
|
||||
}
|
||||
|
||||
// Implements the k32 Dir Calendar To Epoch Seconds operation.
|
||||
static uint64_t K32DirCalendarToEpochSeconds(const SYS_SYSTEM_TIME* st) {
|
||||
uint64_t days = 0;
|
||||
for (unsigned int y = 1970u; y < st->Year; y++)
|
||||
@@ -2230,7 +2198,6 @@ static uint64_t K32DirCalendarToEpochSeconds(const SYS_SYSTEM_TIME* st) {
|
||||
return (((days * 24u) + st->Hour) * 60u + st->Minute) * 60u + st->Second;
|
||||
}
|
||||
|
||||
// Implements the k32 Dir Store File Time operation.
|
||||
static void K32DirStoreFileTime(FILETIME* ft, const SYS_SYSTEM_TIME* st) {
|
||||
if (!ft || !st || !(st->Flags & SYS_TIME_FLAG_VALID) || st->Year < 1970u) {
|
||||
if (ft) { ft->dwLowDateTime = 0; ft->dwHighDateTime = 0; }
|
||||
@@ -2245,7 +2212,6 @@ static void K32DirStoreFileTime(FILETIME* ft, const SYS_SYSTEM_TIME* st) {
|
||||
ft->dwHighDateTime = (DWORD)(value >> 32);
|
||||
}
|
||||
|
||||
// Implements the kdir To Find Data operation.
|
||||
static void KdirToFindData(const KDIR_ENTRY* ke, WIN32_FIND_DATAA* fd) {
|
||||
// Zero the entire struct (covers all FILETIME and reserved fields).
|
||||
unsigned char* p = (unsigned char*)fd;
|
||||
@@ -2554,7 +2520,6 @@ __declspec(dllexport) BOOL InitializeCriticalSectionAndSpinCount(CRITICAL_SECTIO
|
||||
}
|
||||
// Releases critical Section.
|
||||
__declspec(dllexport) void DeleteCriticalSection(CRITICAL_SECTION* lpCS) { (void)lpCS; }
|
||||
// Implements the enter Critical Section operation.
|
||||
__declspec(dllexport) void EnterCriticalSection(CRITICAL_SECTION* lpCS) {
|
||||
if (!lpCS) return;
|
||||
DWORD tid = K32CurrentTidOrOne();
|
||||
@@ -2571,7 +2536,6 @@ __declspec(dllexport) void EnterCriticalSection(CRITICAL_SECTION* lpCS) {
|
||||
lpCS->Owner = tid;
|
||||
lpCS->Recursion = 1;
|
||||
}
|
||||
// Implements the leave Critical Section operation.
|
||||
__declspec(dllexport) void LeaveCriticalSection(CRITICAL_SECTION* lpCS) {
|
||||
if (!lpCS) return;
|
||||
DWORD tid = K32CurrentTidOrOne();
|
||||
@@ -2584,7 +2548,6 @@ __declspec(dllexport) void LeaveCriticalSection(CRITICAL_SECTION* lpCS) {
|
||||
NtlAtomicExchange32(&lpCS->Lock, 0);
|
||||
}
|
||||
}
|
||||
// Implements the try Enter Critical Section operation.
|
||||
__declspec(dllexport) BOOL TryEnterCriticalSection(CRITICAL_SECTION* lpCS) {
|
||||
if (!lpCS) return FALSE;
|
||||
DWORD tid = K32CurrentTidOrOne();
|
||||
@@ -2826,7 +2789,6 @@ static long long TscFreqCalibrate(void) {
|
||||
return (int64_t)(delta_tsc * 1000000ULL / delta_us);
|
||||
}
|
||||
|
||||
// Implements the tsc Freq Get operation.
|
||||
static long long TscFreqGet(void) {
|
||||
int64_t cached = NtlAtomicLoad64(&gTscFreq);
|
||||
if (cached)
|
||||
@@ -2855,12 +2817,10 @@ __declspec(dllexport) BOOL QueryPerformanceCounter(LARGE_INTEGER* lpPerformanceC
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Implements the k32 Is Leap Year operation.
|
||||
static BOOL K32IsLeapYear(unsigned int year) {
|
||||
return ((year % 4u) == 0u && (year % 100u) != 0u) || ((year % 400u) == 0u);
|
||||
}
|
||||
|
||||
// Implements the k32 Days In Month operation.
|
||||
static unsigned int K32DaysInMonth(unsigned int year, unsigned int month) {
|
||||
static const unsigned char days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
|
||||
if (month == 2u && K32IsLeapYear(year)) return 29u;
|
||||
@@ -2868,7 +2828,6 @@ static unsigned int K32DaysInMonth(unsigned int year, unsigned int month) {
|
||||
return days[month - 1u];
|
||||
}
|
||||
|
||||
// Implements the k32 Calendar To Epoch Seconds operation.
|
||||
static uint64_t K32CalendarToEpochSeconds(const SYSTEMTIME* st) {
|
||||
uint64_t days = 0;
|
||||
for (unsigned int y = 1970u; y < st->wYear; y++)
|
||||
@@ -2879,14 +2838,12 @@ static uint64_t K32CalendarToEpochSeconds(const SYSTEMTIME* st) {
|
||||
return (((days * 24u) + st->wHour) * 60u + st->wMinute) * 60u + st->wSecond;
|
||||
}
|
||||
|
||||
// Implements the k32 Epoch To File Time operation.
|
||||
static uint64_t K32EpochToFileTime(uint64_t epochSeconds, uint32_t nanosecond) {
|
||||
const uint64_t WINDOWS_EPOCH_BIAS_SECONDS = 11644473600ULL;
|
||||
return (epochSeconds + WINDOWS_EPOCH_BIAS_SECONDS) * 10000000ULL +
|
||||
((uint64_t)nanosecond / 100ULL);
|
||||
}
|
||||
|
||||
// Implements the k32 Store File Time operation.
|
||||
static void K32StoreFileTime(FILETIME* ft, uint64_t value) {
|
||||
ft->dwLowDateTime = (DWORD)(value & 0xFFFFFFFFULL);
|
||||
ft->dwHighDateTime = (DWORD)(value >> 32);
|
||||
@@ -3663,7 +3620,6 @@ __declspec(dllexport) void RaiseException(DWORD dwExceptionCode, DWORD dwExcepti
|
||||
SysExitProcess((int32_t)status);
|
||||
}
|
||||
|
||||
// Implements the unhandled Exception Filter operation.
|
||||
__declspec(dllexport) long UnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo) {
|
||||
(void)ExceptionInfo;
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
@@ -3698,7 +3654,6 @@ __declspec(dllexport) BOOL RtlAddFunctionTable(RUNTIME_FUNCTION* FunctionTable,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Implements the rtl Delete Function Table operation.
|
||||
__declspec(dllexport) BOOL RtlDeleteFunctionTable(RUNTIME_FUNCTION* FunctionTable) {
|
||||
(void)FunctionTable;
|
||||
return TRUE;
|
||||
@@ -3729,7 +3684,6 @@ __declspec(dllexport) void* RtlVirtualUnwind(unsigned long HandlerType,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Implements the rtl Capture Context operation.
|
||||
__declspec(dllexport) void RtlCaptureContext(void* ContextRecord) {
|
||||
// Zero out the context record so callers don't read garbage.
|
||||
if (!ContextRecord) return;
|
||||
@@ -3813,7 +3767,6 @@ __declspec(dllexport) int GetLocaleInfoA(unsigned int Locale, DWORD LCType,
|
||||
|
||||
static int gFlsUsed[FLS_MAX_SLOTS]; // 0 = free, 1 = allocated
|
||||
|
||||
// Implements the fls Alloc operation.
|
||||
__declspec(dllexport) DWORD FlsAlloc(void* lpCallback) {
|
||||
(void)lpCallback;
|
||||
for (int i = 0; i < FLS_MAX_SLOTS; i++) {
|
||||
@@ -3827,7 +3780,6 @@ __declspec(dllexport) DWORD FlsAlloc(void* lpCallback) {
|
||||
return (DWORD)FLS_OUT_OF_INDEXES;
|
||||
}
|
||||
|
||||
// Implements the fls Get Value operation.
|
||||
__declspec(dllexport) void* FlsGetValue(DWORD dwFlsIndex) {
|
||||
if (dwFlsIndex >= FLS_MAX_SLOTS || !gFlsUsed[dwFlsIndex]) {
|
||||
gLastError = 87; // ERROR_INVALID_PARAMETER
|
||||
@@ -3836,7 +3788,6 @@ __declspec(dllexport) void* FlsGetValue(DWORD dwFlsIndex) {
|
||||
return K32ThreadEnv()->FlsSlots[dwFlsIndex];
|
||||
}
|
||||
|
||||
// Implements the fls Set Value operation.
|
||||
__declspec(dllexport) BOOL FlsSetValue(DWORD dwFlsIndex, void* lpFlsData) {
|
||||
if (dwFlsIndex >= FLS_MAX_SLOTS || !gFlsUsed[dwFlsIndex]) {
|
||||
gLastError = 87;
|
||||
@@ -3846,7 +3797,6 @@ __declspec(dllexport) BOOL FlsSetValue(DWORD dwFlsIndex, void* lpFlsData) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Implements the fls Free operation.
|
||||
__declspec(dllexport) BOOL FlsFree(DWORD dwFlsIndex) {
|
||||
if (dwFlsIndex >= FLS_MAX_SLOTS || !gFlsUsed[dwFlsIndex]) {
|
||||
gLastError = 87;
|
||||
@@ -3861,5 +3811,4 @@ __declspec(dllexport) BOOL FlsFree(DWORD dwFlsIndex) {
|
||||
// We have no security cookie; return the pointer unchanged.
|
||||
|
||||
__declspec(dllexport) void* EncodePointer(void* Ptr) { return Ptr; }
|
||||
// Implements the decode Pointer operation.
|
||||
__declspec(dllexport) void* DecodePointer(void* Ptr) { return Ptr; }
|
||||
Reference in new issue
Block a user