Author: hbelusca Date: Sat Feb 13 16:08:09 2016 New Revision: 70730
URL: http://svn.reactos.org/svn/reactos?rev=70730&view=rev Log: [CLIPBRD]: Complete the read support from .clp clipboard files to be actually able to read files saved with the Windows 2k3 clipboard. There actually exist two clipboard file formats, so-called "Win3.1" and a "WinNT" formats. Strangely enough Win2k (and Win2k3) clipboard viewer always save the files under the "Win3.1" format, whichever one you select. I discovered the subtle difference between those two formats by looking at a very old MSDN sample program "EMFDCODE (Enhanced Metafile Decoder)" by Dennis Crain (see https://web.archive.org/web/20080406095812/http://msdn.microsoft.com/archive... ) that still can be found on the Internet... CORE-10550 #comment Read support fixed in r70730.
Modified: trunk/reactos/base/applications/clipbrd/clipbrd.c trunk/reactos/base/applications/clipbrd/fileutils.c trunk/reactos/base/applications/clipbrd/fileutils.h trunk/reactos/base/applications/clipbrd/precomp.h
Modified: trunk/reactos/base/applications/clipbrd/clipbrd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/clipbrd/c... ============================================================================== --- trunk/reactos/base/applications/clipbrd/clipbrd.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/clipbrd/clipbrd.c [iso-8859-1] Sat Feb 13 16:08:09 2016 @@ -318,15 +318,15 @@ break; }
+ case CF_METAFILEPICT: + { + PlayMetaFileFromClipboard(hdc, &rc); + break; + } + case CF_ENHMETAFILE: { PlayEnhMetaFileFromClipboard(hdc, &rc); - break; - } - - case CF_METAFILEPICT: - { - PlayMetaFileFromClipboard(hdc, &rc); break; }
Modified: trunk/reactos/base/applications/clipbrd/fileutils.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/clipbrd/f... ============================================================================== --- trunk/reactos/base/applications/clipbrd/fileutils.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/clipbrd/fileutils.c [iso-8859-1] Sat Feb 13 16:08:09 2016 @@ -4,6 +4,7 @@ * FILE: base/applications/clipbrd/fileutils.c * PURPOSE: Clipboard file format helper functions. * PROGRAMMERS: Ricardo Hanke + * Hermes Belusca-Maito */
#include "precomp.h" @@ -16,9 +17,7 @@
hData = GlobalAlloc(GHND, dwLength); if (!hData) - { return NULL; - }
lpData = GlobalLock(hData); if (!lpData) @@ -46,20 +45,22 @@ return hData; }
-static BOOL ClipboardReadMemory(HANDLE hFile, DWORD dwFormat, DWORD dwOffset, DWORD dwLength, LPCWSTR lpFormatName) +static BOOL ClipboardReadMemory(HANDLE hFile, DWORD dwFormat, DWORD dwOffset, DWORD dwLength, WORD FileIdentifier, PVOID lpFormatName) { HGLOBAL hData; DWORD dwTemp;
hData = ClipboardReadMemoryBlock(hFile, dwOffset, dwLength); if (!hData) - { - return FALSE; - } + return FALSE;
if ((dwFormat >= 0xC000) && (dwFormat <= 0xFFFF)) { - dwTemp = RegisterClipboardFormatW(lpFormatName); + if (FileIdentifier == CLIP_FMT_31) + dwTemp = RegisterClipboardFormatA((LPCSTR)lpFormatName); + else if ((FileIdentifier == CLIP_FMT_NT) || (FileIdentifier == CLIP_FMT_BK)) + dwTemp = RegisterClipboardFormatW((LPCWSTR)lpFormatName); + if (!dwTemp) { GlobalFree(hData); @@ -120,9 +121,9 @@ return TRUE; }
-static BOOL ClipboardReadEnhMetafile(HANDLE hFile, DWORD dwOffset, DWORD dwLength) -{ - HENHMETAFILE hEmf; +static BOOL ClipboardReadMetafile(HANDLE hFile, DWORD dwOffset, DWORD dwLength) +{ + HMETAFILE hMf; HGLOBAL hData; LPVOID lpData;
@@ -139,11 +140,50 @@ return FALSE; }
- hEmf = SetEnhMetaFileBits(dwLength, lpData); + hMf = SetMetaFileBitsEx(dwLength, lpData);
GlobalUnlock(hData); GlobalFree(hData);
+ if (!hMf) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + + if (!SetClipboardData(CF_METAFILEPICT, hMf)) + { + DeleteMetaFile(hMf); + return FALSE; + } + + return TRUE; +} + +static BOOL ClipboardReadEnhMetafile(HANDLE hFile, DWORD dwOffset, DWORD dwLength) +{ + HENHMETAFILE hEmf; + HGLOBAL hData; + LPVOID lpData; + + hData = ClipboardReadMemoryBlock(hFile, dwOffset, dwLength); + if (!hData) + { + return FALSE; + } + + lpData = GlobalLock(hData); + if (!lpData) + { + GlobalFree(hData); + return FALSE; + } + + hEmf = SetEnhMetaFileBits(dwLength, lpData); + + GlobalUnlock(hData); + GlobalFree(hData); + if (!hEmf) { SetLastError(ERROR_OUTOFMEMORY); @@ -202,13 +242,27 @@
void ReadClipboardFile(LPCWSTR lpFileName) { - CLIPBOARDFILEHEADER cfhFileHeader; - CLIPBOARDFORMATHEADER *cfhFormatArray = NULL; + CLIPFILEHEADER ClipFileHeader; + CLIPFORMATHEADER ClipFormatArray; + NTCLIPFILEHEADER NtClipFileHeader; + NTCLIPFORMATHEADER NtClipFormatArray; + PVOID pClipFileHeader; + PVOID pClipFormatArray; + DWORD SizeOfFileHeader, SizeOfFormatHeader; + + WORD wFileIdentifier; + WORD wFormatCount; + DWORD dwFormatID; + DWORD dwLenData; + DWORD dwOffData; + PVOID szName; + HANDLE hFile; DWORD dwBytesRead; BOOL bResult; int i;
+ /* Open the file */ hFile = CreateFileW(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { @@ -216,39 +270,99 @@ goto done; }
- if (!ReadFile(hFile, &cfhFileHeader, sizeof(cfhFileHeader), &dwBytesRead, NULL)) + /* Just read enough bytes to get the clipboard file format ID */ + if (!ReadFile(hFile, &wFileIdentifier, sizeof(wFileIdentifier), &dwBytesRead, NULL)) { ShowLastWin32Error(Globals.hMainWnd); goto done; } - - if ((cfhFileHeader.wFileIdentifier != CLIPBOARD_FORMAT_NT) && (cfhFileHeader.wFileIdentifier != CLIPBOARD_FORMAT_BK)) - { - MessageBoxRes(Globals.hMainWnd, Globals.hInstance, ERROR_INVALID_FILE_FORMAT, 0, MB_ICONSTOP | MB_OK); - goto done; - } - - cfhFormatArray = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cfhFileHeader.wFormatCount * sizeof(CLIPBOARDFORMATHEADER)); - if (!cfhFormatArray) - { - SetLastError(ERROR_OUTOFMEMORY); + SetFilePointer(hFile, 0, NULL, FILE_BEGIN); + + /* Set data according to the clipboard file format ID */ + switch (wFileIdentifier) + { + case CLIP_FMT_31: + SizeOfFileHeader = sizeof(CLIPFILEHEADER); + SizeOfFormatHeader = sizeof(CLIPFORMATHEADER); + pClipFileHeader = &ClipFileHeader; + pClipFormatArray = &ClipFormatArray; + MessageBox(Globals.hMainWnd, L"We have a Win3.11 clipboard file!", L"File format", 0); + break; + + case CLIP_FMT_NT: + case CLIP_FMT_BK: + SizeOfFileHeader = sizeof(NTCLIPFILEHEADER); + SizeOfFormatHeader = sizeof(NTCLIPFORMATHEADER); + pClipFileHeader = &NtClipFileHeader; + pClipFormatArray = &NtClipFormatArray; + MessageBox(Globals.hMainWnd, L"We have a WinNT clipboard file!", L"File format", 0); + break; + + default: + MessageBoxRes(Globals.hMainWnd, Globals.hInstance, ERROR_INVALID_FILE_FORMAT, 0, MB_ICONSTOP | MB_OK); + goto done; + } + + /* Completely read the header */ + if (!ReadFile(hFile, pClipFileHeader, SizeOfFileHeader, &dwBytesRead, NULL) || + dwBytesRead != SizeOfFileHeader) + { ShowLastWin32Error(Globals.hMainWnd); goto done; }
- if (!ReadFile(hFile, cfhFormatArray, cfhFileHeader.wFormatCount * sizeof(CLIPBOARDFORMATHEADER), &dwBytesRead, NULL)) - { - ShowLastWin32Error(Globals.hMainWnd); - goto done; - } - - for (i = 0; i < cfhFileHeader.wFormatCount; i++) - { - switch (cfhFormatArray[i].dwFormatID) + /* Get header data */ + switch (wFileIdentifier) + { + case CLIP_FMT_31: + assert(wFileIdentifier == ((CLIPFILEHEADER*)pClipFileHeader)->wFileIdentifier); + wFormatCount = ((CLIPFILEHEADER*)pClipFileHeader)->wFormatCount; + break; + + case CLIP_FMT_NT: + case CLIP_FMT_BK: + assert(wFileIdentifier == ((NTCLIPFILEHEADER*)pClipFileHeader)->wFileIdentifier); + wFormatCount = ((NTCLIPFILEHEADER*)pClipFileHeader)->wFormatCount; + break; + } + + /* Loop through the data array */ + for (i = 0; i < wFormatCount; i++) + { + if (SetFilePointer(hFile, SizeOfFileHeader + i * SizeOfFormatHeader, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) + { + ShowLastWin32Error(Globals.hMainWnd); + goto done; + } + + if (!ReadFile(hFile, pClipFormatArray, SizeOfFormatHeader, &dwBytesRead, NULL)) + { + ShowLastWin32Error(Globals.hMainWnd); + goto done; + } + + /* Get format data */ + switch (wFileIdentifier) + { + case CLIP_FMT_31: + dwFormatID = ((CLIPFORMATHEADER*)pClipFormatArray)->dwFormatID; + dwLenData = ((CLIPFORMATHEADER*)pClipFormatArray)->dwLenData; + dwOffData = ((CLIPFORMATHEADER*)pClipFormatArray)->dwOffData; + szName = ((CLIPFORMATHEADER*)pClipFormatArray)->szName; + break; + + case CLIP_FMT_NT: + case CLIP_FMT_BK: + dwFormatID = ((NTCLIPFORMATHEADER*)pClipFormatArray)->dwFormatID; + dwLenData = ((NTCLIPFORMATHEADER*)pClipFormatArray)->dwLenData; + dwOffData = ((NTCLIPFORMATHEADER*)pClipFormatArray)->dwOffData; + szName = ((NTCLIPFORMATHEADER*)pClipFormatArray)->szName; + break; + } + + switch (dwFormatID) { case CF_OWNERDISPLAY: - case CF_DSPMETAFILEPICT: - case CF_METAFILEPICT: { break; } @@ -256,49 +370,47 @@ case CF_BITMAP: case CF_DSPBITMAP: { - bResult = ClipboardReadBitmap(hFile, cfhFormatArray[i].dwOffData, cfhFormatArray[i].dwLenData); - break; - } - + bResult = ClipboardReadBitmap(hFile, dwOffData, dwLenData); + break; + } + + case CF_METAFILEPICT: + case CF_DSPMETAFILEPICT: + { + bResult = ClipboardReadMetafile(hFile, dwOffData, dwLenData); + break; + } + + case CF_ENHMETAFILE: case CF_DSPENHMETAFILE: - case CF_ENHMETAFILE: - { - bResult = ClipboardReadEnhMetafile(hFile, cfhFormatArray[i].dwOffData, cfhFormatArray[i].dwLenData); + { + bResult = ClipboardReadEnhMetafile(hFile, dwOffData, dwLenData); break; }
case CF_PALETTE: { - bResult = ClipboardReadPalette(hFile, cfhFormatArray[i].dwOffData, cfhFormatArray[i].dwLenData); + bResult = ClipboardReadPalette(hFile, dwOffData, dwLenData); break; }
default: { - if ((cfhFormatArray[i].dwFormatID < CF_PRIVATEFIRST) || (cfhFormatArray[i].dwFormatID > CF_PRIVATELAST)) + if ((dwFormatID < CF_PRIVATEFIRST) || (dwFormatID > CF_PRIVATELAST)) { - bResult = ClipboardReadMemory(hFile, cfhFormatArray[i].dwFormatID, cfhFormatArray[i].dwOffData, cfhFormatArray[i].dwLenData, cfhFormatArray[i].szName); + bResult = ClipboardReadMemory(hFile, dwFormatID, dwOffData, dwLenData, wFileIdentifier, szName); } break; } }
if (!bResult) - { ShowLastWin32Error(Globals.hMainWnd); - } }
done: if (hFile != INVALID_HANDLE_VALUE) - { CloseHandle(hFile); - } - - if (cfhFormatArray) - { - HeapFree(GetProcessHeap(), 0, cfhFormatArray); - }
return; }
Modified: trunk/reactos/base/applications/clipbrd/fileutils.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/clipbrd/f... ============================================================================== --- trunk/reactos/base/applications/clipbrd/fileutils.h [iso-8859-1] (original) +++ trunk/reactos/base/applications/clipbrd/fileutils.h [iso-8859-1] Sat Feb 13 16:08:09 2016 @@ -4,26 +4,49 @@ * FILE: base/applications/clipbrd/fileutils.h * PURPOSE: Clipboard file format helper functions. * PROGRAMMERS: Ricardo Hanke + * Hermes Belusca-Maito */
-#define CLIPBOARD_FORMAT_31 0xC350 -#define CLIPBOARD_FORMAT_NT 0xC351 -#define CLIPBOARD_FORMAT_BK 0xC352 +#define CLIP_FMT_31 0xC350 +#define CLIP_FMT_NT 0xC351 +#define CLIP_FMT_BK 0xC352 #define MAX_FMT_NAME_LEN 79
-typedef struct _CLIPBOARDFILEHEADER +/* + * Win3.1 Clipboard File Format (default) + */ +#pragma pack(push, 1) +typedef struct _CLIPFILEHEADER { WORD wFileIdentifier; WORD wFormatCount; -} CLIPBOARDFILEHEADER; +} CLIPFILEHEADER;
-typedef struct _CLIPBOARDFORMATHEADER +typedef struct _CLIPFORMATHEADER +{ + WORD dwFormatID; + DWORD dwLenData; + DWORD dwOffData; + CHAR szName[MAX_FMT_NAME_LEN]; +} CLIPFORMATHEADER; +#pragma pack(pop) + +/* + * NT Clipboard File Format + */ +typedef struct _NTCLIPFILEHEADER +{ + WORD wFileIdentifier; + WORD wFormatCount; +} NTCLIPFILEHEADER; + +typedef struct _NTCLIPFORMATHEADER { DWORD dwFormatID; DWORD dwLenData; DWORD dwOffData; WCHAR szName[MAX_FMT_NAME_LEN]; -} CLIPBOARDFORMATHEADER; +} NTCLIPFORMATHEADER;
void ReadClipboardFile(LPCWSTR lpFileName); void WriteClipboardFile(LPCWSTR lpFileName);
Modified: trunk/reactos/base/applications/clipbrd/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/clipbrd/p... ============================================================================== --- trunk/reactos/base/applications/clipbrd/precomp.h [iso-8859-1] (original) +++ trunk/reactos/base/applications/clipbrd/precomp.h [iso-8859-1] Sat Feb 13 16:08:09 2016 @@ -4,6 +4,8 @@ // #pragma once
#include <limits.h> + +#include <assert.h>
#include <windef.h> #include <winbase.h>