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