Windows: Explorer Shell extensions
authorStefan Kueng <tortoisesvn@gmail.com>
Thu, 15 Sep 2011 04:57:23 +0000 (00:57 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Thu, 15 Sep 2011 18:24:35 +0000 (11:24 -0700)
This patchset implements a broad range of improvements to
the explorer shell.  There is still a significant amount of
work to be done.

 * Remove the 'cut' and 'delete' options from the
   context menu if the selected object is a symlink
   or mount point.  This is performed in a language
   neutral manner.

 * Add AFS Property page to the property sheet

 * Add AFS Volume Property page

 * Add AFS ACL Property page

 * force the linker to add the common-controls V6 manifest and
   define ISOLATION_AWARE_ENABLED to make property sheets
   work for the shell extension dll

 * Fix the InfoTip handler.  Display symlink and mount point
   target strings

Stefan Kueng was assisted by Jeffrey Altman.

Change-Id: I6b7c4506026270a5408d90cdc5358864e3fb44c3
Reviewed-on: http://gerrit.openafs.org/5430
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>

31 files changed:
src/WINNT/client_exp/NTMakefile
src/WINNT/client_exp/PropACL.cpp [new file with mode: 0644]
src/WINNT/client_exp/PropACL.h [new file with mode: 0644]
src/WINNT/client_exp/PropBase.cpp [new file with mode: 0644]
src/WINNT/client_exp/PropBase.h [new file with mode: 0644]
src/WINNT/client_exp/PropFile.cpp [new file with mode: 0644]
src/WINNT/client_exp/PropFile.h [new file with mode: 0644]
src/WINNT/client_exp/PropVolume.cpp [new file with mode: 0644]
src/WINNT/client_exp/PropVolume.h [new file with mode: 0644]
src/WINNT/client_exp/add_acl_entry_dlg.cpp
src/WINNT/client_exp/add_acl_entry_dlg.h
src/WINNT/client_exp/afs_shl_ext.cpp
src/WINNT/client_exp/gui2fs.cpp
src/WINNT/client_exp/gui2fs.h
src/WINNT/client_exp/lang/de_DE/afs_shl_ext.rc
src/WINNT/client_exp/lang/en_US/afs_shl_ext.rc
src/WINNT/client_exp/lang/es_ES/afs_shl_ext.rc
src/WINNT/client_exp/lang/ja_JP/afs_shl_ext.rc
src/WINNT/client_exp/lang/ko_KR/afs_shl_ext.rc
src/WINNT/client_exp/lang/pt_BR/afs_shl_ext.rc
src/WINNT/client_exp/lang/zh_CN/afs_shl_ext.rc
src/WINNT/client_exp/lang/zh_TW/afs_shl_ext.rc
src/WINNT/client_exp/make_mount_point_dlg.cpp
src/WINNT/client_exp/make_mount_point_dlg.h
src/WINNT/client_exp/make_symbolic_link_dlg.cpp
src/WINNT/client_exp/resource.h
src/WINNT/client_exp/set_afs_acl.h
src/WINNT/client_exp/shell_ext.cpp
src/WINNT/client_exp/shell_ext.h
src/WINNT/client_exp/stdafx.h
src/config/NTDllmap.txt

index 4dae2d1..e7c9830 100644 (file)
@@ -55,6 +55,10 @@ DLLOBJS =\
        $(OUT)\volumeinfo.obj \
        $(OUT)\make_symbolic_link_dlg.obj \
         $(OUT)\symlinks_dlg.obj \
+        $(OUT)\propbase.obj \
+        $(OUT)\propfile.obj \
+        $(OUT)\propacl.obj \
+        $(OUT)\propvolume.obj \
        $(OUT)\AFS_component_version_number.obj
 
 AFSD = ..\afsd
@@ -72,14 +76,15 @@ DLLSDKLIBS =\
     mpr.lib
 
 DLLLIBS =\
+        $(DESTDIR)\lib\afs\afsauth.lib \
        $(DESTDIR)\lib\afsrpc.lib \
        $(DESTDIR)\lib\afsauthent.lib \
-       $(DESTDIR)\lib\libafsconf.lib \
        $(DESTDIR)\lib\libosi.lib \
         $(DESTDIR)\lib\afs\afsreg.lib  \
        $(DESTDIR)\lib\afs\TaLocaleU.lib \
-       $(DESTDIR)\lib\afs\afsutil.lib \
-        $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afs\mtafsutil.lib \
+        $(DESTDIR)\lib\afsroken.lib \
+        $(DESTDIR)\lib\libafsconf.lib
 
 $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
        $(DLLCONLINK) /DEF:afs_shl_ext.def $(DLLSDKLIBS)
diff --git a/src/WINNT/client_exp/PropACL.cpp b/src/WINNT/client_exp/PropACL.cpp
new file mode 100644 (file)
index 0000000..fa0c223
--- /dev/null
@@ -0,0 +1,310 @@
+// PropFile.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "PropACL.h"
+
+extern "C" {
+#include <afs/param.h>
+#include <afs/stds.h>
+}
+
+#include "WINNT\talocale.h"
+#include "afs_shl_ext.h"
+#include "set_afs_acl.h"
+#include "clear_acl_dlg.h"
+#include "add_acl_entry_dlg.h"
+#include "copy_acl_dlg.h"
+#include "gui2fs.h"
+#include "msgs.h"
+
+
+BOOL CPropACL::PropPageProc( HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam )
+{
+    switch(uMessage)
+    {
+    case WM_INITDIALOG:
+        {
+            CPropACL * sheetpage = (CPropACL*) ((LPPROPSHEETPAGE) lParam)->lParam;
+            SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) sheetpage);
+            sheetpage->SetHwnd(hwnd);
+            AfxSetResourceHandle(m_hInst);
+
+            CString sText;
+
+            if(filenames.GetCount() > 1) {
+            // multiple items selected
+            LoadString(sText, IDS_PROP_MULTIPLEITEMS);
+            SetDlgItemText(hwnd, IDC_PROP_FILENAME, sText);
+
+            EnablePermChanges(FALSE);
+            EnableWindow(GetDlgItem(m_hwnd, IDC_ADD), FALSE);
+            EnableWindow(GetDlgItem(m_hwnd, IDC_COPY), FALSE);
+            } else {
+            SetDlgItemText(hwnd, IDC_PROP_FILENAME, filenames.GetAt(0));
+
+            if (GetRights(filenames.GetAt(0), m_Normal, m_Negative)) {
+                EnablePermChanges(FALSE);
+
+                int tabstops[2] = {10,58};
+                SendDlgItemMessage(hwnd, IDC_NORMAL_RIGHTS, LB_SETTABSTOPS, 2, (LPARAM)&tabstops);
+                FillACLList();
+            }
+
+            }
+            return TRUE;
+        }
+        break;
+    case WM_NOTIFY:
+        {
+            LPNMHDR point = (LPNMHDR)lParam;
+            int code = point->code;
+            BOOL bRet = FALSE;
+            switch (code)
+            {
+            case PSN_APPLY:
+                {
+                    SaveACL(CString(), filenames.GetAt(0), m_Normal, m_Negative);
+                    // Return PSNRET_NOERROR to allow the sheet to close if the user clicked OK.
+                    SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
+                }
+                break;
+            }
+            SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, FALSE);
+            return bRet;
+        }
+        break;
+    case WM_COMMAND:
+        switch (HIWORD(wParam))
+        {
+        case LBN_SELCHANGE:
+            OnSelChange();
+            return TRUE;
+            break;
+        case BN_CLICKED:
+            switch (LOWORD(wParam))
+            {
+            case IDC_ADD:
+                {
+                    CAddAclEntryDlg dlg;
+
+                    dlg.SetAclDlg(this);
+
+                    if (dlg.DoModal() == IDCANCEL)
+                        return FALSE;
+
+                    OnNothingSelected();
+
+                    CString name = dlg.GetName();
+                    CString rights = dlg.GetRights();
+                    BOOL bNormal = dlg.IsNormal();
+
+                    if (bNormal) {
+                        m_Normal.Add(name);
+                        m_Normal.Add(rights);
+                    } else {
+                        m_Negative.Add(name);
+                        m_Negative.Add(rights);
+                    }
+
+                    FillACLList();
+                    ShowRights(rights);
+                    EnablePermChanges(TRUE);
+                    return TRUE;
+                }
+            case IDC_COPY:
+                {
+                    CCopyAclDlg dlg;
+
+                    dlg.SetFromDir(filenames.GetAt(0));
+
+                    if (dlg.DoModal() == IDCANCEL)
+                        return FALSE;
+
+                    CString strToDir = dlg.GetToDir();
+                    BOOL bClear = dlg.GetClear();
+
+                    CopyACL(strToDir, m_Normal, m_Negative, bClear);
+                    return TRUE;
+                }
+            case IDC_CLEAN:
+                CleanACL(filenames);
+                return TRUE;
+            case IDC_READ:
+            case IDC_WRITE:
+            case IDC_LOOKUP:
+            case IDC_DELETE:
+            case IDC_INSERT:
+            case IDC_LOCK:
+            case IDC_ADMINISTER:
+                OnPermChange();
+                return TRUE;
+            }
+            break;
+        }
+        break;
+    }
+
+    return FALSE;
+}
+
+void CPropACL::FillACLList()
+{
+    SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_RESETCONTENT, 0, 0);
+    int i;
+    for (i = 0; i < m_Normal.GetSize(); i += 2) {
+        CString sText = _T("+\t") + m_Normal[i + 1] + _T("\t") + m_Normal[i];
+        SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR)sText);
+    }
+
+    for (i = 0; i < m_Negative.GetSize(); i += 2) {
+        CString sText = _T("+\t") + m_Negative[i + 1] + _T("\t") + m_Negative[i];
+        SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR)sText);
+    }
+}
+
+void CPropACL::ShowRights(const CString& strRights)
+{
+    SendDlgItemMessage(m_hwnd, IDC_READ, BM_SETCHECK, (strRights.Find(_T("r")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_WRITE, BM_SETCHECK, (strRights.Find(_T("w")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_LOOKUP, BM_SETCHECK, (strRights.Find(_T("l")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_DELETE, BM_SETCHECK, (strRights.Find(_T("d")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_INSERT, BM_SETCHECK, (strRights.Find(_T("i")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_LOCK, BM_SETCHECK, (strRights.Find(_T("k")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_ADMINISTER, BM_SETCHECK, (strRights.Find(_T("a")) == -1) ? UNCHECKED : CHECKED, 0);
+}
+
+CString CPropACL::MakeRightsString()
+{
+    CString str;
+
+    if (SendDlgItemMessage(m_hwnd, IDC_READ, BM_GETCHECK, 0,0) == CHECKED)
+        str += _T("r");
+    if (SendDlgItemMessage(m_hwnd, IDC_LOOKUP, BM_GETCHECK, 0,0) == CHECKED)
+        str += _T("l");
+    if (SendDlgItemMessage(m_hwnd, IDC_INSERT, BM_GETCHECK, 0,0) == CHECKED)
+        str += _T("i");
+    if (SendDlgItemMessage(m_hwnd, IDC_DELETE, BM_GETCHECK, 0,0) == CHECKED)
+        str += _T("d");
+    if (SendDlgItemMessage(m_hwnd, IDC_WRITE, BM_GETCHECK, 0,0) == CHECKED)
+        str += _T("w");
+    if (SendDlgItemMessage(m_hwnd, IDC_LOCK, BM_GETCHECK, 0,0) == CHECKED)
+        str += _T("k");
+    if (SendDlgItemMessage(m_hwnd, IDC_ADMINISTER, BM_GETCHECK, 0,0) == CHECKED)
+        str += _T("a");
+
+    return str;
+}
+
+void CPropACL::EnablePermChanges(BOOL bEnable)
+{
+    EnableWindow(GetDlgItem(m_hwnd, IDC_READ), bEnable);
+    EnableWindow(GetDlgItem(m_hwnd, IDC_WRITE), bEnable);
+    EnableWindow(GetDlgItem(m_hwnd, IDC_LOOKUP), bEnable);
+    EnableWindow(GetDlgItem(m_hwnd, IDC_DELETE), bEnable);
+    EnableWindow(GetDlgItem(m_hwnd, IDC_INSERT), bEnable);
+    EnableWindow(GetDlgItem(m_hwnd, IDC_LOCK), bEnable);
+    EnableWindow(GetDlgItem(m_hwnd, IDC_ADMINISTER), bEnable);
+}
+
+void CPropACL::OnNothingSelected()
+{
+    SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_SETSEL, FALSE, (LPARAM)-1);
+
+    ShowRights(_T(""));                                // Show no rights
+    EnablePermChanges(FALSE);          // Allow no rights changes
+    EnableWindow(GetDlgItem(m_hwnd, IDC_REMOVE), FALSE);
+}
+
+void CPropACL::OnSelection()
+{
+    EnablePermChanges(TRUE);
+    EnableWindow(GetDlgItem(m_hwnd, IDC_REMOVE), TRUE);
+}
+
+void CPropACL::OnSelChange()
+{
+    int nNum = (int)SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_GETSELCOUNT, 0, 0);
+    if (nNum != 1) {
+        ShowRights(_T(""));
+        EnablePermChanges(FALSE);
+        return;
+    }
+
+    int nSel = 0;
+    SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_GETSELITEMS, 1, (LPARAM)&nSel);
+
+    CString strRights;
+    if (nSel >= m_Normal.GetCount()) {
+        nSel -= (int)m_Normal.GetCount();
+        strRights = m_Negative[(nSel * 2) + 1];
+    } else {
+        strRights = m_Normal[(nSel * 2) + 1];
+    }
+
+    ShowRights(strRights);
+    OnSelection();
+}
+
+void CPropACL::OnRemove()
+{
+    int nNum = (int)SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_GETSELCOUNT, 0, 0);
+    if (nNum < 0) {
+        ASSERT(FALSE);
+        return;
+    }
+
+    int *pIndexes = new int[nNum];
+    SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_GETSELITEMS, nNum, (LPARAM)pIndexes);
+
+    for (int i = nNum - 1; i >= 0; i--) {
+        SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_DELETESTRING, pIndexes[i], 0);
+
+        if (pIndexes[i] >= m_Normal.GetCount()) {
+            pIndexes[i] -= (int)m_Normal.GetCount();
+            m_Negative.RemoveAt((pIndexes[i] * 2), 2);
+        } else {
+            m_Normal.RemoveAt((pIndexes[i] * 2), 2);
+        }
+    }
+
+    delete [] pIndexes;
+
+    OnNothingSelected();
+}
+
+BOOL CPropACL::IsNameInUse( BOOL bNormal, const CString& strName )
+{
+    if (bNormal) {
+        for (int i = 0; i < m_Normal.GetSize(); i += 2)
+            if (m_Normal[i] == strName)
+                return TRUE;
+        return FALSE;
+    }
+
+    for (int i = 0; i < m_Negative.GetSize(); i += 2)
+        if (m_Negative[i] == strName)
+            return TRUE;
+    return FALSE;
+}
+
+void CPropACL::OnPermChange()
+{
+    int nSel = 0;
+    SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_GETSELITEMS, 1, (LPARAM)&nSel);
+
+    CString str = MakeRightsString();
+    if (nSel >= m_Normal.GetCount()) {
+        nSel -= (int)m_Normal.GetCount();
+        m_Negative[(2 * nSel) + 1] = str;
+        str += _T("\t") + m_Negative[(2 * nSel)];
+    } else {
+        m_Normal[(2 * nSel) + 1] = str;
+        str += _T("\t") + m_Normal[(2 * nSel)];
+    }
+
+    FillACLList();
+    SendDlgItemMessage(m_hwnd, IDC_NORMAL_RIGHTS, LB_SETSEL, TRUE, nSel);
+
+    SendMessage(GetParent(m_hwnd), PSM_CHANGED, (WPARAM)m_hwnd, 0);
+}
diff --git a/src/WINNT/client_exp/PropACL.h b/src/WINNT/client_exp/PropACL.h
new file mode 100644 (file)
index 0000000..0a58df8
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma once
+#include "resource.h"
+#include "PropBase.h"
+#include "add_acl_entry_dlg.h"
+
+
+class CPropACL : public PropertyPage, public CSetACLInterface
+{
+public:
+    CPropACL(const CStringArray& filenames) : PropertyPage(filenames){}
+
+    virtual BOOL PropPageProc(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
+
+    virtual BOOL IsNameInUse(BOOL bNormal, const CString& strName);
+
+private:
+    void ShowRights(const CString& strRights);
+    CString MakeRightsString();
+    void EnablePermChanges(BOOL bEnable);
+    void OnNothingSelected();
+    void OnSelection();
+    void OnSelChange();
+    void FillACLList();
+    void OnRemove();
+    void OnPermChange();
+
+    CStringArray m_Normal, m_Negative;
+};
diff --git a/src/WINNT/client_exp/PropBase.cpp b/src/WINNT/client_exp/PropBase.cpp
new file mode 100644 (file)
index 0000000..a35b54d
--- /dev/null
@@ -0,0 +1,21 @@
+#include "stdafx.h"
+#include "PropBase.h"
+
+PropertyPage::PropertyPage(const CStringArray& newFilenames)
+{
+    filenames.Copy(newFilenames);
+}
+
+PropertyPage::~PropertyPage(void)
+{
+}
+
+void PropertyPage::SetHwnd(HWND newHwnd)
+{
+    m_hwnd = newHwnd;
+}
+
+BOOL PropertyPage::PropPageProc( HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam )
+{
+    return FALSE;
+}
diff --git a/src/WINNT/client_exp/PropBase.h b/src/WINNT/client_exp/PropBase.h
new file mode 100644 (file)
index 0000000..ffc5c66
--- /dev/null
@@ -0,0 +1,19 @@
+#pragma once
+#include "resource.h"
+
+class PropertyPage
+{
+public:
+    PropertyPage(const CStringArray& filenames);
+    virtual ~PropertyPage();
+
+    virtual void SetHwnd(HWND hwnd);
+    virtual BOOL PropPageProc(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
+
+    HWND m_hwnd;
+    HINSTANCE m_hInst;
+    CStringArray filenames;
+    BOOL m_bIsSymlink;         // is symbolic link!
+    BOOL m_bIsMountpoint;      // is mount point!
+    BOOL m_bIsDir;              // is a directory
+};
diff --git a/src/WINNT/client_exp/PropFile.cpp b/src/WINNT/client_exp/PropFile.cpp
new file mode 100644 (file)
index 0000000..9002369
--- /dev/null
@@ -0,0 +1,239 @@
+// PropFile.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "PropFile.h"
+
+extern "C" {
+#include <afs/param.h>
+#include <afs/stds.h>
+}
+
+#include "WINNT\talocale.h"
+#include "afs_shl_ext.h"
+#include "set_afs_acl.h"
+#include "clear_acl_dlg.h"
+#include "add_acl_entry_dlg.h"
+#include "copy_acl_dlg.h"
+#include "make_mount_point_dlg.h"
+#include "make_symbolic_link_dlg.h"
+#include "gui2fs.h"
+#include "msgs.h"
+
+
+BOOL CPropFile::PropPageProc( HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam )
+{
+    switch(uMessage)
+    {
+    case WM_INITDIALOG:
+        {
+            CPropFile * sheetpage = (CPropFile*) ((LPPROPSHEETPAGE) lParam)->lParam;
+            SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) sheetpage);
+            sheetpage->SetHwnd(hwnd);
+            AfxSetResourceHandle(m_hInst);
+
+            CString sText;
+
+            if(filenames.GetCount() > 1) {
+                // multiple items selected
+                LoadString(sText, IDS_PROP_MULTIPLEITEMS);
+                SetDlgItemText(hwnd, IDC_PROP_TYPE, sText);
+            } else {
+                if (m_bIsDir)
+                    LoadString(sText, IDS_PROP_TYPEDIRECTORY);
+                else
+                    LoadString(sText, IDS_PROP_TYPEFILE);
+                if (m_bIsMountpoint)
+                    LoadString(sText, IDS_PROP_TYPEMOUNTPOINT);
+                if (m_bIsSymlink)
+                    LoadString(sText, IDS_PROP_TYPESYMLINK);
+                SetDlgItemText(hwnd, IDC_PROP_TYPE, sText);
+            }
+            if (m_bIsMountpoint) {
+                ShowWindow(GetDlgItem(m_hwnd, IDC_REMOVEMOUNTPOINT), SW_SHOW);
+                ShowWindow(GetDlgItem(m_hwnd, IDC_SYMLINK_LABEL), SW_HIDE);
+            }
+            if (m_bIsSymlink) {
+                ShowWindow(GetDlgItem(m_hwnd, IDC_MOUNTPOINT_LABEL), SW_HIDE);
+            }
+            CString user, group, other, suid;
+            GetUnixModeBits(filenames.GetAt(0), user, group, other, suid);
+            ShowUnixMode(user, group, other, suid);
+
+            if (filenames.GetCount() == 1) {
+                SetDlgItemText(hwnd, IDC_PROP_FILENAME, filenames.GetAt(0));
+                if (!GetFID(filenames.GetAt(0), sText, TRUE))
+                    sText = _T("(unknown)");
+                SetDlgItemText(hwnd, IDC_PROP_FID, sText);
+                sText = GetCellName(filenames.GetAt(0));
+                m_cellName = sText;
+                SetDlgItemText(hwnd, IDC_PROP_CELL, sText);
+                sText = GetServer(filenames.GetAt(0));
+                m_volName = sText;
+                SetDlgItemText(hwnd, IDC_PROP_FILESERVER, sText);
+                sText = GetOwner(filenames.GetAt(0));
+                SetDlgItemText(hwnd, IDC_PROP_OWNER, sText);
+                sText = GetGroup(filenames.GetAt(0));
+                SetDlgItemText(hwnd, IDC_PROP_GROUP, sText);
+
+                if (!m_bIsMountpoint && !m_bIsSymlink)
+                    ShowWindow(GetDlgItem(m_hwnd, IDC_EDIT), SW_HIDE);
+
+                if (!m_bIsMountpoint && m_bIsSymlink)
+                    ShowWindow(GetDlgItem(m_hwnd, IDC_REMOVESYMLINK), SW_SHOW);
+
+                if (m_bIsMountpoint){
+                    sText = GetMountpoint(filenames.GetAt(0));
+                    sText = sText.Mid(sText.Find('\t')+1);
+                    SetDlgItemText(hwnd, IDC_PROP_SMINFO, sText);
+                }
+                if (m_bIsSymlink){
+                    sText = GetSymlink(filenames.GetAt(0));
+                    sText = sText.Mid(sText.Find('\t')+1);
+                    SetDlgItemText(hwnd, IDC_PROP_SMINFO, sText);
+                }
+            }
+            return TRUE;
+        }
+        break;
+    case WM_NOTIFY:
+        {
+            LPNMHDR point = (LPNMHDR)lParam;
+            int code = point->code;
+            BOOL bRet = FALSE;
+            switch (code)
+            {
+            case PSN_APPLY:
+                {
+                    CString user, group, other, suid;
+                    MakeUnixModeString(user, group, other, suid);
+                    SetUnixModeBits(filenames, user, group, other, suid);
+                    // Return PSNRET_NOERROR to allow the sheet to close if the user clicked OK.
+                    SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
+                }
+                break;
+            }
+            SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, FALSE);
+            return bRet;
+        }
+        break;
+    case WM_COMMAND:
+        switch (HIWORD(wParam))
+        {
+        case BN_CLICKED:
+            switch (LOWORD(wParam))
+            {
+            case IDC_FLUSH:
+                Flush(filenames);
+                return TRUE;
+            case IDC_REMOVESYMLINK:
+                {
+                    int nChoice = ShowMessageBox(IDS_REALLY_REMOVE_SYMLINK, MB_ICONQUESTION | MB_YESNO, IDS_REALLY_REMOVE_SYMLINK);
+                    if (nChoice == IDYES)
+                        RemoveSymlink(filenames.GetAt(0));
+                    return TRUE;
+                }
+            case IDC_REMOVEMOUNTPOINT:
+                {
+                    int nChoice = ShowMessageBox(IDS_REALLY_DEL_MOUNT_POINTS, MB_ICONQUESTION | MB_YESNO, IDS_REALLY_DEL_MOUNT_POINTS);
+                    if (nChoice == IDYES)
+                        RemoveMount(filenames);
+                    return TRUE;
+                }
+            case IDC_EDIT:
+                {
+                    if (m_bIsMountpoint){
+                        CMakeMountPointDlg dlg;
+                        dlg.SetDir(filenames.GetAt(0));
+                        dlg.SetCell(m_cellName);
+                        dlg.SetVol(m_volName);
+                        dlg.DoModal();
+                    }
+                    if (m_bIsSymlink){
+                        CMakeSymbolicLinkDlg dlg;
+                        CStringA msg(filenames.GetAt(0));
+                        int i;
+                        if ((i=msg.ReverseFind('\\'))>0)
+                            msg=msg.Left(i+1);
+                        else if ((i=msg.ReverseFind(':'))>0)
+                            msg=msg.Left(i+1)+"\\";
+                        dlg.Setbase(msg);
+                        dlg.m_strDir = filenames.GetAt(0);
+                        dlg.m_strName = GetSymlink(filenames.GetAt(0));
+                        dlg.DoModal();
+                    }
+                }
+            case IDC_ATTR_USER_READ:
+            case IDC_ATTR_USER_WRITE:
+            case IDC_ATTR_USER_EXECUTE:
+            case IDC_ATTR_GROUP_READ:
+            case IDC_ATTR_GROUP_WRITE:
+            case IDC_ATTR_GROUP_EXECUTE:
+            case IDC_ATTR_OTHER_READ:
+            case IDC_ATTR_OTHER_WRITE:
+            case IDC_ATTR_OTHER_EXECUTE:
+                SendMessage(GetParent(m_hwnd), PSM_CHANGED, (WPARAM)m_hwnd, 0);     // enable the "apply" button
+                return TRUE;
+            }
+            break;
+        }
+        break;
+    }
+
+    return FALSE;
+}
+
+void CPropFile::ShowUnixMode(const CString& strUserRights, const CString& strGroupRights, const CString& strOtherRights, const CString& strSuidRights)
+{
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_USER_READ, BM_SETCHECK, (strUserRights.Find(_T("r")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_USER_WRITE, BM_SETCHECK, (strUserRights.Find(_T("w")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_USER_EXECUTE, BM_SETCHECK, (strUserRights.Find(_T("x")) == -1) ? UNCHECKED : CHECKED, 0);
+
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_GROUP_READ, BM_SETCHECK, (strGroupRights.Find(_T("r")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_GROUP_WRITE, BM_SETCHECK, (strGroupRights.Find(_T("w")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_GROUP_EXECUTE, BM_SETCHECK, (strGroupRights.Find(_T("x")) == -1) ? UNCHECKED : CHECKED, 0);
+
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_OTHER_READ, BM_SETCHECK, (strOtherRights.Find(_T("r")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_OTHER_WRITE, BM_SETCHECK, (strOtherRights.Find(_T("w")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_OTHER_EXECUTE, BM_SETCHECK, (strOtherRights.Find(_T("x")) == -1) ? UNCHECKED : CHECKED, 0);
+
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_SUID_UID, BM_SETCHECK, (strSuidRights.Find(_T("s")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_SUID_GID, BM_SETCHECK, (strSuidRights.Find(_T("g")) == -1) ? UNCHECKED : CHECKED, 0);
+    SendDlgItemMessage(m_hwnd, IDC_ATTR_SUID_VTX, BM_SETCHECK, (strSuidRights.Find(_T("v")) == -1) ? UNCHECKED : CHECKED, 0);
+}
+
+void CPropFile::MakeUnixModeString(CString& userRights, CString& groupRights, CString& otherRights, CString& suidRights)
+{
+    userRights.Empty();
+    groupRights.Empty();
+    otherRights.Empty();
+    suidRights.Empty();
+
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_USER_READ, BM_GETCHECK, 0,0) == CHECKED)
+        userRights += _T("r");
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_USER_WRITE, BM_GETCHECK, 0,0) == CHECKED)
+        userRights += _T("w");
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_USER_EXECUTE, BM_GETCHECK, 0,0) == CHECKED)
+        userRights += _T("x");
+
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_GROUP_READ, BM_GETCHECK, 0,0) == CHECKED)
+        groupRights += _T("r");
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_GROUP_WRITE, BM_GETCHECK, 0,0) == CHECKED)
+        groupRights += _T("w");
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_GROUP_EXECUTE, BM_GETCHECK, 0,0) == CHECKED)
+        groupRights += _T("x");
+
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_OTHER_READ, BM_GETCHECK, 0,0) == CHECKED)
+        otherRights += _T("r");
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_OTHER_WRITE, BM_GETCHECK, 0,0) == CHECKED)
+        otherRights += _T("w");
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_OTHER_EXECUTE, BM_GETCHECK, 0,0) == CHECKED)
+        otherRights += _T("x");
+
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_SUID_UID, BM_GETCHECK, 0,0) == CHECKED)
+        suidRights += _T("s");
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_SUID_GID, BM_GETCHECK, 0,0) == CHECKED)
+        suidRights += _T("g");
+    if (SendDlgItemMessage(m_hwnd, IDC_ATTR_SUID_VTX, BM_GETCHECK, 0,0) == CHECKED)
+        suidRights += _T("v");
+}
diff --git a/src/WINNT/client_exp/PropFile.h b/src/WINNT/client_exp/PropFile.h
new file mode 100644 (file)
index 0000000..2a0b1da
--- /dev/null
@@ -0,0 +1,19 @@
+#pragma once
+#include "resource.h"
+#include "PropBase.h"
+
+class CPropFile : public PropertyPage
+{
+public:
+    CPropFile(const CStringArray& filenames) : PropertyPage(filenames){}
+
+    virtual BOOL PropPageProc(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
+
+private:
+    void ShowUnixMode(const CString& strUserRights, const CString& strGroupRights, const CString& strOtherRights, const CString& strSuidRights);
+    void EnablePermChanges(BOOL bEnable);
+    void MakeUnixModeString(CString& userRights, CString& groupRights, CString& otherRights, CString& suidRights);
+
+    CString     m_cellName;
+    CString     m_volName;
+};
diff --git a/src/WINNT/client_exp/PropVolume.cpp b/src/WINNT/client_exp/PropVolume.cpp
new file mode 100644 (file)
index 0000000..b4bfdac
--- /dev/null
@@ -0,0 +1,116 @@
+// PropFile.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "PropVolume.h"
+#include <shlwapi.h>
+
+extern "C" {
+#include <afs/param.h>
+#include <afs/stds.h>
+}
+
+#include "WINNT\talocale.h"
+#include "afs_shl_ext.h"
+#include "gui2fs.h"
+#include "msgs.h"
+
+
+BOOL CPropVolume::PropPageProc( HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam )
+{
+    switch(uMessage)
+    {
+    case WM_INITDIALOG:
+        {
+            CPropVolume * sheetpage = (CPropVolume*) ((LPPROPSHEETPAGE) lParam)->lParam;
+            SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) sheetpage);
+            sheetpage->SetHwnd(hwnd);
+            AfxSetResourceHandle(m_hInst);
+
+            CString sText;
+
+            CString user, group, other, suid;
+            GetUnixModeBits(filenames.GetAt(0), user, group, other, suid);
+
+            if(filenames.GetCount() > 1) {
+                // multiple items selected
+                LoadString(sText, IDS_PROP_MULTIPLEITEMS);
+                SetDlgItemText(hwnd, IDC_PROP_FILENAME, sText);
+            } else {
+                SetDlgItemText(hwnd, IDC_PROP_VOLUMENAME, filenames.GetAt(0));
+                if (!GetFID(filenames.GetAt(0), sText, TRUE))
+                    sText = _T("(unknown)");
+                SetDlgItemText(hwnd, IDC_PROP_FID, sText);
+                sText = GetCellName(filenames.GetAt(0));
+                SetDlgItemText(hwnd, IDC_PROP_CELL, sText);
+                sText = GetServer(filenames.GetAt(0));
+                SetDlgItemText(hwnd, IDC_PROP_FILESERVER, sText);
+                sText = GetOwner(filenames.GetAt(0));
+                SetDlgItemText(hwnd, IDC_PROP_OWNER, sText);
+                sText = GetGroup(filenames.GetAt(0));
+                SetDlgItemText(hwnd, IDC_PROP_GROUP, sText);
+
+                TCHAR buf[100];
+                CVolInfo volInfo;
+                GetVolumeInfo(filenames.GetAt(0), volInfo);
+                SetDlgItemText(hwnd, IDC_PROP_VOLUMENAME, volInfo.m_strName);
+                sText.Format(_T("%ld bytes"), volInfo.m_nPartSize - volInfo.m_nPartFree);
+                SetDlgItemText(hwnd, IDC_USEDBYTES, sText);
+                StrFormatByteSize64(volInfo.m_nPartSize - volInfo.m_nPartFree, buf, 100);
+                SetDlgItemText(hwnd, IDC_USEDBYTES2, buf);
+                sText.Format(_T("%ld bytes"), volInfo.m_nPartFree);
+                SetDlgItemText(hwnd, IDC_FREEBYTES, sText);
+                StrFormatByteSize64(volInfo.m_nPartFree, buf, 100);
+                SetDlgItemText(hwnd, IDC_FREEBYTES2, buf);
+                sText.Format(_T("%ld bytes"), volInfo.m_nPartSize);
+                SetDlgItemText(hwnd, IDC_TOTALBYTES, sText);
+                StrFormatByteSize64(volInfo.m_nPartSize, buf, 100);
+                SetDlgItemText(hwnd, IDC_TOTALBYTES2, buf);
+
+                // "where is" info
+                CStringArray servers;
+                GetServers(filenames.GetAt(0), servers);
+                int tabstops[1] = {118};
+                SendDlgItemMessage(hwnd, IDC_SERVERS, LB_SETTABSTOPS, 1, (LPARAM)&tabstops);
+                for (int i=0;i<servers.GetCount();++i){
+                    SendDlgItemMessage(m_hwnd, IDC_SERVERS, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR)servers.GetAt(i));
+                }
+            }
+            return TRUE;
+        }
+        break;
+    case WM_NOTIFY:
+        {
+            LPNMHDR point = (LPNMHDR)lParam;
+            int code = point->code;
+            BOOL bRet = FALSE;
+            switch (code)
+            {
+            case PSN_APPLY:
+                {
+                    // Return PSNRET_NOERROR to allow the sheet to close if the user clicked OK.
+                    SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
+                }
+                break;
+            }
+            SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, FALSE);
+            return bRet;
+        }
+        break;
+    case WM_COMMAND:
+        switch (HIWORD(wParam))
+        {
+        case BN_CLICKED:
+            switch (LOWORD(wParam))
+            {
+            case IDC_FLUSH:
+                FlushVolume(filenames);
+                return TRUE;
+            }
+            break;
+        }
+        break;
+    }
+
+    return FALSE;
+}
diff --git a/src/WINNT/client_exp/PropVolume.h b/src/WINNT/client_exp/PropVolume.h
new file mode 100644 (file)
index 0000000..267e653
--- /dev/null
@@ -0,0 +1,13 @@
+#pragma once
+#include "resource.h"
+#include "PropBase.h"
+
+class CPropVolume : public PropertyPage
+{
+public:
+    CPropVolume(const CStringArray& filenames) : PropertyPage(filenames){}
+
+    virtual BOOL PropPageProc(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
+
+private:
+};
index a40efd5..02da79a 100644 (file)
@@ -87,8 +87,6 @@ BOOL CAddAclEntryDlg::OnInitDialog()
 {
        CDialog::OnInitDialog();
 
-       ASSERT_VALID(m_pAclSetDlg);
-
        m_NormalEntry.SetCheck(CHECKED);
        m_Ok.EnableWindow(FALSE);
 
index 888b81b..4f48ca9 100644 (file)
@@ -6,8 +6,14 @@
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
+#ifndef __ADD_ACL_ENTRY_DLG_H__
+#define __ADD_ACL_ENTRY_DLG_H__
 
-class CSetAfsAcl;
+class CSetACLInterface
+{
+public:
+    virtual BOOL IsNameInUse(BOOL bNormal, const CString& strName) = 0;
+};
 
 /////////////////////////////////////////////////////////////////////////////
 // CAddAclEntryDlg dialog
@@ -17,7 +23,7 @@ class CAddAclEntryDlg : public CDialog
        BOOL m_bNormal;
        CString m_Rights;
        CString m_strName;
-       CSetAfsAcl *m_pAclSetDlg;
+       CSetACLInterface *m_pAclSetDlg;
 
        CString MakePermString();
 
@@ -25,7 +31,7 @@ class CAddAclEntryDlg : public CDialog
 public:
        CAddAclEntryDlg(CWnd* pParent = NULL);   // standard constructor
 
-       void SetAclDlg(CSetAfsAcl *pAclSetDlg)  { m_pAclSetDlg = pAclSetDlg; }
+       void SetAclDlg(CSetACLInterface *pAclSetDlg)    { m_pAclSetDlg = pAclSetDlg; }
 
        CString GetName()               { return m_strName; }
        CString GetRights()             { return m_Rights; }
@@ -67,3 +73,5 @@ protected:
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
 };
+
+#endif
index c796b90..1045ebd 100644 (file)
@@ -363,6 +363,16 @@ STDAPI DllRegisterServer(void)
             return lResult;
     }
 
