Source code of Windows XP (NT5)
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.

484 lines
8.9 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. faxshell.cpp
  5. Abstract:
  6. fax tiff data column provider
  7. Author:
  8. Andrew Ritz (andrewr) 2-27-98
  9. Environment:
  10. user-mode
  11. Notes:
  12. Revision History:
  13. 2-27-98 (andrewr) Created.
  14. 8-06-99 (steveke) Major rewrite -> changed from shell extension to column provider
  15. --*/
  16. #include <windows.h>
  17. #include <shlobj.h>
  18. #include <shlwapi.h>
  19. #include <shlwapip.h>
  20. #include <faxcom.h>
  21. #include <faxcom_i.c>
  22. #include <initguid.h>
  23. #include "faxutil.h"
  24. #include "resource.h"
  25. #include "faxshell.h"
  26. extern "C" int APIENTRY
  27. DllMain(
  28. HINSTANCE hInstance,
  29. DWORD dwReason,
  30. LPVOID pContext
  31. )
  32. /*++
  33. Routine Description:
  34. DLL entry point
  35. Arguments:
  36. hInstance - handle to the module
  37. dwReason - indicates the reason for being called
  38. pContext - pointer to the context
  39. Return Value:
  40. TRUE on success
  41. --*/
  42. {
  43. if (dwReason == DLL_PROCESS_ATTACH) {
  44. g_hInstance = hInstance;
  45. }
  46. return TRUE;
  47. }
  48. STDAPI
  49. DllGetClassObject(
  50. REFCLSID rclsid,
  51. REFIID riid,
  52. LPVOID *ppvOut
  53. )
  54. /*++
  55. Routine Description:
  56. Retrieves the class object
  57. Arguments:
  58. rclsid - clsid for the class object
  59. riid - reference to the identifier of the interface
  60. ppvOut - interface pointer of the requested identifier
  61. Return Value:
  62. S_OK on success
  63. --*/
  64. {
  65. if (ppvOut == NULL) {
  66. return E_INVALIDARG;
  67. }
  68. *ppvOut = NULL;
  69. // Verify the class id is CLSID_FaxShellExtension
  70. if (IsEqualCLSID(rclsid, CLSID_FaxShellExtension) == FALSE)
  71. {
  72. return CLASS_E_CLASSNOTAVAILABLE;
  73. }
  74. // Instantiate a class factory object
  75. CClassFactory *pClassFactory = new CClassFactory();
  76. if (pClassFactory == NULL)
  77. {
  78. return E_OUTOFMEMORY;
  79. }
  80. // Get the interface pointer from QueryInterface and copy it to *ppvOut
  81. HRESULT hr = pClassFactory->QueryInterface(riid, ppvOut);
  82. pClassFactory->Release();
  83. return hr;
  84. }
  85. STDAPI
  86. DllCanUnloadNow(
  87. VOID
  88. )
  89. /*++
  90. Routine Description:
  91. Determines whether the the Dll is in use.
  92. Arguments:
  93. None
  94. Return Value:
  95. S_OK if the Dll can be unloaded, S_FALSE if the Dll cannot be unloaded
  96. --*/
  97. {
  98. return (InterlockedCompareExchange(&cLockCount, 0, 0) == 0) ? S_OK : S_FALSE;
  99. }
  100. STDMETHODIMP
  101. CClassFactory::CreateInstance(
  102. LPUNKNOWN pUnknown,
  103. REFIID riid,
  104. LPVOID FAR *ppvOut
  105. )
  106. /*++
  107. Routine Description:
  108. Creates an uninitialized object
  109. Arguments:
  110. pUnknown - pointer to controlling IUnknown
  111. riid - reference to the identifier of the interface
  112. ppvOut - interface pointer of the requested identifier
  113. Return Value:
  114. S_OK on success
  115. --*/
  116. {
  117. if (ppvOut == NULL)
  118. {
  119. return E_INVALIDARG;
  120. }
  121. *ppvOut = NULL;
  122. if (pUnknown != NULL)
  123. {
  124. return CLASS_E_NOAGGREGATION;
  125. }
  126. // Instantiate a fax column provider object
  127. CFaxColumnProvider *pFaxColumnProvider = new CFaxColumnProvider();
  128. if (pFaxColumnProvider == NULL)
  129. {
  130. return E_OUTOFMEMORY;
  131. }
  132. // Get the interface pointer from QueryInterface and copy it to *ppvOut
  133. HRESULT hr = pFaxColumnProvider->QueryInterface(riid, ppvOut);
  134. pFaxColumnProvider->Release();
  135. return hr;
  136. }
  137. STDMETHODIMP
  138. CFaxColumnProvider::GetColumnInfo(
  139. DWORD dwIndex,
  140. SHCOLUMNINFO *psci
  141. )
  142. /*++
  143. Routine Description:
  144. Provides information about a column
  145. Arguments:
  146. dwIndex - column's zero based index
  147. psci - pointer to an SHCOLUMNINFO structure to hold the column information
  148. Return Value:
  149. S_OK on success
  150. --*/
  151. {
  152. ZeroMemory(psci, sizeof(SHCOLUMNINFO));
  153. if (dwIndex < ColumnTableCount)
  154. {
  155. WCHAR szColumnName[MAX_COLUMN_NAME_LEN];
  156. // Load the column name
  157. LoadString(g_hInstance, ColumnTable[dwIndex].dwId, szColumnName, ColumnTable[dwIndex].dwSize);
  158. lstrcpy(psci->wszTitle, szColumnName);
  159. lstrcpy(psci->wszDescription, szColumnName);
  160. psci->scid = *ColumnTable[dwIndex].pscid;
  161. psci->cChars = lstrlen(szColumnName) + 1;
  162. psci->vt = ColumnTable[dwIndex].vt;
  163. psci->fmt = LVCFMT_LEFT;
  164. psci->csFlags = SHCOLSTATE_TYPE_STR;
  165. return S_OK;
  166. }
  167. return S_FALSE;
  168. }
  169. STDMETHODIMP
  170. CFaxColumnProvider::GetItemData(
  171. LPCSHCOLUMNID pscid,
  172. LPCSHCOLUMNDATA pscd,
  173. VARIANT *pvarData
  174. )
  175. /*++
  176. Routine Description:
  177. Provides column data for a specified file
  178. Arguments:
  179. pscid - SHCOLUMNID structure that identifies the column
  180. pscd - SHCOLUMNDATA structure that specifies the file
  181. pvarData - pointer to a VARIANT with the data for the file
  182. Return Value:
  183. S_OK if file data is returned, S_FALSE if the file is not supported by the column provider and no data is returned
  184. --*/
  185. {
  186. // hr is the result of an object method
  187. HRESULT hr = S_FALSE;
  188. // FaxData is the fax tiff data
  189. BSTR FaxData = NULL;
  190. // Check if file is a directory, which is not supported
  191. if ((pscd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == TRUE)
  192. {
  193. return S_FALSE;
  194. }
  195. // Check if file is supported, i.e. pscd->pwszExt == L".tif"
  196. if (lstrcmpi(pscd->pwszExt, L".tif") != 0)
  197. {
  198. return S_FALSE;
  199. }
  200. // Check if the IFaxTiff object exists
  201. if (m_IFaxTiff == NULL)
  202. {
  203. // Create the IFaxTiff object
  204. hr = CoCreateInstance(CLSID_FaxTiff, NULL, CLSCTX_INPROC_SERVER, IID_IFaxTiff, (LPVOID *) &m_IFaxTiff);
  205. if (FAILED(hr) == TRUE)
  206. {
  207. return hr;
  208. }
  209. }
  210. // Set the full path and file name of the fax tiff
  211. hr = m_IFaxTiff->put_Image((LPWSTR) pscd->wszFile);
  212. if (FAILED(hr) == TRUE)
  213. {
  214. return hr;
  215. }
  216. // Retrieve the fax tiff data
  217. switch (pscid->pid)
  218. {
  219. case PID_SENDERNAME:
  220. hr = m_IFaxTiff->get_SenderName(&FaxData);
  221. break;
  222. case PID_RECIPIENTNAME:
  223. hr = m_IFaxTiff->get_RecipientName(&FaxData);
  224. break;
  225. case PID_RECIPIENTNUMBER:
  226. hr = m_IFaxTiff->get_RecipientNumber(&FaxData);
  227. break;
  228. case PID_CSID:
  229. hr = m_IFaxTiff->get_Csid(&FaxData);
  230. break;
  231. case PID_TSID:
  232. hr = m_IFaxTiff->get_Tsid(&FaxData);
  233. break;
  234. case PID_RECEIVETIME:
  235. hr = m_IFaxTiff->get_ReceiveTime(&FaxData);
  236. break;
  237. case PID_CALLERID:
  238. hr = m_IFaxTiff->get_CallerId(&FaxData);
  239. break;
  240. case PID_ROUTING:
  241. hr = m_IFaxTiff->get_Routing(&FaxData);
  242. break;
  243. default:
  244. hr = S_FALSE;
  245. }
  246. if (FAILED(hr) == TRUE)
  247. {
  248. goto e0;
  249. }
  250. // Set the column data
  251. pvarData->vt = VT_BSTR;
  252. pvarData->bstrVal = SysAllocString(FaxData);
  253. SysFreeString(FaxData);
  254. if (pvarData->bstrVal == NULL)
  255. {
  256. hr = E_OUTOFMEMORY;
  257. goto e0;
  258. }
  259. hr = S_OK;
  260. e0:
  261. // Close the file
  262. m_IFaxTiff->put_Image(L"");
  263. return hr;
  264. }
  265. STDAPI
  266. DllRegisterServer(
  267. VOID
  268. )
  269. /*++
  270. Routine Description:
  271. Function for the in-process server to create its registry entries
  272. Return Value:
  273. S_OK on success
  274. --*/
  275. {
  276. // hKey is a handle to the registry key
  277. HKEY hKey;
  278. // szKeyName is the name of a registry key
  279. WCHAR szKeyName[MAX_PATH];
  280. // Register the COM object
  281. wsprintf(szKeyName, L"%s\\%s", REGKEY_CLASSES_CLSID, REGKEY_FAXSHELL_CLSID);
  282. hKey = OpenRegistryKey(HKEY_CLASSES_ROOT, szKeyName, TRUE, NULL);
  283. if (hKey == NULL)
  284. {
  285. return E_FAIL;
  286. }
  287. SetRegistryString(hKey, NULL, REGVAL_FAXSHELL_TEXT);
  288. RegCloseKey(hKey);
  289. wsprintf(szKeyName, L"%s\\%s\\%s", REGKEY_CLASSES_CLSID, REGKEY_FAXSHELL_CLSID, REGKEY_INPROC);
  290. hKey = OpenRegistryKey(HKEY_CLASSES_ROOT, szKeyName, TRUE, NULL);
  291. if (hKey == NULL)
  292. {
  293. return E_FAIL;
  294. }
  295. SetRegistryString(hKey, REGVAL_THREADING, REGVAL_APARTMENT);
  296. SetRegistryStringExpand(hKey, NULL, REGVAL_LOCATION);
  297. RegCloseKey(hKey);
  298. // Register the column provider
  299. wsprintf(szKeyName, L"%s\\%s", REGKEY_COLUMNHANDLERS, REGKEY_FAXSHELL_CLSID);
  300. hKey = OpenRegistryKey(HKEY_CLASSES_ROOT, szKeyName, TRUE, NULL);
  301. if (hKey == NULL)
  302. {
  303. return E_FAIL;
  304. }
  305. SetRegistryString(hKey, NULL, REGVAL_FAXSHELL_TEXT);
  306. RegCloseKey(hKey);
  307. return S_OK;
  308. }
  309. STDAPI
  310. DllUnregisterServer(
  311. VOID
  312. )
  313. /*++
  314. Routine Description:
  315. Function for the in-process server to remove its registry entries
  316. Return Value:
  317. S_OK on success
  318. --*/
  319. {
  320. // szKeyName is the name of a registry key
  321. WCHAR szKeyName[MAX_PATH];
  322. // Unregister the COM object
  323. wsprintf(szKeyName, L"%s\\%s", REGKEY_CLASSES_CLSID, REGKEY_FAXSHELL_CLSID);
  324. if (DeleteRegistryKey(HKEY_CLASSES_ROOT, szKeyName) == FALSE)
  325. {
  326. return E_FAIL;
  327. }
  328. // Unregister the column provider
  329. wsprintf(szKeyName, L"%s\\%s", REGKEY_COLUMNHANDLERS, REGKEY_FAXSHELL_CLSID);
  330. if (DeleteRegistryKey(HKEY_CLASSES_ROOT, szKeyName) == FALSE)
  331. {
  332. return E_FAIL;
  333. }
  334. return S_OK;
  335. }