/////////////////////////////////////////////////////////////////////////////// /* File: extinit.cpp Description: Implements IShellExtInit for disk quota shell extensions. Revision History: Date Description Programmer -------- --------------------------------------------------- ---------- 08/15/96 Initial creation. BrianAu */ /////////////////////////////////////////////////////////////////////////////// #include "pch.h" // PCH #pragma hdrstop #include "extinit.h" #include "prshtext.h" #include "volprop.h" #include "guidsp.h" /////////////////////////////////////////////////////////////////////////////// /* Function: ShellExtInit::QueryInterface Description: Returns an interface pointer to the object's IUnknown or IShellExtInit interface. Only IID_IUnknown and IID_IShellExtInit are recognized. Arguments: riid - Reference to requested interface ID. ppvOut - Address of interface pointer variable to accept interface ptr. Returns: NO_ERROR - Success. E_NOINTERFACE - Requested interface not supported. E_INVALIDARG - ppvOut argument was NULL. Revision History: Date Description Programmer -------- --------------------------------------------------- ---------- 08/15/96 Initial creation. BrianAu 06/25/98 Disabled MMC snapin code. BrianAu */ /////////////////////////////////////////////////////////////////////////////// STDMETHODIMP ShellExtInit::QueryInterface( REFIID riid, LPVOID *ppvOut ) { HRESULT hResult = E_NOINTERFACE; if (NULL == ppvOut) return E_INVALIDARG; *ppvOut = NULL; try { if (IID_IUnknown == riid || IID_IShellExtInit == riid) { *ppvOut = this; ((LPUNKNOWN)*ppvOut)->AddRef(); hResult = NOERROR; } else if (IID_IShellPropSheetExt == riid) { // // This can throw OutOfMemory. // hResult = Create_IShellPropSheetExt(riid, ppvOut); } #ifdef POLICY_MMC_SNAPIN else if (IID_ISnapInPropSheetExt == riid) { hResult = Create_ISnapInPropSheetExt(riid, ppvOut); } #endif // POLICY_MMC_SNAPIN } catch(CAllocException& e) { hResult = E_OUTOFMEMORY; } return hResult; } /////////////////////////////////////////////////////////////////////////////// /* Function: ShellExtInit::AddRef Description: Increments object reference count. Arguments: None. Returns: New reference count value. Revision History: Date Description Programmer -------- --------------------------------------------------- ---------- 08/15/96 Initial creation. BrianAu */ /////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_(ULONG) ShellExtInit::AddRef( VOID ) { ULONG ulReturn = m_cRef + 1; DBGPRINT((DM_COM, DL_HIGH, TEXT("ShellExtInit::AddRef, 0x%08X %d -> %d\n"), this, ulReturn - 1, ulReturn)); InterlockedIncrement(&m_cRef); return ulReturn; } /////////////////////////////////////////////////////////////////////////////// /* Function: ShellExtInit::Release Description: Decrements object reference count. If count drops to 0, object is deleted. Arguments: None. Returns: New reference count value. Revision History: Date Description Programmer -------- --------------------------------------------------- ---------- 08/15/96 Initial creation. BrianAu */ /////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_(ULONG) ShellExtInit::Release( VOID ) { ULONG ulReturn = m_cRef - 1; DBGPRINT((DM_COM, DL_HIGH, TEXT("ShellExtInit::Release, 0x%08X %d -> %d\n"), this, ulReturn + 1, ulReturn)); if (InterlockedDecrement(&m_cRef) == 0) { delete this; ulReturn = 0; } return ulReturn; } /////////////////////////////////////////////////////////////////////////////// /* Function: ShellExtInit::Initialize Description: Called by the shell to initialize the shell extension. Arguments: pidlFolder - Pointer to IDL of selected folder. This NULL for property sheet and context menu extensions. lpDataObj - Pointer to data object containing list of selected objects. hkeyProgID - Registry key for the file object or folder type. Returns: S_OK - Success. E_FAIL - Can't initialize extension. Revision History: Date Description Programmer -------- --------------------------------------------------- ---------- 08/15/96 Initial creation. BrianAu 06/28/98 Added mounted-volume support. BrianAu Includes introduction of CVolumeID object. */ /////////////////////////////////////////////////////////////////////////////// STDMETHODIMP ShellExtInit::Initialize( LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpDataObj, HKEY hkeyProgID) { HRESULT hResult = E_FAIL; if (NULL != lpDataObj) { // // First assume it's a normal volume ID (i.e. "C:\"). // The DataObject will provide CF_HDROP if it is. // FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM medium; bool bMountedVol = false; hResult = lpDataObj->GetData(&fe, &medium); if (FAILED(hResult)) { // // Isn't a normal volume name. Maybe it's a mounted volume. // Mounted volume names come in on a different clipboard format // so we can treat them differently from normal volume // names like "C:\". A mounted volume name will be the path // to the folder hosting the mounted volume. // For mounted volumes, the DataObject provides CF "MountedVolume". // fe.cfFormat = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_MOUNTEDVOLUME); hResult = lpDataObj->GetData(&fe, &medium); bMountedVol = SUCCEEDED(hResult); } if (SUCCEEDED(hResult)) { if (1 == DragQueryFile((HDROP)medium.hGlobal, (DWORD)-1, NULL, 0)) { // // Retrieve volume ID string passed in from the shell. // CString strForParsing; // Used for calling Win32 functions. CString strForDisplay; // Used for UI display. CString strFSPath; // Used when an FS path is required. DragQueryFile((HDROP)medium.hGlobal, 0, strForParsing.GetBuffer(MAX_PATH), MAX_PATH); strForParsing.ReleaseBuffer(); if (!bMountedVol) { // // If it's a normal volume name like "C:\", just // use that as the display name and FS Path also. // strFSPath = strForDisplay = strForParsing; } else { // // It's a mounted volume so we need to come up with something // better than "\\?\Volume{ }\" to display. // // The UI spec says the name shall be like this: // //