+    // register property handler
+    wsprintf(szSubKey, TEXT("*\\shellex\\PropertySheetHandlers\\%s"),STR_EXT_TITLE);
+    if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR)
+        return lResult;
+    wsprintf(szSubKey, TEXT("Drive\\shellex\\PropertySheetHandlers\\%s"),STR_EXT_TITLE);
+    if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR)
+        return lResult;
+    wsprintf(szSubKey, TEXT("Directory\\shellex\\PropertySheetHandlers\\%s"),STR_EXT_TITLE);
+    if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szCLSID))!=NOERROR)
+        return lResult;
 
     return S_OK;
 }
@@ -419,6 +429,12 @@ STDAPI DllUnregisterServer(void)
     DoValueDelete(HKEY_CLASSES_ROOT, szSubKey);
     wsprintf(szSubKey, TEXT("%s\\%s"), STR_REG_PATH, STR_EXT_TITLE);
     DoValueDelete(HKEY_LOCAL_MACHINE, szSubKey);
+    wsprintf(szSubKey, TEXT("*\\shellex\\PropertySheetHandlers\\%s"),STR_EXT_TITLE);
+    DoValueDelete(HKEY_CLASSES_ROOT, szSubKey);
+    wsprintf(szSubKey, TEXT("Drive\\shellex\\PropertySheetHandlers\\%s"),STR_EXT_TITLE);
+    DoValueDelete(HKEY_CLASSES_ROOT, szSubKey);
+    wsprintf(szSubKey, TEXT("Directory\\shellex\\PropertySheetHandlers\\%s"),STR_EXT_TITLE);
+    DoValueDelete(HKEY_CLASSES_ROOT, szSubKey);
 
     StringFromIID(IID_IShellExt2, &pwsz);
     if(pwsz)
