/*++ Copyright (c) 1998 Microsoft Corporation Module Name: faxshell.cpp Abstract: fax tiff data column provider Author: Andrew Ritz (andrewr) 2-27-98 Environment: user-mode Notes: Revision History: 2-27-98 (andrewr) Created. 8-06-99 (steveke) Major rewrite -> changed from shell extension to column provider --*/ #include #include #include #include #include #include #include #include "faxutil.h" #include "resource.h" #include "faxshell.h" extern "C" int APIENTRY DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID pContext ) /*++ Routine Description: DLL entry point Arguments: hInstance - handle to the module dwReason - indicates the reason for being called pContext - pointer to the context Return Value: TRUE on success --*/ { if (dwReason == DLL_PROCESS_ATTACH) { g_hInstance = hInstance; } return TRUE; } STDAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID *ppvOut ) /*++ Routine Description: Retrieves the class object Arguments: rclsid - clsid for the class object riid - reference to the identifier of the interface ppvOut - interface pointer of the requested identifier Return Value: S_OK on success --*/ { if (ppvOut == NULL) { return E_INVALIDARG; } *ppvOut = NULL; // Verify the class id is CLSID_FaxShellExtension if (IsEqualCLSID(rclsid, CLSID_FaxShellExtension) == FALSE) { return CLASS_E_CLASSNOTAVAILABLE; } // Instantiate a class factory object CClassFactory *pClassFactory = new CClassFactory(); if (pClassFactory == NULL) { return E_OUTOFMEMORY; } // Get the interface pointer from QueryInterface and copy it to *ppvOut HRESULT hr = pClassFactory->QueryInterface(riid, ppvOut); pClassFactory->Release(); return hr; } STDAPI DllCanUnloadNow( VOID ) /*++ Routine Description: Determines whether the the Dll is in use. Arguments: None Return Value: S_OK if the Dll can be unloaded, S_FALSE if the Dll cannot be unloaded --*/ { return (InterlockedCompareExchange(&cLockCount, 0, 0) == 0) ? S_OK : S_FALSE; } STDMETHODIMP CClassFactory::CreateInstance( LPUNKNOWN pUnknown, REFIID riid, LPVOID FAR *ppvOut ) /*++ Routine Description: Creates an uninitialized object Arguments: pUnknown - pointer to controlling IUnknown riid - reference to the identifier of the interface ppvOut - interface pointer of the requested identifier Return Value: S_OK on success --*/ { if (ppvOut == NULL) { return E_INVALIDARG; } *ppvOut = NULL; if (pUnknown != NULL) { return CLASS_E_NOAGGREGATION; } // Instantiate a fax column provider object CFaxColumnProvider *pFaxColumnProvider = new CFaxColumnProvider(); if (pFaxColumnProvider == NULL) { return E_OUTOFMEMORY; } // Get the interface pointer from QueryInterface and copy it to *ppvOut HRESULT hr = pFaxColumnProvider->QueryInterface(riid, ppvOut); pFaxColumnProvider->Release(); return hr; } STDMETHODIMP CFaxColumnProvider::GetColumnInfo( DWORD dwIndex, SHCOLUMNINFO *psci ) /*++ Routine Description: Provides information about a column Arguments: dwIndex - column's zero based index psci - pointer to an SHCOLUMNINFO structure to hold the column information Return Value: S_OK on success --*/ { ZeroMemory(psci, sizeof(SHCOLUMNINFO)); if (dwIndex < ColumnTableCount) { WCHAR szColumnName[MAX_COLUMN_NAME_LEN]; // Load the column name LoadString(g_hInstance, ColumnTable[dwIndex].dwId, szColumnName, ColumnTable[dwIndex].dwSize); lstrcpy(psci->wszTitle, szColumnName); lstrcpy(psci->wszDescription, szColumnName); psci->scid = *ColumnTable[dwIndex].pscid; psci->cChars = lstrlen(szColumnName) + 1; psci->vt = ColumnTable[dwIndex].vt; psci->fmt = LVCFMT_LEFT; psci->csFlags = SHCOLSTATE_TYPE_STR; return S_OK; } return S_FALSE; } STDMETHODIMP CFaxColumnProvider::GetItemData( LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, VARIANT *pvarData ) /*++ Routine Description: Provides column data for a specified file Arguments: pscid - SHCOLUMNID structure that identifies the column pscd - SHCOLUMNDATA structure that specifies the file pvarData - pointer to a VARIANT with the data for the file Return Value: S_OK if file data is returned, S_FALSE if the file is not supported by the column provider and no data is returned --*/ { // hr is the result of an object method HRESULT hr = S_FALSE; // FaxData is the fax tiff data BSTR FaxData = NULL; // Check if file is a directory, which is not supported if ((pscd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == TRUE) { return S_FALSE; } // Check if file is supported, i.e. pscd->pwszExt == L".tif" if (lstrcmpi(pscd->pwszExt, L".tif") != 0) { return S_FALSE; } // Check if the IFaxTiff object exists if (m_IFaxTiff == NULL) { // Create the IFaxTiff object hr = CoCreateInstance(CLSID_FaxTiff, NULL, CLSCTX_INPROC_SERVER, IID_IFaxTiff, (LPVOID *) &m_IFaxTiff); if (FAILED(hr) == TRUE) { return hr; } } // Set the full path and file name of the fax tiff hr = m_IFaxTiff->put_Image((LPWSTR) pscd->wszFile); if (FAILED(hr) == TRUE) { return hr; } // Retrieve the fax tiff data switch (pscid->pid) { case PID_SENDERNAME: hr = m_IFaxTiff->get_SenderName(&FaxData); break; case PID_RECIPIENTNAME: hr = m_IFaxTiff->get_RecipientName(&FaxData); break; case PID_RECIPIENTNUMBER: hr = m_IFaxTiff->get_RecipientNumber(&FaxData); break; case PID_CSID: hr = m_IFaxTiff->get_Csid(&FaxData); break; case PID_TSID: hr = m_IFaxTiff->get_Tsid(&FaxData); break; case PID_RECEIVETIME: hr = m_IFaxTiff->get_ReceiveTime(&FaxData); break; case PID_CALLERID: hr = m_IFaxTiff->get_CallerId(&FaxData); break; case PID_ROUTING: hr = m_IFaxTiff->get_Routing(&FaxData); break; default: hr = S_FALSE; } if (FAILED(hr) == TRUE) { goto e0; } // Set the column data pvarData->vt = VT_BSTR; pvarData->bstrVal = SysAllocString(FaxData); SysFreeString(FaxData); if (pvarData->bstrVal == NULL) { hr = E_OUTOFMEMORY; goto e0; } hr = S_OK; e0: // Close the file m_IFaxTiff->put_Image(L""); return hr; } STDAPI DllRegisterServer( VOID ) /*++ Routine Description: Function for the in-process server to create its registry entries Return Value: S_OK on success --*/ { // hKey is a handle to the registry key HKEY hKey; // szKeyName is the name of a registry key WCHAR szKeyName[MAX_PATH]; // Register the COM object wsprintf(szKeyName, L"%s\\%s", REGKEY_CLASSES_CLSID, REGKEY_FAXSHELL_CLSID); hKey = OpenRegistryKey(HKEY_CLASSES_ROOT, szKeyName, TRUE, NULL); if (hKey == NULL) { return E_FAIL; } SetRegistryString(hKey, NULL, REGVAL_FAXSHELL_TEXT); RegCloseKey(hKey); wsprintf(szKeyName, L"%s\\%s\\%s", REGKEY_CLASSES_CLSID, REGKEY_FAXSHELL_CLSID, REGKEY_INPROC); hKey = OpenRegistryKey(HKEY_CLASSES_ROOT, szKeyName, TRUE, NULL); if (hKey == NULL) { return E_FAIL; } SetRegistryString(hKey, REGVAL_THREADING, REGVAL_APARTMENT); SetRegistryStringExpand(hKey, NULL, REGVAL_LOCATION); RegCloseKey(hKey); // Register the column provider wsprintf(szKeyName, L"%s\\%s", REGKEY_COLUMNHANDLERS, REGKEY_FAXSHELL_CLSID); hKey = OpenRegistryKey(HKEY_CLASSES_ROOT, szKeyName, TRUE, NULL); if (hKey == NULL) { return E_FAIL; } SetRegistryString(hKey, NULL, REGVAL_FAXSHELL_TEXT); RegCloseKey(hKey); return S_OK; } STDAPI DllUnregisterServer( VOID ) /*++ Routine Description: Function for the in-process server to remove its registry entries Return Value: S_OK on success --*/ { // szKeyName is the name of a registry key WCHAR szKeyName[MAX_PATH]; // Unregister the COM object wsprintf(szKeyName, L"%s\\%s", REGKEY_CLASSES_CLSID, REGKEY_FAXSHELL_CLSID); if (DeleteRegistryKey(HKEY_CLASSES_ROOT, szKeyName) == FALSE) { return E_FAIL; } // Unregister the column provider wsprintf(szKeyName, L"%s\\%s", REGKEY_COLUMNHANDLERS, REGKEY_FAXSHELL_CLSID); if (DeleteRegistryKey(HKEY_CLASSES_ROOT, szKeyName) == FALSE) { return E_FAIL; } return S_OK; }