Reactos
at master 175 lines 4.2 kB view raw
1/* 2 * PROJECT: sendmail 3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+) 4 * PURPOSE: DeskLink implementation 5 * COPYRIGHT: Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 6 */ 7 8#include "precomp.hpp" 9 10WINE_DEFAULT_DEBUG_CHANNEL(sendmail); 11 12BEGIN_OBJECT_MAP(ObjectMap) 13 OBJECT_ENTRY(CLSID_DeskLinkDropHandler, CDeskLinkDropHandler) 14END_OBJECT_MAP() 15 16CComModule gModule; 17LONG g_ModuleRefCnt = 0; 18HINSTANCE g_hModule; 19 20static BOOL 21CreateEmptyFile(LPCWSTR pszFile) 22{ 23 HANDLE hFile; 24 hFile = CreateFileW(pszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, 25 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 26 if (hFile != INVALID_HANDLE_VALUE) 27 { 28 CloseHandle(hFile); 29 return TRUE; 30 } 31 return FALSE; 32} 33 34static HRESULT 35CreateSendToDeskLink(LPCWSTR pszSendTo) 36{ 37 WCHAR szTarget[MAX_PATH], szSendToFile[MAX_PATH]; 38 39 LoadStringW(g_hModule, IDS_DESKLINK, szTarget, _countof(szTarget)); 40 StringCbCatW(szTarget, sizeof(szTarget), L".DeskLink"); 41 42 StringCbCopyW(szSendToFile, sizeof(szSendToFile), pszSendTo); 43 PathAppendW(szSendToFile, szTarget); 44 45 if (!CreateEmptyFile(szSendToFile)) 46 { 47 ERR("CreateEmptyFile('%ls')\n", szSendToFile); 48 return E_FAIL; 49 } 50 return S_OK; 51} 52 53static HRESULT 54GetDefaultUserSendTo(LPWSTR pszPath) 55{ 56 return SHGetFolderPathW(NULL, CSIDL_SENDTO, INVALID_HANDLE_VALUE, 57 SHGFP_TYPE_DEFAULT, pszPath); 58} 59 60STDAPI DllCanUnloadNow(void) 61{ 62 if (g_ModuleRefCnt) 63 return S_FALSE; 64 return gModule.DllCanUnloadNow(); 65} 66 67STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 68{ 69 TRACE("CLSID:%s,IID:%s\n", wine_dbgstr_guid(&rclsid), wine_dbgstr_guid(&riid)); 70 71 HRESULT hr = gModule.DllGetClassObject(rclsid, riid, ppv); 72 73 TRACE("-- pointer to class factory: %p\n", *ppv); 74 75 return hr; 76} 77 78STDAPI DllRegisterServer(void) 79{ 80 HRESULT hr = gModule.DllRegisterServer(FALSE); 81 if (FAILED_UNEXPECTEDLY(hr)) 82 return hr; 83 84 WCHAR szSendTo[MAX_PATH]; 85 hr = GetDefaultUserSendTo(szSendTo); 86 if (SUCCEEDED(hr)) 87 CreateSendToDeskLink(szSendTo); 88 89 return S_OK; 90} 91 92STDAPI DllUnregisterServer(void) 93{ 94 HRESULT hr = gModule.DllUnregisterServer(FALSE); 95 if (FAILED_UNEXPECTEDLY(hr)) 96 return hr; 97 98 return S_OK; 99} 100 101HRESULT 102CreateShellLink( 103 LPCWSTR pszLinkPath, 104 LPCWSTR pszTargetPath OPTIONAL, 105 LPCITEMIDLIST pidlTarget OPTIONAL, 106 LPCWSTR pszArg OPTIONAL, 107 LPCWSTR pszDir OPTIONAL, 108 LPCWSTR pszIconPath OPTIONAL, 109 INT iIconNr OPTIONAL, 110 LPCWSTR pszComment OPTIONAL) 111{ 112 CComPtr<IShellLinkW> psl; 113 HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, 114 CLSCTX_INPROC_SERVER, 115 IID_PPV_ARG(IShellLinkW, &psl)); 116 if (FAILED_UNEXPECTEDLY(hr)) 117 return hr; 118 119 if (pszTargetPath) 120 { 121 hr = psl->SetPath(pszTargetPath); 122 if (FAILED_UNEXPECTEDLY(hr)) 123 return hr; 124 } 125 else if (pidlTarget) 126 { 127 hr = psl->SetIDList(pidlTarget); 128 if (FAILED_UNEXPECTEDLY(hr)) 129 return hr; 130 } 131 else 132 { 133 ERR("invalid argument\n"); 134 return E_INVALIDARG; 135 } 136 137 if (pszArg) 138 hr = psl->SetArguments(pszArg); 139 140 if (pszDir) 141 hr = psl->SetWorkingDirectory(pszDir); 142 143 if (pszIconPath) 144 hr = psl->SetIconLocation(pszIconPath, iIconNr); 145 146 if (pszComment) 147 hr = psl->SetDescription(pszComment); 148 149 CComPtr<IPersistFile> ppf; 150 hr = psl->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf)); 151 if (FAILED_UNEXPECTEDLY(hr)) 152 return hr; 153 154 hr = ppf->Save(pszLinkPath, TRUE); 155 if (FAILED_UNEXPECTEDLY(hr)) 156 return hr; 157 158 return hr; 159} 160 161STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad) 162{ 163 TRACE("%p 0x%x %p\n", hInstance, dwReason, fImpLoad); 164 if (dwReason == DLL_PROCESS_ATTACH) 165 { 166 g_hModule = hInstance; 167 gModule.Init(ObjectMap, hInstance, NULL); 168 DisableThreadLibraryCalls(hInstance); 169 } 170 else if (dwReason == DLL_PROCESS_DETACH) 171 { 172 gModule.Term(); 173 } 174 return TRUE; 175}