/* File: D:\WACKER\ext\iconext.c (Created: 11-Mar-1994) * * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI * All rights reserved * * $Revision: 3 $ * $Date: 11/07/00 10:44a $ */ #define _INC_OLE // WIN32, get ole2 from windows.h #define CONST_VTABLE #define INITGUID #include #pragma hdrstop #include // // Initialize GUIDs (should be done only and at-least once per DLL/EXE) // #pragma data_seg(".text") #include #include //#include //#include #include #include #include "pageext.hh" #pragma data_seg() // // Function prototypes // HRESULT CALLBACK PageExt_CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR*); BOOL WINAPI TDllEntry(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved); BOOL WINAPI _CRT_INIT(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved); // // Global variables // UINT g_cRefThisDll = 0; // Reference count of this DLL. HINSTANCE hInstanceDll; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: * IconEntry * * DESCRIPTION: * Currently, just initializes the C-Runtime library but may be used * for other things later. * * ARGUMENTS: * hInstDll - Instance of this DLL * fdwReason - Why this entry point is called * lpReserved - reserved * * RETURNS: * BOOL * */ BOOL WINAPI IconEntry(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved) { hInstanceDll = hInstDll; // You need to initialize the C runtime if you use any C-Runtime // functions. Currently this is not the case execpt for memcmp // used in IsEqualGUID(). However, if we're compiling for release // we get the inline version of memcmp and so we don't need the // C-Runtime. #if defined(NDEBUG) return TRUE; #else return _CRT_INIT(hInstDll, fdwReason, lpReserved); #endif } //--------------------------------------------------------------------------- // DllCanUnloadNow //--------------------------------------------------------------------------- STDAPI DllCanUnloadNow(void) { return ResultFromScode((g_cRefThisDll==0) ? S_OK : S_FALSE); } //--------------------------------------------------------------------------- // // DllGetClassObject // // This is the entry of this DLL, which all the In-Proc server DLLs should // export. See the description of "DllGetClassObject" of OLE 2.0 reference // manual for detail. // //--------------------------------------------------------------------------- STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppvOut) { // // This DLL has only one class (CLSID_SampleIconExt). If a DLL supports // multiple classes, it should have either multiple if-statements or // efficient table lookup code. // if (IsEqualIID(rclsid, &CLSID_SampleIconExt)) { // // We are supposed return the class object for this class. Instead // of fully implementing it in this DLL, we just call a helper // function in the shell DLL which creates a default class factory // object for us. When its CreateInstance member is called, it // will call back our create instance function (IconExt_CreateInstance). // return SHCreateDefClassObject( riid, ppvOut, IconExt_CreateInstance, // callback function &g_cRefThisDll, // reference count of this DLL &IID_IPersistFile // init interface ); } return ResultFromScode(CLASS_E_CLASSNOTAVAILABLE); } //--------------------------------------------------------------------------- // // CSampleIconExt class // // In C++: // class CSampleIconExt : protected IExtractIcon, protected IPersistFile // { // protected: // int _cRef; // LPDATAOBJECT _pdtobj; // HKEY _hkeyProgID; // public: // CSampleIconExt() _cRef(1), _pdtobj(NULL), _hkeyProgID(NULL) {}; // ... // }; // //--------------------------------------------------------------------------- typedef struct _CSampleIconExt // smx { IExtractIcon _ctm; // 1st base class IPersistFile _sxi; // 2nd base class int _cRef; // reference count char _szFile[MAX_PATH]; // } CSampleIconExt, * PSAMPLEICONEXT; #define SMX_OFFSETOF(x) ((UINT_PTR)(&((PSAMPLEICONEXT)0)->x)) #define PVOID2PSMX(pv,offset) ((PSAMPLEICONEXT)(((LPBYTE)pv)-offset)) #define PCTM2PSMX(pctm) PVOID2PSMX(pctm, SMX_OFFSETOF(_ctm)) #define PSXI2PSMX(psxi) PVOID2PSMX(psxi, SMX_OFFSETOF(_sxi)) // // Vtable prototype // extern IExtractIconVtbl c_SampleIconExt_CTMVtbl; extern IPersistFileVtbl c_SampleIconExt_SXIVtbl; //--------------------------------------------------------------------------- // // IconExt_CreateInstance // // This function is called back from within IClassFactory::CreateInstance() // of the default class factory object, which is created by SHCreateClassObject. // //--------------------------------------------------------------------------- HRESULT CALLBACK IconExt_CreateInstance(LPUNKNOWN punkOuter, REFIID riid, LPVOID FAR* ppvOut) { HRESULT hres; PSAMPLEICONEXT psmx; // // Shell extentions typically does not support aggregation. // if (punkOuter) return ResultFromScode(CLASS_E_NOAGGREGATION); // // in C++: // psmx = new CSampleIconExt(); // psmx = LocalAlloc(LPTR, sizeof(CSampleIconExt)); if (!psmx) return ResultFromScode(E_OUTOFMEMORY); psmx->_ctm.lpVtbl = &c_SampleIconExt_CTMVtbl; psmx->_sxi.lpVtbl = &c_SampleIconExt_SXIVtbl; psmx->_cRef = 1; g_cRefThisDll++; // // in C++: // hres = psmx->QueryInterface(riid, ppvOut); // psmx->Release(); // // Note that the Release member will free the object, if QueryInterface // failed. // hres = c_SampleIconExt_CTMVtbl.QueryInterface(&psmx->_ctm, riid, ppvOut); c_SampleIconExt_CTMVtbl.Release(&psmx->_ctm); return hres; // S_OK or E_NOINTERFACE } //--------------------------------------------------------------------------- // CSampleIconExt::Load (IPersistFile override) //--------------------------------------------------------------------------- STDMETHODIMP IconExt_GetClassID(LPPERSISTFILE pPersistFile, LPCLSID lpClassID) { return ResultFromScode(E_FAIL); } STDMETHODIMP IconExt_IsDirty(LPPERSISTFILE pPersistFile) { return ResultFromScode(E_FAIL); } STDMETHODIMP IconExt_Load(LPPERSISTFILE pPersistFile, LPCOLESTR lpszFileName, DWORD grfMode) { PSAMPLEICONEXT this = PSXI2PSMX(pPersistFile); int iRet = 0; #if 1 iRet = WideCharToMultiByte( CP_ACP, // CodePage 0, // dwFlags lpszFileName, // lpWideCharStr -1, // cchWideChar this->_szFile, // lpMultiByteStr sizeof(this->_szFile), // cchMultiByte, NULL, // lpDefaultChar, NULL // lpUsedDefaultChar ); #endif // // WideCharToMultiByte does not work on build 84. // #if 1 if (iRet==0) { LPSTR psz=this->_szFile; while(*psz++ = (char)*lpszFileName++); } #endif return NOERROR; } STDMETHODIMP IconExt_Save(LPPERSISTFILE pPersistFile, LPCOLESTR lpszFileName, BOOL fRemember) { return ResultFromScode(E_FAIL); } STDMETHODIMP IconExt_SaveCompleted(LPPERSISTFILE pPersistFile, LPCOLESTR lpszFileName) { return ResultFromScode(E_FAIL); } STDMETHODIMP IconExt_GetCurFile(LPPERSISTFILE pPersistFile, LPOLESTR FAR* lplpszFileName) { return ResultFromScode(E_FAIL); } /* * At the time I write this, the only known documentation for these next two * functions is in SHLOBJ.H. Please take the time to read it. */ STDMETHODIMP IconExt_GetIconLocation(LPEXTRACTICON pexic, UINT uFlags, LPSTR szIconFile, UINT cchMax, int FAR * piIndex, UINT FAR * pwFlags) { PSAMPLEICONEXT this = PCTM2PSMX(pexic); if (this->_szFile[0]) { HANDLE hFile; DWORD dw; DWORD dwSize; DWORD dwIdx; int nIndex = 0; int nRet = 0; GetModuleFileName(hInstanceDll, szIconFile, cchMax); hFile = CreateFile(this->_szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if ( hFile != INVALID_HANDLE_VALUE ) //mpt:4-29-98 we weren't checking for failure here { // Skip past header. First ID will be the icon number. // (IDs are shorts). Size field follows (DWORD) if (SetFilePointer(hFile, 256+sizeof(SHORT), 0, FILE_BEGIN) != (DWORD)-1) { if (ReadFile(hFile, &dwSize, sizeof(DWORD), &dw, 0)) { dwIdx = 0; if (ReadFile(hFile, &dwIdx, min(sizeof(DWORD), dwSize), &dw, 0)) { nIndex = (int)dwIdx; nIndex -= IDI_PROG; } } } CloseHandle(hFile); } *piIndex = nIndex; } *pwFlags = 0; return NOERROR; } STDMETHODIMP IconExt_Extract(LPEXTRACTICON pexic, LPCSTR pszFile, UINT nIconIndex, HICON FAR *phiconLarge, HICON FAR *phiconSmall, UINT nIcons) { // Force default extraction. return ResultFromScode(S_FALSE); } //--------------------------------------------------------------------------- // CSampleIconExt::AddRef (IExtractIcon override) //--------------------------------------------------------------------------- STDMETHODIMP_(UINT) IconExt_CTM_AddRef(LPEXTRACTICON pctm) { PSAMPLEICONEXT this = PCTM2PSMX(pctm); return ++this->_cRef; } //--------------------------------------------------------------------------- // CSampleIconExt::AddRef (IPersistFile override) //--------------------------------------------------------------------------- STDMETHODIMP_(UINT) IconExt_SXI_AddRef(LPPERSISTFILE psxi) { PSAMPLEICONEXT this = PSXI2PSMX(psxi); return ++this->_cRef; } //--------------------------------------------------------------------------- // CSampleIconExt::Release (IExtractIcon override) //--------------------------------------------------------------------------- STDMETHODIMP_(UINT) IconExt_CTM_Release(LPEXTRACTICON pctm) { UINT cRef; PSAMPLEICONEXT this = PCTM2PSMX(pctm); #if DBG==1 if( 0 == this->_cRef ) { DebugBreak(); // ref counting problem } #endif cRef = InterlockedDecrement(&this->_cRef); if ( 0 == cRef ) { LocalFree((HLOCAL)this); g_cRefThisDll--; } return cRef; } //--------------------------------------------------------------------------- // CSampleIconExt::Release (IPersistFile thunk) //--------------------------------------------------------------------------- STDMETHODIMP_(UINT) IconExt_SXI_Release(LPPERSISTFILE psxi) { PSAMPLEICONEXT this = PSXI2PSMX(psxi); return IconExt_CTM_Release(&this->_ctm); } //--------------------------------------------------------------------------- // CSampleIconExt::QueryInterface (IExtractIcon override) //--------------------------------------------------------------------------- STDMETHODIMP IconExt_CTM_QueryInterface(LPEXTRACTICON pctm, REFIID riid, LPVOID FAR* ppvOut) { PSAMPLEICONEXT this = PCTM2PSMX(pctm); if (IsEqualIID(riid, &IID_IExtractIcon) || IsEqualIID(riid, &IID_IUnknown)) { (LPEXTRACTICON)*ppvOut=pctm; this->_cRef++; return NOERROR; } if (IsEqualIID(riid, &IID_IPersistFile)) { (LPPERSISTFILE)*ppvOut=&this->_sxi; this->_cRef++; return NOERROR; } return ResultFromScode(E_NOINTERFACE); } //--------------------------------------------------------------------------- // CSampleIconExt::QueryInterface (IPersistFile thunk) //--------------------------------------------------------------------------- STDMETHODIMP IconExt_SXI_QueryInterface(LPPERSISTFILE psxi, REFIID riid, LPVOID FAR* ppv) { PSAMPLEICONEXT this = PSXI2PSMX(psxi); return IconExt_CTM_QueryInterface(&this->_ctm, riid, ppv); } //--------------------------------------------------------------------------- // CSampleIconExt class : Vtables //--------------------------------------------------------------------------- #pragma data_seg(".text") IExtractIconVtbl c_SampleIconExt_CTMVtbl = { IconExt_CTM_QueryInterface, IconExt_CTM_AddRef, IconExt_CTM_Release, IconExt_GetIconLocation, IconExt_Extract, }; IPersistFileVtbl c_SampleIconExt_SXIVtbl = { IconExt_SXI_QueryInterface, IconExt_SXI_AddRef, IconExt_SXI_Release, IconExt_GetClassID, IconExt_IsDirty, IconExt_Load, IconExt_Save, IconExt_SaveCompleted, IconExt_GetCurFile }; #pragma data_seg()