~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/shell32/shfldr_mycomp.c

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  *    Virtual Workplace folder
  3  *
  4  *    Copyright 1997            Marcus Meissner
  5  *    Copyright 1998, 1999, 2002    Juergen Schmied
  6  *
  7  * This library is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU Lesser General Public
  9  * License as published by the Free Software Foundation; either
 10  * version 2.1 of the License, or (at your option) any later version.
 11  *
 12  * This library is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  * Lesser General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU Lesser General Public
 18  * License along with this library; if not, write to the Free Software
 19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 20  */
 21 
 22 #include "config.h"
 23 #include "wine/port.h"
 24 
 25 #include <stdlib.h>
 26 #include <string.h>
 27 #include <stdarg.h>
 28 #include <stdio.h>
 29 
 30 #define COBJMACROS
 31 #define NONAMELESSUNION
 32 #define NONAMELESSSTRUCT
 33 
 34 #include "winerror.h"
 35 #include "windef.h"
 36 #include "winbase.h"
 37 #include "winreg.h"
 38 
 39 #include "wingdi.h"
 40 #include "pidl.h"
 41 #include "shlguid.h"
 42 #include "undocshell.h"
 43 #include "shell32_main.h"
 44 #include "shresdef.h"
 45 #include "shlwapi.h"
 46 #include "wine/debug.h"
 47 #include "debughlp.h"
 48 #include "shfldr.h"
 49 
 50 WINE_DEFAULT_DEBUG_CHANNEL (shell);
 51 
 52 /***********************************************************************
 53 *   IShellFolder implementation
 54 */
 55 
 56 typedef struct {
 57     IShellFolder2   IShellFolder2_iface;
 58     IPersistFolder2 IPersistFolder2_iface;
 59     LONG            ref;
 60 
 61     /* both paths are parsible from the desktop */
 62     LPITEMIDLIST pidlRoot;    /* absolute pidl */
 63 } IMyComputerFolderImpl;
 64 
 65 static const IShellFolder2Vtbl vt_ShellFolder2;
 66 static const IPersistFolder2Vtbl vt_PersistFolder2;
 67 
 68 static inline IMyComputerFolderImpl *impl_from_IShellFolder2(IShellFolder2 *iface)
 69 {
 70     return CONTAINING_RECORD(iface, IMyComputerFolderImpl, IShellFolder2_iface);
 71 }
 72 
 73 static inline IMyComputerFolderImpl *impl_from_IPersistFolder2(IPersistFolder2 *iface)
 74 {
 75     return CONTAINING_RECORD(iface, IMyComputerFolderImpl, IPersistFolder2_iface);
 76 }
 77 
 78 
 79 /***********************************************************************
 80 *   IShellFolder [MyComputer] implementation
 81 */
 82 
 83 static const shvheader mycomputer_header[] = {
 84     {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
 85     {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
 86     {IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
 87     {IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
 88 };
 89 
 90 #define MYCOMPUTERSHELLVIEWCOLUMNS sizeof(mycomputer_header)/sizeof(shvheader)
 91 
 92 /**************************************************************************
 93 *    ISF_MyComputer_Constructor
 94 */
 95 HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
 96 {
 97     IMyComputerFolderImpl *sf;
 98 
 99     TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
100 
101     if (!ppv)
102         return E_POINTER;
103     if (pUnkOuter)
104         return CLASS_E_NOAGGREGATION;
105 
106     sf = LocalAlloc (LMEM_ZEROINIT, sizeof (IMyComputerFolderImpl));
107     if (!sf)
108         return E_OUTOFMEMORY;
109 
110     sf->ref = 0;
111     sf->IShellFolder2_iface.lpVtbl = &vt_ShellFolder2;
112     sf->IPersistFolder2_iface.lpVtbl = &vt_PersistFolder2;
113     sf->pidlRoot = _ILCreateMyComputer ();    /* my qualified pidl */
114 
115     if (FAILED (IUnknown_QueryInterface (&sf->IShellFolder2_iface, riid, ppv)))
116     {
117         IUnknown_Release (&sf->IShellFolder2_iface);
118         return E_NOINTERFACE;
119     }
120 
121     TRACE ("--(%p)\n", sf);
122     return S_OK;
123 }
124 
125 /**************************************************************************
126  *    ISF_MyComputer_fnQueryInterface
127  *
128  * NOTES supports not IPersist/IPersistFolder
129  */
130 static HRESULT WINAPI ISF_MyComputer_fnQueryInterface (IShellFolder2 *iface,
131                REFIID riid, LPVOID *ppvObj)
132 {
133     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
134 
135     TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
136 
137     *ppvObj = NULL;
138 
139     if (IsEqualIID (riid, &IID_IUnknown) ||
140         IsEqualIID (riid, &IID_IShellFolder) ||
141         IsEqualIID (riid, &IID_IShellFolder2))
142     {
143         *ppvObj = This;
144     }
145     else if (IsEqualIID (riid, &IID_IPersist) ||
146              IsEqualIID (riid, &IID_IPersistFolder) ||
147              IsEqualIID (riid, &IID_IPersistFolder2))
148     {
149         *ppvObj = &This->IPersistFolder2_iface;
150     }
151 
152     if (*ppvObj)
153     {
154         IUnknown_AddRef ((IUnknown *) (*ppvObj));
155         TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
156         return S_OK;
157     }
158     TRACE ("-- Interface: E_NOINTERFACE\n");
159     return E_NOINTERFACE;
160 }
161 
162 static ULONG WINAPI ISF_MyComputer_fnAddRef (IShellFolder2 * iface)
163 {
164     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
165     ULONG refCount = InterlockedIncrement(&This->ref);
166 
167     TRACE ("(%p)->(count=%u)\n", This, refCount - 1);
168 
169     return refCount;
170 }
171 
172 static ULONG WINAPI ISF_MyComputer_fnRelease (IShellFolder2 * iface)
173 {
174     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
175     ULONG refCount = InterlockedDecrement(&This->ref);
176 
177     TRACE ("(%p)->(count=%u)\n", This, refCount + 1);
178 
179     if (!refCount)
180     {
181         TRACE ("-- destroying IShellFolder(%p)\n", This);
182         SHFree (This->pidlRoot);
183         LocalFree (This);
184     }
185     return refCount;
186 }
187 
188 /**************************************************************************
189 *    ISF_MyComputer_fnParseDisplayName
190 */
191 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface,
192                HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
193                DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
194 {
195     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
196     HRESULT hr = E_INVALIDARG;
197     LPCWSTR szNext = NULL;
198     WCHAR szElement[MAX_PATH];
199     LPITEMIDLIST pidlTemp = NULL;
200     CLSID clsid;
201 
202     TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", This,
203           hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
204           pchEaten, ppidl, pdwAttributes);
205 
206     *ppidl = 0;
207     if (pchEaten)
208         *pchEaten = 0;        /* strange but like the original */
209 
210     /* handle CLSID paths */
211     if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
212     {
213         szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
214         TRACE ("-- element: %s\n", debugstr_w (szElement));
215         SHCLSIDFromStringW (szElement + 2, &clsid);
216         pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
217     }
218     /* do we have an absolute path name ? */
219     else if (PathGetDriveNumberW (lpszDisplayName) >= 0 &&
220               lpszDisplayName[2] == (WCHAR) '\\')
221     {
222         szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
223         /* make drive letter uppercase to enable PIDL comparison */
224         szElement[0] = toupper(szElement[0]);
225         pidlTemp = _ILCreateDrive (szElement);
226     }
227 
228     if (szNext && *szNext)
229     {
230         hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc, &pidlTemp,
231                               (LPOLESTR) szNext, pchEaten, pdwAttributes);
232     }
233     else
234     {
235         if (pdwAttributes && *pdwAttributes)
236             SHELL32_GetItemAttributes ((IShellFolder*)&This->IShellFolder2_iface, pidlTemp,
237                     pdwAttributes);
238         hr = S_OK;
239     }
240 
241     *ppidl = pidlTemp;
242 
243     TRACE ("(%p)->(-- ret=0x%08x)\n", This, hr);
244 
245     return hr;
246 }
247 
248 /* retrieve a map of drives that should be displayed */
249 static DWORD get_drive_map(void)
250 {
251     static const WCHAR policiesW[] = {'S','o','f','t','w','a','r','e','\\',
252                                       'M','i','c','r','o','s','o','f','t','\\',
253                                       'W','i','n','d','o','w','s','\\',
254                                       'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
255                                       'P','o','l','i','c','i','e','s','\\',
256                                       'E','x','p','l','o','r','e','r',0};
257     static const WCHAR nodrivesW[] = {'N','o','D','r','i','v','e','s',0};
258     static DWORD drive_mask, init_done;
259 
260     if (!init_done)
261     {
262         DWORD type, size, data, mask = 0;
263         HKEY hkey;
264 
265         if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, policiesW, &hkey ))
266         {
267             size = sizeof(data);
268             if (!RegQueryValueExW( hkey, nodrivesW, NULL, &type, (LPBYTE)&data, &size ) && type == REG_DWORD)
269                 mask |= data;
270             RegCloseKey( hkey );
271         }
272         if (!RegOpenKeyW( HKEY_CURRENT_USER, policiesW, &hkey ))
273         {
274             size = sizeof(data);
275             if (!RegQueryValueExW( hkey, nodrivesW, NULL, &type, (LPBYTE)&data, &size ) && type == REG_DWORD)
276                 mask |= data;
277             RegCloseKey( hkey );
278         }
279         drive_mask = mask;
280         init_done = 1;
281     }
282 
283     return GetLogicalDrives() & ~drive_mask;
284 }
285 
286 /**************************************************************************
287  *  CreateMyCompEnumList()
288  */
289 static const WCHAR MyComputer_NameSpaceW[] = { 'S','O','F','T','W','A','R','E',
290  '\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
291  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l',
292  'o','r','e','r','\\','M','y','C','o','m','p','u','t','e','r','\\','N','a','m',
293  'e','s','p','a','c','e','\0' };
294 
295 static BOOL CreateMyCompEnumList(IEnumIDListImpl *list, DWORD dwFlags)
296 {
297     BOOL ret = TRUE;
298 
299     TRACE("(%p)->(flags=0x%08x)\n", list, dwFlags);
300 
301     /* enumerate the folders */
302     if (dwFlags & SHCONTF_FOLDERS)
303     {
304         WCHAR wszDriveName[] = {'A', ':', '\\', '\0'};
305         DWORD dwDrivemap = get_drive_map();
306         HKEY hkey;
307         UINT i;
308 
309         while (ret && wszDriveName[0]<='Z')
310         {
311             if(dwDrivemap & 0x00000001L)
312                 ret = AddToEnumList(list, _ILCreateDrive(wszDriveName));
313             wszDriveName[0]++;
314             dwDrivemap = dwDrivemap >> 1;
315         }
316 
317         TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n",list);
318         for (i=0; i<2; i++) {
319             if (ret && !RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
320                                       MyComputer_NameSpaceW, 0, KEY_READ, &hkey))
321             {
322                 WCHAR iid[50];
323                 int i=0;
324 
325                 while (ret)
326                 {
327                     DWORD size;
328                     LONG r;
329 
330                     size = sizeof(iid) / sizeof(iid[0]);
331                     r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
332                     if (ERROR_SUCCESS == r)
333                     {
334                         /* FIXME: shell extensions, shouldn't the type be
335                          * PT_SHELLEXT? */
336                         ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
337                         i++;
338                     }
339                     else if (ERROR_NO_MORE_ITEMS == r)
340                         break;
341                     else
342                         ret = FALSE;
343                 }
344                 RegCloseKey(hkey);
345             }
346         }
347     }
348     return ret;
349 }
350 
351 /**************************************************************************
352 *        ISF_MyComputer_fnEnumObjects
353 */
354 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects (IShellFolder2 *iface,
355                HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
356 {
357     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
358     IEnumIDListImpl *list;
359 
360     TRACE("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", This,
361           hwndOwner, dwFlags, ppEnumIDList);
362 
363     if (!(list = IEnumIDList_Constructor()))
364         return E_OUTOFMEMORY;
365     CreateMyCompEnumList(list, dwFlags);
366     *ppEnumIDList = &list->IEnumIDList_iface;
367 
368     TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
369 
370     return S_OK;
371 }
372 
373 /**************************************************************************
374 *        ISF_MyComputer_fnBindToObject
375 */
376 static HRESULT WINAPI ISF_MyComputer_fnBindToObject (IShellFolder2 *iface,
377                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
378 {
379     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
380 
381     TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", This,
382           pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
383 
384     return SHELL32_BindToChild (This->pidlRoot, NULL, pidl, riid, ppvOut);
385 }
386 
387 /**************************************************************************
388 *    ISF_MyComputer_fnBindToStorage
389 */
390 static HRESULT WINAPI ISF_MyComputer_fnBindToStorage (IShellFolder2 * iface,
391                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
392 {
393     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
394 
395     FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", This,
396           pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
397 
398     *ppvOut = NULL;
399     return E_NOTIMPL;
400 }
401 
402 /**************************************************************************
403 *     ISF_MyComputer_fnCompareIDs
404 */
405 
406 static HRESULT WINAPI ISF_MyComputer_fnCompareIDs (IShellFolder2 *iface,
407                LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
408 {
409     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
410     HRESULT hr;
411 
412     TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
413     hr = SHELL32_CompareIDs ((IShellFolder*)&This->IShellFolder2_iface, lParam, pidl1, pidl2);
414     TRACE ("-- 0x%08x\n", hr);
415     return hr;
416 }
417 
418 /**************************************************************************
419 *    ISF_MyComputer_fnCreateViewObject
420 */
421 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject (IShellFolder2 *iface,
422                HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
423 {
424     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
425     LPSHELLVIEW pShellView;
426     HRESULT hr = E_INVALIDARG;
427 
428     TRACE("(%p)->(hwnd=%p,%s,%p)\n", This,
429           hwndOwner, shdebugstr_guid (riid), ppvOut);
430 
431     if (!ppvOut)
432         return hr;
433 
434     *ppvOut = NULL;
435 
436     if (IsEqualIID (riid, &IID_IDropTarget))
437     {
438         WARN ("IDropTarget not implemented\n");
439         hr = E_NOTIMPL;
440     }
441     else if (IsEqualIID (riid, &IID_IContextMenu))
442     {
443         WARN ("IContextMenu not implemented\n");
444         hr = E_NOTIMPL;
445     }
446     else if (IsEqualIID (riid, &IID_IShellView))
447     {
448         pShellView = IShellView_Constructor ((IShellFolder *) iface);
449         if (pShellView)
450         {
451             hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
452             IShellView_Release (pShellView);
453         }
454     }
455     TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
456     return hr;
457 }
458 
459 /**************************************************************************
460 *  ISF_MyComputer_fnGetAttributesOf
461 */
462 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface,
463                 UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
464 {
465     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
466     HRESULT hr = S_OK;
467 
468     TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
469            This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
470 
471     if (!rgfInOut)
472         return E_INVALIDARG;
473     if (cidl && !apidl)
474         return E_INVALIDARG;
475 
476     if (*rgfInOut == 0)
477         *rgfInOut = ~0;
478     
479     if(cidl == 0){
480         IShellFolder *psfParent = NULL;
481         LPCITEMIDLIST rpidl = NULL;
482 
483         hr = SHBindToParent(This->pidlRoot, &IID_IShellFolder, (LPVOID*)&psfParent, &rpidl);
484         if(SUCCEEDED(hr)) {
485             SHELL32_GetItemAttributes (psfParent, rpidl, rgfInOut);
486             IShellFolder_Release(psfParent);
487         }
488     } else {
489         while (cidl > 0 && *apidl) {
490             pdump (*apidl);
491             SHELL32_GetItemAttributes ((IShellFolder*)&This->IShellFolder2_iface, *apidl, rgfInOut);
492             apidl++;
493             cidl--;
494         }
495     }
496     /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
497     *rgfInOut &= ~SFGAO_VALIDATE;
498 
499     TRACE ("-- result=0x%08x\n", *rgfInOut);
500     return hr;
501 }
502 
503 /**************************************************************************
504 *    ISF_MyComputer_fnGetUIObjectOf
505 *
506 * PARAMETERS
507 *  hwndOwner [in]  Parent window for any output
508 *  cidl      [in]  array size
509 *  apidl     [in]  simple pidl array
510 *  riid      [in]  Requested Interface
511 *  prgfInOut [   ] reserved
512 *  ppvObject [out] Resulting Interface
513 *
514 */
515 static HRESULT WINAPI ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
516                 HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid,
517                 UINT * prgfInOut, LPVOID * ppvOut)
518 {
519     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
520 
521     LPITEMIDLIST pidl;
522     IUnknown *pObj = NULL;
523     HRESULT hr = E_INVALIDARG;
524 
525     TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", This,
526           hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
527 
528     if (!ppvOut)
529         return hr;
530 
531     *ppvOut = NULL;
532 
533     if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1))
534     {
535         return ItemMenu_Constructor((IShellFolder*) iface, This->pidlRoot, apidl, cidl, riid, ppvOut);
536     }
537     else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1))
538     {
539         pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner,
540                                               This->pidlRoot, apidl, cidl);
541         hr = S_OK;
542     }
543     else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1))
544     {
545         pidl = ILCombine (This->pidlRoot, apidl[0]);
546         pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
547         SHFree (pidl);
548         hr = S_OK;
549     }
550     else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1))
551     {
552         pidl = ILCombine (This->pidlRoot, apidl[0]);
553         pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
554         SHFree (pidl);
555         hr = S_OK;
556     }
557     else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1))
558     {
559         hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget,
560                                           (LPVOID *) &pObj);
561     }
562     else if ((IsEqualIID(riid,&IID_IShellLinkW) ||
563               IsEqualIID(riid,&IID_IShellLinkA)) && (cidl == 1))
564     {
565         pidl = ILCombine (This->pidlRoot, apidl[0]);
566         hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*) &pObj);
567         SHFree (pidl);
568     }
569     else 
570         hr = E_NOINTERFACE;
571 
572     if (SUCCEEDED(hr) && !pObj)
573         hr = E_OUTOFMEMORY;
574 
575     *ppvOut = pObj;
576     TRACE ("(%p)->hr=0x%08x\n", This, hr);
577     return hr;
578 }
579 
580 /**************************************************************************
581 *    ISF_MyComputer_fnGetDisplayNameOf
582 */
583 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 *iface,
584                LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
585 {
586     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
587 
588     LPWSTR pszPath;
589     HRESULT hr = S_OK;
590 
591     TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", This, pidl, dwFlags, strRet);
592     pdump (pidl);
593 
594     if (!strRet)
595         return E_INVALIDARG;
596 
597     pszPath = CoTaskMemAlloc((MAX_PATH +1) * sizeof(WCHAR));
598     if (!pszPath)
599         return E_OUTOFMEMORY;
600 
601     pszPath[0] = 0;
602 
603     if (!pidl->mkid.cb)
604     {
605         /* parsing name like ::{...} */
606         pszPath[0] = ':';
607         pszPath[1] = ':';
608         SHELL32_GUIDToStringW(&CLSID_MyComputer, &pszPath[2]);
609     }
610     else if (_ILIsPidlSimple(pidl))    
611     {
612         /* take names of special folders only if its only this folder */
613         if (_ILIsSpecialFolder(pidl))
614         {
615             GUID const *clsid;
616 
617             clsid = _ILGetGUIDPointer (pidl);
618             if (clsid)
619             {
620                 if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)
621                 {
622                     static const WCHAR clsidW[] =
623                      { 'C','L','S','I','D','\\',0 };
624                     static const WCHAR shellfolderW[] =
625                      { '\\','s','h','e','l','l','f','o','l','d','e','r',0 };
626                     static const WCHAR wantsForParsingW[] =
627                      { 'W','a','n','t','s','F','o','r','P','a','r','s','i','n',
628                      'g',0 };
629                     int bWantsForParsing = FALSE;
630                     WCHAR szRegPath[100];
631                     LONG r;
632 
633                     /*
634                      * We can only get a filesystem path from a shellfolder
635                      * if the value WantsFORPARSING exists in
636                      *      CLSID\\{...}\\shellfolder 
637                      * exception: the MyComputer folder has this keys not
638                      *            but like any filesystem backed
639                      *            folder it needs these behaviour
640                      *
641                      * Get the "WantsFORPARSING" flag from the registry
642                      */
643 
644                     lstrcpyW (szRegPath, clsidW);
645                     SHELL32_GUIDToStringW (clsid, &szRegPath[6]);
646                     lstrcatW (szRegPath, shellfolderW);
647                     r = SHGetValueW (HKEY_CLASSES_ROOT, szRegPath, 
648                                      wantsForParsingW, NULL, NULL, NULL);
649                     if (r == ERROR_SUCCESS)
650                         bWantsForParsing = TRUE;
651 
652                     if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
653                         bWantsForParsing)
654                     {
655                         /*
656                          * We need the filesystem path to the destination folder
657                          * Only the folder itself can know it
658                          */
659                         hr = SHELL32_GetDisplayNameOfChild (iface, pidl,
660                                                 dwFlags, pszPath, MAX_PATH);
661                     }
662                     else
663                     {
664                         LPWSTR p = pszPath;
665 
666                         /* parsing name like ::{...} */
667                         p[0] = ':';
668                         p[1] = ':';
669                         p += 2;
670                         p += SHELL32_GUIDToStringW(&CLSID_MyComputer, p);
671 
672                         /* \:: */
673                         p[0] = '\\';
674                         p[1] = ':';
675                         p[2] = ':';
676                         p += 3;
677                         SHELL32_GUIDToStringW(clsid, p);
678                     }
679                 }
680                 else
681                 {
682                     /* user friendly name */
683                     HCR_GetClassNameW (clsid, pszPath, MAX_PATH);
684                 }
685             }
686             else
687             {
688                 /* append my own path */
689                 _ILSimpleGetTextW (pidl, pszPath, MAX_PATH);
690             }
691         }
692         else if (_ILIsDrive(pidl))
693         {        
694             _ILSimpleGetTextW (pidl, pszPath, MAX_PATH);    /* append my own path */
695 
696             /* long view "lw_name (C:)" */
697             if (!(dwFlags & SHGDN_FORPARSING))
698             {
699                 DWORD dwVolumeSerialNumber, dwMaximumComponetLength, dwFileSystemFlags;
700                 WCHAR wszDrive[18] = {0};
701                 static const WCHAR wszOpenBracket[] = {' ','(',0};
702                 static const WCHAR wszCloseBracket[] = {')',0};
703 
704                 GetVolumeInformationW (pszPath, wszDrive,
705                            sizeof(wszDrive)/sizeof(wszDrive[0]) - 6,
706                            &dwVolumeSerialNumber,
707                            &dwMaximumComponetLength, &dwFileSystemFlags, NULL, 0);
708                 strcatW (wszDrive, wszOpenBracket);
709                 lstrcpynW (wszDrive + strlenW(wszDrive), pszPath, 3);
710                 strcatW (wszDrive, wszCloseBracket);
711                 strcpyW (pszPath, wszDrive);
712             }
713         }
714         else 
715         {
716             /* Neither a shell namespace extension nor a drive letter. */
717             ERR("Wrong pidl type\n");
718             CoTaskMemFree(pszPath);
719             return E_INVALIDARG;
720         }
721     }
722     else
723     {
724         /* Complex pidl. Let the child folder do the work */
725         hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, pszPath, MAX_PATH);
726     }
727 
728     if (SUCCEEDED (hr))
729     {
730         /* Win9x always returns ANSI strings, NT always returns Unicode strings */
731         if (GetVersion() & 0x80000000)
732         {
733             strRet->uType = STRRET_CSTR;
734             if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->u.cStr, MAX_PATH,
735                     NULL, NULL))
736                 strRet->u.cStr[0] = '\0';
737             CoTaskMemFree(pszPath);
738         }
739         else
740         {
741             strRet->uType = STRRET_WSTR;
742             strRet->u.pOleStr = pszPath;
743         }
744     }
745     else
746         CoTaskMemFree(pszPath);
747 
748     TRACE ("-- (%p)->(%s)\n", This, strRet->uType == STRRET_CSTR ? strRet->u.cStr : debugstr_w(strRet->u.pOleStr));
749     return hr;
750 }
751 
752 /**************************************************************************
753 *  ISF_MyComputer_fnSetNameOf
754 *  Changes the name of a file object or subfolder, possibly changing its item
755 *  identifier in the process.
756 *
757 * PARAMETERS
758 *  hwndOwner  [in]   Owner window for output
759 *  pidl       [in]   simple pidl of item to change
760 *  lpszName   [in]   the items new display name
761 *  dwFlags    [in]   SHGNO formatting flags
762 *  ppidlOut   [out]  simple pidl returned
763 */
764 static HRESULT WINAPI ISF_MyComputer_fnSetNameOf (
765                IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,
766                LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
767 {
768     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
769     FIXME ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", This,
770            hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
771     return E_FAIL;
772 }
773 
774 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID (
775                IShellFolder2 * iface, GUID * pguid)
776 {
777     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
778     FIXME ("(%p)\n", This);
779     return E_NOTIMPL;
780 }
781 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches (
782                IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
783 {
784     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
785     FIXME ("(%p)\n", This);
786     return E_NOTIMPL;
787 }
788 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn (
789                IShellFolder2 *iface, DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
790 {
791     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
792 
793     TRACE ("(%p)\n", This);
794 
795     if (pSort)
796          *pSort = 0;
797     if (pDisplay)
798         *pDisplay = 0;
799     return S_OK;
800 }
801 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState (
802                IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
803 {
804     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
805 
806     TRACE ("(%p)->(%d %p)\n", This, iColumn, pcsFlags);
807 
808     if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS)
809         return E_INVALIDARG;
810 
811     *pcsFlags = mycomputer_header[iColumn].pcsFlags;
812 
813     return S_OK;
814 }
815 
816 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx (IShellFolder2 * iface,
817                LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
818 {
819     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
820     FIXME ("(%p)\n", This);
821     return E_NOTIMPL;
822 }
823 
824 /* FIXME: drive size >4GB is rolling over */
825 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 *iface,
826                LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd)
827 {
828     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
829     char szPath[MAX_PATH];
830     ULARGE_INTEGER ulBytes;
831     HRESULT hr = S_OK;
832 
833     TRACE ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);
834 
835     if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS)
836         return E_INVALIDARG;
837 
838     if (!pidl)
839         return SHELL32_GetColumnDetails(mycomputer_header, iColumn, psd);
840 
841     psd->str.u.cStr[0] = 0;
842     psd->str.uType = STRRET_CSTR;
843 
844     switch (iColumn)
845     {
846         case 0:        /* name */
847             hr = IShellFolder_GetDisplayNameOf (iface, pidl,
848                        SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
849             break;
850         case 1:        /* type */
851             _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
852             break;
853         case 2:        /* total size */
854             if (_ILIsDrive (pidl))
855             {
856                 _ILSimpleGetText (pidl, szPath, MAX_PATH);
857                 GetDiskFreeSpaceExA (szPath, NULL, &ulBytes, NULL);
858                 StrFormatByteSizeA (ulBytes.u.LowPart, psd->str.u.cStr, MAX_PATH);
859             }
860             break;
861         case 3:        /* free size */
862             if (_ILIsDrive (pidl))
863             {
864                 _ILSimpleGetText (pidl, szPath, MAX_PATH);
865                 GetDiskFreeSpaceExA (szPath, &ulBytes, NULL, NULL);
866                 StrFormatByteSizeA (ulBytes.u.LowPart, psd->str.u.cStr, MAX_PATH);
867             }
868             break;
869     }
870 
871     return hr;
872 }
873 
874 static HRESULT WINAPI ISF_MyComputer_fnMapColumnToSCID (
875                IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
876 {
877     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
878     FIXME ("(%p)\n", This);
879     return E_NOTIMPL;
880 }
881 
882 static const IShellFolder2Vtbl vt_ShellFolder2 =
883 {
884     ISF_MyComputer_fnQueryInterface,
885     ISF_MyComputer_fnAddRef,
886     ISF_MyComputer_fnRelease,
887     ISF_MyComputer_fnParseDisplayName,
888     ISF_MyComputer_fnEnumObjects,
889     ISF_MyComputer_fnBindToObject,
890     ISF_MyComputer_fnBindToStorage,
891     ISF_MyComputer_fnCompareIDs,
892     ISF_MyComputer_fnCreateViewObject,
893     ISF_MyComputer_fnGetAttributesOf,
894     ISF_MyComputer_fnGetUIObjectOf,
895     ISF_MyComputer_fnGetDisplayNameOf,
896     ISF_MyComputer_fnSetNameOf,
897     /* ShellFolder2 */
898     ISF_MyComputer_fnGetDefaultSearchGUID,
899     ISF_MyComputer_fnEnumSearches,
900     ISF_MyComputer_fnGetDefaultColumn,
901     ISF_MyComputer_fnGetDefaultColumnState,
902     ISF_MyComputer_fnGetDetailsEx,
903     ISF_MyComputer_fnGetDetailsOf,
904     ISF_MyComputer_fnMapColumnToSCID
905 };
906 
907 /************************************************************************
908  *    IMCFldr_PersistFolder2_QueryInterface
909  */
910 static HRESULT WINAPI IMCFldr_PersistFolder2_QueryInterface (
911                IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObj)
912 {
913     IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
914     TRACE ("(%p)\n", This);
915     return IUnknown_QueryInterface (&This->IShellFolder2_iface, iid, ppvObj);
916 }
917 
918 /************************************************************************
919  *    IMCFldr_PersistFolder2_AddRef
920  */
921 static ULONG WINAPI IMCFldr_PersistFolder2_AddRef (IPersistFolder2 * iface)
922 {
923     IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
924     TRACE ("(%p)->(count=%u)\n", This, This->ref);
925     return IUnknown_AddRef (&This->IShellFolder2_iface);
926 }
927 
928 /************************************************************************
929  *    ISFPersistFolder_Release
930  */
931 static ULONG WINAPI IMCFldr_PersistFolder2_Release (IPersistFolder2 * iface)
932 {
933     IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
934     TRACE ("(%p)->(count=%u)\n", This, This->ref);
935     return IUnknown_Release (&This->IShellFolder2_iface);
936 }
937 
938 /************************************************************************
939  *    IMCFldr_PersistFolder2_GetClassID
940  */
941 static HRESULT WINAPI IMCFldr_PersistFolder2_GetClassID (
942                IPersistFolder2 * iface, CLSID * lpClassId)
943 {
944     IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
945 
946     TRACE ("(%p)\n", This);
947 
948     if (!lpClassId)
949     return E_POINTER;
950     *lpClassId = CLSID_MyComputer;
951 
952     return S_OK;
953 }
954 
955 /************************************************************************
956  *    IMCFldr_PersistFolder2_Initialize
957  *
958  * NOTES: it makes no sense to change the pidl
959  */
960 static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize (
961                IPersistFolder2 * iface, LPCITEMIDLIST pidl)
962 {
963     IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
964     TRACE ("(%p)->(%p)\n", This, pidl);
965     return E_NOTIMPL;
966 }
967 
968 /**************************************************************************
969  *    IPersistFolder2_fnGetCurFolder
970  */
971 static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder (
972                IPersistFolder2 * iface, LPITEMIDLIST * pidl)
973 {
974     IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
975 
976     TRACE ("(%p)->(%p)\n", This, pidl);
977 
978     if (!pidl)
979         return E_POINTER;
980     *pidl = ILClone (This->pidlRoot);
981     return S_OK;
982 }
983 
984 static const IPersistFolder2Vtbl vt_PersistFolder2 =
985 {
986     IMCFldr_PersistFolder2_QueryInterface,
987     IMCFldr_PersistFolder2_AddRef,
988     IMCFldr_PersistFolder2_Release,
989     IMCFldr_PersistFolder2_GetClassID,
990     IMCFldr_PersistFolder2_Initialize,
991     IMCFldr_PersistFolder2_GetCurFolder
992 };
993 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.