[ros-diffs] [fireball] 50637: - Robert Horvath: LocalUnlock has to be different from GlobalUnlock. The subtle difference between LocalUnlock and GlobalUnlock, is, that the former will return FALSE and set ERRO...
fireball at svn.reactos.org
fireball at svn.reactos.org
Wed Feb 9 20:42:45 UTC 2011
Author: fireball
Date: Wed Feb 9 20:42:44 2011
New Revision: 50637
URL: http://svn.reactos.org/svn/reactos?rev=50637&view=rev
Log:
- Robert Horvath: LocalUnlock has to be different from GlobalUnlock. The subtle difference between LocalUnlock and GlobalUnlock, is, that the former will return FALSE and set ERROR_NOT_LOCKED on LMEM_FIXED allocations. Fixes 1 kernel32:heap failure.
See issue #5869 for more details.
Modified:
trunk/reactos/dll/win32/kernel32/mem/local.c
Modified: trunk/reactos/dll/win32/kernel32/mem/local.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/mem/local.c?rev=50637&r1=50636&r2=50637&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/mem/local.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/mem/local.c [iso-8859-1] Wed Feb 9 20:42:44 2011
@@ -441,8 +441,62 @@
NTAPI
LocalUnlock(HLOCAL hMem)
{
- /* This is the same as a Global Unlock */
- return GlobalUnlock(hMem);
+ PBASE_HEAP_HANDLE_ENTRY HandleEntry;
+ BOOL RetVal = TRUE;
+
+ /* Check if this was a simple allocated heap entry */
+ if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY))
+ {
+ /* Fail, because LocalUnlock is not supported on LMEM_FIXED allocations */
+ SetLastError(ERROR_NOT_LOCKED);
+ return FALSE;
+ }
+
+ /* Otherwise, lock the heap */
+ RtlLockHeap(hProcessHeap);
+
+ /* Get the handle entry */
+ HandleEntry = BaseHeapGetEntry(hMem);
+ BASE_TRACE_HANDLE(HandleEntry, hMem);
+
+ _SEH2_TRY
+ {
+ /* Make sure it's valid */
+ if (!BaseHeapValidateEntry(HandleEntry))
+ {
+ /* It's not, fail */
+ BASE_TRACE_FAILURE();
+ SetLastError(ERROR_INVALID_HANDLE);
+ RetVal = FALSE;
+ }
+ else
+ {
+ /* Otherwise, decrement lock count, unless we're already at 0*/
+ if (!HandleEntry->LockCount--)
+ {
+ /* In which case we simply lock it back and fail */
+ HandleEntry->LockCount++;
+ SetLastError(ERROR_NOT_LOCKED);
+ RetVal = FALSE;
+ }
+ else if (!HandleEntry->LockCount)
+ {
+ /* Nothing to unlock */
+ SetLastError(NO_ERROR);
+ RetVal = FALSE;
+ }
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ RetVal = FALSE;
+ }
+ _SEH2_END
+
+ /* All done. Unlock the heap and return the pointer */
+ RtlUnlockHeap(hProcessHeap);
+ return RetVal;
}
/* EOF */
More information about the Ros-diffs
mailing list