Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

746 lines
20 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995
//
// File: ofsfldr.cpp
//
// Contents: Implements most of COFSFolder class
//
// History: 6-26-95 Davepl,JonBe Created
//
//--------------------------------------------------------------------------
#include "precomp.h"
#include <iofs.h>
#include <dsys.h>
//+-------------------------------------------------------------------------
//
// COFSFolder Constructor
//
//--------------------------------------------------------------------------
COFSFolder::COFSFolder()
{
m_cRef = 1L;
m_pidl = NULL;
m_fIsDSFolder = FALSE;
m_fCachedCLSID = FALSE;
m_fHasCLSID = FALSE;
}
//+-------------------------------------------------------------------------
//
// COFSFolder Destructor
//
//--------------------------------------------------------------------------
COFSFolder::~COFSFolder()
{
if (m_pidl)
{
SHFree(m_pidl);
}
}
//+-------------------------------------------------------------------------
//
// COFSFolder::QueryInterface
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
HRESULT hr = S_OK;
*ppv = NULL;
if (IsEqualIID(riid, IID_IShellFolder))
{
*ppv = (LPSHELLFOLDER) this;
}
else if (IsEqualIID(riid, IID_IUnknown))
{
*ppv = (LPUNKNOWN) (LPSHELLFOLDER) this;
}
else if (IsEqualIID(riid, IID_IPersistFolder))
{
*ppv = (LPPERSISTFOLDER) this;
}
else if (IsEqualIID(riid, IID_IShellIcon))
{
*ppv = (LPSHELLICON) this;
}
if (*ppv)
{
AddRef();
hr = NOERROR;
}
else
{
hr = E_NOINTERFACE;
}
return hr;
}
//+-------------------------------------------------------------------------
//
// COFSFolder RefCounting
//
//--------------------------------------------------------------------------
STDMETHODIMP_(ULONG) COFSFolder::AddRef()
{
InterlockedIncrement((LONG *)&m_cRef);
return m_cRef;
}
STDMETHODIMP_(ULONG) COFSFolder::Release()
{
if (0 != InterlockedDecrement((LONG *)&m_cRef))
{
return m_cRef;
}
delete this;
return 0L;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::InitializeFromIDList
//
// Synopsis: Initializes this COFSFolder object based on the pidl passed
// in, and returns an IShellFolder ptr on the OUT ptr.
//
// History: 6-26-95 davepl Created
//
// Notes: Currently, we create an FSFolder object to delegate
// everything to
//
//--------------------------------------------------------------------------
HRESULT COFSFolder::InitializeFromIDList(const CIDList * pidl,
REFIID riid,
LPVOID * ppvOut)
{
HRESULT hr;
m_wSpecialFID = CSIDL_NOTCACHED;
//
// Make a copy of the pidl, then QI for the interface.
//
hr = pidl->CloneTo(&m_pidl);
if (SUCCEEDED(hr))
{
hr = QueryInterface(riid, ppvOut);
}
Release();
m_fIsDSFolder = IsDSFolder((LPCITEMIDLIST) m_pidl);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::ParseDisplayName
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::ParseDisplayName(HWND hwnd,
LPBC pbcReserved,
LPOLESTR lpszDisplayName,
ULONG * pchEaten,
LPITEMIDLIST * ppidl,
ULONG * pdwAttributes)
{
HRESULT hr;
hr = CFSFolder_ParseDisplayName( (LPSHELLFOLDER) this,
hwnd,
pbcReserved,
lpszDisplayName,
pchEaten,
ppidl,
pdwAttributes);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::EnumObjects
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::EnumObjects(HWND hwndOwner,
DWORD grfFlags,
LPENUMIDLIST * ppenumIDList)
{
HRESULT hr;
TCHAR szFolder[MAX_PATH];
CEnumOLEDB * pEnumOLEDB = new CEnumOLEDB;
if (NULL == pEnumOLEDB)
{
return E_OUTOFMEMORY;
}
hr = pEnumOLEDB->InitInstance();
if (FAILED(hr))
{
delete pEnumOLEDB;
return hr;
}
if (FALSE == SHGetPathFromIDList((LPITEMIDLIST) m_pidl, szFolder))
{
//
// NOTES: We assume SHGetpathFromIDList fails only bacause
// the path is too long in this context. If not, we should
// change SHGetPathFromIDList so that it returns HRESULT
// instead of BOOL.
//
if (hwndOwner)
{
(void) ShellMessageBox(HINST_THISDLL, hwndOwner,
MAKEINTRESOURCE(IDS_ENUMERR_PATHTOOLONG),
NULL, // get the title from hwndOwner
MB_OK | MB_ICONHAND);
}
delete pEnumOLEDB;
hr = E_INVALIDARG;
return hr;
}
hr = SynchronousQuery(szFolder, grfFlags, pEnumOLEDB);
//
// If successful, set the out pointer. If anything failed along the way,
// release the enumerator BUGBUG Release vs. delete?
//
if (SUCCEEDED(hr))
{
*ppenumIDList = pEnumOLEDB;
// Lie to DefView_FillObjects, which will only call your enumerator
// if you return exactly S_OK (and no other success HRESULTs)
// (JonBe, 8/11/95)
hr = S_OK;
}
else
{
delete pEnumOLEDB;
}
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::BindToObject
//
// Synopsis:
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::BindToObject(LPCITEMIDLIST pidl,
LPBC pbcReserved,
REFIID riid,
LPVOID * ppvOut)
{
HRESULT hr;
hr = CFSFolder_BindToObject( (LPSHELLFOLDER) this, pidl, pbcReserved, riid, ppvOut);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::BindToStorage
//
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::BindToStorage(LPCITEMIDLIST pidl,
LPBC pbcReserved,
REFIID riid,
LPVOID * ppvObj)
{
HRESULT hr;
hr = CFSFolder_BindToObject( (LPSHELLFOLDER) this, pidl, pbcReserved, riid, ppvObj);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::CompareIDs
//
// Synopsis:
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::CompareIDs(LPARAM lParam,
LPCITEMIDLIST pidl1,
LPCITEMIDLIST pidl2)
{
HRESULT hr;
hr = CFSFolder_CompareIDs( (LPSHELLFOLDER) this, lParam, pidl1, pidl2);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::CreateViewObject
//
// Synopsis:
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
// BUGBUG This string is also defined in fstreex.c There should be one
// common def'n
TCHAR const c_szCLSIDView[] = TEXT("UICLSID");
STDMETHODIMP COFSFolder::CreateViewObject(HWND hwnd,
REFIID riid,
LPVOID * ppvOut)
{
HRESULT hr;
if (IsEqualIID(riid, IID_IShellView) || IsEqualIID(riid, IID_IDropTarget))
{
if (FALSE == m_fCachedCLSID)
{
LPIDFOLDER pidf = (LPIDFOLDER) (m_pidl->FindLastID());
if (pidf && (pidf->fs.wAttrs & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
{
TCHAR szPath[MAX_PATH];
if (FALSE == SHGetPathFromIDList((LPITEMIDLIST) m_pidl, szPath))
{
return E_FAIL;
}
m_fHasCLSID = _GetFolderCLSID(szPath, NULL, &m_clsidView, c_szCLSIDView);
}
m_fCachedCLSID = TRUE;
}
//
// Use the view handler if it exists.
//
if (m_fHasCLSID)
{
LPPERSISTFOLDER ppf;
HRESULT hres = SHCoCreateInstance(NULL, &m_clsidView, NULL, IID_IPersistFolder, (LPVOID *) &ppf);
if (SUCCEEDED(hres))
{
hres = ppf->Initialize((LPITEMIDLIST) m_pidl);
if (SUCCEEDED(hres))
{
hres = ppf->QueryInterface(riid, ppvOut);
}
ppf->Release();
}
if (SUCCEEDED(hres))
{
return hres;
}
}
if (IsEqualIID(riid, IID_IDropTarget))
{
if (this->m_fIsDSFolder)
{
hr = CDS_IDLDropTarget_CreateFromPidl(hwnd,
(LPITEMIDLIST) m_pidl,
(LPDROPTARGET *)ppvOut);
}
else
{
hr = CIDLDropTarget_CreateFromPidl(hwnd,
(LPITEMIDLIST) m_pidl,
(LPDROPTARGET *)ppvOut);
}
}
else
{
CSFV csfv = {
SIZEOF(CSFV), // cbSize
(LPSHELLFOLDER) this, // pshf
NULL, // psvOuter
(LPITEMIDLIST) m_pidl, // pidl
SHCNE_DISKEVENTS |
SHCNE_ASSOCCHANGED |
SHCNE_NETSHARE |
SHCNE_NETUNSHARE,
FS_FNVCallBack, // pfnCallback
(FOLDERVIEWMODE) 0, // BUGBUG add 0 to enumeration
};
LPSHELLBROWSER psb = FileCabinet_GetIShellBrowser(hwnd);
HWND hwndTree;
//
// If in explorer mode, we want to register for freespace changes too
//
psb->GetControlWindow(FCW_TREE, &hwndTree);
if (hwndTree)
{
csfv.lEvents |= SHCNE_FREESPACE;
}
return SHCreateShellFolderViewEx(&csfv, (LPSHELLVIEW *)ppvOut);
}
}
else if (IsEqualIID(riid, IID_IContextMenu))
{
//
// Do background menu.
//
hr = CDefFolderMenu_Create((LPITEMIDLIST) m_pidl,
hwnd,
0,
NULL,
(LPSHELLFOLDER) this,
CFSFolder_DFMCallBackBG,
NULL,
NULL,
(LPCONTEXTMENU *) ppvOut);
}
else
{
hr = E_NOINTERFACE;
}
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::GetAttributesOf
//
// Synopsis: Returns attributers of a set of items
//
// Arguments: [cidl] -- count of items in the ID List
// [apidl] -- the IDList of items to get attrigutes for
// [rgfInOut] -- flags to be evaluated
//
// Returns: HRESULT
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::GetAttributesOf (UINT cidl,
LPCITEMIDLIST * apidl,
ULONG * prgfInOut)
{
HRESULT hr;
hr = CFSFolder_GetAttributesOf( (LPSHELLFOLDER) this, cidl, apidl, prgfInOut);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::GetUIObjectOf
//
// Synopsis:
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::GetUIObjectOf(HWND hwnd,
UINT cidl,
LPCITEMIDLIST * apidl,
REFIID riid,
UINT * prgfInOut,
LPVOID * ppvOut)
{
HRESULT hr;
hr = CFSFolder_GetUIObjectOf( (LPSHELLFOLDER) this, hwnd, cidl, apidl, riid, prgfInOut, ppvOut);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::GetDisplayNameOf
//
// Synopsis:
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::GetDisplayNameOf(LPCITEMIDLIST pidl,
DWORD uFlags,
LPSTRRET lpName)
{
HRESULT hr;
hr = CFSFolder_GetDisplayNameOf( (LPSHELLFOLDER) this, pidl, uFlags, lpName);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::SetNameOf
//
// Synopsis:
//
// History: 6-26-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::SetNameOf (HWND hwnd,
LPCITEMIDLIST pidl,
LPCOLESTR lpszName,
DWORD uFlags,
LPITEMIDLIST * ppidlOut)
{
HRESULT hr;
hr = CFSFolder_SetNameOf( (LPSHELLFOLDER) this, hwnd, pidl, lpszName, uFlags, ppidlOut);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::GetClassID [IPersist]
//
// Synopsis:
//
// History: 6-28-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::GetClassID(LPCLSID lpClassID)
{
HRESULT hr;
hr = CFSFolder_PF_GetClassID( (LPPERSISTFOLDER) this, lpClassID);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::Initialize [IPersistFolder]
//
// Synopsis:
//
// History: 6-28-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::Initialize(LPCITEMIDLIST pidl)
{
HRESULT hr;
hr = CFSFolder_PF_Initialize( (LPPERSISTFOLDER) this, pidl);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::GetIconOf [IShellIcon]
//
// Synopsis:
//
// History: 6-28-95 davepl Created
//
// Notes:
//
//--------------------------------------------------------------------------
STDMETHODIMP COFSFolder::GetIconOf(LPCITEMIDLIST pidl, UINT flags, LPINT lpIconIndex)
{
HRESULT hr;
hr = CFSFolder_Icon_GetIconOf( (LPSHELLICON) this, pidl, flags, lpIconIndex);
return hr;
}
//+-------------------------------------------------------------------------
//
// Member: COFSFolder::IsDSFolder [private helper member]
//
// Synopsis:
//
// History: 9 19 95 jimharr created
//
// Notes:
//
//--------------------------------------------------------------------------
BOOL
COFSFolder::IsDSFolder (LPCITEMIDLIST pidl)
{
BOOL fSuccess = FALSE;
BOOL fGotPath;
TCHAR szPath[MAX_PATH];
TCHAR szClassName[40]; // REVIEW: This len should be in a header
NTSTATUS nts;
HANDLE h;
CLSID clsid;
UNICODE_STRING UFileName;
OBJECT_ATTRIBUTES Obja;
IO_STATUS_BLOCK IoStatusBlock;
CHAR EaBuffer[sizeof(FILE_FULL_EA_INFORMATION) + sizeof(EA_NAME_OPENIFJP)];
ULONG cbOpenIfJPEa = sizeof(EaBuffer);
PFILE_FULL_EA_INFORMATION pOpenIfJPEa = (PFILE_FULL_EA_INFORMATION)EaBuffer;
DWORD err = GetLastError();
fGotPath = SHGetPathFromIDList (pidl, szPath);
RtlDosPathNameToNtPathName_U(szPath,
&UFileName,
NULL, NULL);
InitializeObjectAttributes(
&Obja,
&UFileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
pOpenIfJPEa->NextEntryOffset = 0;
pOpenIfJPEa->Flags = 0;
pOpenIfJPEa->EaNameLength = lstrlenA(EA_NAME_OPENIFJP);
pOpenIfJPEa->EaValueLength = 0;
lstrcpyA(pOpenIfJPEa->EaName, EA_NAME_OPENIFJP);
nts = NtCreateFile(
&h,
SYNCHRONIZE | FILE_LIST_DIRECTORY | FILE_READ_ATTRIBUTES,
&Obja,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
pOpenIfJPEa,
cbOpenIfJPEa
);
if ((nts == STATUS_DFS_EXIT_PATH_FOUND) || (nts == STATUS_PATH_NOT_COVERED)) {
nts = NtCreateFile(
&h,
SYNCHRONIZE | FILE_LIST_DIRECTORY | FILE_READ_ATTRIBUTES,
&Obja,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_STORAGE_TYPE_SPECIFIED | FILE_STORAGE_TYPE_JUNCTION_POINT |
FILE_SYNCHRONOUS_IO_NONALERT,
pOpenIfJPEa,
cbOpenIfJPEa
);
}
if (!NT_SUCCESS(nts)) {
return FALSE;
}
nts = RtlQueryClassId(h, &clsid);
CloseHandle( h );
if (nts == STATUS_NOT_FOUND) {
return FALSE;
}
if (!NT_SUCCESS(nts)) {
nts = GetClassFile (szPath, &clsid);
}
if (!NT_SUCCESS(nts)) {
return FALSE;
}
fSuccess = (IsEqualCLSID (CLSID_CDSFolder, clsid));
return fSuccess;
}