[4121] | 1 | /*
|
---|
[6709] | 2 | * handling of SHELL32.DLL OLE-Objects
|
---|
[4121] | 3 | *
|
---|
[6709] | 4 | * Copyright 1997 Marcus Meissner
|
---|
| 5 | * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
|
---|
[4121] | 6 | *
|
---|
[8614] | 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
[4121] | 20 | */
|
---|
| 21 |
|
---|
[8614] | 22 | #include "config.h"
|
---|
| 23 |
|
---|
[4121] | 24 | #include <stdlib.h>
|
---|
| 25 | #include <string.h>
|
---|
| 26 |
|
---|
[8614] | 27 | #include "shellapi.h"
|
---|
[5618] | 28 | #include "shlobj.h"
|
---|
[4121] | 29 | #include "shlguid.h"
|
---|
| 30 | #include "winreg.h"
|
---|
| 31 | #include "winerror.h"
|
---|
| 32 |
|
---|
[8614] | 33 | #include "undocshell.h"
|
---|
| 34 | #include "wine/unicode.h"
|
---|
[4121] | 35 | #include "shell32_main.h"
|
---|
| 36 |
|
---|
[8614] | 37 | #include "wine/debug.h"
|
---|
[4121] | 38 |
|
---|
[8614] | 39 | WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
---|
| 40 |
|
---|
| 41 | DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id);
|
---|
[4121] | 42 | extern IShellFolder * IShellFolder_Constructor(
|
---|
[6709] | 43 | IShellFolder * psf,
|
---|
| 44 | LPITEMIDLIST pidl);
|
---|
[4121] | 45 | extern HRESULT IFSFolder_Constructor(
|
---|
[6709] | 46 | IUnknown * pUnkOuter,
|
---|
| 47 | REFIID riid,
|
---|
| 48 | LPVOID * ppv);
|
---|
[4121] | 49 |
|
---|
| 50 | /*************************************************************************
|
---|
| 51 | * SHCoCreateInstance [SHELL32.102]
|
---|
[8614] | 52 | *
|
---|
[4121] | 53 | * NOTES
|
---|
| 54 | * exported by ordinal
|
---|
| 55 | */
|
---|
| 56 | LRESULT WINAPI SHCoCreateInstance(
|
---|
[8614] | 57 | LPCSTR aclsid,
|
---|
[6709] | 58 | REFCLSID clsid,
|
---|
[7085] | 59 | LPUNKNOWN unknownouter,
|
---|
[6709] | 60 | REFIID refiid,
|
---|
| 61 | LPVOID *ppv)
|
---|
[4121] | 62 | {
|
---|
[6709] | 63 | DWORD hres;
|
---|
| 64 | IID iid;
|
---|
| 65 | CLSID * myclsid = (CLSID*)clsid;
|
---|
[8614] | 66 |
|
---|
[6709] | 67 | if (!clsid)
|
---|
| 68 | {
|
---|
| 69 | if (!aclsid) return REGDB_E_CLASSNOTREG;
|
---|
| 70 | SHCLSIDFromStringA(aclsid, &iid);
|
---|
| 71 | myclsid = &iid;
|
---|
| 72 | }
|
---|
[4121] | 73 |
|
---|
[6709] | 74 | TRACE("(%p,\n\tCLSID:\t%s, unk:%p\n\tIID:\t%s,%p)\n",
|
---|
| 75 | aclsid,debugstr_guid(myclsid),unknownouter,debugstr_guid(refiid),ppv);
|
---|
[4121] | 76 |
|
---|
[6709] | 77 | if IsEqualCLSID(myclsid, &CLSID_ShellFSFolder)
|
---|
| 78 | {
|
---|
| 79 | hres = IFSFolder_Constructor(unknownouter, refiid, ppv);
|
---|
| 80 | }
|
---|
| 81 | else
|
---|
[8614] | 82 | {
|
---|
| 83 | CoInitialize(NULL);
|
---|
[6709] | 84 | hres = CoCreateInstance(myclsid, unknownouter, CLSCTX_INPROC_SERVER, refiid, ppv);
|
---|
| 85 | }
|
---|
[8614] | 86 |
|
---|
[6709] | 87 | if(hres!=S_OK)
|
---|
| 88 | {
|
---|
| 89 | ERR("failed (0x%08lx) to create \n\tCLSID:\t%s\n\tIID:\t%s\n",
|
---|
[4121] | 90 | hres, debugstr_guid(myclsid), debugstr_guid(refiid));
|
---|
[6709] | 91 | ERR("class not found in registry\n");
|
---|
| 92 | }
|
---|
[4121] | 93 |
|
---|
[6709] | 94 | TRACE("-- instance: %p\n",*ppv);
|
---|
| 95 | return hres;
|
---|
[4121] | 96 | }
|
---|
| 97 |
|
---|
| 98 | /*************************************************************************
|
---|
[8614] | 99 | * DllGetClassObject [SHELL32.128]
|
---|
[4121] | 100 | */
|
---|
| 101 | HRESULT WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
|
---|
[6709] | 102 | { HRESULT hres = E_OUTOFMEMORY;
|
---|
| 103 | LPCLASSFACTORY lpclf;
|
---|
[4121] | 104 |
|
---|
[6709] | 105 | TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
|
---|
[8614] | 106 |
|
---|
[6709] | 107 | *ppv = NULL;
|
---|
[4121] | 108 |
|
---|
[8614] | 109 | if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)||
|
---|
[6709] | 110 | IsEqualCLSID(rclsid, &CLSID_ShellLink))
|
---|
| 111 | {
|
---|
| 112 | lpclf = IClassFactory_Constructor( rclsid );
|
---|
[4121] | 113 |
|
---|
[8614] | 114 | if(lpclf)
|
---|
[6709] | 115 | {
|
---|
| 116 | hres = IClassFactory_QueryInterface(lpclf,iid, ppv);
|
---|
| 117 | IClassFactory_Release(lpclf);
|
---|
| 118 | }
|
---|
| 119 | }
|
---|
| 120 | else
|
---|
| 121 | {
|
---|
| 122 | WARN("-- CLSID not found\n");
|
---|
| 123 | hres = CLASS_E_CLASSNOTAVAILABLE;
|
---|
| 124 | }
|
---|
| 125 | TRACE("-- pointer to class factory: %p\n",*ppv);
|
---|
| 126 | return hres;
|
---|
[4121] | 127 | }
|
---|
| 128 |
|
---|
| 129 | /*************************************************************************
|
---|
[6709] | 130 | * SHCLSIDFromString [SHELL32.147]
|
---|
[4121] | 131 | *
|
---|
| 132 | * NOTES
|
---|
| 133 | * exported by ordinal
|
---|
| 134 | */
|
---|
[8614] | 135 | DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id)
|
---|
[4121] | 136 | {
|
---|
| 137 | WCHAR buffer[40];
|
---|
| 138 | TRACE("(%p(%s) %p)\n", clsid, clsid, id);
|
---|
| 139 | if (!MultiByteToWideChar( CP_ACP, 0, clsid, -1, buffer, sizeof(buffer)/sizeof(WCHAR) ))
|
---|
| 140 | return CO_E_CLASSSTRING;
|
---|
| 141 | return CLSIDFromString( buffer, id );
|
---|
| 142 | }
|
---|
| 143 | DWORD WINAPI SHCLSIDFromStringW (LPWSTR clsid, CLSID *id)
|
---|
| 144 | {
|
---|
[6709] | 145 | TRACE("(%p(%s) %p)\n", clsid, debugstr_w(clsid), id);
|
---|
[8614] | 146 | return CLSIDFromString(clsid, id);
|
---|
[4121] | 147 | }
|
---|
| 148 | DWORD WINAPI SHCLSIDFromStringAW (LPVOID clsid, CLSID *id)
|
---|
| 149 | {
|
---|
[6709] | 150 | if (SHELL_OsIsUnicode())
|
---|
| 151 | return SHCLSIDFromStringW (clsid, id);
|
---|
| 152 | return SHCLSIDFromStringA (clsid, id);
|
---|
[4121] | 153 | }
|
---|
| 154 |
|
---|
| 155 | /*************************************************************************
|
---|
[8614] | 156 | * SHGetMalloc [SHELL32.@]
|
---|
[4121] | 157 | * returns the interface to shell malloc.
|
---|
| 158 | *
|
---|
| 159 | * [SDK header win95/shlobj.h:
|
---|
| 160 | * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
|
---|
| 161 | * ]
|
---|
| 162 | * What we are currently doing is not very wrong, since we always use the same
|
---|
| 163 | * heap (ProcessHeap).
|
---|
| 164 | */
|
---|
[8614] | 165 | DWORD WINAPI SHGetMalloc(LPMALLOC *lpmal)
|
---|
[4121] | 166 | {
|
---|
[6709] | 167 | TRACE("(%p)\n", lpmal);
|
---|
| 168 | return CoGetMalloc(MEMCTX_TASK, lpmal);
|
---|
[4121] | 169 | }
|
---|
| 170 |
|
---|
| 171 | /*************************************************************************
|
---|
[8614] | 172 | * SHGetDesktopFolder [SHELL32.@]
|
---|
[4121] | 173 | */
|
---|
| 174 | LPSHELLFOLDER pdesktopfolder=NULL;
|
---|
| 175 |
|
---|
| 176 | DWORD WINAPI SHGetDesktopFolder(IShellFolder **psf)
|
---|
| 177 | {
|
---|
[6709] | 178 | HRESULT hres = S_OK;
|
---|
| 179 | LPCLASSFACTORY lpclf;
|
---|
| 180 | TRACE("%p->(%p)\n",psf,*psf);
|
---|
[4121] | 181 |
|
---|
[6709] | 182 | *psf=NULL;
|
---|
[4121] | 183 |
|
---|
[8614] | 184 | if (!pdesktopfolder)
|
---|
[6709] | 185 | {
|
---|
| 186 | lpclf = IClassFactory_Constructor(&CLSID_ShellDesktop);
|
---|
[8614] | 187 | if(lpclf)
|
---|
[6709] | 188 | {
|
---|
| 189 | hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
|
---|
| 190 | IClassFactory_Release(lpclf);
|
---|
[8614] | 191 | }
|
---|
[6709] | 192 | }
|
---|
[8614] | 193 |
|
---|
| 194 | if (pdesktopfolder)
|
---|
[6709] | 195 | {
|
---|
| 196 | /* even if we create the folder, add a ref so the application canŽt destroy the folder*/
|
---|
| 197 | IShellFolder_AddRef(pdesktopfolder);
|
---|
| 198 | *psf = pdesktopfolder;
|
---|
| 199 | }
|
---|
[4121] | 200 |
|
---|
[6709] | 201 | TRACE("-- %p->(%p)\n",psf, *psf);
|
---|
| 202 | return hres;
|
---|
[4121] | 203 | }
|
---|
| 204 |
|
---|
| 205 | /**************************************************************************
|
---|
| 206 | * IClassFactory Implementation
|
---|
| 207 | */
|
---|
| 208 |
|
---|
| 209 | typedef struct
|
---|
| 210 | {
|
---|
| 211 | /* IUnknown fields */
|
---|
| 212 | ICOM_VFIELD(IClassFactory);
|
---|
| 213 | DWORD ref;
|
---|
[6709] | 214 | CLSID *rclsid;
|
---|
[4121] | 215 | } IClassFactoryImpl;
|
---|
| 216 |
|
---|
| 217 | static ICOM_VTABLE(IClassFactory) clfvt;
|
---|
| 218 |
|
---|
| 219 | /**************************************************************************
|
---|
| 220 | * IClassFactory_Constructor
|
---|
| 221 | */
|
---|
| 222 |
|
---|
| 223 | LPCLASSFACTORY IClassFactory_Constructor(REFCLSID rclsid)
|
---|
| 224 | {
|
---|
[6709] | 225 | IClassFactoryImpl* lpclf;
|
---|
[4121] | 226 |
|
---|
[6709] | 227 | lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
|
---|
| 228 | lpclf->ref = 1;
|
---|
| 229 | ICOM_VTBL(lpclf) = &clfvt;
|
---|
| 230 | lpclf->rclsid = (CLSID*)rclsid;
|
---|
[4121] | 231 |
|
---|
[6709] | 232 | TRACE("(%p)->()\n",lpclf);
|
---|
| 233 | InterlockedIncrement(&shell32_ObjCount);
|
---|
| 234 | return (LPCLASSFACTORY)lpclf;
|
---|
[4121] | 235 | }
|
---|
| 236 | /**************************************************************************
|
---|
| 237 | * IClassFactory_QueryInterface
|
---|
| 238 | */
|
---|
| 239 | static HRESULT WINAPI IClassFactory_fnQueryInterface(
|
---|
| 240 | LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
|
---|
| 241 | {
|
---|
[6709] | 242 | ICOM_THIS(IClassFactoryImpl,iface);
|
---|
| 243 | TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
|
---|
[4121] | 244 |
|
---|
[6709] | 245 | *ppvObj = NULL;
|
---|
[4121] | 246 |
|
---|
[6709] | 247 | if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
|
---|
[8614] | 248 | { *ppvObj = This;
|
---|
[6709] | 249 | }
|
---|
| 250 | else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
|
---|
| 251 | { *ppvObj = (IClassFactory*)This;
|
---|
[8614] | 252 | }
|
---|
[4121] | 253 |
|
---|
[6709] | 254 | if(*ppvObj)
|
---|
[8614] | 255 | { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
|
---|
[6709] | 256 | TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
|
---|
| 257 | return S_OK;
|
---|
| 258 | }
|
---|
| 259 | TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
|
---|
| 260 | return E_NOINTERFACE;
|
---|
[8614] | 261 | }
|
---|
[4121] | 262 | /******************************************************************************
|
---|
| 263 | * IClassFactory_AddRef
|
---|
| 264 | */
|
---|
| 265 | static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface)
|
---|
| 266 | {
|
---|
[6709] | 267 | ICOM_THIS(IClassFactoryImpl,iface);
|
---|
| 268 | TRACE("(%p)->(count=%lu)\n",This,This->ref);
|
---|
[4121] | 269 |
|
---|
[6709] | 270 | InterlockedIncrement(&shell32_ObjCount);
|
---|
| 271 | return InterlockedIncrement(&This->ref);
|
---|
[4121] | 272 | }
|
---|
| 273 | /******************************************************************************
|
---|
| 274 | * IClassFactory_Release
|
---|
| 275 | */
|
---|
| 276 | static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface)
|
---|
| 277 | {
|
---|
[6709] | 278 | ICOM_THIS(IClassFactoryImpl,iface);
|
---|
| 279 | TRACE("(%p)->(count=%lu)\n",This,This->ref);
|
---|
[4121] | 280 |
|
---|
[6709] | 281 | InterlockedDecrement(&shell32_ObjCount);
|
---|
[8614] | 282 | if (!InterlockedDecrement(&This->ref))
|
---|
[6709] | 283 | {
|
---|
| 284 | TRACE("-- destroying IClassFactory(%p)\n",This);
|
---|
| 285 | HeapFree(GetProcessHeap(),0,This);
|
---|
| 286 | return 0;
|
---|
| 287 | }
|
---|
| 288 | return This->ref;
|
---|
[4121] | 289 | }
|
---|
| 290 | /******************************************************************************
|
---|
| 291 | * IClassFactory_CreateInstance
|
---|
| 292 | */
|
---|
| 293 | static HRESULT WINAPI IClassFactory_fnCreateInstance(
|
---|
| 294 | LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
|
---|
| 295 | {
|
---|
[6709] | 296 | ICOM_THIS(IClassFactoryImpl,iface);
|
---|
| 297 | IUnknown *pObj = NULL;
|
---|
| 298 | HRESULT hres;
|
---|
[4121] | 299 |
|
---|
[6709] | 300 | TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,debugstr_guid(riid),ppObject);
|
---|
[4121] | 301 |
|
---|
[6709] | 302 | *ppObject = NULL;
|
---|
[8614] | 303 |
|
---|
[6709] | 304 | if(pUnknown)
|
---|
| 305 | {
|
---|
| 306 | return(CLASS_E_NOAGGREGATION);
|
---|
| 307 | }
|
---|
[4121] | 308 |
|
---|
[6709] | 309 | if (IsEqualCLSID(This->rclsid, &CLSID_ShellDesktop))
|
---|
| 310 | {
|
---|
| 311 | pObj = (IUnknown *)ISF_Desktop_Constructor();
|
---|
| 312 | }
|
---|
| 313 | else if (IsEqualCLSID(This->rclsid, &CLSID_ShellLink))
|
---|
| 314 | {
|
---|
| 315 | pObj = (IUnknown *)IShellLink_Constructor(FALSE);
|
---|
[8614] | 316 | }
|
---|
[6709] | 317 | else
|
---|
| 318 | {
|
---|
| 319 | ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid));
|
---|
| 320 | return(E_NOINTERFACE);
|
---|
| 321 | }
|
---|
[8614] | 322 |
|
---|
[6709] | 323 | if (!pObj)
|
---|
| 324 | {
|
---|
| 325 | return(E_OUTOFMEMORY);
|
---|
| 326 | }
|
---|
[8614] | 327 |
|
---|
[6709] | 328 | hres = IUnknown_QueryInterface(pObj,riid, ppObject);
|
---|
| 329 | IUnknown_Release(pObj);
|
---|
[4121] | 330 |
|
---|
[6709] | 331 | TRACE("-- Object created: (%p)->%p\n",This,*ppObject);
|
---|
[4121] | 332 |
|
---|
[6709] | 333 | return hres;
|
---|
[4121] | 334 | }
|
---|
| 335 | /******************************************************************************
|
---|
| 336 | * IClassFactory_LockServer
|
---|
| 337 | */
|
---|
| 338 | static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
|
---|
| 339 | {
|
---|
[6709] | 340 | ICOM_THIS(IClassFactoryImpl,iface);
|
---|
| 341 | TRACE("%p->(0x%x), not implemented\n",This, fLock);
|
---|
| 342 | return E_NOTIMPL;
|
---|
[4121] | 343 | }
|
---|
| 344 |
|
---|
[8614] | 345 | static ICOM_VTABLE(IClassFactory) clfvt =
|
---|
[4121] | 346 | {
|
---|
| 347 | ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
---|
| 348 | IClassFactory_fnQueryInterface,
|
---|
| 349 | IClassFactory_fnAddRef,
|
---|
| 350 | IClassFactory_fnRelease,
|
---|
| 351 | IClassFactory_fnCreateInstance,
|
---|
| 352 | IClassFactory_fnLockServer
|
---|
| 353 | };
|
---|
| 354 |
|
---|
| 355 | /**************************************************************************
|
---|
| 356 | * Default ClassFactory Implementation
|
---|
| 357 | *
|
---|
| 358 | * SHCreateDefClassObject
|
---|
| 359 | *
|
---|
| 360 | * NOTES
|
---|
| 361 | * helper function for dll's without a own classfactory
|
---|
| 362 | * a generic classfactory is returned
|
---|
| 363 | * when the CreateInstance of the cf is called the callback is executed
|
---|
| 364 | */
|
---|
| 365 | #ifdef __WIN32OS2__
|
---|
| 366 | typedef HRESULT (* CALLBACK LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
|
---|
| 367 | #else
|
---|
[8614] | 368 | typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
|
---|
[4121] | 369 | #endif
|
---|
| 370 |
|
---|
| 371 | typedef struct
|
---|
| 372 | {
|
---|
| 373 | ICOM_VFIELD(IClassFactory);
|
---|
| 374 | DWORD ref;
|
---|
[6709] | 375 | CLSID *rclsid;
|
---|
| 376 | LPFNCREATEINSTANCE lpfnCI;
|
---|
| 377 | const IID * riidInst;
|
---|
| 378 | ULONG * pcRefDll; /* pointer to refcounter in external dll (ugrrr...) */
|
---|
[4121] | 379 | } IDefClFImpl;
|
---|
| 380 |
|
---|
| 381 | static ICOM_VTABLE(IClassFactory) dclfvt;
|
---|
| 382 |
|
---|
| 383 | /**************************************************************************
|
---|
| 384 | * IDefClF_fnConstructor
|
---|
| 385 | */
|
---|
| 386 |
|
---|
| 387 | IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, REFIID riidInst)
|
---|
| 388 | {
|
---|
[6709] | 389 | IDefClFImpl* lpclf;
|
---|
[4121] | 390 |
|
---|
[6709] | 391 | lpclf = (IDefClFImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDefClFImpl));
|
---|
| 392 | lpclf->ref = 1;
|
---|
| 393 | ICOM_VTBL(lpclf) = &dclfvt;
|
---|
| 394 | lpclf->lpfnCI = lpfnCI;
|
---|
| 395 | lpclf->pcRefDll = pcRefDll;
|
---|
[4121] | 396 |
|
---|
[6709] | 397 | if (pcRefDll) InterlockedIncrement(pcRefDll);
|
---|
| 398 | lpclf->riidInst = riidInst;
|
---|
[4121] | 399 |
|
---|
[6709] | 400 | TRACE("(%p)\n\tIID:\t%s\n",lpclf, debugstr_guid(riidInst));
|
---|
| 401 | InterlockedIncrement(&shell32_ObjCount);
|
---|
| 402 | return (LPCLASSFACTORY)lpclf;
|
---|
[4121] | 403 | }
|
---|
| 404 | /**************************************************************************
|
---|
| 405 | * IDefClF_fnQueryInterface
|
---|
| 406 | */
|
---|
| 407 | static HRESULT WINAPI IDefClF_fnQueryInterface(
|
---|
| 408 | LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
|
---|
| 409 | {
|
---|
[6709] | 410 | ICOM_THIS(IDefClFImpl,iface);
|
---|
[4121] | 411 |
|
---|
[6709] | 412 | TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
|
---|
[4121] | 413 |
|
---|
[6709] | 414 | *ppvObj = NULL;
|
---|
[4121] | 415 |
|
---|
[6709] | 416 | if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
|
---|
[8614] | 417 | { *ppvObj = This;
|
---|
[6709] | 418 | }
|
---|
| 419 | else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/
|
---|
| 420 | { *ppvObj = (IClassFactory*)This;
|
---|
[8614] | 421 | }
|
---|
[4121] | 422 |
|
---|
[6709] | 423 | if(*ppvObj)
|
---|
[8614] | 424 | { IUnknown_AddRef((LPUNKNOWN)*ppvObj);
|
---|
[6709] | 425 | TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
|
---|
| 426 | return S_OK;
|
---|
| 427 | }
|
---|
| 428 | TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
|
---|
| 429 | return E_NOINTERFACE;
|
---|
[8614] | 430 | }
|
---|
[4121] | 431 | /******************************************************************************
|
---|
| 432 | * IDefClF_fnAddRef
|
---|
| 433 | */
|
---|
| 434 | static ULONG WINAPI IDefClF_fnAddRef(LPCLASSFACTORY iface)
|
---|
| 435 | {
|
---|
[6709] | 436 | ICOM_THIS(IDefClFImpl,iface);
|
---|
| 437 | TRACE("(%p)->(count=%lu)\n",This,This->ref);
|
---|
[4121] | 438 |
|
---|
[6709] | 439 | InterlockedIncrement(&shell32_ObjCount);
|
---|
| 440 | return InterlockedIncrement(&This->ref);
|
---|
[4121] | 441 | }
|
---|
| 442 | /******************************************************************************
|
---|
| 443 | * IDefClF_fnRelease
|
---|
| 444 | */
|
---|
| 445 | static ULONG WINAPI IDefClF_fnRelease(LPCLASSFACTORY iface)
|
---|
| 446 | {
|
---|
[6709] | 447 | ICOM_THIS(IDefClFImpl,iface);
|
---|
| 448 | TRACE("(%p)->(count=%lu)\n",This,This->ref);
|
---|
[4121] | 449 |
|
---|
[6709] | 450 | InterlockedDecrement(&shell32_ObjCount);
|
---|
[4121] | 451 |
|
---|
[8614] | 452 | if (!InterlockedDecrement(&This->ref))
|
---|
| 453 | {
|
---|
[6709] | 454 | if (This->pcRefDll) InterlockedDecrement(This->pcRefDll);
|
---|
[4121] | 455 |
|
---|
[6709] | 456 | TRACE("-- destroying IClassFactory(%p)\n",This);
|
---|
| 457 | HeapFree(GetProcessHeap(),0,This);
|
---|
| 458 | return 0;
|
---|
| 459 | }
|
---|
| 460 | return This->ref;
|
---|
[4121] | 461 | }
|
---|
| 462 | /******************************************************************************
|
---|
| 463 | * IDefClF_fnCreateInstance
|
---|
| 464 | */
|
---|
| 465 | static HRESULT WINAPI IDefClF_fnCreateInstance(
|
---|
| 466 | LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
|
---|
| 467 | {
|
---|
[6709] | 468 | ICOM_THIS(IDefClFImpl,iface);
|
---|
[4121] | 469 |
|
---|
[6709] | 470 | TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnkOuter,debugstr_guid(riid),ppvObject);
|
---|
[4121] | 471 |
|
---|
[6709] | 472 | *ppvObject = NULL;
|
---|
[8614] | 473 |
|
---|
[6709] | 474 | if(pUnkOuter)
|
---|
| 475 | return(CLASS_E_NOAGGREGATION);
|
---|
[4121] | 476 |
|
---|
[6709] | 477 | if ( This->riidInst==NULL ||
|
---|
| 478 | IsEqualCLSID(riid, This->riidInst) ||
|
---|
| 479 | IsEqualCLSID(riid, &IID_IUnknown) )
|
---|
| 480 | {
|
---|
| 481 | return This->lpfnCI(pUnkOuter, riid, ppvObject);
|
---|
| 482 | }
|
---|
[4121] | 483 |
|
---|
[6709] | 484 | ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid));
|
---|
| 485 | return E_NOINTERFACE;
|
---|
[4121] | 486 | }
|
---|
| 487 | /******************************************************************************
|
---|
| 488 | * IDefClF_fnLockServer
|
---|
| 489 | */
|
---|
| 490 | static HRESULT WINAPI IDefClF_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
|
---|
| 491 | {
|
---|
[6709] | 492 | ICOM_THIS(IDefClFImpl,iface);
|
---|
| 493 | TRACE("%p->(0x%x), not implemented\n",This, fLock);
|
---|
| 494 | return E_NOTIMPL;
|
---|
[4121] | 495 | }
|
---|
| 496 |
|
---|
[8614] | 497 | static ICOM_VTABLE(IClassFactory) dclfvt =
|
---|
[4121] | 498 | {
|
---|
| 499 | ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
---|
| 500 | IDefClF_fnQueryInterface,
|
---|
| 501 | IDefClF_fnAddRef,
|
---|
| 502 | IDefClF_fnRelease,
|
---|
| 503 | IDefClF_fnCreateInstance,
|
---|
| 504 | IDefClF_fnLockServer
|
---|
| 505 | };
|
---|
| 506 |
|
---|
| 507 | /******************************************************************************
|
---|
[6709] | 508 | * SHCreateDefClassObject [SHELL32.70]
|
---|
[4121] | 509 | */
|
---|
| 510 | HRESULT WINAPI SHCreateDefClassObject(
|
---|
[8614] | 511 | REFIID riid,
|
---|
| 512 | LPVOID* ppv,
|
---|
[6709] | 513 | LPFNCREATEINSTANCE lpfnCI, /* [in] create instance callback entry */
|
---|
[8614] | 514 | LPDWORD pcRefDll, /* [in/out] ref count of the dll */
|
---|
[6709] | 515 | REFIID riidInst) /* [in] optional interface to the instance */
|
---|
[4121] | 516 | {
|
---|
[6709] | 517 | TRACE("\n\tIID:\t%s %p %p %p \n\tIIDIns:\t%s\n",
|
---|
[4121] | 518 | debugstr_guid(riid), ppv, lpfnCI, pcRefDll, debugstr_guid(riidInst));
|
---|
| 519 |
|
---|
[6709] | 520 | if ( IsEqualCLSID(riid, &IID_IClassFactory) )
|
---|
| 521 | {
|
---|
| 522 | IClassFactory * pcf = IDefClF_fnConstructor(lpfnCI, pcRefDll, riidInst);
|
---|
| 523 | if (pcf)
|
---|
| 524 | {
|
---|
| 525 | *ppv = pcf;
|
---|
| 526 | return NOERROR;
|
---|
| 527 | }
|
---|
| 528 | return E_OUTOFMEMORY;
|
---|
| 529 | }
|
---|
| 530 | return E_NOINTERFACE;
|
---|
[4121] | 531 | }
|
---|
| 532 |
|
---|
| 533 | /*************************************************************************
|
---|
[6709] | 534 | * DragAcceptFiles [SHELL32.54]
|
---|
[4121] | 535 | */
|
---|
| 536 | void WINAPI DragAcceptFiles(HWND hWnd, BOOL b)
|
---|
| 537 | {
|
---|
[6709] | 538 | LONG exstyle;
|
---|
[8614] | 539 |
|
---|
[6709] | 540 | if( !IsWindow(hWnd) ) return;
|
---|
| 541 | exstyle = GetWindowLongA(hWnd,GWL_EXSTYLE);
|
---|
| 542 | if (b)
|
---|
| 543 | exstyle |= WS_EX_ACCEPTFILES;
|
---|
| 544 | else
|
---|
| 545 | exstyle &= ~WS_EX_ACCEPTFILES;
|
---|
| 546 | SetWindowLongA(hWnd,GWL_EXSTYLE,exstyle);
|
---|
[4121] | 547 | }
|
---|
| 548 |
|
---|
| 549 | /*************************************************************************
|
---|
[6709] | 550 | * DragFinish [SHELL32.80]
|
---|
[4121] | 551 | */
|
---|
| 552 | void WINAPI DragFinish(HDROP h)
|
---|
| 553 | {
|
---|
[6709] | 554 | TRACE("\n");
|
---|
| 555 | GlobalFree((HGLOBAL)h);
|
---|
[4121] | 556 | }
|
---|
| 557 |
|
---|
| 558 | /*************************************************************************
|
---|
[6709] | 559 | * DragQueryPoint [SHELL32.135]
|
---|
[4121] | 560 | */
|
---|
| 561 | BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p)
|
---|
| 562 | {
|
---|
[5618] | 563 | DROPFILES *lpDropFileStruct;
|
---|
[6709] | 564 | BOOL bRet;
|
---|
[4121] | 565 |
|
---|
[6709] | 566 | TRACE("\n");
|
---|
[4121] | 567 |
|
---|
[6709] | 568 | lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
|
---|
[5618] | 569 |
|
---|
| 570 | *p = lpDropFileStruct->pt;
|
---|
[6709] | 571 | bRet = lpDropFileStruct->fNC;
|
---|
[8614] | 572 |
|
---|
[6709] | 573 | GlobalUnlock(hDrop);
|
---|
| 574 | return bRet;
|
---|
[4121] | 575 | }
|
---|
| 576 |
|
---|
| 577 | /*************************************************************************
|
---|
[8614] | 578 | * DragQueryFile [SHELL32.81]
|
---|
| 579 | * DragQueryFileA [SHELL32.82]
|
---|
[4121] | 580 | */
|
---|
| 581 | UINT WINAPI DragQueryFileA(
|
---|
[6709] | 582 | HDROP hDrop,
|
---|
| 583 | UINT lFile,
|
---|
| 584 | LPSTR lpszFile,
|
---|
| 585 | UINT lLength)
|
---|
[4121] | 586 | {
|
---|
[6709] | 587 | LPSTR lpDrop;
|
---|
| 588 | UINT i = 0;
|
---|
| 589 | DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
|
---|
[8614] | 590 |
|
---|
[6709] | 591 | TRACE("(%08x, %x, %p, %u)\n", hDrop,lFile,lpszFile,lLength);
|
---|
[8614] | 592 |
|
---|
[6709] | 593 | if(!lpDropFileStruct) goto end;
|
---|
[4121] | 594 |
|
---|
[6709] | 595 | lpDrop = (LPSTR) lpDropFileStruct + lpDropFileStruct->pFiles;
|
---|
[4121] | 596 |
|
---|
[8614] | 597 | if(lpDropFileStruct->fWide == TRUE) {
|
---|
| 598 | LPWSTR lpszFileW = NULL;
|
---|
[8552] | 599 |
|
---|
[8614] | 600 | if(lpszFile) {
|
---|
| 601 | lpszFileW = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, lLength*sizeof(WCHAR));
|
---|
| 602 | if(lpszFileW == NULL) {
|
---|
| 603 | goto end;
|
---|
| 604 | }
|
---|
[8552] | 605 | }
|
---|
[8614] | 606 | i = DragQueryFileW(hDrop, lFile, lpszFileW, lLength);
|
---|
[8552] | 607 |
|
---|
[8614] | 608 | if(lpszFileW) {
|
---|
| 609 | WideCharToMultiByte(CP_ACP, 0, lpszFileW, -1, lpszFile, lLength, 0, NULL);
|
---|
| 610 | HeapFree(GetProcessHeap(), 0, lpszFileW);
|
---|
| 611 | }
|
---|
| 612 | goto end;
|
---|
[8552] | 613 | }
|
---|
| 614 |
|
---|
[6709] | 615 | while (i++ < lFile)
|
---|
| 616 | {
|
---|
| 617 | while (*lpDrop++); /* skip filename */
|
---|
[8614] | 618 | if (!*lpDrop)
|
---|
[6709] | 619 | {
|
---|
[8614] | 620 | i = (lFile == 0xFFFFFFFF) ? i : 0;
|
---|
[6709] | 621 | goto end;
|
---|
| 622 | }
|
---|
| 623 | }
|
---|
[8614] | 624 |
|
---|
[6709] | 625 | i = strlen(lpDrop);
|
---|
| 626 | i++;
|
---|
| 627 | if (!lpszFile ) goto end; /* needed buffer size */
|
---|
| 628 | i = (lLength > i) ? i : lLength;
|
---|
| 629 | lstrcpynA (lpszFile, lpDrop, i);
|
---|
[4121] | 630 | end:
|
---|
[6709] | 631 | GlobalUnlock(hDrop);
|
---|
| 632 | return i;
|
---|
[4121] | 633 | }
|
---|
| 634 |
|
---|
| 635 | /*************************************************************************
|
---|
[8614] | 636 | * DragQueryFileW [SHELL32.133]
|
---|
[4121] | 637 | */
|
---|
| 638 | UINT WINAPI DragQueryFileW(
|
---|
[6709] | 639 | HDROP hDrop,
|
---|
| 640 | UINT lFile,
|
---|
| 641 | LPWSTR lpszwFile,
|
---|
| 642 | UINT lLength)
|
---|
[4121] | 643 | {
|
---|
[6709] | 644 | LPWSTR lpwDrop;
|
---|
| 645 | UINT i = 0;
|
---|
| 646 | DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
|
---|
[8614] | 647 |
|
---|
[6709] | 648 | TRACE("(%08x, %x, %p, %u)\n", hDrop,lFile,lpszwFile,lLength);
|
---|
[8614] | 649 |
|
---|
[6709] | 650 | if(!lpDropFileStruct) goto end;
|
---|
[4121] | 651 |
|
---|
[8614] | 652 | lpwDrop = (LPWSTR) ((LPSTR)lpDropFileStruct + lpDropFileStruct->pFiles);
|
---|
[8552] | 653 |
|
---|
[8614] | 654 | if(lpDropFileStruct->fWide == FALSE) {
|
---|
| 655 | LPSTR lpszFileA = NULL;
|
---|
| 656 |
|
---|
| 657 | if(lpszwFile) {
|
---|
[10172] | 658 | #ifdef __WIN32OS2__
|
---|
| 659 | lpszFileA = (LPSTR) HeapAlloc(GetProcessHeap(), 0, lLength * sizeof( WCHAR ));
|
---|
| 660 | #else
|
---|
[8614] | 661 | lpszFileA = (LPSTR) HeapAlloc(GetProcessHeap(), 0, lLength);
|
---|
[10172] | 662 | #endif
|
---|
[8614] | 663 | if(lpszFileA == NULL) {
|
---|
| 664 | goto end;
|
---|
| 665 | }
|
---|
[8552] | 666 | }
|
---|
[10172] | 667 | #ifdef __WIN32OS2__
|
---|
| 668 | i = DragQueryFileA(hDrop, lFile, lpszFileA, lLength * sizeof( WCHAR ));
|
---|
| 669 | #else
|
---|
[8614] | 670 | i = DragQueryFileA(hDrop, lFile, lpszFileA, lLength);
|
---|
[10172] | 671 | #endif
|
---|
[8552] | 672 |
|
---|
[8614] | 673 | if(lpszFileA) {
|
---|
| 674 | MultiByteToWideChar(CP_ACP, 0, lpszFileA, -1, lpszwFile, lLength);
|
---|
| 675 | HeapFree(GetProcessHeap(), 0, lpszFileA);
|
---|
| 676 | }
|
---|
| 677 | goto end;
|
---|
[8552] | 678 | }
|
---|
| 679 |
|
---|
[6709] | 680 | i = 0;
|
---|
| 681 | while (i++ < lFile)
|
---|
| 682 | {
|
---|
| 683 | while (*lpwDrop++); /* skip filename */
|
---|
[8614] | 684 | if (!*lpwDrop)
|
---|
[6709] | 685 | {
|
---|
[8614] | 686 | i = (lFile == 0xFFFFFFFF) ? i : 0;
|
---|
[6709] | 687 | goto end;
|
---|
| 688 | }
|
---|
| 689 | }
|
---|
[8614] | 690 |
|
---|
[6709] | 691 | i = strlenW(lpwDrop);
|
---|
| 692 | i++;
|
---|
| 693 | if ( !lpszwFile) goto end; /* needed buffer size */
|
---|
[4121] | 694 |
|
---|
[6709] | 695 | i = (lLength > i) ? i : lLength;
|
---|
| 696 | lstrcpynW (lpszwFile, lpwDrop, i);
|
---|
[4121] | 697 | end:
|
---|
[6709] | 698 | GlobalUnlock(hDrop);
|
---|
| 699 | return i;
|
---|
[4121] | 700 | }
|
---|