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.
472 lines
17 KiB
472 lines
17 KiB
#ifndef __SHLINK_H__
|
|
#define __SHLINK_H__
|
|
|
|
#include <trkwks.h>
|
|
#include <rpcasync.h>
|
|
#include <filter.h>
|
|
#include "cowsite.h"
|
|
|
|
class CDarwinContextMenuCB;
|
|
class CTracker;
|
|
|
|
class CShellLink : public IShellLinkA,
|
|
public IShellLinkW,
|
|
public IPersistStream,
|
|
public IPersistFile,
|
|
public IShellExtInit,
|
|
public IContextMenu3,
|
|
public IDropTarget,
|
|
public IQueryInfo,
|
|
public IShellLinkDataList,
|
|
public IExtractIconA,
|
|
public IExtractIconW,
|
|
public IExtractImage2,
|
|
public IPersistPropertyBag,
|
|
public IServiceProvider,
|
|
public IFilter,
|
|
public CObjectWithSite,
|
|
public ICustomizeInfoTip
|
|
{
|
|
friend CTracker;
|
|
friend CDarwinContextMenuCB;
|
|
|
|
public:
|
|
CShellLink();
|
|
|
|
// IUnknown
|
|
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
|
|
STDMETHODIMP_(ULONG) AddRef();
|
|
STDMETHODIMP_(ULONG) Release();
|
|
|
|
// IShellLinkA methods
|
|
STDMETHOD(GetPath)(LPSTR pszFile, int cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD flags);
|
|
STDMETHOD(SetPath)(LPCSTR pszFile);
|
|
//STDMETHOD(GetIDList)(LPITEMIDLIST *ppidl);
|
|
//STDMETHOD(SetIDList)(LPCITEMIDLIST pidl);
|
|
STDMETHOD(GetDescription)(LPSTR pszName, int cchMaxName);
|
|
STDMETHOD(SetDescription)(LPCSTR pszName);
|
|
STDMETHOD(GetWorkingDirectory)(LPSTR pszDir, int cchMaxPath);
|
|
STDMETHOD(SetWorkingDirectory)(LPCSTR pszDir);
|
|
STDMETHOD(GetArguments)(LPSTR pszArgs, int cchMaxPath);
|
|
STDMETHOD(SetArguments)(LPCSTR pszArgs);
|
|
//STDMETHOD(GetHotkey)(WORD *pwHotkey);
|
|
//STDMETHOD(SetHotkey)(WORD wHotkey);
|
|
//STDMETHOD(GetShowCmd)(int *piShowCmd);
|
|
//STDMETHOD(SetShowCmd)(int iShowCmd);
|
|
STDMETHOD(GetIconLocation)(LPSTR pszIconPath, int cchIconPath, int *piIcon);
|
|
STDMETHOD(SetIconLocation)(LPCSTR pszIconPath, int iIcon);
|
|
//STDMETHOD(Resolve)(HWND hwnd, DWORD dwResolveFlags);
|
|
STDMETHOD(SetRelativePath)(LPCSTR pszPathRel, DWORD dwReserved);
|
|
|
|
// IShellLinkW
|
|
STDMETHOD(GetPath)(LPWSTR pszFile, int cchMaxPath, WIN32_FIND_DATAW *pfd, DWORD fFlags);
|
|
STDMETHOD(GetIDList)(LPITEMIDLIST *ppidl);
|
|
STDMETHOD(SetIDList)(LPCITEMIDLIST pidl);
|
|
STDMETHOD(GetDescription)(LPWSTR pszName, int cchMaxName);
|
|
STDMETHOD(SetDescription)(LPCWSTR pszName);
|
|
STDMETHOD(GetWorkingDirectory)(LPWSTR pszDir, int cchMaxPath);
|
|
STDMETHOD(SetWorkingDirectory)(LPCWSTR pszDir);
|
|
STDMETHOD(GetArguments)(LPWSTR pszArgs, int cchMaxPath);
|
|
STDMETHOD(SetArguments)(LPCWSTR pszArgs);
|
|
STDMETHOD(GetHotkey)(WORD *pwHotKey);
|
|
STDMETHOD(SetHotkey)(WORD wHotkey);
|
|
STDMETHOD(GetShowCmd)(int *piShowCmd);
|
|
STDMETHOD(SetShowCmd)(int iShowCmd);
|
|
STDMETHOD(GetIconLocation)(LPWSTR pszIconPath, int cchIconPath, int *piIcon);
|
|
STDMETHOD(SetIconLocation)(LPCWSTR pszIconPath, int iIcon);
|
|
STDMETHOD(SetRelativePath)(LPCWSTR pszPathRel, DWORD dwReserved);
|
|
STDMETHOD(Resolve)(HWND hwnd, DWORD dwResolveFlags);
|
|
STDMETHOD(SetPath)(LPCWSTR pszFile);
|
|
|
|
// IPersist
|
|
STDMETHOD(GetClassID)(CLSID *pClassID);
|
|
STDMETHOD(IsDirty)();
|
|
|
|
// IPersistStream
|
|
STDMETHOD(Load)(IStream *pstm);
|
|
STDMETHOD(Save)(IStream *pstm, BOOL fClearDirty);
|
|
STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize);
|
|
|
|
// IPersistFile
|
|
STDMETHOD(Load)(LPCOLESTR pwszFile, DWORD grfMode);
|
|
STDMETHOD(Save)(LPCOLESTR pwszFile, BOOL fRemember);
|
|
STDMETHOD(SaveCompleted)(LPCOLESTR pwszFile);
|
|
STDMETHOD(GetCurFile)(LPOLESTR *lplpszFileName);
|
|
|
|
// IPersistPropertyBag
|
|
STDMETHOD(Save)(IPropertyBag* pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties);
|
|
STDMETHOD(Load)(IPropertyBag* pPropBag, IErrorLog* pErrorLog);
|
|
STDMETHOD(InitNew)(void);
|
|
|
|
// IShellExtInit
|
|
STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
|
|
|
|
// IContextMenu3
|
|
STDMETHOD(QueryContextMenu)(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
|
|
STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO piciIn);
|
|
STDMETHOD(GetCommandString)(UINT_PTR idCmd, UINT wFlags, UINT *pmf, LPSTR pszName, UINT cchMax);
|
|
STDMETHOD(HandleMenuMsg)(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
STDMETHOD(HandleMenuMsg2)(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult);
|
|
|
|
// IDropTarget
|
|
STDMETHOD(DragEnter)(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
|
STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
|
STDMETHOD(DragLeave)();
|
|
STDMETHOD(Drop)(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
|
|
|
// IQueryInfo
|
|
STDMETHOD(GetInfoTip)(DWORD dwFlags, WCHAR **ppwszTip);
|
|
STDMETHOD(GetInfoFlags)(LPDWORD pdwFlags);
|
|
|
|
// IShellLinkDataList
|
|
STDMETHOD(AddDataBlock)(void *pdb);
|
|
STDMETHOD(CopyDataBlock)(DWORD dwSig, void **ppdb);
|
|
STDMETHOD(RemoveDataBlock)(DWORD dwSig);
|
|
STDMETHOD(GetFlags)(LPDWORD pdwFlags);
|
|
STDMETHOD(SetFlags)(DWORD dwFlags);
|
|
|
|
// IExtractIconA
|
|
STDMETHOD(GetIconLocation)(UINT uFlags,LPSTR szIconFile,UINT cchMax,int *piIndex,UINT * pwFlags);
|
|
STDMETHOD(Extract)(LPCSTR pszFile,UINT nIconIndex,HICON *phiconLarge,HICON *phiconSmall,UINT nIcons);
|
|
|
|
// IExtractIconW
|
|
STDMETHOD(GetIconLocation)(UINT uFlags, LPWSTR pszIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
|
|
STDMETHOD(Extract)(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
|
|
|
|
// IExtractImage
|
|
STDMETHOD (GetLocation)(LPWSTR pszPathBuffer, DWORD cch, DWORD * pdwPriority, const SIZE * prgSize,
|
|
DWORD dwRecClrDepth, DWORD *pdwFlags);
|
|
STDMETHOD (Extract)(HBITMAP *phBmpThumbnail);
|
|
|
|
// IExtractImage2
|
|
STDMETHOD (GetDateStamp)(FILETIME *pftDateStamp);
|
|
|
|
// IServiceProvider
|
|
STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void **ppv);
|
|
|
|
// IFilter
|
|
STDMETHOD(Init)(ULONG grfFlags, ULONG cAttributes, const FULLPROPSPEC *aAttributes, ULONG *pFlags);
|
|
STDMETHOD(GetChunk)(STAT_CHUNK *pStat);
|
|
STDMETHOD(GetText)(ULONG *pcwcBuffer, WCHAR *awcBuffer);
|
|
STDMETHOD(GetValue)(PROPVARIANT **ppPropValue);
|
|
STDMETHOD(BindRegion)(FILTERREGION origPos, REFIID riid, void **ppunk);
|
|
|
|
//*** IObjectWithSite ***
|
|
//STDMETHOD(SetSite)(IUnknown *punkSite);
|
|
//STDMETHOD(GetSite)(REFIID riid, void **ppvSite);
|
|
|
|
// ICustomizeInfoTip
|
|
STDMETHODIMP SetPrefixText(LPCWSTR pszPrefix);
|
|
STDMETHODIMP SetExtraProperties(const SHCOLUMNID *pscid, UINT cscid);
|
|
|
|
// public non interface members
|
|
void _AddExtraDataSection(DATABLOCK_HEADER *pdbh);
|
|
void _RemoveExtraDataSection(DWORD dwSig);
|
|
|
|
protected:
|
|
HRESULT _Resolve(HWND hwnd, DWORD dwResolveFlags, DWORD dwTracker);
|
|
|
|
private:
|
|
~CShellLink();
|
|
|
|
static DWORD CALLBACK _InvokeThreadProc(void *pv);
|
|
static DWORD CALLBACK _VerifyPathThreadProc(void *pv);
|
|
|
|
void _ResetPersistData();
|
|
BOOL _GetRelativePath(LPTSTR pszPath);
|
|
|
|
HRESULT _SetPIDLPath(LPCITEMIDLIST pidl, LPCTSTR pszPath, BOOL bUpdateTrackingData);
|
|
HRESULT _SetSimplePIDL(LPCTSTR pszPath);
|
|
void _UpdateWorkingDir(LPCTSTR pszPath);
|
|
|
|
PLINKINFO _GetLinkInfo(LPCTSTR pszPath);
|
|
void _FreeLinkInfo();
|
|
HRESULT _GetFindDataAndTracker(LPCTSTR pszPath);
|
|
void _ClearTrackerData();
|
|
|
|
BOOL _SetFindData(const WIN32_FIND_DATA *pfd);
|
|
void _GetFindData(WIN32_FIND_DATA *pfd);
|
|
BOOL _IsEqualFindData(const WIN32_FIND_DATA *pfd);
|
|
|
|
HRESULT _ResolveIDList(HWND hwnd, DWORD dwResolveFlags);
|
|
HRESULT _ResolveLinkInfo(HWND hwnd, DWORD dwResolveFlags, LPTSTR pszPath, DWORD *pfifFlags);
|
|
HRESULT _ResolveRemovable(HWND hwnd, LPCTSTR pszPath);
|
|
BOOL _ShouldTryRemovable(HRESULT hr, LPCTSTR pszPath);
|
|
void _SetIDListFromEnvVars();
|
|
BOOL _ResolveDarwin(HWND hwnd, DWORD dwResolveFlags, HRESULT *phr);
|
|
|
|
HRESULT _ResolveLogo3Link(HWND hwnd, DWORD dwResolveFlags);
|
|
HRESULT _CheckForLinkBlessing(LPCTSTR *ppszPathIn);
|
|
HRESULT BlessLink(LPCTSTR *ppszPath, DWORD dwSignature);
|
|
BOOL _EncodeSpecialFolder();
|
|
void _DecodeSpecialFolder();
|
|
HRESULT _SetRelativePath(LPCTSTR pszRelSource);
|
|
HRESULT _UpdateTracker();
|
|
HRESULT _LoadFromFile(LPCTSTR pszPath);
|
|
HRESULT _LoadFromPIF(LPCTSTR szPath);
|
|
HRESULT _SaveToFile(LPTSTR pszPathSave, BOOL fRemember);
|
|
HRESULT _SaveAsLink(LPCTSTR szPath);
|
|
HRESULT _SaveAsPIF(LPCTSTR pszPath, BOOL fPath);
|
|
BOOL _GetWorkingDir(LPTSTR pszDir);
|
|
HRESULT _GetUIObject(HWND hwnd, REFIID riid, void **ppvOut);
|
|
HRESULT _ShortNetTimeout();
|
|
|
|
HRESULT _CreateDarwinContextMenu(HWND hwnd,IContextMenu **pcmOut);
|
|
HRESULT _CreateDarwinContextMenuForPidl(HWND hwnd, LPCITEMIDLIST pidlTarget, IContextMenu **pcmOut);
|
|
HRESULT _InvokeCommandAsync(LPCMINVOKECOMMANDINFO pici);
|
|
HRESULT _InitDropTarget();
|
|
HRESULT _GetExtractIcon(REFIID riid, void **ppvOut);
|
|
HRESULT _InitExtractIcon();
|
|
HRESULT _InitExtractImage();
|
|
BOOL _GetExpandedPath(LPTSTR psz, DWORD cch);
|
|
HRESULT _SetField(LPTSTR *ppszField, LPCWSTR pszValueW);
|
|
HRESULT _SetField(LPTSTR *ppszField, LPCSTR pszValueA);
|
|
HRESULT _GetField(LPCTSTR pszField, LPWSTR pszValueW, int cchValue);
|
|
HRESULT _GetField(LPCTSTR pszField, LPSTR pszValueA, int cchValue);
|
|
int _IsOldDarwin(LPCTSTR pszPath);
|
|
HRESULT _SetPathOldDarwin(LPCTSTR pszPath);
|
|
HRESULT _CreateProcessWithShimLayer(HANDLE hData, BOOL fAllowAsync);
|
|
HRESULT _MaybeAddShim(IBindCtx **ppbcRelease);
|
|
HRESULT _UpdateIconFromExpIconSz();
|
|
|
|
//
|
|
// Inner class to manage the context menu of the shortcut target.
|
|
// We do this to ensure that the target's context menu gets a proper
|
|
// SetSite call so it can contact the containing shortcut.
|
|
//
|
|
class TargetContextMenu {
|
|
public:
|
|
operator IUnknown*() { return _pcmTarget; }
|
|
|
|
// WARNING! Use only as an output pointer
|
|
IContextMenu **GetOutputPtr() { return &_pcmTarget; }
|
|
|
|
HRESULT QueryContextMenu(IShellLink *outer, HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
|
|
{
|
|
IUnknown_SetSite(_pcmTarget, outer);
|
|
HRESULT hr = _pcmTarget->QueryContextMenu(hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
|
|
IUnknown_SetSite(_pcmTarget, NULL);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT InvokeCommand(IShellLink *outer, LPCMINVOKECOMMANDINFO pici)
|
|
{
|
|
IUnknown_SetSite(_pcmTarget, outer);
|
|
HRESULT hr = _pcmTarget->InvokeCommand(pici);
|
|
IUnknown_SetSite(_pcmTarget, NULL);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HandleMenuMsg2(IShellLink *outer, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
|
|
|
|
// This doesn't need to be wrapped in a SetSite (yet)
|
|
UINT GetCommandString(IShellLink *outer, UINT_PTR idCmd, UINT wFlags, UINT *pmf, LPSTR pszName, UINT cchMax)
|
|
{
|
|
HRESULT hr = _pcmTarget->GetCommandString(idCmd, wFlags, pmf, pszName, cchMax);
|
|
return hr;
|
|
}
|
|
|
|
// This doesn't need to be wrapped in a SetSite (yet)
|
|
UINT GetMenuIndexForCanonicalVerb(IShellLink *outer, HMENU hMenu, UINT idCmdFirst, LPCWSTR pwszVerb)
|
|
{
|
|
UINT ui = ::GetMenuIndexForCanonicalVerb(hMenu, _pcmTarget, idCmdFirst, pwszVerb);
|
|
return ui;
|
|
}
|
|
|
|
void AtomicRelease()
|
|
{
|
|
ATOMICRELEASE(_pcmTarget);
|
|
}
|
|
|
|
~TargetContextMenu()
|
|
{
|
|
IUnknown_SetSite(_pcmTarget, NULL);
|
|
AtomicRelease();
|
|
}
|
|
|
|
private:
|
|
IContextMenu *_pcmTarget; // stuff for IContextMenu
|
|
};
|
|
|
|
// Data Members
|
|
LONG _cRef; // Ref Count
|
|
BOOL _bDirty; // something has changed
|
|
LPTSTR _pszCurFile; // current file from IPersistFile
|
|
LPTSTR _pszRelSource; // overrides pszCurFile in relative tracking
|
|
|
|
TargetContextMenu _cmTarget; // stuff for IContextMenu
|
|
CDarwinContextMenuCB *_pcbDarwin;
|
|
|
|
UINT _indexMenuSave;
|
|
UINT _idCmdFirstSave;
|
|
UINT _idCmdLastSave;
|
|
UINT _uFlagsSave;
|
|
|
|
// IDropTarget specific
|
|
IDropTarget* _pdtSrc; // IDropTarget of link source (unresolved)
|
|
DWORD _grfKeyStateLast;
|
|
|
|
IExtractIconW *_pxi; // for IExtractIcon support
|
|
IExtractIconA *_pxiA;
|
|
IExtractImage *_pxthumb;
|
|
UINT _gilFlags; // ::GetIconLocation() flags
|
|
|
|
// persistant data
|
|
|
|
LPITEMIDLIST _pidl; // may be NULL
|
|
PLINKINFO _pli; // may be NULL
|
|
|
|
LPTSTR _pszName; // title on short volumes
|
|
LPTSTR _pszRelPath;
|
|
LPTSTR _pszWorkingDir;
|
|
LPTSTR _pszArgs;
|
|
LPTSTR _pszIconLocation;
|
|
|
|
LPDBLIST _pExtraData; // extra data to preserve for future compatibility
|
|
|
|
CTracker *_ptracker;
|
|
|
|
WORD _wOldHotkey; // to broadcast hotkey changes
|
|
WORD _wAllign;
|
|
SHELL_LINK_DATA _sld;
|
|
BOOL _bExpandedIcon; // have we already tried to update the icon from the env variable for this instance?
|
|
|
|
// IFilter stuff
|
|
UINT _iChunkIndex;
|
|
UINT _iValueIndex;
|
|
|
|
LPWSTR _pszPrefix;
|
|
};
|
|
|
|
DECLARE_INTERFACE_(ISLTracker, IUnknown)
|
|
{
|
|
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
|
|
STDMETHOD_(ULONG, AddRef)();
|
|
STDMETHOD_(ULONG, Release)();
|
|
|
|
STDMETHOD(Resolve)(HWND hwnd, DWORD fFlags, DWORD TrackerRestrictions) PURE;
|
|
STDMETHOD(GetIDs)(CDomainRelativeObjId *pdroidBirth, CDomainRelativeObjId *pdroidLast, CMachineId *pmcid) PURE;
|
|
STDMETHOD(CancelSearch)() PURE;
|
|
};
|
|
|
|
// This class implements the object ID-based link tracking (new to NT5).
|
|
|
|
class CTracker : public ISLTracker
|
|
{
|
|
public:
|
|
// IUnknown
|
|
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
|
|
STDMETHODIMP_(ULONG) AddRef();
|
|
STDMETHODIMP_(ULONG) Release();
|
|
|
|
// ISLTracker
|
|
STDMETHODIMP Resolve(HWND hwnd, DWORD fFlags, DWORD TrackerRestrictions);
|
|
STDMETHODIMP GetIDs(CDomainRelativeObjId *pdroidBirth, CDomainRelativeObjId *pdroidLast, CMachineId *pmcid);
|
|
|
|
CTracker(CShellLink *psl) : _psl(psl)
|
|
{
|
|
_fLoadedAtLeastOnce = _fLoaded = _fDirty = FALSE;
|
|
_fCritsecInitialized = _fMendInProgress = _fUserCancelled = FALSE;
|
|
_hEvent = NULL;
|
|
_pRpcAsyncState = NULL;
|
|
};
|
|
|
|
~CTracker()
|
|
{
|
|
if (_fCritsecInitialized)
|
|
{
|
|
DeleteCriticalSection(&_cs);
|
|
_fCritsecInitialized = FALSE;
|
|
}
|
|
|
|
if (NULL != _pRpcAsyncState)
|
|
{
|
|
delete _pRpcAsyncState;
|
|
_pRpcAsyncState = NULL;
|
|
}
|
|
|
|
if (NULL != _hEvent)
|
|
{
|
|
CloseHandle(_hEvent);
|
|
_hEvent = NULL;
|
|
}
|
|
}
|
|
|
|
// Initialization.
|
|
|
|
HRESULT InitFromHandle(const HANDLE hFile, const TCHAR* ptszFile);
|
|
HRESULT InitNew();
|
|
void UnInit();
|
|
|
|
// Load and Save
|
|
|
|
HRESULT Load(BYTE *pb, ULONG cb);
|
|
ULONG GetSize()
|
|
{
|
|
return sizeof(DWORD) // To save the length
|
|
+ sizeof(DWORD) // To save flags
|
|
+ sizeof(_mcidLast) + sizeof(_droidLast) + sizeof(_droidBirth);
|
|
}
|
|
|
|
void Save(BYTE *pb, ULONG cb);
|
|
|
|
// Search for a file
|
|
|
|
HRESULT Search(const DWORD dwTickCountDeadline,
|
|
const WIN32_FIND_DATA *pfdIn,
|
|
WIN32_FIND_DATA *pfdOut,
|
|
UINT uShlinkFlags,
|
|
DWORD TrackerRestrictions);
|
|
STDMETHODIMP CancelSearch(); // Also in ISLTracker
|
|
|
|
BOOL IsDirty()
|
|
{
|
|
return _fDirty;
|
|
}
|
|
|
|
BOOL IsLoaded()
|
|
{
|
|
return _fLoaded;
|
|
}
|
|
|
|
BOOL WasLoadedAtLeastOnce()
|
|
{
|
|
return _fLoadedAtLeastOnce;
|
|
}
|
|
|
|
private:
|
|
// Call this from either InitNew or Load
|
|
HRESULT InitRPC();
|
|
|
|
BOOL _fDirty:1;
|
|
|
|
// TRUE => InitNew has be called, but neither InitFromHandle nor Load
|
|
// has been called since.
|
|
BOOL _fLoaded:1;
|
|
|
|
// TRUE => _cs has been intialized and must be deleted on destruction.
|
|
BOOL _fCritsecInitialized:1;
|
|
|
|
// TRUE => An async call to LnkMendLink is active
|
|
BOOL _fMendInProgress:1;
|
|
|
|
BOOL _fUserCancelled:1;
|
|
|
|
// Event used for the async RPC call LnkMendLink, and a critsec to
|
|
// coordinate the search thread and UI thread.
|
|
|
|
HANDLE _hEvent;
|
|
CRITICAL_SECTION _cs;
|
|
|
|
// Either InitFromHandle or Load has been called at least once, though
|
|
// InitNew may have been called since.
|
|
BOOL _fLoadedAtLeastOnce:1;
|
|
CShellLink *_psl;
|
|
PRPC_ASYNC_STATE _pRpcAsyncState;
|
|
|
|
CMachineId _mcidLast;
|
|
CDomainRelativeObjId _droidLast;
|
|
CDomainRelativeObjId _droidBirth;
|
|
};
|
|
|
|
#endif //__SHLINK_H__
|