Skip to content

Commit

Permalink
[ZIPFLDR] Initial implementation.
Browse files Browse the repository at this point in the history
Icon by Jared Smudde
CORE-7684
  • Loading branch information
learn-more committed Apr 7, 2018
1 parent 5100859 commit c7e6a9d
Show file tree
Hide file tree
Showing 19 changed files with 2,105 additions and 0 deletions.
1 change: 1 addition & 0 deletions dll/shellext/CMakeLists.txt
Expand Up @@ -8,3 +8,4 @@ add_subdirectory(netshell)
add_subdirectory(ntobjshex)
add_subdirectory(shellbtrfs)
add_subdirectory(stobject)
add_subdirectory(zipfldr)
95 changes: 95 additions & 0 deletions dll/shellext/zipfldr/CEnumZipContents.cpp
@@ -0,0 +1,95 @@
/*
* PROJECT: ReactOS Zip Shell Extension
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: CEnumZipContents
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
*/

#include "precomp.h"

class CEnumZipContents :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IEnumIDList
{
private:
CZipEnumerator mEnumerator;
DWORD dwFlags;
CStringA m_Prefix;
public:
CEnumZipContents()
:dwFlags(0)
{
}

STDMETHODIMP Initialize(IZip* zip, DWORD flags, const char* prefix)
{
dwFlags = flags;
m_Prefix = prefix;
if (mEnumerator.initialize(zip))
return S_OK;
return E_FAIL;
}

// *** IEnumIDList methods ***
STDMETHODIMP Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched)
{
if (!pceltFetched || !rgelt)
return E_POINTER;

*pceltFetched = 0;

if (celt != 1)
return E_FAIL;

CStringA name;
bool dir;
unz_file_info64 info;
if (mEnumerator.next_unique(m_Prefix, name, dir, info))
{
*pceltFetched = 1;
*rgelt = _ILCreate(dir ? ZIP_PIDL_DIRECTORY : ZIP_PIDL_FILE, name, info);
return S_OK;
}

return S_FALSE;
}
STDMETHODIMP Skip(ULONG celt)
{
CStringA name;
bool dir;
unz_file_info64 info;
while (celt--)
{
if (!mEnumerator.next_unique(m_Prefix, name, dir, info))
return E_FAIL;
;
}
return S_OK;
}
STDMETHODIMP Reset()
{
if (mEnumerator.reset())
return S_OK;
return E_FAIL;
}
STDMETHODIMP Clone(IEnumIDList **ppenum)
{
return E_NOTIMPL;
}


public:
DECLARE_NOT_AGGREGATABLE(CEnumZipContents)
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CEnumZipContents)
COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
END_COM_MAP()
};


HRESULT _CEnumZipContents_CreateInstance(IZip* zip, DWORD flags, const char* prefix, REFIID riid, LPVOID * ppvOut)
{
return ShellObjectCreatorInit<CEnumZipContents>(zip, flags, prefix, riid, ppvOut);
}

189 changes: 189 additions & 0 deletions dll/shellext/zipfldr/CExplorerCommand.cpp
@@ -0,0 +1,189 @@
/*
* PROJECT: ReactOS Zip Shell Extension
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: IExplorerCommand implementation
* COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
*/

#include "precomp.h"