index fe33753..80c7e00 100644 (file)
@@ -37,6 +37,8 @@ extern "C" {
 #include <afs/afsint.h>
 #include <afs/afs_consts.h>
 #include <afs/cellconfig.h>
+#include <afs/ptserver.h>
+#include <afs/ptuser.h>
 #include <afs/vldbint.h>
 #include <afs/volser.h>
 #include <afs/auth.h>
@@ -47,6 +49,7 @@ extern "C" {
 #include <cm_user.h>
 #include <cm_scache.h>
 #include <cm_ioctl.h>
+#include <cm_config.h>
 }
 
 #define STRSAFE_NO_DEPRECATE
@@ -194,7 +197,7 @@ OpenFile(char *file, char *rwp)
     return fp;
 }
 
-CString StripPath(CString& strPath)
+CString StripPath(const CString& strPath)
 {
     int nIndex = strPath.ReverseFind('\\');
 
@@ -902,10 +905,12 @@ ParseMountPoint(const CString strFile, CString strMountPoint)
     if (nColon >= 0) {
         strCell = strMountPoint.Mid(1, nColon - 1);
         strVolume = strMountPoint.Mid(nColon + 1);
-    } else
+    } else {
         strVolume = strMountPoint.Mid(1);
+        strCell = _T("(local)");
+    }
 
