Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
netfldr.cpp
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 129k
Category:
Windows Kernel
Development Platform:
Visual C++
- #include "shellprv.h"
- #include "caggunk.h"
- #include "views.h"
- #include "ids.h"
- #include "shitemid.h"
- #include "dbgmem.h"
- #include "idmk.h"
- #include "fstreex.h"
- #include "shobjprv.h"
- #include "datautil.h"
- #include "sfviewp.h"
- #include "winnetp.h" // RESOURCE_SHAREABLE
- #include "prop.h"
- #include "infotip.h"
- extern "C"
- {
- #include "netview.h"
- #ifdef DEBUG // For leak detection
- extern void GetAndRegisterLeakDetection(void);
- extern BOOL g_fInitTable;
- extern LEAKDETECTFUNCS LeakDetFunctionTable;
- #endif
- // {22BEB58B-0794-11d2-A4AA-00C04F8EEB3E}
- const GUID CLSID_CNetFldr = { 0x22beb58b, 0x794, 0x11d2, 0xa4, 0xaa, 0x0, 0xc0, 0x4f, 0x8e, 0xeb, 0x3e };
- // idlist.c
- void StrRetFormat(LPSTRRET pStrRet, LPCITEMIDLIST pidlRel, LPCTSTR pszTemplate, LPCTSTR pszAppend);
- // in stdenum.cpp
- void* CStandardEnum_CreateInstance(REFIID riid, BOOL bInterfaces, int cElement, int cbElement, void *rgElements,
- void (WINAPI * pfnCopyElement)(void *, const void *, DWORD));
- // Where WNet stores its policy
- #define WNET_POLICY_KEY TEXT("Software\Microsoft\Windows\CurrentVersion\Policies\Network")
- // netviewx.c
- extern const IDataObjectVtbl c_CNETIDLDataVtbl;
- extern const IDropTargetVtbl c_CPrintDropTargetVtbl;
- extern const IDropTargetVtbl c_CNetRootTargetVtbl;
- // fstreex.c
- extern TCHAR const c_szDirectoryClass[];
- }
- // is a \serverprinter object
- BOOL _IsPrintShare(LPCIDNETRESOURCE pidn)
- {
- return NET_GetDisplayType(pidn) == RESOURCEDISPLAYTYPE_SHARE &&
- NET_GetType(pidn) == RESOURCETYPE_PRINT;
- }
- STDAPI CNetFldr_CreateInstance(LPCITEMIDLIST pidlAbs, LPCITEMIDLIST pidlTarget, UINT uDisplayType,
- LPCIDNETRESOURCE pidnForProvider, LPCTSTR pszResName,
- REFIID riid, void **ppvOut);
- STDAPI_(BOOL) CreateNetHoodShortcuts();
- class CNetFolder : public CAggregatedUnknown,
- public IShellFolder2,
- public IPersistFolder3,
- public IShellIconOverlay
- {
- public:
- // *** IUnknown ***
- STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObj)
- { return CAggregatedUnknown::QueryInterface(riid, ppvObj); };
- STDMETHODIMP_(ULONG) AddRef(void)
- { return CAggregatedUnknown::AddRef(); };
- STDMETHODIMP_(ULONG) Release(void)
- { return CAggregatedUnknown::Release(); };
- // *** IShellFolder methods ***
- STDMETHODIMP ParseDisplayName(HWND hwnd, LPBC pbc, LPOLESTR lpszDisplayName,
- ULONG* pchEaten, LPITEMIDLIST* ppidl, ULONG* pdwAttributes);
- STDMETHODIMP EnumObjects(HWND hwnd, DWORD grfFlags, IEnumIDList ** ppenumIDList);
- STDMETHODIMP BindToObject(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void** ppvOut);
- STDMETHODIMP BindToStorage(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void** ppvObj);
- STDMETHODIMP CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
- STDMETHODIMP CreateViewObject (HWND hwndOwner, REFIID riid, void** ppvOut);
- STDMETHODIMP GetAttributesOf(UINT cidl, LPCITEMIDLIST* apidl, ULONG* rgfInOut);
- STDMETHODIMP GetUIObjectOf(HWND hwndOwner, UINT cidl, LPCITEMIDLIST* apidl,
- REFIID riid, UINT* prgfInOut, void** ppvOut);
- STDMETHODIMP GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD uFlags, LPSTRRET lpName);
- STDMETHODIMP SetNameOf(HWND hwnd, LPCITEMIDLIST pidl, LPCOLESTR lpszName, DWORD uFlags,
- LPITEMIDLIST* ppidlOut);
- // *** IShellFolder2 methods ***
- STDMETHODIMP GetDefaultSearchGUID(LPGUID lpGuid);
- STDMETHODIMP EnumSearches(LPENUMEXTRASEARCH* ppenum);
- STDMETHODIMP GetDefaultColumn(DWORD dwRes, ULONG* pSort, ULONG* pDisplay);
- STDMETHODIMP GetDefaultColumnState(UINT iColumn, DWORD* pbState);
- STDMETHODIMP GetDetailsEx(LPCITEMIDLIST pidl, const SHCOLUMNID* pscid, VARIANT* pv);
- STDMETHODIMP GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS* pDetails);
- STDMETHODIMP MapColumnToSCID(UINT iColumn, SHCOLUMNID* pscid);
- // *** IPersist methods ***
- STDMETHODIMP GetClassID(CLSID* pClassID);
- // *** IPersistFolder methods ***
- STDMETHODIMP Initialize(LPCITEMIDLIST pidl);
- // *** IPersistFolder2 methods ***
- STDMETHODIMP GetCurFolder(LPITEMIDLIST* ppidl);
- // *** IPersistFolderAlias methods ***
- STDMETHOD(InitializeEx)(IBindCtx *pbc, LPCITEMIDLIST pidlRoot, const PERSIST_FOLDER_TARGET_INFO *ppfai);
- STDMETHOD(GetFolderTargetInfo)(PERSIST_FOLDER_TARGET_INFO *ppfai);
- // *** IShellIconOverlay methods***
- STDMETHOD(GetOverlayIndex)(LPCITEMIDLIST pidl, int * pIndex);
- STDMETHOD(GetOverlayIconIndex)(LPCITEMIDLIST pidl, int * pIconIndex);
- protected:
- CNetFolder(IUnknown* punkOuter);
- ~CNetFolder();
- virtual HRESULT v_GetFileFolder(IShellFolder2 **ppsfFiles)
- { *ppsfFiles = NULL; return E_NOTIMPL; };
- // used by the CAggregatedUnknown stuff
- HRESULT v_InternalQueryInterface(REFIID riid, void** ppvObj);
- static HRESULT CALLBACK EnumCallBack(LPARAM lParam, void* pvData, UINT ecid, UINT index);
- HRESULT _OpenKeys(LPCIDNETRESOURCE pidn, HKEY ahkeys[]);
- LPCTSTR _GetProvider(LPCIDNETRESOURCE pidn, LPTSTR pszProvider, UINT cchProvider);
- DWORD _OpenEnum(HWND hwnd, DWORD grfFlags, LPNETRESOURCE pnr, HANDLE *phEnum);
- static HRESULT _CreateNetIDList(LPIDNETRESOURCE pidnIn,
- LPCTSTR pszName, LPCTSTR pszProvider, LPCTSTR pszComment,
- LPITEMIDLIST *ppidl);
- static HRESULT _NetResToIDList(NETRESOURCE *pnr,
- BOOL fAllowNull, BOOL fKeepProviderName, BOOL fKeepComment,
- LPITEMIDLIST *ppidl, LPARAM lParam);
- static HRESULT _CreateEntireNetwork(LPITEMIDLIST *ppidl, LPARAM lParam);
- LPTSTR _GetNameForParsing(LPCWSTR pwszName, LPTSTR pszBuffer, INT cchBuffer, LPTSTR *ppszRegItem);
- HRESULT _ParseRest(LPBC pbc, LPCWSTR pszRest, LPITEMIDLIST* ppidl, DWORD* pdwAttributes);
- HRESULT _AddUnknownIDList(DWORD dwDisplayType, LPITEMIDLIST *ppidl);
- HRESULT _ParseSimple(LPBC pbc, LPWSTR pszName, LPITEMIDLIST* ppidl, DWORD* pdwAttributes);
- HRESULT _NetResToIDLists(NETRESOURCE *pnr, DWORD dwbuf, LPITEMIDLIST *ppidl);
- HRESULT _ParseNetName(HWND hwnd, LPBC pbc, LPCWSTR pwszName, ULONG* pchEaten,
- LPITEMIDLIST* ppidl, DWORD* pdwAttributes);
- LONG _GetFilePIDLType(LPCITEMIDLIST pidl);
- LPITEMIDLIST _AddProviderToPidl(LPITEMIDLIST pidl, LPCTSTR lpProvider);
- BOOL _MakeStripToLikeKinds(UINT *pcidl, LPCITEMIDLIST **papidl, BOOL fNetObjects);
- LPFNDFMCALLBACK _GetCallbackType(LPCIDNETRESOURCE pidn)
- { return _IsPrintShare(pidn) ? &PrinterDFMCallBack : &DFMCallBack; };
- static HRESULT CALLBACK GAOCallbackNetRoot(IShellFolder2* psf, LPCITEMIDLIST pidl, ULONG* prgfInOut);
- LPITEMIDLIST _pidl;
- LPITEMIDLIST _pidlTarget; // pidl of where the folder is in the namespace
- LPCIDNETRESOURCE _pidnForProvider; // optional provider for this container...
- LPTSTR _pszResName; // optional resource name of this container
- UINT _uDisplayType; // display type of the folder
- IShellFolder2* _psfFiles;
- IUnknown* _punkInner;
- private:
- friend HRESULT CNetFldr_CreateInstance(LPCITEMIDLIST pidlAbs, LPCITEMIDLIST pidlTarget,
- UINT uDisplayType,
- LPCIDNETRESOURCE pidnForProvider, LPCTSTR pszResName,
- REFIID riid, void** ppvOut);
- friend HRESULT CNetwork_DFMCallBackBG(IShellFolder *psf, HWND hwnd,
- IDataObject *pdtobj, UINT uMsg,
- WPARAM wParam, LPARAM lParam);
- static DWORD CALLBACK _PropertiesThreadProc(void *pv);
- friend BOOL NET_GetProviderKeyName(IShellFolder* psf, LPTSTR pszName, UINT uNameLen);
- static HRESULT DFMCallBack(IShellFolder* psf, HWND hwnd,
- IDataObject* pdtobj, UINT uMsg,
- WPARAM wParam, LPARAM lParam);
- static HRESULT PrinterDFMCallBack(IShellFolder* psf, HWND hwnd,
- IDataObject* pdtobj, UINT uMsg,
- WPARAM wParam, LPARAM lParam);
- static HRESULT CALLBACK GAOCallbackNet(IShellFolder2* psf, LPCITEMIDLIST pidl, ULONG* prgfInOut);
- BOOL _GetPathForShare(LPCIDNETRESOURCE pidn, LPTSTR pszPath);
- HRESULT _GetPathForItem(LPCIDNETRESOURCE pidn, LPTSTR pszPath);
- HRESULT _GetPathForItemW(LPCIDNETRESOURCE pidn, LPWSTR pszPath);
- HRESULT _CreateFolderForItem(LPCITEMIDLIST pidl, LPCITEMIDLIST pidlTarget, LPCIDNETRESOURCE pidnForProvider, REFIID riid, void** ppv);
- HRESULT _GetFormatName(LPCIDNETRESOURCE pidn, STRRET* pStrRet);
- HRESULT _GetIconOverlayInfo(LPCIDNETRESOURCE pidn, int *pIndex, DWORD dwFlags);
- #ifdef WINNT
- HKEY _OpenProviderTypeKey(LPCIDNETRESOURCE pidn);
- #endif // WINNT
- HKEY _OpenProviderKey(LPCIDNETRESOURCE pidn);
- static void WINAPI _CopyEnumElement(void* pDest, const void* pSource, DWORD dwSize);
- HRESULT _GetNetResource(LPCIDNETRESOURCE pidn, NETRESOURCEW* pnr, int cb);
- };
- class CNetRootFolder : public CNetFolder
- {
- public:
- // *** IUnknown ***
- STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObj)
- { return CNetFolder::QueryInterface(riid, ppvObj); };
- STDMETHODIMP_(ULONG) AddRef(void)
- { return CNetFolder::AddRef(); };
- STDMETHODIMP_(ULONG) Release(void)
- { return CNetFolder::Release(); };
- // *** IShellFolder methods ***
- STDMETHODIMP ParseDisplayName(HWND hwnd, LPBC pbc, LPOLESTR lpszDisplayName,
- ULONG* pchEaten, LPITEMIDLIST* ppidl, ULONG* pdwAttributes);
- STDMETHODIMP EnumObjects(HWND hwnd, DWORD grfFlags, IEnumIDList ** ppenumIDList);
- STDMETHODIMP BindToObject(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void** ppvOut);
- STDMETHODIMP BindToStorage(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void** ppvObj)
- { return CNetFolder::BindToStorage(pidl, pbc, riid, ppvObj); };
- STDMETHODIMP CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
- STDMETHODIMP CreateViewObject (HWND hwndOwner, REFIID riid, void** ppvOut);
- STDMETHODIMP GetAttributesOf(UINT cidl, LPCITEMIDLIST* apidl, ULONG* rgfInOut);
- STDMETHODIMP GetUIObjectOf(HWND hwndOwner, UINT cidl, LPCITEMIDLIST* apidl,
- REFIID riid, UINT* prgfInOut, void** ppvOut);
- STDMETHODIMP GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD uFlags, LPSTRRET lpName);
- STDMETHODIMP SetNameOf(HWND hwnd, LPCITEMIDLIST pidl, LPCOLESTR lpszName, DWORD uFlags,
- LPITEMIDLIST* ppidlOut);
- // *** IShellFolder2 methods ***
- STDMETHODIMP GetDefaultSearchGUID(LPGUID lpGuid)
- { return CNetFolder::GetDefaultSearchGUID(lpGuid); };
- STDMETHODIMP EnumSearches(LPENUMEXTRASEARCH* ppenum)
- { return CNetFolder::EnumSearches(ppenum); };
- STDMETHODIMP GetDefaultColumn(DWORD dwRes, ULONG* pSort, ULONG* pDisplay)
- { return CNetFolder::GetDefaultColumn(dwRes, pSort, pDisplay); };
- STDMETHODIMP GetDefaultColumnState(UINT iColumn, DWORD* pbState)
- { return CNetFolder::GetDefaultColumnState(iColumn, pbState); };
- STDMETHODIMP GetDetailsEx(LPCITEMIDLIST pidl, const SHCOLUMNID* pscid, VARIANT* pv)
- { return CNetFolder::GetDetailsEx(pidl, pscid, pv); };
- STDMETHODIMP GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS* pDetails)
- { return CNetFolder::GetDetailsOf(pidl, iColumn, pDetails); };
- STDMETHODIMP MapColumnToSCID(UINT iColumn, SHCOLUMNID* pscid)
- { return CNetFolder::MapColumnToSCID(iColumn, pscid); };
- // *** IPersist methods ***
- STDMETHODIMP GetClassID(CLSID* pClassID);
- // *** IPersistFolder methods ***
- STDMETHODIMP Initialize(LPCITEMIDLIST pidl);
- // *** IPersistFolder2 methods ***
- STDMETHODIMP GetCurFolder(LPITEMIDLIST* ppidl)
- { return CNetFolder::GetCurFolder(ppidl); };
- // *** IPersistFolderAlias methods ***
- STDMETHOD(InitializeEx)(IBindCtx *pbc, LPCITEMIDLIST pidlRoot, const PERSIST_FOLDER_TARGET_INFO *ppfai)
- { return CNetFolder::InitializeEx(pbc, pidlRoot, ppfai); };
- STDMETHOD(GetFolderTargetInfo)(PERSIST_FOLDER_TARGET_INFO *ppfai)
- { return CNetFolder::GetFolderTargetInfo(ppfai); };
- protected:
- CNetRootFolder(IUnknown* punkOuter) : CNetFolder(punkOuter) { };
- ~CNetRootFolder() { ASSERT(NULL != _spThis); _spThis = NULL; };
- BOOL v_HandleDelete(PLONG pcRef);
- HRESULT v_GetFileFolder(IShellFolder2 **ppsfFiles);
- private:
- HRESULT _TryParseEntireNet(HWND hwnd, LPBC pbc, WCHAR *pwszName, LPITEMIDLIST *ppidl, DWORD *pdwAttributes);
- friend HRESULT CNetwork_CreateInstance(IUnknown* punkOuter, REFIID riid, void** ppv);
- static CNetRootFolder* _spThis;
- };
- class CNetSFVCB : public CBaseShellFolderViewCB
- {
- public:
- CNetSFVCB(IShellFolder* psf, UINT uNetResType, LPCITEMIDLIST pidlMonitor, LONG lEvents) :
- CBaseShellFolderViewCB(psf, pidlMonitor, lEvents), _uNetResType(uNetResType) {}
- ~CNetSFVCB() {}
- STDMETHODIMP RealMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
- private:
- UINT _uNetResType;
- private:
- HRESULT OnMERGEMENU(DWORD pv, QCMINFO*lP)
- {
- CDefFolderMenu_MergeMenu(HINST_THISDLL, 0, POPUP_NETWORK_POPUPMERGE, lP);
- return S_OK;
- }
- HRESULT OnINVOKECOMMAND(DWORD pv, UINT wP)
- {
- return CNetwork_DFMCallBackBG(m_pshf, m_hwndMain, NULL, DFM_INVOKECOMMAND, wP, 0);
- }
- HRESULT OnGETHELPTEXT(DWORD pv, UINT wPl, UINT wPh, LPTSTR lP)
- {
- #ifdef UNICODE
- return CNetwork_DFMCallBackBG(m_pshf, m_hwndMain, NULL, DFM_GETHELPTEXTW, MAKEWPARAM(wPl, wPh), (LPARAM)lP);
- #else
- return CNetwork_DFMCallBackBG(m_pshf, m_hwndMain, NULL, DFM_GETHELPTEXT, MAKEWPARAM(wPl, wPh), (LPARAM)lP);
- #endif
- }
- HRESULT OnBACKGROUNDENUM(DWORD pv)
- {
- return S_OK;
- }
- HRESULT OnGETCOLSAVESTREAM(DWORD pv, WPARAM wP, IStream **pps)
- {
- LPCTSTR pszValName;
- switch (_uNetResType) {
- case RESOURCEDISPLAYTYPE_DOMAIN:
- pszValName = TEXT("NetDomainColsX");
- break;
- case RESOURCEDISPLAYTYPE_SERVER:
- pszValName = TEXT("NetServerColsX");
- break;
- default:
- return E_FAIL;
- }
- *pps = OpenRegStream(HKEY_CURRENT_USER, REGSTR_PATH_EXPLORER, pszValName, (DWORD) wP);
- return *pps ? S_OK : E_FAIL;
- }
- HRESULT OnDEFITEMCOUNT(DWORD pv, UINT *pnItems)
- {
- // if we time out enuming items make a guess at how many items there
- // will be to make sure we get large icon mode and a reasonable window size
- switch (_uNetResType) {
- case RESOURCEDISPLAYTYPE_GENERIC: // MyNetPlaces now has only a few items typically
- case RESOURCEDISPLAYTYPE_SERVER: // printers & shares, usually only a few
- *pnItems = 10;
- break;
- case RESOURCEDISPLAYTYPE_ROOT: // usually only one or two items
- *pnItems = 5;
- break;
- }
- return S_OK;
- }
- HRESULT OnGetViews(DWORD pv, SHELLVIEWID *pvid, IEnumSFVViews **ppObj);
- HRESULT OnGetZone(DWORD pv, DWORD * pdwZone);
- HRESULT OnDefViewMode(DWORD pv, FOLDERVIEWMODE* pvm)
- {
- //
- // force large icons for My Network Places.
- //
- if ( pvm && (_uNetResType == RESOURCEDISPLAYTYPE_GENERIC) )
- *pvm = FVM_ICON;
- return NOERROR;
- }
- };
- HRESULT CNetSFVCB::OnGetZone(DWORD pv, DWORD * pdwZone)
- {
- if (pdwZone)
- *pdwZone = URLZONE_INTRANET; // default is "Local Intranet"
- return S_OK;
- }
- HRESULT CNetSFVCB::OnGetViews(DWORD pv, SHELLVIEWID *pvid, IEnumSFVViews **ppObj)
- {
- *ppObj = NULL;
- CViewsList cViews;
- TCHAR szTemp[MAX_PATH];
- // Add base class stuff
- cViews.AddReg(HKEY_CLASSES_ROOT, TEXT("folder"));
- switch (_uNetResType)
- {
- case RESOURCEDISPLAYTYPE_NETWORK:
- if (NET_GetProviderKeyName(m_pshf, szTemp, ARRAYSIZE(szTemp)))
- {
- cViews.AddReg(HKEY_CLASSES_ROOT, szTemp);
- }
- break;
- case RESOURCEDISPLAYTYPE_DOMAIN:
- cViews.AddReg(HKEY_CLASSES_ROOT, TEXT("NetDomain"));
- if (NET_GetProviderKeyName(m_pshf, szTemp, ARRAYSIZE(szTemp)))
- {
- lstrcat(szTemp, TEXT("\Domain"));
- cViews.AddReg(HKEY_CLASSES_ROOT, szTemp);
- }
- break;
- case RESOURCEDISPLAYTYPE_SERVER:
- cViews.AddReg(HKEY_CLASSES_ROOT, TEXT("NetServer"));
- if (NET_GetProviderKeyName(m_pshf, szTemp, ARRAYSIZE(szTemp)))
- {
- lstrcat(szTemp, TEXT("\Server"));
- cViews.AddReg(HKEY_CLASSES_ROOT, szTemp);
- }
- break;
- case RESOURCEDISPLAYTYPE_ROOT:
- cViews.AddReg(HKEY_CLASSES_ROOT, TEXT("Network"));
- break;
- case RESOURCEDISPLAYTYPE_GENERIC:
- // This is the "My Network Places" (net root)
- cViews.AddCLSID(&CLSID_NetworkPlaces);
- break;
- }
- cViews.GetDef(pvid);
- return CreateEnumCViewList(&cViews, ppObj);
- // Note the automatic destructor will free any views still left
- }
- STDMETHODIMP CNetSFVCB::RealMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- HANDLE_MSG(0, SFVM_MERGEMENU, OnMERGEMENU);
- HANDLE_MSG(0, SFVM_INVOKECOMMAND, OnINVOKECOMMAND);
- HANDLE_MSG(0, SFVM_GETHELPTEXT, OnGETHELPTEXT);
- HANDLE_MSG(0, SFVM_BACKGROUNDENUM, OnBACKGROUNDENUM);
- HANDLE_MSG(0, SFVM_GETCOLSAVESTREAM, OnGETCOLSAVESTREAM);
- HANDLE_MSG(0, SFVM_GETVIEWS, OnGetViews);
- HANDLE_MSG(0, SFVM_DEFITEMCOUNT, OnDEFITEMCOUNT);
- HANDLE_MSG(0, SFVM_GETZONE, OnGetZone);
- HANDLE_MSG(0, SFVM_DEFVIEWMODE, OnDefViewMode);
- default:
- return E_FAIL;
- }
- return NOERROR;
- }
- STDAPI_(IShellFolderViewCB*) Net_CreateSFVCB(IShellFolder* psf,
- UINT uNetResType,
- LPCITEMIDLIST pidlMonitor,
- LONG lEvents)
- {
- return new CNetSFVCB(psf, uNetResType, pidlMonitor, lEvents);
- }
- // Define a collate order for the hood object types
- #define _HOOD_COL_RON 0
- #define _HOOD_COL_REMOTE 1
- #define _HOOD_COL_FILE 2
- #define _HOOD_COL_NET 3
- typedef struct
- {
- CNetFolder *pnf; // CNetFolder object (this)
- HANDLE hEnum;
- DWORD grfFlags;
- LONG cItems; // Count of items in buffer
- LONG iItem; // Current index of the item in the buffer
- DWORD dwRemote;
- union {
- NETRESOURCE anr[0];
- BYTE szBuffer[8192];
- };
- IEnumIDList *peunk; // used for enumerating file system items (links)
- } ENUM_DATA;
- // Flags for the dwRemote field
- #define RMF_CONTEXT 0x00000001 // Entire network is being enumerated
- #define RMF_SHOWREMOTE 0x00000002 // Return Remote Services for next enumeration
- #define RMF_STOP_ENUM 0x00000004 // Stop enumeration
- #define RMF_GETLINKENUM 0x00000008 // Hoodlinks enum needs to be fetched
- #define RMF_SHOWLINKS 0x00000010 // Hoodlinks need to be shown
- #define RMF_FAKENETROOT 0x00000020 // Don't enumerate the workgroup items
- #define RMF_ENTIRENETSHOWN 0x40000000 // Entire network object shown
- #define RMF_REMOTESHOWN 0x80000000 // Return Remote Services for next enumeration
- const static ICONMAP c_aicmpNet[] = {
- { SHID_NET_NETWORK , II_NETWORK },
- { SHID_NET_DOMAIN , II_GROUP },
- { SHID_NET_SERVER , II_SERVER },
- { SHID_NET_SHARE , (UINT)EIRESID(IDI_SERVERSHARE) },
- { SHID_NET_DIRECTORY , II_FOLDER },
- { SHID_NET_PRINTER , II_PRINTER },
- { SHID_NET_RESTOFNET , II_WORLD },
- { SHID_NET_SHAREADMIN , II_DRIVEFIXED },
- { SHID_NET_TREE , II_TREE },
- #ifdef WINNT
- { SHID_NET_NDSCONTAINER, (UINT)EIRESID(IDI_NDSCONTAINER) },
- #endif
- };
- enum
- {
- NKID_PROVIDERTYPE = 0,
- NKID_PROVIDER,
- NKID_NETCLASS,
- NKID_NETWORK,
- NKID_DIRECTORY,
- NKID_FOLDER
- };
- #define NKID_COUNT 6
- enum
- {
- ICOL_NAME = 0,
- ICOL_COMMENT,
- };
- #define ICOL_FIRST ICOL_NAME
- const COL_DATA s_net_cols[] = {
- {ICOL_NAME, IDS_NAME_COL, 30, LVCFMT_LEFT, &SCID_NAME},
- {ICOL_COMMENT, IDS_COMMENT_COL, 30, LVCFMT_LEFT, &SCID_Comment}
- };
- // This is one-entry cache for remote junctions resolution
- TCHAR g_szLastAttemptedJunctionName[MAX_PATH] = {0};
- TCHAR g_szLastResolvedJunctionName[MAX_PATH] = {0};
- REGITEMSINFO g_riiNetRoot =
- {
- REGSTR_PATH_EXPLORER TEXT("\NetworkNeighborhood\NameSpace"),
- NULL,
- TEXT(':'),
- SHID_NET_REGITEM,
- 1,
- SFGAO_CANLINK,
- 0,
- NULL,
- RIISA_ORIGINAL,
- NULL,
- 0,
- 0,
- };
- CNetRootFolder* CNetRootFolder::_spThis = NULL;
- HRESULT CNetFldr_CreateInstance(LPCITEMIDLIST pidlAbs, LPCITEMIDLIST pidlTarget, UINT uDisplayType,
- LPCIDNETRESOURCE pidnForProvider, LPCTSTR pszResName,
- REFIID riid, void **ppvOut)
- {
- HRESULT hres = E_OUTOFMEMORY;
- *ppvOut = NULL;
- if (!ILIsEmpty(pidlAbs))
- {
- CNetFolder* pNetF = new CNetFolder(NULL);
- if (NULL != pNetF)
- {
- pNetF->_uDisplayType = uDisplayType;
- if ( pidnForProvider )
- {
- //Make sure that the pidnProvider has provider information.
- ASSERT(NET_FHasProvider(pidnForProvider))
- //We are interested only in the provider informarion which is contained in the first entry.
- //Its enought if we clone only the first item in the pidl.
- pNetF->_pidnForProvider = (LPCIDNETRESOURCE)ILCloneFirst((LPCITEMIDLIST)pidnForProvider);
- }
- if (pszResName && *pszResName)
- pNetF->_pszResName = StrDup(pszResName);
- pNetF->_pidl = ILClone(pidlAbs);
- pNetF->_pidlTarget = ILClone(pidlTarget);
- if ( pNetF->_pidl && (!pidlTarget || (pidlTarget && pNetF->_pidlTarget)) )
- {
- if (uDisplayType == RESOURCEDISPLAYTYPE_SERVER)
- {
- // This is a remote computer. See if there are any remote
- // computer registry items. If so, aggregate with the registry
- // class.
- REGITEMSINFO riiComputer =
- {
- REGSTR_PATH_EXPLORER TEXT("\RemoteComputer\NameSpace"),
- NULL,
- TEXT(':'),
- SHID_NET_REMOTEREGITEM,
- -1,
- SFGAO_FOLDER | SFGAO_CANLINK,
- 0, // no required reg items
- NULL,
- RIISA_ORIGINAL,
- pszResName,
- 0,
- 0,
- };
- CRegFolder_CreateInstance(&riiComputer,
- (IUnknown*) (IShellFolder*) pNetF,
- IID_IUnknown,
- (void**) &pNetF->_punkInner);
- }
- else if ( uDisplayType == RESOURCEDISPLAYTYPE_ROOT )
- {
- //
- // this is the entire net icon, so lets create an instance of the regitem folder
- // so we can merge in the items from there.
- //
- REGITEMSINFO riiEntireNet =
- {
- REGSTR_PATH_EXPLORER TEXT("\NetworkNeighborhood\EntireNetwork\NameSpace"),
- NULL,
- TEXT(':'),
- SHID_NET_REGITEM,
- -1,
- SFGAO_CANLINK,
- 0, // no required reg items
- NULL,
- RIISA_ORIGINAL,
- NULL,
- 0,
- 0,
- };
- CRegFolder_CreateInstance(&riiEntireNet,
- (IUnknown*) (IShellFolder*) pNetF,
- IID_IUnknown,
- (void**) &pNetF->_punkInner);
- }
- else
- {
- ASSERT(hres == E_OUTOFMEMORY);
- }
- hres = pNetF->QueryInterface(riid, ppvOut);
- }
- pNetF->Release();
- }
- else
- {
- ASSERT(hres == E_OUTOFMEMORY);
- }
- }
- else
- {
- ASSERT(0);
- hres = E_INVALIDARG;
- }
- return hres;
- }
- HRESULT CNetwork_CreateInstance(IUnknown* punkOuter, REFIID riid, void** ppv)
- {
- HRESULT hres = S_OK;
- ASSERT(NULL != ppv);
- // Must enter critical section to avoid racing against v_HandleDelete
- ENTERCRITICAL;
- if (NULL != CNetRootFolder::_spThis)
- {
- hres = CNetRootFolder::_spThis->QueryInterface(riid, ppv);
- }
- else
- {
- CNetRootFolder* pNetRootF = new CNetRootFolder(punkOuter);
- if (NULL != pNetRootF)
- {
- pNetRootF->_uDisplayType = RESOURCEDISPLAYTYPE_GENERIC;
- ASSERT(NULL == pNetRootF->_punkInner);
- if (SHRestricted(REST_NOSETFOLDERS))
- g_riiNetRoot.iReqItems = 0;
- // create the regitems object, he has the NetRoot object as his outer guy.
- hres = CRegFolder_CreateInstance(&g_riiNetRoot,
- (IUnknown*) (IShellFolder2*) pNetRootF,
- IID_IUnknown,
- (void**) &pNetRootF->_punkInner);
- // NOTE: not using SHInterlockedCompareExchange() because we have the critsec
- CNetRootFolder::_spThis = pNetRootF;
- hres = pNetRootF->QueryInterface(riid, ppv);
- #ifdef DEBUG
- // these objects are created on the background thread, so to avoid
- // fake leak swhen that thread terminates we have to remove them from its memlist.
- // TO DO: transfer these pointers to main thread's memlist so that it shows up in the leak detection
- // because we DO leak them (only at process detach time). here's why:
- // we can't release _spThis at DLL detatch time since it calls other DLLs
- // that may be unloaded now. we just leak instead of crash
- GetAndRegisterLeakDetection();
- if (g_fInitTable)
- {
- // Remove the class pointer:
- LeakDetFunctionTable.pfnremove_from_memlist(pNetRootF);
- if ( NULL != pNetRootF->_punkInner )
- {
- // Remove the _punkInner if it isn't the regfolder pointer
- // (which means it is a delegate pointer - which may be allocated
- // on our heap)
- LeakDetFunctionTable.pfnremove_from_memlist(pNetRootF->_punkInner);
- }
- }
- #endif
- // Release the self-reference, but keep the the _spThis pointer intact
- // (it will be reset to NULL in the destructor)
- pNetRootF->Release();
- }
- else
- {
- hres = E_OUTOFMEMORY;
- *ppv = NULL;
- }
- }
- LEAVECRITICAL;
- return hres;
- }
- CNetFolder::CNetFolder(IUnknown* punkOuter) :
- CAggregatedUnknown (punkOuter)
- {
- // Assert that we're still using a zero-init flag inside the new operator
- ASSERT(NULL == _pidl);
- ASSERT(NULL == _pidlTarget);
- ASSERT(NULL == _pidnForProvider);
- ASSERT(NULL == _pszResName);
- ASSERT(0 == _uDisplayType);
- ASSERT(NULL == _psfFiles);
- ASSERT(NULL == _punkInner);
- DllAddRef();
- }
- CNetFolder::~CNetFolder()
- {
- ILFree(_pidl);
- ILFree(_pidlTarget);
- ILFree((LPITEMIDLIST)_pidnForProvider);
- if (NULL != _pszResName)
- {
- LocalFree(_pszResName);
- }
- SHReleaseInnerInterface(SAFECAST(this, IShellFolder *), &_punkInner);
- DllRelease();
- }
- HRESULT CNetFolder::v_InternalQueryInterface(REFIID riid, void** ppv)
- {
- static const QITAB qit[] = {
- QITABENT(CNetFolder, IShellFolder2), // IID_IShellFolder2
- QITABENTMULTI(CNetFolder, IShellFolder, IShellFolder2), // IID_IShellFolder
- QITABENT(CNetFolder, IPersistFolder3), // IID_IPersistFolderAlias
- QITABENT(CNetFolder, IShellIconOverlay), // IID_IShellIconOverlay
- QITABENTMULTI(CNetFolder, IPersistFolder2, IPersistFolder3), // IID_IPersistFolder2
- QITABENTMULTI(CNetFolder, IPersistFolder, IPersistFolder3), // IID_IPersistFolder
- QITABENTMULTI(CNetFolder, IPersist, IPersistFolder3), // IID_IPersist
- QITABENTMULTI2(CNetFolder, IID_IPersistFreeThreadedObject, IPersist), // IID_IPersistFreeThreadedObject
- { 0 },
- };
- if (_punkInner && (IsEqualIID(riid, IID_IShellFolder) || IsEqualIID(riid, IID_IShellFolder2)))
- {
- return _punkInner->QueryInterface(riid, ppv);
- }
- else if (IsEqualIID(riid, CLSID_CNetFldr))
- {
- *ppv = this; // get class pointer (unrefed!)
- return S_OK;
- }
- else
- {
- HRESULT hr = QISearch(this, qit, riid, ppv);
- if ((E_NOINTERFACE == hr) && (NULL != _punkInner))
- {
- return _punkInner->QueryInterface(riid, ppv);
- }
- else
- {
- return hr;
- }
- }
- }
- BOOL CNetRootFolder::v_HandleDelete(PLONG pcRef)
- {
- ASSERT(NULL != pcRef);
- ENTERCRITICAL;
- // Once inside the critical section things are slightly more stable.
- // CNetwork_CreateInstance won't be able to rescue the cached reference
- // (and bump the refcount from 0 to 1). And we don't have to worry
- // about somebody Release()ing us down to zero a second time, since
- // no new references can show up.
- //
- // HOWEVER! All those scary things could've happened WHILE WE WERE
- // WAITING TO ENTER THE CRITICAL SECTION.
- //
- // While we were waiting, somebody could've called CNetwork_CreateInstance,
- // which bumps the reference count back up. So don't destroy ourselves
- // if our object got "rescued".
- //
- // What's more, while we were waiting, that somebody could've then
- // Release()d us back down to zero, causing us to be called on that
- // other thread, notice that the refcount is indeed zero, and destroy
- // the object, all on that other thread. So if we are not the cached
- // instance, then don't destroy ourselves since that other thread did
- // it already.
- //
- // And even more, somebody might call CNetwork_CreateInstance again
- // and create a brand new object, which might COINCIDENTALLY happen
- // to have the same address as the old object we are trying to destroy
- // here. But in that case, it's okay to destroy the new object because
- // it is indeed the case that the object's reference count is zero and
- // deserves to be destroyed.
- if (this == _spThis && 0 == *pcRef)
- {
- *pcRef = 1000; // protect against cached pointers bumping us up then down
- delete this;
- }
- LEAVECRITICAL;
- // return TRUE to indicate that we've implemented this function
- // (regardless of whether or not this object was actually deleted)
- return TRUE;
- }
- STDMETHODIMP CNetFolder::ParseDisplayName(HWND hwnd, LPBC pbc, WCHAR* pszName, ULONG* pchEaten,
- LPITEMIDLIST* ppidl, DWORD* pdwAttributes)
- {
- return E_NOTIMPL;
- }
- // new for Win2K, this enables enuming the hidden admin shares
- #ifndef RESOURCE_SHAREABLE
- #define RESOURCE_SHAREABLE 0x00000006
- #endif
- //
- // in:
- // hwnd NULL indicates no UI.
- // grfFlags IShellFolder::EnumObjects() SHCONTF_ flags
- // pnr in/out params
- //
- //
- DWORD CNetFolder::_OpenEnum(HWND hwnd, DWORD grfFlags, LPNETRESOURCE pnr, HANDLE *phEnum)
- {
- DWORD dwType = (grfFlags & SHCONTF_NETPRINTERSRCH) ? RESOURCETYPE_PRINT : RESOURCETYPE_ANY;
- DWORD dwScope = pnr ? RESOURCE_GLOBALNET : RESOURCE_CONTEXT;
- if ((_uDisplayType == RESOURCEDISPLAYTYPE_SERVER) &&
- (grfFlags & SHCONTF_SHAREABLE))
- {
- dwScope = RESOURCE_SHAREABLE; // hidden admin shares for this server
- }
- DWORD err = WNetOpenEnum(dwScope, dwType, RESOURCEUSAGE_ALL, pnr, phEnum);
- if ((err != WN_SUCCESS) && hwnd)
- {
- // UI has been enabled
- #ifndef WINNT
- //
- // If it failed, because the user has not been logged on,
- // give him/her a chance to logon at this moment.
- //
- if (err == WN_NOT_LOGGED_ON)
- {
- err = WNetLogon(pnr ? pnr->lpProvider : NULL, hwnd);
- if (err == WN_SUCCESS)
- err = WNetOpenEnum(dwScope, dwType, RESOURCEUSAGE_ALL, pnr, phEnum);
- }
- #endif // !WINNT
- //
- // If it failed because you are not authenticated yet,
- // we need to let the user loggin to this network resource.
- //
- // REVIEW: Ask LenS to review this code.
- if (err == WN_NOT_AUTHENTICATED ||
- err == ERROR_LOGON_FAILURE ||
- err == WN_BAD_PASSWORD ||
- err == WN_ACCESS_DENIED)
- {
- // Retry with password dialog box.
- err = WNetAddConnection3(hwnd, pnr, NULL, NULL, CONNECT_TEMPORARY | CONNECT_INTERACTIVE);
- if (err == WN_SUCCESS)
- err = WNetOpenEnum(dwScope, dwType, RESOURCEUSAGE_ALL, pnr, phEnum);
- }
- UINT idTemplate = pnr && pnr->lpRemoteName ? IDS_ENUMERR_NETTEMPLATE2 : IDS_ENUMERR_NETTEMPLATE1;
- SHEnumErrorMessageBox(hwnd, idTemplate, err, pnr ? pnr->lpRemoteName : NULL, TRUE, MB_OK | MB_ICONHAND);
- }
- return err;
- }
- STDMETHODIMP CNetFolder::EnumObjects(HWND hwnd, DWORD grfFlags, IEnumIDList** ppenum)
- {
- HRESULT hr = E_OUTOFMEMORY;
- ENUM_DATA *penet = (ENUM_DATA *)LocalAlloc(LPTR, SIZEOF(ENUM_DATA));
- if (penet)
- {
- DWORD err;
- TCHAR szProvider[MAX_PATH];
- AddRef();
- penet->pnf = this;
- ASSERT(penet->anr[0].lpRemoteName == NULL);
- ASSERT(penet->dwRemote == 0);
- ASSERT(penet->peunk == NULL);
- ASSERT(penet->cItems == 0);
- ASSERT(penet->iItem == 0);
- penet->anr[0].lpProvider = (LPTSTR) _GetProvider(NULL, szProvider, ARRAYSIZE(szProvider));
- if (_uDisplayType != RESOURCEDISPLAYTYPE_ROOT &&
- _uDisplayType != RESOURCEDISPLAYTYPE_NETWORK)
- {
- penet->anr[0].lpRemoteName = _pszResName;
- }
- err = _OpenEnum(hwnd, grfFlags, &penet->anr[0], &penet->hEnum);
- if (err == WN_SUCCESS)
- {
- penet->grfFlags = grfFlags;
- hr = SHCreateEnumObjects(hwnd, penet, EnumCallBack, ppenum);
- }
- else
- {
- Release();
- LocalFree(penet);
- hr = HRESULT_FROM_WIN32(err);
- }
- }
- return hr;
- }
- LPCIDNETRESOURCE NET_IsValidID(LPCITEMIDLIST pidl)
- {
- if (pidl && !ILIsEmpty(pidl) && ((pidl->mkid.abID[0] & SHID_GROUPMASK) == SHID_NET))
- return (LPCIDNETRESOURCE)pidl;
- return NULL;
- }
- STDMETHODIMP CNetFolder::BindToObject(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void** ppvOut)
- {
- HRESULT hres;
- LPCIDNETRESOURCE pidn;
- *ppvOut = NULL;
- pidn = NET_IsValidID(pidl);
- if (pidn)
- {
- IShellFolder *psfJunction;
- LPITEMIDLIST pidlInit = NULL;
- LPITEMIDLIST pidlTarget = NULL;
- LPCITEMIDLIST pidlRight = _ILNext(pidl);
- BOOL fRightIsEmpty = ILIsEmpty(pidlRight);
- LPCIDNETRESOURCE pidnProvider = NET_FHasProvider(pidn) ? pidn :_pidnForProvider;
- hres = S_OK;
- // lets get the IDLISTs we are going to use to initialize the shell folder
- // if we are doing a single level bind then then ILCombine otherwise
- // be more careful.
- pidlInit = ILCombineParentAndFirst(_pidl, pidl, pidlRight);
- if ( _pidlTarget )
- pidlTarget = ILCombineParentAndFirst(_pidlTarget, pidl, pidlRight);
- if ( !pidlInit || (!pidlTarget && _pidlTarget) )
- hres = E_OUTOFMEMORY;
- // now create the folder object we are using, and either return that
- // object to the caller, or continue the binding down.
- if ( SUCCEEDED(hres) )
- {
- hres = _CreateFolderForItem(pidlInit, pidlTarget, pidnProvider,
- fRightIsEmpty ? riid : IID_IShellFolder,
- fRightIsEmpty ? ppvOut : (void **)&psfJunction);
- if ( !fRightIsEmpty && SUCCEEDED(hres) )
- {
- hres = psfJunction->BindToObject(pidlRight, pbc, riid, ppvOut);
- psfJunction->Release();
- }
- }
- ILFree(pidlInit);
- ILFree(pidlTarget);
- }
- else
- {
- hres = E_INVALIDARG;
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::BindToStorage(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void** ppvOut)
- {
- *ppvOut = NULL;
- return E_NOTIMPL;
- }
- STDMETHODIMP CNetFolder::CompareIDs(LPARAM iCol, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
- {
- HRESULT hres = E_INVALIDARG;
- LPCIDNETRESOURCE pidn1 = NET_IsValidID(pidl1);
- LPCIDNETRESOURCE pidn2 = NET_IsValidID(pidl2);
- if ( pidn1 && pidn2 )
- {
- TCHAR szBuff1[MAX_PATH], szBuff2[MAX_PATH];
- switch (iCol & SHCIDS_COLUMNMASK)
- {
- case ICOL_COMMENT:
- {
- hres = ResultFromShort(lstrcmpi(NET_CopyComment(pidn1, szBuff1, ARRAYSIZE(szBuff1)),
- NET_CopyComment(pidn2, szBuff2, ARRAYSIZE(szBuff2))));
- if ( hres != 0 )
- return hres;
- // drop down into the name comparison
- }
- case ICOL_NAME:
- {
- // Compare by name. This is the one case where we need to handle
- // simple ids in either place. We will try to resync the items
- // if we find a case of this before do the compares.
- // Check for relative IDs. In particular if one item is at
- // a server and the other is at RestOfNet then try to resync
- // the two
- //
- if ( NET_IsFake(pidn1) || NET_IsFake(pidn2) )
- {
- // if either pidn1 or pidn2 is fake then we assume they are identical,
- // this allows us to compare a simple net ID to a real net ID. we
- // assume that if this fails later then the world will be happy
- hres = 0;
- }
- else
- {
- // otherwise lets look at the names and provider strings accordingly
- NET_CopyResName(pidn1, szBuff1, ARRAYSIZE(szBuff1));
- NET_CopyResName(pidn2, szBuff2, ARRAYSIZE(szBuff2));
- hres = ResultFromShort(lstrcmpi(szBuff1, szBuff2));
- // If they're still identical, compare provider names.
- if ( (hres == 0) && (iCol & SHCIDS_ALLFIELDS) )
- {
- LPCTSTR pszProv1 = _GetProvider(pidn1, szBuff1, ARRAYSIZE(szBuff1));
- LPCTSTR pszProv2 = _GetProvider(pidn2, szBuff2, ARRAYSIZE(szBuff2));
- if (pszProv1 && pszProv2)
- hres = ResultFromShort(lstrcmp(pszProv1, pszProv2));
- else
- {
- if (pszProv1 || pszProv2)
- hres = ResultFromShort(pszProv1 ? 1 : -1);
- else
- hres = ResultFromShort(0);
- }
- }
- }
- // If they identical, compare the rest of IDs.
- if (hres == 0)
- hres = ILCompareRelIDs((IShellFolder*)this, (LPCITEMIDLIST)pidn1, (LPCITEMIDLIST)pidn2);
- }
- }
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::CreateViewObject(HWND hwnd, REFIID riid, void** ppvOut)
- {
- HRESULT hres;
- *ppvOut = NULL;
- if (IsEqualIID(riid, IID_IShellView))
- {
- SFV_CREATE sSFV;
- sSFV.cbSize = sizeof(sSFV);
- sSFV.psvOuter = NULL;
- sSFV.psfvcb = Net_CreateSFVCB((IShellFolder*) this, _uDisplayType, _pidl,
- SHCNE_RENAMEITEM | SHCNE_RENAMEFOLDER |
- SHCNE_CREATE | SHCNE_DELETE | SHCNE_UPDATEDIR | SHCNE_UPDATEITEM |
- SHCNE_MKDIR | SHCNE_RMDIR);
- QueryInterface(IID_IShellFolder, (void**) &sSFV.pshf); // in case we are agregated
- hres = SHCreateShellFolderView(&sSFV, (IShellView**) ppvOut);
- if (sSFV.pshf)
- sSFV.pshf->Release();
- if (sSFV.psfvcb)
- sSFV.psfvcb->Release();
- }
- else if (IsEqualIID(riid, IID_IContextMenu))
- {
- IShellFolder* psfOuter;
- hres = QueryInterface(IID_IShellFolder, (void**) &psfOuter);
- if (SUCCEEDED(hres))
- {
- hres = CDefFolderMenu_Create(_pidl, hwnd, 0, NULL, psfOuter,
- CNetwork_DFMCallBackBG, NULL, NULL, (IContextMenu**) ppvOut);
- psfOuter->Release();
- }
- }
- else
- {
- hres = E_NOINTERFACE;
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST* apidl, ULONG* prgfInOut)
- {
- HRESULT hres;
- if (cidl == 0)
- {
- *prgfInOut &= (SFGAO_CANLINK | SFGAO_HASPROPSHEET | SFGAO_HASSUBFOLDER |
- SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | SFGAO_CANMONIKER);
- hres = S_OK;
- }
- else
- {
- hres = Multi_GetAttributesOf((IShellFolder2*) this, cidl, apidl, prgfInOut, GAOCallbackNet);
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, STRRET* pStrRet)
- {
- HRESULT hres;
- LPCIDNETRESOURCE pidn = NET_IsValidID(pidl);
- if (pidn)
- {
- TCHAR szPath[MAX_PATH];
- LPCITEMIDLIST pidlNext = _ILNext(pidl);
- if (dwFlags & SHGDN_FORPARSING)
- {
- if (dwFlags & SHGDN_INFOLDER)
- {
- NET_CopyResName(pidn, szPath, ARRAYSIZE(szPath));
- if (ILIsEmpty(pidlNext))
- {
- // we just need the last part of the display name (IN FOLDER)
- LPTSTR pszT = StrRChr(szPath, NULL, TEXT('\'));
- if (!pszT)
- pszT = szPath;
- else
- pszT++; // move past ''
- hres = StringToStrRet(pszT, pStrRet);
- }
- else
- {
- hres = ILGetRelDisplayName((IShellFolder*) this, pStrRet, pidl, szPath, MAKEINTRESOURCE(IDS_DSPTEMPLATE_WITH_BACKSLASH));
- }
- }
- else
- {
- LPCITEMIDLIST pidlRight = _ILNext(pidl);
- if ( ILIsEmpty(pidlRight) )
- {
- hres = _GetPathForItem(pidn, szPath);
- if (SUCCEEDED(hres))
- {
- hres = StringToStrRet(szPath, pStrRet);
- }
- }
- else
- {
- IShellFolder *psfJunction;
- //Get the pidn which has network provider information.
- LPCIDNETRESOURCE pidnProvider = NET_FHasProvider(pidn) ? pidn :_pidnForProvider;
- LPITEMIDLIST pidlInit, pidlTarget = NULL;
- pidlInit = ILCombineParentAndFirst(_pidl, pidl, pidlRight);
- if ( _pidlTarget )
- pidlTarget = ILCombineParentAndFirst(_pidlTarget, pidl, pidlRight);
- if ( !pidlInit || (_pidlTarget && !pidlTarget) )
- return E_OUTOFMEMORY;
- hres = _CreateFolderForItem(pidlInit, pidlTarget, pidnProvider, IID_IShellFolder, (void **)&psfJunction);
- if ( SUCCEEDED(hres) )
- {
- hres = psfJunction->GetDisplayNameOf(pidlRight, dwFlags, pStrRet);
- psfJunction->Release();
- }
- ILFree(pidlInit);
- ILFree(pidlTarget);
- }
- }
- }
- else
- {
- hres = _GetFormatName(pidn, pStrRet);
- if (SUCCEEDED(hres) && !(dwFlags & SHGDN_INFOLDER) && (NET_GetFlags(pidn) & SHID_JUNCTION))
- {
- TCHAR szServer[MAX_PATH];
- LPITEMIDLIST pidlServer = _pidl;
- if (_pidlTarget)
- pidlServer = _pidlTarget;
- SHGetNameAndFlags(pidlServer, SHGDN_FORPARSING, szServer, ARRAYSIZE(szServer), NULL);
- StrRetFormat(pStrRet, pidl, MAKEINTRESOURCE(IDS_DSPTEMPLATE_WITH_ON), SkipServerSlashes(szServer));
- }
- }
- }
- else
- hres = E_INVALIDARG;
- return hres;
- }
- STDMETHODIMP CNetFolder::SetNameOf(HWND hwnd, LPCITEMIDLIST pidl, LPCOLESTR lpszName, DWORD dwRes, LPITEMIDLIST* ppidl)
- {
- if (ppidl)
- *ppidl = NULL;
- return E_NOTIMPL; // not supported
- }
- STDMETHODIMP CNetFolder::GetUIObjectOf(HWND hwnd, UINT cidl, LPCITEMIDLIST* apidl,
- REFIID riid, UINT* prgfInOut, void** ppvOut)
- {
- HRESULT hres = E_INVALIDARG;
- LPCIDNETRESOURCE pidn = cidl ? NET_IsValidID(apidl[0]) : NULL;
- *ppvOut = NULL;
- if ((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && pidn)
- {
- UINT iIndex;
- if (_IsPrintShare(pidn))
- iIndex = (UINT)EIRESID(IDI_PRINTER_NET);
- else if (NET_IsRemoteFld(pidn))
- iIndex = II_RNA;
- else
- iIndex = SILGetIconIndex(apidl[0], c_aicmpNet, ARRAYSIZE(c_aicmpNet));
- hres = SHCreateDefExtIcon(NULL, iIndex, iIndex, GIL_PERCLASS, riid, ppvOut);
- }
- else if (IsEqualIID(riid, IID_IContextMenu) && pidn)
- {
- HKEY ahkeys[NKID_COUNT];
- hres = _OpenKeys(pidn, ahkeys);
- if (SUCCEEDED(hres))
- {
- IShellFolder* psfOuter;
- hres = QueryInterface(IID_IShellFolder, (void**) &psfOuter);
- if (SUCCEEDED(hres))
- {
- hres = CDefFolderMenu_Create2(_pidl, hwnd, cidl, apidl,
- psfOuter, _GetCallbackType(pidn),
- ARRAYSIZE(ahkeys), ahkeys, (IContextMenu**) ppvOut);
- psfOuter->Release();
- }
- SHRegCloseKeys(ahkeys, ARRAYSIZE(ahkeys));
- }
- }
- else if (cidl && IsEqualIID(riid, IID_IDataObject))
- {
- // Point & Print printer installation assumes that the
- // netresources from CNETIDLData_GetData and the
- // pidls from CIDLData_GetData are in the same order.
- // Keep it this way.
- hres = CIDLData_CreateFromIDArray2(&c_CNETIDLDataVtbl, _pidl, cidl, apidl,
- (IDataObject**) ppvOut);
- }
- else if (pidn && IsEqualIID(riid, IID_IDropTarget))
- {
- // special support because this is an item (not a folder)
- if (_IsPrintShare(pidn))
- {
- hres = CIDLDropTarget_Create(hwnd, &c_CPrintDropTargetVtbl, (LPITEMIDLIST)pidn, (IDropTarget**) ppvOut);
- }
- else
- {
- IShellFolder* psf;
- hres = BindToObject(apidl[0], NULL, IID_PPV_ARG(IShellFolder, &psf));
- if (SUCCEEDED(hres))
- {
- hres = psf->CreateViewObject(hwnd, riid, ppvOut);
- psf->Release();
- }
- }
- }
- else if (pidn && IsEqualIID(riid, IID_IQueryInfo))
- {
- if (NET_GetDisplayType(pidn) == RESOURCEDISPLAYTYPE_ROOT)
- {
- hres = CreateInfoTipFromText(MAKEINTRESOURCE(IDS_RESTOFNETTIP), riid, ppvOut);
- }
- else
- {
- // Someday maybe have infotips for other things too
- }
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::GetDefaultSearchGUID(LPGUID pguid)
- {
- *pguid = SRCID_SFindComputer;
- return S_OK;
- }
- void WINAPI CNetFolder::_CopyEnumElement(void* pDest, const void* pSource, DWORD dwSize)
- {
- if ( pDest && pSource )
- memcpy(pDest, pSource, dwSize);
- }
- STDMETHODIMP CNetFolder::EnumSearches(IEnumExtraSearch** ppenum)
- {
- HRESULT hres = E_NOTIMPL;
- *ppenum = NULL;
- // if the restriction is set then this item should be enumerated from the registry
- // so we fail, else enumerate it
- // only enumerate if we actually have a network to search against
- if (!SHRestricted(REST_HASFINDCOMPUTERS) &&
- (GetSystemMetrics(SM_NETWORK) & RNC_NETWORKS))
- {
- EXTRASEARCH *pxs = (EXTRASEARCH *)LocalAlloc(LPTR, sizeof(EXTRASEARCH));
- if (pxs)
- {
- pxs->guidSearch = SRCID_SFindComputer;
- if (LoadStringW(g_hinst, IDS_FC_NAME, pxs->wszFriendlyName, SIZEOF(pxs->wszFriendlyName)))
- {
- *ppenum = (IEnumExtraSearch*)CStandardEnum_CreateInstance(IID_IEnumExtraSearch, FALSE,
- 1, sizeof(EXTRASEARCH), pxs, _CopyEnumElement);
- if (*ppenum == NULL)
- {
- LocalFree(pxs);
- hres = E_OUTOFMEMORY;
- }
- else
- hres = S_OK;
- }
- }
- else
- hres = E_OUTOFMEMORY;
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::GetDefaultColumn(DWORD dwRes, ULONG* pSort, ULONG* pDisplay)
- {
- return E_NOTIMPL;
- }
- STDMETHODIMP CNetFolder::GetDefaultColumnState(UINT iColumn, DWORD* pdwState)
- {
- HRESULT hr = S_OK;
- *pdwState = 0;
- if (iColumn < ARRAYSIZE(s_net_cols))
- {
- *pdwState |= SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
- }
- else
- {
- hr = E_INVALIDARG;
- }
- return hr;
- }
- STDMETHODIMP CNetFolder::GetDetailsEx(LPCITEMIDLIST pidl, const SHCOLUMNID* pscid, VARIANT* pv)
- {
- HRESULT hres = E_NOTIMPL;
- LPCIDNETRESOURCE pidn = NET_IsValidID(pidl);
- if (pidn)
- {
- if (IsEqualSCID(*pscid, SCID_NETRESOURCE))
- {
- // Office calls SHGetDataFromIDList() with a large buffer to hold all
- // of the strings in the NETRESOURCE structure, so we need to make sure
- // that our variant can hold enough data to pass back to it:
- BYTE rgBuffer[sizeof(NETRESOURCEW) + (4 * MAX_PATH * sizeof(WCHAR))];
- hres = _GetNetResource(pidn, (NETRESOURCEW*) rgBuffer, sizeof(rgBuffer));
- if (SUCCEEDED(hres))
- {
- hres = InitVariantFromBuffer(pv, rgBuffer, sizeof(rgBuffer));
- if (SUCCEEDED(hres))
- {
- // Fixup pointers in structure to point within the variant
- // instead of our stack variable (rgBuffer):
- ASSERT(pv->vt == (VT_ARRAY | VT_UI1));
- NETRESOURCEW* pnrw = (NETRESOURCEW*) pv->parray->pvData;
- if (pnrw->lpLocalName)
- {
- pnrw->lpLocalName = (LPWSTR) ((BYTE*) pnrw +
- ((BYTE*) pnrw->lpLocalName - rgBuffer));
- }
- if (pnrw->lpRemoteName)
- {
- pnrw->lpRemoteName = (LPWSTR) ((BYTE*) pnrw +
- ((BYTE*) pnrw->lpRemoteName - rgBuffer));
- }
- if (pnrw->lpComment)
- {
- pnrw->lpComment = (LPWSTR) ((BYTE*) pnrw +
- ((BYTE*) pnrw->lpComment - rgBuffer));
- }
- if (pnrw->lpProvider)
- {
- pnrw->lpProvider = (LPWSTR) ((BYTE*) pnrw +
- ((BYTE*) pnrw->lpProvider - rgBuffer));
- }
- }
- }
- }
- else if (IsEqualSCID(*pscid, SCID_DESCRIPTIONID))
- {
- SHDESCRIPTIONID did;
- switch(SIL_GetType(pidl) & SHID_TYPEMASK)
- {
- case SHID_NET_DOMAIN:
- did.dwDescriptionId = SHDID_NET_DOMAIN;
- break;
- case SHID_NET_SERVER:
- did.dwDescriptionId = SHDID_NET_SERVER;
- break;
- case SHID_NET_SHARE:
- did.dwDescriptionId = SHDID_NET_SHARE;
- break;
- case SHID_NET_RESTOFNET:
- did.dwDescriptionId = SHDID_NET_RESTOFNET;
- break;
- default:
- did.dwDescriptionId = SHDID_NET_OTHER;
- break;
- }
- did.clsid = CLSID_NULL;
- hres = InitVariantFromBuffer(pv, &did, sizeof(did));
- }
- else if (IsEqualSCID(*pscid, SCID_Comment))
- {
- TCHAR szTemp[MAX_PATH];
- NET_CopyComment(pidn, szTemp, ARRAYSIZE(szTemp));
- hres = InitVariantFromStr(pv, szTemp);
- }
- else if (IsEqualSCID(*pscid, SCID_NAME))
- {
- TCHAR szTemp[MAX_PATH];
- NET_CopyResName(pidn, szTemp, ARRAYSIZE(szTemp));
- hres = InitVariantFromStr(pv, szTemp);
- }
- }
- else
- {
- IShellFolder2* psfFiles;
- hres = v_GetFileFolder(&psfFiles);
- if (SUCCEEDED(hres))
- hres = psfFiles->GetDetailsEx(pidl, pscid, pv);
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *pDetails)
- {
- TCHAR szTemp[MAX_PATH];
- LPCIDNETRESOURCE pidn;
- if (iColumn >= ARRAYSIZE(s_net_cols))
- return E_NOTIMPL;
- pDetails->str.uType = STRRET_CSTR;
- pDetails->str.cStr[0] = 0;
- if (!pidl)
- {
- pDetails->fmt = s_net_cols[iColumn].iFmt;
- pDetails->cxChar = s_net_cols[iColumn].cchCol;
- return ResToStrRet(s_net_cols[iColumn].ids, &pDetails->str);
- }
- pidn = NET_IsValidID(pidl);
- switch (iColumn)
- {
- case ICOL_NAME:
- if (pidn)
- {
- NET_CopyResName(pidn, szTemp, ARRAYSIZE(szTemp));
- return StringToStrRet(szTemp, &pDetails->str);
- }
- else
- {
- IShellFolder2* psfFiles;
- if (SUCCEEDED(v_GetFileFolder(&psfFiles)))
- return psfFiles->GetDisplayNameOf(pidl, SHGDN_NORMAL, &pDetails->str);
- }
- break;
- case ICOL_COMMENT:
- if (pidn)
- {
- NET_CopyComment(pidn, szTemp, ARRAYSIZE(szTemp));
- return StringToStrRet(szTemp, &pDetails->str);
- }
- else
- {
- IShellFolder2* psfFiles;
- if (SUCCEEDED(v_GetFileFolder(&psfFiles)))
- {
- // call the nethood folder and get the comment field from that, we cannot
- // use the column index we have, instead we must use GetDetailsEx and
- // pass the unique columne ID.
- return MapSCIDToDetailsOf(psfFiles, pidl, &SCID_Comment, pDetails);
- }
- }
- break;
- }
- return S_OK;
- }
- STDMETHODIMP CNetFolder::MapColumnToSCID(UINT iColumn, SHCOLUMNID* pscid)
- {
- return MapColumnToSCIDImpl(s_net_cols, ARRAYSIZE(s_net_cols), iColumn, pscid);
- }
- // IPersist methods
- STDMETHODIMP CNetFolder::GetClassID(CLSID* pCLSID)
- {
- switch (_uDisplayType)
- {
- case RESOURCEDISPLAYTYPE_ROOT:
- *pCLSID = CLSID_NetworkRoot;
- break;
- case RESOURCEDISPLAYTYPE_SERVER:
- *pCLSID = CLSID_NetworkServer;
- break;
- case RESOURCEDISPLAYTYPE_DOMAIN:
- *pCLSID = CLSID_NetworkDomain;
- break;
- case RESOURCEDISPLAYTYPE_SHARE:
- *pCLSID = CLSID_NetworkShare;
- break;
- default:
- *pCLSID = CLSID_NULL;
- break;
- }
- return S_OK;
- }
- // IPersistFolder method
- STDMETHODIMP CNetFolder::Initialize(LPCITEMIDLIST pidl)
- {
- ILFree(_pidl);
- ILFree(_pidlTarget);
- _pidl = _pidlTarget = NULL;
- return SHILClone(pidl, &_pidl);
- }
- // IPersistFolder2 method
- STDMETHODIMP CNetFolder::GetCurFolder(LPITEMIDLIST* ppidl)
- {
- return GetCurFolderImpl(_pidl, ppidl);
- }
- // IPersistFolder3 methods
- STDMETHODIMP CNetFolder::InitializeEx(IBindCtx *pbc, LPCITEMIDLIST pidlRoot, const PERSIST_FOLDER_TARGET_INFO *pfti)
- {
- ILFree(_pidl);
- ILFree(_pidlTarget);
- _pidl = _pidlTarget = NULL;
- HRESULT hres = SHILClone(pidlRoot, &_pidl);
- if ( SUCCEEDED(hres) && pfti && pfti->pidlTargetFolder )
- {
- hres = SHILClone(pfti->pidlTargetFolder, &_pidlTarget);
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO *pfti)
- {
- HRESULT hres = S_OK;
- ZeroMemory(pfti, SIZEOF(*pfti));
- if ( _pidlTarget )
- hres = SHILClone(_pidlTarget, &pfti->pidlTargetFolder);
- pfti->dwAttributes = FILE_ATTRIBUTE_DIRECTORY; // maybe add system?
- pfti->csidl = -1;
- return hres;
- }
- // IShellIconOverlay
- HRESULT CNetFolder::_GetIconOverlayInfo(LPCIDNETRESOURCE pidn, int *pIndex, DWORD dwFlags)
- {
- HRESULT hres = E_FAIL;
- //
- // For netshare objects we want to get the icon overlay.
- // If the share is "pinned" to be available offline it will
- // have the "Offline Files" overlay.
- //
- if (RESOURCEDISPLAYTYPE_SHARE == NET_GetDisplayType(pidn))
- {
- TCHAR szPath[MAX_PATH];
- hres = _GetPathForItem(pidn, szPath);
- if (SUCCEEDED(hres))
- {
- IShellIconOverlayManager *psiom;
- hres = GetIconOverlayManager(&psiom);
- if (SUCCEEDED(hres))
- {
- WCHAR szPathW[MAX_PATH];
- SHTCharToUnicode(szPath, szPathW, ARRAYSIZE(szPathW));
- hres = psiom->GetFileOverlayInfo(szPathW, 0, pIndex, dwFlags);
- psiom->Release();
- }
- }
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::GetOverlayIndex(LPCITEMIDLIST pidl, int *pIndex)
- {
- HRESULT hres = E_FAIL;
- LPCIDNETRESOURCE pidn = NET_IsValidID(pidl);
- if (NULL != pidn)
- {
- hres = _GetIconOverlayInfo(pidn, pIndex, SIOM_OVERLAYINDEX);
- }
- return hres;
- }
- STDMETHODIMP CNetFolder::GetOverlayIconIndex(LPCITEMIDLIST pidl, int *pIndex)
- {
- HRESULT hres = E_FAIL;
- LPCIDNETRESOURCE pidn = NET_IsValidID(pidl);
- if (NULL != pidn)
- {
- hres = _GetIconOverlayInfo(pidn, pIndex, SIOM_ICONINDEX);
- }
- return hres;
- }
- //
- // Helper function to allow external callers to query information from a
- // network pidl...
- //
- // NOTE NOTE - This function returns a NETRESOURCE structure whose string
- // pointers are not valid. On Win95 they were pointers back into the pidl's
- // strings (even though the strings were copied into the supplied pv buffer.)
- // Now we make the pointers really point into the buffer.
- //
- HRESULT CNetFolder::_GetNetResource(LPCIDNETRESOURCE pidn, NETRESOURCEW* pnr, int cb)
- {
- TCHAR szStrings[3][MAX_PATH];
- LPWSTR psz, lpsz[3] = {NULL, NULL, NULL};
- int i, cchT;
- if (cb < SIZEOF(*pnr))
- return DISP_E_BUFFERTOOSMALL;
- ZeroMemory(pnr, cb);
- NET_CopyResName(pidn, szStrings[0], ARRAYSIZE(szStrings[0]));
- NET_CopyComment(pidn, szStrings[1], ARRAYSIZE(szStrings[1]));
- _GetProvider(pidn, szStrings[2], ARRAYSIZE(szStrings[2]));
- // Fill in some of the stuff first.
- // pnr->dwScope = 0;
- pnr->dwType = NET_GetType(pidn);
- pnr->dwDisplayType = NET_GetDisplayType(pidn);
- pnr->dwUsage = NET_GetUsage(pidn);
- // pnr->lpLocalName = NULL;
- // Now lets copy the strings into the buffer and make the pointers
- // relative to the buffer...
- psz = (LPWSTR)(pnr + 1);
- cb -= SIZEOF(*pnr);
- for (i = 0; i < ARRAYSIZE(szStrings); i++)
- {
- if (*szStrings[i])
- {
- cchT = (lstrlen(szStrings[i]) + 1) * SIZEOF(TCHAR);
- if (cchT <= cb)
- {
- SHTCharToUnicode(szStrings[i], psz, cb);
- lpsz[i] = psz;
- psz += cchT;
- cb -= cchT * SIZEOF(TCHAR);
- }
- else
- {
- // A hint that the structure is ok,
- // but the strings are missing
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- }
- }
- }
- pnr->lpRemoteName = lpsz[0];
- pnr->lpComment = lpsz[1];
- pnr->lpProvider = lpsz[2];
- return S_OK;
- }
- // Replace all the space characters in the provider name with '_'.
- void ReplaceSpacesWithUnderscore(LPTSTR psz)
- {
- while (psz = StrChr(psz, TEXT(' ')))
- {
- *psz = TEXT('_');
- psz++; // DBCS safe
- }
- }
- //
- // This function opens a reg. database key based on the "network provider".
- //
- // Returns: hkey
- //
- // The caller is responsibe to close the key by calling RegCloseKey().
- //
- HKEY CNetFolder::_OpenProviderKey(LPCIDNETRESOURCE pidn)
- {
- TCHAR szProvider[MAX_PATH];
- if (_GetProvider(pidn, szProvider, ARRAYSIZE(szProvider)))
- {
- HKEY hkeyProgID = NULL;
- ReplaceSpacesWithUnderscore(szProvider);
- RegOpenKey(HKEY_CLASSES_ROOT, szProvider, &hkeyProgID);
- return hkeyProgID;
- }
- return NULL;
- }
- // for netview.cpp
- STDAPI_(BOOL) NET_GetProviderKeyName(IShellFolder* psf, LPTSTR pszName, UINT uNameLen)
- {
- CNetFolder* pThis;
- *pszName = 0;
- if (SUCCEEDED(psf->QueryInterface(CLSID_CNetFldr, (void**) &pThis)) &&
- pThis->_GetProvider(NULL, pszName, uNameLen))
- {
- ReplaceSpacesWithUnderscore(pszName);
- }
- return (BOOL)*pszName;
- }
- //
- // This function opens a reg. database key based on the network provider type.
- // The type is a number that is not localized, as opposed to the provider name
- // which may be localized.
- //
- // Arguments:
- // pidlAbs -- Absolute IDList to a network resource object.
- //
- // Returns: hkey
- //
- // Notes:
- // The caller is responsible to close the key by calling RegCloseKey().
- //
- #ifdef WINNT
- HKEY CNetFolder::_OpenProviderTypeKey(LPCIDNETRESOURCE pidn)
- {
- HKEY hkeyProgID = NULL;
- TCHAR szProvider[MAX_PATH];
- if (_GetProvider(pidn, szProvider, ARRAYSIZE(szProvider)))
- {
- // Now that we've got the provider name, get the provider id.
- DWORD dwType;
- if (WNetGetProviderType(szProvider, &dwType) == WN_SUCCESS)
- {
- // convert nis.wNetType to a string, and then open the key
- // HKEY_CLASSES_ROOTNetworkType<type string>
- TCHAR szRegValue[MAX_PATH];
- wsprintf(szRegValue, TEXT("Network\Type\%d"), HIWORD(dwType));
- RegOpenKey(HKEY_CLASSES_ROOT, szRegValue, &hkeyProgID);
- }
- }
- return hkeyProgID;
- }
- #endif // WINNT
- HRESULT CNetFolder::_OpenKeys(LPCIDNETRESOURCE pidn, HKEY ahkeys[NKID_COUNT])
- {
- // See if there is a key specific to the type of Network object...
- ahkeys[0] = ahkeys[1] = ahkeys[2] = ahkeys[3] = ahkeys[4] = ahkeys[5] = NULL;
- #ifdef WINNT
- ahkeys[NKID_PROVIDERTYPE] = _OpenProviderTypeKey(pidn);
- #endif
- ahkeys[NKID_PROVIDER] = _OpenProviderKey(pidn);
- if (NET_GetDisplayType(pidn) == RESOURCEDISPLAYTYPE_SHARE)
- RegOpenKey(HKEY_CLASSES_ROOT, TEXT("NetShare"), &ahkeys[NKID_NETCLASS]);
- else if (NET_GetDisplayType(pidn) == RESOURCEDISPLAYTYPE_SERVER)
- RegOpenKey(HKEY_CLASSES_ROOT, TEXT("NetServer"), &ahkeys[NKID_NETCLASS]);
- RegOpenKey(HKEY_CLASSES_ROOT, TEXT("Network"), &ahkeys[NKID_NETWORK]);
- // make sure it is not a printer before adding "Folder" or "directory"
- if (!_IsPrintShare(pidn))
- {
- // Shares should also support directory stuff...
- if (NET_GetDisplayType(pidn) == RESOURCEDISPLAYTYPE_SHARE)
- RegOpenKey(HKEY_CLASSES_ROOT, c_szDirectoryClass, &ahkeys[NKID_DIRECTORY]);
- RegOpenKey(HKEY_CLASSES_ROOT, c_szFolderClass, &ahkeys[NKID_FOLDER]);
- }
- return S_OK;
- }
- #ifdef WINNT
- #define WNFMT_PLATFORM WNFMT_ABBREVIATED | WNFMT_INENUM
- #else
- #define WNFMT_PLATFORM WNFMT_INENUM // Win95 net providers improperly implement spec, and shell does too
- #endif // WINNT
- //
- // This function retrieves the formatted (display) name of the specified network object.
- //
- HRESULT CNetFolder::_GetFormatName(LPCIDNETRESOURCE pidn, STRRET* pStrRet)
- {
- TCHAR szName[MAX_PATH];
- NET_CopyResName(pidn, szName, ARRAYSIZE(szName));
- if ((NET_GetDisplayType(pidn) != RESOURCEDISPLAYTYPE_ROOT) &&
- (NET_GetDisplayType(pidn) != RESOURCEDISPLAYTYPE_NETWORK))
- {
- TCHAR szDisplayName[MAX_PATH], szProvider[MAX_PATH];
- DWORD dwSize = ARRAYSIZE(szDisplayName);
- LPCTSTR pszProvider = _GetProvider(pidn, szProvider, ARRAYSIZE(szProvider));
- if ( pszProvider )
- {
- DWORD dwRes = WNetFormatNetworkName(pszProvider, szName, szDisplayName, &dwSize, WNFMT_PLATFORM, 8 + 1 + 3);
- if ( dwRes == WN_SUCCESS )
- lstrcpy(szName, szDisplayName);
- }
- }
- return StringToStrRet(szName, pStrRet);
- }
- //
- // resolve non-UNC share names (novell) to UNC style names
- //
- // returns:
- // TRUE translated the name
- // FALSE didn't translate (maybe error case)
- //