[SHELLEXT][MYDOCS][INF] Add mydocs.dll and .mydocs file extension (#2624)

I found "SendTo My Documents" is realized by .mydocs filename extension in WinXP/2k3. To implement this, I will add mydocs.dll file. CORE-12562
This commit is contained in:
Katayama Hirofumi MZ 2020-04-22 19:34:15 +09:00 committed by GitHub
parent 333b7f254b
commit 4efff7f463
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 511 additions and 0 deletions

View file

@ -5,6 +5,7 @@ add_subdirectory(deskadp)
add_subdirectory(deskmon)
add_subdirectory(devcpux)
add_subdirectory(fontext)
add_subdirectory(mydocs)
add_subdirectory(netplwiz)
add_subdirectory(netshell)
add_subdirectory(ntobjshex)

View file

@ -0,0 +1,35 @@
set_cpp(WITH_RUNTIME)
spec2def(mydocs.dll mydocs.spec)
add_definitions(
-D_WINE
-D_ATL_NO_EXCEPTIONS)
if(NOT MSVC)
# HACK: this should be enabled globally!
add_compile_flags_language("-std=c++11" "CXX")
endif()
include_directories(
${REACTOS_SOURCE_DIR}/sdk/lib/atl
${REACTOS_SOURCE_DIR})
file(GLOB_RECURSE mydocs_rc_deps res/*.*)
add_rc_deps(mydocs.rc ${mydocs_rc_deps})
list(APPEND SOURCE
CMyDocsDropHandler.cpp
mydocs.cpp
precomp.hpp)
add_library(mydocs MODULE
${SOURCE}
mydocs.rc
${CMAKE_CURRENT_BINARY_DIR}/mydocs.def)
set_module_type(mydocs win32dll UNICODE)
target_link_libraries(mydocs uuid wine)
add_delay_importlibs(mydocs ole32 oleaut32)
add_importlibs(mydocs advapi32 shell32 user32 comctl32 shlwapi msvcrt kernel32 ntdll)
add_pch(mydocs precomp.hpp SOURCE)
add_cd_file(TARGET mydocs DESTINATION reactos/system32 FOR all)

View file

@ -0,0 +1,214 @@
/*
* PROJECT: mydocs
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: MyDocs implementation
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#include "precomp.hpp"
WINE_DEFAULT_DEBUG_CHANNEL(mydocs);
static CLIPFORMAT g_cfHIDA = 0;
CMyDocsDropHandler::CMyDocsDropHandler()
{
InterlockedIncrement(&g_ModuleRefCnt);
}
CMyDocsDropHandler::~CMyDocsDropHandler()
{
InterlockedDecrement(&g_ModuleRefCnt);
}
// IDropTarget
STDMETHODIMP
CMyDocsDropHandler::DragEnter(IDataObject *pDataObject, DWORD dwKeyState,
POINTL pt, DWORD *pdwEffect)
{
TRACE("(%p)\n", this);
*pdwEffect &= DROPEFFECT_COPY; // Copy only
return S_OK;
}
STDMETHODIMP
CMyDocsDropHandler::DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
TRACE("(%p)\n", this);
*pdwEffect &= DROPEFFECT_COPY; // Copy only
return S_OK;
}
STDMETHODIMP CMyDocsDropHandler::DragLeave()
{
TRACE("(%p)\n", this);
return S_OK;
}
STDMETHODIMP
CMyDocsDropHandler::Drop(IDataObject *pDataObject, DWORD dwKeyState,
POINTL pt, DWORD *pdwEffect)
{
TRACE("(%p)\n", this);
if (!pDataObject)
{
ERR("pDataObject is NULL\n");
*pdwEffect = 0;
DragLeave();
return E_POINTER;
}
CComPtr<IShellFolder> pDesktop;
HRESULT hr = SHGetDesktopFolder(&pDesktop);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
// get the clipboard format
if (g_cfHIDA == 0)
g_cfHIDA = ::RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
// Retrieve an HIDA (handle of IDA)
STGMEDIUM medium;
FORMATETC fmt = { g_cfHIDA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
hr = pDataObject->GetData(&fmt, &medium);
if (FAILED_UNEXPECTEDLY(hr))
{
*pdwEffect = 0;
DragLeave();
return E_FAIL;
}
// lock HIDA
LPIDA pida = reinterpret_cast<LPIDA>(GlobalLock(medium.hGlobal));
UINT iItem, cItems = pida->cidl;
// get the path of "My Documents"
WCHAR szzDir[MAX_PATH + 1];
SHGetSpecialFolderPathW(NULL, szzDir, CSIDL_PERSONAL, FALSE);
szzDir[lstrlenW(szzDir) + 1] = 0; // ends with double NULs
// for all source items
CStringW strSrcList;
WCHAR szSrc[MAX_PATH];
const BYTE *pb = reinterpret_cast<BYTE *>(pida);
PCIDLIST_ABSOLUTE pidlParent = reinterpret_cast<PCIDLIST_ABSOLUTE>(pb + pida->aoffset[0]);
for (iItem = 0; iItem < cItems; ++iItem)
{
// query source pidl
PCITEMID_CHILD pidlChild = reinterpret_cast<PCITEMID_CHILD>(pb + pida->aoffset[iItem + 1]);
CComHeapPtr<ITEMIDLIST> pidl(ILCombine(pidlParent, pidlChild));
// can get path?
szSrc[0] = 0;
if (!SHGetPathFromIDListW(pidl, szSrc))
{
// try to retrieve path from desktop
STRRET strret;
hr = pDesktop->GetDisplayNameOf(pidl, SHGDN_INFOLDER, &strret);
if (FAILED_UNEXPECTEDLY(hr))
break;
hr = StrRetToBufW(&strret, pidl, szSrc, _countof(szSrc));
if (FAILED_UNEXPECTEDLY(hr))
break;
if (!PathFileExistsW(szSrc))
break;
}
if (iItem > 0)
strSrcList += L'|'; // separator is '|'
strSrcList += szSrc;
}
// unlock HIDA
GlobalUnlock(medium.hGlobal);
if (iItem != cItems)
{
// source not found
CStringW strText;
strText.Format(IDS_NOSRCFILEFOUND, szSrc[0] ? szSrc : L"(null)");
MessageBoxW(NULL, strText, NULL, MB_ICONERROR);
*pdwEffect = 0;
DragLeave();
return E_FAIL;
}
strSrcList += L"||"; // double separators
// lock the buffer
LPWSTR pszzSrcList = strSrcList.GetBuffer();
// convert every separator to a NUL
INT cch = strSrcList.GetLength();
for (INT i = 0; i < cch; ++i)
{
if (pszzSrcList[i] == L'|')
pszzSrcList[i] = L'\0';
}
// copy them
SHFILEOPSTRUCTW fileop = { NULL };
fileop.wFunc = FO_COPY;
fileop.pFrom = pszzSrcList;
fileop.pTo = szzDir;
fileop.fFlags = FOF_ALLOWUNDO | FOF_FILESONLY | FOF_MULTIDESTFILES | FOF_NOCONFIRMMKDIR;
SHFileOperationW(&fileop);
// unlock buffer
strSrcList.ReleaseBuffer();
DragLeave();
return hr;
}
// IPersistFile
STDMETHODIMP CMyDocsDropHandler::GetCurFile(LPOLESTR *ppszFileName)
{
FIXME("(%p)\n", this);
return E_NOTIMPL;
}
STDMETHODIMP CMyDocsDropHandler::IsDirty()
{
FIXME("(%p)\n", this);
return E_NOTIMPL;
}
STDMETHODIMP CMyDocsDropHandler::Load(LPCOLESTR pszFileName, DWORD dwMode)
{
return S_OK;
}
STDMETHODIMP CMyDocsDropHandler::Save(LPCOLESTR pszFileName, BOOL fRemember)
{
FIXME("(%p)\n", this);
return E_NOTIMPL;
}
STDMETHODIMP CMyDocsDropHandler::SaveCompleted(LPCOLESTR pszFileName)
{
FIXME("(%p)\n", this);
return E_NOTIMPL;
}
// IPersist
STDMETHODIMP CMyDocsDropHandler::GetClassID(CLSID * lpClassId)
{
TRACE("(%p)\n", this);
if (!lpClassId)
{
ERR("lpClassId is NULL\n");
return E_POINTER;
}
*lpClassId = CLSID_MyDocsDropHandler;
return S_OK;
}

View file

@ -0,0 +1,50 @@
/*
* PROJECT: mydocs
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: MyDocs implementation
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#pragma once
#include "resource.h"
class CMyDocsDropHandler :
public CComCoClass<CMyDocsDropHandler, &CLSID_MyDocsDropHandler>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDropTarget,
public IPersistFile
{
public:
CMyDocsDropHandler();
~CMyDocsDropHandler();
// IDropTarget
STDMETHODIMP DragEnter(IDataObject *pDataObject, DWORD dwKeyState,
POINTL pt, DWORD *pdwEffect);
STDMETHODIMP DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
STDMETHODIMP DragLeave();
STDMETHODIMP Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt,
DWORD *pdwEffect);
// IPersist
STDMETHODIMP GetClassID(CLSID *lpClassId);
// IPersistFile
STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName);
STDMETHODIMP IsDirty();
STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode);
STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember);
STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName);
DECLARE_REGISTRY_RESOURCEID(IDR_MYDOCS)
DECLARE_NOT_AGGREGATABLE(CMyDocsDropHandler)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CMyDocsDropHandler)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
END_COM_MAP()
};

View file

@ -0,0 +1,6 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
STRINGTABLE
{
IDS_NOSRCFILEFOUND "Source file or folder '%ls' is not found."
}

View file

@ -0,0 +1,68 @@
/*
* PROJECT: mydocs
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: MyDocs implementation
* COPYRIGHT: Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#include "precomp.hpp"
WINE_DEFAULT_DEBUG_CHANNEL(mydocs);
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_MyDocsDropHandler, CMyDocsDropHandler)
END_OBJECT_MAP()
CComModule gModule;
LONG g_ModuleRefCnt = 0;
STDAPI DllCanUnloadNow(void)
{
if (g_ModuleRefCnt)
return S_FALSE;
return gModule.DllCanUnloadNow();
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
TRACE("CLSID:%s,IID:%s\n", wine_dbgstr_guid(&rclsid), wine_dbgstr_guid(&riid));
HRESULT hr = gModule.DllGetClassObject(rclsid, riid, ppv);
TRACE("-- pointer to class factory: %p\n", *ppv);
return hr;
}
STDAPI DllRegisterServer(void)
{
HRESULT hr = gModule.DllRegisterServer(FALSE);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return S_OK;
}
STDAPI DllUnregisterServer(void)
{
HRESULT hr = gModule.DllUnregisterServer(FALSE);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return S_OK;
}
STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad)
{
TRACE("%p 0x%x %p\n", hInstance, dwReason, fImpLoad);
if (dwReason == DLL_PROCESS_ATTACH)
{
gModule.Init(ObjectMap, hInstance, NULL);
DisableThreadLibraryCalls(hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
gModule.Term();
}
return TRUE;
}

View file

@ -0,0 +1,23 @@
/*
* PROJECT: mydocs
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: MyDocs implementation
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#include <windef.h>
#include <winuser.h>
#include "resource.h"
#include "mydocs_version.rc"
/* UTF-8 */
#pragma code_page(65001)
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDR_MYDOCS REGISTRY "res/mydocs.rgs"
#ifdef LANGUAGE_EN_US
#include "lang/en-US.rc"
#endif

View file

@ -0,0 +1,4 @@
@ stdcall -private DllCanUnloadNow()
@ stdcall -private DllGetClassObject(ptr ptr ptr)
@ stdcall -private DllRegisterServer()
@ stdcall -private DllUnregisterServer()

View file

@ -0,0 +1,15 @@
/*
* PROJECT: mydocs
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: MyDocs implementation
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#pragma once
#define WINE_FILEVERSION_MAJOR 6
#define WINE_FILEVERSION_MINOR 0
#define WINE_FILEVERSION_BUILD 3790
#define WINE_FILEVERSION_PLATFORMID 3959
#define WINE_FILEVERSION_STR "6.0.3790.3959"

View file

@ -0,0 +1,14 @@
/*
* PROJECT: mydocs
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: MyDocs implementation
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#include "mydocs_version.h"
#define WINE_OLESELFREGISTER
#define WINE_FILEVERSION WINE_FILEVERSION_MAJOR,WINE_FILEVERSION_MINOR,WINE_FILEVERSION_BUILD,WINE_FILEVERSION_PLATFORMID
#define WINE_FILENAME_STR "mydocs.dll"
#include <wine/wine_common_ver.rc>

View file

@ -0,0 +1,29 @@
/*
* PROJECT: mydocs
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: MyDocs implementation
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#define COBJMACROS
#define WIN32_NO_STATUS
#include <windows.h>
#include <shlwapi.h>
#include <shlobj.h>
#include <shobjidl.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <atlstr.h>
#include <shlguid_undoc.h>
#include <shellapi.h>
#include <shellutils.h>
#include <strsafe.h>
#include <wine/debug.h>
#include "CMyDocsDropHandler.hpp"
#include "mydocs_version.h"
#include "resource.h"
extern LONG g_ModuleRefCnt;

View file

@ -0,0 +1,35 @@
HKCR
{
NoRemove CLSID
{
'{ECF03A32-103D-11d2-854D-006008059367}' = s 'MyDocs Drop Target'
{
val 'NeverShowExt' = s ''
val 'NoOpen' = s 'Drag Files onto this icon to store them in My Documents'
val EditFlags = d '0x01'
DefaultIcon = e '%%SystemRoot%%\system32\shell32.dll,-235'
{
}
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'shellex'
{
'DropHandler' = s '{ECF03A32-103D-11d2-854D-006008059367}'
{
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Classes
{
'.mydocs' = s 'CLSID\{ECF03A32-103D-11d2-854D-006008059367}'
}
}
}

View file

@ -0,0 +1,15 @@
/*
* PROJECT: mydocs
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: MyDocs implementation
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#ifndef RESOURCE_H_
#define RESOURCE_H_
#define IDR_MYDOCS 100
#define IDS_NOSRCFILEFOUND 100
#endif

View file

@ -86,6 +86,7 @@ AddReg=Classes
11,,msxml3.dll,1
11,,msxml4.dll,1
11,,msxml6.dll,1
11,,mydocs.dll,1
11,,netshell.dll,1
11,,ntobjshex.dll,1
11,,objsel.dll,1

View file

@ -112,6 +112,7 @@ DEFINE_GUID(CLSID_ShellNetDefExt, 0x86422020, 0x42A0, 0x1069, 0xA2, 0xE
DEFINE_GUID(CLSID_ExeDropHandler, 0x86C86720, 0x42A0, 0x1069, 0xA2, 0xE8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
DEFINE_GUID(CLSID_DeskLinkDropHandler, 0x9E56BE61, 0xC50F, 0x11CF, 0x9A, 0x2C, 0x00, 0xA0, 0xC9, 0x0A, 0x90, 0xCE);
DEFINE_GUID(CLSID_MyDocsDropHandler, 0xECF03A32, 0x103D, 0x11d2, 0x85, 0x4D, 0x00, 0x60, 0x08, 0x05, 0x93, 0x67);
DEFINE_GUID(CLSID_MergedFolder, 0x26FDC864, 0xBE88, 0x46E7, 0x92, 0x35, 0x03, 0x2D, 0x8E, 0xA5, 0x16, 0x2E);
DEFINE_GUID(IID_IAugmentedShellFolder, 0x91EA3F8C, 0xC99B, 0x11D0, 0x98, 0x15, 0x00, 0xC0, 0x4F, 0xD9, 0x19, 0x72);