"Fossies" - the Fresh Open Source Software Archive

Member "seafile-client-7.0.4/extensions/shell-ext.cpp" (19 Nov 2019, 4857 Bytes) of package /linux/www/seafile-client-7.0.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "shell-ext.cpp" see the Fossies "Dox" file reference documentation.

    1 // Initialize GUIDs (should be done only and at-least once per DLL/EXE)
    2 #include <initguid.h>
    3 #include "guids.h"
    4 
    5 #include "ext-common.h"
    6 #include "ext-utils.h"
    7 #include "commands.h"
    8 #include "log.h"
    9 #include "shell-ext.h"
   10 
   11 namespace utils = seafile::utils;
   12 
   13 namespace {
   14 
   15 const int kWorktreeCacheExpireMSecs = 3 * 1000;
   16 
   17 } // namespace
   18 
   19 std::unique_ptr<seafile::RepoInfoList> ShellExt::repos_cache_;
   20 uint64_t ShellExt::cache_ts_;
   21 
   22 // *********************** ShellExt *************************
   23 ShellExt::ShellExt(seafile::RepoInfo::Status status)
   24   : main_menu_(0),
   25     index_(0),
   26     first_(0),
   27     last_(0)
   28 {
   29     m_cRef = 0L;
   30     InterlockedIncrement(&g_cRefThisDll);
   31 
   32     sub_menu_ = CreateMenu();
   33     next_active_item_ = 0;
   34     status_ = status;
   35 
   36     // INITCOMMONCONTROLSEX used = {
   37     //     sizeof(INITCOMMONCONTROLSEX),
   38     //         ICC_LISTVIEW_CLASSES | ICC_WIN95_CLASSES | ICC_BAR_CLASSES | ICC_USEREX_CLASSES
   39     // };
   40     // InitCommonControlsEx(&used);
   41 }
   42 
   43 ShellExt::~ShellExt()
   44 {
   45     InterlockedDecrement(&g_cRefThisDll);
   46 }
   47 
   48 STDMETHODIMP ShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv)
   49 {
   50     if (ppv == 0)
   51         return E_POINTER;
   52 
   53     *ppv = NULL;
   54 
   55     if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown)) {
   56         *ppv = static_cast<LPSHELLEXTINIT>(this);
   57     }
   58     else if (IsEqualIID(riid, IID_IContextMenu)) {
   59         *ppv = static_cast<LPCONTEXTMENU>(this);
   60     }
   61     else if (IsEqualIID(riid, IID_IShellIconOverlayIdentifier)) {
   62         *ppv = static_cast<IShellIconOverlayIdentifier*>(this);
   63     }
   64     // else if (IsEqualIID(riid, IID_IContextMenu3))
   65     // {
   66     //     *ppv = static_cast<LPCONTEXTMENU3>(this);
   67     // }
   68     else
   69     {
   70         return E_NOINTERFACE;
   71     }
   72 
   73     AddRef();
   74     return S_OK;
   75 }
   76 
   77 STDMETHODIMP_(ULONG) ShellExt::AddRef()
   78 {
   79     return ++m_cRef;
   80 }
   81 
   82 STDMETHODIMP_(ULONG) ShellExt::Release()
   83 {
   84     if (--m_cRef)
   85         return m_cRef;
   86 
   87     delete this;
   88 
   89     return 0L;
   90 }
   91 
   92 bool ShellExt::getReposList(seafile::RepoInfoList *wts)
   93 {
   94     seafile::utils::MutexLocker lock(&repos_cache_mutex_);
   95 
   96     uint64_t now = utils::currentMSecsSinceEpoch();
   97     if (repos_cache_ && now < cache_ts_ + kWorktreeCacheExpireMSecs) {
   98         *wts = *(repos_cache_.get());
   99         // seaf_ext_log("use cached repos list!");
  100         return true;
  101     }
  102 
  103     // no cached worktree list, send request to seafile client
  104     seafile::ListReposCommand cmd;
  105     seafile::RepoInfoList repos;
  106     if (!cmd.sendAndWait(&repos)) {
  107         // seaf_ext_log("ListReposCommand returned false!");
  108         return false;
  109     }
  110 
  111     cache_ts_ = utils::currentMSecsSinceEpoch();
  112     repos_cache_.reset(new seafile::RepoInfoList(repos));
  113 
  114     *wts = repos;
  115     return true;
  116 }
  117 
  118 bool ShellExt::pathInRepo(const std::string& path,
  119                           std::string *path_in_repo,
  120                           seafile::RepoInfo *repo)
  121 {
  122     seafile::RepoInfoList repos;
  123     if (!getReposList(&repos)) {
  124         return false;
  125     }
  126     std::string p = utils::normalizedPath(path);
  127 
  128     for (size_t i = 0; i < repos.size(); i++) {
  129         std::string wt = repos[i].worktree;
  130         // seaf_ext_log ("work tree is %s, path is %s\n", wt.c_str(), p.c_str());
  131         if (p.size() >= wt.size() && p.substr(0, wt.size()) == wt) {
  132             if (p.size() > wt.size() && p[wt.size()] != '/') {
  133                 continue;
  134             }
  135             *path_in_repo = p.substr(wt.size(), p.size() - wt.size());
  136             if (repo) {
  137                 *repo = repos[i];
  138             }
  139             return true;
  140         }
  141     }
  142 
  143     return false;
  144 }
  145 
  146 bool ShellExt::isRepoTopDir(const std::string& path)
  147 {
  148     seafile::RepoInfoList repos;
  149     if (!getReposList(&repos)) {
  150         return false;
  151     }
  152 
  153     std::string p = utils::normalizedPath(path);
  154     for (size_t i = 0; i < repos.size(); i++) {
  155         std::string wt = repos[i].worktree;
  156         if (p == wt) {
  157             return true;
  158         }
  159     }
  160 
  161     return false;
  162 }
  163 
  164 seafile::RepoInfo ShellExt::getRepoInfoByPath(const std::string& path)
  165 {
  166     seafile::RepoInfoList repos;
  167     if (!getReposList(&repos)) {
  168         return seafile::RepoInfo();
  169     }
  170 
  171     std::string p = utils::normalizedPath(path);
  172     for (size_t i = 0; i < repos.size(); i++) {
  173         std::string wt = repos[i].worktree;
  174         if (p == wt) {
  175             return repos[i];
  176         }
  177     }
  178 
  179     return seafile::RepoInfo();
  180 }
  181 
  182 seafile::RepoInfo::Status
  183 ShellExt::getRepoFileStatus(const std::string& repo_id,
  184                             const std::string& path_in_repo,
  185                             bool isdir)
  186 {
  187     // TODO: get the files under the same folder in a single command to reduce overhead
  188     seafile::GetFileStatusCommand cmd(repo_id, path_in_repo, isdir);
  189     seafile::RepoInfo::Status status;
  190     if (!cmd.sendAndWait(&status)) {
  191         return seafile::RepoInfo::NoStatus;
  192     }
  193 
  194     return status;
  195 }