2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
18 #include <afs/param.h>
20 #include <afs/afs_consts.h>
24 #include <sys/types.h>
26 #include "afs_shl_ext.h"
27 #include "shell_ext.h"
28 #include "volume_info.h"
29 #include "set_afs_acl.h"
31 #include "make_mount_point_dlg.h"
33 #include "server_status_dlg.h"
35 #include "submounts_dlg.h"
36 #include "make_symbolic_link_dlg.h"
37 #include <WINNT\afsreg.h>
42 static char THIS_FILE[] = __FILE__;
46 ULONG nCMRefCount = 0; // IContextMenu ref count
47 ULONG nSERefCount = 0; // IShellExtInit ref count
52 #define PCCHAR(str) ((char *)(const char *)str)
53 static char space[AFS_PIOCTL_MAXSIZE];
55 static BOOL IsADir(const CString& strName)
59 if (_tstat(strName, &statbuf) < 0)
62 return statbuf.st_mode & _S_IFDIR;
65 /////////////////////////////////////////////////////////////////////////////
68 IMPLEMENT_DYNCREATE(CShellExt, CCmdTarget)
69 #define REG_CLIENT_PARMS_KEY "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"
70 #define OVERLAYENABLED 1
72 CShellExt::CShellExt()
79 DWORD ShellOption,LSPsize,LSPtype;
80 hr = SHGetMalloc(&m_pAlloc);
81 m_bIsOverlayEnabled=FALSE;
84 RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &NPKey);
85 LSPsize=sizeof(ShellOption);
86 code=RegQueryValueEx(NPKey, _T("ShellOption"), NULL,
87 &LSPtype, (LPBYTE)&ShellOption, &LSPsize);
89 m_bIsOverlayEnabled=((code==0) && (LSPtype==REG_DWORD) && ((ShellOption & OVERLAYENABLED)!=0));
90 TRACE("Create CShellExt, Ref count %d/n",nCMRefCount);
93 CShellExt::~CShellExt()
98 TRACE("Destroy CShellExt, Ref count %d/n",nCMRefCount);
102 void CShellExt::OnFinalRelease()
104 // When the last reference for an automation object is released
105 // OnFinalRelease is called. The base class will automatically
106 // deletes the object. Add additional cleanup required for your
107 // object before calling the base class.
109 CCmdTarget::OnFinalRelease();
113 BEGIN_MESSAGE_MAP(CShellExt, CCmdTarget)
114 //{{AFX_MSG_MAP(CShellExt)
115 // NOTE - the ClassWizard will add and remove mapping macros here.
119 BEGIN_DISPATCH_MAP(CShellExt, CCmdTarget)
120 //{{AFX_DISPATCH_MAP(CShellExt)
121 // NOTE - the ClassWizard will add and remove mapping macros here.
125 // Note: we add support for IID_IShellExt to support typesafe binding
126 // from VBA. This IID must match the GUID that is attached to the
127 // dispinterface in the .ODL file.
131 // {DC515C27-6CAC-11D1-BAE7-00C04FD140D2}
132 static const IID IID_IShellExt =
133 { 0xdc515c27, 0x6cac, 0x11d1, { 0xba, 0xe7, 0x0, 0xc0, 0x4f, 0xd1, 0x40, 0xd2 } };
136 // {5f820ca1-3dde-11db-b2ce-001558092db5}
137 static const IID IID_IShellExt =
138 { 0x5f820ca1, 0x3dde, 0x11db, {0xb2, 0xce, 0x00, 0x15, 0x58, 0x09, 0x2d, 0xb5 } };
141 BEGIN_INTERFACE_MAP(CShellExt, CCmdTarget)
142 INTERFACE_PART(CShellExt, IID_IShellExt, Dispatch)
143 INTERFACE_PART(CShellExt, IID_IContextMenu, MenuExt)
144 INTERFACE_PART(CShellExt, IID_IShellExtInit, ShellInit)
145 INTERFACE_PART(CShellExt, IID_IShellIconOverlayIdentifier, IconExt)
146 INTERFACE_PART(CShellExt, IID_IQueryInfo , ToolTipExt)
147 INTERFACE_PART(CShellExt, IID_IPersistFile , PersistFileExt)
152 IMPLEMENT_OLECREATE(CShellExt, STR_EXT_TITLE, 0xdc515c27, 0x6cac, 0x11d1, 0xba, 0xe7, 0x0, 0xc0, 0x4f, 0xd1, 0x40, 0xd2)
155 IMPLEMENT_OLECREATE(CShellExt, STR_EXT_TITLE, 0x5f820ca1, 0x3dde, 0x11db, 0xb2, 0xce, 0x0, 0x15, 0x58, 0x09, 0x2d, 0xb5)
159 /////////////////////////////////////////////////////////////////////////////
160 // CShellExt message handlers
161 /////////////////////////////////////////////////////////////////////////////
164 /////////////////////////////////////////////////////////////////////////////
165 // IUnknown for IContextMenu
166 /////////////////////////////////////////////////////////////////////////////
167 STDMETHODIMP CShellExt::XMenuExt::QueryInterface(REFIID riid, void** ppv)
169 METHOD_PROLOGUE(CShellExt, MenuExt);
171 return pThis->ExternalQueryInterface(&riid, ppv);
174 STDMETHODIMP_(ULONG) CShellExt::XMenuExt::AddRef(void)
176 return ++nCMRefCount;
179 STDMETHODIMP_(ULONG) CShellExt::XMenuExt::Release(void)
187 /////////////////////////////////////////////////////////////////////////////
188 // IConextMenu Functions
189 /////////////////////////////////////////////////////////////////////////////
190 STDMETHODIMP CShellExt::XMenuExt::QueryContextMenu(HMENU hMenu,UINT indexMenu,
191 UINT idCmdFirst, UINT idCmdLast,UINT uFlags)
193 METHOD_PROLOGUE(CShellExt, MenuExt);
195 // Don't add any menu items if we're being asked to deal with this file as a shortcut.
196 if (uFlags & CMF_VERBSONLY)
197 return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, (USHORT)0);
199 // Check to see if there's already an AFS menu here; if so, remove it
200 int nItemsNow = GetMenuItemCount (hMenu);
201 CString strAfsItemText = GetMessageString(IDS_AFS_ITEM);
202 LPCTSTR pszAfsItemText = (LPCTSTR)strAfsItemText;
203 for (int iItem = 0; iItem < nItemsNow; iItem++) {
204 TCHAR szItemText[256];
205 if (!GetMenuString (hMenu, iItem, szItemText, 256, MF_BYPOSITION))
207 if (!lstrcmp (szItemText, pszAfsItemText)) {
208 DeleteMenu (hMenu, iItem, MF_BYPOSITION);
211 if ((!lstrcmp(szItemText,_T("&Delete")))&&(pThis->m_bIsSymlink)) { /*this is a symlink - don't present a delete menu!*/
212 DeleteMenu (hMenu, iItem, MF_BYPOSITION);
215 if ((!lstrcmp(szItemText,_T("Cu&t")))&&(pThis->m_bIsSymlink)) { /*same for cut*/
216 DeleteMenu (hMenu, iItem, MF_BYPOSITION);
220 int indexShellMenu = 0;
222 // Create the AFS submenu using the allowed ID's.
223 HMENU hAfsMenu = CreatePopupMenu();
224 int indexAfsMenu = 0;
226 // Only enable the ACL menu item if a single directory is selected
227 int nSingleDirOnly = MF_GRAYED;
228 if (pThis->m_bDirSelected && (pThis->m_astrFileNames.GetSize() == 1))
229 nSingleDirOnly = MF_ENABLED;
230 ::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION | nSingleDirOnly, idCmdFirst + IDM_ACL_SET, GetMessageString(IDS_ACLS_ITEM));
232 // Volume/Partition submenu of the AFS submenu
233 HMENU hVolPartMenu = CreatePopupMenu();
234 int indexVolPartMenu = 0;
235 ::InsertMenu(hVolPartMenu, indexVolPartMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_VOLUME_PROPERTIES, GetMessageString(IDS_VOL_PART_PROPS_ITEM));
236 ::InsertMenu(hVolPartMenu, indexVolPartMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_VOLUMEPARTITION_UPDATENAMEIDTABLE, GetMessageString(IDS_VOL_PART_REFRESH_ITEM));
237 ::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION | MF_POPUP, (UINT)hVolPartMenu, GetMessageString(IDS_VOL_PART_ITEM));
239 // Mount Point submenu of the AFS submenu
240 HMENU hMountPointMenu = CreatePopupMenu();
241 int indexMountPointMenu = 0;
242 int nMountPointSelected = MF_GRAYED;
243 for (int n = pThis->m_astrFileNames.GetSize() - 1 ; n >= 0; n--) {
244 if ( IsMountPoint(pThis->m_astrFileNames[n]) ) {
245 nMountPointSelected = MF_ENABLED;
249 ::InsertMenu(hMountPointMenu, indexMountPointMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_MOUNTPOINT_SHOW, GetMessageString(IDS_MP_SHOW_ITEM));
250 ::InsertMenu(hMountPointMenu, indexMountPointMenu++, MF_STRING | MF_BYPOSITION | nMountPointSelected, idCmdFirst + IDM_MOUNTPOINT_REMOVE, GetMessageString(IDS_MP_REMOVE_ITEM));
251 ::InsertMenu(hMountPointMenu, indexMountPointMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_MOUNTPOINT_MAKE, GetMessageString(IDS_MP_MAKE_ITEM));
252 ::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION | MF_POPUP, (UINT)hMountPointMenu, GetMessageString(IDS_MOUNT_POINT_ITEM));
254 ::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_FLUSH, GetMessageString(IDS_FLUSH_FILE_DIR_ITEM));
255 ::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_FLUSH_VOLUME, GetMessageString(IDS_FLUSH_VOLUME_ITEM));
256 ::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_SHOW_SERVER, GetMessageString(IDS_SHOW_FILE_SERVERS_ITEM));
257 ::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_SHOWCELL, GetMessageString(IDS_SHOW_CELL_ITEM));
258 ::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_SERVER_STATUS, GetMessageString(IDS_SHOW_SERVER_STATUS_ITEM));
260 HMENU hSymbolicMenu = CreatePopupMenu();
261 int indexSymbolicMenu = 0;
262 int nSymlinkSelected = MF_GRAYED;
263 for (int n = pThis->m_astrFileNames.GetSize() - 1 ; n >= 0; n--) {
264 if ( IsSymlink(pThis->m_astrFileNames[n]) ) {
265 nSymlinkSelected = MF_ENABLED;
270 ::InsertMenu(hSymbolicMenu, indexSymbolicMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_SYMBOLICLINK_ADD, GetMessageString(IDS_SYMBOLICLINK_ADD));
271 ::InsertMenu(hSymbolicMenu, indexSymbolicMenu++, MF_STRING | MF_BYPOSITION | nSymlinkSelected, idCmdFirst + IDM_SYMBOLICLINK_SHOW, GetMessageString(IDS_SYMBOLICLINK_SHOW));
272 ::InsertMenu(hSymbolicMenu, indexSymbolicMenu++, MF_STRING | MF_BYPOSITION | nSymlinkSelected, idCmdFirst + IDM_SYMBOLICLINK_REMOVE, GetMessageString(IDS_SYMBOLICLINK_REMOVE));
273 ::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION | MF_POPUP, (UINT)hSymbolicMenu, GetMessageString(IDS_SYMBOLIC_LINK_ITEM));
275 // The Submounts menu has been removed because the AFS tray icon
276 // and control panel now support mapping drives directly to an AFS
279 //HMENU hSubmountMenu = CreatePopupMenu();
280 //int indexSubmountMenu = 0;
281 //::InsertMenu(hSubmountMenu, indexSubmountMenu++, MF_STRING | MF_BYPOSITION | nSingleDirOnly, idCmdFirst + IDM_SUBMOUNTS_CREATE, GetMessageString(IDS_SUBMOUNTS_CREATE_ITEM));
282 //::InsertMenu(hSubmountMenu, indexSubmountMenu++, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_SUBMOUNTS_EDIT, GetMessageString(IDS_SUBMOUNTS_EDIT_ITEM));
283 //::InsertMenu(hAfsMenu, indexAfsMenu++, MF_STRING | MF_BYPOSITION | MF_POPUP, (UINT)hSubmountMenu, GetMessageString(IDS_SUBMOUNTS_ITEM));
286 ::InsertMenu (hMenu, indexMenu + indexShellMenu++, MF_STRING | MF_BYPOSITION | MF_SEPARATOR, 0, TEXT(""));
288 // Add the AFS submenu to the shell's menu
289 ::InsertMenu(hMenu, indexMenu + indexShellMenu++, MF_STRING | MF_BYPOSITION | MF_POPUP, (UINT)hAfsMenu, GetMessageString(IDS_AFS_ITEM));
291 // Add a separator after us
292 ::InsertMenu (hMenu, indexMenu + indexShellMenu++, MF_STRING | MF_BYPOSITION | MF_SEPARATOR, 0, TEXT(""));
294 return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL,
295 (USHORT)indexAfsMenu + indexVolPartMenu + indexMountPointMenu + indexShellMenu + indexSymbolicMenu);
298 STDMETHODIMP CShellExt::XMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
300 METHOD_PROLOGUE(CShellExt, MenuExt);
302 if (HIWORD(lpici->lpVerb ))
307 CStringArray &files = pThis->m_astrFileNames;
309 switch (LOWORD(lpici->lpVerb))
311 case IDM_AUTHENTICATION: {
319 ASSERT(files.GetSize() == 1);
320 dlg.SetDir(files[0]);
325 case IDM_VOLUME_PROPERTIES: {
332 case IDM_VOLUMEPARTITION_UPDATENAMEIDTABLE:
336 case IDM_MOUNTPOINT_SHOW:
340 case IDM_MOUNTPOINT_REMOVE: {
341 int nChoice = ShowMessageBox(IDS_REALLY_DEL_MOUNT_POINTS, MB_ICONQUESTION | MB_YESNO, IDS_REALLY_DEL_MOUNT_POINTS);
342 if (nChoice == IDYES)
347 case IDM_MOUNTPOINT_MAKE: {
348 CMakeMountPointDlg dlg;
349 ASSERT(files.GetSize() == 1);
350 dlg.SetDir(files[0]);
359 case IDM_FLUSH_VOLUME:
363 case IDM_SHOW_SERVER:
371 case IDM_SERVER_STATUS: {
372 CServerStatusDlg dlg;
378 case IDM_SUBMOUNTS_EDIT: {
383 case IDM_SUBMOUNTS_CREATE: {
384 ASSERT(files.GetSize() == 1);
386 dlg.SetAddOnlyMode(files[0]);
391 case IDM_SYMBOLICLINK_REMOVE: {
392 if (files.GetSize()>1)
394 CString msg=files.GetAt(0);
396 if ((i=msg.ReverseFind('\\'))>0)
398 else if ((i=msg.ReverseFind(':'))>0)
399 msg=msg.Left(i+1)+"\\";
400 if (!SetCurrentDirectory(msg))
402 MessageBeep((UINT)-1);
403 ShowMessageBox(IDS_UNABLE_TO_SET_CURRENT_DIRECTORY,MB_OK,IDS_UNABLE_TO_SET_CURRENT_DIRECTORY);
407 if ((i=msg.ReverseFind('\\'))>0||((i=msg.ReverseFind(':'))>0))
408 msg=msg.Right(msg.GetLength()-i-1);
409 int nChoice = ShowMessageBox(IDS_REALLY_REMOVE_SYMLINK, MB_ICONQUESTION | MB_YESNO, IDS_REALLY_REMOVE_SYMLINK,msg);
410 if (nChoice == IDYES)
411 RemoveSymlink(files.GetAt(0));
415 case IDM_SYMBOLICLINK_ADD: {
416 CStringA msg(files.GetAt(0));
418 if ((i=msg.ReverseFind('\\'))>0)
420 else if ((i=msg.ReverseFind(':'))>0)
421 msg=msg.Left(i+1)+"\\";
422 CMakeSymbolicLinkDlg dlg;
428 case IDM_SYMBOLICLINK_SHOW:
432 case IDM_REMOVE_SYMLINK: {
433 if (files.GetSize()>1)
435 int nChoice = ShowMessageBox(IDS_REALLY_REMOVE_SYMLINK, MB_ICONQUESTION | MB_YESNO, IDS_REALLY_REMOVE_SYMLINK);
436 if (nChoice == IDYES)
437 RemoveSymlink(files.GetAt(0));
451 STDMETHODIMP CShellExt::XMenuExt::GetCommandString(UINT_PTR idCmd, UINT uType,
452 UINT* pwReserved, LPSTR pszName, UINT cchMax)
454 if (uType != GCS_HELPTEXT)
455 return NOERROR; // ?????????????????????????????????????????????????
459 AfxSetResourceHandle(theApp.m_hInstance);
463 case IDM_AUTHENTICATION:
464 nCmdStrID = ID_AUTHENTICATE;
468 nCmdStrID = ID_ACL_SET;
471 case IDM_VOLUME_PROPERTIES:
472 nCmdStrID = ID_VOLUME_PROPERTIES;
475 case IDM_VOLUMEPARTITION_UPDATENAMEIDTABLE:
476 nCmdStrID = ID_VOLUMEPARTITION_UPDATENAMEIDTABLE;
479 case IDM_MOUNTPOINT_SHOW:
480 nCmdStrID = ID_MOUNTPOINT_SHOW;
483 case IDM_MOUNTPOINT_REMOVE:
484 nCmdStrID = ID_MOUNTPOINT_REMOVE;
487 case IDM_MOUNTPOINT_MAKE:
488 nCmdStrID = ID_MOUNTPOINT_MAKE;
492 nCmdStrID = ID_FLUSH;
495 case IDM_FLUSH_VOLUME:
496 nCmdStrID = ID_VOLUME_FLUSH;
499 case IDM_SHOW_SERVER:
500 nCmdStrID = ID_WHEREIS;
504 nCmdStrID = ID_SHOWCELL;
507 case IDM_SERVER_STATUS:
508 nCmdStrID = ID_SERVER_STATUS;
511 case IDM_SYMBOLICLINK_ADD:
512 nCmdStrID = ID_SYMBOLICLINK_ADD;
515 case IDM_SYMBOLICLINK_SHOW:
516 nCmdStrID = ID_SYMBOLICLINK_SHOW;
519 case IDM_SYMBOLICLINK_REMOVE:
520 nCmdStrID = ID_SYMBOLICLINK_REMOVE;
523 case IDM_REMOVE_SYMLINK:
524 nCmdStrID= ID_REMOVE_SYMLINK;
534 LoadString (strMsg, nCmdStrID);
536 _tcsncpy((LPTSTR) pszName, strMsg, cchMax);
541 /////////////////////////////////////////////////////////////////////////////
542 // IUnknown for IShellExtInit
543 /////////////////////////////////////////////////////////////////////////////
544 STDMETHODIMP CShellExt::XShellInit::QueryInterface(REFIID riid, void** ppv)
546 METHOD_PROLOGUE(CShellExt, ShellInit);
548 return pThis->ExternalQueryInterface(&riid, ppv);
551 STDMETHODIMP_(ULONG) CShellExt::XShellInit::AddRef(void)
553 return ++nSERefCount;
556 STDMETHODIMP_(ULONG) CShellExt::XShellInit::Release(void)
564 /////////////////////////////////////////////////////////////////////////////
565 // IShellInit Functions
566 /////////////////////////////////////////////////////////////////////////////
567 STDMETHODIMP CShellExt::XShellInit::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdobj, HKEY hkeyProgID)
569 METHOD_PROLOGUE(CShellExt, ShellInit);
571 HRESULT hres = E_FAIL;
572 FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
575 // We must have a data object
576 if ((pdobj == NULL) && (pidlFolder == NULL))
580 // Use the given IDataObject to get a list of filenames (CF_HDROP)
581 hres = pdobj->GetData(&fmte, &medium);
586 int nNumFiles = DragQueryFile((HDROP)medium.hGlobal, 0xFFFFFFFF, NULL, 0);
590 pThis->m_bDirSelected = FALSE;
592 for (int ii = 0; ii < nNumFiles; ii++) {
595 // Get the size of the file name string
596 int nNameLen = DragQueryFile((HDROP)medium.hGlobal, ii, 0, 0);
598 // Make room for it in our string object
599 LPTSTR pszFileNameBuf = strFileName.GetBuffer(nNameLen + 1); // +1 for the terminating NULL
600 ASSERT(pszFileNameBuf);
603 DragQueryFile((HDROP)medium.hGlobal, ii, pszFileNameBuf, nNameLen + 1);
605 strFileName.ReleaseBuffer();
606 if (!IsPathInAfs(strFileName)) {
607 pThis->m_astrFileNames.RemoveAll();
610 pThis->m_bIsSymlink=IsSymlink(strFileName);
613 if (IsADir(strFileName))
614 pThis->m_bDirSelected = TRUE;
616 pThis->m_astrFileNames.Add(strFileName);
619 ReleaseStgMedium(&medium);
622 if ((pThis->m_astrFileNames.GetSize() == 0)&&(pidlFolder)) {
623 // if there are no valid files selected, try the folder background
624 IShellFolder *parentFolder = NULL;
626 TCHAR * szDisplayName = NULL;
628 hres = ::SHGetDesktopFolder(&parentFolder);
632 hres = parentFolder->GetDisplayNameOf(pidlFolder, SHGDN_NORMAL | SHGDN_FORPARSING, &name);
634 parentFolder->Release();
638 hres = StrRetToStr (&name, pidlFolder, &szDisplayName);
641 parentFolder->Release();
643 pThis->m_bDirSelected = TRUE;
644 CString strFileName = CString(szDisplayName);
645 if (IsPathInAfs(strFileName)) {
646 pThis->m_bIsSymlink=IsSymlink(strFileName);
647 pThis->m_astrFileNames.Add(strFileName);
649 CoTaskMemFree(szDisplayName);
652 if (pThis->m_astrFileNames.GetSize() > 0)
660 STDMETHODIMP CShellExt::XIconExt::QueryInterface(REFIID riid, void** ppv)
662 METHOD_PROLOGUE(CShellExt, IconExt);
663 return pThis->ExternalQueryInterface(&riid, ppv);
666 STDMETHODIMP_(ULONG) CShellExt::XIconExt::AddRef(void)
668 return ++nICRefCount;
671 STDMETHODIMP_(ULONG) CShellExt::XIconExt::Release(void)
680 /////////////////////////////////////////////////////////////////////////////
681 // IIconHandler Functions
682 /////////////////////////////////////////////////////////////////////////////
684 STDMETHODIMP CShellExt::XIconExt::GetOverlayInfo(LPWSTR pwszIconFile
685 ,int cchMax,int* pIndex,DWORD* pdwFlags)
687 if(IsBadWritePtr(pIndex, sizeof(int)))
689 if(IsBadWritePtr(pdwFlags, sizeof(DWORD)))
692 HMODULE hModule=GetModuleHandle(_T("shell32.dll"));
693 TCHAR szModule[MAX_PATH];
694 DWORD z=GetModuleFileName(hModule,szModule,sizeof(szModule));
696 MultiByteToWideChar( CP_ACP,0,szModule,-1,pwszIconFile,cchMax);
698 _tcsncpy(pwszIconFile, szModule, cchMax);
701 *pdwFlags = ISIOI_ICONFILE|ISIOI_ICONINDEX;
705 STDMETHODIMP CShellExt::XIconExt::GetPriority(int* pPriority)
707 if(IsBadWritePtr(pPriority, sizeof(int)))
713 STDMETHODIMP CShellExt::XIconExt::IsMemberOf(LPCWSTR pwszPath,DWORD dwAttrib)
715 TCHAR szPath[MAX_PATH];
717 _tcscpy(szPath, pwszPath);
719 WideCharToMultiByte( CP_ACP,0,pwszPath,-1,szPath,MAX_PATH,NULL,NULL);
721 if (IsSymlink(szPath) || IsMountPoint(szPath)) {
727 /* TOOL TIP INFO IMPLIMENTION */
729 STDMETHODIMP CShellExt::XToolTipExt::QueryInterface(REFIID riid, void** ppv)
731 METHOD_PROLOGUE(CShellExt, ToolTipExt);
732 return pThis->ExternalQueryInterface(&riid, ppv);
735 STDMETHODIMP_(ULONG) CShellExt::XToolTipExt::AddRef(void)
737 return ++nTPRefCount;
740 STDMETHODIMP_(ULONG) CShellExt::XToolTipExt::Release(void)
748 STDMETHODIMP CShellExt::XToolTipExt::GetInfoTip(DWORD dwFlags, LPWSTR *ppwszTip)
750 METHOD_PROLOGUE(CShellExt, ToolTipExt);
752 if (!IsSymlink(pThis->m_szFile))
758 // dwFlags is currently unused.
759 *ppwszTip = (WCHAR*) (pThis->m_pAlloc)->Alloc((1+lstrlen(pThis->m_szFile))*sizeof(WCHAR));
762 wcscpy(*ppwszTip, (WCHAR*)T2OLE(pThis->m_szFile));
767 STDMETHODIMP CShellExt::XToolTipExt::GetInfoFlags(LPDWORD pdwFlags)
772 ////////// IPersistFile
773 /////// PersistFileExt
775 STDMETHODIMP CShellExt::XPersistFileExt::QueryInterface(REFIID riid, void** ppv)
777 METHOD_PROLOGUE(CShellExt, PersistFileExt);
778 return pThis->ExternalQueryInterface(&riid, ppv);
781 STDMETHODIMP_(ULONG) CShellExt::XPersistFileExt::AddRef(void)
783 return ++nXPRefCount;
786 STDMETHODIMP_(ULONG) CShellExt::XPersistFileExt::Release(void)
794 STDMETHODIMP CShellExt::XPersistFileExt::Load(LPCOLESTR wszFile, DWORD dwMode)
796 METHOD_PROLOGUE(CShellExt, PersistFileExt);
798 _tcscpy(pThis->m_szFile, OLE2T((WCHAR*)wszFile));
802 STDMETHODIMP CShellExt::XPersistFileExt::GetClassID(LPCLSID)
807 STDMETHODIMP CShellExt::XPersistFileExt::IsDirty(VOID)
812 STDMETHODIMP CShellExt::XPersistFileExt::Save(LPCOLESTR, BOOL)
817 STDMETHODIMP CShellExt::XPersistFileExt::SaveCompleted(LPCOLESTR)
822 STDMETHODIMP CShellExt::XPersistFileExt::GetCurFile(LPOLESTR FAR*)