BOOL WTSFreeMemoryExA(
WTS_TYPE_CLASS WTSTypeClass,
PVOID pMemory,
ULONG NumberOfEntries
);
WTS_TYPE_CLASS declared in WtsApi32.h as
enum _WTS_TYPE_CLASS {
WTSTypeProcessInfoLevel0 = 0x0,
WTSTypeProcessInfoLevel1 = 0x1,
WTSTypeSessionInfoLevel1 = 0x2,
};
ok, check in disasm what happens:
WTSFreeMemoryExA proc near
push rbx
sub rsp, 20h
xor ebx, ebx
cmp ecx, ebx
jl short loc_7FF70582EC2
cmp ecx, 1 ; whut ?
jg short loc_7FF70582EC2
call WTSFreeMemoryExW
mov ebx, eax
jmp short loc_7FF70582ECD
loc_7FF70582EC2:
mov ecx, 87 ; dwErrCode - ERROR_INVALID_PARAMETER
call cs:__imp_SetLastError
as you can see you cannot pass WTSTypeSessionInfoLevel1 to function WTSFreeMemoryExA - it gives error ERROR_INVALID_PARAMETER. As dirty workaround you can use WTSFreeMemoryExW - it has correct checking of WTSTypeClass. btw this lead to memory leaks and known at least since 2013