-    strMountPointInfo = strFile + _T("\t") + strVolume + _T("\t") + strCell + _T("\t") + strType;
+    strMountPointInfo = _T("=> ") + strVolume + _T(" : ") + strCell + _T(" cell [") + strType + _T("]");
 
     return strMountPointInfo;
 }
@@ -915,12 +920,41 @@ ParseSymlink(const CString strFile, CString strSymlink)
 {
     CString strSymlinkInfo;
 
-    strSymlinkInfo = strFile + _T("\t") + strSymlink;
+    strSymlinkInfo = _T("-> ") + strSymlink;
 
     return strSymlinkInfo;
 }
 
 BOOL
+GetFID(const CString& path, CString& fidstring, BOOL bLiteral)
+{
+    struct ViceIoctl blob;
+    cm_ioctlQueryOptions_t options;
+    cm_fid_t fid;
+    int code;
+
+    memset(&options, 0, sizeof(options));
+    options.size = sizeof(options);
+    options.field_flags |= CM_IOCTL_QOPTS_FIELD_LITERAL;
+    options.literal = bLiteral ? 1 : 0;
+    blob.in_size = options.size;    /* no variable length data */
+    blob.in = &options;
+    blob.out_size = sizeof(cm_fid_t);
+    blob.out = (char *) &fid;
+
+    code = pioctl_T(path, VIOCGETFID, &blob, 1);
+    fidstring.Empty();
+    if (code == 0) {
+        fidstring.Format( TEXT("%lu.%lu.%lu"),
+                          fid.volume,
+                          fid.vnode,
+                          fid.unique);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+BOOL
 IsPathInAfs(const CString & strPath)
 {
     struct ViceIoctl blob;
@@ -1916,3 +1950,345 @@ ListSymlink(CStringArray& files)
     return !error;
 }
 
+CString
+GetCellName( const CString& strPath )
+{
+    return GetCell(strPath);
+}
+
+CString
+GetServer( const CString& strPath )
+{
+    LONG code;
+    struct ViceIoctl blob;
+    CString server;
+    char space[AFS_PIOCTL_MAXSIZE];
+
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
+    blob.in_size = 0;
+    blob.out = space;
+    memset(space, 0, sizeof(space));
+
+    code = pioctl_T(strPath, VIOCWHEREIS, &blob, 1);
+    if (code) {
+        server=GetAfsError(errno);
+    } else {
+        LONG *hosts = (LONG *)space;
+
+        for (int j = 0; j < AFS_MAXHOSTS; j++) {
+            if (hosts[j] == 0)
+                break;
+            char *hostName = hostutil_GetNameByINet(hosts[j]);
+            server=hostName;
+        }
+    }
+
+    return server;
+}
+
+void
+GetServers( const CString& strPath, CStringArray& servers )
+{
+    LONG code;
+    struct ViceIoctl blob;
+    char space[AFS_PIOCTL_MAXSIZE];
+
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
+    blob.in_size = 0;
+    blob.out = space;
+    memset(space, 0, sizeof(space));
+
+    code = pioctl_T(strPath, VIOCWHEREIS, &blob, 1);
+    if (code) {
+        servers.Add(GetAfsError(errno));
+    } else {
+        LONG *hosts = (LONG *)space;
+
+        for (int j = 0; j < AFS_MAXHOSTS; j++) {
+            if (hosts[j] == 0)
+                break;
+            char *hostName = hostutil_GetNameByINet(hosts[j]);
+            servers.Add(hostName);
+        }
+    }
+}
+
+CString
+GetOwner( const CString& strPath )
+{
+    LONG code;
+    struct ViceIoctl blob;
+    afs_int32 owner[2];
+    CString ret = TEXT("(unknown)");
+
+    blob.in_size = 0;
+    blob.out_size = 2 * sizeof(afs_int32);
+    blob.out = (char *) &owner;
+
+    code = pioctl_T(strPath, VIOCGETOWNER, &blob, 1);
+    if (code == 0 && blob.out_size == 2 * sizeof(afs_int32)) {
+        char oname[PR_MAXNAMELEN] = "(unknown)";
+        char confDir[257];
+        CStringUtf8 cell;
+
+        cell = GetCell(strPath);
+
+        /* Go to the PRDB and see if this all number username is valid */
+        cm_GetConfigDir(confDir, sizeof(confDir));
+
+        pr_Initialize(1, confDir, PCCHAR(cell));
+        pr_SIdToName(owner[0], oname);
+
+        ret.Empty();
+        ret.Format(TEXT("%s [%d]"), (LPCTSTR)CString(oname), owner[0]);
+    }
+
+    return ret;
+}
+
+CString
+GetGroup( const CString& strPath )
+{
+    LONG code;
+    struct ViceIoctl blob;
+    afs_int32 owner[2];
+    CString ret = TEXT("(unknown)");
+
+    blob.in_size = 0;
+    blob.out_size = 2 * sizeof(afs_int32);
+    blob.out = (char *) &owner;
+
+    code = pioctl_T(strPath, VIOCGETOWNER, &blob, 1);
+    if (code == 0 && blob.out_size == 2 * sizeof(afs_int32)) {
+        char gname[PR_MAXNAMELEN] = "(unknown)";
+        char confDir[257];
+        CStringUtf8 cell;
+
+        cell = GetCell(strPath);
+
+        /* Go to the PRDB and see if this all number username is valid */
+        cm_GetConfigDir(confDir, sizeof(confDir));
+
+        pr_Initialize(1, confDir, PCCHAR(cell));
+        pr_SIdToName(owner[1], gname);
+
+        ret.Empty();
+        ret.Format(TEXT("%s [%d]"), (LPCTSTR)CString(gname), owner[1]);
+    }
+
+    return ret;
+}
+
+BOOL
+GetUnixModeBits( const CString& strPath, CString& user, CString& group, CString& other, CString& suid )
+{
+    // the strings must match the unix ls command output: "rwx" means read/write/execute permissions
+
+    LONG code;
+    struct ViceIoctl blob;
+    afs_uint32 unixModeBits;
+    CString ret = TEXT("(unknown)");
+
+    user.Empty();
+    group.Empty();
+    other.Empty();
+    suid.Empty();
+
+    blob.in_size = 0;
+    blob.out_size = sizeof(afs_int32);
+    blob.out = (char *) &unixModeBits;
+
+    code = pioctl_T(strPath, VIOC_GETUNIXMODE, &blob, 1);
+    if (code == 0 && blob.out_size == sizeof(afs_uint32)) {
+        if (unixModeBits & S_IRUSR)
+            user + TEXT("r");
+        if (unixModeBits & S_IWUSR)
+            user + TEXT("w");
+        if (unixModeBits & S_IXUSR)
+            user + TEXT("x");
+
+        if (unixModeBits & S_IRGRP)
+            group + TEXT("r");
+        if (unixModeBits & S_IWGRP)
+            group + TEXT("w");
+        if (unixModeBits & S_IXGRP)
+            group + TEXT("x");
+
+        if (unixModeBits & S_IROTH)
+            other + TEXT("r");
+        if (unixModeBits & S_IWOTH)
+            other + TEXT("w");
+        if (unixModeBits & S_IXOTH)
+            other + TEXT("x");
+
+        if (unixModeBits & S_ISUID)
+            suid + TEXT("s");
+        if (unixModeBits & S_ISGID)
+            suid + TEXT("g");
+        if (unixModeBits & S_ISVTX)
+            suid + TEXT("v");
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+void
+SetUnixModeBits( const CStringArray& files, const CString& user, const CString& group, const CString& other, const CString& suid )
+{
+    // set the unix file attributes for all paths in 'files'.
+    LONG code;
+    struct ViceIoctl blob;
+    struct {
+        cm_ioctlQueryOptions_t options;
+        afs_uint32 unixModeBits;
+    } inData;
+
+    memset(&inData, 0, sizeof(inData));
+    inData.options.size = sizeof(inData.options);
+    inData.options.field_flags = 0;
+    inData.options.literal = 0;            /* always applying to target */
+    blob.in_size = inData.options.size;    /* no variable length data */
+    blob.in = &inData;
+    blob.out = NULL;
+    blob.out_size = 0;
+    inData.unixModeBits = 0;
+
+    if (user.Find(_T("r")) != -1)
+        inData.unixModeBits |= S_IRUSR;
+    if (user.Find(_T("w")) != -1)
+        inData.unixModeBits |= S_IWUSR;
+    if (user.Find(_T("x")) != -1)
+        inData.unixModeBits |= S_IXUSR;
+
+    if (group.Find(_T("r")) != -1)
+        inData.unixModeBits |= S_IRGRP;
+    if (group.Find(_T("w")) != -1)
+        inData.unixModeBits |= S_IWGRP;
+    if (group.Find(_T("x")) != -1)
+        inData.unixModeBits |= S_IXGRP;
+
+    if (other.Find(_T("r")) != -1)
+        inData.unixModeBits |= S_IROTH;
+    if (other.Find(_T("w")) != -1)
+        inData.unixModeBits |= S_IWOTH;
+    if (other.Find(_T("x")) != -1)
+        inData.unixModeBits |= S_IXOTH;
+
+    if (suid.Find(_T("s")) != -1)
+        inData.unixModeBits |= S_ISUID;
+    if (suid.Find(_T("g")) != -1)
+        inData.unixModeBits |= S_ISGID;
+    if (suid.Find(_T("v")) != -1)
+        inData.unixModeBits |= S_ISVTX;
+
+    for (int i = 0; i < files.GetSize(); i++)
+        code = pioctl_T(files[i], VIOC_SETUNIXMODE, &blob, 1);
+}
+
+CString GetMountpoint( const CString& strPath )
+{
+    LONG code;
+    struct ViceIoctl blob;
+    char space[AFS_PIOCTL_MAXSIZE];
+    CString parent_dir;                /* Parent directory of true name */
+    CStringUtf8 last_component;                /* Last component of true name */
+
+    CString mountPoint;
+
+
+    int last_slash = strPath.ReverseFind(_T('\\'));
+
+    if (last_slash != -1) {
+        last_component.SetString( strPath.Mid(last_slash + 1) );
+        parent_dir.SetString( strPath.Left(last_slash + 1) );
+        FixNetbiosPath(parent_dir);
+    } else {
+        // The path is of the form "C:foo" or just "foo".  If
+        // there is a drive, then use the current directory of
+        // that drive.  Otherwise we just use '.'.
+
+        if (strPath.GetLength() >= 2 && strPath[1] == _T(':')) {
+            parent_dir.Format(_T("%c:."), strPath[0]);
+            last_component.SetString( strPath.Mid(2) );
+        } else {
+            parent_dir.SetString( _T("."));
+            last_component.SetString( strPath );
+        }
+    }
+
+    blob.in_size = last_component.GetLength() + 1;
+    blob.in = last_component.GetBuffer();
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
+    blob.out = space;
+    memset(space, 0, AFS_PIOCTL_MAXSIZE);
+
+    code = pioctl_T(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
+
+    last_component.ReleaseBuffer();
+
+    if (code == 0) {
+        int nPos;
+        space[AFS_PIOCTL_MAXSIZE - 1] = '\0';
+        nPos = strlen(space) - 1;
+        if (space[nPos] == '.')
+            space[nPos] = 0;
+        mountPoint = ParseMountPoint(StripPath(strPath), Utf8ToCString(space));
+    } else {
+        if (errno == EINVAL)
+            mountPoint = GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(strPath));
+        else
+            mountPoint = GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(strPath)));
+    }
+
+    return mountPoint;
+}
+
+CString GetSymlink( const CString& strPath )
+{
+    LONG code;
+    struct ViceIoctl blob;
+    CString symlink;
+    char space[AFS_PIOCTL_MAXSIZE];
+
+    CString strParent = Parent(strPath);
+    CStringUtf8 ustrLast(LastComponent(strPath));
+
+    FixNetbiosPath(strParent);
+
+    blob.in_size = ustrLast.GetLength() + 1;
+    blob.in = ustrLast.GetBuffer();
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
+    blob.out = space;
+    memset(space, 0, AFS_PIOCTL_MAXSIZE);
+
+    code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 1);
+
+    ustrLast.ReleaseBuffer();
+
+    if (code == 0) {
+        CString syml;
+        int len;
+
+        space[AFS_PIOCTL_MAXSIZE - 1] = '\0';
+        syml = Utf8ToCString(space);
+        len = syml.GetLength();
+
+        if (len > 0) {
+            if (syml[len - 1] == _T('.'))
+                syml.Truncate(len - 1);
+        }
+
+        symlink = ParseSymlink(StripPath(strPath), syml);
+
+    } else {
+        if (errno == EINVAL)
+            symlink = GetMessageString(IDS_NOT_SYMLINK_ERROR, StripPath(strPath));
+        else
+            symlink = GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(strPath)));
+    }
+
+
+    return symlink;
+}
index 1fa2f47..ef306e7 100644 (file)
@@ -33,10 +33,20 @@ BOOL SetVolInfo(CVolInfo& volInfo);
 enum WHICH_CELLS { LOCAL_CELL = 0, SPECIFIC_CELL = 1, ALL_CELLS = 2 };
 BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast);
 BOOL GetTokenInfo(CStringArray& tokenInfo);
