1 /* 2 * Common Dialog Boxes interface (32 bit) 3 * Find/Replace 4 * 5 * Copyright 1999 Bertho A. Stultiens 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include <stdarg.h> 23 24 #define COBJMACROS 25 26 #include "windef.h" 27 #include "winbase.h" 28 #include "wingdi.h" 29 #include "winuser.h" 30 #include "objbase.h" 31 #include "rpcproxy.h" 32 #include "commdlg.h" 33 #include "cderr.h" 34 #include "wine/debug.h" 35 36 WINE_DEFAULT_DEBUG_CHANNEL(commdlg); 37 38 #include "cdlg.h" 39 40 41 DECLSPEC_HIDDEN HINSTANCE COMDLG32_hInstance = 0; 42 43 static DWORD COMDLG32_TlsIndex = TLS_OUT_OF_INDEXES; 44 45 static HINSTANCE SHELL32_hInstance; 46 static HINSTANCE SHFOLDER_hInstance; 47 48 /* ITEMIDLIST */ 49 LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILClone) (LPCITEMIDLIST) DECLSPEC_HIDDEN; 50 LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILCombine)(LPCITEMIDLIST,LPCITEMIDLIST) DECLSPEC_HIDDEN; 51 LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILGetNext)(LPITEMIDLIST) DECLSPEC_HIDDEN; 52 BOOL (WINAPI *COMDLG32_PIDL_ILRemoveLastID)(LPCITEMIDLIST) DECLSPEC_HIDDEN; 53 BOOL (WINAPI *COMDLG32_PIDL_ILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST) DECLSPEC_HIDDEN; 54 UINT (WINAPI *COMDLG32_PIDL_ILGetSize)(LPCITEMIDLIST) DECLSPEC_HIDDEN; 55 56 /* SHELL */ 57 LPVOID (WINAPI *COMDLG32_SHAlloc)(DWORD) DECLSPEC_HIDDEN; 58 DWORD (WINAPI *COMDLG32_SHFree)(LPVOID) DECLSPEC_HIDDEN; 59 BOOL (WINAPI *COMDLG32_SHGetFolderPathW)(HWND,int,HANDLE,DWORD,LPWSTR) DECLSPEC_HIDDEN; 60 LPITEMIDLIST (WINAPI *COMDLG32_SHSimpleIDListFromPathAW)(LPCVOID) DECLSPEC_HIDDEN; 61 62 /*********************************************************************** 63 * DllMain (COMDLG32.init) 64 * 65 * Initialization code for the COMDLG32 DLL 66 * 67 * RETURNS: 68 * FALSE if sibling could not be loaded or instantiated twice, TRUE 69 * otherwise. 70 */ 71 static const char GPA_string[] = "Failed to get entry point %s for hinst = %p\n"; 72 #define GPA(dest, hinst, name) \ 73 if(!(dest = (void*)GetProcAddress(hinst,name)))\ 74 { \ 75 ERR(GPA_string, debugstr_a(name), hinst); \ 76 return FALSE; \ 77 } 78 79 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) 80 { 81 TRACE("(%p, %d, %p)\n", hInstance, Reason, Reserved); 82 83 switch(Reason) 84 { 85 case DLL_PROCESS_ATTACH: 86 COMDLG32_hInstance = hInstance; 87 DisableThreadLibraryCalls(hInstance); 88 89 SHELL32_hInstance = GetModuleHandleA("SHELL32.DLL"); 90 91 /* ITEMIDLIST */ 92 GPA(COMDLG32_PIDL_ILIsEqual, SHELL32_hInstance, (LPCSTR)21L); 93 GPA(COMDLG32_PIDL_ILCombine, SHELL32_hInstance, (LPCSTR)25L); 94 GPA(COMDLG32_PIDL_ILGetNext, SHELL32_hInstance, (LPCSTR)153L); 95 GPA(COMDLG32_PIDL_ILClone, SHELL32_hInstance, (LPCSTR)18L); 96 GPA(COMDLG32_PIDL_ILRemoveLastID, SHELL32_hInstance, (LPCSTR)17L); 97 GPA(COMDLG32_PIDL_ILGetSize, SHELL32_hInstance, (LPCSTR)152L); 98 99 /* SHELL */ 100 GPA(COMDLG32_SHSimpleIDListFromPathAW, SHELL32_hInstance, (LPCSTR)162); 101 GPA(COMDLG32_SHAlloc, SHELL32_hInstance, (LPCSTR)196L); 102 GPA(COMDLG32_SHFree, SHELL32_hInstance, (LPCSTR)195L); 103 104 /* for the first versions of shell32 SHGetFolderPathW is in SHFOLDER.DLL */ 105 COMDLG32_SHGetFolderPathW = (void*)GetProcAddress(SHELL32_hInstance,"SHGetFolderPathW"); 106 if (!COMDLG32_SHGetFolderPathW) 107 { 108 SHFOLDER_hInstance = LoadLibraryA("SHFOLDER.DLL"); 109 GPA(COMDLG32_SHGetFolderPathW, SHFOLDER_hInstance,"SHGetFolderPathW"); 110 } 111 112 break; 113 114 case DLL_PROCESS_DETACH: 115 if (Reserved) break; 116 if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) TlsFree(COMDLG32_TlsIndex); 117 if(SHFOLDER_hInstance) FreeLibrary(SHFOLDER_hInstance); 118 break; 119 } 120 return TRUE; 121 } 122 #undef GPA 123 124 /*********************************************************************** 125 * COMDLG32_AllocMem (internal) 126 * Get memory for internal datastructure plus stringspace etc. 127 * RETURNS 128 * Success: Pointer to a heap block 129 * Failure: null 130 */ 131 LPVOID COMDLG32_AllocMem( 132 int size /* [in] Block size to allocate */ 133 ) { 134 LPVOID ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 135 if(!ptr) 136 { 137 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE); 138 return NULL; 139 } 140 return ptr; 141 } 142 143 144 /*********************************************************************** 145 * COMDLG32_SetCommDlgExtendedError (internal) 146 * 147 * Used to set the thread's local error value if a comdlg32 function fails. 148 */ 149 void COMDLG32_SetCommDlgExtendedError(DWORD err) 150 { 151 TRACE("(%08x)\n", err); 152 if (COMDLG32_TlsIndex == TLS_OUT_OF_INDEXES) 153 COMDLG32_TlsIndex = TlsAlloc(); 154 if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) 155 TlsSetValue(COMDLG32_TlsIndex, (LPVOID)(DWORD_PTR)err); 156 else 157 FIXME("No Tls Space\n"); 158 } 159 160 161 /*********************************************************************** 162 * CommDlgExtendedError (COMDLG32.@) 163 * 164 * Get the thread's local error value if a comdlg32 function fails. 165 * RETURNS 166 * Current error value which might not be valid 167 * if a previous call succeeded. 168 */ 169 DWORD WINAPI CommDlgExtendedError(void) 170 { 171 if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) 172 return (DWORD_PTR)TlsGetValue(COMDLG32_TlsIndex); 173 else 174 return 0; /* we never set an error, so there isn't one */ 175 } 176 177 #ifndef __REACTOS__ /* Win 7 */ 178 179 /************************************************************************* 180 * Implement the CommDlg32 class factory 181 * 182 * (Taken from shdocvw/factory.c; based on implementation in 183 * ddraw/main.c) 184 */ 185 typedef struct 186 { 187 IClassFactory IClassFactory_iface; 188 HRESULT (*cf)(IUnknown*, REFIID, void**); 189 } IClassFactoryImpl; 190 191 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) 192 { 193 return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); 194 } 195 196 /************************************************************************* 197 * CDLGCF_QueryInterface (IUnknown) 198 */ 199 static HRESULT WINAPI CDLGCF_QueryInterface(IClassFactory* iface, 200 REFIID riid, void **ppobj) 201 { 202 TRACE("%p (%s %p)\n", iface, debugstr_guid(riid), ppobj); 203 204 if(!ppobj) 205 return E_POINTER; 206 207 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) 208 { 209 *ppobj = iface; 210 IClassFactory_AddRef(iface); 211 return S_OK; 212 } 213 214 WARN("Interface not supported.\n"); 215 216 *ppobj = NULL; 217 return E_NOINTERFACE; 218 } 219 220 /************************************************************************* 221 * CDLGCF_AddRef (IUnknown) 222 */ 223 static ULONG WINAPI CDLGCF_AddRef(IClassFactory *iface) 224 { 225 return 2; /* non-heap based object */ 226 } 227 228 /************************************************************************* 229 * CDLGCF_Release (IUnknown) 230 */ 231 static ULONG WINAPI CDLGCF_Release(IClassFactory *iface) 232 { 233 return 1; /* non-heap based object */ 234 } 235 236 /************************************************************************* 237 * CDLGCF_CreateInstance (IClassFactory) 238 */ 239 static HRESULT WINAPI CDLGCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, 240 REFIID riid, void **ppobj) 241 { 242 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 243 return This->cf(pOuter, riid, ppobj); 244 } 245 246 /************************************************************************* 247 * CDLGCF_LockServer (IClassFactory) 248 */ 249 static HRESULT WINAPI CDLGCF_LockServer(IClassFactory *iface, BOOL dolock) 250 { 251 TRACE("%p (%d)\n", iface, dolock); 252 return S_OK; 253 } 254 255 static const IClassFactoryVtbl CDLGCF_Vtbl = 256 { 257 CDLGCF_QueryInterface, 258 CDLGCF_AddRef, 259 CDLGCF_Release, 260 CDLGCF_CreateInstance, 261 CDLGCF_LockServer 262 }; 263 264 /************************************************************************* 265 * DllGetClassObject (COMMDLG32.@) 266 */ 267 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) 268 { 269 static IClassFactoryImpl FileOpenDlgClassFactory = {{&CDLGCF_Vtbl}, FileOpenDialog_Constructor}; 270 static IClassFactoryImpl FileSaveDlgClassFactory = {{&CDLGCF_Vtbl}, FileSaveDialog_Constructor}; 271 272 TRACE("%s, %s, %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); 273 274 if(IsEqualGUID(&CLSID_FileOpenDialog, rclsid)) 275 return IClassFactory_QueryInterface(&FileOpenDlgClassFactory.IClassFactory_iface, riid, ppv); 276 277 if(IsEqualGUID(&CLSID_FileSaveDialog, rclsid)) 278 return IClassFactory_QueryInterface(&FileSaveDlgClassFactory.IClassFactory_iface, riid, ppv); 279 280 return CLASS_E_CLASSNOTAVAILABLE; 281 } 282 283 /*********************************************************************** 284 * DllRegisterServer (COMMDLG32.@) 285 */ 286 HRESULT WINAPI DllRegisterServer(void) 287 { 288 #ifdef __REACTOS__ 289 return E_FAIL; // FIXME: __wine_register_resources(COMDLG32_hInstance); 290 #else 291 return __wine_register_resources(COMDLG32_hInstance); 292 #endif 293 } 294 295 /*********************************************************************** 296 * DllUnregisterServer (COMMDLG32.@) 297 */ 298 HRESULT WINAPI DllUnregisterServer(void) 299 { 300 #ifdef __REACTOS__ 301 return E_FAIL; // FIXME: __wine_unregister_resources(COMDLG32_hInstance); 302 #else 303 return __wine_unregister_resources(COMDLG32_hInstance); 304 #endif 305 } 306 307 #endif /* Win 7 */ 308