[WIN32KNT_APITEST][NTUSER] Fix NtUserConvertMemHandle BSOD (#7878)

Fix NtUserConvertMemHandle BSOD.

JIRA issue: CORE-18121
This commit is contained in:
Max Korostil
2026-04-13 03:10:34 +03:00
committed by GitHub
parent cbfc755c2f
commit feb9febaae
4 changed files with 138 additions and 2 deletions

View File

@@ -53,6 +53,7 @@ list(APPEND SOURCE
# ntuser/NtUserCallHwndParamLock.c
# ntuser/NtUserCallNoParam.c
# ntuser/NtUserCallOneParam.c
ntuser/NtUserConvertMemHandle.c
ntuser/NtUserCountClipboardFormats.c
ntuser/NtUserCreateAcceleratorTable.c
ntuser/NtUserCreateWindowEx.c

View File

@@ -0,0 +1,132 @@
/*
* PROJECT: ReactOS api tests
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Test for NtUserConvertMemHandle
* COPYRIGHT: Copyright 2025 Max Korostil (mrmks04@yandex.ru)
*/
#include "../win32nt.h"
HGLOBAL createGlobalMemory(const CHAR* pString, DWORD stringLength)
{
HGLOBAL hGlobalBuffer = NULL;
CHAR* pLockedBuffer = NULL;
hGlobalBuffer = GlobalAlloc(GMEM_DDESHARE, stringLength);
if (hGlobalBuffer == NULL)
{
return hGlobalBuffer;
}
pLockedBuffer = (CHAR*)GlobalLock(hGlobalBuffer);
if (pLockedBuffer)
{
memcpy(pLockedBuffer, pString, stringLength);
}
GlobalUnlock(hGlobalBuffer);
return hGlobalBuffer;
}
HANDLE setClipboardData(UINT uFormat, HANDLE hGlobalMem)
{
DWORD dwSize = 0;
PVOID pMem = NULL;
HANDLE hRet = NULL;
HANDLE hMem = NULL;
SETCLIPBDATA scd = {FALSE, FALSE};
// Get global memory
pMem = GlobalLock(hGlobalMem);
dwSize = GlobalSize(hGlobalMem);
hMem = NtUserConvertMemHandle(pMem, dwSize);
GlobalUnlock(hGlobalMem);
if (hMem == NULL)
{
return hMem;
}
scd.fGlobalHandle = TRUE;
hRet = NtUserSetClipboardData(uFormat, hMem, &scd);
return hRet;
}
HANDLE getClipboardData(UINT uFormat)
{
HANDLE hData = NULL;
HANDLE hGlobal = NULL;
PVOID pData = NULL;
DWORD cbData = 0;
GETCLIPBDATA gcd;
hData = NtUserGetClipboardData(uFormat, &gcd);
if (gcd.fGlobalHandle)
{
NtUserCreateLocalMemHandle(hData, NULL, 0, &cbData);
hGlobal = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbData);
if (hGlobal == NULL)
{
return hGlobal;
}
pData = GlobalLock(hGlobal);
NtUserCreateLocalMemHandle(hData, pData, cbData, NULL);
GlobalUnlock(hGlobal);
}
return hGlobal;
}
START_TEST(NtUserConvertMemHandle)
{
HANDLE hMem;
CONST CHAR testString[] = "Test string";
HGLOBAL hGlobal = NULL;
hMem = NtUserConvertMemHandle(UlongToPtr(0xDEADBEEF), 0xFFFF);
ok_hdl(hMem, NULL);
// Alloc global memory
hGlobal = createGlobalMemory(testString, sizeof(testString));
if (hGlobal == NULL)
{
skip("hGlobal is NULL\n");
}
else
{
HANDLE hMem = NULL;
HANDLE hRet = NULL;
OpenClipboard(NULL);
hRet = setClipboardData(CF_TEXT, hGlobal);
CloseClipboard();
if (hRet == NULL)
{
skip("Set clipboard data failed\n");
goto cleanup;
}
OpenClipboard(NULL);
hMem = getClipboardData(CF_TEXT);
CloseClipboard();
if (hMem)
{
PVOID pData = GlobalLock(hMem);
ok_long(memcmp(pData, testString, sizeof(testString)), 0);
GlobalUnlock(hMem);
}
else
{
skip("Get clipboard data failed\n");
}
cleanup:
GlobalFree(hGlobal);
}
}

View File

@@ -48,6 +48,7 @@ extern void func_NtGdiTransformPoints(void);
//extern void func_NtUserCallHwndParamLock(void);
//extern void func_NtUserCallNoParam(void);
//extern void func_NtUserCallOneParam(void);
extern void func_NtUserConvertMemHandle(void);
extern void func_NtUserCountClipboardFormats(void);
extern void func_NtUserCreateAcceleratorTable(void);
extern void func_NtUserCreateWindowEx(void);
@@ -121,6 +122,7 @@ const struct test winetest_testlist[] =
//{ "NtUserCallHwndParamLock", func_NtUserCallHwndParamLock },
//{ "NtUserCallNoParam", func_NtUserCallNoParam },
//{ "NtUserCallOneParam", func_NtUserCallOneParam },
{ "NtUserConvertMemHandle", func_NtUserConvertMemHandle },
{ "NtUserCountClipboardFormats", func_NtUserCountClipboardFormats },
{ "NtUserCreateAcceleratorTable", func_NtUserCreateAcceleratorTable },
{ "NtUserCreateWindowEx", func_NtUserCreateWindowEx },

View File

@@ -1190,6 +1190,7 @@ NtUserConvertMemHandle(
{
HANDLE hMem = NULL;
PCLIPBOARDDATA pMemObj;
NTSTATUS Status = STATUS_SUCCESS;
UserEnterExclusive();
@@ -1208,7 +1209,7 @@ NtUserConvertMemHandle(
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
pMemObj = NULL;
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
@@ -1216,7 +1217,7 @@ NtUserConvertMemHandle(
UserDereferenceObject(pMemObj);
/* If we failed to copy data, remove handle */
if (!pMemObj)
if (!NT_SUCCESS(Status))
{
UserDeleteObject(hMem, TYPE_CLIPDATA);
hMem = NULL;