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/en-us/dnargdi/html/msdn_emfdcode.asp?
 ) 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/clipbrd.c?rev=70730&r1=70729&r2=70730&view=diff
==============================================================================
--- 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/fileutils.c?rev=70730&r1=70729&r2=70730&view=diff
==============================================================================
--- 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/fileutils.h?rev=70730&r1=70729&r2=70730&view=diff
==============================================================================
--- 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/precomp.h?rev=70730&r1=70729&r2=70730&view=diff
==============================================================================
--- 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>


Reply via email to