Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

458 lines
12 KiB

  1. /* File: D:\WACKER\ext\iconext.c (Created: 11-Mar-1994)
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 3 $
  7. * $Date: 11/07/00 10:44a $
  8. */
  9. #define _INC_OLE // WIN32, get ole2 from windows.h
  10. #define CONST_VTABLE
  11. #define INITGUID
  12. #include <windows.h>
  13. #pragma hdrstop
  14. #include <term\res.h>
  15. //
  16. // Initialize GUIDs (should be done only and at-least once per DLL/EXE)
  17. //
  18. #pragma data_seg(".text")
  19. #include <objbase.h>
  20. #include <initguid.h>
  21. //#include <coguid.h>
  22. //#include <oleguid.h>
  23. #include <shlguid.h>
  24. #include <shlobj.h>
  25. #include "pageext.hh"
  26. #pragma data_seg()
  27. //
  28. // Function prototypes
  29. //
  30. HRESULT CALLBACK PageExt_CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR*);
  31. BOOL WINAPI TDllEntry(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved);
  32. BOOL WINAPI _CRT_INIT(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved);
  33. //
  34. // Global variables
  35. //
  36. UINT g_cRefThisDll = 0; // Reference count of this DLL.
  37. HINSTANCE hInstanceDll;
  38. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  39. * FUNCTION:
  40. * IconEntry
  41. *
  42. * DESCRIPTION:
  43. * Currently, just initializes the C-Runtime library but may be used
  44. * for other things later.
  45. *
  46. * ARGUMENTS:
  47. * hInstDll - Instance of this DLL
  48. * fdwReason - Why this entry point is called
  49. * lpReserved - reserved
  50. *
  51. * RETURNS:
  52. * BOOL
  53. *
  54. */
  55. BOOL WINAPI IconEntry(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved)
  56. {
  57. hInstanceDll = hInstDll;
  58. // You need to initialize the C runtime if you use any C-Runtime
  59. // functions. Currently this is not the case execpt for memcmp
  60. // used in IsEqualGUID(). However, if we're compiling for release
  61. // we get the inline version of memcmp and so we don't need the
  62. // C-Runtime.
  63. #if defined(NDEBUG)
  64. return TRUE;
  65. #else
  66. return _CRT_INIT(hInstDll, fdwReason, lpReserved);
  67. #endif
  68. }
  69. //---------------------------------------------------------------------------
  70. // DllCanUnloadNow
  71. //---------------------------------------------------------------------------
  72. STDAPI DllCanUnloadNow(void)
  73. {
  74. return ResultFromScode((g_cRefThisDll==0) ? S_OK : S_FALSE);
  75. }
  76. //---------------------------------------------------------------------------
  77. //
  78. // DllGetClassObject
  79. //
  80. // This is the entry of this DLL, which all the In-Proc server DLLs should
  81. // export. See the description of "DllGetClassObject" of OLE 2.0 reference
  82. // manual for detail.
  83. //
  84. //---------------------------------------------------------------------------
  85. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppvOut)
  86. {
  87. //
  88. // This DLL has only one class (CLSID_SampleIconExt). If a DLL supports
  89. // multiple classes, it should have either multiple if-statements or
  90. // efficient table lookup code.
  91. //
  92. if (IsEqualIID(rclsid, &CLSID_SampleIconExt))
  93. {
  94. //
  95. // We are supposed return the class object for this class. Instead
  96. // of fully implementing it in this DLL, we just call a helper
  97. // function in the shell DLL which creates a default class factory
  98. // object for us. When its CreateInstance member is called, it
  99. // will call back our create instance function (IconExt_CreateInstance).
  100. //
  101. return SHCreateDefClassObject(
  102. riid,
  103. ppvOut,
  104. IconExt_CreateInstance, // callback function
  105. &g_cRefThisDll, // reference count of this DLL
  106. &IID_IPersistFile // init interface
  107. );
  108. }
  109. return ResultFromScode(CLASS_E_CLASSNOTAVAILABLE);
  110. }
  111. //---------------------------------------------------------------------------
  112. //
  113. // CSampleIconExt class
  114. //
  115. // In C++:
  116. // class CSampleIconExt : protected IExtractIcon, protected IPersistFile
  117. // {
  118. // protected:
  119. // int _cRef;
  120. // LPDATAOBJECT _pdtobj;
  121. // HKEY _hkeyProgID;
  122. // public:
  123. // CSampleIconExt() _cRef(1), _pdtobj(NULL), _hkeyProgID(NULL) {};
  124. // ...
  125. // };
  126. //
  127. //---------------------------------------------------------------------------
  128. typedef struct _CSampleIconExt // smx
  129. {
  130. IExtractIcon _ctm; // 1st base class
  131. IPersistFile _sxi; // 2nd base class
  132. int _cRef; // reference count
  133. char _szFile[MAX_PATH]; //
  134. } CSampleIconExt, * PSAMPLEICONEXT;
  135. #define SMX_OFFSETOF(x) ((UINT_PTR)(&((PSAMPLEICONEXT)0)->x))
  136. #define PVOID2PSMX(pv,offset) ((PSAMPLEICONEXT)(((LPBYTE)pv)-offset))
  137. #define PCTM2PSMX(pctm) PVOID2PSMX(pctm, SMX_OFFSETOF(_ctm))
  138. #define PSXI2PSMX(psxi) PVOID2PSMX(psxi, SMX_OFFSETOF(_sxi))
  139. //
  140. // Vtable prototype
  141. //
  142. extern IExtractIconVtbl c_SampleIconExt_CTMVtbl;
  143. extern IPersistFileVtbl c_SampleIconExt_SXIVtbl;
  144. //---------------------------------------------------------------------------
  145. //
  146. // IconExt_CreateInstance
  147. //
  148. // This function is called back from within IClassFactory::CreateInstance()
  149. // of the default class factory object, which is created by SHCreateClassObject.
  150. //
  151. //---------------------------------------------------------------------------
  152. HRESULT CALLBACK IconExt_CreateInstance(LPUNKNOWN punkOuter,
  153. REFIID riid, LPVOID FAR* ppvOut)
  154. {
  155. HRESULT hres;
  156. PSAMPLEICONEXT psmx;
  157. //
  158. // Shell extentions typically does not support aggregation.
  159. //
  160. if (punkOuter)
  161. return ResultFromScode(CLASS_E_NOAGGREGATION);
  162. //
  163. // in C++:
  164. // psmx = new CSampleIconExt();
  165. //
  166. psmx = LocalAlloc(LPTR, sizeof(CSampleIconExt));
  167. if (!psmx)
  168. return ResultFromScode(E_OUTOFMEMORY);
  169. psmx->_ctm.lpVtbl = &c_SampleIconExt_CTMVtbl;
  170. psmx->_sxi.lpVtbl = &c_SampleIconExt_SXIVtbl;
  171. psmx->_cRef = 1;
  172. g_cRefThisDll++;
  173. //
  174. // in C++:
  175. // hres = psmx->QueryInterface(riid, ppvOut);
  176. // psmx->Release();
  177. //
  178. // Note that the Release member will free the object, if QueryInterface
  179. // failed.
  180. //
  181. hres = c_SampleIconExt_CTMVtbl.QueryInterface(&psmx->_ctm, riid, ppvOut);
  182. c_SampleIconExt_CTMVtbl.Release(&psmx->_ctm);
  183. return hres; // S_OK or E_NOINTERFACE
  184. }
  185. //---------------------------------------------------------------------------
  186. // CSampleIconExt::Load (IPersistFile override)
  187. //---------------------------------------------------------------------------
  188. STDMETHODIMP IconExt_GetClassID(LPPERSISTFILE pPersistFile, LPCLSID lpClassID)
  189. {
  190. return ResultFromScode(E_FAIL);
  191. }
  192. STDMETHODIMP IconExt_IsDirty(LPPERSISTFILE pPersistFile)
  193. {
  194. return ResultFromScode(E_FAIL);
  195. }
  196. STDMETHODIMP IconExt_Load(LPPERSISTFILE pPersistFile, LPCOLESTR lpszFileName, DWORD grfMode)
  197. {
  198. PSAMPLEICONEXT this = PSXI2PSMX(pPersistFile);
  199. int iRet = 0;
  200. #if 1
  201. iRet = WideCharToMultiByte(
  202. CP_ACP, // CodePage
  203. 0, // dwFlags
  204. lpszFileName, // lpWideCharStr
  205. -1, // cchWideChar
  206. this->_szFile, // lpMultiByteStr
  207. sizeof(this->_szFile), // cchMultiByte,
  208. NULL, // lpDefaultChar,
  209. NULL // lpUsedDefaultChar
  210. );
  211. #endif
  212. //
  213. // WideCharToMultiByte does not work on build 84.
  214. //
  215. #if 1
  216. if (iRet==0)
  217. {
  218. LPSTR psz=this->_szFile;
  219. while(*psz++ = (char)*lpszFileName++);
  220. }
  221. #endif
  222. return NOERROR;
  223. }
  224. STDMETHODIMP IconExt_Save(LPPERSISTFILE pPersistFile, LPCOLESTR lpszFileName, BOOL fRemember)
  225. {
  226. return ResultFromScode(E_FAIL);
  227. }
  228. STDMETHODIMP IconExt_SaveCompleted(LPPERSISTFILE pPersistFile, LPCOLESTR lpszFileName)
  229. {
  230. return ResultFromScode(E_FAIL);
  231. }
  232. STDMETHODIMP IconExt_GetCurFile(LPPERSISTFILE pPersistFile, LPOLESTR FAR* lplpszFileName)
  233. {
  234. return ResultFromScode(E_FAIL);
  235. }
  236. /*
  237. * At the time I write this, the only known documentation for these next two
  238. * functions is in SHLOBJ.H. Please take the time to read it.
  239. */
  240. STDMETHODIMP IconExt_GetIconLocation(LPEXTRACTICON pexic,
  241. UINT uFlags,
  242. LPSTR szIconFile,
  243. UINT cchMax,
  244. int FAR * piIndex,
  245. UINT FAR * pwFlags)
  246. {
  247. PSAMPLEICONEXT this = PCTM2PSMX(pexic);
  248. if (this->_szFile[0])
  249. {
  250. HANDLE hFile;
  251. DWORD dw;
  252. DWORD dwSize;
  253. DWORD dwIdx;
  254. int nIndex = 0;
  255. int nRet = 0;
  256. GetModuleFileName(hInstanceDll, szIconFile, cchMax);
  257. hFile = CreateFile(this->_szFile, GENERIC_READ, FILE_SHARE_READ,
  258. 0, OPEN_EXISTING, 0, 0);
  259. if ( hFile != INVALID_HANDLE_VALUE ) //mpt:4-29-98 we weren't checking for failure here
  260. {
  261. // Skip past header. First ID will be the icon number.
  262. // (IDs are shorts). Size field follows (DWORD)
  263. if (SetFilePointer(hFile, 256+sizeof(SHORT), 0,
  264. FILE_BEGIN) != (DWORD)-1)
  265. {
  266. if (ReadFile(hFile, &dwSize, sizeof(DWORD), &dw, 0))
  267. {
  268. dwIdx = 0;
  269. if (ReadFile(hFile, &dwIdx, min(sizeof(DWORD), dwSize),
  270. &dw, 0))
  271. {
  272. nIndex = (int)dwIdx;
  273. nIndex -= IDI_PROG;
  274. }
  275. }
  276. }
  277. CloseHandle(hFile);
  278. }
  279. *piIndex = nIndex;
  280. }
  281. *pwFlags = 0;
  282. return NOERROR;
  283. }
  284. STDMETHODIMP IconExt_Extract(LPEXTRACTICON pexic,
  285. LPCSTR pszFile,
  286. UINT nIconIndex,
  287. HICON FAR *phiconLarge,
  288. HICON FAR *phiconSmall,
  289. UINT nIcons)
  290. {
  291. // Force default extraction.
  292. return ResultFromScode(S_FALSE);
  293. }
  294. //---------------------------------------------------------------------------
  295. // CSampleIconExt::AddRef (IExtractIcon override)
  296. //---------------------------------------------------------------------------
  297. STDMETHODIMP_(UINT) IconExt_CTM_AddRef(LPEXTRACTICON pctm)
  298. {
  299. PSAMPLEICONEXT this = PCTM2PSMX(pctm);
  300. return ++this->_cRef;
  301. }
  302. //---------------------------------------------------------------------------
  303. // CSampleIconExt::AddRef (IPersistFile override)
  304. //---------------------------------------------------------------------------
  305. STDMETHODIMP_(UINT) IconExt_SXI_AddRef(LPPERSISTFILE psxi)
  306. {
  307. PSAMPLEICONEXT this = PSXI2PSMX(psxi);
  308. return ++this->_cRef;
  309. }
  310. //---------------------------------------------------------------------------
  311. // CSampleIconExt::Release (IExtractIcon override)
  312. //---------------------------------------------------------------------------
  313. STDMETHODIMP_(UINT) IconExt_CTM_Release(LPEXTRACTICON pctm)
  314. {
  315. UINT cRef;
  316. PSAMPLEICONEXT this = PCTM2PSMX(pctm);
  317. #if DBG==1
  318. if( 0 == this->_cRef )
  319. {
  320. DebugBreak(); // ref counting problem
  321. }
  322. #endif
  323. cRef = InterlockedDecrement(&this->_cRef);
  324. if ( 0 == cRef )
  325. {
  326. LocalFree((HLOCAL)this);
  327. g_cRefThisDll--;
  328. }
  329. return cRef;
  330. }
  331. //---------------------------------------------------------------------------
  332. // CSampleIconExt::Release (IPersistFile thunk)
  333. //---------------------------------------------------------------------------
  334. STDMETHODIMP_(UINT) IconExt_SXI_Release(LPPERSISTFILE psxi)
  335. {
  336. PSAMPLEICONEXT this = PSXI2PSMX(psxi);
  337. return IconExt_CTM_Release(&this->_ctm);
  338. }
  339. //---------------------------------------------------------------------------
  340. // CSampleIconExt::QueryInterface (IExtractIcon override)
  341. //---------------------------------------------------------------------------
  342. STDMETHODIMP IconExt_CTM_QueryInterface(LPEXTRACTICON pctm, REFIID riid, LPVOID FAR* ppvOut)
  343. {
  344. PSAMPLEICONEXT this = PCTM2PSMX(pctm);
  345. if (IsEqualIID(riid, &IID_IExtractIcon) ||
  346. IsEqualIID(riid, &IID_IUnknown))
  347. {
  348. (LPEXTRACTICON)*ppvOut=pctm;
  349. this->_cRef++;
  350. return NOERROR;
  351. }
  352. if (IsEqualIID(riid, &IID_IPersistFile))
  353. {
  354. (LPPERSISTFILE)*ppvOut=&this->_sxi;
  355. this->_cRef++;
  356. return NOERROR;
  357. }
  358. return ResultFromScode(E_NOINTERFACE);
  359. }
  360. //---------------------------------------------------------------------------
  361. // CSampleIconExt::QueryInterface (IPersistFile thunk)
  362. //---------------------------------------------------------------------------
  363. STDMETHODIMP IconExt_SXI_QueryInterface(LPPERSISTFILE psxi, REFIID riid, LPVOID FAR* ppv)
  364. {
  365. PSAMPLEICONEXT this = PSXI2PSMX(psxi);
  366. return IconExt_CTM_QueryInterface(&this->_ctm, riid, ppv);
  367. }
  368. //---------------------------------------------------------------------------
  369. // CSampleIconExt class : Vtables
  370. //---------------------------------------------------------------------------
  371. #pragma data_seg(".text")
  372. IExtractIconVtbl c_SampleIconExt_CTMVtbl =
  373. {
  374. IconExt_CTM_QueryInterface,
  375. IconExt_CTM_AddRef,
  376. IconExt_CTM_Release,
  377. IconExt_GetIconLocation,
  378. IconExt_Extract,
  379. };
  380. IPersistFileVtbl c_SampleIconExt_SXIVtbl =
  381. {
  382. IconExt_SXI_QueryInterface,
  383. IconExt_SXI_AddRef,
  384. IconExt_SXI_Release,
  385. IconExt_GetClassID,
  386. IconExt_IsDirty,
  387. IconExt_Load,
  388. IconExt_Save,
  389. IconExt_SaveCompleted,
  390. IconExt_GetCurFile
  391. };
  392. #pragma data_seg()