+BOOL GetFID(const CString& path, CString& fidstring, BOOL bLiteral = TRUE);
 BOOL IsPathInAfs(const CString& strPath);
 BOOL IsSymlink(const CString& name);
 BOOL IsMountPoint(const CString& name);
 UINT MakeSymbolicLink(const CString&,const CString&);
 void ListSymbolicLinkPath(CString&,CString&,UINT nlenPath);
 BOOL ListSymlink(CStringArray& files);
+CString GetCellName(const CString& strPath);
+CString GetServer(const CString& strPath);
+void GetServers( const CString& strPath, CStringArray& servers );
+CString GetOwner(const CString& strPath);
+CString GetGroup(const CString& strPath);
+BOOL GetUnixModeBits(const CString& strPath, CString& user, CString& group, CString& other, CString& suid);
+void SetUnixModeBits(const CStringArray& files, const CString& user, const CString& group, const CString& other, const CString& suid);
+CString GetMountpoint(const CString& strPath);
+CString GetSymlink(const CString& strPath);
 #endif //__GUI2FS_H__
index 29ed76c..4f026cf 100644 (file)
@@ -632,6 +632,12 @@ BEGIN
     AFX_IDS_APP_TITLE       "AFS Client"
 END
 
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_MENU_DELETE         "&Delete"
+    IDS_MENU_CUT            "Cu&t"
+END
+
 #endif    // English (U.S.) resources
 /////////////////////////////////////////////////////////////////////////////
 
index b7c9abc..9beff22 100644 (file)
@@ -461,6 +461,104 @@ BEGIN
     LTEXT           "Path Name:",IDC_STATIC,19,25,28,8
 END
 
