|
|
#include <windows.h>
#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);
}
|