source: trunk/src/shell32/shlfolder.c@ 5087

Last change on this file since 5087 was 4121, checked in by sandervl, 25 years ago

complete merge with shell32 from wine 20000801

File size: 71.0 KB
Line 
1/* $Id: shlfolder.c,v 1.1 2000-08-30 13:52:57 sandervl Exp $ */
2/*
3 * Shell Folder stuff
4 *
5 * Copyright 1997 Marcus Meissner
6 * Copyright 1998, 1999 Juergen Schmied
7 *
8 * IShellFolder2 and related interfaces
9 *
10 */
11#ifdef __WIN32OS2__
12#define ICOM_CINTERFACE 1
13#include <odin.h>
14#endif
15
16#include <stdlib.h>
17#include <string.h>
18#include <stdio.h>
19
20#include "debugtools.h"
21#include "winerror.h"
22
23#include "oleidl.h"
24#include "shlguid.h"
25
26#include "pidl.h"
27#include "wine/obj_base.h"
28#include "wine/obj_dragdrop.h"
29#include "wine/obj_shellfolder.h"
30#include "wine/undocshell.h"
31#include "shell32_main.h"
32#include "shresdef.h"
33#include "shlwapi.h"
34
35#define INITGUID
36#include "initguid.h"
37#include "shellfolder.h"
38
39
40DEFAULT_DEBUG_CHANNEL(shell)
41
42
43/***************************************************************************
44 * debughelper: print out the return adress
45 * helps especially to track down unbalanced AddRef/Release
46 */
47#define MEM_DEBUG 0
48
49#if MEM_DEBUG
50#define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
51#else
52#define _CALL_TRACE
53#endif
54
55typedef struct
56{
57 int colnameid;
58 int pcsFlags;
59 int fmt;
60 int cxChar;
61
62} shvheader;
63
64/***************************************************************************
65 * GetNextElement (internal function)
66 *
67 * gets a part of a string till the first backslash
68 *
69 * PARAMETERS
70 * pszNext [IN] string to get the element from
71 * pszOut [IN] pointer to buffer whitch receives string
72 * dwOut [IN] length of pszOut
73 *
74 * RETURNS
75 * LPSTR pointer to first, not yet parsed char
76 */
77
78static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
79{ LPCWSTR pszTail = pszNext;
80 DWORD dwCopy;
81 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
82
83 *pszOut=0x0000;
84
85 if(!pszNext || !*pszNext)
86 return NULL;
87
88 while(*pszTail && (*pszTail != (WCHAR)'\\'))
89 pszTail++;
90
91 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
92 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
93
94 if(*pszTail)
95 pszTail++;
96 else
97 pszTail = NULL;
98
99 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
100 return pszTail;
101}
102
103static HRESULT SHELL32_ParseNextElement(
104 HWND hwndOwner,
105 IShellFolder2 * psf,
106 LPITEMIDLIST * pidlInOut,
107 LPOLESTR szNext,
108 DWORD *pEaten,
109 DWORD *pdwAttributes)
110{
111 HRESULT hr = E_OUTOFMEMORY;
112 LPITEMIDLIST pidlOut, pidlTemp = NULL;
113 IShellFolder *psfChild;
114
115 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
116
117
118 /* get the shellfolder for the child pidl and let it analyse further */
119 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
120
121 if (psfChild)
122 {
123 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
124 IShellFolder_Release(psfChild);
125
126 pidlTemp = ILCombine(*pidlInOut, pidlOut);
127
128 if (pidlOut)
129 ILFree(pidlOut);
130 }
131
132 ILFree(*pidlInOut);
133 *pidlInOut = pidlTemp;
134
135 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
136 return hr;
137}
138
139/***********************************************************************
140 * SHELL32_CoCreateInitSF
141 *
142 * creates a initialized shell folder
143 */
144static HRESULT SHELL32_CoCreateInitSF (
145 LPITEMIDLIST pidlRoot,
146 LPITEMIDLIST pidlChild,
147 REFCLSID clsid,
148 REFIID iid,
149 LPVOID * ppvOut)
150{
151 HRESULT hr;
152 LPITEMIDLIST absPidl;
153 IShellFolder2 *pShellFolder;
154 IPersistFolder *pPersistFolder;
155
156 TRACE("%p %p\n", pidlRoot, pidlChild);
157
158 *ppvOut = NULL;
159
160 /* we have to ask first for IPersistFolder, some special folders are expecting this */
161 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
162 if (SUCCEEDED(hr))
163 {
164 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
165 if (SUCCEEDED(hr))
166 {
167 absPidl = ILCombine (pidlRoot, pidlChild);
168 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
169 IPersistFolder_Release(pPersistFolder);
170 SHFree(absPidl);
171 *ppvOut = pShellFolder;
172 }
173 }
174
175 TRACE("-- ret=0x%08lx\n", hr);
176 return hr;
177}
178
179static HRESULT SHELL32_GetDisplayNameOfChild(
180 IShellFolder2 * psf,
181 LPCITEMIDLIST pidl,
182 DWORD dwFlags,
183 LPSTR szOut,
184 DWORD dwOutLen)
185{
186 LPITEMIDLIST pidlFirst, pidlNext;
187 IShellFolder2 * psfChild;
188 HRESULT hr = E_OUTOFMEMORY;
189 STRRET strTemp;
190
191 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
192 pdump(pidl);
193
194 if ((pidlFirst = ILCloneFirst(pidl)))
195 {
196 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
197 if (SUCCEEDED(hr))
198 {
199 pidlNext = ILGetNext(pidl);
200
201 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
202 if (SUCCEEDED(hr))
203 {
204 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
205 }
206
207 IShellFolder_Release(psfChild);
208 }
209 ILFree(pidlFirst);
210 }
211
212 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
213
214 return hr;
215}
216
217/***********************************************************************
218 * SHELL32_GetItemAttributes
219 *
220 * NOTES
221 * observerd values:
222 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
223 * file: 0x40000177 FILESYSTEM
224 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
225 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
226 * (seems to be default for shell extensions if no registry entry exists)
227 *
228 * This functions does not set flags!! It only resets flags when nessesary.
229 */
230static HRESULT SHELL32_GetItemAttributes(
231 IShellFolder * psf,
232 LPITEMIDLIST pidl,
233 LPDWORD pdwAttributes)
234{
235 GUID const * clsid;
236 DWORD dwAttributes;
237
238 TRACE("0x%08lx\n", *pdwAttributes);
239
240 if (*pdwAttributes & (0xcff3fe88))
241 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
242 *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
243
244 if (_ILIsDrive(pidl))
245 {
246 *pdwAttributes &= 0xf0000144;
247 }
248 else if ((clsid=_ILGetGUIDPointer(pidl)))
249 {
250 if (HCR_GetFolderAttributes(clsid, &dwAttributes))
251 {
252 *pdwAttributes &= dwAttributes;
253 }
254 else
255 {
256 *pdwAttributes &= 0xb0000154;
257 }
258 }
259 else if (_ILGetDataPointer(pidl))
260 {
261 dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
262 *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
263
264 if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
265 *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
266
267 if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
268 *pdwAttributes &= ~SFGAO_HIDDEN;
269
270 if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
271 *pdwAttributes &= ~SFGAO_READONLY;
272 }
273 else
274 {
275 *pdwAttributes &= 0xb0000154;
276 }
277 TRACE("-- 0x%08lx\n", *pdwAttributes);
278 return S_OK;
279}
280
281/***********************************************************************
282* IShellFolder implementation
283*/
284
285typedef struct
286{
287 ICOM_VFIELD(IUnknown);
288 DWORD ref;
289 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
290 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
291 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
292 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
293
294 IUnknown *pUnkOuter; /* used for aggregation */
295
296 CLSID* pclsid;
297
298 LPSTR sMyPath;
299 LPITEMIDLIST absPidl; /* complete pidl */
300
301 UINT cfShellIDList; /* clipboardformat for IDropTarget */
302 BOOL fAcceptFmt; /* flag for pending Drop */
303} IGenericSFImpl;
304
305static struct ICOM_VTABLE(IUnknown) unkvt;
306static struct ICOM_VTABLE(IShellFolder2) sfvt;
307static struct ICOM_VTABLE(IPersistFolder2) psfvt;
308static struct ICOM_VTABLE(IDropTarget) dtvt;
309static struct ICOM_VTABLE(ISFHelper) shvt;
310
311static IShellFolder * ISF_MyComputer_Constructor(void);
312
313#define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
314#define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
315
316#define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
317#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
318
319#define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
320#define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
321
322#define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
323#define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
324/*
325 converts This to a interface pointer
326*/
327#define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
328#define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
329#define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
330#define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
331#define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
332#define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
333#define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
334#define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
335/**************************************************************************
336* registers clipboardformat once
337*/
338static void SF_RegisterClipFmt (IGenericSFImpl * This)
339{
340 TRACE("(%p)\n", This);
341
342 if (!This->cfShellIDList)
343 {
344 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
345 }
346}
347
348/**************************************************************************
349* we need a seperate IUnknown to handle aggregation
350* (inner IUnknown)
351*/
352static HRESULT WINAPI IUnknown_fnQueryInterface(
353 IUnknown * iface,
354 REFIID riid,
355 LPVOID *ppvObj)
356{
357 ICOM_THIS(IGenericSFImpl, iface);
358
359 _CALL_TRACE
360 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
361
362 *ppvObj = NULL;
363
364 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
365 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
366 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
367 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
368 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
369 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
370 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
371 else if(IsEqualIID(riid, &IID_IDropTarget))
372 {
373 *ppvObj = _IDropTarget_(This);
374 SF_RegisterClipFmt(This);
375 }
376
377 if(*ppvObj)
378 {
379 IUnknown_AddRef((IUnknown*)(*ppvObj));
380 TRACE("-- Interface = %p\n", *ppvObj);
381 return S_OK;
382 }
383 TRACE("-- Interface: E_NOINTERFACE\n");
384 return E_NOINTERFACE;
385}
386
387static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
388{
389 ICOM_THIS(IGenericSFImpl, iface);
390
391 _CALL_TRACE
392 TRACE("(%p)->(count=%lu)\n",This,This->ref);
393
394 shell32_ObjCount++;
395 return ++(This->ref);
396}
397
398static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
399{
400 ICOM_THIS(IGenericSFImpl, iface);
401
402 _CALL_TRACE
403 TRACE("(%p)->(count=%lu)\n",This,This->ref);
404
405 shell32_ObjCount--;
406 if (!--(This->ref))
407 {
408 TRACE("-- destroying IShellFolder(%p)\n",This);
409
410 if (pdesktopfolder == _IShellFolder_(This))
411 {
412 pdesktopfolder=NULL;
413 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
414 }
415 if(This->absPidl) SHFree(This->absPidl);
416 if(This->sMyPath) SHFree(This->sMyPath);
417 HeapFree(GetProcessHeap(),0,This);
418 return 0;
419 }
420 return This->ref;
421}
422
423static ICOM_VTABLE(IUnknown) unkvt =
424{
425 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
426 IUnknown_fnQueryInterface,
427 IUnknown_fnAddRef,
428 IUnknown_fnRelease,
429};
430
431static shvheader GenericSFHeader [] =
432{
433 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
434 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
435 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
436 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
437 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
438};
439#define GENERICSHELLVIEWCOLUMNS 5
440
441/**************************************************************************
442* IShellFolder_Constructor
443*
444* NOTES
445* creating undocumented ShellFS_Folder as part of an aggregation
446* {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
447*
448* FIXME
449* when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
450*/
451HRESULT IFSFolder_Constructor(
452 IUnknown * pUnkOuter,
453 REFIID riid,
454 LPVOID * ppv)
455{
456 IGenericSFImpl * sf;
457 HRESULT hr = S_OK;
458
459 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
460
461 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
462 {
463 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
464 }
465 else
466 {
467 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
468 if (sf)
469 {
470 sf->ref=1;
471 ICOM_VTBL(sf)=&unkvt;
472 sf->lpvtblShellFolder=&sfvt;
473 sf->lpvtblPersistFolder2=&psfvt;
474 sf->lpvtblDropTarget=&dtvt;
475 sf->lpvtblSFHelper=&shvt;
476
477 sf->pclsid = (CLSID*)&CLSID_SFFile;
478 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
479 *ppv = _IUnknown_(sf);
480 hr = S_OK;
481 shell32_ObjCount++;
482 }
483 else
484 {
485 hr = E_OUTOFMEMORY;
486 }
487 }
488 return hr;
489}
490/**************************************************************************
491* IShellFolder_Constructor
492*
493* NOTES
494* THIS points to the parent folder
495*/
496
497IShellFolder * IShellFolder_Constructor(
498 IShellFolder2 * iface,
499 LPITEMIDLIST pidl)
500{
501 IGenericSFImpl * sf;
502 DWORD dwSize=0;
503
504 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
505
506 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
507 sf->ref=1;
508
509 ICOM_VTBL(sf)=&unkvt;
510 sf->lpvtblShellFolder=&sfvt;
511 sf->lpvtblPersistFolder2=&psfvt;
512 sf->lpvtblDropTarget=&dtvt;
513 sf->lpvtblSFHelper=&shvt;
514
515 sf->pclsid = (CLSID*)&CLSID_SFFile;
516 sf->pUnkOuter = _IUnknown_(sf);
517
518 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
519 pdump(pidl);
520
521 if(pidl && iface) /* do we have a pidl? */
522 {
523 int len;
524
525 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
526
527 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
528 {
529 if(This->sMyPath) /* get the size of the parents path */
530 {
531 dwSize += strlen(This->sMyPath) ;
532 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
533 }
534
535 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
536 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
537
538 if(!sf->sMyPath) return NULL;
539 *(sf->sMyPath)=0x00;
540
541 if(This->sMyPath) /* if the parent has a path, get it*/
542 {
543 strcpy(sf->sMyPath, This->sMyPath);
544 PathAddBackslashA (sf->sMyPath);
545 }
546
547 len = strlen(sf->sMyPath);
548 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
549 }
550
551 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
552
553 pdump (sf->absPidl);
554 }
555
556 shell32_ObjCount++;
557 return _IShellFolder_(sf);
558}
559
560/**************************************************************************
561 * IShellFolder_fnQueryInterface
562 *
563 * PARAMETERS
564 * REFIID riid [in ] Requested InterfaceID
565 * LPVOID* ppvObject [out] Interface* to hold the result
566 */
567static HRESULT WINAPI IShellFolder_fnQueryInterface(
568 IShellFolder2 * iface,
569 REFIID riid,
570 LPVOID *ppvObj)
571{
572 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
573
574 _CALL_TRACE
575 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
576
577 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
578}
579
580/**************************************************************************
581* IShellFolder_AddRef
582*/
583
584static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
585{
586 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
587
588 _CALL_TRACE
589 TRACE("(%p)->(count=%lu)\n",This,This->ref);
590
591 return IUnknown_AddRef(This->pUnkOuter);
592}
593
594/**************************************************************************
595 * IShellFolder_fnRelease
596 */
597static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
598{
599 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
600
601 _CALL_TRACE
602 TRACE("(%p)->(count=%lu)\n",This,This->ref);
603
604 return IUnknown_Release(This->pUnkOuter);
605}
606
607/**************************************************************************
608* IShellFolder_fnParseDisplayName
609* PARAMETERS
610* HWND hwndOwner, //[in ] Parent window for any message's
611* LPBC pbc, //[in ] reserved
612* LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
613* ULONG* pchEaten, //[out] (unicode) characters processed
614* LPITEMIDLIST* ppidl, //[out] complex pidl to item
615* ULONG* pdwAttributes //[out] items attributes
616*
617* NOTES
618* every folder trys to parse only it's own (the leftmost) pidl and creates a
619* subfolder to evaluate the remaining parts
620* now we can parse into namespaces implemented by shell extensions
621*
622* behaviour on win98: lpszDisplayName=NULL -> chrash
623* lpszDisplayName="" -> returns mycoputer-pidl
624*
625* FIXME:
626* pdwAttributes: not set
627* pchEaten: not set like in windows
628*/
629static HRESULT WINAPI IShellFolder_fnParseDisplayName(
630 IShellFolder2 * iface,
631 HWND hwndOwner,
632 LPBC pbcReserved,
633 LPOLESTR lpszDisplayName,
634 DWORD *pchEaten,
635 LPITEMIDLIST *ppidl,
636 DWORD *pdwAttributes)
637{
638 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
639
640 HRESULT hr = E_OUTOFMEMORY;
641 LPCWSTR szNext=NULL;
642 WCHAR szElement[MAX_PATH];
643 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
644 LPITEMIDLIST pidlTemp=NULL;
645
646 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
647 This,hwndOwner,pbcReserved,lpszDisplayName,
648 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
649
650 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
651
652 if (pchEaten) *pchEaten = 0; /* strange but like the original */
653
654 if (*lpszDisplayName)
655 {
656 /* get the next element */
657 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
658
659 /* build the full pathname to the element */
660 lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
661 strcpy(szPath, This->sMyPath);
662 PathAddBackslashA(szPath);
663 strcat(szPath, szTempA);
664
665 /* get the pidl */
666 pidlTemp = SHSimpleIDListFromPathA(szPath);
667
668 if (pidlTemp)
669 {
670 /* try to analyse the next element */
671 if (szNext && *szNext)
672 {
673 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
674 }
675 else
676 {
677 if (pdwAttributes && *pdwAttributes)
678 {
679 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
680/* WIN32_FIND_DATAA fd;
681 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
682 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
683 *pdwAttributes &= ~SFGAO_FOLDER;
684 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
685 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
686*/
687 }
688 hr = S_OK;
689 }
690 }
691 }
692
693 *ppidl = pidlTemp;
694
695 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
696
697 return hr;
698}
699
700/**************************************************************************
701* IShellFolder_fnEnumObjects
702* PARAMETERS
703* HWND hwndOwner, //[in ] Parent Window
704* DWORD grfFlags, //[in ] SHCONTF enumeration mask
705* LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
706*/
707static HRESULT WINAPI IShellFolder_fnEnumObjects(
708 IShellFolder2 * iface,
709 HWND hwndOwner,
710 DWORD dwFlags,
711 LPENUMIDLIST* ppEnumIDList)
712{
713 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
714
715 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
716
717 *ppEnumIDList = NULL;
718 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
719
720 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
721
722 if(!*ppEnumIDList) return E_OUTOFMEMORY;
723
724 return S_OK;
725}
726
727/**************************************************************************
728* IShellFolder_fnBindToObject
729* PARAMETERS
730* LPCITEMIDLIST pidl, //[in ] relative pidl to open
731* LPBC pbc, //[in ] reserved
732* REFIID riid, //[in ] Initial Interface
733* LPVOID* ppvObject //[out] Interface*
734*/
735static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
736 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
737{
738 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
739 GUID const * iid;
740 IShellFolder *pShellFolder, *pSubFolder;
741 IPersistFolder *pPersistFolder;
742 LPITEMIDLIST absPidl;
743
744 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
745
746 if(!pidl || !ppvOut) return E_INVALIDARG;
747
748 *ppvOut = NULL;
749
750 if ((iid=_ILGetGUIDPointer(pidl)))
751 {
752 /* we have to create a alien folder */
753 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
754 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
755 {
756 absPidl = ILCombine (This->absPidl, pidl);
757 IPersistFolder_Initialize(pPersistFolder, absPidl);
758 IPersistFolder_Release(pPersistFolder);
759 SHFree(absPidl);
760 }
761 else
762 {
763 return E_FAIL;
764 }
765 }
766 else if(_ILIsFolder(pidl))
767 {
768 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
769 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
770 ILFree(pidltemp);
771 }
772 else
773 {
774 ERR("can't bind to a file\n");
775 return E_FAIL;
776 }
777
778 if (_ILIsPidlSimple(pidl))
779 {
780 *ppvOut = pShellFolder;
781 }
782 else
783 {
784 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
785 IShellFolder_Release(pShellFolder);
786 *ppvOut = pSubFolder;
787 }
788
789 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
790
791 return S_OK;
792}
793
794/**************************************************************************
795* IShellFolder_fnBindToStorage
796* PARAMETERS
797* LPCITEMIDLIST pidl, //[in ] complex pidl to store
798* LPBC pbc, //[in ] reserved
799* REFIID riid, //[in ] Initial storage interface
800* LPVOID* ppvObject //[out] Interface* returned
801*/
802static HRESULT WINAPI IShellFolder_fnBindToStorage(
803 IShellFolder2 * iface,
804 LPCITEMIDLIST pidl,
805 LPBC pbcReserved,
806 REFIID riid,
807 LPVOID *ppvOut)
808{
809 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
810
811 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
812 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
813
814 *ppvOut = NULL;
815 return E_NOTIMPL;
816}
817
818/**************************************************************************
819* IShellFolder_fnCompareIDs
820*
821* PARMETERS
822* LPARAM lParam, //[in ] Column?
823* LPCITEMIDLIST pidl1, //[in ] simple pidl
824* LPCITEMIDLIST pidl2) //[in ] simple pidl
825*
826* NOTES
827* Special case - If one of the items is a Path and the other is a File,
828* always make the Path come before the File.
829*
830* NOTES
831* use SCODE_CODE() on the return value to get the result
832*/
833
834static HRESULT WINAPI IShellFolder_fnCompareIDs(
835 IShellFolder2 * iface,
836 LPARAM lParam,
837 LPCITEMIDLIST pidl1,
838 LPCITEMIDLIST pidl2)
839{
840 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
841
842 CHAR szTemp1[MAX_PATH];
843 CHAR szTemp2[MAX_PATH];
844 int nReturn;
845 IShellFolder * psf;
846 HRESULT hr = E_OUTOFMEMORY;
847 LPCITEMIDLIST pidlTemp;
848 PIDLTYPE pt1, pt2;
849
850 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
851 pdump (pidl1);
852 pdump (pidl2);
853
854 if (!pidl1 && !pidl2)
855 {
856 hr = ResultFromShort(0);
857 }
858 else if (!pidl1)
859 {
860 hr = ResultFromShort(-1);
861 }
862 else if (!pidl2)
863 {
864 hr = ResultFromShort(1);
865 }
866 else
867 {
868 LPPIDLDATA pd1, pd2;
869 pd1 = _ILGetDataPointer(pidl1);
870 pd2 = _ILGetDataPointer(pidl2);
871
872 /* compate the types. sort order is the PT_* constant */
873 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
874 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
875
876 if (pt1 != pt2)
877 {
878 hr = ResultFromShort(pt1-pt2);
879 }
880 else /* same type of pidl */
881 {
882 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
883 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
884 nReturn = strcasecmp(szTemp1, szTemp2);
885
886 if (nReturn == 0) /* first pidl different ? */
887 {
888 pidl1 = ILGetNext(pidl1);
889
890 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
891 {
892 pidlTemp = ILCloneFirst(pidl1);
893 pidl2 = ILGetNext(pidl2);
894
895 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
896 if (SUCCEEDED(hr))
897 {
898 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
899 IShellFolder_Release(psf);
900 hr = ResultFromShort(nReturn);
901 }
902 ILFree(pidlTemp);
903 }
904 else
905 {
906 hr = ResultFromShort(nReturn); /* two equal simple pidls */
907 }
908 }
909 else
910 {
911 hr = ResultFromShort(nReturn); /* two different simple pidls */
912 }
913 }
914 }
915
916 TRACE("-- res=0x%08lx\n", hr);
917 return hr;
918}
919
920/**************************************************************************
921* IShellFolder_fnCreateViewObject
922*/
923static HRESULT WINAPI IShellFolder_fnCreateViewObject(
924 IShellFolder2 * iface,
925 HWND hwndOwner,
926 REFIID riid,
927 LPVOID *ppvOut)
928{
929 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
930
931 LPSHELLVIEW pShellView;
932 HRESULT hr = E_INVALIDARG;
933
934 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
935
936 if(ppvOut)
937 {
938 *ppvOut = NULL;
939
940 if(IsEqualIID(riid, &IID_IDropTarget))
941 {
942 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
943 }
944 else if(IsEqualIID(riid, &IID_IContextMenu))
945 {
946 FIXME("IContextMenu not implemented\n");
947 hr = E_NOTIMPL;
948 }
949 else if(IsEqualIID(riid, &IID_IShellView))
950 {
951 pShellView = IShellView_Constructor((IShellFolder*)iface);
952 if(pShellView)
953 {
954 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
955 IShellView_Release(pShellView);
956 }
957 }
958 }
959 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
960 return hr;
961}
962
963/**************************************************************************
964* IShellFolder_fnGetAttributesOf
965*
966* PARAMETERS
967* UINT cidl, //[in ] num elements in pidl array
968* LPCITEMIDLIST* apidl, //[in ] simple pidl array
969* ULONG* rgfInOut) //[out] result array
970*
971*/
972static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
973 IShellFolder2 * iface,
974 UINT cidl,
975 LPCITEMIDLIST *apidl,
976 DWORD *rgfInOut)
977{
978 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
979
980 HRESULT hr = S_OK;
981
982 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
983
984 if ( (!cidl) || (!apidl) || (!rgfInOut))
985 return E_INVALIDARG;
986
987 while (cidl > 0 && *apidl)
988 {
989 pdump (*apidl);
990 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
991 apidl++;
992 cidl--;
993 }
994
995 TRACE("-- result=0x%08lx\n",*rgfInOut);
996
997 return hr;
998}
999/**************************************************************************
1000* IShellFolder_fnGetUIObjectOf
1001*
1002* PARAMETERS
1003* HWND hwndOwner, //[in ] Parent window for any output
1004* UINT cidl, //[in ] array size
1005* LPCITEMIDLIST* apidl, //[in ] simple pidl array
1006* REFIID riid, //[in ] Requested Interface
1007* UINT* prgfInOut, //[ ] reserved
1008* LPVOID* ppvObject) //[out] Resulting Interface
1009*
1010* NOTES
1011* This function gets asked to return "view objects" for one or more (multiple select)
1012* items:
1013* The viewobject typically is an COM object with one of the following interfaces:
1014* IExtractIcon,IDataObject,IContextMenu
1015* In order to support icon positions in the default Listview your DataObject
1016* must implement the SetData method (in addition to GetData :) - the shell passes
1017* a barely documented "Icon positions" structure to SetData when the drag starts,
1018* and GetData's it if the drop is in another explorer window that needs the positions.
1019*/
1020static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1021 IShellFolder2 * iface,
1022 HWND hwndOwner,
1023 UINT cidl,
1024 LPCITEMIDLIST * apidl,
1025 REFIID riid,
1026 UINT * prgfInOut,
1027 LPVOID * ppvOut)
1028{
1029 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1030
1031 LPITEMIDLIST pidl;
1032 IUnknown* pObj = NULL;
1033 HRESULT hr = E_INVALIDARG;
1034
1035 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1036 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1037
1038 if (ppvOut)
1039 {
1040 *ppvOut = NULL;
1041
1042 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1043 {
1044 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1045 hr = S_OK;
1046 }
1047 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1048 {
1049 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1050 hr = S_OK;
1051 }
1052 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1053 {
1054 pidl = ILCombine(This->absPidl,apidl[0]);
1055 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1056 SHFree(pidl);
1057 hr = S_OK;
1058 }
1059 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1060 {
1061 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1062 }
1063 else
1064 {
1065 hr = E_NOINTERFACE;
1066 }
1067
1068 if(!pObj)
1069 hr = E_OUTOFMEMORY;
1070
1071 *ppvOut = pObj;
1072 }
1073 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1074 return hr;
1075}
1076
1077/**************************************************************************
1078* IShellFolder_fnGetDisplayNameOf
1079* Retrieves the display name for the specified file object or subfolder
1080*
1081* PARAMETERS
1082* LPCITEMIDLIST pidl, //[in ] complex pidl to item
1083* DWORD dwFlags, //[in ] SHGNO formatting flags
1084* LPSTRRET lpName) //[out] Returned display name
1085*
1086* FIXME
1087* if the name is in the pidl the ret value should be a STRRET_OFFSET
1088*/
1089#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1090#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1091
1092static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1093 IShellFolder2 * iface,
1094 LPCITEMIDLIST pidl,
1095 DWORD dwFlags,
1096 LPSTRRET strRet)
1097{
1098 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1099
1100 CHAR szPath[MAX_PATH]= "";
1101 int len = 0;
1102 BOOL bSimplePidl;
1103
1104 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1105 pdump(pidl);
1106
1107 if(!pidl || !strRet) return E_INVALIDARG;
1108
1109 bSimplePidl = _ILIsPidlSimple(pidl);
1110
1111 /* take names of special folders only if its only this folder */
1112 if (_ILIsSpecialFolder(pidl))
1113 {
1114 if ( bSimplePidl)
1115 {
1116 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1117 }
1118 }
1119 else
1120 {
1121 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1122 {
1123 strcpy (szPath, This->sMyPath); /* get path to root*/
1124 PathAddBackslashA(szPath);
1125 len = strlen(szPath);
1126 }
1127 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1128 }
1129
1130 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1131 {
1132 PathAddBackslashA(szPath);
1133 len = strlen(szPath);
1134
1135 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1136 return E_OUTOFMEMORY;
1137 }
1138 strRet->uType = STRRET_CSTRA;
1139 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1140
1141 TRACE("-- (%p)->(%s)\n", This, szPath);
1142 return S_OK;
1143}
1144
1145/**************************************************************************
1146* IShellFolder_fnSetNameOf
1147* Changes the name of a file object or subfolder, possibly changing its item
1148* identifier in the process.
1149*
1150* PARAMETERS
1151* HWND hwndOwner, //[in ] Owner window for output
1152* LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1153* LPCOLESTR lpszName, //[in ] the items new display name
1154* DWORD dwFlags, //[in ] SHGNO formatting flags
1155* LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1156*/
1157static HRESULT WINAPI IShellFolder_fnSetNameOf(
1158 IShellFolder2 * iface,
1159 HWND hwndOwner,
1160 LPCITEMIDLIST pidl, /*simple pidl*/
1161 LPCOLESTR lpName,
1162 DWORD dwFlags,
1163 LPITEMIDLIST *pPidlOut)
1164{
1165 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1166 char szSrc[MAX_PATH], szDest[MAX_PATH];
1167 int len;
1168 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1169
1170 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1171 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1172
1173 /* build source path */
1174 if (dwFlags & SHGDN_INFOLDER)
1175 {
1176 strcpy(szSrc, This->sMyPath);
1177 PathAddBackslashA(szSrc);
1178 len = strlen (szSrc);
1179 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1180 }
1181 else
1182 {
1183 SHGetPathFromIDListA(pidl, szSrc);
1184 }
1185
1186 /* build destination path */
1187 strcpy(szDest, This->sMyPath);
1188 PathAddBackslashA(szDest);
1189 len = strlen (szDest);
1190 lstrcpynWtoA(szDest+len, lpName, MAX_PATH-len);
1191
1192 TRACE("src=%s dest=%s\n", szSrc, szDest);
1193 if ( MoveFileA(szSrc, szDest) )
1194 {
1195 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1196 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1197 return S_OK;
1198 }
1199 return E_FAIL;
1200}
1201
1202static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1203 IShellFolder2 * iface,
1204 GUID *pguid)
1205{
1206 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1207 FIXME("(%p)\n",This);
1208 return E_NOTIMPL;
1209}
1210static HRESULT WINAPI IShellFolder_fnEnumSearches(
1211 IShellFolder2 * iface,
1212 IEnumExtraSearch **ppenum)
1213{
1214 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1215 FIXME("(%p)\n",This);
1216 return E_NOTIMPL;
1217}
1218static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1219 IShellFolder2 * iface,
1220 DWORD dwRes,
1221 ULONG *pSort,
1222 ULONG *pDisplay)
1223{
1224 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1225
1226 TRACE("(%p)\n",This);
1227
1228 if (pSort) *pSort = 0;
1229 if (pDisplay) *pDisplay = 0;
1230
1231 return S_OK;
1232}
1233static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1234 IShellFolder2 * iface,
1235 UINT iColumn,
1236 DWORD *pcsFlags)
1237{
1238 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1239
1240 TRACE("(%p)\n",This);
1241
1242 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1243
1244 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1245
1246 return S_OK;
1247}
1248static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1249 IShellFolder2 * iface,
1250 LPCITEMIDLIST pidl,
1251 const SHCOLUMNID *pscid,
1252 VARIANT *pv)
1253{
1254 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1255 FIXME("(%p)\n",This);
1256
1257 return E_NOTIMPL;
1258}
1259static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1260 IShellFolder2 * iface,
1261 LPCITEMIDLIST pidl,
1262 UINT iColumn,
1263 SHELLDETAILS *psd)
1264{
1265 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1266 HRESULT hr = E_FAIL;
1267
1268 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1269
1270 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1271
1272 if (!pidl)
1273 {
1274 /* the header titles */
1275 psd->fmt = GenericSFHeader[iColumn].fmt;
1276 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1277 psd->str.uType = STRRET_CSTRA;
1278 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1279 return S_OK;
1280 }
1281 else
1282 {
1283 /* the data from the pidl */
1284 switch(iColumn)
1285 {
1286 case 0: /* name */
1287 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1288 break;
1289 case 1: /* size */
1290 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1291 break;
1292 case 2: /* type */
1293 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1294 break;
1295 case 3: /* date */
1296 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1297 break;
1298 case 4: /* attributes */
1299 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1300 break;
1301 }
1302 hr = S_OK;
1303 psd->str.uType = STRRET_CSTRA;
1304 }
1305
1306 return hr;
1307}
1308static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1309 IShellFolder2 * iface,
1310 LPCWSTR pwszName,
1311 SHCOLUMNID *pscid)
1312{
1313 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1314 FIXME("(%p)\n",This);
1315 return E_NOTIMPL;
1316}
1317
1318static ICOM_VTABLE(IShellFolder2) sfvt =
1319{
1320 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1321 IShellFolder_fnQueryInterface,
1322 IShellFolder_fnAddRef,
1323 IShellFolder_fnRelease,
1324 IShellFolder_fnParseDisplayName,
1325 IShellFolder_fnEnumObjects,
1326 IShellFolder_fnBindToObject,
1327 IShellFolder_fnBindToStorage,
1328 IShellFolder_fnCompareIDs,
1329 IShellFolder_fnCreateViewObject,
1330 IShellFolder_fnGetAttributesOf,
1331 IShellFolder_fnGetUIObjectOf,
1332 IShellFolder_fnGetDisplayNameOf,
1333 IShellFolder_fnSetNameOf,
1334
1335 /* ShellFolder2 */
1336 IShellFolder_fnGetDefaultSearchGUID,
1337 IShellFolder_fnEnumSearches,
1338 IShellFolder_fnGetDefaultColumn,
1339 IShellFolder_fnGetDefaultColumnState,
1340 IShellFolder_fnGetDetailsEx,
1341 IShellFolder_fnGetDetailsOf,
1342 IShellFolder_fnMapNameToSCID
1343};
1344
1345/****************************************************************************
1346 * ISFHelper for IShellFolder implementation
1347 */
1348
1349static HRESULT WINAPI ISFHelper_fnQueryInterface(
1350 ISFHelper *iface,
1351 REFIID riid,
1352 LPVOID *ppvObj)
1353{
1354 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1355
1356 TRACE("(%p)\n", This);
1357
1358 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1359}
1360
1361static ULONG WINAPI ISFHelper_fnAddRef(
1362 ISFHelper *iface)
1363{
1364 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1365
1366 TRACE("(%p)\n", This);
1367
1368 return IUnknown_AddRef(This->pUnkOuter);
1369}
1370
1371static ULONG WINAPI ISFHelper_fnRelease(
1372 ISFHelper *iface)
1373{
1374 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1375
1376 TRACE("(%p)\n", This);
1377
1378 return IUnknown_Release(This->pUnkOuter);
1379}
1380
1381
1382/****************************************************************************
1383 * ISFHelper_fnAddFolder
1384 *
1385 * creates a unique folder name
1386 */
1387
1388static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1389 ISFHelper *iface,
1390 LPSTR lpName,
1391 UINT uLen)
1392{
1393 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1394 IEnumIDList * penum;
1395 HRESULT hr;
1396 char szText[MAX_PATH];
1397 char * szNewFolder = "New Folder";
1398
1399 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1400
1401 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1402
1403 strcpy(lpName, szNewFolder);
1404
1405 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1406 if (penum)
1407 {
1408 LPITEMIDLIST pidl;
1409 DWORD dwFetched;
1410 int i=1;
1411
1412next: IEnumIDList_Reset(penum);
1413 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1414 {
1415 _ILSimpleGetText(pidl, szText, MAX_PATH);
1416 if (0 == strcasecmp(szText, lpName))
1417 {
1418 sprintf(lpName, "%s %d", szNewFolder, i++);
1419 if (i > 99)
1420 {
1421 hr = E_FAIL;
1422 break;
1423 }
1424 goto next;
1425 }
1426 }
1427
1428 IEnumIDList_Release(penum);
1429 }
1430 return hr;
1431}
1432
1433/****************************************************************************
1434 * ISFHelper_fnAddFolder
1435 *
1436 * adds a new folder.
1437 */
1438
1439static HRESULT WINAPI ISFHelper_fnAddFolder(
1440 ISFHelper *iface,
1441 HWND hwnd,
1442 LPCSTR lpName,
1443 LPITEMIDLIST* ppidlOut)
1444{
1445 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1446 char lpstrNewDir[MAX_PATH];
1447 DWORD bRes;
1448 HRESULT hres = E_FAIL;
1449
1450 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1451
1452 strcpy(lpstrNewDir, This->sMyPath);
1453 PathAddBackslashA(lpstrNewDir);
1454 strcat(lpstrNewDir, lpName);
1455
1456 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1457
1458 if (bRes)
1459 {
1460 LPITEMIDLIST pidl, pidlitem;
1461
1462 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1463
1464 pidl = ILCombine(This->absPidl, pidlitem);
1465 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1466 SHFree(pidl);
1467
1468 if (ppidlOut) *ppidlOut = pidlitem;
1469 hres = S_OK;
1470 }
1471 else
1472 {
1473 char lpstrText[128+MAX_PATH];
1474 char lpstrTempText[128];
1475 char lpstrCaption[256];
1476
1477 /* Cannot Create folder because of permissions */
1478 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1479 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1480 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1481 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1482 }
1483
1484 return hres;
1485}
1486
1487/****************************************************************************
1488 * ISFHelper_fnDeleteItems
1489 *
1490 * deletes items in folder
1491 */
1492static HRESULT WINAPI ISFHelper_fnDeleteItems(
1493 ISFHelper *iface,
1494 UINT cidl,
1495 LPCITEMIDLIST* apidl)
1496{
1497 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1498 int i;
1499 char szPath[MAX_PATH];
1500
1501 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1502
1503 for(i=0; i< cidl; i++)
1504 {
1505 strcpy(szPath, This->sMyPath);
1506 PathAddBackslashA(szPath);
1507 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1508
1509 if (_ILIsFolder(apidl[i]))
1510 {
1511 LPITEMIDLIST pidl;
1512
1513 MESSAGE("delete %s\n", szPath);
1514 if (! SHELL_DeleteDirectoryA(szPath, TRUE)) return E_FAIL;
1515 pidl = ILCombine(This->absPidl, apidl[i]);
1516 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1517 SHFree(pidl);
1518 }
1519 else if (_ILIsValue(apidl[i]))
1520 {
1521 LPITEMIDLIST pidl;
1522
1523 MESSAGE("delete %s\n", szPath);
1524 if (! DeleteFileA(szPath)) return E_FAIL;
1525 pidl = ILCombine(This->absPidl, apidl[i]);
1526 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1527 SHFree(pidl);
1528 }
1529
1530 }
1531 return S_OK;
1532}
1533
1534/****************************************************************************
1535 * ISFHelper_fnCopyItems
1536 *
1537 * copys items to this folder
1538 */
1539static HRESULT WINAPI ISFHelper_fnCopyItems(
1540 ISFHelper *iface,
1541 IShellFolder* pSFFrom,
1542 UINT cidl,
1543 LPCITEMIDLIST *apidl)
1544{
1545 int i;
1546 IPersistFolder2 * ppf2=NULL;
1547 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1548 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1549
1550 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1551
1552 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1553 if (ppf2)
1554 {
1555 LPITEMIDLIST pidl;
1556 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1557 {
1558 for (i=0; i<cidl; i++)
1559 {
1560 SHGetPathFromIDListA(pidl, szSrcPath);
1561 PathAddBackslashA(szSrcPath);
1562 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1563
1564 strcpy(szDstPath, This->sMyPath);
1565 PathAddBackslashA(szDstPath);
1566 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1567 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1568 }
1569 SHFree(pidl);
1570 }
1571 IPersistFolder2_Release(ppf2);
1572 }
1573 return S_OK;
1574}
1575
1576static ICOM_VTABLE(ISFHelper) shvt =
1577{
1578 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1579 ISFHelper_fnQueryInterface,
1580 ISFHelper_fnAddRef,
1581 ISFHelper_fnRelease,
1582 ISFHelper_fnGetUniqueName,
1583 ISFHelper_fnAddFolder,
1584 ISFHelper_fnDeleteItems,
1585 ISFHelper_fnCopyItems,
1586};
1587
1588/***********************************************************************
1589* [Desktopfolder] IShellFolder implementation
1590*/
1591static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1592
1593static shvheader DesktopSFHeader [] =
1594{
1595 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1596 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1597 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1598 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1599 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1600};
1601#define DESKTOPSHELLVIEWCOLUMNS 5
1602
1603/**************************************************************************
1604* ISF_Desktop_Constructor
1605*
1606*/
1607IShellFolder * ISF_Desktop_Constructor()
1608{
1609 IGenericSFImpl * sf;
1610
1611 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1612 sf->ref=1;
1613 ICOM_VTBL(sf)=&unkvt;
1614 sf->lpvtblShellFolder=&sfdvt;
1615 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1616 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1617
1618 TRACE("(%p)\n",sf);
1619
1620 shell32_ObjCount++;
1621 return _IShellFolder_(sf);
1622}
1623
1624/**************************************************************************
1625 * ISF_Desktop_fnQueryInterface
1626 *
1627 * NOTES supports not IPersist/IPersistFolder
1628 */
1629static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1630 IShellFolder2 * iface,
1631 REFIID riid,
1632 LPVOID *ppvObj)
1633{
1634 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1635
1636 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1637
1638 *ppvObj = NULL;
1639
1640 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1641 {
1642 *ppvObj = _IUnknown_(This);
1643 }
1644 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1645 {
1646 *ppvObj = _IShellFolder_(This);
1647 }
1648 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1649 {
1650 *ppvObj = _IShellFolder_(This);
1651 }
1652
1653 if(*ppvObj)
1654 {
1655 IUnknown_AddRef((IUnknown*)(*ppvObj));
1656 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1657 return S_OK;
1658 }
1659 TRACE("-- Interface: E_NOINTERFACE\n");
1660 return E_NOINTERFACE;
1661}
1662
1663/**************************************************************************
1664* ISF_Desktop_fnParseDisplayName
1665*
1666* NOTES
1667* "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1668* to MyComputer
1669*/
1670static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1671 IShellFolder2 * iface,
1672 HWND hwndOwner,
1673 LPBC pbcReserved,
1674 LPOLESTR lpszDisplayName,
1675 DWORD *pchEaten,
1676 LPITEMIDLIST *ppidl,
1677 DWORD *pdwAttributes)
1678{
1679 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1680
1681 LPCWSTR szNext=NULL;
1682 LPITEMIDLIST pidlTemp=NULL;
1683 HRESULT hr=E_OUTOFMEMORY;
1684
1685 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1686 This,hwndOwner,pbcReserved,lpszDisplayName,
1687 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1688
1689 *ppidl = 0;
1690 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1691
1692 /* fixme no real parsing implemented */
1693 pidlTemp = _ILCreateMyComputer();
1694 szNext = lpszDisplayName;
1695
1696 if (szNext && *szNext)
1697 {
1698 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1699 }
1700 else
1701 {
1702 hr = S_OK;
1703
1704 if (pdwAttributes && *pdwAttributes)
1705 {
1706 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1707 }
1708 }
1709
1710 *ppidl = pidlTemp;
1711
1712 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1713
1714 return hr;
1715}
1716
1717/**************************************************************************
1718* ISF_Desktop_fnEnumObjects
1719*/
1720static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1721 IShellFolder2 * iface,
1722 HWND hwndOwner,
1723 DWORD dwFlags,
1724 LPENUMIDLIST* ppEnumIDList)
1725{
1726 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1727
1728 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1729
1730 *ppEnumIDList = NULL;
1731 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1732
1733 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1734
1735 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1736
1737 return S_OK;
1738}
1739
1740/**************************************************************************
1741* ISF_Desktop_fnBindToObject
1742*/
1743static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1744 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1745{
1746 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1747 GUID const * clsid;
1748 IShellFolder *pShellFolder, *pSubFolder;
1749
1750 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1751 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1752
1753 *ppvOut = NULL;
1754
1755 if ((clsid=_ILGetGUIDPointer(pidl)))
1756 {
1757 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1758 {
1759 pShellFolder = ISF_MyComputer_Constructor();
1760 }
1761 else
1762 {
1763 /* shell extension */
1764 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1765 {
1766 return E_INVALIDARG;
1767 }
1768 }
1769 }
1770 else
1771 {
1772 /* file system folder on the desktop */
1773 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1774 IPersistFolder * ppf;
1775
1776 /* combine pidls */
1777 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1778 firstpidl = ILCloneFirst(pidl);
1779 completepidl = ILCombine(deskpidl, firstpidl);
1780
1781 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1782 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1783 {
1784 IPersistFolder_Initialize(ppf, completepidl);
1785 IPersistFolder_Release(ppf);
1786 }
1787 ILFree(completepidl);
1788 ILFree(deskpidl);
1789 ILFree(firstpidl);
1790 }
1791
1792 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1793 {
1794 *ppvOut = pShellFolder;
1795 }
1796 else /* go deeper */
1797 {
1798 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1799 IShellFolder_Release(pShellFolder);
1800 *ppvOut = pSubFolder;
1801 }
1802
1803 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1804
1805 return S_OK;
1806}
1807
1808/**************************************************************************
1809* ISF_Desktop_fnCreateViewObject
1810*/
1811static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1812 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1813{
1814 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1815
1816 LPSHELLVIEW pShellView;
1817 HRESULT hr = E_INVALIDARG;
1818
1819 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1820
1821 if(ppvOut)
1822 {
1823 *ppvOut = NULL;
1824
1825 if(IsEqualIID(riid, &IID_IDropTarget))
1826 {
1827 WARN("IDropTarget not implemented\n");
1828 hr = E_NOTIMPL;
1829 }
1830 else if(IsEqualIID(riid, &IID_IContextMenu))
1831 {
1832 WARN("IContextMenu not implemented\n");
1833 hr = E_NOTIMPL;
1834 }
1835 else if(IsEqualIID(riid, &IID_IShellView))
1836 {
1837 pShellView = IShellView_Constructor((IShellFolder*)iface);
1838 if(pShellView)
1839 {
1840 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1841 IShellView_Release(pShellView);
1842 }
1843 }
1844 }
1845 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1846 return hr;
1847}
1848
1849/**************************************************************************
1850* ISF_Desktop_fnGetAttributesOf
1851*/
1852static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1853 IShellFolder2 * iface,
1854 UINT cidl,
1855 LPCITEMIDLIST *apidl,
1856 DWORD *rgfInOut)
1857{
1858 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1859
1860 HRESULT hr = S_OK;
1861
1862 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1863
1864 if ( (!cidl) || (!apidl) || (!rgfInOut))
1865 return E_INVALIDARG;
1866
1867 while (cidl > 0 && *apidl)
1868 {
1869 pdump (*apidl);
1870 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1871 apidl++;
1872 cidl--;
1873 }
1874
1875 TRACE("-- result=0x%08lx\n",*rgfInOut);
1876
1877 return hr;
1878}
1879
1880/**************************************************************************
1881* ISF_Desktop_fnGetDisplayNameOf
1882*
1883* NOTES
1884* special case: pidl = null gives desktop-name back
1885*/
1886static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1887 IShellFolder2 * iface,
1888 LPCITEMIDLIST pidl,
1889 DWORD dwFlags,
1890 LPSTRRET strRet)
1891{
1892 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1893
1894 CHAR szPath[MAX_PATH]= "";
1895
1896 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1897 pdump(pidl);
1898
1899 if(!strRet) return E_INVALIDARG;
1900
1901 if(!pidl)
1902 {
1903 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1904 }
1905 else if ( _ILIsPidlSimple(pidl) )
1906 {
1907 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1908 }
1909 else
1910 {
1911 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1912 return E_OUTOFMEMORY;
1913 }
1914 strRet->uType = STRRET_CSTRA;
1915 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1916
1917
1918 TRACE("-- (%p)->(%s)\n", This, szPath);
1919 return S_OK;
1920}
1921
1922static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1923 IShellFolder2 * iface,
1924 GUID *pguid)
1925{
1926 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1927 FIXME("(%p)\n",This);
1928 return E_NOTIMPL;
1929}
1930static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1931 IShellFolder2 * iface,
1932 IEnumExtraSearch **ppenum)
1933{
1934 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1935 FIXME("(%p)\n",This);
1936 return E_NOTIMPL;
1937}
1938static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1939 IShellFolder2 * iface,
1940 DWORD dwRes,
1941 ULONG *pSort,
1942 ULONG *pDisplay)
1943{
1944 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1945
1946 TRACE("(%p)\n",This);
1947
1948 if (pSort) *pSort = 0;
1949 if (pDisplay) *pDisplay = 0;
1950
1951 return S_OK;
1952}
1953static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1954 IShellFolder2 * iface,
1955 UINT iColumn,
1956 DWORD *pcsFlags)
1957{
1958 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1959
1960 TRACE("(%p)\n",This);
1961
1962 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1963
1964 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1965
1966 return S_OK;
1967}
1968static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1969 IShellFolder2 * iface,
1970 LPCITEMIDLIST pidl,
1971 const SHCOLUMNID *pscid,
1972 VARIANT *pv)
1973{
1974 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1975 FIXME("(%p)\n",This);
1976
1977 return E_NOTIMPL;
1978}
1979static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
1980 IShellFolder2 * iface,
1981 LPCITEMIDLIST pidl,
1982 UINT iColumn,
1983 SHELLDETAILS *psd)
1984{
1985 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1986 HRESULT hr = E_FAIL;;
1987
1988 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1989
1990 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1991
1992 if (!pidl)
1993 {
1994 psd->fmt = DesktopSFHeader[iColumn].fmt;
1995 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
1996 psd->str.uType = STRRET_CSTRA;
1997 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1998 return S_OK;
1999 }
2000 else
2001 {
2002 /* the data from the pidl */
2003 switch(iColumn)
2004 {
2005 case 0: /* name */
2006 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2007 break;
2008 case 1: /* size */
2009 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2010 break;
2011 case 2: /* type */
2012 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2013 break;
2014 case 3: /* date */
2015 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2016 break;
2017 case 4: /* attributes */
2018 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2019 break;
2020 }
2021 hr = S_OK;
2022 psd->str.uType = STRRET_CSTRA;
2023 }
2024
2025 return hr;
2026}
2027static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2028 IShellFolder2 * iface,
2029 LPCWSTR pwszName,
2030 SHCOLUMNID *pscid)
2031{
2032 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2033 FIXME("(%p)\n",This);
2034 return E_NOTIMPL;
2035}
2036
2037static ICOM_VTABLE(IShellFolder2) sfdvt =
2038{
2039 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2040 ISF_Desktop_fnQueryInterface,
2041 IShellFolder_fnAddRef,
2042 IShellFolder_fnRelease,
2043 ISF_Desktop_fnParseDisplayName,
2044 ISF_Desktop_fnEnumObjects,
2045 ISF_Desktop_fnBindToObject,
2046 IShellFolder_fnBindToStorage,
2047 IShellFolder_fnCompareIDs,
2048 ISF_Desktop_fnCreateViewObject,
2049 ISF_Desktop_fnGetAttributesOf,
2050 IShellFolder_fnGetUIObjectOf,
2051 ISF_Desktop_fnGetDisplayNameOf,
2052 IShellFolder_fnSetNameOf,
2053
2054 /* ShellFolder2 */
2055 ISF_Desktop_fnGetDefaultSearchGUID,
2056 ISF_Desktop_fnEnumSearches,
2057 ISF_Desktop_fnGetDefaultColumn,
2058 ISF_Desktop_fnGetDefaultColumnState,
2059 ISF_Desktop_fnGetDetailsEx,
2060 ISF_Desktop_fnGetDetailsOf,
2061 ISF_Desktop_fnMapNameToSCID
2062};
2063
2064
2065/***********************************************************************
2066* IShellFolder [MyComputer] implementation
2067*/
2068
2069static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2070
2071static shvheader MyComputerSFHeader [] =
2072{
2073 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2074 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2075 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2076 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2077};
2078#define MYCOMPUTERSHELLVIEWCOLUMNS 4
2079
2080/**************************************************************************
2081* ISF_MyComputer_Constructor
2082*/
2083static IShellFolder * ISF_MyComputer_Constructor(void)
2084{
2085 IGenericSFImpl * sf;
2086
2087 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2088 sf->ref=1;
2089
2090 ICOM_VTBL(sf)=&unkvt;
2091 sf->lpvtblShellFolder=&sfmcvt;
2092 sf->lpvtblPersistFolder2 = &psfvt;
2093 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2094 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2095 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2096
2097 TRACE("(%p)\n",sf);
2098
2099 shell32_ObjCount++;
2100 return _IShellFolder_(sf);
2101}
2102
2103/**************************************************************************
2104* ISF_MyComputer_fnParseDisplayName
2105*/
2106static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2107 IShellFolder2 * iface,
2108 HWND hwndOwner,
2109 LPBC pbcReserved,
2110 LPOLESTR lpszDisplayName,
2111 DWORD *pchEaten,
2112 LPITEMIDLIST *ppidl,
2113 DWORD *pdwAttributes)
2114{
2115 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2116
2117 HRESULT hr = E_OUTOFMEMORY;
2118 LPCWSTR szNext=NULL;
2119 WCHAR szElement[MAX_PATH];
2120 CHAR szTempA[MAX_PATH];
2121 LPITEMIDLIST pidlTemp;
2122
2123 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2124 This,hwndOwner,pbcReserved,lpszDisplayName,
2125 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2126
2127 *ppidl = 0;
2128 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2129
2130 /* do we have an absolute path name ? */
2131 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2132 lpszDisplayName[2] == (WCHAR)'\\')
2133 {
2134 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2135 lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
2136 pidlTemp = _ILCreateDrive(szTempA);
2137
2138 if (szNext && *szNext)
2139 {
2140 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2141 }
2142 else
2143 {
2144 if (pdwAttributes && *pdwAttributes)
2145 {
2146 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2147 }
2148 hr = S_OK;
2149 }
2150 *ppidl = pidlTemp;
2151 }
2152
2153 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2154
2155 return hr;
2156}
2157
2158/**************************************************************************
2159* ISF_MyComputer_fnEnumObjects
2160*/
2161static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2162 IShellFolder2 * iface,
2163 HWND hwndOwner,
2164 DWORD dwFlags,
2165 LPENUMIDLIST* ppEnumIDList)
2166{
2167 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2168
2169 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2170
2171 *ppEnumIDList = NULL;
2172 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2173
2174 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2175
2176 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2177
2178 return S_OK;
2179}
2180
2181/**************************************************************************
2182* ISF_MyComputer_fnBindToObject
2183*/
2184static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2185 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2186{
2187 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2188 GUID const * clsid;
2189 IShellFolder *pShellFolder, *pSubFolder;
2190 LPITEMIDLIST pidltemp;
2191
2192 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2193 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2194
2195 if(!pidl || !ppvOut) return E_INVALIDARG;
2196
2197 *ppvOut = NULL;
2198
2199 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2200 {
2201 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2202 {
2203 return E_FAIL;
2204 }
2205 }
2206 else
2207 {
2208 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2209
2210 pidltemp = ILCloneFirst(pidl);
2211 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2212 ILFree(pidltemp);
2213 }
2214
2215 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2216 {
2217 *ppvOut = pShellFolder;
2218 }
2219 else /* go deeper */
2220 {
2221 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
2222 IShellFolder_Release(pShellFolder);
2223 *ppvOut = pSubFolder;
2224 }
2225
2226 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
2227
2228 return S_OK;
2229}
2230
2231/**************************************************************************
2232* ISF_MyComputer_fnCreateViewObject
2233*/
2234static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2235 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2236{
2237 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2238
2239 LPSHELLVIEW pShellView;
2240 HRESULT hr = E_INVALIDARG;
2241
2242 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2243
2244 if(ppvOut)
2245 {
2246 *ppvOut = NULL;
2247
2248 if(IsEqualIID(riid, &IID_IDropTarget))
2249 {
2250 WARN("IDropTarget not implemented\n");
2251 hr = E_NOTIMPL;
2252 }
2253 else if(IsEqualIID(riid, &IID_IContextMenu))
2254 {
2255 WARN("IContextMenu not implemented\n");
2256 hr = E_NOTIMPL;
2257 }
2258 else if(IsEqualIID(riid, &IID_IShellView))
2259 {
2260 pShellView = IShellView_Constructor((IShellFolder*)iface);
2261 if(pShellView)
2262 {
2263 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2264 IShellView_Release(pShellView);
2265 }
2266 }
2267 }
2268 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2269 return hr;
2270}
2271
2272/**************************************************************************
2273* ISF_MyComputer_fnGetAttributesOf
2274*/
2275static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2276 IShellFolder2 * iface,
2277 UINT cidl,
2278 LPCITEMIDLIST *apidl,
2279 DWORD *rgfInOut)
2280{
2281 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2282
2283 HRESULT hr = S_OK;
2284
2285 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2286
2287 if ( (!cidl) || (!apidl) || (!rgfInOut))
2288 return E_INVALIDARG;
2289
2290 while (cidl > 0 && *apidl)
2291 {
2292 pdump (*apidl);
2293 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2294 apidl++;
2295 cidl--;
2296 }
2297
2298 TRACE("-- result=0x%08lx\n",*rgfInOut);
2299 return hr;
2300}
2301
2302/**************************************************************************
2303* ISF_MyComputer_fnGetDisplayNameOf
2304*
2305* NOTES
2306* The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2307* SHGDN_INFOLDER makes no sense.
2308*/
2309static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2310 IShellFolder2 * iface,
2311 LPCITEMIDLIST pidl,
2312 DWORD dwFlags,
2313 LPSTRRET strRet)
2314{
2315 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2316
2317 char szPath[MAX_PATH], szDrive[18];
2318 int len = 0;
2319 BOOL bSimplePidl;
2320
2321 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2322 pdump(pidl);
2323
2324 if(!strRet) return E_INVALIDARG;
2325
2326 szPath[0]=0x00; szDrive[0]=0x00;
2327
2328
2329 bSimplePidl = _ILIsPidlSimple(pidl);
2330
2331 if (_ILIsSpecialFolder(pidl))
2332 {
2333 /* take names of special folders only if its only this folder */
2334 if ( bSimplePidl )
2335 {
2336 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2337 }
2338 }
2339 else
2340 {
2341 if (!_ILIsDrive(pidl))
2342 {
2343 ERR("Wrong pidl type\n");
2344 return E_INVALIDARG;
2345 }
2346
2347 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2348
2349 /* long view "lw_name (C:)" */
2350 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2351 {
2352 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2353
2354#ifdef __WIN32OS2__
2355//CB: floppy drives have a fixed name
2356 if ((szPath[0] == 'A') || (szPath[0] == 'a') || (szPath[0] == 'B') || (szPath[0] == 'b'))
2357 {
2358 //floppy
2359 strncpy(szDrive,szPath,2);
2360 //3.5 floppy
2361 LoadStringA(shell32_hInstance,IDS_35FLOPPY,szPath,sizeof(szPath)-10);
2362 //CB: todo: 5.25 floppy check
2363 strcat(szPath," (");
2364 strncat(szPath,szDrive,2);
2365 strcat(szPath,")");
2366 } else
2367 {
2368 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2369 strcat (szDrive," (");
2370 strncat (szDrive, szPath, 2);
2371 strcat (szDrive,")");
2372 strcpy (szPath, szDrive);
2373 }
2374#else
2375 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2376 strcat (szDrive," (");
2377 strncat (szDrive, szPath, 2);
2378 strcat (szDrive,")");
2379 strcpy (szPath, szDrive);
2380#endif
2381 }
2382 }
2383
2384 if (!bSimplePidl) /* go deeper if needed */
2385 {
2386 PathAddBackslashA(szPath);
2387 len = strlen(szPath);
2388
2389 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2390 return E_OUTOFMEMORY;
2391 }
2392 strRet->uType = STRRET_CSTRA;
2393 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2394
2395
2396 TRACE("-- (%p)->(%s)\n", This, szPath);
2397 return S_OK;
2398}
2399
2400static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2401 IShellFolder2 * iface,
2402 GUID *pguid)
2403{
2404 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2405 FIXME("(%p)\n",This);
2406 return E_NOTIMPL;
2407}
2408static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2409 IShellFolder2 * iface,
2410 IEnumExtraSearch **ppenum)
2411{
2412 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2413 FIXME("(%p)\n",This);
2414 return E_NOTIMPL;
2415}
2416static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2417 IShellFolder2 * iface,
2418 DWORD dwRes,
2419 ULONG *pSort,
2420 ULONG *pDisplay)
2421{
2422 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2423
2424 TRACE("(%p)\n",This);
2425
2426 if (pSort) *pSort = 0;
2427 if (pDisplay) *pDisplay = 0;
2428
2429 return S_OK;
2430}
2431static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2432 IShellFolder2 * iface,
2433 UINT iColumn,
2434 DWORD *pcsFlags)
2435{
2436 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2437
2438 TRACE("(%p)\n",This);
2439
2440 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2441
2442 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2443
2444 return S_OK;
2445}
2446static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2447 IShellFolder2 * iface,
2448 LPCITEMIDLIST pidl,
2449 const SHCOLUMNID *pscid,
2450 VARIANT *pv)
2451{
2452 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2453 FIXME("(%p)\n",This);
2454
2455 return E_NOTIMPL;
2456}
2457
2458/* fixme: drive size >4GB is rolling over */
2459static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2460 IShellFolder2 * iface,
2461 LPCITEMIDLIST pidl,
2462 UINT iColumn,
2463 SHELLDETAILS *psd)
2464{
2465 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2466 HRESULT hr;
2467
2468 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2469
2470 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2471
2472 if (!pidl)
2473 {
2474 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2475 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2476 psd->str.uType = STRRET_CSTRA;
2477 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2478 return S_OK;
2479 }
2480 else
2481 {
2482 char szPath[MAX_PATH];
2483 ULARGE_INTEGER ulBytes;
2484
2485 psd->str.u.cStr[0] = 0x00;
2486 psd->str.uType = STRRET_CSTRA;
2487 switch(iColumn)
2488 {
2489 case 0: /* name */
2490 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2491 break;
2492 case 1: /* type */
2493 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2494 break;
2495 case 2: /* total size */
2496 if (_ILIsDrive(pidl))
2497 {
2498 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2499 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2500#ifdef __WIN32OS2__
2501 StrFormatByteSizeA(ulBytes.LowPart, psd->str.u.cStr, MAX_PATH);
2502#else
2503 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2504#endif
2505 }
2506 break;
2507 case 3: /* free size */
2508 if (_ILIsDrive(pidl))
2509 {
2510 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2511 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2512#ifdef __WIN32OS2__
2513 StrFormatByteSizeA(ulBytes.LowPart, psd->str.u.cStr, MAX_PATH);
2514#else
2515 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2516#endif
2517 }
2518 break;
2519 }
2520 hr = S_OK;
2521 }
2522
2523 return hr;
2524}
2525static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2526 IShellFolder2 * iface,
2527 LPCWSTR pwszName,
2528 SHCOLUMNID *pscid)
2529{
2530 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2531 FIXME("(%p)\n",This);
2532 return E_NOTIMPL;
2533}
2534
2535static ICOM_VTABLE(IShellFolder2) sfmcvt =
2536{
2537 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2538 IShellFolder_fnQueryInterface,
2539 IShellFolder_fnAddRef,
2540 IShellFolder_fnRelease,
2541 ISF_MyComputer_fnParseDisplayName,
2542 ISF_MyComputer_fnEnumObjects,
2543 ISF_MyComputer_fnBindToObject,
2544 IShellFolder_fnBindToStorage,
2545 IShellFolder_fnCompareIDs,
2546 ISF_MyComputer_fnCreateViewObject,
2547 ISF_MyComputer_fnGetAttributesOf,
2548 IShellFolder_fnGetUIObjectOf,
2549 ISF_MyComputer_fnGetDisplayNameOf,
2550 IShellFolder_fnSetNameOf,
2551
2552 /* ShellFolder2 */
2553 ISF_MyComputer_fnGetDefaultSearchGUID,
2554 ISF_MyComputer_fnEnumSearches,
2555 ISF_MyComputer_fnGetDefaultColumn,
2556 ISF_MyComputer_fnGetDefaultColumnState,
2557 ISF_MyComputer_fnGetDetailsEx,
2558 ISF_MyComputer_fnGetDetailsOf,
2559 ISF_MyComputer_fnMapNameToSCID
2560};
2561
2562
2563/************************************************************************
2564 * ISFPersistFolder_QueryInterface (IUnknown)
2565 *
2566 */
2567static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2568 IPersistFolder2 * iface,
2569 REFIID iid,
2570 LPVOID* ppvObj)
2571{
2572 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2573
2574 TRACE("(%p)\n", This);
2575
2576 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2577}
2578
2579/************************************************************************
2580 * ISFPersistFolder_AddRef (IUnknown)
2581 *
2582 */
2583static ULONG WINAPI ISFPersistFolder2_AddRef(
2584 IPersistFolder2 * iface)
2585{
2586 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2587
2588 TRACE("(%p)\n", This);
2589
2590 return IUnknown_AddRef(This->pUnkOuter);
2591}
2592
2593/************************************************************************
2594 * ISFPersistFolder_Release (IUnknown)
2595 *
2596 */
2597static ULONG WINAPI ISFPersistFolder2_Release(
2598 IPersistFolder2 * iface)
2599{
2600 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2601
2602 TRACE("(%p)\n", This);
2603
2604 return IUnknown_Release(This->pUnkOuter);
2605}
2606
2607/************************************************************************
2608 * ISFPersistFolder_GetClassID (IPersist)
2609 */
2610static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2611 IPersistFolder2 * iface,
2612 CLSID * lpClassId)
2613{
2614 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2615
2616 TRACE("(%p)\n", This);
2617
2618 if (!lpClassId) return E_POINTER;
2619 *lpClassId = *This->pclsid;
2620
2621 return S_OK;
2622}
2623
2624/************************************************************************
2625 * ISFPersistFolder_Initialize (IPersistFolder)
2626 *
2627 * NOTES
2628 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2629 */
2630static HRESULT WINAPI ISFPersistFolder2_Initialize(
2631 IPersistFolder2 * iface,
2632 LPCITEMIDLIST pidl)
2633{
2634 char sTemp[MAX_PATH];
2635 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2636
2637 TRACE("(%p)->(%p)\n", This, pidl);
2638
2639 /* free the old stuff */
2640 if(This->absPidl)
2641 {
2642 SHFree(This->absPidl);
2643 This->absPidl = NULL;
2644 }
2645 if(This->sMyPath)
2646 {
2647 SHFree(This->sMyPath);
2648 This->sMyPath = NULL;
2649 }
2650
2651 /* set my pidl */
2652 This->absPidl = ILClone(pidl);
2653
2654 /* set my path */
2655 if (SHGetPathFromIDListA(pidl, sTemp))
2656 {
2657 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2658 strcpy(This->sMyPath, sTemp);
2659 }
2660
2661 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2662
2663 return S_OK;
2664}
2665
2666/**************************************************************************
2667* IPersistFolder2_fnGetCurFolder
2668*/
2669static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2670 IPersistFolder2 * iface,
2671 LPITEMIDLIST * pidl)
2672{
2673 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2674
2675 TRACE("(%p)->(%p)\n",This, pidl);
2676
2677 if (!pidl) return E_POINTER;
2678
2679 *pidl = ILClone(This->absPidl);
2680
2681 return S_OK;
2682}
2683
2684static ICOM_VTABLE(IPersistFolder2) psfvt =
2685{
2686 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2687 ISFPersistFolder2_QueryInterface,
2688 ISFPersistFolder2_AddRef,
2689 ISFPersistFolder2_Release,
2690 ISFPersistFolder2_GetClassID,
2691 ISFPersistFolder2_Initialize,
2692 ISFPersistFolder2_fnGetCurFolder
2693};
2694
2695/****************************************************************************
2696 * ISFDropTarget implementation
2697 */
2698static BOOL ISFDropTarget_QueryDrop(
2699 IDropTarget *iface,
2700 DWORD dwKeyState,
2701 LPDWORD pdwEffect)
2702{
2703 DWORD dwEffect = *pdwEffect;
2704
2705 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2706
2707 *pdwEffect = DROPEFFECT_NONE;
2708
2709 if (This->fAcceptFmt)
2710 { /* Does our interpretation of the keystate ... */
2711 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2712
2713 /* ... matches the desired effect ? */
2714 if (dwEffect & *pdwEffect)
2715 {
2716 return TRUE;
2717 }
2718 }
2719 return FALSE;
2720}
2721
2722static HRESULT WINAPI ISFDropTarget_QueryInterface(
2723 IDropTarget *iface,
2724 REFIID riid,
2725 LPVOID *ppvObj)
2726{
2727 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2728
2729 TRACE("(%p)\n", This);
2730
2731 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2732}
2733
2734static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2735{
2736 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2737
2738 TRACE("(%p)\n", This);
2739
2740 return IUnknown_AddRef(This->pUnkOuter);
2741}
2742
2743static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2744{
2745 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2746
2747 TRACE("(%p)\n", This);
2748
2749 return IUnknown_Release(This->pUnkOuter);
2750}
2751
2752static HRESULT WINAPI ISFDropTarget_DragEnter(
2753 IDropTarget *iface,
2754 IDataObject *pDataObject,
2755 DWORD dwKeyState,
2756 POINTL pt,
2757 DWORD *pdwEffect)
2758{
2759 FORMATETC fmt;
2760
2761 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2762
2763 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2764
2765 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2766
2767 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2768
2769 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2770
2771 return S_OK;
2772}
2773
2774static HRESULT WINAPI ISFDropTarget_DragOver(
2775 IDropTarget *iface,
2776 DWORD dwKeyState,
2777 POINTL pt,
2778 DWORD *pdwEffect)
2779{
2780 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2781
2782 TRACE("(%p)\n",This);
2783
2784 if(!pdwEffect) return E_INVALIDARG;
2785
2786 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2787
2788 return S_OK;
2789}
2790
2791static HRESULT WINAPI ISFDropTarget_DragLeave(
2792 IDropTarget *iface)
2793{
2794 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2795
2796 TRACE("(%p)\n",This);
2797
2798 This->fAcceptFmt = FALSE;
2799
2800 return S_OK;
2801}
2802
2803static HRESULT WINAPI ISFDropTarget_Drop(
2804 IDropTarget *iface,
2805 IDataObject* pDataObject,
2806 DWORD dwKeyState,
2807 POINTL pt,
2808 DWORD *pdwEffect)
2809{
2810 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2811
2812 FIXME("(%p) object dropped\n",This);
2813
2814 return E_NOTIMPL;
2815}
2816
2817static struct ICOM_VTABLE(IDropTarget) dtvt =
2818{
2819 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2820 ISFDropTarget_QueryInterface,
2821 ISFDropTarget_AddRef,
2822 ISFDropTarget_Release,
2823 ISFDropTarget_DragEnter,
2824 ISFDropTarget_DragOver,
2825 ISFDropTarget_DragLeave,
2826 ISFDropTarget_Drop
2827};
Note: See TracBrowser for help on using the repository browser.