shellfs.c File Reference

#include "winefile.h"

Include dependency graph for shellfs.c:

Go to the source code of this file.

Defines

#define FETCH_ITEM_COUNT   32

Functions

static void free_strret (STRRET *str)
static LPSTR strcpyn (LPSTR dest, LPCSTR source, size_t count)
static void get_strretA (STRRET *str, const SHITEMID *shiid, LPSTR buffer, int len)
HRESULT path_from_pidlA (IShellFolder *folder, LPITEMIDLIST pidl, LPSTR buffer, int len)
static LPWSTR wcscpyn (LPWSTR dest, LPCWSTR source, size_t count)
static void get_strretW (STRRET *str, const SHITEMID *shiid, LPWSTR buffer, int len)
static HRESULT name_from_pidl (IShellFolder *folder, LPITEMIDLIST pidl, LPTSTR buffer, int len, SHGDNF flags)
HRESULT path_from_pidlW (IShellFolder *folder, LPITEMIDLIST pidl, LPWSTR buffer, int len)
LPITEMIDLIST get_path_pidl (LPCTSTR path, HWND hwnd)
LPITEMIDLIST get_to_absolute_pidl (Entry *entry, HWND hwnd)
static HICON extract_icon (IShellFolder *folder, LPCITEMIDLIST pidl)
static Entryfind_entry_shell (Entry *dir, LPCITEMIDLIST pidl)
Entryread_tree_shell (Root *root, LPITEMIDLIST pidl, enum SORT_ORDER sortOrder, HWND hwnd)
static void fill_w32fdata_shell (IShellFolder *folder, LPCITEMIDLIST pidl, SFGAOF attribs, WIN32_FIND_DATA *w32fdata)
void read_directory_shell (Entry *dir, HWND hwnd)


Define Documentation

#define FETCH_ITEM_COUNT   32

Referenced by read_directory_shell().


Function Documentation

static HICON extract_icon ( IShellFolder *  folder,
LPCITEMIDLIST  pidl 
) [static]

Definition at line 208 of file shellfs.c.

References _MAX_PATH, and PropertiesDialog::path.

Referenced by read_directory_shell().

00209 {
00210     IExtractIcon* pExtract;
00211 
00212     if (SUCCEEDED(IShellFolder_GetUIObjectOf(folder, 0, 1, (LPCITEMIDLIST*)&pidl, &IID_IExtractIcon, 0, (LPVOID*)&pExtract))) {
00213         TCHAR path[_MAX_PATH];
00214         unsigned flags;
00215         HICON hicon;
00216         int idx;
00217 
00218         if (SUCCEEDED((*pExtract->lpVtbl->GetIconLocation)(pExtract, GIL_FORSHELL, path, _MAX_PATH, &idx, &flags))) {
00219             if (!(flags & GIL_NOTFILENAME)) {
00220                 if (idx == -1)
00221                     idx = 0;    /* special case for some control panel applications */
00222 
00223                 if ((int)ExtractIconEx(path, idx, 0, &hicon, 1) > 0)
00224                     flags &= ~GIL_DONTCACHE;
00225             } else {
00226                 HICON hIconLarge = 0;
00227 
00228                 HRESULT hr = (*pExtract->lpVtbl->Extract)(pExtract, path, idx, &hIconLarge, &hicon, MAKELONG(0/*GetSystemMetrics(SM_CXICON)*/,GetSystemMetrics(SM_CXSMICON)));
00229 
00230                 if (SUCCEEDED(hr))
00231                     DestroyIcon(hIconLarge);
00232             }
00233 
00234             return hicon;
00235         }
00236     }
00237 
00238     return 0;
00239 }

Here is the caller graph for this function:

static void fill_w32fdata_shell ( IShellFolder *  folder,
LPCITEMIDLIST  pidl,
SFGAOF  attribs,
WIN32_FIND_DATA *  w32fdata 
) [static]

Definition at line 314 of file shellfs.c.

References WINEFILE_GLOBALS::cfStrFName, Globals, and PropertiesDialog::path.

Referenced by read_directory_shell().