class CExplorerCommand :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IExplorerCommand
{
private:
CComPtr<IContextMenu> m_pZipObject;

public:

STDMETHODIMP Initialize(IContextMenu* zipObject)
{
m_pZipObject = zipObject;
return S_OK;
}

// *** IExplorerCommand methods ***
STDMETHODIMP GetTitle(IShellItemArray *psiItemArray, LPWSTR *ppszName)
{
CStringW Title(MAKEINTRESOURCEW(IDS_MENUITEM));
return SHStrDup(Title, ppszName);
}
STDMETHODIMP GetIcon(IShellItemArray *psiItemArray, LPWSTR *ppszIcon)
{
CStringW IconName = L"zipfldr.dll,-1";
return SHStrDup(IconName, ppszIcon);
}
STDMETHODIMP GetToolTip(IShellItemArray *psiItemArray, LPWSTR *ppszInfotip)
{
CStringW HelpText(MAKEINTRESOURCEW(IDS_HELPTEXT));
return SHStrDup(HelpText, ppszInfotip);
}
STDMETHODIMP GetCanonicalName(GUID *pguidCommandName)
{
*pguidCommandName = CLSID_ZipFolderExtractAllCommand;
return S_OK;
}
STDMETHODIMP GetState(IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState)
{
*pCmdState = ECS_ENABLED;
return S_OK;
}
STDMETHODIMP Invoke(IShellItemArray *psiItemArray, IBindCtx *pbc)
{
CMINVOKECOMMANDINFO cm = { sizeof(cm), 0 };
cm.lpVerb = EXTRACT_VERBA;
cm.nShow = SW_SHOW;
return m_pZipObject->InvokeCommand(&cm);
}
STDMETHODIMP GetFlags(EXPCMDFLAGS *pFlags)
{
*pFlags = ECF_DEFAULT;
return S_OK;
}
STDMETHODIMP EnumSubCommands(IEnumExplorerCommand **ppEnum)
{
DbgPrint("%s\n", __FUNCTION__);
return E_NOTIMPL;
}

public:
DECLARE_NOT_AGGREGATABLE(CExplorerCommand)
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CExplorerCommand)
COM_INTERFACE_ENTRY_IID(IID_IExplorerCommand, IExplorerCommand)
END_COM_MAP()
};


class CEnumExplorerCommand :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IEnumExplorerCommand
{
private:
bool m_bFirst;
CComPtr<IContextMenu> m_pZipObject;

public:

CEnumExplorerCommand()
:m_bFirst(true)
{
}

STDMETHODIMP Initialize(IContextMenu* zipObject)
{
m_pZipObject = zipObject;
return S_OK;
}

// *** IEnumExplorerCommand methods ***
STDMETHODIMP Next(ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched)
{
if (!pUICommand)
return E_POINTER;

if (pceltFetched)
*pceltFetched = 0;
if (m_bFirst && celt)
{
m_bFirst = false;
celt--;
HRESULT hr = ShellObjectCreatorInit<CExplorerCommand>(m_pZipObject, IID_PPV_ARG(IExplorerCommand, pUICommand));
if (SUCCEEDED(hr))
{
if (pceltFetched)
*pceltFetched = 1;
}
return hr;
}
return S_FALSE;
}
STDMETHODIMP Skip(ULONG celt)
{
if (m_bFirst)
{
m_bFirst = false;
return S_OK;
}
return S_FALSE;
}
STDMETHODIMP Reset()
{
m_bFirst = true;
return S_OK;
}
STDMETHODIMP Clone(IEnumExplorerCommand **ppenum)
{
return E_NOTIMPL;
}

public:
DECLARE_NOT_AGGREGATABLE(CEnumExplorerCommand)
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CEnumExplorerCommand)
COM_INTERFACE_ENTRY_IID(IID_IEnumExplorerCommand, IEnumExplorerCommand)
END_COM_MAP()
};

class CExplorerCommandProvider :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IExplorerCommandProvider
{
private:
CComPtr<IContextMenu> m_pZipObject;

public:
STDMETHODIMP Initialize(IContextMenu* zipObject)
{
m_pZipObject = zipObject;
return S_OK;
}

// *** IExplorerCommandProvider methods ***
STDMETHODIMP GetCommands(IUnknown *punkSite, REFIID riid, void **ppv)
{
return ShellObjectCreatorInit<CEnumExplorerCommand>(m_pZipObject, riid, ppv);
}
STDMETHODIMP GetCommand(REFGUID rguidCommandId, REFIID riid, void **ppv)
{
UNIMPLEMENTED;
*ppv = NULL;
return E_NOTIMPL;
}

public:
DECLARE_NOT_AGGREGATABLE(CExplorerCommandProvider)
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CExplorerCommandProvider)
COM_INTERFACE_ENTRY_IID(IID_IExplorerCommandProvider, IExplorerCommandProvider)
END_COM_MAP()
};


