mirror of
https://github.com/reactos/reactos.git
synced 2025-05-07 18:56:48 +00:00
NtGdiGetObject:
- return 0 if buffer != 0 and count == 0 - don't write beyond umode buffer size (max count bytes!) - use SEH only once - No need for Ret & RetCount, use only RetCount - document the function svn path=/trunk/; revision=26396
This commit is contained in:
parent
c52d16c759
commit
81e62c37bf
1 changed files with 55 additions and 36 deletions
|
@ -1808,26 +1808,73 @@ IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NtGdiGetObject
|
||||||
|
*
|
||||||
|
* Copies information of the specified gdi object to a buffer
|
||||||
|
* and returns the size of the data.
|
||||||
|
*
|
||||||
|
* @param
|
||||||
|
* handle
|
||||||
|
* [in] Handle to the gdi object to retrieve the data from.
|
||||||
|
*
|
||||||
|
* count
|
||||||
|
* [in] Size of the buffer to copy the data to.
|
||||||
|
*
|
||||||
|
* buffer
|
||||||
|
* [out] Pointer to the buffer to copy the data to.
|
||||||
|
* This parameter can be NULL.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Size of the data of the GDI object, if the function succeeds.
|
||||||
|
* 0 if the function fails.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* The function will always return the complete size of the object's data,
|
||||||
|
* but will copy only a maximum of count bytes to the specified buffer.
|
||||||
|
* If the handle is invalid, the function will fail.
|
||||||
|
* If buffer is NULL the function will only return the size of the data.
|
||||||
|
* If buffer is not NULL and count is 0, the function will fail.
|
||||||
|
*/
|
||||||
INT STDCALL
|
INT STDCALL
|
||||||
NtGdiGetObject(HANDLE handle, INT count, LPVOID buffer)
|
NtGdiGetObject(HANDLE handle, INT count, LPVOID buffer)
|
||||||
{
|
{
|
||||||
INT Ret = 0;
|
INT RetCount;
|
||||||
LPVOID SafeBuf;
|
LPVOID SafeBuf;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
INT RetCount = 0;
|
|
||||||
|
|
||||||
/* From Wine: GetObject does not SetLastError() on a null object */
|
/* From Wine: GetObject does not SetLastError() on a null object */
|
||||||
if (!handle) return Ret;
|
if (!handle) return 0;
|
||||||
|
|
||||||
RetCount = IntGdiGetObject(handle, 0, NULL);
|
RetCount = IntGdiGetObject(handle, 0, NULL);
|
||||||
if ((count <= 0) || (!buffer))
|
if (!buffer)
|
||||||
{
|
{
|
||||||
return RetCount;
|
return RetCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!count || !RetCount)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > RetCount)
|
||||||
|
{
|
||||||
|
count = RetCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeBuf = ExAllocatePoolWithTag(PagedPool, RetCount, TAG_GDIOBJ);
|
||||||
|
if(!SafeBuf)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
IntGdiGetObject(handle, RetCount, SafeBuf);
|
||||||
|
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
ProbeForWrite(buffer, count, 1);
|
ProbeForWrite(buffer, count, 1);
|
||||||
|
RtlCopyMemory(buffer, SafeBuf, count);
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
@ -1835,43 +1882,15 @@ NtGdiGetObject(HANDLE handle, INT count, LPVOID buffer)
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
|
|
||||||
|
ExFreePool(SafeBuf);
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
return Ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RetCount)
|
return RetCount;
|
||||||
{
|
|
||||||
SafeBuf = ExAllocatePoolWithTag(PagedPool, RetCount, TAG_GDIOBJ);
|
|
||||||
if(!SafeBuf)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return Ret;
|
|
||||||
}
|
|
||||||
Ret = IntGdiGetObject(handle, RetCount, SafeBuf);
|
|
||||||
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
/* pointer already probed! */
|
|
||||||
RtlCopyMemory(buffer, SafeBuf, RetCount);
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
ExFreePool(SafeBuf);
|
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD STDCALL
|
DWORD STDCALL
|
||||||
|
|
Loading…
Reference in a new issue