00315 {
00316     if (!(attribs & SFGAO_FILESYSTEM) ||
00317           FAILED(SHGetDataFromIDList(folder, pidl, SHGDFIL_FINDDATA, w32fdata, sizeof(WIN32_FIND_DATA)))) {
00318         WIN32_FILE_ATTRIBUTE_DATA fad;
00319         IDataObject* pDataObj;
00320 
00321         STGMEDIUM medium = {0, {0}, 0};
00322         FORMATETC fmt = {Globals.cfStrFName, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
00323 
00324         HRESULT hr = IShellFolder_GetUIObjectOf(folder, 0, 1, &pidl, &IID_IDataObject, 0, (LPVOID*)&pDataObj);
00325 
00326         if (SUCCEEDED(hr)) {
00327             hr = IDataObject_GetData(pDataObj, &fmt, &medium);
00328 
00329             IDataObject_Release(pDataObj);
00330 
00331             if (SUCCEEDED(hr)) {
00332                 LPCTSTR path = (LPCTSTR)GlobalLock(medium.UNION_MEMBER(hGlobal));
00333                 UINT sem_org = SetErrorMode(SEM_FAILCRITICALERRORS);
00334 
00335                 if (GetFileAttributesEx(path, GetFileExInfoStandard, &fad)) {
00336                     w32fdata->dwFileAttributes = fad.dwFileAttributes;
00337                     w32fdata->ftCreationTime = fad.ftCreationTime;
00338                     w32fdata->ftLastAccessTime = fad.ftLastAccessTime;
00339                     w32fdata->ftLastWriteTime = fad.ftLastWriteTime;
00340 
00341                     if (!(fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
00342                         w32fdata->nFileSizeLow = fad.nFileSizeLow;
00343                         w32fdata->nFileSizeHigh = fad.nFileSizeHigh;
00344                     }
00345                 }
00346 
00347                 SetErrorMode(sem_org);
00348 
00349                 GlobalUnlock(medium.UNION_MEMBER(hGlobal));
00350                 GlobalFree(medium.UNION_MEMBER(hGlobal));
00351             }
00352         }
00353     }
00354 
00355     if (attribs & (SFGAO_FOLDER|SFGAO_HASSUBFOLDER))
00356         w32fdata->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
00357 
00358     if (attribs & SFGAO_READONLY)
00359         w32fdata->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
00360 
00361     if (attribs & SFGAO_COMPRESSED)
00362         w32fdata->dwFileAttributes |= FILE_ATTRIBUTE_COMPRESSED;
00363 }

Here is the caller graph for this function:

static Entry* find_entry_shell ( Entry dir,
LPCITEMIDLIST  pidl 
) [static]

Definition at line 243 of file shellfs.c.

References _Entry::down, PropertiesDialog::entry, _Entry::next, and _Entry::pidl.

Referenced by read_tree_shell().

00244 {
00245     Entry* entry;
00246 
00247     for(entry=dir->down; entry; entry=entry->next) {
00248         if (entry->pidl->mkid.cb == pidl->mkid.cb &&
00249             !memcmp(entry->pidl, pidl, entry->pidl->mkid.cb))
00250             return entry;
00251     }
00252 
00253     return 0;
00254 }

Here is the caller graph for this function:

static void free_strret ( STRRET *  str  )  [static]

Definition at line 27 of file shellfs.c.

References Globals, and WINEFILE_GLOBALS::iMalloc.

Referenced by name_from_pidl(), path_from_pidlA(), and path_from_pidlW().

00028 {
00029     if (str->uType == STRRET_WSTR)
00030         IMalloc_Free(Globals.iMalloc, str->UNION_MEMBER(pOleStr));
00031 }

Here is the caller graph for this function:

LPITEMIDLIST get_path_pidl ( LPCTSTR  path,
HWND  hwnd 
)

Definition at line 153 of file shellfs.c.

References Globals, and WINEFILE_GLOBALS::iDesktop.

Referenced by FrameWndProc(), and get_to_absolute_pidl().

00154 {
00155     LPITEMIDLIST pidl;
00156     HRESULT hr;
00157     ULONG len;
00158 
00159 #ifdef UNICODE
00160     LPCWSTR buffer = path;
00161 #else
00162     WCHAR buffer[MAX_PATH];
00163     MultiByteToWideChar(CP_ACP, 0, path, -1, buffer, MAX_PATH);
00164 #endif
00165 
00166     hr = IShellFolder_ParseDisplayName(Globals.iDesktop, hwnd, NULL, (LPOLESTR)buffer, &len, &pidl, NULL);
00167     if (FAILED(hr))
00168         return NULL;
00169 
00170     return pidl;
00171 }

Here is the caller graph for this function:

static void get_strretA ( STRRET *  str,
const SHITEMID *  shiid,
LPSTR  buffer,
int  len 
) [static]

Definition at line 49 of file shellfs.c.

References strcpyn().

Referenced by path_from_pidlA().

00050 {
00051  switch(str->uType) {
00052   case STRRET_WSTR:
00053     WideCharToMultiByte(CP_ACP, 0, str->UNION_MEMBER(pOleStr), -1, buffer, len, NULL, NULL);
00054     break;
00055 
00056   case STRRET_OFFSET:
00057     strcpyn(buffer, (LPCSTR)shiid+str->UNION_MEMBER(uOffset), len);
00058     break;
00059 
00060   case STRRET_CSTR:
00061     strcpyn(buffer, str->UNION_MEMBER(cStr), len);
00062  }
00063 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_strretW ( STRRET *  str,
const SHITEMID *  shiid,
LPWSTR  buffer,
int  len 
) [static]

Definition at line 97 of file shellfs.c.

References wcscpyn().

Referenced by path_from_pidlW().

00098 {
00099  switch(str->uType) {
00100   case STRRET_WSTR:
00101     wcscpyn(buffer, str->UNION_MEMBER(pOleStr), len);
00102     break;
00103 
00104   case STRRET_OFFSET:
00105     MultiByteToWideChar(CP_ACP, 0, (LPCSTR)shiid+str->UNION_MEMBER(uOffset), -1, buffer, len);
00106     break;
00107 
00108   case STRRET_CSTR:
00109     MultiByteToWideChar(CP_ACP, 0, str->UNION_MEMBER(cStr), -1, buffer, len);
00110  }
00111 }

Here is the call graph for this function:

Here is the caller graph for this function:

LPITEMIDLIST get_to_absolute_pidl ( Entry entry,
HWND  hwnd 
)

Definition at line 176 of file shellfs.c.

References ET_SHELL, ET_WINDOWS, _Entry::etype, _Entry::folder, get_path(), get_path_pidl(), Globals, WINEFILE_GLOBALS::iDesktop, PropertiesDialog::path, path_from_pidlW(), _Entry::pidl, and _Entry::up.

00177 {
00178     if (entry->up && entry->up->etype==ET_SHELL) {
00179         IShellFolder* folder = entry->up->folder;
00180         WCHAR buffer[MAX_PATH];
00181 
00182         HRESULT hr = path_from_pidlW(folder, entry->pidl, buffer, MAX_PATH);
00183 
00184         if (SUCCEEDED(hr)) {
00185             LPITEMIDLIST pidl;
00186             ULONG len;
00187 
00188             hr = IShellFolder_ParseDisplayName(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL);
00189 
00190             if (SUCCEEDED(hr))
00191                 return pidl;
00192         }
00193     } else if (entry->etype == ET_WINDOWS) {
00194         TCHAR path[MAX_PATH];
00195 
00196         get_path(entry, path);
00197 
00198         return get_path_pidl(path, hwnd);
00199     } else if (entry->pidl)
00200         return ILClone(entry->pidl);
00201 
00202     return NULL;
00203 }

Here is the call graph for this function:

static HRESULT name_from_pidl ( IShellFolder *  folder,
LPITEMIDLIST  pidl,
LPTSTR  buffer,
int  len,
SHGDNF  flags 
) [static]

Definition at line 116 of file shellfs.c.

References free_strret(), and get_strret.

Referenced by read_directory_shell().

00117 {
00118     STRRET str;
00119 
00120     HRESULT hr = IShellFolder_GetDisplayNameOf(folder, pidl, flags, &str);
00121 
00122     if (SUCCEEDED(hr)) {
00123         get_strret(&str, &pidl->mkid, buffer, len);
00124         free_strret(&str);
00125     } else
00126         buffer[0] = '\0';
00127 
00128     return hr;
00129 }

Here is the call graph for this function:

Here is the caller graph for this function:

HRESULT path_from_pidlA ( IShellFolder *  folder,
LPITEMIDLIST  pidl,
LPSTR  buffer,
int  len 
)

Definition at line 66 of file shellfs.c.

References free_strret(), and get_strretA().

00067 {
00068     STRRET str;
00069 
00070     /* SHGDN_FORPARSING: get full path of id list */
00071     HRESULT hr = IShellFolder_GetDisplayNameOf(folder, pidl, SHGDN_FORPARSING, &str);
00072 
00073     if (SUCCEEDED(hr)) {
00074         get_strretA(&str, &pidl->mkid, buffer, len);
00075         free_strret(&str);
00076     } else
00077         buffer[0] = '\0';
00078 
00079     return hr;
00080 }

Here is the call graph for this function:

HRESULT path_from_pidlW ( IShellFolder *  folder,
LPITEMIDLIST  pidl,
LPWSTR  buffer,
int  len 
)

Definition at line 134 of file shellfs.c.

References free_strret(), and get_strretW().

Referenced by get_to_absolute_pidl().

00135 {
00136     STRRET str;
00137 
00138     /* SHGDN_FORPARSING: get full path of id list */
00139     HRESULT hr = IShellFolder_GetDisplayNameOf(folder, pidl, SHGDN_FORPARSING, &str);
00140 
00141     if (SUCCEEDED(hr)) {
00142         get_strretW(&str, &pidl->mkid, buffer, len);
00143         free_strret(&str);
00144     } else
00145         buffer[0] = '\0';
00146 
00147     return hr;
00148 }

Here is the call graph for this function:

Here is the caller graph for this function:

void read_directory_shell ( Entry dir,
HWND  hwnd 
)

Definition at line 368 of file shellfs.c.

References alloc_entry(), _Entry::bhfi_valid, _Entry::data, _Entry::down, PropertiesDialog::entry, ET_SHELL, _Entry::etype, _Entry::expanded, extract_icon(), FETCH_ITEM_COUNT, fill_w32fdata_shell(), _Entry::folder, _Entry::hicon, _Entry::level, name_from_pidl(), _Entry::next, _Entry::pidl, _Entry::scanned, and _Entry::up.

Referenced by read_directory().

00369 {
00370     IShellFolder* folder = dir->folder;
00371     int level = dir->level + 1;
00372     HRESULT hr;
00373 
00374     IShellFolder* child;
00375     IEnumIDList* idlist;
00376 
00377     Entry* first_entry = NULL;
00378     Entry* last = NULL;
00379     Entry* entry;
00380 
00381     if (!folder)
00382         return;
00383 
00384     hr = IShellFolder_EnumObjects(folder, hwnd, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE, &idlist);
00385 
00386     if (SUCCEEDED(hr)) {
00387         for(;;) {
00388 #define FETCH_ITEM_COUNT    32
00389             LPITEMIDLIST pidls[FETCH_ITEM_COUNT];
00390             SFGAOF attribs;
00391             ULONG cnt = 0;
00392             ULONG n;
00393 
00394             memset(pidls, 0, sizeof(pidls));
00395 
00396             hr = IEnumIDList_Next(idlist, FETCH_ITEM_COUNT, pidls, &cnt);
00397             if (!SUCCEEDED(hr))
00398                 break;
00399 
00400             if (hr == S_FALSE)
00401                 break;
00402 
00403             for(n=0; n<cnt; ++n) {
00404                 entry = alloc_entry();
00405 
00406                 if (!first_entry)
00407                     first_entry = entry;
00408 
00409                 if (last)
00410                     last->next = entry;
00411 
00412                 memset(&entry->data, 0, sizeof(WIN32_FIND_DATA));
00413                 entry->bhfi_valid = FALSE;
00414 
00415                 attribs = ~SFGAO_FILESYSTEM;    /*SFGAO_HASSUBFOLDER|SFGAO_FOLDER; SFGAO_FILESYSTEM sorgt dafür, daß "My Documents" anstatt von "Martin's Documents" angezeigt wird */
00416 
00417                 hr = IShellFolder_GetAttributesOf(folder, 1, (LPCITEMIDLIST*)&pidls[n], &attribs);
00418 
00419                 if (SUCCEEDED(hr)) {
00420                     if (attribs != (SFGAOF)~SFGAO_FILESYSTEM) {
00421                         fill_w32fdata_shell(folder, pidls[n], attribs, &entry->data);
00422 
00423                         entry->bhfi_valid = TRUE;
00424                     } else
00425                         attribs = 0;
00426                 } else
00427                     attribs = 0;
00428 
00429                 entry->pidl = pidls[n];
00430 
00431                 if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
00432                     hr = IShellFolder_BindToObject(folder, pidls[n], 0, &IID_IShellFolder, (void**)&child);
00433 
00434                     if (SUCCEEDED(hr))
00435                         entry->folder = child;
00436                     else
00437                         entry->folder = NULL;
00438                 }
00439                 else
00440                     entry->folder = NULL;
00441 
00442                 if (!entry->data.cFileName[0])
00443                     /*hr = */name_from_pidl(folder, pidls[n], entry->data.cFileName, MAX_PATH, /*SHGDN_INFOLDER*/0x2000/*0x2000=SHGDN_INCLUDE_NONFILESYS*/);
00444 
00445                 /* get display icons for files and virtual objects */
00446                 if (!(entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
00447                     !(attribs & SFGAO_FILESYSTEM)) {
00448                     entry->hicon = extract_icon(folder, pidls[n]);
00449 
00450                     if (!entry->hicon)
00451                         entry->hicon = (HICON)-1;   /* don't try again later */
00452                 }
00453 
00454                 entry->down = NULL;
00455                 entry->up = dir;
00456                 entry->expanded = FALSE;
00457                 entry->scanned = FALSE;
00458                 entry->level = level;
00459 
00460 #ifndef _NO_EXTENSIONS
00461                 entry->etype = ET_SHELL;
00462                 entry->bhfi_valid = FALSE;
00463 #endif
00464 
00465                 last = entry;
00466             }
00467         }
00468 
00469         IEnumIDList_Release(idlist);
00470     }
00471 
00472     if (last)
00473         last->next = NULL;
00474 
00475     dir->down = first_entry;
00476     dir->scanned = TRUE;
00477 }

Here is the call graph for this function:

Here is the caller graph for this function:

Entry* read_tree_shell ( Root root,
LPITEMIDLIST  pidl,
enum SORT_ORDER  sortOrder,
HWND  hwnd 
)

Definition at line 257 of file shellfs.c.

References _Entry::down, _Root::entry, PropertiesDialog::entry, ET_SHELL, _Entry::etype, _Entry::expanded, find_entry_shell(), _Entry::folder, Globals, WINEFILE_GLOBALS::iDesktop, WINEFILE_GLOBALS::iMalloc, _Entry::pidl, and read_directory().

Referenced by read_tree().

00258 {
00259     Entry* entry = &root->entry;
00260     Entry* next;
00261     LPITEMIDLIST next_pidl = pidl;
00262     IShellFolder* folder;
00263     IShellFolder* child = NULL;
00264     HRESULT hr;
00265 
00266     HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT));
00267 
00268 #ifndef _NO_EXTENSIONS
00269     entry->etype = ET_SHELL;
00270 #endif
00271 
00272     folder = Globals.iDesktop;
00273 
00274     while(entry) {
00275         entry->pidl = next_pidl;
00276         entry->folder = folder;
00277 
00278         if (!pidl->mkid.cb)
00279             break;
00280 
00281         /* copy first element of item id list */
00282         next_pidl = IMalloc_Alloc(Globals.iMalloc, pidl->mkid.cb+sizeof(USHORT));
00283         memcpy(next_pidl, pidl, pidl->mkid.cb);
00284         ((LPITEMIDLIST)((LPBYTE)next_pidl+pidl->mkid.cb))->mkid.cb = 0;
00285 
00286         hr = IShellFolder_BindToObject(folder, next_pidl, 0, &IID_IShellFolder, (void**)&child);
00287         if (!SUCCEEDED(hr))
00288             break;
00289 
00290         read_directory(entry, NULL, sortOrder, hwnd);
00291 
00292         if (entry->down)
00293             entry->expanded = TRUE;
00294 
00295         next = find_entry_shell(entry, next_pidl);
00296         if (!next)
00297             break;
00298 
00299         folder = child;
00300         entry = next;
00301 
00302         /* go to next element */
00303         pidl = (LPITEMIDLIST) ((LPBYTE)pidl+pidl->mkid.cb);
00304     }
00305 
00306     SetCursor(old_cursor);
00307 
00308     return entry;
00309 }

Here is the call graph for this function:

Here is the caller graph for this function:

static LPSTR strcpyn ( LPSTR  dest,
LPCSTR  source,
size_t  count 
) [static]

Definition at line 37 of file shellfs.c.

Referenced by get_strretA().

00038 {
00039  LPCSTR s;
00040  LPSTR d = dest;
00041 
00042  for(s=source; count&&(*d++=*s++); )
00043   count--;
00044 
00045  return dest;
00046 }

Here is the caller graph for this function:

static LPWSTR wcscpyn ( LPWSTR  dest,
LPCWSTR  source,
size_t  count 
) [static]

Definition at line 85 of file shellfs.c.

Referenced by get_strretW().

00086 {
00087  LPCWSTR s;
00088  LPWSTR d = dest;
00089 
00090  for(s=source; count&&(*d++=*s++); )
00091   count--;
00092 
00093  return dest;
00094 }

Here is the caller graph for this function:


Winefile Source Code Documentation
generated on 15.09.2008 by doxygen

Winefile Homepage