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
recdocs.cpp
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 26k
Category:
Windows Kernel
Development Platform:
Visual C++
- //---------------------------------------------------------------------------
- //
- // Copyright (c) Microsoft Corporation 1991-1996
- //
- // File: recdocs.cpp
- //
- // History - created from recent.c in explorer - ZekeL - 5-MAR-98
- // combining functionality in to one place
- // now that the desktop lives here.
- //---------------------------------------------------------------------------
- #include "shellprv.h"
- #include "shobjprv.h"
- #include "recdocs.h"
- #include "fstreex.h"
- #include "shcombox.h"
- #include "ids.h"
- #include <urlhist.h>
- #include <runtask.h>
- #define DM_RECENTDOCS 0x80000000
- #define GETRECNAME(p) ((LPCTSTR)(p))
- #define GETRECPIDL(p) ((LPCITEMIDLIST) (((LPBYTE) (p)) + CbFromCch(lstrlen(GETRECNAME(p)) +1)))
- #define REGSTR_KEY_RECENTDOCS TEXT("RecentDocs")
- #define MAX_RECMRU_BUF (CbFromCch(3 * MAX_PATH)) // Max MRUBuf size
- STDAPI RecentDocs_Install(BOOL bInstall)
- {
- TCHAR szPath[MAX_PATH];
- // get the path to the favorites folder. Create it if it is missing and we
- // are installing, otherwise don't bother.
- if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_RECENT, bInstall))
- {
- if (bInstall)
- {
- SHFOLDERCUSTOMSETTINGS fcs = {sizeof(fcs), FCSM_INFOTIP | FCSM_ICONFILE, 0};
- TCHAR szInfoTip[128];
- TCHAR szIconFile[MAX_PATH];
- //Get the infotip for the recent files Folder
- LoadString(HINST_THISDLL, IDS_RECENT, szInfoTip, ARRAYSIZE(szInfoTip) );
- fcs.pszInfoTip = szInfoTip;
- // Get the IconFile and IconIndex for the Recent Files Folder
- GetSystemDirectory(szIconFile, ARRAYSIZE(szIconFile));
- PathAppend(szIconFile, TEXT("shdocvw.dll"));
- fcs.pszIconFile = szIconFile;
- fcs.iIconIndex = -20785; // IDI_HISTFOLDER
- SHGetSetFolderCustomSettings(&fcs, szPath, FCS_WRITE);
- }
- }
- return NOERROR;
- }
- class CTaskAddDoc : public CRunnableTask
- {
- public:
- CTaskAddDoc();
- HRESULT Init(HANDLE hMem, DWORD dwProcId);
- // *** pure virtuals ***
- virtual STDMETHODIMP RunInitRT(void);
- private:
- virtual ~CTaskAddDoc();
- void _AddToRecentDocs(LPCITEMIDLIST pidlItem, LPCTSTR pszPath);
- void _TryDeleteMRUItem(HANDLE hmru, DWORD cMax, LPCTSTR pszFileName, LPCITEMIDLIST pidlItem, HANDLE hmruOther, BOOL fOverwrite);
- LPBYTE _CreateMRUItem(LPCITEMIDLIST pidlItem, LPCTSTR pszItem, DWORD *pcbItem, UINT uFlags);
- BOOL _AddDocToRecentAndExtRecent(LPCITEMIDLIST pidlItem, LPCTSTR pszFileName, LPCTSTR pszExt);
- void _TryUpdateNetHood(LPCITEMIDLIST pidlFolder, LPCTSTR pszFolder);
- void _UpdateNetHood(LPCITEMIDLIST pidlFolder, LPCTSTR pszShare);
- // private members
- HANDLE _hMem;
- DWORD _dwProcId;
- HANDLE _hmruRecent;
- DWORD _cMaxRecent;
- LPITEMIDLIST _pidlTarget;
- };
- BOOL ShouldAddToRecentDocs(LPCITEMIDLIST pidl)
- {
- HKEY hk;
- BOOL fRet = TRUE; // default to true
- SHGetClassKey(pidl, &hk, NULL);
- if (hk)
- {
- fRet = !(GetFileTypeAttributes(hk) & FTA_NoRecentDocs);
- SHCloseClassKey(hk);
- }
- return fRet;
- }
- int cdecl RecentDocsCompareName(const void * p1, const void *p2, size_t cb)
- {
- return lstrcmpi(GETRECNAME(p2), (LPCTSTR)p1);
- }
- int cdecl RecentDocsComparePidl(const void * p1, const void *p2, size_t cb)
- {
- // p2 is the one that is in the MRU and p1 is the one that we are passing in...
- return !ILIsEqual(GETRECPIDL(p2), (LPCITEMIDLIST)p1);
- }
- CTaskAddDoc::~CTaskAddDoc(void)
- {
- TraceMsg(DM_RECENTDOCS, "[%X] CTaskAddDoc destroyed", this);
- }
- CTaskAddDoc::CTaskAddDoc(void) : CRunnableTask(RTF_DEFAULT)
- {
- TraceMsg(DM_RECENTDOCS, "[%X] CTaskAddDoc created", this);
- }
- HRESULT CTaskAddDoc::Init( HANDLE hMem, DWORD dwProcId)
- {
- if (hMem)
- {
- _hMem = hMem;
- _dwProcId = dwProcId;
- return S_OK;
- }
- return E_FAIL;
- }
- typedef struct _ARD {
- DWORD dwOffsetPath;
- DWORD dwOffsetPidl;
- } XMITARD, *PXMITARD;
- HRESULT CTaskAddDoc::RunInitRT(void)
- {
- TraceMsg(DM_RECENTDOCS, "[%X] CTaskAddDoc::RunInitRT() running", this);
- PXMITARD px = (PXMITARD)SHLockShared(_hMem, _dwProcId);
- if (px)
- {
- LPITEMIDLIST pidl = px->dwOffsetPidl ? (LPITEMIDLIST)((LPBYTE)px+px->dwOffsetPidl) : NULL;
- LPTSTR pszPath = px->dwOffsetPath ? (LPTSTR)((LPBYTE)px+px->dwOffsetPath) : NULL;
- ASSERT(pszPath);
- _AddToRecentDocs(pidl, pszPath);
- SHUnlockShared(px);
- SHFreeShared(_hMem, _dwProcId);
- }
- return S_OK;
- }
- BOOL GetExtensionClassDescription(LPCTSTR lpszFile)
- {
- LPTSTR lpszExt = PathFindExtension(lpszFile);
- if (*lpszExt)
- {
- TCHAR szClass[128];
- TCHAR szDescription[MAX_PATH];
- long cchClass = SIZEOF(szClass);
- if (SHRegQueryValue(HKEY_CLASSES_ROOT, lpszExt, szClass, &cchClass) != ERROR_SUCCESS)
- {
- // if this fails, use the extension cause it might be a pseudoclass
- lstrcpyn(szClass, lpszExt, ARRAYSIZE(szClass));
- }
- return GetClassDescription(HKEY_CLASSES_ROOT, szClass, szDescription, ARRAYSIZE(szDescription),
- GCD_MUSTHAVEOPENCMD | GCD_ALLOWPSUDEOCLASSES);
- }
- return FALSE;
- }
- STDAPI_(void) FlushRunDlgMRU(void);
- //
- // _CleanRecentDocs()
- // cleans out the recent docs folder and the associate registry keys.
- //
- void _CleanRecentDocs(void)
- {
- LPITEMIDLIST pidlTargetLocal = SHCloneSpecialIDList(NULL, CSIDL_RECENT, TRUE);
- if (pidlTargetLocal)
- {
- HKEY hkey;
- TCHAR szDir[MAX_PATH];
- // first, delete all the files
- SHFILEOPSTRUCT sFileOp =
- {
- NULL,
- FO_DELETE,
- szDir,
- NULL,
- FOF_NOCONFIRMATION | FOF_SILENT,
- };
- SHGetPathFromIDList(pidlTargetLocal, szDir);
- PathAppend(szDir, c_szStarDotStar);
- szDir[lstrlen(szDir) +1] = 0; // double null terminate
- SHFileOperation(&sFileOp);
- ILFree(pidlTargetLocal);
- pidlTargetLocal = SHCloneSpecialIDList(NULL, CSIDL_NETHOOD, TRUE);
- if (pidlTargetLocal)
- {
- // now we take care of cleaning out the nethood
- // we have to more careful, cuz we let other people
- // add their own stuff in here.
- HANDLE hmru = CreateSharedRecentMRUList(TEXT("NetHood"), NULL, SRMLF_COMPPIDL);
- if (hmru)
- {
- IShellFolder* psf;
- if (SUCCEEDED(SHBindToObject(NULL, IID_IShellFolder, pidlTargetLocal, (void **)&psf)))
- {
- BOOL fUpdate = FALSE;
- int iItem = 0;
- LPITEMIDLIST pidlItem;
- ASSERT(psf);
- while (-1 != EnumSharedRecentMRUList(hmru, iItem++, NULL, &pidlItem))
- {
- ASSERT(pidlItem);
- STRRET str;
- if (SUCCEEDED(psf->GetDisplayNameOf(pidlItem, SHGDN_FORPARSING, &str))
- && SUCCEEDED(StrRetToBuf(&str, pidlItem, szDir, ARRAYSIZE(szDir))))
- {
- szDir[lstrlen(szDir) +1] = 0; // double null terminate
- SHFileOperation(&sFileOp);
- }
- ILFree(pidlItem);
- }
- if (fUpdate)
- SHChangeNotify(SHCNE_UPDATEDIR, 0, (void *)pidlTargetLocal, NULL);
- psf->Release();
- }
- FreeMRUList(hmru);
- }
- ILFree(pidlTargetLocal);
- }
- // now delete the registry stuff
- hkey = SHGetExplorerHkey(HKEY_CURRENT_USER, TRUE);
- if (hkey)
- {
- SHDeleteKey(hkey, REGSTR_KEY_RECENTDOCS);
- RegCloseKey(hkey);
- }
- // reinit the the folder.
- RecentDocs_Install(TRUE);
- SHChangeNotifyHandleEvents();
- }
- FlushRunDlgMRU();
- return;
- }
- //
- // WARNING - _TryDeleteMRUItem() returns an allocated string that must be freed
- //
- void CTaskAddDoc::_TryDeleteMRUItem(HANDLE hmru, DWORD cMax, LPCTSTR pszFileName, LPCITEMIDLIST pidlItem, HANDLE hmruOther, BOOL fOverwrite)
- {
- BYTE buf[MAX_RECMRU_BUF] = {0};
- DWORD cbItem = CbFromCch(lstrlen(pszFileName) + 1);
- int iItem = fOverwrite ? FindMRUData(hmru, pszFileName, cbItem, NULL) : -1;
- //
- // if iItem is not -1 then it is already existing item that we will replace.
- // if it is -1 then we need to point iItem to the last in the list.
- if (iItem == -1)
- {
- // torch the last one if we have the max number of items in the list.
- // default to success, cuz if we dont find it we dont need to delete it
- iItem = cMax - 1;
- }
- // if we cannot get it in order to delete it,
- // then we will not overwrite the item.
- if (EnumMRUList(hmru, iItem, buf, SIZEOF(buf)) != -1)
- {
- // convert the buf into the last segment of the pidl
- LPITEMIDLIST pidlFullLink = ILCombine(_pidlTarget, GETRECPIDL(buf));
- if (pidlFullLink)
- {
- // This is semi-gross, but some link types like calling cards are the
- // actual data. If we delete and recreate they lose their info for the
- // run. We will detect this by knowing that their pidl will be the
- // same as the one we are deleting...
- if (!ILIsEqual(pidlFullLink, pidlItem))
- {
- TCHAR sz[MAX_PATH];
- // now remove out link to it
- SHGetPathFromIDList(pidlFullLink, sz);
- Win32DeleteFile(sz);
- TraceMsg(DM_RECENTDOCS, "[%X] CTaskAddDoc::_TryDeleteMRUItem() deleting '%s'", this, sz);
- if (hmruOther)
- {
- // deleted a shortcut,
- // need to try and remove it from the hmruOther...
- iItem = FindMRUData(hmruOther, GETRECNAME(buf), CbFromCch(lstrlen(GETRECNAME(buf)) +1), NULL);
- if (iItem != -1)
- DelMRUString(hmruOther, iItem);
- }
- }
- ILFree(pidlFullLink);
- }
- }
- }
- // in:
- // pidlItem - full IDList for the item being added
- // pszItem - name (file spec) of the item (used in the display to the user)
- // uFlags - SHCL_ flags
- LPBYTE CTaskAddDoc::_CreateMRUItem(LPCITEMIDLIST pidlItem, LPCTSTR pszItem,
- DWORD *pcbOut, UINT uFlags)
- {
- TCHAR sz[MAX_PATH];
- LPBYTE pitem = NULL;
- // create the new one
- if (SHGetPathFromIDList(_pidlTarget, sz))
- {
- LPITEMIDLIST pidlFullLink;
- if (SUCCEEDED(CreateLinkToPidl(pidlItem, sz, &pidlFullLink, uFlags)) &&
- pidlFullLink)
- {
- LPCITEMIDLIST pidlLinkLast = ILFindLastID(pidlFullLink);
- int cbLinkLast = ILGetSize(pidlLinkLast);
- DWORD cbItem = CbFromCch(lstrlen(pszItem) + 1);
- pitem = (LPBYTE) LocalAlloc(LPTR, cbItem + cbLinkLast);
- if (pitem)
- {
- memcpy( pitem, pszItem, cbItem );
- memcpy( pitem + cbItem, pidlLinkLast, cbLinkLast);
- *pcbOut = cbItem + cbLinkLast;
- }
- ILFree(pidlFullLink);
- }
- }
- return pitem;
- }
- int EnumSharedRecentMRUList(HANDLE hmru, int iItem, LPTSTR *ppszName, LPITEMIDLIST *ppidl)
- {
- BYTE buf[MAX_RECMRU_BUF] = {0};
- int iRet;
- // if both out params are NULL or iItem < 0 then this is a query for the size
- // of the MRU list...
- if (ppszName)
- *ppszName = NULL;
- if (ppidl)
- *ppidl = NULL;
- if (iItem < 0 || (!ppszName && !ppidl))
- iRet = EnumMRUList(hmru, -1, NULL, 0);
- else if (-1 != (iRet = EnumMRUList(hmru, iItem, buf, SIZEOF(buf))))
- {
- if (ppszName)
- {
- *ppszName = StrDup(GETRECNAME(buf));
- if (!*ppszName)
- iRet = -1;
- }
- else if (ppidl)
- {
- *ppidl = ILClone(GETRECPIDL(buf));
- if (!*ppidl)
- iRet = -1;
- }
- }
- return iRet;
- }
- #define MAXRECENT_DEFAULTDOC 10
- #define MAXRECENT_MAJORDOC 20
- HANDLE CreateSharedRecentMRUList(LPCTSTR pszClass, DWORD *pcMax, DWORD dwFlags)
- {
- if (SHRestricted(REST_NORECENTDOCSHISTORY))
- return NULL;
- DWORD cMax;
- MRUCMPDATAPROC procCompare = RecentDocsCompareName;
- TCHAR szKey[MAX_PATH];
- LPCTSTR pszKey = REGSTR_PATH_EXPLORER TEXT("\") REGSTR_KEY_RECENTDOCS;
- if (pszClass)
- {
- // want to use the pszExt as a sub key
- lstrcpy(szKey, pszKey);
- StrCatBuff(szKey, TEXT("\"), SIZECHARS(szKey));
- StrCatBuff(szKey, pszClass, SIZECHARS(szKey));
- pszKey = szKey;
- // we need to find out how many
- DWORD dwType = REG_DWORD, dwMajor = 0, cbSize = SIZEOF(cbSize);
- SHGetValue(HKEY_CLASSES_ROOT, pszClass, TEXT("MajorDoc"), &dwType, (LPVOID)&dwMajor, &cbSize);
- cMax = dwMajor ? MAXRECENT_MAJORDOC : MAXRECENT_DEFAULTDOC;
- }
- else
- {
- // this the root MRU
- cMax = SHRestricted(REST_MaxRecentDocs);
- // default max docs...
- if (cMax < 1)
- cMax = MAXRECENTDOCS * MAXRECENT_DEFAULTDOC;
- }
- if (dwFlags & SRMLF_COMPPIDL)
- procCompare = RecentDocsComparePidl;
- MRUDATAINFO mi = {
- SIZEOF(MRUDATAINFO),
- cMax,
- MRU_BINARY | MRU_CACHEWRITE,
- HKEY_CURRENT_USER,
- pszKey,
- procCompare
- };
- if (pcMax)
- *pcMax = cMax;
- return CreateMRUList((MRUINFO *)&mi);
- }
- BOOL CTaskAddDoc::_AddDocToRecentAndExtRecent(LPCITEMIDLIST pidlItem, LPCTSTR pszFileName,
- LPCTSTR pszExt)
- {
- DWORD cbItem = CbFromCch(lstrlen(pszFileName) + 1);
- DWORD cMax;
- HANDLE hmru = CreateSharedRecentMRUList(pszExt, &cMax, SRMLF_COMPNAME);
- _TryDeleteMRUItem(_hmruRecent, _cMaxRecent, pszFileName, pidlItem, hmru, TRUE);
- LPBYTE pitem = _CreateMRUItem(pidlItem, pszFileName, &cbItem, 0);
- if (pitem)
- {
- AddMRUData(_hmruRecent, pitem, cbItem);
- if (hmru)
- {
- // we dont want to delete the file if it already existed, because
- // the TryDelete on the RecentMRU would have already done that
- // we only want to delete if we have some overflow from the ExtMRU
- _TryDeleteMRUItem(hmru, cMax, pszFileName, pidlItem, _hmruRecent, FALSE);
- // can reuse the already created item to this mru
- AddMRUData(hmru, pitem, cbItem);
- FreeMRUList(hmru);
- }
- LocalFree(pitem);
- }
- // its been freed but not nulled out...
- return (pitem != NULL);
- }
- //
- // WARNING: UpdateNetHood() changes _pidlTarget to the NetHood then frees it!
- //
- void CTaskAddDoc::_UpdateNetHood(LPCITEMIDLIST pidlFolder, LPCTSTR pszShare)
- {
- if (SHRestricted(REST_NORECENTDOCSNETHOOD))
- return;
- // need to add this boy to the Network Places
- LPITEMIDLIST pidl = ILCreateFromPath(pszShare);
- if (pidl)
- {
- //
- // BUGBUG - must verify parentage here - ZekeL - 27-MAY-99
- // http servers exist in both the webfolders namespace
- // and the Internet namespace. thus we must make sure
- // that what ever parent the folder had, the share has
- // the same one.
- //
- if (ILIsParent(pidl, pidlFolder, FALSE))
- {
- ASSERT(_pidlTarget);
- ILFree(_pidlTarget);
- _pidlTarget = SHCloneSpecialIDList(NULL, CSIDL_NETHOOD, TRUE);
- if (_pidlTarget)
- {
- DWORD cMax;
- HANDLE hmru = CreateSharedRecentMRUList(TEXT("NetHood"), &cMax, SRMLF_COMPNAME);
- if (hmru)
- {
- _TryDeleteMRUItem(hmru, cMax, pszShare, pidl, NULL, TRUE);
- DWORD cbItem = CbFromCch(lstrlen(pszShare) + 1);
- LPBYTE pitem = _CreateMRUItem(pidl, pszShare, &cbItem, SHCL_MAKEFOLDERSHORTCUT);
- if (pitem)
- {
- AddMRUData(hmru, pitem, cbItem);
- LocalFree(pitem);
- }
- FreeMRUList(hmru);
- }
- ILFree(_pidlTarget);
- _pidlTarget = NULL;
- }
- }
- ILFree(pidl);
- }
- }
- BOOL PathIsOneOf(const UINT rgFolders[], LPCTSTR pszFolder);
- BOOL _IsPlacesFolder(LPCTSTR pszFolder)
- {
- static const UINT places[] = {
- CSIDL_PERSONAL,
- CSIDL_DESKTOPDIRECTORY,
- CSIDL_COMMON_DESKTOPDIRECTORY,
- CSIDL_NETHOOD,
- CSIDL_FAVORITES,
- (UINT)-1 // terminator
- };
- return PathIsOneOf(places, pszFolder);
- }
- void _AddToUrlHistory(LPCTSTR pszPath)
- {
- ASSERT(pszPath);
- WCHAR szUrl[MAX_URL_STRING];
- DWORD cchUrl = SIZECHARS(szUrl);
- SHTCharToUnicode(pszPath, szUrl, cchUrl);
- // the URL parsing APIs tolerate same in/out buffer
- if (SUCCEEDED(UrlCreateFromPathW(szUrl, szUrl, &cchUrl, 0)))
- {
- IUrlHistoryStg *puhs;
- if (SUCCEEDED(CoCreateInstance(CLSID_CUrlHistory, NULL, CLSCTX_INPROC_SERVER,
- IID_IUrlHistoryStg, (void **)&puhs)))
- {
- ASSERT(puhs);
- puhs->AddUrl(szUrl, NULL, 0);
- puhs->Release();
- }
- }
- }
- void CTaskAddDoc::_TryUpdateNetHood(LPCITEMIDLIST pidlFolder, LPCTSTR pszFolder)
- {
- TCHAR sz[MAX_URL_STRING];
- DWORD cch = SIZECHARS(sz);
- BOOL fUpdate = FALSE;
- // changing szFolder, and changing _pidlTarget here...
- // if this is an URL or a UNC share add it to the nethood
- if (UrlIs(pszFolder, URLIS_URL)
- && !UrlIs(pszFolder, URLIS_OPAQUE)
- && SUCCEEDED(UrlCombine(pszFolder, TEXT("/"), sz, &cch, 0)))
- fUpdate = TRUE;
- else if (PathIsUNC(pszFolder)
- && StrCpyN(sz, pszFolder, cch)
- && PathStripToRoot(sz))
- fUpdate = TRUE;
- if (fUpdate)
- _UpdateNetHood(pidlFolder, sz);
- }
- //-----------------------------------------------------------------
- //
- // Add the named file to the Recently opened MRU list, that is used
- // by the shell to display the recent menu of the tray.
- // this registry will hold two pidls: the target pointing to followed by
- // the pidl of the link created pointing it. In both cases,
- // only the last item id is stored. (we may want to change this... but
- // then again, we may not)
- void CTaskAddDoc::_AddToRecentDocs(LPCITEMIDLIST pidlItem, LPCTSTR pszItem)
- {
- TCHAR szUnescaped[MAX_PATH];
- LPTSTR pszFileName;
- // if these are NULL the caller meant to call _CleanRecentDocs()
- ASSERT(pszItem && *pszItem);
- TraceMsg(DM_RECENTDOCS, "[%X] CTaskAddDoc::_AddToRecentDocs() called for '%s'", this, pszItem);
- // allow only classes with default commands
- //
- // dont add if:
- // it is RESTRICTED
- // it is in the temporary directory
- // it actually has a file name
- // it can be shell exec'd with "open" verb
- //
- if ( (SHRestricted(REST_NORECENTDOCSHISTORY)) ||
- (PathIsTemporary(pszItem)) ||
- (!(pszFileName = PathFindFileName(pszItem))) ||
- (!*pszFileName) ||
- (!GetExtensionClassDescription(pszFileName))
- )
- return;
- // pretty up the URL file names.
- if (UrlIs(pszItem, URLIS_URL))
- {
- StrCpyN(szUnescaped, pszFileName, SIZECHARS(szUnescaped));
- UrlUnescapeInPlace(szUnescaped, 0);
- pszFileName = szUnescaped;
- }
- // otherwise we try our best.
- ASSERT(!_pidlTarget);
- _pidlTarget = SHCloneSpecialIDList(NULL, CSIDL_RECENT, TRUE);
- if (_pidlTarget)
- {
- _hmruRecent = CreateSharedRecentMRUList(NULL, &_cMaxRecent, SRMLF_COMPNAME);
- if (_hmruRecent)
- {
- if (_AddDocToRecentAndExtRecent(pidlItem, pszFileName, PathFindExtension(pszFileName)))
- {
- _AddToUrlHistory(pszItem);
- // get the folder and do it to the folder
- LPITEMIDLIST pidlFolder = ILClone(pidlItem);
- if (pidlFolder)
- {
- ILRemoveLastID(pidlFolder);
- // if it is a folder we already have quick
- // access to from the shell, dont put it in here
- TCHAR szFolder[MAX_URL_STRING];
- if (SUCCEEDED(SHGetNameAndFlags(pidlFolder, SHGDN_FORPARSING, szFolder, SIZECHARS(szFolder), NULL))
- && !_IsPlacesFolder(szFolder))
- {
- // get the friendly name for the folder
- TCHAR szTitle[MAX_PATH];
- if (FAILED(SHGetNameAndFlags(pidlFolder, SHGDN_NORMAL, szTitle, SIZECHARS(szTitle), NULL)))
- StrCpyN(szTitle, PathFindFileName(szFolder), ARRAYSIZE(szTitle));
- _AddDocToRecentAndExtRecent(pidlFolder, szTitle, TEXT("Folder"));
- _TryUpdateNetHood(pidlFolder, szFolder);
- }
- ILFree(pidlFolder);
- }
- SHChangeNotifyHandleEvents();
- }
- FreeMRUList(_hmruRecent);
- _hmruRecent = NULL;
- }
- //cleanup
- if (_pidlTarget)
- {
- ILFree(_pidlTarget);
- _pidlTarget = NULL;
- }
- }
- }
- STDAPI_(void) OpenWithListSoftRegisterProcess(DWORD dwFlags, LPCTSTR pszExt);
- void AddToRecentDocs(LPCITEMIDLIST pidl, LPCTSTR pszItem)
- {
- HWND hwnd;
- DWORD cbSizePidl, cbSizePath;
- ASSERT(pidl && pszItem);
- if (!ShouldAddToRecentDocs(pidl))
- return;
- OpenWithListSoftRegisterProcess(0, PathFindExtension(pszItem));
- cbSizePidl = ILGetSize(pidl);
- cbSizePath = CbFromCch(lstrlen(pszItem) + 1);
- hwnd = GetShellWindow();
- if (hwnd)
- {
- PXMITARD px;
- DWORD dwProcId, dwOffset;
- HANDLE hARD;
- GetWindowThreadProcessId(hwnd, &dwProcId);
- hARD = SHAllocShared(NULL, SIZEOF(XMITARD)+cbSizePath+cbSizePidl, dwProcId);
- if (!hARD)
- return; // Well, we are going to miss one, sorry.
- px = (PXMITARD)SHLockShared(hARD,dwProcId);
- if (!px)
- {
- SHFreeShared(hARD,dwProcId);
- return; // Well, we are going to miss one, sorry.
- }
- px->dwOffsetPidl = 0;
- px->dwOffsetPath = 0;
- dwOffset = SIZEOF(XMITARD);
- if (pszItem)
- {
- px->dwOffsetPath = dwOffset;
- memcpy((LPBYTE)px + dwOffset, pszItem, cbSizePath);
- dwOffset += cbSizePath;
- }
- if (pidl)
- {
- px->dwOffsetPidl = dwOffset;
- memcpy((LPBYTE)px + dwOffset, pidl, cbSizePidl);
- }
- SHUnlockShared(px);
- PostMessage(hwnd, CWM_ADDTORECENT, (WPARAM)hARD, (LPARAM)dwProcId);
- }
- }
- //
- // put things in the shells recent docs list for the start menu
- //
- // in:
- // uFlags SHARD_ (shell add recent docs) flags
- // pv LPCSTR or LPCITEMIDLIST (path or pidl indicated by uFlags)
- // may be NULL, meaning clear the recent list
- //
- STDAPI_(void) SHAddToRecentDocs(UINT uFlags, LPCVOID pv)
- {
- TCHAR szTemp[MAX_URL_STRING]; // for double null
- TraceMsg(DM_RECENTDOCS, "SHAddToRecentDocs() called with %d, [%X]", uFlags, pv);
- if (pv == NULL) // we should nuke all recent docs.
- {
- // we do this synchronously
- _CleanRecentDocs();
- return;
- }
- if (SHRestricted(REST_NORECENTDOCSHISTORY))
- // Don't bother tracking recent documents if restriction is set
- // for privacy.
- return;
- if (uFlags == SHARD_PIDL)
- {
- // pv is a LPCITEMIDLIST (pidl)
- if (SUCCEEDED(SHGetNameAndFlags((LPCITEMIDLIST)pv, SHGDN_FORPARSING, szTemp, SIZECHARS(szTemp), NULL)))
- {
- AddToRecentDocs((LPCITEMIDLIST)pv, szTemp);
- }
- }
- else if (uFlags == SHARD_PATH)
- {
- // pv is a LPTCSTR (path)
- LPITEMIDLIST pidl = ILCreateFromPath((LPCTSTR)pv);
- if (!pidl)
- pidl = SHSimpleIDListFromPath((LPCTSTR)pv);
- if (pidl)
- {
- AddToRecentDocs(pidl, (LPCTSTR)pv);
- ILFree(pidl);
- }
- }
- #ifdef UNICODE
- else if (uFlags == SHARD_PATHA)
- {
- SHAnsiToUnicode((LPCSTR)pv, szTemp, ARRAYSIZE(szTemp));
- SHAddToRecentDocs(SHARD_PATH, szTemp);
- }
- #else
- else if (uFlags == SHARD_PATHW)
- {
- SHUnicodeToAnsi((LPCWSTR)pv, szTemp, ARRAYSIZE(szTemp));
- SHAddToRecentDocs(SHARD_PATH, szTemp);
- }
- #endif
- }
- WINSHELLAPI void ReceiveAddToRecentDocs(HANDLE hARD, DWORD dwProcId)
- {
- // NOTIMPL
- ASSERT(FALSE);
- }
- STDAPI CTaskAddDoc_Create(HANDLE hMem, DWORD dwProcId, IRunnableTask **pptask)
- {
- HRESULT hres;
- CTaskAddDoc *ptad = new CTaskAddDoc();
- if (ptad)
- {
- hres = ptad->Init(hMem, dwProcId);
- if (SUCCEEDED(hres))
- hres = ptad->QueryInterface(IID_IRunnableTask, (void **)pptask);
- ptad->Release();
- }
- else
- hres = E_OUTOFMEMORY;
- return hres;
- }
- STDAPI RecentDocs_GetDisplayName(LPCITEMIDLIST pidl, LPTSTR pszName, DWORD cchName)
- {
- HRESULT hr = E_FAIL;
- HANDLE hmru = CreateSharedRecentMRUList(NULL, NULL, SRMLF_COMPPIDL);
- if (hmru)
- {
- int iItem = FindMRUData(hmru, pidl, ILGetSize(pidl), NULL);
- if (-1 != iItem)
- {
- BYTE buf[MAX_RECMRU_BUF];
- if (-1 != EnumMRUList(hmru, iItem, buf, SIZEOF(buf)))
- {
- StrCpyN(pszName, GETRECNAME(buf), cchName);
- hr = S_OK;
- }
- }
- FreeMRUList(hmru);
- }
- return hr;
- }