2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Clipboard Viewer
4 * FILE: base/applications/clipbrd/fileutils.c
5 * PURPOSE: Clipboard file format helper functions.
6 * PROGRAMMERS: Ricardo Hanke
12 static HGLOBAL
ClipboardReadMemoryBlock(HANDLE hFile
, DWORD dwOffset
, DWORD dwLength
)
18 hData
= GlobalAlloc(GHND
, dwLength
);
22 lpData
= GlobalLock(hData
);
29 if (SetFilePointer(hFile
, dwOffset
, NULL
, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
)
36 if (!ReadFile(hFile
, lpData
, dwLength
, &dwBytesRead
, NULL
))
48 static BOOL
ClipboardReadMemory(HANDLE hFile
, DWORD dwFormat
, DWORD dwOffset
, DWORD dwLength
, WORD FileIdentifier
, PVOID lpFormatName
)
53 hData
= ClipboardReadMemoryBlock(hFile
, dwOffset
, dwLength
);
57 if ((dwFormat
>= 0xC000) && (dwFormat
<= 0xFFFF))
59 if (FileIdentifier
== CLIP_FMT_31
)
60 dwTemp
= RegisterClipboardFormatA((LPCSTR
)lpFormatName
);
61 else if ((FileIdentifier
== CLIP_FMT_NT
) || (FileIdentifier
== CLIP_FMT_BK
))
62 dwTemp
= RegisterClipboardFormatW((LPCWSTR
)lpFormatName
);
75 if (!SetClipboardData(dwTemp
, hData
))
84 static BOOL
ClipboardReadPalette(HANDLE hFile
, DWORD dwOffset
, DWORD dwLength
)
86 LPLOGPALETTE lpPalette
;
90 hData
= ClipboardReadMemoryBlock(hFile
, dwOffset
, dwLength
);
96 lpPalette
= GlobalLock(hData
);
103 hPalette
= CreatePalette(lpPalette
);
108 SetLastError(ERROR_OUTOFMEMORY
);
115 if (!SetClipboardData(CF_PALETTE
, hPalette
))
117 DeleteObject(hPalette
);
124 static BOOL
ClipboardReadMetafile(HANDLE hFile
, DWORD dwOffset
, DWORD dwLength
)
130 hData
= ClipboardReadMemoryBlock(hFile
, dwOffset
, dwLength
);
136 lpData
= GlobalLock(hData
);
143 hMf
= SetMetaFileBitsEx(dwLength
, lpData
);
150 SetLastError(ERROR_OUTOFMEMORY
);
154 if (!SetClipboardData(CF_METAFILEPICT
, hMf
))
163 static BOOL
ClipboardReadEnhMetafile(HANDLE hFile
, DWORD dwOffset
, DWORD dwLength
)
169 hData
= ClipboardReadMemoryBlock(hFile
, dwOffset
, dwLength
);
175 lpData
= GlobalLock(hData
);
182 hEmf
= SetEnhMetaFileBits(dwLength
, lpData
);
189 SetLastError(ERROR_OUTOFMEMORY
);
193 if (!SetClipboardData(CF_ENHMETAFILE
, hEmf
))
195 DeleteEnhMetaFile(hEmf
);
202 static BOOL
ClipboardReadBitmap(HANDLE hFile
, DWORD dwOffset
, DWORD dwLength
)
208 hData
= ClipboardReadMemoryBlock(hFile
, dwOffset
, dwLength
);
214 lpBitmap
= GlobalLock(hData
);
221 lpBitmap
->bmBits
= lpBitmap
+ sizeof(BITMAP
) + 1;
223 hBitmap
= CreateBitmapIndirect(lpBitmap
);
230 SetLastError(ERROR_OUTOFMEMORY
);
234 if (!SetClipboardData(CF_BITMAP
, hBitmap
))
236 DeleteObject(hBitmap
);
243 void ReadClipboardFile(LPCWSTR lpFileName
)
245 CLIPFILEHEADER ClipFileHeader
;
246 CLIPFORMATHEADER ClipFormatArray
;
247 NTCLIPFILEHEADER NtClipFileHeader
;
248 NTCLIPFORMATHEADER NtClipFormatArray
;
249 PVOID pClipFileHeader
;
250 PVOID pClipFormatArray
;
251 DWORD SizeOfFileHeader
, SizeOfFormatHeader
;
253 WORD wFileIdentifier
;
266 hFile
= CreateFileW(lpFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
267 if (hFile
== INVALID_HANDLE_VALUE
)
269 ShowLastWin32Error(Globals
.hMainWnd
);
273 /* Just read enough bytes to get the clipboard file format ID */
274 if (!ReadFile(hFile
, &wFileIdentifier
, sizeof(wFileIdentifier
), &dwBytesRead
, NULL
))
276 ShowLastWin32Error(Globals
.hMainWnd
);
279 SetFilePointer(hFile
, 0, NULL
, FILE_BEGIN
);
281 /* Set data according to the clipboard file format ID */
282 switch (wFileIdentifier
)
285 SizeOfFileHeader
= sizeof(CLIPFILEHEADER
);
286 SizeOfFormatHeader
= sizeof(CLIPFORMATHEADER
);
287 pClipFileHeader
= &ClipFileHeader
;
288 pClipFormatArray
= &ClipFormatArray
;
289 MessageBox(Globals
.hMainWnd
, L
"We have a Win3.11 clipboard file!", L
"File format", 0);
294 SizeOfFileHeader
= sizeof(NTCLIPFILEHEADER
);
295 SizeOfFormatHeader
= sizeof(NTCLIPFORMATHEADER
);
296 pClipFileHeader
= &NtClipFileHeader
;
297 pClipFormatArray
= &NtClipFormatArray
;
298 MessageBox(Globals
.hMainWnd
, L
"We have a WinNT clipboard file!", L
"File format", 0);
302 MessageBoxRes(Globals
.hMainWnd
, Globals
.hInstance
, ERROR_INVALID_FILE_FORMAT
, 0, MB_ICONSTOP
| MB_OK
);
306 /* Completely read the header */
307 if (!ReadFile(hFile
, pClipFileHeader
, SizeOfFileHeader
, &dwBytesRead
, NULL
) ||
308 dwBytesRead
!= SizeOfFileHeader
)
310 ShowLastWin32Error(Globals
.hMainWnd
);
314 /* Get header data */
315 switch (wFileIdentifier
)
318 assert(wFileIdentifier
== ((CLIPFILEHEADER
*)pClipFileHeader
)->wFileIdentifier
);
319 wFormatCount
= ((CLIPFILEHEADER
*)pClipFileHeader
)->wFormatCount
;
324 assert(wFileIdentifier
== ((NTCLIPFILEHEADER
*)pClipFileHeader
)->wFileIdentifier
);
325 wFormatCount
= ((NTCLIPFILEHEADER
*)pClipFileHeader
)->wFormatCount
;
329 /* Loop through the data array */
330 for (i
= 0; i
< wFormatCount
; i
++)
332 if (SetFilePointer(hFile
, SizeOfFileHeader
+ i
* SizeOfFormatHeader
, NULL
, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
)
334 ShowLastWin32Error(Globals
.hMainWnd
);
338 if (!ReadFile(hFile
, pClipFormatArray
, SizeOfFormatHeader
, &dwBytesRead
, NULL
))
340 ShowLastWin32Error(Globals
.hMainWnd
);
344 /* Get format data */
345 switch (wFileIdentifier
)
348 dwFormatID
= ((CLIPFORMATHEADER
*)pClipFormatArray
)->dwFormatID
;
349 dwLenData
= ((CLIPFORMATHEADER
*)pClipFormatArray
)->dwLenData
;
350 dwOffData
= ((CLIPFORMATHEADER
*)pClipFormatArray
)->dwOffData
;
351 szName
= ((CLIPFORMATHEADER
*)pClipFormatArray
)->szName
;
356 dwFormatID
= ((NTCLIPFORMATHEADER
*)pClipFormatArray
)->dwFormatID
;
357 dwLenData
= ((NTCLIPFORMATHEADER
*)pClipFormatArray
)->dwLenData
;
358 dwOffData
= ((NTCLIPFORMATHEADER
*)pClipFormatArray
)->dwOffData
;
359 szName
= ((NTCLIPFORMATHEADER
*)pClipFormatArray
)->szName
;
365 case CF_OWNERDISPLAY
:
373 bResult
= ClipboardReadBitmap(hFile
, dwOffData
, dwLenData
);
377 case CF_METAFILEPICT
:
378 case CF_DSPMETAFILEPICT
:
380 bResult
= ClipboardReadMetafile(hFile
, dwOffData
, dwLenData
);
385 case CF_DSPENHMETAFILE
:
387 bResult
= ClipboardReadEnhMetafile(hFile
, dwOffData
, dwLenData
);
393 bResult
= ClipboardReadPalette(hFile
, dwOffData
, dwLenData
);
399 if ((dwFormatID
< CF_PRIVATEFIRST
) || (dwFormatID
> CF_PRIVATELAST
))
401 bResult
= ClipboardReadMemory(hFile
, dwFormatID
, dwOffData
, dwLenData
, wFileIdentifier
, szName
);
408 ShowLastWin32Error(Globals
.hMainWnd
);
412 if (hFile
!= INVALID_HANDLE_VALUE
)
418 void WriteClipboardFile(LPCWSTR lpFileName
)
420 MessageBoxW(Globals
.hMainWnd
, L
"This function is currently not implemented.", L
"Clipboard", MB_OK
| MB_ICONINFORMATION
);