+IDD_PROPPAGE_FILE DIALOGEX 0, 0, 247, 277
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_CAPTION
+CAPTION "AFS"
+FONT 8, "MS Shell Dlg", 400, 0, 0x0
+BEGIN
+    LTEXT           "Type:",IDC_STATIC,7,9,20,8
+    EDITTEXT        IDC_PROP_TYPE,56,9,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Name:",IDC_STATIC,7,25,22,8
+    EDITTEXT        IDC_PROP_FILENAME,56,25,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "FID:",IDC_STATIC,7,41,15,8
+    EDITTEXT        IDC_PROP_FID,56,41,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Cell:",IDC_STATIC,7,89,15,8
+    EDITTEXT        IDC_PROP_CELL,56,89,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Fileserver:",IDC_STATIC,7,105,35,8
+    EDITTEXT        IDC_PROP_FILESERVER,56,105,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    GROUPBOX        "Unix file attributes",IDC_STATIC,7,161,232,75
+    LTEXT           "Owner:",IDC_STATIC,7,57,25,8
+    LTEXT           "Group:",IDC_STATIC,7,73,23,8
+    EDITTEXT        IDC_PROP_OWNER,56,56,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    EDITTEXT        IDC_PROP_GROUP,56,73,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Symlink:",IDC_SYMLINK_LABEL,7,120,27,8
+    EDITTEXT        IDC_PROP_SMINFO,56,120,185,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Mount Point:",IDC_MOUNTPOINT_LABEL,7,121,42,8
+    PUSHBUTTON      "&Flush",IDC_FLUSH,190,137,50,14
+    LTEXT           "User:",IDC_STATIC,14,175,18,8
+    LTEXT           "Group:",IDC_STATIC,14,190,23,8
+    LTEXT           "Other:",IDC_STATIC,14,205,22,8
+    CONTROL         "Read",IDC_ATTR_USER_READ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,174,33,10
+    CONTROL         "Read",IDC_ATTR_GROUP_READ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,189,33,10
+    CONTROL         "Read",IDC_ATTR_OTHER_READ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,204,33,10
+    CONTROL         "Write",IDC_ATTR_USER_WRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,174,33,10
+    CONTROL         "Write",IDC_ATTR_GROUP_WRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,189,33,10
+    CONTROL         "Write",IDC_ATTR_OTHER_WRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,204,33,10
+    CONTROL         "Execute",IDC_ATTR_USER_EXECUTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,136,174,33,10
+    CONTROL         "Execute",IDC_ATTR_GROUP_EXECUTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,136,189,33,10
+    CONTROL         "Execute",IDC_ATTR_OTHER_EXECUTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,136,204,33,10
+    CONTROL         "SUid",IDC_ATTR_SUID_UID,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,219,33,10
+    CONTROL         "SGid",IDC_ATTR_SUID_GID,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,219,33,10
+    CONTROL         "SVtx",IDC_ATTR_SUID_VTX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,136,219,33,10
+    PUSHBUTTON      "Edit...",IDC_EDIT,134,137,50,14
+    PUSHBUTTON      "Remove Symlink",IDC_REMOVESYMLINK,54,137,73,14,NOT WS_VISIBLE
+    PUSHBUTTON      "Remove Mountpoint",IDC_REMOVEMOUNTPOINT,54,137,73,14,NOT WS_VISIBLE
+END
+
+IDD_PROPPAGE_ACL DIALOGEX 0, 0, 247, 277
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_CAPTION
+CAPTION "AFS ACL"
+FONT 8, "MS Shell Dlg", 400, 0, 0x0
+BEGIN
+    LTEXT           "Name:",IDC_STATIC,7,7,22,8
+    EDITTEXT        IDC_PROP_FILENAME,56,7,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LISTBOX         IDC_NORMAL_RIGHTS,14,43,218,110,LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
+    GROUPBOX        "User Permissions",IDC_STATIC,8,29,232,129
+    CONTROL         "r - Read",IDC_READ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,172,73,12
+    CONTROL         "w - Write",IDC_WRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,117,172,73,12
+    CONTROL         "l - Lookup",IDC_LOOKUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,185,73,12
+    CONTROL         "k - Lock",IDC_LOCK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,117,185,73,12
+    CONTROL         "i - Insert",IDC_INSERT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,198,73,12
+    CONTROL         "a - Administer",IDC_ADMINISTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,117,198,73,12
+    CONTROL         "d - Delete",IDC_DELETE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,211,73,12
+    PUSHBUTTON      "&Add...",IDC_ADD,7,231,60,17
+    PUSHBUTTON      "&Remove",IDC_REMOVE,73,231,60,17,WS_DISABLED
+    PUSHBUTTON      "&Clean",IDC_CLEAN,141,231,60,17
+    PUSHBUTTON      "Co&py...",IDC_COPY,7,253,60,17
+    GROUPBOX        "Specific Permissions",IDC_STATIC,7,161,225,68
+END
+
+IDD_PROPPAGE_VOLUME DIALOGEX 0, 0, 247, 277
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_CAPTION
+CAPTION "AFS"
+FONT 8, "MS Shell Dlg", 400, 0, 0x0
+BEGIN
+    LTEXT           "Volume:",IDC_STATIC,7,7,26,8
+    EDITTEXT        IDC_PROP_VOLUMENAME,56,7,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "FID:",IDC_STATIC,7,23,15,8
+    EDITTEXT        IDC_PROP_FID,56,23,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Owner:",IDC_STATIC,7,39,25,8
+    EDITTEXT        IDC_PROP_OWNER,56,38,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Group:",IDC_STATIC,7,55,23,8
+    EDITTEXT        IDC_PROP_GROUP,56,55,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Cell:",IDC_STATIC,7,71,15,8
+    EDITTEXT        IDC_PROP_CELL,56,71,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Fileserver:",IDC_STATIC,7,87,35,8
+    EDITTEXT        IDC_PROP_FILESERVER,56,87,184,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    PUSHBUTTON      "&Flush",IDC_FLUSH,191,103,50,14
+    GROUPBOX        "Capacity",IDC_STATIC,9,129,225,68
+    LTEXT           "Used Space:",IDC_STATIC,18,144,41,8
+    EDITTEXT        IDC_USEDBYTES,76,143,81,14,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    EDITTEXT        IDC_USEDBYTES2,157,143,69,14,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Free Space:",IDC_STATIC,18,162,40,8
+    EDITTEXT        IDC_FREEBYTES,76,162,81,14,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    EDITTEXT        IDC_FREEBYTES2,157,162,69,14,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    LTEXT           "Total Space:",IDC_STATIC,18,180,41,8
+    EDITTEXT        IDC_TOTALBYTES,76,180,81,14,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    EDITTEXT        IDC_TOTALBYTES2,157,180,69,14,ES_RIGHT | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
+    GROUPBOX        "Servers",IDC_STATIC,9,200,225,63
+    LISTBOX         IDC_SERVERS,16,210,211,44,LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
+END
 
 /////////////////////////////////////////////////////////////////////////////
 //
@@ -687,6 +785,21 @@ BEGIN
     AFX_IDS_APP_TITLE       "AFS Client"
 END
 
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_MENU_DELETE         "&Delete"
+    IDS_MENU_CUT            "Cu&t"
+    IDS_PROP_MULTIPLEITEMS  "(multiple items selected)"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_PROP_TYPEDIRECTORY  "Directory"
+    IDS_PROP_TYPEFILE       "File"
+    IDS_PROP_TYPEMOUNTPOINT "Mount point"
+    IDS_PROP_TYPESYMLINK    "Symlink"
+END
+
 #endif    // English (U.S.) resources
 /////////////////////////////////////////////////////////////////////////////
 
index 1b1e24e..7d400c0 100644 (file)
@@ -650,6 +650,12 @@ BEGIN
     AFX_IDS_APP_TITLE       "AFS Client"
 END
 
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_MENU_DELETE         "&Delete"
+    IDS_MENU_CUT            "Cu&t"
+END
+
 #endif    // English (U.S.) resources
 /////////////////////////////////////////////////////////////////////////////
 
index e2b8c2f..99c1351 100644 (file)
@@ -633,6 +633,12 @@ BEGIN
     AFX_IDS_APP_TITLE       "AFS ƒNƒ‰ƒCƒAƒ“ƒg"
 END
 
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_MENU_DELETE         "&Delete"
+    IDS_MENU_CUT            "Cu&t"
+END
+
 #endif    // Japanese resources
 /////////////////////////////////////////////////////////////////////////////
 
index 7b20f29..172252c 100644 (file)
@@ -632,6 +632,12 @@ BEGIN
     AFX_IDS_APP_TITLE       "AFS Å¬¶óÀ̾ðÆ®"
 END
 
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_MENU_DELETE         "&Delete"
+    IDS_MENU_CUT            "Cu&t"
+END
+
 #endif    // Korean resources
 /////////////////////////////////////////////////////////////////////////////
 
index 225cfa1..26affcc 100644 (file)
@@ -633,6 +633,12 @@ BEGIN
     AFX_IDS_APP_TITLE       "AFS Client"
 END
 
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_MENU_DELETE         "&Delete"
+    IDS_MENU_CUT            "Cu&t"
+END
+
 #endif    // English (U.S.) resources
 /////////////////////////////////////////////////////////////////////////////
 
index 55e744e..4a0ab6c 100644 (file)
@@ -627,6 +627,12 @@ BEGIN
     AFX_IDS_APP_TITLE       "AFS ¿Í»§»ú"
 END
 
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_MENU_DELETE         "&Delete"
+    IDS_MENU_CUT            "Cu&t"
+END
+
 #endif    // Chinese (P.R.C.) resources
 /////////////////////////////////////////////////////////////////////////////
 
index 5b9f5f8..72d6896 100644 (file)
@@ -627,6 +627,12 @@ BEGIN
     AFX_IDS_APP_TITLE       "AFS ¥Î¤áºÝ"
 END
 
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_MENU_DELETE         "&Delete"
+    IDS_MENU_CUT            "Cu&t"
+END
+
 #endif    // Chinese (Taiwan) resources
 /////////////////////////////////////////////////////////////////////////////
 
index 5b619ca..ccf185e 100644 (file)
@@ -119,16 +119,18 @@ void CMakeMountPointDlg::CheckEnableOk()
 
 BOOL CMakeMountPointDlg::OnInitDialog()
 {
-       CDialog::OnInitDialog();
+        CDialog::OnInitDialog();
 
-       m_Dir.SetWindowText(m_strDir);
+        m_Dir.SetWindowText(m_strDir);
+        m_Vol.SetWindowText(m_strVol);
+        m_Cell.SetWindowText(m_strCell);
 
-       m_nType = 0;
+        m_nType = 0;
 
-       UpdateData(FALSE);
+        UpdateData(FALSE);
 
-       return TRUE;  // return TRUE unless you set the focus to a control
-                     // EXCEPTION: OCX Property Pages should return FALSE
+        return TRUE;  // return TRUE unless you set the focus to a control
+                      // EXCEPTION: OCX Property Pages should return FALSE
 }
 
 void CMakeMountPointDlg::OnHelp()
index cb31d3d..0426349 100644 (file)
@@ -20,8 +20,10 @@ class CMakeMountPointDlg : public CDialog
 public:
        CMakeMountPointDlg(CWnd* pParent = NULL);   // standard constructor
 
-       void SetDir(const CString& strDir)      { m_strDir = strDir; }
-       BOOL MountWasMade()                                     { return m_bMade; }
+       void SetDir(const CString& strDir)   { m_strDir = strDir; }
+        void SetCell(const CString& strCell) { m_strCell = strCell; }
+        void SetVol(const CString& strVol)   { m_strVol = strVol; }
+       BOOL MountWasMade()                  { return m_bMade; }
 
 // Dialog Data
        //{{AFX_DATA(CMakeMountPointDlg)
