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 #include "wine/heap.h" 36 37 WINE_DEFAULT_DEBUG_CHANNEL(commdlg); 38 39 #include "cdlg.h" 40 41 42 DECLSPEC_HIDDEN HINSTANCE COMDLG32_hInstance = 0; 43 #ifdef __REACTOS__ 44 CRITICAL_SECTION COMDLG32_OpenFileLock DECLSPEC_HIDDEN; 45 #endif 46 47 static DWORD COMDLG32_TlsIndex = TLS_OUT_OF_INDEXES; 48 49 static HINSTANCE SHELL32_hInstance; 50 51 /* SHELL */ 52 LPITEMIDLIST (WINAPI *COMDLG32_SHSimpleIDListFromPathAW)(LPCVOID) DECLSPEC_HIDDEN; 53 54 /*********************************************************************** 55 * DllMain (COMDLG32.init) 56 * 57 * Initialization code for the COMDLG32 DLL 58 * 59 * RETURNS: 60 * FALSE if sibling could not be loaded or instantiated twice, TRUE 61 * otherwise. 62 */ 63 static const char GPA_string[] = "Failed to get entry point %s for hinst = %p\n"; 64 #define GPA(dest, hinst, name) \ 65 if(!(dest = (void*)GetProcAddress(hinst,name)))\ 66 { \ 67 ERR(GPA_string, debugstr_a(name), hinst); \ 68 return FALSE; \ 69 } 70 71 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) 72 { 73 TRACE("(%p, %d, %p)\n", hInstance, Reason, Reserved); 74 75 switch(Reason) 76 { 77 case DLL_PROCESS_ATTACH: 78 COMDLG32_hInstance = hInstance; 79 DisableThreadLibraryCalls(hInstance); 80 81 SHELL32_hInstance = GetModuleHandleA("SHELL32.DLL"); 82 #ifdef __REACTOS__ 83 InitializeCriticalSection(&COMDLG32_OpenFileLock); 84 #endif 85 86 /* SHELL */ 87 GPA(COMDLG32_SHSimpleIDListFromPathAW, SHELL32_hInstance, (LPCSTR)162); 88 break; 89 90 case DLL_PROCESS_DETACH: 91 if (Reserved) break; 92 if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) TlsFree(COMDLG32_TlsIndex); 93 #ifdef __REACTOS__ 94 DeleteCriticalSection(&COMDLG32_OpenFileLock); 95 #endif 96 break; 97 } 98 return TRUE; 99 } 100 #undef GPA 101 102 /*********************************************************************** 103 * COMDLG32_AllocMem (internal) 104 * Get memory for internal datastructure plus stringspace etc. 105 * RETURNS 106 * Success: Pointer to a heap block 107 * Failure: null 108 */ 109 void *COMDLG32_AllocMem(int size) 110 { 111 void *ptr = heap_alloc_zero(size); 112 113 if (!ptr) 114 { 115 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE); 116 return NULL; 117 } 118 119 return ptr; 120 } 121 122 123 /*********************************************************************** 124 * COMDLG32_SetCommDlgExtendedError (internal) 125 * 126 * Used to set the thread's local error value if a comdlg32 function fails. 127 */ 128 void COMDLG32_SetCommDlgExtendedError(DWORD err) 129 { 130 TRACE("(%08x)\n", err); 131 if (COMDLG32_TlsIndex == TLS_OUT_OF_INDEXES) 132 COMDLG32_TlsIndex = TlsAlloc(); 133 if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) 134 TlsSetValue(COMDLG32_TlsIndex, (LPVOID)(DWORD_PTR)err); 135 else 136 FIXME("No Tls Space\n"); 137 } 138 139 140 /*********************************************************************** 141 * CommDlgExtendedError (COMDLG32.@) 142 * 143 * Get the thread's local error value if a comdlg32 function fails. 144 * RETURNS 145 * Current error value which might not be valid 146 * if a previous call succeeded. 147 */ 148 DWORD WINAPI CommDlgExtendedError(void) 149 { 150 if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) 151 return (DWORD_PTR)TlsGetValue(COMDLG32_TlsIndex); 152 else 153 return 0; /* we never set an error, so there isn't one */ 154 } 155 156 #ifndef __REACTOS__ /* Win 7 */ 157 158 /************************************************************************* 159 * Implement the CommDlg32 class factory 160 * 161 * (Taken from shdocvw/factory.c; based on implementation in 162 * ddraw/main.c) 163 */ 164 typedef struct 165 { 166 IClassFactory IClassFactory_iface; 167 HRESULT (*cf)(IUnknown*, REFIID, void**); 168 } IClassFactoryImpl; 169 170 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) 171 { 172 return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); 173 } 174 175 /************************************************************************* 176 * CDLGCF_QueryInterface (IUnknown) 177 */ 178 static HRESULT WINAPI CDLGCF_QueryInterface(IClassFactory* iface, 179 REFIID riid, void **ppobj) 180 { 181 TRACE("%p (%s %p)\n", iface, debugstr_guid(riid), ppobj); 182 183 if(!ppobj) 184 return E_POINTER; 185 186 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) 187 { 188 *ppobj = iface; 189 IClassFactory_AddRef(iface); 190 return S_OK; 191 } 192 193 WARN("Interface not supported.\n"); 194 195 *ppobj = NULL; 196 return E_NOINTERFACE; 197 } 198 199 /************************************************************************* 200 * CDLGCF_AddRef (IUnknown) 201 */ 202 static ULONG WINAPI CDLGCF_AddRef(IClassFactory *iface) 203 { 204 return 2; /* non-heap based object */ 205 } 206 207 /************************************************************************* 208 * CDLGCF_Release (IUnknown) 209 */ 210 static ULONG WINAPI CDLGCF_Release(IClassFactory *iface) 211 { 212 return 1; /* non-heap based object */ 213 } 214 215 /************************************************************************* 216 * CDLGCF_CreateInstance (IClassFactory) 217 */ 218 static HRESULT WINAPI CDLGCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, 219 REFIID riid, void **ppobj) 220 { 221 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 222 return This->cf(pOuter, riid, ppobj); 223 } 224 225 /************************************************************************* 226 * CDLGCF_LockServer (IClassFactory) 227 */ 228 static HRESULT WINAPI CDLGCF_LockServer(IClassFactory *iface, BOOL dolock) 229 { 230 TRACE("%p (%d)\n", iface, dolock); 231 return S_OK; 232 } 233 234 static const IClassFactoryVtbl CDLGCF_Vtbl = 235 { 236 CDLGCF_QueryInterface, 237 CDLGCF_AddRef, 238 CDLGCF_Release, 239 CDLGCF_CreateInstance, 240 CDLGCF_LockServer 241 }; 242 243 /************************************************************************* 244 * DllGetClassObject (COMMDLG32.@) 245 */ 246 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) 247 { 248 static IClassFactoryImpl FileOpenDlgClassFactory = {{&CDLGCF_Vtbl}, FileOpenDialog_Constructor}; 249 static IClassFactoryImpl FileSaveDlgClassFactory = {{&CDLGCF_Vtbl}, FileSaveDialog_Constructor}; 250 251 TRACE("%s, %s, %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); 252 253 if(IsEqualGUID(&CLSID_FileOpenDialog, rclsid)) 254 return IClassFactory_QueryInterface(&FileOpenDlgClassFactory.IClassFactory_iface, riid, ppv); 255 256 if(IsEqualGUID(&CLSID_FileSaveDialog, rclsid)) 257 return IClassFactory_QueryInterface(&FileSaveDlgClassFactory.IClassFactory_iface, riid, ppv); 258 259 return CLASS_E_CLASSNOTAVAILABLE; 260 } 261 262 /*********************************************************************** 263 * DllRegisterServer (COMMDLG32.@) 264 */ 265 HRESULT WINAPI DllRegisterServer(void) 266 { 267 #ifdef __REACTOS__ 268 return E_FAIL; // FIXME: __wine_register_resources(COMDLG32_hInstance); 269 #else 270 return __wine_register_resources(COMDLG32_hInstance); 271 #endif 272 } 273 274 /*********************************************************************** 275 * DllUnregisterServer (COMMDLG32.@) 276 */ 277 HRESULT WINAPI DllUnregisterServer(void) 278 { 279 #ifdef __REACTOS__ 280 return E_FAIL; // FIXME: __wine_unregister_resources(COMDLG32_hInstance); 281 #else 282 return __wine_unregister_resources(COMDLG32_hInstance); 283 #endif 284 } 285 286 #endif /* Win 7 */ 287