source: trunk/src/shell32/shellole.c

Last change on this file was 10172, checked in by sandervl, 22 years ago

KOM: DragQueryFileW; allocate more for unicode conversion (DBCS)

File size: 17.8 KB
RevLine 
[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]39WINE_DEFAULT_DEBUG_CHANNEL(shell);
40
41DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id);
[4121]42extern IShellFolder * IShellFolder_Constructor(
[6709]43 IShellFolder * psf,
44 LPITEMIDLIST pidl);
[4121]45extern 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 */
56LRESULT 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 */
101HRESULT 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]135DWORD 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}
143DWORD 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}
148DWORD 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]165DWORD 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 */
174LPSHELLFOLDER pdesktopfolder=NULL;
175
176DWORD 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
209typedef struct
210{
211 /* IUnknown fields */
212 ICOM_VFIELD(IClassFactory);
213 DWORD ref;
[6709]214 CLSID *rclsid;
[4121]215} IClassFactoryImpl;
216
217static ICOM_VTABLE(IClassFactory) clfvt;
218
219/**************************************************************************
220 * IClassFactory_Constructor
221 */
222
223LPCLASSFACTORY 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 */
239static 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 */
265static 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 */
276static 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 */
293static 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 */
338static 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]345static 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__
366typedef HRESULT (* CALLBACK LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
367#else
[8614]368typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
[4121]369#endif
370
371typedef 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
381static ICOM_VTABLE(IClassFactory) dclfvt;
382
383/**************************************************************************
384 * IDefClF_fnConstructor
385 */
386
387IClassFactory * 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 */
407static 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 */
434static 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 */
445static 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 */
465static 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 */
490static 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]497static 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 */
510HRESULT 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 */
536void 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 */
552void WINAPI DragFinish(HDROP h)
553{
[6709]554 TRACE("\n");
555 GlobalFree((HGLOBAL)h);
[4121]556}
557
558/*************************************************************************
[6709]559 * DragQueryPoint [SHELL32.135]
[4121]560 */
561BOOL 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 */
581UINT 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]630end:
[6709]631 GlobalUnlock(hDrop);
632 return i;
[4121]633}
634
635/*************************************************************************
[8614]636 * DragQueryFileW [SHELL32.133]
[4121]637 */
638UINT 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]697end:
[6709]698 GlobalUnlock(hDrop);
699 return i;
[4121]700}
Note: See TracBrowser for help on using the repository browser.