mirror of
https://github.com/reactos/reactos.git
synced 2025-05-06 18:31:26 +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;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
NtGdiGetObject(HANDLE handle, INT count, LPVOID buffer)
|
||||
{
|
||||
INT Ret = 0;
|
||||
INT RetCount;
|
||||
LPVOID SafeBuf;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
INT RetCount = 0;
|
||||
|
||||
/* From Wine: GetObject does not SetLastError() on a null object */
|
||||
if (!handle) return Ret;
|
||||
if (!handle) return 0;
|
||||
|
||||
RetCount = IntGdiGetObject(handle, 0, NULL);
|
||||
if ((count <= 0) || (!buffer))
|
||||
if (!buffer)
|
||||
{
|
||||
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
|
||||
{
|
||||
ProbeForWrite(buffer, count, 1);
|
||||
RtlCopyMemory(buffer, SafeBuf, count);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
|
@ -1835,43 +1882,15 @@ NtGdiGetObject(HANDLE handle, INT count, LPVOID buffer)
|
|||
}
|
||||
_SEH_END;
|
||||
|
||||
ExFreePool(SafeBuf);
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastNtError(Status);
|
||||
return Ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (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;
|
||||
return RetCount;
|
||||
}
|
||||
|
||||
DWORD STDCALL
|
||||
|
|
Loading…
Reference in a new issue