Index: win32ss/user/ntuser/clipboard.c =================================================================== --- win32ss/user/ntuser/clipboard.c (revision 74033) +++ win32ss/user/ntuser/clipboard.c (working copy) @@ -68,11 +68,12 @@ } } -/* Adds a new format and data to the clipboard */ -static PCLIP NTAPI +/* Adds a new format and data to the clipboard, returns TRUE on memory reallocation */ +static BOOL NTAPI IntAddFormatedData(PWINSTATION_OBJECT pWinStaObj, UINT fmt, HANDLE hData, BOOLEAN fGlobalHandle, BOOL bEnd) { PCLIP pElement = NULL; + BOOL bReallocated = 0; /* Use existing entry with specified format */ if (!bEnd) @@ -93,7 +94,7 @@ if (!pNewClip) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; + return FALSE; } /* Copy data */ @@ -101,7 +102,10 @@ /* Free old clipboard */ if (pWinStaObj->pClipBase) + { ExFreePoolWithTag(pWinStaObj->pClipBase, USERTAG_CLIPBOARD); + bReallocated = TRUE; + } /* Update WinSta */ pWinStaObj->pClipBase = pNewClip; @@ -118,7 +122,7 @@ pElement->hData = hData; pElement->fGlobalHandle = fGlobalHandle; - return pElement; + return bReallocated; } static BOOL FASTCALL @@ -280,11 +284,7 @@ PCLIP pTextEl, pUniTextEl, pOemTextEl, pLocaleEl, pBmEl, pDibEl; 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); /* Add CF_LOCALE format if we have CF_TEXT */ if (!pLocaleEl && pTextEl) @@ -298,7 +298,8 @@ { pMemObj->cbData = sizeof(LCID); *((LCID*)pMemObj->Data) = NtCurrentTeb()->CurrentLocale; - IntAddFormatedData(pWinStaObj, CF_LOCALE, hMem, TRUE, TRUE); + if (IntAddFormatedData(pWinStaObj, CF_LOCALE, hMem, TRUE, TRUE)) + pTextEl = IntIsFormatAvailable(pWinStaObj, CF_TEXT); /* Release the extra reference (UserCreateObject added 2 references) */ UserDereferenceObject(pMemObj); @@ -305,21 +306,54 @@ } } + pOemTextEl = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); + pUniTextEl = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); + /* Add CF_TEXT. Note: it is synthesized in user32.dll */ if (!pTextEl && (pUniTextEl || pOemTextEl)) - IntAddFormatedData(pWinStaObj, CF_TEXT, DATA_SYNTH_USER, FALSE, TRUE); + { + if (IntAddFormatedData(pWinStaObj, CF_TEXT, DATA_SYNTH_USER, FALSE, TRUE)) + { + pOemTextEl = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); + pUniTextEl = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); + pTextEl = IntIsFormatAvailable(pWinStaObj, CF_TEXT); + } + } /* Add CF_OEMTEXT. Note: it is synthesized in user32.dll */ if (!pOemTextEl && (pUniTextEl || pTextEl)) - IntAddFormatedData(pWinStaObj, CF_OEMTEXT, DATA_SYNTH_USER, FALSE, TRUE); + { + if (IntAddFormatedData(pWinStaObj, CF_OEMTEXT, DATA_SYNTH_USER, FALSE, TRUE)) + { + pOemTextEl = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); + pUniTextEl = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); + pTextEl = IntIsFormatAvailable(pWinStaObj, CF_TEXT); + } + } /* Add CF_UNICODETEXT. Note: it is synthesized in user32.dll */ if (!pUniTextEl && (pTextEl || pOemTextEl)) - IntAddFormatedData(pWinStaObj, CF_UNICODETEXT, DATA_SYNTH_USER, FALSE, TRUE); + { + if (IntAddFormatedData(pWinStaObj, CF_UNICODETEXT, DATA_SYNTH_USER, FALSE, TRUE)) + { + pOemTextEl = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); + pUniTextEl = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); + pTextEl = IntIsFormatAvailable(pWinStaObj, CF_TEXT); + } + } + pBmEl = IntIsFormatAvailable(pWinStaObj, CF_BITMAP); + pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB); + /* Add CF_BITMAP. Note: it is synthesized on demand */ if (!pBmEl && pDibEl) - IntAddFormatedData(pWinStaObj, CF_BITMAP, DATA_SYNTH_KRNL, FALSE, TRUE); + { + if (IntAddFormatedData(pWinStaObj, CF_BITMAP, DATA_SYNTH_KRNL, FALSE, TRUE)) + { + pBmEl = IntIsFormatAvailable(pWinStaObj, CF_BITMAP); + pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB); + } + } /* Note: We need to render the DIB or DIBV5 format as soon as possible because pallette information may change */