index acf6598..abbee85 100644 (file)
@@ -135,8 +135,8 @@ BOOL CMakeSymbolicLinkDlg::OnInitDialog()
 {
        CDialog::OnInitDialog();
 
-//     m_Dir.SetWindowText(m_strDir);
-//     m_Name.SetWindowText(m_strName);
+       m_Dir.SetWindowText(m_strDir);
+       m_Name.SetWindowText(m_strName);
        UpdateData(FALSE);
 
        return TRUE;  // return TRUE unless you set the focus to a control
index 18a2564..21d9487 100644 (file)
 #define IDS_WARNING                           138
 #define IDS_VOLUME_NOT_IN_CELL_WARNING         139
 #define IDS_NOT_SYMLINK_ERROR                  140
+#define IDS_MENU_DELETE                        141
+#define IDS_MENU_CUT                           142
+#define IDS_PROP_MULTIPLEITEMS                 143
+#define IDS_PROP_TYPEDIRECTORY                 144
+#define IDS_PROP_TYPEFILE                      145
+#define IDS_PROP_TYPEMOUNTPOINT                146
+#define IDS_PROP_TYPESYMLINK                   147
+
 
 #define IDM_AUTHENTICATION                    0
 #define IDM_ACL_SET                           1
 #define ID_SYMBOLICLINK_REMOVE          959
 #define ID_SYMBOLICLINK_SHOW            960
 #define IDD_SYMLINKS                    961
+#define IDD_PROPPAGE_FILE               962
+#define IDD_PROPPAGE_ACL                963
+#define IDD_PROPPAGE_VOLUME             964
+
 #define IDC_LIST                        1001
 #define IDC_PASSWORD                    1002
 #define IDC_OFFLINE_MSG                 1003
 #define IDC_PERCENT_USED                1054
 #define IDC_TO_DIR                      1055
 #define IDC_CB_H                        1056
-#define IDC_BUTTON1                     1057
 #define IDC_BROWSE                      1058
 #define IDC_ACL_CLEAR                   1059
 #define IDC_ACL_LIST_SET_COPY           1060
 #define IDC_SHOWSTATUS                  1061
 #define IDC_VOL_PART_PROPERTIES         1062
-#define IDC_COLUMN_3                    1063
+#define IDC_FLUSH                       1063
 #define IDC_VOL_PART_UPDATE             1064
-#define IDC_COLUMN_4                    1065
+#define IDC_COLUMN_3                    1065
 #define IDC_MOUNT_POINT_SHOW            1066
 #define IDC_MOUNT_POINT_REMOVE          1067
 #define IDC_MOUNT_POINT_MAKE            1068
 #define IDC_STATIC_CONTROL2             1084
 #define IDC_SHARE_NAME                  1085
 #define IDC_PATH_NAME                   1086
-
+#define IDC_PROP_FILENAME               1087
+#define IDC_PROP_FID                    1088
+#define IDC_PROP_OWNER                  1089
+#define IDC_PROP_GROUP                  1090
+#define IDC_SHOW                        1091
+#define IDC_REMOVESYMLINK               1092
+#define IDC_REMOVEMOUNTPOINT            1093
+#define IDC_PROP_CELL                   1096
+#define IDC_PROP_FILESERVER             1097
+#define IDC_ATTR_USER_READ              1099
+#define IDC_ATTR_GROUP_READ             1100
+#define IDC_ATTR_OTHER_READ             1101
+#define IDC_ATTR_USER_WRITE             1102
+#define IDC_ATTR_GROUP_WRITE            1103
+#define IDC_ATTR_OTHER_WRITE            1104
+#define IDC_ATTR_USER_EXECUTE           1105
+#define IDC_ATTR_GROUP_EXECUTE          1106
+#define IDC_ATTR_OTHER_WRITE2           1107
+#define IDC_ATTR_OTHER_EXECUTE          1107
+#define IDC_PROP_SMINFO                 1108
+#define IDC_USEDBYTES                   1108
+#define IDC_SYMLINK_LABEL               1109
+#define IDC_USEDBYTES2                  1109
+#define IDC_MOUNTPOINT_LABEL            1110
+#define IDC_PROP_VOLUMENAME             1111
+#define IDC_FREEBYTES                   1112
+#define IDC_TOTALBYTES                  1113
+#define IDC_FREEBYTES2                  1114
+#define IDC_TOTALBYTES2                 1115
+#define IDC_COLUMN_4                    1116
+#define IDC_PROP_TYPE                   1117
+#define IDC_BUTTON2                     1118
+#define IDC_EDIT                        1119
+#define IDC_SERVERS                     1120
+#define IDC_ATTR_SUID_UID               1121
+#define IDC_ATTR_SUID_GID               1122
+#define IDC_ATTR_SUID_VTX               1123
 
 // Next default values for new objects
 //
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        163
+#define _APS_NEXT_RESOURCE_VALUE        165
 #define _APS_NEXT_COMMAND_VALUE         32829
-#define _APS_NEXT_CONTROL_VALUE         1087
+#define _APS_NEXT_CONTROL_VALUE         1124
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
index 65185f0..94e06f2 100644 (file)
@@ -6,8 +6,9 @@
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
+#include "add_acl_entry_dlg.h"
 
-class CSetAfsAcl : public CDialog
+class CSetAfsAcl : public CDialog, public CSetACLInterface
 {
        CString m_strDir;
        CString m_strCellName;
index 83df356..fab7d6b 100644 (file)
@@ -9,6 +9,9 @@
 
 #include <afxpriv.h>
 #include "stdafx.h"
+#include "PropFile.h"
+#include "PropACL.h"
+#include "PropVolume.h"
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <shtypes.h>
@@ -42,12 +45,15 @@ extern "C" {
 static char THIS_FILE[] = __FILE__;
 #endif
 
+#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+
 
 ULONG nCMRefCount = 0; // IContextMenu ref count
 ULONG nSERefCount = 0; // IShellExtInit ref count
 ULONG nICRefCount=0;
 ULONG nTPRefCount=0;
 ULONG nXPRefCount=0;
+UINT nPSRefCount=0;
 
 #define PCCHAR(str)    ((char *)(const char *)str)
 static char space[AFS_PIOCTL_MAXSIZE];
@@ -89,6 +95,13 @@ CShellExt::CShellExt()
                          &LSPtype, (LPBYTE)&ShellOption, &LSPsize);
     RegCloseKey (NPKey);
     m_bIsOverlayEnabled=((code==0) && (LSPtype==REG_DWORD) && ((ShellOption & OVERLAYENABLED)!=0));
+
+    INITCOMMONCONTROLSEX used = {
+        sizeof(INITCOMMONCONTROLSEX),
+        ICC_DATE_CLASSES | ICC_WIN95_CLASSES | ICC_BAR_CLASSES | ICC_USEREX_CLASSES
+    };
+    InitCommonControlsEx(&used);
+
     TRACE("Create CShellExt, Ref count %d/n",nCMRefCount);
 }
 
@@ -151,6 +164,7 @@ BEGIN_INTERFACE_MAP(CShellExt, CCmdTarget)
     INTERFACE_PART(CShellExt, IID_IShellIconOverlayIdentifier, IconExt)
     INTERFACE_PART(CShellExt, IID_IQueryInfo , ToolTipExt)
     INTERFACE_PART(CShellExt, IID_IPersistFile , PersistFileExt)
+    INTERFACE_PART(CShellExt, IID_IShellPropSheetExt , PropertySheetExt)
 END_INTERFACE_MAP()
 
 #ifndef _WIN64
@@ -204,24 +218,25 @@ STDMETHODIMP CShellExt::XMenuExt::QueryContextMenu(HMENU hMenu,UINT indexMenu,
     if (uFlags & CMF_VERBSONLY)
        return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, (USHORT)0);
 
+    if (!pThis->m_bIsPathInAFS)
+       return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, (USHORT)0);
+
     // Check to see if there's already an AFS menu here; if so, remove it
     int nItemsNow = GetMenuItemCount (hMenu);
     CString strAfsItemText = GetMessageString(IDS_AFS_ITEM);
