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/archiv…
) 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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>