mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 22:23:05 +00:00
[WIN32K/USER32]
- Simplify an overcomplicated way to get buffer size from win32k - Do not spaghettize between string length and buffer size. - Properly use GetModuleFileName. svn path=/trunk/; revision=64938
This commit is contained in:
parent
a8e3dcc9e1
commit
25c228cd3f
2 changed files with 64 additions and 71 deletions
|
@ -187,7 +187,8 @@ IntDestroyCurIconObject(
|
||||||
|
|
||||||
/* We just mark the handle as being destroyed.
|
/* We just mark the handle as being destroyed.
|
||||||
* Deleting all the stuff will be deferred to the actual struct free. */
|
* Deleting all the stuff will be deferred to the actual struct free. */
|
||||||
return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
|
UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -357,16 +358,18 @@ NtUserGetIconInfo(
|
||||||
/* Get the module name from the atom table */
|
/* Get the module name from the atom table */
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
if (BufLen > (lpModule->MaximumLength * sizeof(WCHAR)))
|
BufLen += sizeof(WCHAR);
|
||||||
|
if (BufLen > (lpModule->MaximumLength))
|
||||||
{
|
{
|
||||||
lpModule->Length = 0;
|
lpModule->Length = 0;
|
||||||
|
lpModule->MaximumLength = BufLen;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ProbeForWrite(lpModule->Buffer, lpModule->MaximumLength, 1);
|
ProbeForWrite(lpModule->Buffer, lpModule->MaximumLength, 1);
|
||||||
BufLen = lpModule->MaximumLength * sizeof(WCHAR);
|
BufLen = lpModule->MaximumLength;
|
||||||
RtlQueryAtomInAtomTable(gAtomTable, CurIcon->atomModName, NULL, NULL, lpModule->Buffer, &BufLen);
|
RtlQueryAtomInAtomTable(gAtomTable, CurIcon->atomModName, NULL, NULL, lpModule->Buffer, &BufLen);
|
||||||
lpModule->Length = BufLen/sizeof(WCHAR);
|
lpModule->Length = BufLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
@ -395,15 +398,18 @@ NtUserGetIconInfo(
|
||||||
{
|
{
|
||||||
lpResName->Buffer = CurIcon->strName.Buffer;
|
lpResName->Buffer = CurIcon->strName.Buffer;
|
||||||
lpResName->Length = 0;
|
lpResName->Length = 0;
|
||||||
|
lpResName->MaximumLength = 0;
|
||||||
}
|
}
|
||||||
else if (lpResName->MaximumLength < CurIcon->strName.Length)
|
else if (lpResName->MaximumLength < CurIcon->strName.MaximumLength)
|
||||||
{
|
{
|
||||||
lpResName->Length = 0;
|
lpResName->Length = 0;
|
||||||
|
lpResName->MaximumLength = CurIcon->strName.MaximumLength;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ProbeForWrite(lpResName->Buffer, lpResName->MaximumLength * sizeof(WCHAR), 1);
|
ProbeForWrite(lpResName->Buffer, lpResName->MaximumLength, 1);
|
||||||
RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, lpResName->Length);
|
RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, CurIcon->strName.Length);
|
||||||
|
lpResName->Length = CurIcon->strName.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
|
|
@ -1342,27 +1342,37 @@ CURSORICON_LoadImageW(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
RtlInitUnicodeString(&ustrRsrc, lpszName);
|
RtlInitUnicodeString(&ustrRsrc, lpszName);
|
||||||
|
|
||||||
/* Prepare the module name string */
|
/* Get the module name string */
|
||||||
ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
|
while (TRUE)
|
||||||
/* Get it */
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
DWORD ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size);
|
DWORD ret;
|
||||||
|
ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
|
||||||
|
if (!ustrModule.Buffer)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size);
|
||||||
if(ret == 0)
|
if(ret == 0)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
|
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(ret < size)
|
|
||||||
|
/* This API is completely broken... */
|
||||||
|
if (ret == size)
|
||||||
{
|
{
|
||||||
ustrModule.Length = ret*sizeof(WCHAR);
|
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
|
||||||
ustrModule.MaximumLength = size*sizeof(WCHAR);
|
size *= 2;
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
size *= 2;
|
|
||||||
ustrModule.Buffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, size*sizeof(WCHAR));
|
ustrModule.Buffer[ret] = UNICODE_NULL;
|
||||||
} while(TRUE);
|
ustrModule.Length = ret * sizeof(WCHAR);
|
||||||
|
ustrModule.MaximumLength = size * sizeof(WCHAR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ask win32k */
|
/* Ask win32k */
|
||||||
param.bIcon = bIcon;
|
param.bIcon = bIcon;
|
||||||
|
@ -1691,75 +1701,51 @@ CURSORICON_CopyImage(
|
||||||
/* Get the icon module/resource names */
|
/* Get the icon module/resource names */
|
||||||
UNICODE_STRING ustrModule;
|
UNICODE_STRING ustrModule;
|
||||||
UNICODE_STRING ustrRsrc;
|
UNICODE_STRING ustrRsrc;
|
||||||
PVOID pvBuf;
|
|
||||||
HMODULE hModule;
|
HMODULE hModule;
|
||||||
|
|
||||||
ustrModule.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
ustrModule.MaximumLength = 0;
|
||||||
ustrRsrc.MaximumLength = 256;
|
ustrRsrc.MaximumLength = 0;
|
||||||
|
|
||||||
|
/* Get the buffer size */
|
||||||
|
if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
|
ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
|
||||||
if (!ustrModule.Buffer)
|
if (!ustrModule.Buffer)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Keep track of the buffer for the resource, NtUserGetIconInfo might overwrite it */
|
|
||||||
pvBuf = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength);
|
|
||||||
if (!pvBuf)
|
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
|
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ustrRsrc.Buffer = pvBuf;
|
|
||||||
|
|
||||||
do
|
if (ustrRsrc.MaximumLength)
|
||||||
{
|
{
|
||||||
if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
|
ustrRsrc.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength);
|
||||||
|
if (!ustrRsrc.Buffer)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
|
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
|
||||||
HeapFree(GetProcessHeap(), 0, pvBuf);
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (ustrModule.Length && (ustrRsrc.Length || IS_INTRESOURCE(ustrRsrc.Buffer)))
|
|
||||||
{
|
if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
|
||||||
/* Buffers were big enough */
|
{
|
||||||
break;
|
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
|
||||||
}
|
if (!IS_INTRESOURCE(ustrRsrc.Buffer))
|
||||||
|
HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
|
||||||
/* Find which buffer were too small */
|
return NULL;
|
||||||
if (!ustrModule.Length)
|
}
|
||||||
{
|
|
||||||
PWSTR newBuffer;
|
|
||||||
ustrModule.MaximumLength *= 2;
|
|
||||||
newBuffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, ustrModule.MaximumLength);
|
|
||||||
if(!ustrModule.Buffer)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
ustrModule.Buffer = newBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ustrRsrc.Length)
|
|
||||||
{
|
|
||||||
ustrRsrc.MaximumLength *= 2;
|
|
||||||
pvBuf = HeapReAlloc(GetProcessHeap(), 0, ustrRsrc.Buffer, ustrRsrc.MaximumLength);
|
|
||||||
if (!pvBuf)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
ustrRsrc.Buffer = pvBuf;
|
|
||||||
}
|
|
||||||
} while(TRUE);
|
|
||||||
|
|
||||||
/* NULL-terminate our strings */
|
/* NULL-terminate our strings */
|
||||||
ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = 0;
|
ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
if (!IS_INTRESOURCE(ustrRsrc.Buffer))
|
if (!IS_INTRESOURCE(ustrRsrc.Buffer))
|
||||||
ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = 0;
|
ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
|
TRACE("Got module %S, resource %p (%S).\n", ustrModule.Buffer,
|
||||||
|
ustrRsrc.Buffer, IS_INTRESOURCE(ustrRsrc.Buffer) ? L"" : ustrRsrc.Buffer);
|
||||||
|
|
||||||
/* Get the module handle */
|
/* Get the module handle */
|
||||||
if (!GetModuleHandleExW(0, ustrModule.Buffer, &hModule))
|
if (!GetModuleHandleExW(0, ustrModule.Buffer, &hModule))
|
||||||
{
|
{
|
||||||
|
@ -1783,7 +1769,8 @@ CURSORICON_CopyImage(
|
||||||
/* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */
|
/* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */
|
||||||
leave:
|
leave:
|
||||||
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
|
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
|
||||||
HeapFree(GetProcessHeap(), 0, pvBuf);
|
if (!IS_INTRESOURCE(ustrRsrc.Buffer))
|
||||||
|
HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
|
||||||
|
|
||||||
TRACE("Returning 0x%08x.\n", ret);
|
TRACE("Returning 0x%08x.\n", ret);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue