Windows2003-3790/inetsrv/iis/admin/w3ext/propshellext.cpp
2020-09-30 16:53:55 +02:00

182 lines
5.0 KiB
C++

// PropShellExt.cpp : Implementation of CW3extApp and DLL registration.
#include "stdafx.h"
#include "w3ext.h"
#include "PropShellExt.h"
#include "StrFn.h"
/////////////////////////////////////////////////////////////////////////////
//
// IShellExtInit Implementation.
STDMETHODIMP
CPropShellExt::Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hKeyID)
{
if (pDataObj == NULL)
{
ATLASSERT(FALSE);
return (E_INVALIDARG);
}
FORMATETC f = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM m;
HRESULT hr = pDataObj->GetData(&f, &m);
if (FAILED(hr))
{
return(hr);
}
hr = E_FAIL;
if (1 == DragQueryFile((HDROP)m.hGlobal, (UINT)(-1), NULL,0))
{
TCHAR szFileName[MAX_PATH];
DragQueryFile((HDROP)m.hGlobal, 0, szFileName, sizeof(szFileName) / sizeof(TCHAR));
SHFILEINFO shfi;
SHGetFileInfo(szFileName, 0, &shfi, sizeof(SHFILEINFO), SHGFI_ATTRIBUTES);
if ( (shfi.dwAttributes & (SFGAO_LINK | SFGAO_REMOVABLE)) == 0
&& (shfi.dwAttributes & SFGAO_FILESYSTEM) != 0
)
{
int drive_number, drive_type;
TCHAR szRoot[4];
if ( -1 != (drive_number = PathGetDriveNumber(szFileName))
&& NULL != PathBuildRoot(szRoot, drive_number)
&& DRIVE_REMOTE != (drive_type = GetDriveType(szRoot))
&& DRIVE_NO_ROOT_DIR != drive_type
)
{
StrCpy(m_szFileName, szFileName);
hr = S_OK;
}
}
}
ReleaseStgMedium(&m);
return hr;
}
STDMETHODIMP
CPropShellExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
{
// We only add the page if the user has admin priviliges in the metabase.
// The only way to check it now is to try to write something.
// Test key is /LM/W3SVC.
CMetabasePath path(SZ_MBN_WEB);
CMetaKey key(LOCAL_KEY, path,
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE
);
if (key.Succeeded() && SUCCEEDED(key.SetValue(MD_ISM_ACCESS_CHECK, 0x0000FFFF)))
{
m_psW3ShellExtProp.SetParentExt(this);
HPROPSHEETPAGE hpage = m_psW3ShellExtProp.Create();
ASSERT(hpage != NULL);
if (NULL != hpage)
{
AddRef();
if (!lpfnAddPage(hpage, lParam))
{
DestroyPropertySheetPage(hpage);
}
}
}
return key.QueryResult();
}
STDMETHODIMP
CPropShellExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplaceWith, LPARAM lParam)
{
return E_FAIL;
}
BOOL
RecursiveCheckVRoots(CMetaEnumerator& en, LPCTSTR meta_path, LPCTSTR folder_path)
{
BOOL shared = FALSE;
CString vrpath, csPathMunged;
BOOL bInheritOverride = FALSE;
if (SUCCEEDED(en.QueryValue(MD_VR_PATH, vrpath, &bInheritOverride, meta_path)))
{
// vrpath could be a "special" path
// like \\?\c:\temp\mydir
// we need to munge it before compareing it.
GetSpecialPathRealPath(vrpath,csPathMunged);
if (csPathMunged.CompareNoCase(folder_path) == 0)
{
return TRUE;
}
}
CString vdir;
while (SUCCEEDED(en.Next(vdir, meta_path)) && !shared)
{
CString next_vdir;
if (meta_path != NULL)
next_vdir += meta_path;
next_vdir += vdir;
next_vdir += SZ_MBN_SEP_STR;
en.Push();
en.Reset();
shared = RecursiveCheckVRoots(en, next_vdir, folder_path);
en.Pop();
}
return shared;
}
BOOL IsFolderShared(LPCTSTR path)
{
BOOL shared = FALSE;
CMetaEnumerator en(LOCAL_KEY, CMetabasePath(SZ_MBN_WEB));
if (en.Succeeded())
{
DWORD di;
int i = -1;
CString inst;
HRESULT hr = S_OK;
while (SUCCEEDED(hr) && !shared)
{
if (SUCCEEDED(hr = en.Next(di, inst)))
{
CMetabasePath meta_path(TRUE, SZ_MBN_WEB, inst, SZ_MBN_ROOT);
CMetaEnumerator en(LOCAL_KEY, meta_path);
ASSERT(en.Succeeded());
if (en.Succeeded())
{
shared = RecursiveCheckVRoots(en, NULL, path);
}
}
}
}
return shared;
}
UINT
CPropShellExt::CopyCallback(
HWND hwnd,
UINT wFunc,
UINT wFlags,
LPCTSTR pszSrcFile,
DWORD dwSrcAttribs,
LPCTSTR pszDestFile,
DWORD dwDestAttribs
)
{
UINT rc = IDYES;
if ((dwSrcAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0)
{
switch (wFunc)
{
case FO_DELETE:
case FO_MOVE:
case FO_RENAME:
if (IsFolderShared(pszSrcFile))
{
CString cap, msg;
cap.LoadString(_Module.GetResourceInstance(), IDS_PAGE_TITLE);
msg.Format(_Module.GetResourceInstance(), IDS_CONFIRM_OPERATION, pszSrcFile);
rc = MessageBox(hwnd, msg, cap, MB_YESNOCANCEL|MB_ICONQUESTION);
}
break;
}
}
return rc;
}