Author: tkreuzer
Date: Wed Apr 18 17:46:11 2007
New Revision: 26396
URL:
http://svn.reactos.org/svn/reactos?rev=26396&view=rev
Log:
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
Modified:
trunk/reactos/subsystems/win32/win32k/objects/dc.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/dc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/dc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/dc.c Wed Apr 18 17:46:11 2007
@@ -1808,26 +1808,73 @@
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 @@
}
_SEH_END;
+ ExFreePool(SafeBuf);
+
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
- return Ret;
- }
-
- 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 0;
+ }
+
+ return RetCount;
}
DWORD STDCALL