/* disable unnecessary level-4 warnings */
#pragma warning(disable: 4201) // nonstandard extension used
#pragma warning(disable: 4514) // unreferenced inline function
/* include files */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include "Filter.h"
/* private manifest constants */
#define FILTER_VER_TYPE2 2 // type 2 filter version
#define FILTER_FAILED 0 // operation failed
#define FILTER_TEXT 1 // filter is a text filter
#define FILTER_GRAPHIC 2 // filter is a graphic filter
#define CCH_MAX_KEY_NAME 256
#define CCH_MAX_FILTER_EXT MAX_PATH
/* private constants */
static const LPCSTR lpszGetFilterInfoExportNames[] = {
"GetFilterInfo",
"GetFilterInfo@16",
"GETFILTERINFO",
NULL };
static const LPCSTR lpszGetFilterPrefExportNames[] = {
"GetFilterPref",
"GetFilterPref@16",
"GETFILTERPREF",
NULL };
static const LPCSTR lpszImportGRExportNames[] = {
"ImportGR",
"ImportGr",
"ImportGR@16",
"ImportGr@16",
"IMPORTGR",
NULL };
/* private type defintions */
#pragma pack(push, 1)
typedef DWORD FILETYPE;
typedef struct
{
WORD slippery : 1; // TRUE if file may disappear
WORD write : 1; // TRUE if open for write
WORD unnamed : 1; // TRUE if unnamed
WORD linked : 1; // Linked to an FS FCB
WORD mark : 1; // Generic mark bit
FILETYPE fType; // The file type
WORD handle; // MS-DOS open file handle
char fullName[MAX_PATH]; // Device, path, file name
DWORD filePos; // Current file posn
} FILESPEC;
#pragma pack(pop)
typedef UINT (CALLBACK * GETFILTERINFOPROC)(
DWORD idVersion,
LPSTR lpszIni,
HGLOBAL * lphPrefMem,
HANDLE * lphFileTypes);
typedef VOID (CALLBACK * GETFILTERPREFPROC)(
HINSTANCE hInstance,
HWND hwndParent,
HGLOBAL hPrefMem,
DWORD dwFlags);
typedef UINT (CALLBACK * IMPORTGRPROC)(
HDC hdcPrint,
FILESPEC * lpfs,
PICTINFO * lppi,
HGLOBAL hPrefMem);
/* private helper macros */
#ifndef CountOf
#define CountOf(array) (sizeof(array)/sizeof((array)[0]))
#endif
/* private function prototypes */
static BOOL FindGraphicImportFilter(
LPCSTR lpszExtension,
LPSTR lpszDestFilterPath,
const UINT cchDestFilterPath);
static FARPROC ResolveProcAddress(
const HMODULE hLibrary,
const LPCSTR * lpszNames);
/*** ***
*** PUBLIC IMPLEMENTATION ***
*** ***/
//---------------------------------------------------------------
//ImportGraphic
//---------------------------------------------------------------
UINT ImportGraphic(
const LPCSTR lpszFileName,
PICTINFO * pPictInfo,
const BOOL fPreferences,
const HWND hwndParent)
{
/* TEMPORARY variables */
GETFILTERINFOPROC GetFilterInfo = NULL;
GETFILTERPREFPROC GetFilterPref = NULL;
IMPORTGRPROC ImportGR = NULL;
FILESPEC fs = { 0 };
HMODULE hFilterLib = NULL;
HGLOBAL hPrefMem = NULL;
char szType[_MAX_EXT+1] = "";
char szImportFilter[MAX_PATH+1] = "";
UINT uResult = IE_NOT_MY_FILE;
/* init */
if (pPictInfo != NULL)
{
ZeroMemory(pPictInfo, sizeof(PICTINFO));
/* get file type (extension) */
_splitpath(lpszFileName, NULL, NULL, NULL, szType);
if (szType[0] != NULL)
{
/* locate graphic import filter based on type */
if (FindGraphicImportFilter(
szType,
szImportFilter,
CountOf(szImportFilter)))
{
/* convert the file name to its short representation */
if (!GetShortPathName(
lpszFileName,
fs.fullName,
CountOf(fs.fullName)))
{
/* couldn't convert (probably UNC), use name anyway */
lstrcpyn(fs.fullName, lpszFileName,
CountOf(fs.fullName));
}
/* load the filter library and locate the entry-points */
hFilterLib = LoadLibrary(szImportFilter);
if (hFilterLib != NULL)
{
GetFilterInfo = (GETFILTERINFOPROC)ResolveProcAddress(
hFilterLib,
lpszGetFilterInfoExportNames);
GetFilterPref = (GETFILTERPREFPROC)ResolveProcAddress(
hFilterLib,
lpszGetFilterPrefExportNames);
ImportGR = (IMPORTGRPROC)ResolveProcAddress(
hFilterLib,
lpszImportGRExportNames);
if ((GetFilterInfo!=NULL) && (ImportGR!=NULL))
{
/* get filter info */
if (GetFilterInfo(FILTER_VER_TYPE2, NULL, &hPrefMem,
NULL)
== FILTER_GRAPHIC)
{
/* get filter preferences if specified */
if (fPreferences && (GetFilterPref!=NULL))
{
GetFilterPref(NULL, hwndParent, hPrefMem, 0);
}
/* perform import */
uResult = ImportGR(NULL, &fs, pPictInfo, hPrefMem);
}
/* release preference memory as necessary */
if (hPrefMem != NULL)
{
GlobalFree(hPrefMem);
hPrefMem = NULL;
}
}
/* clean up */
FreeLibrary(hFilterLib);
hFilterLib = NULL;
GetFilterInfo = NULL;
GetFilterPref = NULL;
ImportGR = NULL;
}
}
}
}
/* done */
return uResult;
}
/*** ***
*** PRIVATE IMPLEMENTATION ***
*** ***/
//---------------------------------------------------------------
//FindGraphicImportFilter
// LPCSTR lpszExtension - file extension (file type) to
// locate filter for
// LPSTR lpszDestFilterPath - destination address to store
// filter path and file name
// const UINT cchDestFilterPath - size of desintaion buffer, in
// characters
// >BOOL> - TRUE if filter located, FALSE
// otherwise
//---------------------------------------------------------------
BOOL FindGraphicImportFilter(
LPCSTR lpszExtension,
LPSTR lpszDestFilterPath,
const UINT cchDestFilterPath)
{
/* TEMPORARY variables */
FILETIME ftLastWrite = { 0 };
LPSTR lpszNextExt = NULL;
DWORD dwIndex = 0;
DWORD cbData = 0;
LONG lResult = 0;
HKEY hkeyImport = NULL;
HKEY hkeyFilter = NULL;
char szKeyName[CCH_MAX_KEY_NAME+1] = "";
char szFilterExtensions[CCH_MAX_FILTER_EXT+1] = "";
BOOL fFilterFound = FALSE;
/* init */
lpszDestFilterPath[0] = NULL;
if (lpszExtension[0] == '.')
{
++lpszExtension; //skip leading period
}
/* open graphic import key */
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Shared Tools\\Graphics Filters\\Import",
0,
KEY_READ,
&hkeyImport);
if (lResult == ERROR_SUCCESS)
{
/* enumerate the available import keys */
cbData = CountOf(szKeyName);
szKeyName[0] = NULL;
while (!fFilterFound && (RegEnumKeyEx(
hkeyImport,
dwIndex,
szKeyName,
&cbData,
NULL,
NULL,
NULL,
&ftLastWrite) == ERROR_SUCCESS))
{
++dwIndex;
/* open the filter key */
lResult = RegOpenKeyEx(
hkeyImport,
szKeyName,
0,
KEY_READ,
&hkeyFilter);
if (lResult == ERROR_SUCCESS)
{
/* get supported filter extensions */
cbData = CountOf(szFilterExtensions);
szFilterExtensions[0] = NULL;
lResult = RegQueryValueEx(
hkeyFilter,
"ExtensionsEx",
NULL,
NULL,
(LPBYTE)szFilterExtensions,
&cbData);
if (lResult != ERROR_SUCCESS)
{
/* ex extensions not found, use default */
lResult = RegQueryValueEx(
hkeyFilter,
"Extensions",
NULL,
NULL,
(LPBYTE)szFilterExtensions,
&cbData);
}
if (lResult == ERROR_SUCCESS)
{
/* check for specified extension */
do
{
lpszNextExt = strchr(szFilterExtensions, ' ');
if (lpszNextExt != NULL)
{
*lpszNextExt = NULL;
++lpszNextExt;
}
fFilterFound = lstrcmpi(
szFilterExtensions,
lpszExtension) == 0;
if (!fFilterFound && (lpszNextExt!=NULL))
{
MoveMemory(
szFilterExtensions,
lpszNextExt,
lstrlen(lpszNextExt) + 1);
}
}
while (!fFilterFound && (lpszNextExt!=NULL));
if (fFilterFound)
{
/* get the filter path */
cbData = cchDestFilterPath;
lResult = RegQueryValueEx(
hkeyFilter,
"Path",
NULL,
NULL,
(LPBYTE)lpszDestFilterPath,
&cbData);
fFilterFound = lResult == ERROR_SUCCESS;
}
}
/* close filter key */
RegCloseKey(hkeyFilter);
hkeyFilter = NULL;
}
/* prep for next filter key */
cbData = CountOf(szKeyName);
szKeyName[0] = NULL;
}
/* close import key */
RegCloseKey(hkeyImport);
hkeyImport = NULL;
}
/* done */
return fFilterFound;
}
//---------------------------------------------------------------
//ResolveProcAddress
//---------------------------------------------------------------
FARPROC ResolveProcAddress(
const HMODULE hLibrary,
const LPCSTR * lpszNames)
{
/* TEMPORARY variables */
FARPROC fn = NULL;
UINT uIndex = 0;
/* attempt to resolve proc name */
while ((fn==NULL) && (lpszNames[uIndex]!=NULL))
{
fn = GetProcAddress(hLibrary, lpszNames[uIndex]);
++uIndex;
}
/* done */
return fn;
}
End of Listing