Index: clipboard.c =================================================================== --- win32ss/user/ntuser/clipboard.c (revision 74977) +++ win32ss/user/ntuser/clipboard.c (working copy) @@ -36,9 +36,8 @@ return pWinStaObj; } -/* If format exists, returns a non zero value (pointing to formated object) */ static PCLIP FASTCALL -IntIsFormatAvailable(PWINSTATION_OBJECT pWinStaObj, UINT fmt) +IntGetFormatElement(PWINSTATION_OBJECT pWinStaObj, UINT fmt) { DWORD i; @@ -51,6 +50,12 @@ return NULL; } +static BOOL FASTCALL +IntIsFormatAvailable(PWINSTATION_OBJECT pWinStaObj, UINT fmt) +{ + return IntGetFormatElement(pWinStaObj, fmt) != NULL; +} + static VOID FASTCALL IntFreeElementData(PCLIP pElement) { @@ -76,7 +81,7 @@ /* Use existing entry with specified format */ if (!bEnd) - pElement = IntIsFormatAvailable(pWinStaObj, fmt); + pElement = IntGetFormatElement(pWinStaObj, fmt); /* Put new entry at the end if nothing was found */ if (!pElement) @@ -154,6 +159,7 @@ } /* Get information about the bitmap format */ + bmiBuffer.bmih.biSize = sizeof(bmiBuffer.bmih); iResult = GreGetDIBitsInternal(hdc, hbm, 0, @@ -225,7 +231,7 @@ TRACE("IntSynthesizeBitmap(%p, %p)\n", pWinStaObj, pBmEl); - pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB); + pDibEl = IntGetFormatElement(pWinStaObj, CF_DIB); ASSERT(pDibEl && !IS_DATA_SYNTHESIZED(pDibEl)); if (!pDibEl->fGlobalHandle) return; @@ -277,17 +283,17 @@ static VOID NTAPI IntAddSynthesizedFormats(PWINSTATION_OBJECT pWinStaObj) { - PCLIP pTextEl, pUniTextEl, pOemTextEl, pLocaleEl, pBmEl, pDibEl; + BOOL bHaveText, bHaveUniText, bHaveOemText, bHaveLocale, bHaveBm, bHaveDib; - pTextEl = IntIsFormatAvailable(pWinStaObj, CF_TEXT); - pOemTextEl = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); - pUniTextEl = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); - pLocaleEl = IntIsFormatAvailable(pWinStaObj, CF_LOCALE); - pBmEl = IntIsFormatAvailable(pWinStaObj, CF_BITMAP); - pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB); + bHaveText = IntIsFormatAvailable(pWinStaObj, CF_TEXT); + bHaveOemText = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); + bHaveUniText = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); + bHaveLocale = IntIsFormatAvailable(pWinStaObj, CF_LOCALE); + bHaveBm = IntIsFormatAvailable(pWinStaObj, CF_BITMAP); + bHaveDib = IntIsFormatAvailable(pWinStaObj, CF_DIB); /* Add CF_LOCALE format if we have CF_TEXT */ - if (!pLocaleEl && pTextEl) + if (!bHaveLocale && bHaveText) { PCLIPBOARDDATA pMemObj; HANDLE hMem; @@ -306,25 +312,25 @@ } /* Add CF_TEXT. Note: it is synthesized in user32.dll */ - if (!pTextEl && (pUniTextEl || pOemTextEl)) + if (!bHaveText && (bHaveUniText || bHaveOemText)) IntAddFormatedData(pWinStaObj, CF_TEXT, DATA_SYNTH_USER, FALSE, TRUE); /* Add CF_OEMTEXT. Note: it is synthesized in user32.dll */ - if (!pOemTextEl && (pUniTextEl || pTextEl)) + if (!bHaveOemText && (bHaveUniText || bHaveText)) IntAddFormatedData(pWinStaObj, CF_OEMTEXT, DATA_SYNTH_USER, FALSE, TRUE); /* Add CF_UNICODETEXT. Note: it is synthesized in user32.dll */ - if (!pUniTextEl && (pTextEl || pOemTextEl)) + if (!bHaveUniText && (bHaveText || bHaveOemText)) IntAddFormatedData(pWinStaObj, CF_UNICODETEXT, DATA_SYNTH_USER, FALSE, TRUE); /* Add CF_BITMAP. Note: it is synthesized on demand */ - if (!pBmEl && pDibEl) + if (!bHaveBm && bHaveDib) IntAddFormatedData(pWinStaObj, CF_BITMAP, DATA_SYNTH_KRNL, FALSE, TRUE); /* Note: We need to render the DIB or DIBV5 format as soon as possible because pallette information may change */ - if (!pDibEl && pBmEl) - IntSynthesizeDib(pWinStaObj, pBmEl->hData); + if (!bHaveDib && bHaveBm) + IntSynthesizeDib(pWinStaObj, IntGetFormatElement(pWinStaObj, CF_BITMAP)->hData); } VOID NTAPI @@ -440,7 +446,8 @@ else { /* Return next format */ - pElement = IntIsFormatAvailable(pWinStaObj, fmt); + pElement = IntGetFormatElement(pWinStaObj, fmt); + ASSERT(pElement); ++pElement; if (pElement < &pWinStaObj->pClipBase[pWinStaObj->cNumClipFormats]) Ret = pElement->fmt; @@ -884,7 +891,7 @@ goto cleanup; } - pElement = IntIsFormatAvailable(pWinStaObj, fmt); + pElement = IntGetFormatElement(pWinStaObj, fmt); if (pElement && IS_DATA_DELAYED(pElement) && pWinStaObj->spwndClipOwner) { /* Send WM_RENDERFORMAT message */ @@ -893,7 +900,7 @@ pWinStaObj->fInDelayedRendering = FALSE; /* Data should be in clipboard now */ - pElement = IntIsFormatAvailable(pWinStaObj, fmt); + pElement = IntGetFormatElement(pWinStaObj, fmt); } if (!pElement || IS_DATA_DELAYED(pElement)) @@ -908,11 +915,11 @@ case CF_UNICODETEXT: case CF_TEXT: case CF_OEMTEXT: - pElement = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); + pElement = IntGetFormatElement(pWinStaObj, CF_UNICODETEXT); if (IS_DATA_SYNTHESIZED(pElement)) - pElement = IntIsFormatAvailable(pWinStaObj, CF_TEXT); + pElement = IntGetFormatElement(pWinStaObj, CF_TEXT); if (IS_DATA_SYNTHESIZED(pElement)) - pElement = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); + pElement = IntGetFormatElement(pWinStaObj, CF_OEMTEXT); break; case CF_BITMAP: IntSynthesizeBitmap(pWinStaObj, pElement); @@ -933,7 +940,7 @@ { PCLIP pLocaleEl; - pLocaleEl = IntIsFormatAvailable(pWinStaObj, CF_LOCALE); + pLocaleEl = IntGetFormatElement(pWinStaObj, CF_LOCALE); if (pLocaleEl && !IS_DATA_DELAYED(pLocaleEl)) pgcd->hLocale = pLocaleEl->hData; } @@ -941,7 +948,7 @@ { PCLIP pPaletteEl; - pPaletteEl = IntIsFormatAvailable(pWinStaObj, CF_PALETTE); + pPaletteEl = IntGetFormatElement(pWinStaObj, CF_PALETTE); if (pPaletteEl && !IS_DATA_DELAYED(pPaletteEl)) pgcd->hPalette = pPaletteEl->hData; } @@ -977,11 +984,11 @@ /* * Check if the clipboard is correctly opened: - * - in case of normal rendering, we must have opened the clipboard; + * - in case of normal rendering, someone must have opened the clipboard; * - in case of delayed rendering, the clipboard must be already opened * by another application, but we need to be the clipboard owner. */ - if ((!pWinStaObj->fInDelayedRendering && !IntIsClipboardOpenByMe(pWinStaObj)) || + if ((!pWinStaObj->fInDelayedRendering && !pWinStaObj->ptiClipLock) || (pWinStaObj->fInDelayedRendering && !(pWinStaObj->ptiClipLock && pWinStaObj->spwndClipOwner->head.pti == PsGetCurrentThreadWin32Thread()))) { Index: usrheap.c =================================================================== --- win32ss/user/ntuser/usrheap.c (revision 74970) +++ win32ss/user/ntuser/usrheap.c (working copy) @@ -334,4 +334,148 @@ return STATUS_SUCCESS; } +#define DBG_SIG1 0xaefabba0 +#define DBG_SIG2 0x57e9a61e +typedef struct _DBG_HEADER +{ + ULONG Sig1; + PCSTR File; + INT Line; + ULONG Sig2; +} DBG_HEADER, *PDBG_HEADER; + +static PDBG_HEADER DbgHolding[1024]; +static ULONG DbgHoldingIndex; +static PDBG_HEADER MinAlloc = (PVOID)(LONG_PTR)-1, MaxAlloc; + +PVOID +UserHeapAlloc_(SIZE_T Bytes, + PCSTR File, + INT Line) +{ + PDBG_HEADER Header; + + Bytes = ALIGN_UP_BY(Bytes + sizeof(DBG_HEADER) + 4 * sizeof(ULONG), 2 * sizeof(PVOID)); + + Header = RtlAllocateHeap(GlobalUserHeap, + HEAP_NO_SERIALIZE, + Bytes); + if (!Header) return NULL; + Header->Sig1 = DBG_SIG1; + Header->File = File; + Header->Line = Line; + Header->Sig2 = DBG_SIG2; + if (Header < MinAlloc) + MinAlloc = Header; + if (Header > MaxAlloc) + MaxAlloc = Header; + RtlFillMemory(Header + 1, Bytes - sizeof(DBG_HEADER) - 4 * sizeof(ULONG), 0xe5); + RtlFillMemory((PUCHAR)(Header + 1) + Bytes - sizeof(DBG_HEADER) - 4 * sizeof(ULONG), 4 * sizeof(ULONG), 0xdc); + return Header + 1; +} + +BOOL +UserHeapFree(PVOID lpMem) +{ + PDBG_HEADER Header; + ULONG i, Size; + PULONG Data; + ULONG Sig; + + Header = lpMem; + Header--; + if (Header < MinAlloc || Header > MaxAlloc || + (ULONG_PTR)Header % (2 * sizeof(PVOID)) != 0) + { + DPRINT1("Invalid free. lpMem=%p, Min=%p, Max=%p\n", + lpMem, MinAlloc, MaxAlloc); + __debugbreak(); + return FALSE; + } + if (DbgHolding[DbgHoldingIndex]) + { + if (DbgHolding[DbgHoldingIndex]->Sig1 != DBG_SIG1 || + DbgHolding[DbgHoldingIndex]->Sig2 != DBG_SIG2) + { + DPRINT1("Header sig mismatch for %p\n", DbgHolding[DbgHoldingIndex]); + DPRINT1("Allocation is from %s:%d\n", DbgHolding[DbgHoldingIndex]->File, DbgHolding[DbgHoldingIndex]->Line); + DPRINT1("Sigs are 0x%08x, 0x%08x\n", DbgHolding[DbgHoldingIndex]->Sig1, DbgHolding[DbgHoldingIndex]->Sig2); + __debugbreak(); + } + Data = (PULONG)(DbgHolding[DbgHoldingIndex] + 1); + Size = (RtlSizeHeap(GlobalUserHeap, HEAP_NO_SERIALIZE, DbgHolding[DbgHoldingIndex]) - sizeof(DBG_HEADER)) / sizeof(ULONG); + Sig = (ULONG_PTR)DbgHolding[DbgHoldingIndex]->File; + Sig ^= DbgHolding[DbgHoldingIndex]->Line; + Sig ^= DBG_SIG2; + for (i = 0; i < Size; i++) + { + if (Data[i] != Sig + i) + { + DPRINT1("Content sig mismatch for %p\n", DbgHolding[DbgHoldingIndex]); + DPRINT1("Allocation is from %s:%d\n", DbgHolding[DbgHoldingIndex]->File, DbgHolding[DbgHoldingIndex]->Line); + DPRINT1("Sig at offset %lu is 0x%08x, expected 0x%08x\n", i, Data[i], Sig + i); + __debugbreak(); + } + } + RtlFreeHeap(GlobalUserHeap, + HEAP_NO_SERIALIZE, + DbgHolding[DbgHoldingIndex]); + } + Data = (PULONG)(Header + 1); + Size = (RtlSizeHeap(GlobalUserHeap, HEAP_NO_SERIALIZE, Header) - sizeof(DBG_HEADER)) / sizeof(ULONG); + Sig = (ULONG_PTR)Header->File; + Sig ^= Header->Line; + Sig ^= DBG_SIG2; + for (i = Size - 4; i < Size; i++) + { + if (Data[i] != 0xdcdcdcdc) + { + DPRINT1("Post buffer sig mismatch for %p\n", Header); + DPRINT1("Allocation is from %s:%d\n", Header->File, Header->Line); + DPRINT1("Sig at offset %lu is 0x%08x\n", i, Data[i]); + __debugbreak(); + } + } + for (i = 0; i < Size; i++) + { + Data[i] = Sig + i; + } + DbgHolding[DbgHoldingIndex] = Header; + DbgHoldingIndex = (DbgHoldingIndex + 1) % _countof(DbgHolding); + return TRUE; +} + +PVOID +UserHeapReAlloc_(PVOID lpMem, + SIZE_T BytesAsked, + PCSTR File, + INT Line) +{ + PDBG_HEADER Header; + SIZE_T PrevSize; + PVOID pNew; + + Header = lpMem; + Header--; + + PrevSize = RtlSizeHeap(GlobalUserHeap, + HEAP_NO_SERIALIZE, + lpMem); + + pNew = UserHeapAlloc_(BytesAsked, File, Line); + if (pNew != NULL) + { + if (PrevSize < BytesAsked) + BytesAsked = PrevSize; + + RtlCopyMemory(pNew, + lpMem, + BytesAsked); + + UserHeapFree(lpMem); + } + + return pNew; +} + /* EOF */ Index: usrheap.h =================================================================== --- win32ss/user/ntuser/usrheap.h (revision 74970) +++ win32ss/user/ntuser/usrheap.h (working copy) @@ -30,6 +30,23 @@ OUT PVOID* KernelMapping, OUT PVOID* UserMapping); +#if 1 +#define UserHeapAlloc(b) UserHeapAlloc_(b, __FILE__, __LINE__) +PVOID +UserHeapAlloc_(SIZE_T Bytes, + PCSTR File, + INT Line); + +BOOL +UserHeapFree(PVOID lpMem); + +#define UserHeapReAlloc(m, b) UserHeapReAlloc(m, b, __FILE__, __LINE__) +PVOID +UserHeapReAlloc_(PVOID lpMem, + SIZE_T Bytes, + PCSTR File, + INT Line); +#else static __inline PVOID UserHeapAlloc(SIZE_T Bytes) { @@ -87,6 +104,7 @@ return pNew; #endif } +#endif static __inline PVOID UserHeapAddressToUser(PVOID lpMem)