HRESULT _CExplorerCommandProvider_CreateInstance(IContextMenu* zipObject, REFIID riid, LPVOID * ppvOut)
{
return ShellObjectCreatorInit<CExplorerCommandProvider>(zipObject, riid, ppvOut);
}
54 changes: 54 additions & 0 deletions dll/shellext/zipfldr/CFolderViewCB.cpp
@@ -0,0 +1,54 @@
/*
* PROJECT: ReactOS Zip Shell Extension
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: IShellFolderViewCB implementation
* COPYRIGHT: Copyright 2017 David Quintana (gigaherz@gmail.com)
* Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
*/

#include "precomp.h"

class CFolderViewCB :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolderViewCB
{
public:

virtual ~CFolderViewCB()
{
}

// *** IShellFolderViewCB methods ***
STDMETHODIMP MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
/* TODO: Handle SFVM_GET_WEBVIEW_CONTENT to add tasks */
switch (uMsg)
{
case SFVM_DEFVIEWMODE:
{
FOLDERVIEWMODE* pViewMode = (FOLDERVIEWMODE*)lParam;
*pViewMode = FVM_DETAILS;
return S_OK;
}
case SFVM_COLUMNCLICK:
return S_FALSE;
case SFVM_BACKGROUNDENUM:
return S_OK;
}

return E_NOTIMPL;
}

public:
DECLARE_NOT_AGGREGATABLE(CFolderViewCB)
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CFolderViewCB)
COM_INTERFACE_ENTRY_IID(IID_IShellFolderViewCB, IShellFolderViewCB)
END_COM_MAP()
};

HRESULT _CFolderViewCB_CreateInstance(REFIID riid, LPVOID * ppvOut)
{
return ShellObjectCreator<CFolderViewCB>(riid, ppvOut);
}
50 changes: 50 additions & 0 deletions dll/shellext/zipfldr/CMakeLists.txt
@@ -0,0 +1,50 @@

set_cpp(WITH_RUNTIME WITH_EXCEPTIONS)
if(NOT MSVC)
# HACK: this should be enabled globally!
add_compile_flags_language("-std=c++11" "CXX")
endif()

remove_definitions(-D_WIN32_WINNT=0x502)
add_definitions(-D_WIN32_WINNT=0x600)

add_definitions(
-D_ATL_NO_EXCEPTIONS)

include_directories(
${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/zlib
${REACTOS_SOURCE_DIR}/sdk/lib/atl
${REACTOS_SOURCE_DIR}/sdk/lib/3rdparty/zlib/contrib)

spec2def(zipfldr.dll zipfldr.spec ADD_IMPORTLIB)


list(APPEND SOURCE
zipfldr.cpp
zippidl.cpp
zippidl.hpp
IZip.hpp
CExplorerCommand.cpp
CEnumZipContents.cpp
CFolderViewCB.cpp
CZipEnumerator.hpp
CZipExtract.cpp
CZipFolder.hpp
Debug.cpp
zipfldr.spec
precomp.h
resource.h)

add_library(zipfldr SHARED
${SOURCE}
${ZLIB_SOURCE}
zipfldr.rc
${CMAKE_CURRENT_BINARY_DIR}/zipfldr.def)


set_module_type(zipfldr win32dll UNICODE)
target_link_libraries(zipfldr minizip zlib atlnew uuid)
add_importlibs(zipfldr oleaut32 ole32 shlwapi comctl32 shell32 user32 advapi32 msvcrt kernel32 ntdll)
add_pch(zipfldr precomp.h SOURCE)
add_cd_file(TARGET zipfldr DESTINATION reactos/system32 FOR all)

0 comments on commit c7e6a9d

Please sign in to comment.