mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 21:56:40 +00:00
- 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. svn path=/trunk/; revision=50637
This commit is contained in:
parent
50df1352e9
commit
05de74702a
|
@ -441,8 +441,62 @@ BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
LocalUnlock(HLOCAL hMem)
|
LocalUnlock(HLOCAL hMem)
|
||||||
{
|
{
|
||||||
/* This is the same as a Global Unlock */
|
PBASE_HEAP_HANDLE_ENTRY HandleEntry;
|
||||||
return GlobalUnlock(hMem);
|
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 */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue