#include #include "common.h" #include "clipfile.h" #include "render.h" #include "debugout.h" #include "dib.h" /* * RenderFormat() - * * Read the data from fh and SetClipboardData() with it. */ HANDLE RenderFormat( FORMATHEADER *pfmthdr, register HANDLE fh) { HANDLE hBitmap; register HANDLE hData; LPSTR lpData; DWORD MetaOffset; /* special case hack for metafiles */ BITMAP bitmap; HPALETTE hPalette; LPLOGPALETTE lpLogPalette; DWORD dwBytesRead; DWORD dwDataOffset; if (PRIVATE_FORMAT(pfmthdr->FormatID)) pfmthdr->FormatID = RegisterClipboardFormatW(pfmthdr->Name); // Special case hack for metafiles to get hData referencing // the metafile bits, not the METAFILEPICT structure. switch (pfmthdr->FormatID) { case CF_METAFILEPICT: if (!fNTReadFileFormat) { MetaOffset = sizeof(WIN31METAFILEPICT); } else { MetaOffset = sizeof(METAFILEPICT); } break; case CF_BITMAP: if (!fNTReadFileFormat) { MetaOffset = sizeof(WIN31BITMAP); } else { MetaOffset = sizeof(BITMAP); } break; default: MetaOffset = 0; break; } if (!(hData = GlobalAlloc(GHND, pfmthdr->DataLen - MetaOffset))) { PERROR(TEXT("GlobalAlloc failure in RenderFormat\n\r")); return NULL; } if (!(lpData = GlobalLock(hData))) { PERROR(TEXT("GlobalLock failure in RenderFormat\n\r")); GlobalFree(hData); return NULL; } dwDataOffset = pfmthdr->DataOffset + MetaOffset; PINFO("Getting data for %ws at offset %ld\r\n",pfmthdr->Name, dwDataOffset); SetFilePointer(fh, dwDataOffset, NULL, FILE_BEGIN); ReadFile (fh, lpData, pfmthdr->DataLen - MetaOffset, &dwBytesRead, NULL); if(pfmthdr->DataLen - MetaOffset != dwBytesRead) { // Error in reading the file GlobalUnlock(hData); GlobalFree(hData); PERROR(TEXT("RenderFormat: Read err, expected %d bytes, got %d\r\n"), pfmthdr->DataLen - MetaOffset, dwBytesRead); return (NULL); } // As when we write these, we have to special case a few of them // This code and the write code should match in terms of the sizes // and positions of data blocks being written out. // EVERY case in this switch should have a GlobalUnlock(hData); // statement. We go in with the block locked, but should come // out with the block unlocked. switch (pfmthdr->FormatID) { case CF_ENHMETAFILE: { HENHMETAFILE hemf; hemf = SetEnhMetaFileBits(pfmthdr->DataLen, lpData); GlobalUnlock(hData); GlobalFree(hData); hData = hemf; break; } case CF_METAFILEPICT: { HANDLE hMF; HANDLE hMFP; LPMETAFILEPICT lpMFP; /* Create the METAFILE with the bits we read in. */ hMF = SetMetaFileBitsEx(pfmthdr->DataLen, lpData); GlobalUnlock(hData); GlobalFree(hData); hData = NULL; if (hMF) { /* Alloc a METAFILEPICT header. */ if (hMFP = GlobalAlloc(GHND, (DWORD)sizeof(METAFILEPICT))) { if (!(lpMFP = (LPMETAFILEPICT)GlobalLock(hMFP))) { GlobalFree(hMFP); } else { /* Reposition to the start of the METAFILEPICT header. */ SetFilePointer(fh, pfmthdr->DataOffset, NULL, FILE_BEGIN); /* Read in the data */ if (fNTReadFileFormat) { ReadFile(fh, lpMFP, sizeof(METAFILEPICT), &dwBytesRead, NULL); } else { WIN31METAFILEPICT w31mfp; ReadFile(fh, &w31mfp, sizeof(w31mfp), &dwBytesRead, NULL); if (sizeof(w31mfp) == dwBytesRead) { lpMFP->mm = w31mfp.mm; lpMFP->xExt = w31mfp.xExt; lpMFP->yExt = w31mfp.yExt; } } lpMFP->hMF = hMF; /* Update the METAFILE handle */ GlobalUnlock(hMFP); /* Unlock the header */ hData = hMFP; /* Stuff this in the clipboard */ } } } break; } case CF_BITMAP: // Reposition to the start of the METAFILEPICT header. SetFilePointer(fh, pfmthdr->DataOffset, NULL, FILE_BEGIN); /* Read in the BITMAP struct */ if (fNTReadFileFormat) { if (!ReadFile(fh, &bitmap, sizeof(BITMAP), &dwBytesRead, NULL)) memset(&bitmap, 0, sizeof(bitmap)); } else { // Read in an old-style BITMAP struct, and set the fields // of the new-style BITMAP from that. WIN31BITMAP w31bm; if (ReadFile(fh, &w31bm, sizeof(w31bm), &dwBytesRead, NULL)) { bitmap.bmType = w31bm.bmType; bitmap.bmWidth = w31bm.bmWidth; bitmap.bmHeight = w31bm.bmHeight; bitmap.bmWidthBytes = w31bm.bmWidthBytes; bitmap.bmPlanes = w31bm.bmPlanes; bitmap.bmBitsPixel = w31bm.bmBitsPixel; } else { memset(&bitmap, 0, sizeof(bitmap)); } } // Set the bmBits member of the BITMAP to point to our existing // bits and make the bitmap. bitmap.bmBits = lpData; hBitmap = CreateBitmapIndirect(&bitmap); // Dump the original data (which was just the bitmap bits) and // make the bitmap handle our data handle. GlobalUnlock(hData); GlobalFree(hData); hData = hBitmap; // Stuff this in the clipboard break; case CF_PALETTE: lpLogPalette = (LPLOGPALETTE)lpData; hPalette = CreatePalette(lpLogPalette); GlobalUnlock(hData); GlobalFree(hData); hData = hPalette; break; default: GlobalUnlock(hData); break; } return(hData); } HANDLE RenderFormatDibToBitmap( FORMATHEADER *pfmthdr, register HANDLE fh, HPALETTE hPalette) { HANDLE hBitmap; register HANDLE hData; LPSTR lpData; DWORD dwBytesRead; DWORD dwDataOffset; if (PRIVATE_FORMAT(pfmthdr->FormatID)) pfmthdr->FormatID = RegisterClipboardFormatW(pfmthdr->Name); if (!(hData = GlobalAlloc(GHND, pfmthdr->DataLen))) { PERROR(TEXT("GlobalAlloc failure in RenderFormat\n\r")); return NULL; } if (!(lpData = GlobalLock(hData))) { PERROR(TEXT("GlobalLock failure in RenderFormat\n\r")); GlobalFree(hData); return NULL; } dwDataOffset = pfmthdr->DataOffset; PINFO("Getting data for %ws at offset %ld\r\n",pfmthdr->Name, dwDataOffset); SetFilePointer(fh, dwDataOffset, NULL, FILE_BEGIN); ReadFile (fh, lpData, pfmthdr->DataLen, &dwBytesRead, NULL); if(pfmthdr->DataLen != dwBytesRead) { // Error in reading the file GlobalUnlock(hData); GlobalFree(hData); PERROR (TEXT("RenderFormat: Read err, expected %d bytes, got %d\r\n"), pfmthdr->DataLen, dwBytesRead); return (NULL); } GlobalUnlock(hData); hBitmap = BitmapFromDib (hData, hPalette); GlobalFree (hData); return (hBitmap); }