mirror of
https://github.com/reactos/reactos.git
synced 2026-05-30 23:33:24 +08:00
[WIN32KNT_APITEST][NTUSER] Fix NtUserConvertMemHandle BSOD (#7878)
Fix NtUserConvertMemHandle BSOD. JIRA issue: CORE-18121
This commit is contained in:
@@ -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
|
||||
|
||||
132
modules/rostests/apitests/win32u/ntuser/NtUserConvertMemHandle.c
Normal file
132
modules/rostests/apitests/win32u/ntuser/NtUserConvertMemHandle.c
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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 },
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user