+    CString strDeleteText = GetMessageString(IDS_MENU_DELETE);
+    CString strCutText = GetMessageString(IDS_MENU_CUT);
     LPCTSTR pszAfsItemText = (LPCTSTR)strAfsItemText;
     for (int iItem = 0; iItem < nItemsNow; iItem++) {
        TCHAR szItemText[256];
        if (!GetMenuString (hMenu, iItem, szItemText, 256, MF_BYPOSITION))
            continue;
-       if (!lstrcmp (szItemText, pszAfsItemText)) {
+       if (lstrcmp (szItemText, pszAfsItemText)==0) {
            DeleteMenu (hMenu, iItem, MF_BYPOSITION);
            continue;
        }
-       if ((!lstrcmp(szItemText,_T("&Delete")))&&(pThis->m_bIsSymlink)) {      /*this is a symlink - don't present a delete menu!*/
-           DeleteMenu (hMenu, iItem, MF_BYPOSITION);
-           continue;
-       }
-       if ((!lstrcmp(szItemText,_T("Cu&t")))&&(pThis->m_bIsSymlink)) { /*same for cut*/
-           DeleteMenu (hMenu, iItem, MF_BYPOSITION);
+       if (((lstrcmp(szItemText,strDeleteText)==0)||(lstrcmp(szItemText,strCutText)==0))&&((pThis->m_bIsSymlink)||(pThis->m_bIsMountpoint))) {
+        DeleteMenu (hMenu, iItem, MF_BYPOSITION);
            continue;
        }
     }
@@ -584,6 +599,11 @@ STDMETHODIMP CShellExt::XShellInit::Initialize(LPCITEMIDLIST pidlFolder, IDataOb
     if ((pdobj == NULL) && (pidlFolder == NULL))
         return E_FAIL;
 
+    pThis->m_bIsSymlink=false;
+    pThis->m_bIsMountpoint=false;
+    pThis->m_bIsPathInAFS=false;
+    pThis->m_bDirSelected=false;
+
     if (pdobj) {
         //  Use the given IDataObject to get a list of filenames (CF_HDROP)
         hres = pdobj->GetData(&fmte, &medium);
@@ -613,9 +633,12 @@ STDMETHODIMP CShellExt::XShellInit::Initialize(LPCITEMIDLIST pidlFolder, IDataOb
                 strFileName.ReleaseBuffer();
                 if (!IsPathInAfs(strFileName)) {
                 pThis->m_astrFileNames.RemoveAll();
+                pThis->m_bIsPathInAFS=false;
                 break;
                 } else {
-                pThis->m_bIsSymlink=IsSymlink(strFileName);
+                pThis->m_bIsSymlink=pThis->m_bIsSymlink||IsSymlink(strFileName);
+                pThis->m_bIsMountpoint=pThis->m_bIsMountpoint||IsMountPoint(strFileName);
+                pThis->m_bIsPathInAFS=true;
                 }
 
                 if (IsADir(strFileName))
@@ -652,6 +675,8 @@ STDMETHODIMP CShellExt::XShellInit::Initialize(LPCITEMIDLIST pidlFolder, IDataOb
             CString strFileName = CString(szDisplayName);
             if (IsPathInAfs(strFileName)) {
                 pThis->m_bIsSymlink=IsSymlink(strFileName);
+                pThis->m_bIsMountpoint=IsMountPoint(strFileName);
+                pThis->m_bIsPathInAFS=true;
                 pThis->m_astrFileNames.Add(strFileName);
             }
             CoTaskMemFree(szDisplayName);
@@ -778,23 +803,34 @@ STDMETHODIMP CShellExt::XToolTipExt::GetInfoTip(DWORD dwFlags, LPWSTR *ppwszTip)
 {
     METHOD_PROLOGUE(CShellExt, ToolTipExt);
 
-    if (!IsSymlink(pThis->m_szFile))
+    if ((_tcslen(pThis->m_szFile) == 0)||(!IsPathInAfs(pThis->m_szFile)))
+    {
+        ppwszTip=NULL;
+        return S_OK;
+    }
+    bool bIsSymlink = !!IsSymlink(pThis->m_szFile);
+    bool bIsMountpoint = !!IsMountPoint(pThis->m_szFile);
+    if ((!bIsSymlink) && (!bIsMountpoint))
     {
        ppwszTip=NULL;
        return S_OK;
     }
     USES_CONVERSION;
     // dwFlags is currently unused.
-    *ppwszTip = (WCHAR*) (pThis->m_pAlloc)->Alloc((1+lstrlen(pThis->m_szFile))*sizeof(WCHAR));
+    CString sInfo;
+    if (bIsSymlink)
+        sInfo = GetSymlink(pThis->m_szFile);
+    else if (bIsMountpoint)
+        sInfo = GetMountpoint(pThis->m_szFile);
+    *ppwszTip = (WCHAR*) (pThis->m_pAlloc)->Alloc((1+sInfo.GetLength())*sizeof(WCHAR));
     if (*ppwszTip)
-    {
-       wcscpy(*ppwszTip, (WCHAR*)T2OLE(pThis->m_szFile));
-    }
+        wcscpy(*ppwszTip, (WCHAR*)T2COLE((LPCTSTR)sInfo));
 
     return S_OK;
 }
 STDMETHODIMP CShellExt::XToolTipExt::GetInfoFlags(LPDWORD pdwFlags)
 {
+    *pdwFlags = 0;
     return S_OK;
 }
 
@@ -852,3 +888,184 @@ STDMETHODIMP CShellExt::XPersistFileExt::GetCurFile(LPOLESTR FAR*)
 {
     return E_NOTIMPL;
 }
+
+// IShellPropSheetExt
+STDMETHODIMP CShellExt::XPropertySheetExt::QueryInterface(REFIID riid, void** ppv)
+{
+    METHOD_PROLOGUE(CShellExt, PropertySheetExt);
+    return pThis->ExternalQueryInterface(&riid, ppv);
+}
+
+STDMETHODIMP_(ULONG) CShellExt::XPropertySheetExt::AddRef(void)
+{
+    return ++nPSRefCount;
+}
+
+STDMETHODIMP_(ULONG) CShellExt::XPropertySheetExt::Release(void)
+{
+    if (nPSRefCount> 0)
+       nPSRefCount--;
+
+    return nPSRefCount;
+}
+
+BOOL CALLBACK PageProc (HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
+{
+    PropertyPage * sheetpage;
+
+    if (uMessage == WM_INITDIALOG)
+    {
+        sheetpage = (PropertyPage*) ((LPPROPSHEETPAGE) lParam)->lParam;
+        SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) sheetpage);
+        sheetpage->SetHwnd(hwnd);
+    }
+    else
+    {
+        sheetpage = (PropertyPage*) GetWindowLongPtr (hwnd, GWLP_USERDATA);
+    }
+
+    if (sheetpage != 0L)
+        return sheetpage->PropPageProc(hwnd, uMessage, wParam, lParam);
+    else
+        return FALSE;
+}
+
+UINT CALLBACK PropPageCallbackProc ( HWND /*hwnd*/, UINT uMsg, LPPROPSHEETPAGE ppsp )
+{
+    // Delete the page before closing.
+    if (PSPCB_CREATE == uMsg)
+        return TRUE;
+    if (PSPCB_RELEASE == uMsg)
+    {
+        PropertyPage* sheetpage = (PropertyPage*) ppsp->lParam;
+        delete sheetpage;
+    }
+    return TRUE;
+}
+
+STDMETHODIMP CShellExt::XPropertySheetExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
+{
+    METHOD_PROLOGUE(CShellExt, PropertySheetExt);
+
+    if(pThis->m_bIsPathInAFS) {
+        // add the property page for files/folder/mount points/symlinks
+        PROPSHEETPAGE psp;
+        SecureZeroMemory(&psp, sizeof(PROPSHEETPAGE));
+        HPROPSHEETPAGE hPage;
+        CPropFile *sheetpage = NULL;
+
+        sheetpage = new CPropFile(pThis->m_astrFileNames);
+
+        if (sheetpage == NULL)
+            return E_OUTOFMEMORY;
+
+        HINSTANCE hInst = 0;
+        TaLocale_GetResource(RT_DIALOG, MAKEINTRESOURCE(IDD_PROPPAGE_FILE), LANG_USER_DEFAULT, &hInst);
+        sheetpage->m_hInst = hInst;
+        sheetpage->m_bIsMountpoint = pThis->m_bIsMountpoint;
+        sheetpage->m_bIsSymlink = pThis->m_bIsSymlink;
+        sheetpage->m_bIsDir=pThis->m_bDirSelected;
+        psp.dwSize = sizeof (psp);
+        psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK | PSP_USETITLE;
+        psp.hInstance = hInst;
+        psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_FILE);
+        psp.pszIcon = NULL;
+        psp.pszTitle = _T("AFS");
+        psp.pfnDlgProc = (DLGPROC) PageProc;
+        psp.lParam = (LPARAM) sheetpage;
+        psp.pfnCallback = PropPageCallbackProc;
+        psp.pcRefParent = (UINT*) &nPSRefCount;
+
+        hPage = CreatePropertySheetPage (&psp);
+
+        if (hPage != NULL) {
+            if (!lpfnAddPage (hPage, lParam)) {
+                delete sheetpage;
+                DestroyPropertySheetPage (hPage);
+            }
+        }
+    }
+
+    // add the property page for Volume Data
+    PROPSHEETPAGE psp;
+    SecureZeroMemory(&psp, sizeof(PROPSHEETPAGE));
+    HPROPSHEETPAGE hPage;
+    CPropVolume *sheetpage = NULL;
+
+    sheetpage = new CPropVolume(pThis->m_astrFileNames);
+
+    if (sheetpage == NULL)
+        return E_OUTOFMEMORY;
+
+    HINSTANCE hInst = 0;
+    TaLocale_GetResource(RT_DIALOG, MAKEINTRESOURCE(IDD_PROPPAGE_VOLUME), LANG_USER_DEFAULT, &hInst);
+    sheetpage->m_hInst = hInst;
+    sheetpage->m_bIsMountpoint = pThis->m_bIsMountpoint;
+    sheetpage->m_bIsSymlink = pThis->m_bIsSymlink;
+    sheetpage->m_bIsDir=pThis->m_bDirSelected;
+    psp.dwSize = sizeof (psp);
+    psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK | PSP_USETITLE;
+    psp.hInstance = hInst;
+    psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_VOLUME);
+    psp.pszIcon = NULL;
+    psp.pszTitle = _T("AFS Volume");
+    psp.pfnDlgProc = (DLGPROC) PageProc;
+    psp.lParam = (LPARAM) sheetpage;
+    psp.pfnCallback = PropPageCallbackProc;
+    psp.pcRefParent = (UINT*) &nPSRefCount;
+
+    hPage = CreatePropertySheetPage (&psp);
+
+    if (hPage != NULL) {
+        if (!lpfnAddPage (hPage, lParam)) {
+            delete sheetpage;
+            DestroyPropertySheetPage (hPage);
+        }
+    }
+
+    if(pThis->m_bDirSelected) {
+        // add the property page for ACLs
+        PROPSHEETPAGE psp;
+        SecureZeroMemory(&psp, sizeof(PROPSHEETPAGE));
+        HPROPSHEETPAGE hPage;
+        CPropACL *sheetpage = NULL;
+
+        sheetpage = new CPropACL(pThis->m_astrFileNames);
+
+        if (sheetpage == NULL)
+            return E_OUTOFMEMORY;
+
+        HINSTANCE hInst = 0;
+        TaLocale_GetResource(RT_DIALOG, MAKEINTRESOURCE(IDD_PROPPAGE_ACL), LANG_USER_DEFAULT, &hInst);
+        sheetpage->m_hInst = hInst;
+        sheetpage->m_bIsMountpoint = pThis->m_bIsMountpoint;
+        sheetpage->m_bIsSymlink = pThis->m_bIsSymlink;
+        sheetpage->m_bIsDir=pThis->m_bDirSelected;
+        psp.dwSize = sizeof (psp);
+        psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK | PSP_USETITLE;
+        psp.hInstance = hInst;
+        psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_ACL);
+        psp.pszIcon = NULL;
+        psp.pszTitle = _T("AFS ACL");
+        psp.pfnDlgProc = (DLGPROC) PageProc;
+        psp.lParam = (LPARAM) sheetpage;
+        psp.pfnCallback = PropPageCallbackProc;
+        psp.pcRefParent = (UINT*) &nPSRefCount;
+
+        hPage = CreatePropertySheetPage (&psp);
+
+        if (hPage != NULL) {
+            if (!lpfnAddPage (hPage, lParam)) {
+                delete sheetpage;
+                DestroyPropertySheetPage (hPage);
+            }
+        }
+    }
+
+    return S_OK;
+}
+
+STDMETHODIMP CShellExt::XPropertySheetExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam)
+{
+    return E_FAIL;
+}
index 9e0a9c7..3940703 100644 (file)
@@ -38,14 +38,15 @@ class CShellExt : public CCmdTarget
     DECLARE_DYNCREATE(CShellExt)
 
     BOOL m_bDirSelected;
-    BOOL m_bIsSymlink; // is symbolic link!
+    BOOL m_bIsSymlink;     // is symbolic link!
+    BOOL m_bIsMountpoint;      // is mount point!
+    BOOL m_bIsPathInAFS;    // path is in AFS
     TCHAR m_szFile[MAX_PATH];
     BOOL m_bIsOverlayEnabled;
     int  m_overlayObject;
     BOOL IsOverlayEnabled(){return m_bIsOverlayEnabled;}
 
     CStringArray m_astrFileNames;
-
     CShellExt();           // protected constructor used by dynamic creation
     LPMALLOC m_pAlloc;
 
@@ -114,6 +115,11 @@ protected:
         STDMETHOD(GetCurFile)(LPOLESTR FAR*);
     END_INTERFACE_PART(PersistFileExt)
 
+    BEGIN_INTERFACE_PART(PropertySheetExt, IShellPropSheetExt)
+        STDMETHOD(AddPages)(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam);
+        STDMETHOD(ReplacePage)(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam);
+    END_INTERFACE_PART(PropertySheetExt)
+
     DECLARE_INTERFACE_MAP()
 };
 
index 596c51f..bf4e390 100644 (file)
@@ -15,6 +15,7 @@
 #endif // _MSC_VER >= 1000
 
 #define VC_EXTRALEAN           // Exclude rarely-used stuff from Windows headers
+#define ISOLATION_AWARE_ENABLED 1
 
 // Don't include stuff we don't need.
 #define _AFX_NO_DB_SUPPORT
@@ -51,6 +52,7 @@
 #include "help.h"
 
 #include <WINNT/TaLocale.h>
+#include <afxdlgs.h>
 
 #if defined (_DEBUG) && defined (AFS_CRTDBG_MAP_ALLOC)
 #define new DEBUG_NEW
index 52d66f3..af8655b 100644 (file)
@@ -16,7 +16,7 @@ libafsconf.dll                 0x61780000    0x00080000
 libafstokens.dll               0x61800000    0x00080000
 afslogon.dll                   0x61880000    0x00080000
 afslog95.dll                   0x61900000    0x00080000
-afs_shl_ext.dll                0x61980000    0x00080000
+afs_shl_ext.dll                0x61980000    0x000A0000
 afsserver.cpl                  0x61A00000    0x00080000
 afs_cpa.cpl                    0x61A80000    0x00080000