From b165b56577bbb3d9aae42172c50840457eeb63ec Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Fri, 9 Apr 2004 20:24:24 +0000 Subject: [PATCH] Merge Wine shell32 commits: Juan Lang - comment fixes - improved error checking and conformance with Windows - remove some spurious error messages - Move control panel applet enumeration to cpanelfolder.c. - move CreateMyCompEnumList and CreateDesktopEnumList to their respective files - rewrite CreateFolderEnumList to only FindFirstFile/FindNextFile once svn path=/trunk/; revision=9056 --- reactos/lib/shell32/cpanel.h | 2 + reactos/lib/shell32/cpanelfolder.c | 219 ++++++++++++- reactos/lib/shell32/enumidlist.c | 446 ++++----------------------- reactos/lib/shell32/enumidlist.h | 30 ++ reactos/lib/shell32/pidl.c | 57 ---- reactos/lib/shell32/pidl.h | 2 - reactos/lib/shell32/shell32_main.h | 8 - reactos/lib/shell32/shfldr_desktop.c | 64 +++- reactos/lib/shell32/shfldr_fs.c | 7 +- reactos/lib/shell32/shfldr_mycomp.c | 62 +++- reactos/lib/shell32/shlexec.c | 3 +- 11 files changed, 438 insertions(+), 462 deletions(-) create mode 100644 reactos/lib/shell32/enumidlist.h diff --git a/reactos/lib/shell32/cpanel.h b/reactos/lib/shell32/cpanel.h index 1d37d985191..aa6b49962b8 100644 --- a/reactos/lib/shell32/cpanel.h +++ b/reactos/lib/shell32/cpanel.h @@ -20,6 +20,8 @@ #ifndef __WINE_SHELL_CPANEL_H #define __WINE_SHELL_CPANEL_H +#include "cpl.h" + typedef struct CPlApplet { struct CPlApplet* next; /* linked list */ HWND hWnd; diff --git a/reactos/lib/shell32/cpanelfolder.c b/reactos/lib/shell32/cpanelfolder.c index e4531b5c9cb..99a3674700d 100644 --- a/reactos/lib/shell32/cpanelfolder.c +++ b/reactos/lib/shell32/cpanelfolder.c @@ -38,6 +38,8 @@ #include "ole2.h" #include "shlguid.h" +#include "cpanel.h" +#include "enumidlist.h" #include "pidl.h" #include "undocshell.h" #include "shell32_main.h" @@ -227,6 +229,219 @@ ISF_ControlPanel_fnParseDisplayName(IShellFolder2 * iface, return hr; } +static LPITEMIDLIST _ILCreateCPanelApplet(LPCSTR name, LPCSTR displayName, + LPCSTR comment, int iconIdx) +{ + PIDLCPanelStruct *p; + LPITEMIDLIST pidl; + PIDLDATA tmp; + int size0 = (char*)&tmp.u.cpanel.szName-(char*)&tmp.u.cpanel; + int size = size0; + int l; + + tmp.type = 0; + tmp.u.cpanel.dummy = 0; + tmp.u.cpanel.iconIdx = iconIdx; + + l = strlen(name); + size += l+1; + + tmp.u.cpanel.offsDispName = l+1; + l = strlen(displayName); + size += l+1; + + tmp.u.cpanel.offsComment = tmp.u.cpanel.offsDispName+1+l; + l = strlen(comment); + size += l+1; + + pidl = SHAlloc(size+4); + if (!pidl) + return NULL; + + pidl->mkid.cb = size+2; + memcpy(pidl->mkid.abID, &tmp, 2+size0); + + p = &((PIDLDATA*)pidl->mkid.abID)->u.cpanel; + strcpy(p->szName, name); + strcpy(p->szName+tmp.u.cpanel.offsDispName, displayName); + strcpy(p->szName+tmp.u.cpanel.offsComment, comment); + + *(WORD*)((char*)pidl+(size+2)) = 0; + + pcheck(pidl); + + return pidl; +} + +/************************************************************************** + * _ILGetCPanelPointer() + * gets a pointer to the control panel struct stored in the pidl + */ +static PIDLCPanelStruct* _ILGetCPanelPointer(LPCITEMIDLIST pidl) +{ + LPPIDLDATA pdata = _ILGetDataPointer(pidl); + + if (pdata && pdata->type==0) + return (PIDLCPanelStruct*)&(pdata->u.cpanel); + + return NULL; +} + + /************************************************************************** + * ISF_ControlPanel_fnEnumObjects + */ +static BOOL SHELL_RegisterCPanelApp(IEnumIDList* list, LPCSTR path) +{ + LPITEMIDLIST pidl; + CPlApplet* applet; + CPanel panel; + CPLINFO info; + unsigned i; + int iconIdx; + + char displayName[MAX_PATH]; + char comment[MAX_PATH]; + + WCHAR wpath[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); + + panel.first = NULL; + applet = Control_LoadApplet(0, wpath, &panel); + + if (applet) + { + for(i=0; icount; ++i) + { + WideCharToMultiByte(CP_ACP, 0, applet->info[i].szName, -1, displayName, MAX_PATH, 0, 0); + WideCharToMultiByte(CP_ACP, 0, applet->info[i].szInfo, -1, comment, MAX_PATH, 0, 0); + + applet->proc(0, CPL_INQUIRE, i, (LPARAM)&info); + + if (info.idIcon > 0) + iconIdx = -info.idIcon; /* negative icon index instead of icon number */ + else + iconIdx = 0; + + pidl = _ILCreateCPanelApplet(path, displayName, comment, iconIdx); + + if (pidl) + AddToEnumList(list, pidl); + } + Control_UnloadApplet(applet); + } + return TRUE; +} + +static int SHELL_RegisterRegistryCPanelApps(IEnumIDList* list, HKEY hkey_root, LPCSTR szRepPath) +{ + char name[MAX_PATH]; + char value[MAX_PATH]; + HKEY hkey; + + int cnt = 0; + + if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS) + { + int idx = 0; + + for(;; ++idx) + { + DWORD nameLen = MAX_PATH; + DWORD valueLen = MAX_PATH; + + if (RegEnumValueA(hkey, idx, name, &nameLen, NULL, NULL, (LPBYTE)&value, &valueLen) != ERROR_SUCCESS) + break; + + if (SHELL_RegisterCPanelApp(list, value)) + ++cnt; + } + RegCloseKey(hkey); + } + + return cnt; +} + +static int SHELL_RegisterCPanelFolders(IEnumIDList* list, HKEY hkey_root, LPCSTR szRepPath) +{ + char name[MAX_PATH]; + HKEY hkey; + + int cnt = 0; + + if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS) + { + int idx = 0; + for(;; ++idx) + { + if (RegEnumKeyA(hkey, idx, name, MAX_PATH) != ERROR_SUCCESS) + break; + + if (*name == '{') + { + LPITEMIDLIST pidl = _ILCreateGuidFromStrA(name); + + if (pidl && AddToEnumList(list, pidl)) + ++cnt; + } + } + + RegCloseKey(hkey); + } + + return cnt; +} + +/************************************************************************** + * CreateCPanelEnumList() + */ +static BOOL CreateCPanelEnumList( + IEnumIDList * iface, + DWORD dwFlags) +{ + CHAR szPath[MAX_PATH]; + WIN32_FIND_DATAA wfd; + HANDLE hFile; + + TRACE("(%p)->(flags=0x%08lx) \n",iface,dwFlags); + + /* enumerate control panel folders folders */ + if (dwFlags & SHCONTF_FOLDERS) + SHELL_RegisterCPanelFolders(iface, HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace"); + + /* enumerate the control panel applets */ + if (dwFlags & SHCONTF_NONFOLDERS) + { + LPSTR p; + + GetSystemDirectoryA(szPath, MAX_PATH); + p = PathAddBackslashA(szPath); + strcpy(p, "*.cpl"); + + TRACE("-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",iface,debugstr_a(szPath)); + hFile = FindFirstFileA(szPath, &wfd); + + if (hFile != INVALID_HANDLE_VALUE) + { + do + { + if (!(dwFlags & SHCONTF_INCLUDEHIDDEN) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + continue; + + if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + strcpy(p, wfd.cFileName); + SHELL_RegisterCPanelApp((IEnumIDList*)iface, szPath); + } + } while(FindNextFileA(hFile, &wfd)); + FindClose(hFile); + } + + SHELL_RegisterRegistryCPanelApps((IEnumIDList*)iface, HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls"); + SHELL_RegisterRegistryCPanelApps((IEnumIDList*)iface, HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls"); + } + return TRUE; +} + /************************************************************************** * ISF_ControlPanel_fnEnumObjects */ @@ -237,7 +452,9 @@ ISF_ControlPanel_fnEnumObjects(IShellFolder2 * iface, HWND hwndOwner, DWORD dwFl TRACE("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList); - *ppEnumIDList = IEnumIDList_Constructor(NULL, dwFlags, EIDL_CPANEL); + *ppEnumIDList = IEnumIDList_Constructor(); + if (*ppEnumIDList) + CreateCPanelEnumList(*ppEnumIDList, dwFlags); TRACE("--(%p)->(new ID List: %p)\n", This, *ppEnumIDList); diff --git a/reactos/lib/shell32/enumidlist.c b/reactos/lib/shell32/enumidlist.c index bb3b0529cd2..4ce2e7257c2 100644 --- a/reactos/lib/shell32/enumidlist.c +++ b/reactos/lib/shell32/enumidlist.c @@ -30,12 +30,10 @@ #include "shlwapi.h" #include "winerror.h" #include "objbase.h" -#include #include "pidl.h" #include "shlguid.h" -#include "shell32_main.h" -#include "cpanel.h" +#include "enumidlist.h" WINE_DEFAULT_DEBUG_CHANNEL(shell); @@ -61,7 +59,7 @@ static struct ICOM_VTABLE(IEnumIDList) eidlvt; /************************************************************************** * AddToEnumList() */ -static BOOL AddToEnumList( +BOOL AddToEnumList( IEnumIDList * iface, LPITEMIDLIST pidl) { @@ -70,6 +68,10 @@ static BOOL AddToEnumList( LPENUMLIST pNew; TRACE("(%p)->(pidl=%p)\n",This,pidl); + + if (!iface || !pidl) + return FALSE; + pNew = (LPENUMLIST)SHAlloc(sizeof(ENUMLIST)); if(pNew) { @@ -101,351 +103,63 @@ static BOOL AddToEnumList( /************************************************************************** * CreateFolderEnumList() */ -static BOOL CreateFolderEnumList( - IEnumIDList * iface, +BOOL CreateFolderEnumList( + IEnumIDList *list, LPCSTR lpszPath, DWORD dwFlags) { - ICOM_THIS(IEnumIDListImpl,iface); + LPITEMIDLIST pidl=NULL; + WIN32_FIND_DATAA stffile; + HANDLE hFile; + CHAR szPath[MAX_PATH]; + BOOL succeeded = TRUE; - LPITEMIDLIST pidl=NULL; - WIN32_FIND_DATAA stffile; - HANDLE hFile; - CHAR szPath[MAX_PATH]; + TRACE("(%p)->(path=%s flags=0x%08lx) \n",list,debugstr_a(lpszPath),dwFlags); - TRACE("(%p)->(path=%s flags=0x%08lx) \n",This,debugstr_a(lpszPath),dwFlags); + if(!lpszPath || !lpszPath[0]) return FALSE; - if(!lpszPath || !lpszPath[0]) return FALSE; + strcpy(szPath, lpszPath); + PathAddBackslashA(szPath); + strcat(szPath,"*.*"); - strcpy(szPath, lpszPath); - PathAddBackslashA(szPath); - strcat(szPath,"*.*"); - - /*enumerate the folders*/ - if(dwFlags & SHCONTF_FOLDERS) - { - TRACE("-- (%p)-> enumerate SHCONTF_FOLDERS of %s\n",This,debugstr_a(szPath)); - hFile = FindFirstFileA(szPath,&stffile); - if( hFile != INVALID_HANDLE_VALUE ) - { - do - { - if( !(dwFlags & SHCONTF_INCLUDEHIDDEN) && (stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ) continue; - if( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, "..")) - { - pidl = _ILCreateFromFindDataA (&stffile); - if(pidl && AddToEnumList((IEnumIDList*)This, pidl)) - { - continue; - } - return FALSE; - } - } while( FindNextFileA(hFile,&stffile)); - FindClose (hFile); - } - } - - /*enumerate the non-folder items (values) */ - if(dwFlags & SHCONTF_NONFOLDERS) - { - TRACE("-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",This,debugstr_a(szPath)); - hFile = FindFirstFileA(szPath,&stffile); - if( hFile != INVALID_HANDLE_VALUE ) - { - do - { - if( !(dwFlags & SHCONTF_INCLUDEHIDDEN) && (stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ) continue; - if(! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) - { - pidl = _ILCreateFromFindDataA(&stffile); - if(pidl && AddToEnumList((IEnumIDList*)This, pidl)) - { - continue; - } - return FALSE; - } - } while( FindNextFileA(hFile,&stffile)); - FindClose (hFile); - } - } - return TRUE; -} - -BOOL SHELL_RegisterCPanelApp(IEnumIDList* list, LPCSTR path) -{ - LPITEMIDLIST pidl; - CPlApplet* applet; - CPanel panel; - CPLINFO info; - unsigned i; - int iconIdx; - - char displayName[MAX_PATH]; - char comment[MAX_PATH]; - - WCHAR wpath[MAX_PATH]; - - MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); - - panel.first = NULL; - applet = Control_LoadApplet(0, wpath, &panel); - - if (applet) { - for(i=0; icount; ++i) { - WideCharToMultiByte(CP_ACP, 0, applet->info[i].szName, -1, displayName, MAX_PATH, 0, 0); - WideCharToMultiByte(CP_ACP, 0, applet->info[i].szInfo, -1, comment, MAX_PATH, 0, 0); - - applet->proc(0, CPL_INQUIRE, i, (LPARAM)&info); - - if (info.idIcon > 0) - iconIdx = -info.idIcon; /* negative icon index instead of icon number */ - else - iconIdx = 0; - - pidl = _ILCreateCPanel(path, displayName, comment, iconIdx); - - if (pidl) - AddToEnumList(list, pidl); - } - - Control_UnloadApplet(applet); - } - - return TRUE; -} - -int SHELL_RegisterRegistryCPanelApps(IEnumIDList* list, HKEY hkey_root, LPCSTR szRepPath) -{ - char name[MAX_PATH]; - char value[MAX_PATH]; - HKEY hkey; - - int cnt = 0; - - if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS) - { - int idx = 0; - for(;; ++idx) + hFile = FindFirstFileA(szPath,&stffile); + if ( hFile != INVALID_HANDLE_VALUE ) { - DWORD nameLen = MAX_PATH; - DWORD valueLen = MAX_PATH; + BOOL findFinished = FALSE; - if (RegEnumValueA(hkey, idx, name, &nameLen, NULL, NULL, (LPBYTE)&value, &valueLen) != ERROR_SUCCESS) - break; - - if (SHELL_RegisterCPanelApp(list, value)) - ++cnt; + do + { + if ( !(stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) + || (dwFlags & SHCONTF_INCLUDEHIDDEN) ) + { + if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + dwFlags & SHCONTF_FOLDERS && + strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, "..")) + { + pidl = _ILCreateFromFindDataA(&stffile); + succeeded = succeeded && AddToEnumList(list, pidl); + } + else if (!(stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + && dwFlags & SHCONTF_NONFOLDERS) + { + pidl = _ILCreateFromFindDataA(&stffile); + succeeded = succeeded && AddToEnumList(list, pidl); + } + } + if (succeeded) + { + if (!FindNextFileA(hFile, &stffile)) + { + if (GetLastError() == ERROR_NO_MORE_FILES) + findFinished = TRUE; + else + succeeded = FALSE; + } + } + } while (succeeded && !findFinished); + FindClose(hFile); } - - RegCloseKey(hkey); - } - - return cnt; -} - -int SHELL_RegisterCPanelFolders(IEnumIDList* list, HKEY hkey_root, LPCSTR szRepPath) -{ - char name[MAX_PATH]; - HKEY hkey; - - int cnt = 0; - - if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS) - { - int idx = 0; - for(;; ++idx) - { - if (RegEnumKeyA(hkey, idx, name, MAX_PATH) != ERROR_SUCCESS) - break; - - if (*name == '{') { - LPITEMIDLIST pidl = _ILCreateGuidFromStrA(name); - - if (pidl && AddToEnumList(list, pidl)) - ++cnt; - } - } - - RegCloseKey(hkey); - } - - return cnt; -} - -/************************************************************************** - * CreateCPanelEnumList() - */ -static BOOL CreateCPanelEnumList( - IEnumIDList * iface, - DWORD dwFlags) -{ - ICOM_THIS(IEnumIDListImpl,iface); - - CHAR szPath[MAX_PATH]; - WIN32_FIND_DATAA wfd; - HANDLE hFile; - - TRACE("(%p)->(flags=0x%08lx) \n",This,dwFlags); - - /* enumerate control panel folders folders */ - if (dwFlags & SHCONTF_FOLDERS) - SHELL_RegisterCPanelFolders((IEnumIDList*)This, HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace"); - - /* enumerate the control panel applets */ - if (dwFlags & SHCONTF_NONFOLDERS) - { - LPSTR p; - - GetSystemDirectoryA(szPath, MAX_PATH); - p = PathAddBackslashA(szPath); - strcpy(p, "*.cpl"); - - TRACE("-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",This,debugstr_a(szPath)); - hFile = FindFirstFileA(szPath, &wfd); - - if (hFile != INVALID_HANDLE_VALUE) - { - do - { - if (!(dwFlags & SHCONTF_INCLUDEHIDDEN) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) - continue; - - if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - strcpy(p, wfd.cFileName); - SHELL_RegisterCPanelApp((IEnumIDList*)This, szPath); - } - } while(FindNextFileA(hFile, &wfd)); - - FindClose(hFile); - } - - SHELL_RegisterRegistryCPanelApps((IEnumIDList*)This, HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls"); - SHELL_RegisterRegistryCPanelApps((IEnumIDList*)This, HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls"); - } - - return TRUE; -} - -/************************************************************************** - * CreateDesktopEnumList() - */ -static BOOL CreateDesktopEnumList( - IEnumIDList * iface, - DWORD dwFlags) -{ - ICOM_THIS(IEnumIDListImpl,iface); - - LPITEMIDLIST pidl=NULL; - HKEY hkey; - char szPath[MAX_PATH]; - - TRACE("(%p)->(flags=0x%08lx) \n",This,dwFlags); - - /*enumerate the root folders */ - if(dwFlags & SHCONTF_FOLDERS) - { - /*create the pidl for This item */ - pidl = _ILCreateMyComputer(); - if(pidl) - { - if(!AddToEnumList((IEnumIDList*)This, pidl)) - return FALSE; - } - - if(! RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer\\desktop\\NameSpace", 0, KEY_READ, &hkey)) - { - char iid[50]; - int i=0; - - while (1) - { - DWORD size = sizeof (iid); - - if(ERROR_SUCCESS!=RegEnumKeyExA(hkey, i, iid, &size, 0, NULL, NULL, NULL)) - break; - - pidl = _ILCreateGuidFromStrA(iid); - - if(pidl) - AddToEnumList((IEnumIDList*)This, pidl); - - i++; - } - RegCloseKey(hkey); - } - } - - /*enumerate the elements in %windir%\desktop */ - SHGetSpecialFolderPathA(0, szPath, CSIDL_DESKTOPDIRECTORY, FALSE); - - /*FIXME: hide icons for classes in SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer\\HideDesktopIcons\\ClassicStartMenu - -> alter attributes in IDLDATA.folder.uFileAttribs ? - */ - CreateFolderEnumList( (IEnumIDList*)This, szPath, dwFlags); - - return TRUE; -} - -/************************************************************************** - * CreateMyCompEnumList() - */ -static BOOL CreateMyCompEnumList( - IEnumIDList * iface, - DWORD dwFlags) -{ - ICOM_THIS(IEnumIDListImpl,iface); - - LPITEMIDLIST pidl=NULL; - DWORD dwDrivemap; - CHAR szDriveName[4]; - HKEY hkey; - - TRACE("(%p)->(flags=0x%08lx) \n",This,dwFlags); - - /*enumerate the folders*/ - if(dwFlags & SHCONTF_FOLDERS) - { - dwDrivemap = GetLogicalDrives(); - strcpy (szDriveName,"A:\\"); - while (szDriveName[0]<='Z') - { - if(dwDrivemap & 0x00000001L) - { - pidl = _ILCreateDrive(szDriveName); - if(pidl) - { - if(!AddToEnumList((IEnumIDList*)This, pidl)) - return FALSE; - } - } - szDriveName[0]++; - dwDrivemap = dwDrivemap >> 1; - } - - TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n",This); - if(! RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer\\mycomputer\\NameSpace", 0, KEY_READ, &hkey)) - { - char iid[50]; - int i=0; - - while (1) - { - DWORD size = sizeof (iid); - - if(ERROR_SUCCESS!=RegEnumKeyExA(hkey, i, iid, &size, 0, NULL, NULL, NULL)) - break; - - pidl = _ILCreateGuidFromStrA(iid); - - if(pidl) - AddToEnumList((IEnumIDList*)This, pidl); - - i++; - } - RegCloseKey(hkey); - } - } - return TRUE; + return succeeded; } /************************************************************************** @@ -475,51 +189,19 @@ static BOOL DeleteList( * */ -IEnumIDList * IEnumIDList_Constructor( - LPCSTR lpszPath, - DWORD dwFlags, - DWORD dwKind) +IEnumIDList * IEnumIDList_Constructor(void) { - IEnumIDListImpl* lpeidl; - BOOL ret = FALSE; + IEnumIDListImpl *lpeidl = (IEnumIDListImpl*)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(IEnumIDListImpl)); - TRACE("()->(%s flags=0x%08lx kind=0x%08lx)\n",debugstr_a(lpszPath),dwFlags, dwKind); + if (lpeidl) + { + lpeidl->ref = 1; + lpeidl->lpVtbl = &eidlvt; + } + TRACE("-- (%p)->()\n",lpeidl); - lpeidl = (IEnumIDListImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumIDListImpl)); - - if(lpeidl) - { - lpeidl->ref = 1; - lpeidl->lpVtbl = &eidlvt; - - switch (dwKind) - { - case EIDL_DESK: - ret = CreateDesktopEnumList((IEnumIDList*)lpeidl, dwFlags); - break; - - case EIDL_MYCOMP: - ret = CreateMyCompEnumList((IEnumIDList*)lpeidl, dwFlags); - break; - - case EIDL_FILE: - ret = CreateFolderEnumList((IEnumIDList*)lpeidl, lpszPath, dwFlags); - break; - - case EIDL_CPANEL: - ret = CreateCPanelEnumList((IEnumIDList*)lpeidl, dwFlags); - break; - } - - if(!ret) { - HeapFree(GetProcessHeap(),0,lpeidl); - lpeidl = NULL; - } - } - - TRACE("-- (%p)->()\n",lpeidl); - - return (IEnumIDList*)lpeidl; + return (IEnumIDList*)lpeidl; } /************************************************************************** @@ -573,7 +255,7 @@ static ULONG WINAPI IEnumIDList_fnRelease( TRACE("(%p)->(%lu)\n",This,This->ref); - if(!--(This->ref)) { + if (!--(This->ref)) { TRACE(" destroying IEnumIDList(%p)\n",This); DeleteList((IEnumIDList*)This); HeapFree(GetProcessHeap(),0,This); diff --git a/reactos/lib/shell32/enumidlist.h b/reactos/lib/shell32/enumidlist.h new file mode 100644 index 00000000000..53b8b5ff111 --- /dev/null +++ b/reactos/lib/shell32/enumidlist.h @@ -0,0 +1,30 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ENUMIDLIST_H__ +#define __ENUMIDLIST_H__ + +#include "shlobj.h" + +/* Creates an IEnumIDList; add LPITEMIDLISTs to it with AddToEnumList. */ +LPENUMIDLIST IEnumIDList_Constructor(void); +BOOL AddToEnumList(IEnumIDList *list, LPITEMIDLIST pidl); + +/* Enumerates the folders and/or files (depending on dwFlags) in lpszPath and + * adds them to the already-created list. + */ +BOOL CreateFolderEnumList(IEnumIDList *list, LPCSTR lpszPath, DWORD dwFlags); + +#endif /* ndef __ENUMIDLIST_H__ */ diff --git a/reactos/lib/shell32/pidl.c b/reactos/lib/shell32/pidl.c index cd703cfa7ff..1ebdd76330f 100644 --- a/reactos/lib/shell32/pidl.c +++ b/reactos/lib/shell32/pidl.c @@ -1644,49 +1644,6 @@ LPITEMIDLIST _ILCreateDrive( LPCSTR lpszNew) return pidlOut; } -LPITEMIDLIST _ILCreateCPanel(LPCSTR name, LPCSTR displayName, LPCSTR comment, int iconIdx) -{ - PIDLCPanelStruct *p; - LPITEMIDLIST pidl; - PIDLDATA tmp; - int size0 = (char*)&tmp.u.cpanel.szName-(char*)&tmp.u.cpanel; - int size = size0; - int l; - - tmp.type = 0; - tmp.u.cpanel.dummy = 0; - tmp.u.cpanel.iconIdx = iconIdx; - - l = strlen(name); - size += l+1; - - tmp.u.cpanel.offsDispName = l+1; - l = strlen(displayName); - size += l+1; - - tmp.u.cpanel.offsComment = tmp.u.cpanel.offsDispName+1+l; - l = strlen(comment); - size += l+1; - - pidl = SHAlloc(size+4); - if (!pidl) - return NULL; - - pidl->mkid.cb = size+2; - memcpy(pidl->mkid.abID, &tmp, 2+size0); - - p = &((PIDLDATA*)pidl->mkid.abID)->u.cpanel; - strcpy(p->szName, name); - strcpy(p->szName+tmp.u.cpanel.offsDispName, displayName); - strcpy(p->szName+tmp.u.cpanel.offsComment, comment); - - *(WORD*)((char*)pidl+(size+2)) = 0; - - pcheck(pidl); - - return pidl; -} - /************************************************************************** * _ILGetDrive() * @@ -1990,20 +1947,6 @@ REFIID _ILGetGUIDPointer(LPCITEMIDLIST pidl) return NULL; } -/************************************************************************** - * _ILGetCPanelPointer() - * gets a pointer to the control panel struct stored in the pidl - */ -PIDLCPanelStruct* _ILGetCPanelPointer(LPCITEMIDLIST pidl) -{ - LPPIDLDATA pdata = _ILGetDataPointer(pidl); - - if (pdata && pdata->type==0) - return (PIDLCPanelStruct*)&(pdata->u.cpanel); - - return NULL; -} - /************************************************************************* * _ILGetFileDateTime * diff --git a/reactos/lib/shell32/pidl.h b/reactos/lib/shell32/pidl.h index 7a2456ecb2b..bbd8aa35845 100644 --- a/reactos/lib/shell32/pidl.h +++ b/reactos/lib/shell32/pidl.h @@ -209,7 +209,6 @@ LPITEMIDLIST _ILCreatePrinters (void); LPITEMIDLIST _ILCreateNetwork (void); LPITEMIDLIST _ILCreateBitBucket (void); LPITEMIDLIST _ILCreateDrive (LPCSTR); -LPITEMIDLIST _ILCreateCPanel (LPCSTR name, LPCSTR displayName, LPCSTR comment, int iconIdx); /* * helper functions (getting struct-pointer) @@ -218,7 +217,6 @@ LPPIDLDATA _ILGetDataPointer (LPCITEMIDLIST); LPSTR _ILGetTextPointer (LPCITEMIDLIST); LPSTR _ILGetSTextPointer (LPCITEMIDLIST); REFIID _ILGetGUIDPointer (LPCITEMIDLIST pidl); -PIDLCPanelStruct* _ILGetCPanelPointer (LPCITEMIDLIST pidl); /* * debug helper diff --git a/reactos/lib/shell32/shell32_main.h b/reactos/lib/shell32/shell32_main.h index 97e3ee92095..eb399e45628 100644 --- a/reactos/lib/shell32/shell32_main.h +++ b/reactos/lib/shell32/shell32_main.h @@ -97,14 +97,6 @@ HRESULT WINAPI CPanel_GetIconLocationW(LPITEMIDLIST pidl, LPWSTR szIconFile, UIN HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize); HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize); -/* kind of enumidlist */ -#define EIDL_DESK 0 -#define EIDL_MYCOMP 1 -#define EIDL_FILE 2 -#define EIDL_CPANEL 3 - -LPENUMIDLIST IEnumIDList_Constructor(LPCSTR,DWORD,DWORD); - LPEXTRACTICONA IExtractIconA_Constructor(LPCITEMIDLIST); LPEXTRACTICONW IExtractIconW_Constructor(LPCITEMIDLIST); HRESULT CreateStreamOnFile (LPCWSTR pszFilename, DWORD grfMode, IStream ** ppstm); diff --git a/reactos/lib/shell32/shfldr_desktop.c b/reactos/lib/shell32/shfldr_desktop.c index ef053570855..4559912a383 100644 --- a/reactos/lib/shell32/shfldr_desktop.c +++ b/reactos/lib/shell32/shfldr_desktop.c @@ -40,6 +40,7 @@ #include "ole2.h" #include "shlguid.h" +#include "enumidlist.h" #include "pidl.h" #include "undocshell.h" #include "shell32_main.h" @@ -259,6 +260,59 @@ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName (IShellFolder2 * iface, return hr; } +/************************************************************************** + * CreateDesktopEnumList() + */ +static BOOL CreateDesktopEnumList(IEnumIDList *list, DWORD dwFlags) +{ + BOOL ret = TRUE; + char szPath[MAX_PATH]; + + TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags); + + /*enumerate the root folders */ + if(dwFlags & SHCONTF_FOLDERS) + { + HKEY hkey; + + /*create the pidl for This item */ + ret = AddToEnumList(list, _ILCreateMyComputer()); + + if (ret && !RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer\\desktop\\NameSpace", + 0, KEY_READ, &hkey)) + { + char iid[50]; + int i=0; + BOOL moreKeys = TRUE; + + while (ret && moreKeys) + { + DWORD size = sizeof (iid); + LONG apiRet = RegEnumKeyExA(hkey, i, iid, &size, 0, NULL, NULL, + NULL); + + if (ERROR_SUCCESS == apiRet) + { + ret = AddToEnumList(list, _ILCreateGuidFromStrA(iid)); + i++; + } + else if (ERROR_NO_MORE_ITEMS == apiRet) + moreKeys = FALSE; + else + ret = FALSE; + } + RegCloseKey(hkey); + } + } + + /*enumerate the elements in %windir%\desktop */ + SHGetSpecialFolderPathA(0, szPath, CSIDL_DESKTOPDIRECTORY, FALSE); + ret = ret && CreateFolderEnumList(list, szPath, dwFlags); + + return ret; +} + /************************************************************************** * ISF_Desktop_fnEnumObjects */ @@ -269,15 +323,13 @@ static HRESULT WINAPI ISF_Desktop_fnEnumObjects (IShellFolder2 * iface, TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList); - *ppEnumIDList = NULL; - *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK); + *ppEnumIDList = IEnumIDList_Constructor(); + if (*ppEnumIDList) + CreateDesktopEnumList(*ppEnumIDList, dwFlags); TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList); - if (!*ppEnumIDList) - return E_OUTOFMEMORY; - - return S_OK; + return *ppEnumIDList ? S_OK : E_OUTOFMEMORY; } /************************************************************************** diff --git a/reactos/lib/shell32/shfldr_fs.c b/reactos/lib/shell32/shfldr_fs.c index 4346e1f82bb..451df2112de 100644 --- a/reactos/lib/shell32/shfldr_fs.c +++ b/reactos/lib/shell32/shfldr_fs.c @@ -40,6 +40,7 @@ #include "ole2.h" #include "shlguid.h" +#include "enumidlist.h" #include "pidl.h" #include "undocshell.h" #include "shell32_main.h" @@ -391,7 +392,9 @@ IShellFolder_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner, DWORD dwFlags TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList); - *ppEnumIDList = IEnumIDList_Constructor (This->sPathTarget, dwFlags, EIDL_FILE); + *ppEnumIDList = IEnumIDList_Constructor(); + if (*ppEnumIDList) + CreateFolderEnumList(*ppEnumIDList, This->sPathTarget, dwFlags); TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList); @@ -656,7 +659,7 @@ IShellFolder_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, DWOR int len = 0; BOOL bSimplePidl; - *szPath = '\0'; + *szPath = '\0'; TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet); pdump (pidl); diff --git a/reactos/lib/shell32/shfldr_mycomp.c b/reactos/lib/shell32/shfldr_mycomp.c index 9923ab7d0aa..bc6bf164d93 100644 --- a/reactos/lib/shell32/shfldr_mycomp.c +++ b/reactos/lib/shell32/shfldr_mycomp.c @@ -38,7 +38,7 @@ #include "wingdi.h" #include "pidl.h" #include "shlguid.h" - +#include "enumidlist.h" #include "undocshell.h" #include "shell32_main.h" #include "shresdef.h" @@ -237,6 +237,62 @@ ISF_MyComputer_fnParseDisplayName (IShellFolder2 * iface, return hr; } +/************************************************************************** + * CreateMyCompEnumList() + */ +static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags) +{ + BOOL ret = TRUE; + + TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags); + + /*enumerate the folders*/ + if(dwFlags & SHCONTF_FOLDERS) + { + CHAR szDriveName[] = "A:\\"; + DWORD dwDrivemap = GetLogicalDrives(); + HKEY hkey; + + while (ret && szDriveName[0]<='Z') + { + if(dwDrivemap & 0x00000001L) + ret = AddToEnumList(list, _ILCreateDrive(szDriveName)); + szDriveName[0]++; + dwDrivemap = dwDrivemap >> 1; + } + + TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n",list); + if (ret && !RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer\\mycomputer\\NameSpace", + 0, KEY_READ, &hkey)) + { + char iid[50]; + int i=0; + + while (ret) + { + DWORD size = sizeof (iid); + LONG apiRet = RegEnumKeyExA(hkey, i, iid, &size, 0, NULL, NULL, + NULL); + + if (ERROR_SUCCESS == apiRet) + { + /* FIXME: shell extensions, shouldn't the type be + * PT_SHELLEXT? */ + ret = AddToEnumList(list, _ILCreateGuidFromStrA(iid)); + i++; + } + else if (ERROR_NO_MORE_ITEMS == apiRet) + break; + else + ret = FALSE; + } + RegCloseKey(hkey); + } + } + return ret; +} + /************************************************************************** * ISF_MyComputer_fnEnumObjects */ @@ -247,7 +303,9 @@ ISF_MyComputer_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner, DWORD dwFla TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList); - *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP); + *ppEnumIDList = IEnumIDList_Constructor(); + if (*ppEnumIDList) + CreateMyCompEnumList(*ppEnumIDList, dwFlags); TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList); diff --git a/reactos/lib/shell32/shlexec.c b/reactos/lib/shell32/shlexec.c index fac6240f332..22e5922b831 100644 --- a/reactos/lib/shell32/shlexec.c +++ b/reactos/lib/shell32/shlexec.c @@ -537,11 +537,10 @@ UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation, TRACE("%s\n", (lpFile != NULL) ? debugstr_w(lpFile) : "-"); + xlpFile[0] = '\0'; lpResult[0] = '\0'; /* Start off with an empty return string */ if (key) *key = '\0'; - xlpFile[0] = '\0'; - /* trap NULL parameters on entry */ if ((lpFile == NULL) || (lpResult == NULL)) {