From 565b2e0b5de0cdde0d9f5049ea15bd87ff41af1c Mon Sep 17 00:00:00 2001 From: Juergen Schmied Date: Sun, 25 Jul 1999 12:26:05 +0000 Subject: [PATCH] Many fixes/reimplementations. --- dlls/shell32/brsfolder.c | 3 +- dlls/shell32/pidl.c | 1184 +++++++++++++++++++------------- dlls/shell32/pidl.h | 38 +- dlls/shell32/shell32_main.c | 400 +---------- dlls/shell32/shell32_main.h | 72 +- dlls/shell32/shlmenu.c | 136 ++-- include/shell.h | 4 +- include/shlguid.h | 7 +- include/shlobj.h | 7 +- include/wine/obj_enumidlist.h | 8 +- include/wine/obj_shellfolder.h | 9 + relay32/shell32.spec | 8 +- 12 files changed, 886 insertions(+), 990 deletions(-) diff --git a/dlls/shell32/brsfolder.c b/dlls/shell32/brsfolder.c index 19b2bbc4687..45a00471a43 100644 --- a/dlls/shell32/brsfolder.c +++ b/dlls/shell32/brsfolder.c @@ -17,6 +17,7 @@ #include "wine/obj_base.h" #include "wine/obj_enumidlist.h" #include "wine/obj_shellfolder.h" +#include "wine/undocshell.h" #include "pidl.h" #include "shell32_main.h" @@ -253,7 +254,7 @@ BOOL WINAPI BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM wParam, switch (wParam) { case IDOK: pdump ( pidlRet ); - _ILGetPidlPath (pidlRet, lpBrowseInfo->pszDisplayName, MAX_PATH); + SHGetPathFromIDListA(pidlRet, lpBrowseInfo->pszDisplayName); EndDialog(hWnd, (DWORD) ILClone(pidlRet)); return TRUE; diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c index b4d34c5f7d8..de95dbfe748 100644 --- a/dlls/shell32/pidl.c +++ b/dlls/shell32/pidl.c @@ -21,45 +21,70 @@ #include "shell32_main.h" #include "pidl.h" +#include "wine/undocshell.h" DECLARE_DEBUG_CHANNEL(pidl) DECLARE_DEBUG_CHANNEL(shell) -static char * szMyComp = "My Computer"; /* for comparing */ -static char * szNetHood = "Network Neighbourhood"; /* for comparing */ - void pdump (LPCITEMIDLIST pidl) { DWORD type; - CHAR * szData; - CHAR * szShortName; + char * szData; + char * szShortName; + char szName[MAX_PATH]; + BOOL bIsShellDebug; + LPITEMIDLIST pidltemp = pidl; + if (!TRACE_ON(pidl)) + return; + + /* silence the sub-functions */ + bIsShellDebug = TRACE_ON(shell); + __SET_DEBUGGING(__DBCL_TRACE, dbch_shell, FALSE); + __SET_DEBUGGING(__DBCL_TRACE, dbch_pidl, FALSE); + if (! pidltemp) - { TRACE_(pidl)("-------- pidl = NULL (Root)\n"); - return; - } - TRACE_(pidl)("-------- pidl=%p \n", pidl); - if (pidltemp->mkid.cb) - { do - { type = _ILGetDataPointer(pidltemp)->type; - szData = _ILGetTextPointer(type, _ILGetDataPointer(pidltemp)); - szShortName = _ILGetSTextPointer(type, _ILGetDataPointer(pidltemp)); - - TRACE_(pidl)("---- pidl=%p size=%u type=%lx %s, (%s)\n", - pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData), debugstr_a(szShortName)); - - pidltemp = ILGetNext(pidltemp); - } while (pidltemp->mkid.cb); - return; + { + MESSAGE ("-------- pidl=NULL (Desktop)\n"); } else - TRACE_(pidl)("empty pidl (Desktop)\n"); + { + MESSAGE ("-------- pidl=%p\n", pidl); + if (pidltemp->mkid.cb) + { + do + { + type = _ILGetDataPointer(pidltemp)->type; + szData = _ILGetTextPointer(type, _ILGetDataPointer(pidltemp)); + szShortName = _ILGetSTextPointer(type, _ILGetDataPointer(pidltemp)); + _ILSimpleGetText(pidltemp, szName, MAX_PATH); + + MESSAGE ("-- pidl=%p size=%u type=%lx name=%s (%s,%s)\n", + pidltemp, pidltemp->mkid.cb,type,szName,debugstr_a(szData), debugstr_a(szShortName)); + + pidltemp = ILGetNext(pidltemp); + + } while (pidltemp->mkid.cb); + } + else + { + MESSAGE ("empty pidl (Desktop)\n"); + } + } + + __SET_DEBUGGING(__DBCL_TRACE, dbch_shell, bIsShellDebug); + __SET_DEBUGGING(__DBCL_TRACE, dbch_pidl, TRUE); + } #define BYTES_PRINTED 32 BOOL pcheck (LPCITEMIDLIST pidl) { DWORD type, ret=TRUE; + BOOL bIsPidlDebug; LPITEMIDLIST pidltemp = pidl; + bIsPidlDebug = TRACE_ON(shell); + __SET_DEBUGGING(__DBCL_TRACE, dbch_pidl, FALSE); + if (pidltemp && pidltemp->mkid.cb) { do { type = _ILGetDataPointer(pidltemp)->type; @@ -104,6 +129,7 @@ BOOL pcheck (LPCITEMIDLIST pidl) pidltemp = ILGetNext(pidltemp); } while (pidltemp->mkid.cb); } + __SET_DEBUGGING(__DBCL_TRACE, dbch_pidl, bIsPidlDebug); return ret; } @@ -111,30 +137,38 @@ BOOL pcheck (LPCITEMIDLIST pidl) * ILGetDisplayName [SHELL32.15] */ BOOL WINAPI ILGetDisplayName(LPCITEMIDLIST pidl,LPSTR path) -{ TRACE_(shell)("pidl=%p %p semi-stub\n",pidl,path); +{ + TRACE_(shell)("pidl=%p %p semi-stub\n",pidl,path); return SHGetPathFromIDListA(pidl, path); } /************************************************************************* * ILFindLastID [SHELL32.16] + * + * NOTES + * observed: pidl=Desktop return=pidl */ LPITEMIDLIST WINAPI ILFindLastID(LPITEMIDLIST pidl) -{ LPITEMIDLIST pidlLast = NULL; +{ LPITEMIDLIST pidlLast = pidl; TRACE_(pidl)("(pidl=%p)\n",pidl); while (pidl->mkid.cb) - { pidlLast = pidl; + { + pidlLast = pidl; pidl = ILGetNext(pidl); } return pidlLast; } /************************************************************************* * ILRemoveLastID [SHELL32.17] + * * NOTES - * Removes the last item + * when pidl=Desktop return=FALSE */ BOOL WINAPI ILRemoveLastID(LPCITEMIDLIST pidl) -{ TRACE_(shell)("pidl=%p\n",pidl); +{ + TRACE_(shell)("pidl=%p\n",pidl); + if (!pidl || !pidl->mkid.cb) return 0; ILFindLastID(pidl)->mkid.cb = 0; @@ -172,22 +206,26 @@ LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl) */ LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl) { DWORD len; - LPITEMIDLIST newpidl=NULL; + LPITEMIDLIST pidlNew = NULL; TRACE_(pidl)("pidl=%p \n",pidl); pdump(pidl); if (pidl) - { len = pidl->mkid.cb; - newpidl = (LPITEMIDLIST) SHAlloc (len+2); - if (newpidl) - { memcpy(newpidl,pidl,len); - ILGetNext(newpidl)->mkid.cb = 0x00; + { + len = pidl->mkid.cb; + pidlNew = (LPITEMIDLIST) SHAlloc (len+2); + if (pidlNew) + { + memcpy(pidlNew,pidl,len+2); /* 2 -> mind a desktop pidl */ + + if (len) + ILGetNext(pidlNew)->mkid.cb = 0x00; } } - TRACE_(pidl)("-- newpidl=%p\n",newpidl); + TRACE_(pidl)("-- newpidl=%p\n",pidlNew); - return newpidl; + return pidlNew; } /************************************************************************* * ILLoadFromStream @@ -249,7 +287,8 @@ HRESULT WINAPI SHILCreateFromPathA (LPSTR path, LPITEMIDLIST * ppidl, DWORD attr LocalToWideChar(lpszDisplayName, path, MAX_PATH); if (SUCCEEDED (SHGetDesktopFolder(&sf))) - { ret = sf->lpvtbl->fnParseDisplayName(sf,0, NULL,lpszDisplayName,&pchEaten,ppidl,&attributes); + { + ret = sf->lpvtbl->fnParseDisplayName(sf,0, NULL,lpszDisplayName,&pchEaten,ppidl,&attributes); sf->lpvtbl->fnRelease(sf); } return ret; @@ -262,7 +301,8 @@ HRESULT WINAPI SHILCreateFromPathW (LPWSTR path, LPITEMIDLIST * ppidl, DWORD att TRACE_(shell)("%s %p 0x%08lx\n",debugstr_w(path),ppidl,attributes); if (SUCCEEDED (SHGetDesktopFolder(&sf))) - { ret = sf->lpvtbl->fnParseDisplayName(sf,0, NULL, path, &pchEaten, ppidl, &attributes); + { + ret = sf->lpvtbl->fnParseDisplayName(sf,0, NULL, path, &pchEaten, ppidl, &attributes); sf->lpvtbl->fnRelease(sf); } return ret; @@ -323,9 +363,9 @@ LPITEMIDLIST WINAPI ILGlobalClone(LPCITEMIDLIST pidl) * */ BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) -{ LPPIDLDATA ppidldata; - CHAR * szData1; - CHAR * szData2; +{ + char szData1[MAX_PATH]; + char szData2[MAX_PATH]; LPITEMIDLIST pidltemp1 = pidl1; LPITEMIDLIST pidltemp2 = pidl2; @@ -334,39 +374,27 @@ BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) /* explorer reads from registry directly (StreamMRU), so we can only check here */ - if ((!pcheck (pidl1)) || (!pcheck (pidl2))) - return FALSE; + if ((!pcheck (pidl1)) || (!pcheck (pidl2))) return FALSE; pdump (pidl1); pdump (pidl2); - if ( (!pidl1) || (!pidl2) ) - { return FALSE; - } + if ( (!pidl1) || (!pidl2) ) return FALSE; - if (pidltemp1->mkid.cb && pidltemp2->mkid.cb) - { do - { ppidldata = _ILGetDataPointer(pidltemp1); - szData1 = _ILGetTextPointer(ppidldata->type, ppidldata); - - ppidldata = _ILGetDataPointer(pidltemp2); - szData2 = _ILGetTextPointer(ppidldata->type, ppidldata); + while (pidltemp1->mkid.cb && pidltemp2->mkid.cb) + { + _ILSimpleGetText(pidltemp1, szData1, MAX_PATH); + _ILSimpleGetText(pidltemp2, szData2, MAX_PATH); - if (!szData1 || !szData2) - { FIXME_(pidl)("Failure getting text pointer"); - return FALSE; - } - - if (strcmp ( szData1, szData2 )!=0 ) + if (strcasecmp ( szData1, szData2 )!=0 ) return FALSE; pidltemp1 = ILGetNext(pidltemp1); pidltemp2 = ILGetNext(pidltemp2); - - } while (pidltemp1->mkid.cb && pidltemp2->mkid.cb); } - if (!pidltemp1 && !pidltemp2) - { TRACE_(shell)("--- equal\n"); + + if (!pidltemp1->mkid.cb && !pidltemp2->mkid.cb) + { return TRUE; } @@ -381,35 +409,24 @@ BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) */ BOOL WINAPI ILIsParent( LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidlChild, BOOL bImmediate) { - LPPIDLDATA ppidldata; - CHAR * szData1; - CHAR * szData2; + char szData1[MAX_PATH]; + char szData2[MAX_PATH]; LPITEMIDLIST pParent = pidlParent; LPITEMIDLIST pChild = pidlChild; TRACE_(pidl)("%p %p %x\n", pidlParent, pidlChild, bImmediate); - if (pParent->mkid.cb && pChild->mkid.cb) - { do - { ppidldata = _ILGetDataPointer(pParent); - szData1 = _ILGetTextPointer(ppidldata->type, ppidldata); - - ppidldata = _ILGetDataPointer(pChild); - szData2 = _ILGetTextPointer(ppidldata->type, ppidldata); + while (pParent->mkid.cb && pChild->mkid.cb) + { + _ILSimpleGetText(pParent, szData1, MAX_PATH); + _ILSimpleGetText(pChild, szData2, MAX_PATH); - if (!szData1 || !szData2) - { FIXME_(pidl)("Failure getting text pointer"); - return FALSE; - } - - if (strcmp ( szData1, szData2 )!=0 ) - return FALSE; + if (strcasecmp ( szData1, szData2 )!=0 ) + return FALSE; - pParent = ILGetNext(pParent); - pChild = ILGetNext(pChild); - - } while (pParent->mkid.cb && pChild->mkid.cb); + pParent = ILGetNext(pParent); + pChild = ILGetNext(pChild); } if ( pParent->mkid.cb || ! pChild->mkid.cb) /* child shorter or has equal length to parent */ @@ -426,14 +443,17 @@ BOOL WINAPI ILIsParent( LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidlChild, BOOL * * NOTES * Compares elements from pidl1 and pidl2. - * When at least the first element is equal, it gives a pointer - * to the first different element of pidl 2 back. - * Returns 0 if pidl 2 is shorter. + * + * pidl1 is desktop pidl2 + * pidl1 shorter pidl2 pointer to first different element of pidl2 + * if there was at least one equal element + * pidl2 shorter pidl1 0 + * pidl2 equal pidl1 pointer to last 0x00-element of pidl2 */ LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2) -{ LPPIDLDATA ppidldata; - CHAR * szData1; - CHAR * szData2; +{ + char szData1[MAX_PATH]; + char szData2[MAX_PATH]; LPITEMIDLIST pidltemp1 = pidl1; LPITEMIDLIST pidltemp2 = pidl2; @@ -449,38 +469,30 @@ LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2) pdump (pidl1); pdump (pidl2); - if ( !pidl1 || !pidl1->mkid.cb) /* pidl 1 is desktop (root) */ - { TRACE_(shell)("--- %p\n", pidl2); - return pidl2; + if ( _ILIsDesktop(pidl1) ) + { + ret = pidl2; } + else + { + while (pidltemp1->mkid.cb && pidltemp2->mkid.cb) + { + _ILSimpleGetText(pidltemp1, szData1, MAX_PATH); + _ILSimpleGetText(pidltemp2, szData2, MAX_PATH); - if (pidltemp1->mkid.cb && pidltemp2->mkid.cb) - { do - { ppidldata = _ILGetDataPointer(pidltemp1); - szData1 = _ILGetTextPointer(ppidldata->type, ppidldata); - - ppidldata = _ILGetDataPointer(pidltemp2); - szData2 = _ILGetTextPointer(ppidldata->type, ppidldata); + if (strcasecmp(szData1,szData2)) + break; - pidltemp2 = ILGetNext(pidltemp2); /* points behind the pidl2 */ - - if (strcmp(szData1,szData2) == 0) - { ret = pidltemp2; /* found equal element */ - } - else - { if (ret) /* different element after equal -> break */ - { ret = NULL; - break; - } - } pidltemp1 = ILGetNext(pidltemp1); - } while (pidltemp1->mkid.cb && pidltemp2->mkid.cb); - } + pidltemp2 = ILGetNext(pidltemp2); + ret = pidltemp2; + } - if (!pidltemp2->mkid.cb) - { return NULL; /* complete equal or pidl 2 is shorter */ + if (pidltemp1->mkid.cb) + { + ret = NULL; /* elements of pidl1 left*/ + } } - TRACE_(shell)("--- %p\n", ret); return ret; /* pidl 1 is shorter */ } @@ -494,39 +506,41 @@ LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2) * Does not destroy the passed in idlists! */ LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2) -{ DWORD len1,len2; - LPITEMIDLIST pidlNew; - - TRACE_(pidl)("pidl=%p pidl=%p\n",pidl1,pidl2); +{ + DWORD len1,len2; + LPITEMIDLIST pidlNew; + + TRACE_(pidl)("pidl=%p pidl=%p\n",pidl1,pidl2); - if(!pidl1 && !pidl2) - { return NULL; - } + if(!pidl1 && !pidl2) return NULL; - pdump (pidl1); - pdump (pidl2); - - if(!pidl1) - { pidlNew = ILClone(pidl2); - return pidlNew; - } + pdump (pidl1); + pdump (pidl2); - if(!pidl2) - { pidlNew = ILClone(pidl1); - return pidlNew; - } + if(!pidl1) + { + pidlNew = ILClone(pidl2); + return pidlNew; + } - len1 = ILGetSize(pidl1)-2; - len2 = ILGetSize(pidl2); - pidlNew = SHAlloc(len1+len2); - - if (pidlNew) - { memcpy(pidlNew,pidl1,len1); - memcpy(((BYTE *)pidlNew)+len1,pidl2,len2); - } + if(!pidl2) + { + pidlNew = ILClone(pidl1); + return pidlNew; + } -/* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/ - return pidlNew; + len1 = ILGetSize(pidl1)-2; + len2 = ILGetSize(pidl2); + pidlNew = SHAlloc(len1+len2); + + if (pidlNew) + { + memcpy(pidlNew,pidl1,len1); + memcpy(((BYTE *)pidlNew)+len1,pidl2,len2); + } + + /* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/ + return pidlNew; } /************************************************************************* * SHGetRealIDL [SHELL32.98] @@ -534,7 +548,9 @@ LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2) * NOTES */ LPITEMIDLIST WINAPI SHGetRealIDL(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl, DWORD z) -{ FIXME_(pidl)("sf=%p pidl=%p 0x%04lx\n",lpsf,pidl,z); +{ + FIXME_(pidl)("sf=%p pidl=%p 0x%04lx\n",lpsf,pidl,z); + pdump (pidl); return 0; } @@ -543,10 +559,15 @@ LPITEMIDLIST WINAPI SHGetRealIDL(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl, DWORD z) * SHLogILFromFSIL [SHELL32.95] * * NOTES + * pild = CSIDL_DESKTOP ret = 0 + * pild = CSIDL_DRIVES ret = 0 */ LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl) -{ FIXME_(pidl)("(pidl=%p)\n",pidl); +{ + FIXME_(pidl)("(pidl=%p)\n",pidl); + pdump(pidl); + return 0; } @@ -564,7 +585,8 @@ LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl) * exported by ordinal */ DWORD WINAPI ILGetSize(LPITEMIDLIST pidl) -{ LPSHITEMID si = &(pidl->mkid); +{ + LPSHITEMID si = &(pidl->mkid); DWORD len=0; if (pidl) @@ -577,28 +599,30 @@ DWORD WINAPI ILGetSize(LPITEMIDLIST pidl) TRACE_(pidl)("pidl=%p size=%lu\n",pidl, len); return len; } + /************************************************************************* * ILGetNext [SHELL32.153] * gets the next simple pidl of a complex pidl * - * PARAMETERS - * pidl ITEMIDLIST - * - * RETURNS - * pointer to next element - * NULL when last element ist reached + * observed return values: + * null -> null + * desktop -> null + * simple pidl -> pointer to 0x0000 element * */ LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl) -{ LPITEMIDLIST nextpidl; +{ WORD len; TRACE_(pidl)("(pidl=%p)\n",pidl); + if(pidl) - { len = pidl->mkid.cb; + { + len = pidl->mkid.cb; if (len) - { nextpidl = (LPITEMIDLIST) (((LPBYTE)pidl)+len); - return nextpidl; + { + pidl = (LPITEMIDLIST) (((LPBYTE)pidl)+len); + return pidl; } } return NULL; @@ -613,23 +637,31 @@ LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl) * Destroys the passed in idlist! (???) */ LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl,LPCITEMIDLIST item,BOOL bEnd) -{ LPITEMIDLIST idlRet; +{ + LPITEMIDLIST idlRet; + WARN_(pidl)("(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl,item,bEnd); + pdump (pidl); pdump (item); if (_ILIsDesktop(pidl)) - { idlRet = ILClone(item); + { + idlRet = ILClone(item); if (pidl) SHFree (pidl); return idlRet; - } + } + if (bEnd) - { idlRet=ILCombine(pidl,item); + { + idlRet=ILCombine(pidl,item); } else - { idlRet=ILCombine(item,pidl); + { + idlRet=ILCombine(item,pidl); } + SHFree(pidl); return idlRet; } @@ -654,7 +686,8 @@ DWORD WINAPI ILFree(LPITEMIDLIST pidl) * */ DWORD WINAPI ILGlobalFree( LPITEMIDLIST pidl) -{ TRACE_(pidl)("%p\n",pidl); +{ + TRACE_(pidl)("%p\n",pidl); if (!pidl) return FALSE; @@ -666,15 +699,18 @@ DWORD WINAPI ILGlobalFree( LPITEMIDLIST pidl) * */ LPITEMIDLIST WINAPI ILCreateFromPathA (LPSTR path) -{ LPITEMIDLIST pidlnew; +{ + LPITEMIDLIST pidlnew; TRACE_(shell)("%s\n",path); + if (SUCCEEDED (SHILCreateFromPathA (path, &pidlnew, 0))) return pidlnew; return FALSE; } LPITEMIDLIST WINAPI ILCreateFromPathW (LPWSTR path) -{ LPITEMIDLIST pidlnew; +{ + LPITEMIDLIST pidlnew; TRACE_(shell)("%s\n",debugstr_w(path)); @@ -690,66 +726,139 @@ LPITEMIDLIST WINAPI ILCreateFromPathAW (LPVOID path) } /************************************************************************* * SHSimpleIDListFromPath [SHELL32.162] + */ +LPITEMIDLIST WINAPI SHSimpleIDListFromPathA (LPSTR lpszPath) +{ + LPITEMIDLIST pidl=NULL; + HANDLE hFile; + WIN32_FIND_DATAA stffile; + + TRACE_(pidl)("path=%s\n", lpszPath); + + if (!lpszPath) return NULL; + + hFile = FindFirstFileA(lpszPath, &stffile); + + if ( hFile != INVALID_HANDLE_VALUE ) + { + if (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + pidl = _ILCreateFolder (&stffile); + } + else + { + pidl = _ILCreateValue (&stffile); + } + FindClose (hFile); + } + return pidl; +} +LPITEMIDLIST WINAPI SHSimpleIDListFromPathW (LPWSTR lpszPath) +{ + char lpszTemp[MAX_PATH]; + TRACE_(pidl)("path=L%s\n",debugstr_w(lpszPath)); + + WideCharToLocal(lpszTemp, lpszPath, MAX_PATH); + + return SHSimpleIDListFromPathA (lpszTemp); +} + +LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW (LPVOID lpszPath) +{ + if ( VERSION_OsIsUnicode()) + return SHSimpleIDListFromPathW (lpszPath); + return SHSimpleIDListFromPathA (lpszPath); +} + +/************************************************************************* + * SHGetSpecialFolderLocation [SHELL32.223] + * + * gets the folder locations from the registry and creates a pidl + * creates missing reg keys and directorys + * + * PARAMS + * hwndOwner [I] + * nFolder [I] CSIDL_xxxxx + * ppidl [O] PIDL of a special folder * */ -LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW (LPVOID lpszPath) -{ LPCSTR lpszElement; - char lpszTemp[MAX_PATH]; +HRESULT WINAPI SHGetSpecialFolderLocation( + HWND hwndOwner, + INT nFolder, + LPITEMIDLIST * ppidl) +{ + CHAR szPath[256]; + HRESULT hr = E_INVALIDARG; - if (!lpszPath) - return 0; + TRACE_(shell)("(%04x,0x%x,%p)\n", hwndOwner,nFolder,ppidl); - if ( VERSION_OsIsUnicode()) - { TRACE_(pidl)("(path=L%s)\n",debugstr_w((LPWSTR)lpszPath)); - WideCharToLocal(lpszTemp, lpszPath, MAX_PATH); - } - else - { TRACE_(pidl)("(path=%s)\n",(LPSTR)lpszPath); - strcpy(lpszTemp, lpszPath); + *ppidl = NULL; + + if (ppidl) + { + switch (nFolder) + { + case CSIDL_DESKTOP: + *ppidl = _ILCreateDesktop(); + hr = NOERROR; + break; + + case CSIDL_DRIVES: + *ppidl = _ILCreateMyComputer(); + hr = NOERROR; + break; + + default: + if (SHGetSpecialFolderPathA(hwndOwner, szPath, nFolder, TRUE)) + { + DWORD attributes=0; + TRACE_(shell)("Value=%s\n",szPath); + hr = SHILCreateFromPathA(szPath, ppidl, attributes); + } + } } - - lpszElement = PathFindFilenameA(lpszTemp); - if( GetFileAttributesA(lpszTemp) & FILE_ATTRIBUTE_DIRECTORY ) - { return _ILCreateFolder(NULL, lpszElement); /*FIXME: fill shortname */ - } - return _ILCreateValue(NULL, lpszElement); /*FIXME: fill shortname */ + + TRACE_(shell)("-- (new pidl %p)\n",*ppidl); + return hr; } + /************************************************************************* * SHGetDataFromIDListA [SHELL32.247] * */ HRESULT WINAPI SHGetDataFromIDListA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len) -{ TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len); +{ + TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len); - if (! psf || !dest ) - return E_INVALIDARG; + if (! psf || !dest ) return E_INVALIDARG; switch (nFormat) - { case SHGDFIL_FINDDATA: - { WIN32_FIND_DATAA * pfd = dest; - STRRET lpName; + { + case SHGDFIL_FINDDATA: + { + WIN32_FIND_DATAA * pfd = dest; CHAR pszPath[MAX_PATH]; - HANDLE handle; + HANDLE handle; if ( len < sizeof (WIN32_FIND_DATAA)) return E_INVALIDARG; - psf->lpvtbl->fnAddRef(psf); - psf->lpvtbl->fnGetDisplayNameOf( psf, pidl, SHGDN_FORPARSING, &lpName); - psf->lpvtbl->fnRelease(psf); + SHGetPathFromIDListA(pidl, pszPath); - strcpy(pszPath,lpName.u.cStr); if ((handle = FindFirstFileA ( pszPath, pfd))) FindClose (handle); } - break; + return NOERROR; + case SHGDFIL_NETRESOURCE: case SHGDFIL_DESCRIPTIONID: FIXME_(shell)("SHGDFIL %i stub\n", nFormat); break; + default: ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat); } + return E_INVALIDARG; } /************************************************************************* @@ -757,16 +866,130 @@ HRESULT WINAPI SHGetDataFromIDListA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int n * */ HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len) -{ FIXME_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len); +{ + FIXME_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len); + return SHGetDataFromIDListA( psf, pidl, nFormat, dest, len); } -/************************************************************************** -* internal functions -*/ +/************************************************************************* + * SHGetPathFromIDListA [SHELL32.261][NT 4.0: SHELL32.220] + * + * PARAMETERS + * pidl, [IN] pidl + * pszPath [OUT] path + * + * RETURNS + * path from a passed PIDL. + * + * NOTES + * NULL returns FALSE + * desktop pidl gives path to desktopdirectory back + * special pidls returning FALSE + * + * FIXME + * fnGetDisplayNameOf can return different types of OLEString + */ +BOOL WINAPI SHGetPathFromIDListA (LPCITEMIDLIST pidl,LPSTR pszPath) +{ STRRET lpName; + LPSHELLFOLDER shellfolder; + + TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath); + + if (!pidl) return FALSE; + + pdump(pidl); + + if(_ILIsDesktop(pidl)) + { + SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOPDIRECTORY, FALSE); + } + else + { + if (SHGetDesktopFolder(&shellfolder)==S_OK) + { + IShellFolder_GetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName); + IShellFolder_Release(shellfolder); + } + strcpy(pszPath,lpName.u.cStr); + } + TRACE_(shell)("-- (%s)\n",pszPath); + + return TRUE; +} +/************************************************************************* + * SHGetPathFromIDListW [SHELL32.262] + */ +BOOL WINAPI SHGetPathFromIDListW (LPCITEMIDLIST pidl,LPWSTR pszPath) +{ char sTemp[MAX_PATH]; + + TRACE_(shell)("(pidl=%p)\n", pidl); + + SHGetPathFromIDListA (pidl, sTemp); + lstrcpyAtoW(pszPath, sTemp); + + TRACE_(shell)("-- (%s)\n",debugstr_w(pszPath)); + + return TRUE; +} + +/************************************************************************* + * SHBindToParent [shell version 5.0] + */ +HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast) +{ + IShellFolder * psf; + LPITEMIDLIST pidlChild, pidlParent; + HRESULT hr=E_FAIL; + + TRACE_(shell)("pidl=%p\n", pidl); + pdump(pidl); + + if (_ILIsPidlSimple(pidl)) return E_INVALIDARG; + + *ppv = NULL; + pidlChild = ILClone(ILFindLastID(pidl)); + pidlParent = ILClone(pidl); + ILRemoveLastID(pidlParent); + + if (SUCCEEDED(SHGetDesktopFolder(&psf))) + { + if (SUCCEEDED(IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv))) + { + if(ppidlLast) + *ppidlLast = pidlChild; + else + ILFree (pidlChild); + hr = S_OK; + } + } + SHFree (pidlParent); + + TRACE_(shell)("-- psf=%p pidl=%p\n", *ppv, (ppidlLast)?*ppidlLast:NULL); + return hr; +} + +/************************************************************************* + * SHGetPathFromIDListAW [SHELL32.221][NT 4.0: SHELL32.219] + */ +BOOL WINAPI SHGetPathFromIDListAW(LPCITEMIDLIST pidl,LPVOID pszPath) +{ + TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath); + + if (VERSION_OsIsUnicode()) + return SHGetPathFromIDListW(pidl,pszPath); + return SHGetPathFromIDListA(pidl,pszPath); +} /************************************************************************** + * + * internal functions + * + * ### 1. section creating pidls ### + * + ************************************************************************* * _ILCreateDesktop() + * _ILCreateIExplore() * _ILCreateMyComputer() * _ILCreateDrive() * _ILCreateFolder() @@ -776,282 +999,111 @@ LPITEMIDLIST WINAPI _ILCreateDesktop() { TRACE_(pidl)("()\n"); return _ILCreate(PT_DESKTOP, NULL, 0); } + LPITEMIDLIST WINAPI _ILCreateMyComputer() { TRACE_(pidl)("()\n"); return _ILCreate(PT_MYCOMP, &IID_MyComputer, sizeof(GUID)); } + +LPITEMIDLIST WINAPI _ILCreateIExplore() +{ TRACE_(pidl)("()\n"); + return _ILCreate(PT_MYCOMP, &IID_IExplore, sizeof(GUID)); +} + LPITEMIDLIST WINAPI _ILCreateDrive( LPCSTR lpszNew) { char sTemp[4]; - strncpy (sTemp,lpszNew,4); + lstrcpynA (sTemp,lpszNew,4); sTemp[2]='\\'; sTemp[3]=0x00; TRACE_(pidl)("(%s)\n",sTemp); return _ILCreate(PT_DRIVE,(LPVOID)&sTemp[0],4); } -LPITEMIDLIST WINAPI _ILCreateFolder( LPCSTR lpszShortName, LPCSTR lpszName) -{ char buff[MAX_PATH]; + +LPITEMIDLIST WINAPI _ILCreateFolder( WIN32_FIND_DATAA * stffile ) +{ + char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */ char * pbuff = buff; ULONG len, len1; + LPITEMIDLIST pidl; - TRACE_(pidl)("(%s, %s)\n",lpszShortName, lpszName); + TRACE_(pidl)("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName); - len = strlen (lpszName)+1; - memcpy (pbuff, lpszName, len); + /* prepare buffer with both names */ + len = strlen (stffile->cFileName) + 1; + memcpy (pbuff, stffile->cFileName, len); pbuff += len; - if (lpszShortName) - { len1 = strlen (lpszShortName)+1; - memcpy (pbuff, lpszShortName, len1); + if (stffile->cAlternateFileName) + { + len1 = strlen (stffile->cAlternateFileName)+1; + memcpy (pbuff, stffile->cAlternateFileName, len1); } else - { len1 = 1; + { + len1 = 1; *pbuff = 0x00; } - return _ILCreate(PT_FOLDER, (LPVOID)buff, len + len1); + + pidl = _ILCreate(PT_FOLDER, (LPVOID)buff, len + len1); + + /* set attributes */ + if (pidl) + { + LPPIDLDATA pData; + pData = _ILGetDataPointer(pidl); + FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime); + pData->u.folder.dwFileSize = stffile->nFileSizeLow; + pData->u.folder.uFileAttribs=stffile->dwFileAttributes; + } + + return pidl; } -LPITEMIDLIST WINAPI _ILCreateValue(LPCSTR lpszShortName, LPCSTR lpszName) -{ char buff[MAX_PATH]; + +LPITEMIDLIST WINAPI _ILCreateValue(WIN32_FIND_DATAA * stffile) +{ + char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */ char * pbuff = buff; ULONG len, len1; + LPITEMIDLIST pidl; - TRACE_(pidl)("(%s, %s)\n", lpszShortName, lpszName); + TRACE_(pidl)("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName); - len = strlen (lpszName)+1; - memcpy (pbuff, lpszName, len); + /* prepare buffer with both names */ + len = strlen (stffile->cFileName) + 1; + memcpy (pbuff, stffile->cFileName, len); pbuff += len; - if (lpszShortName) - { len1 = strlen (lpszShortName)+1; - memcpy (pbuff, lpszShortName, len1); + if (stffile->cAlternateFileName) + { + len1 = strlen (stffile->cAlternateFileName)+1; + memcpy (pbuff, stffile->cAlternateFileName, len1); } else - { len1 = 1; + { + len1 = 1; *pbuff = 0x00; } - return _ILCreate(PT_VALUE, (LPVOID)buff, len + len1); -} -/************************************************************************** - * _ILGetDrive() - * - * Gets the text for the drive eg. 'c:\' - * - * RETURNS - * strlen (lpszText) - */ -DWORD WINAPI _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize) -{ TRACE_(pidl)("(%p,%p,%u)\n",pidl,pOut,uSize); - - if(_ILIsMyComputer(pidl)) - pidl = ILGetNext(pidl); - - if (pidl && _ILIsDrive(pidl)) - return _ILGetData(PT_DRIVE, pidl, (LPVOID)pOut, uSize)-1; - - return 0; -} -/************************************************************************** - * _ILGetItemText() - * Gets the text for only the first item - * - * RETURNS - * strlen (lpszText) - */ -DWORD WINAPI _ILGetItemText(LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize) -{ DWORD ret = 0; - - TRACE_(pidl)("(pidl=%p %p %d)\n",pidl,lpszText,uSize); - if (_ILIsMyComputer(pidl)) - { ret = _ILGetData(PT_MYCOMP, pidl, (LPVOID)lpszText, uSize)-1; - } - else if (_ILIsDrive(pidl)) - { ret = _ILGetData(PT_DRIVE, pidl, (LPVOID)lpszText, uSize)-1; - } - else if (_ILIsFolder (pidl)) - { ret = _ILGetData(PT_FOLDER, pidl, (LPVOID)lpszText, uSize)-1; - } - else if (_ILIsValue (pidl)) - { ret = _ILGetData(PT_VALUE, pidl, (LPVOID)lpszText, uSize)-1; - } - TRACE_(pidl)("(-- %s)\n",debugstr_a(lpszText)); - return ret; -} -/************************************************************************** - * _ILIsDesktop() - * _ILIsDrive() - * _ILIsFolder() - * _ILIsValue() - */ -BOOL WINAPI _ILIsDesktop(LPCITEMIDLIST pidl) -{ TRACE_(pidl)("(%p)\n",pidl); - return ( !pidl || (pidl && pidl->mkid.cb == 0x00) ); -} - -BOOL WINAPI _ILIsMyComputer(LPCITEMIDLIST pidl) -{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl); - TRACE_(pidl)("(%p)\n",pidl); - return (pidl && lpPData && PT_MYCOMP == lpPData->type); -} - -BOOL WINAPI _ILIsDrive(LPCITEMIDLIST pidl) -{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl); - TRACE_(pidl)("(%p)\n",pidl); - return (pidl && lpPData && (PT_DRIVE == lpPData->type || - PT_DRIVE1 == lpPData->type || - PT_DRIVE2 == lpPData->type || - PT_DRIVE3 == lpPData->type)); -} - -BOOL WINAPI _ILIsFolder(LPCITEMIDLIST pidl) -{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl); - TRACE_(pidl)("(%p)\n",pidl); - return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type)); -} - -BOOL WINAPI _ILIsValue(LPCITEMIDLIST pidl) -{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl); - TRACE_(pidl)("(%p)\n",pidl); - return (pidl && lpPData && PT_VALUE == lpPData->type); -} - -/************************************************************************** - * _ILGetFolderText() - * Creates a Path string from a PIDL, filtering out the special Folders and values - * There is no trailing backslash - * When lpszPath is NULL the needed size is returned - * - * RETURNS - * strlen(lpszPath) - */ -DWORD WINAPI _ILGetFolderText(LPCITEMIDLIST pidl,LPSTR lpszPath, DWORD dwSize) -{ LPITEMIDLIST pidlTemp; - LPPIDLDATA pData; - DWORD dwCopied = 0; - LPSTR pText; - - TRACE_(pidl)("(%p path=%p)\n",pidl, lpszPath); - - if(!pidl) - return 0; - - if(_ILIsMyComputer(pidl)) - { pidlTemp = ILGetNext(pidl); - TRACE_(pidl)("-- skip My Computer\n"); - } - else - { pidlTemp = (LPITEMIDLIST)pidl; - } - - if(lpszPath) - *lpszPath = 0; - - pData = _ILGetDataPointer(pidlTemp); - - while(pidlTemp->mkid.cb && !(PT_VALUE == pData->type)) - { - if (!(pText = _ILGetTextPointer(pData->type,pData))) - return 0; /* foreign pidl */ - - dwCopied += strlen(pText); - - pidlTemp = ILGetNext(pidlTemp); - pData = _ILGetDataPointer(pidlTemp); - - if (lpszPath) - { strcat(lpszPath, pText); - - if (pidlTemp->mkid.cb /* last element ? */ - && (pText[2] != '\\') /* drive has own '\' */ - && (PT_VALUE != pData->type)) /* next element is value */ - { lpszPath[dwCopied] = '\\'; - lpszPath[dwCopied+1] = '\0'; - dwCopied++; - } - } - else /* only length */ - { if (pidlTemp->mkid.cb - && (pText[2] != '\\') - && (PT_VALUE != pData->type)) - dwCopied++; /* backslash between elements */ - } - } - - TRACE_(pidl)("-- (size=%lu path=%s)\n",dwCopied, debugstr_a(lpszPath)); - return dwCopied; -} - - -/************************************************************************** - * _ILGetValueText() - * Gets the text for the last item in the list - */ -DWORD WINAPI _ILGetValueText(LPCITEMIDLIST pidl, LPSTR lpszValue, DWORD dwSize) -{ LPITEMIDLIST pidlTemp=pidl; - CHAR szText[MAX_PATH]; - - TRACE_(pidl)("(pidl=%p %p 0x%08lx)\n",pidl,lpszValue,dwSize); - - if(!pidl) - { return 0; - } - - while(pidlTemp->mkid.cb && !_ILIsValue(pidlTemp)) - { pidlTemp = ILGetNext(pidlTemp); - } - - if(!pidlTemp->mkid.cb) - { return 0; - } - - _ILGetItemText( pidlTemp, szText, sizeof(szText)); - - if(!lpszValue) - { return strlen(szText); - } + pidl = _ILCreate(PT_VALUE, (LPVOID)buff, len + len1); - strcpy(lpszValue, szText); + /* set attributes */ + if (pidl) + { + LPPIDLDATA pData; + pData = _ILGetDataPointer(pidl); + FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime); + pData->u.folder.dwFileSize = stffile->nFileSizeLow; + pData->u.folder.uFileAttribs=stffile->dwFileAttributes; + } - TRACE_(pidl)("-- (pidl=%p %p=%s 0x%08lx)\n",pidl,lpszValue,lpszValue,dwSize); - return strlen(lpszValue); + return pidl; } -/************************************************************************** - * _ILGetPidlPath() - * Create a string that includes the Drive name, the folder text and - * the value text. - * - * RETURNS - * strlen(lpszOut) - */ -DWORD WINAPI _ILGetPidlPath( LPCITEMIDLIST pidl, LPSTR lpszOut, DWORD dwOutSize) -{ int len = 0; - LPSTR lpszTemp = lpszOut; - - TRACE_(pidl)("(%p,%lu)\n",lpszOut,dwOutSize); - - if(!lpszOut) - { return 0; - } - - *lpszOut = 0; - - len = _ILGetFolderText(pidl, lpszOut, dwOutSize); - - lpszOut += len; - strcpy (lpszOut,"\\"); - len++; lpszOut++; dwOutSize -= len; - - len += _ILGetValueText(pidl, lpszOut, dwOutSize ); - - /*remove the last backslash if necessary */ - if( lpszTemp[len-1]=='\\') - { lpszTemp[len-1] = 0; - len--; - } - - TRACE_(pidl)("-- (%p=%s,%u)\n",lpszTemp,lpszTemp,len); - - return len; +LPITEMIDLIST WINAPI _ILCreateSpecial(LPCSTR szGUID) +{ + IID iid; + CLSIDFromString16(szGUID,&iid); + return _ILCreate(PT_MYCOMP, &iid, sizeof(IID)); } /************************************************************************** @@ -1081,16 +1133,18 @@ LPITEMIDLIST WINAPI _ILCreate(PIDLTYPE type, LPCVOID pIn, UINT16 uInSize) case PT_MYCOMP: uSize = 2 + 2 + sizeof(GUID); pidlOut = SHAlloc(uSize + 2); + ZeroMemory(pidlOut, uSize + 2); pidlOut->mkid.cb = uSize; pData =_ILGetDataPointer(pidlOut); pData->type = type; memcpy(&(pData->u.mycomp.guid), pIn, uInSize); - TRACE_(pidl)("- create My Computer\n"); + TRACE_(pidl)("- create GUID-pidl\n"); break; case PT_DRIVE: uSize = 2 + 23; pidlOut = SHAlloc(uSize + 2); + ZeroMemory(pidlOut, uSize + 2); pidlOut->mkid.cb = uSize; pData =_ILGetDataPointer(pidlOut); pData->type = type; @@ -1103,6 +1157,7 @@ LPITEMIDLIST WINAPI _ILCreate(PIDLTYPE type, LPCVOID pIn, UINT16 uInSize) case PT_VALUE: uSize = 2 + 12 + uInSize; pidlOut = SHAlloc(uSize + 2); + ZeroMemory(pidlOut, uSize + 2); pidlOut->mkid.cb = uSize; pData =_ILGetDataPointer(pidlOut); pData->type = type; @@ -1119,52 +1174,187 @@ LPITEMIDLIST WINAPI _ILCreate(PIDLTYPE type, LPCVOID pIn, UINT16 uInSize) TRACE_(pidl)("-- (pidl=%p, size=%u)\n", pidlOut, uSize); return pidlOut; } + /************************************************************************** - * _ILGetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16) + * _ILGetDrive() + * + * Gets the text for the drive eg. 'c:\' * * RETURNS - * length of data (raw) + * strlen (lpszText) */ -DWORD WINAPI _ILGetData(PIDLTYPE type, LPCITEMIDLIST pidl, LPVOID pOut, UINT uOutSize) -{ LPPIDLDATA pData; - DWORD dwReturn=0; - LPSTR pszSrc; - - TRACE_(pidl)("(%x %p %p %x)\n",type,pidl,pOut,uOutSize); - - if( (!pidl) || (!pOut) || (uOutSize < 1)) - { return 0; +DWORD WINAPI _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize) +{ TRACE_(pidl)("(%p,%p,%u)\n",pidl,pOut,uSize); + + if(_ILIsMyComputer(pidl)) + pidl = ILGetNext(pidl); + + if (pidl && _ILIsDrive(pidl)) + return _ILSimpleGetText(pidl, pOut, uSize); + + return 0; +} + +/************************************************************************** + * + * ### 2. section testing pidls ### + * + ************************************************************************** + * _ILIsDesktop() + * _ILIsMyComputer() + * _ILIsSpecialFolder() + * _ILIsDrive() + * _ILIsFolder() + * _ILIsValue() + * _ILIsPidlSimple() + */ +BOOL WINAPI _ILIsDesktop(LPCITEMIDLIST pidl) +{ TRACE_(pidl)("(%p)\n",pidl); + return ( !pidl || (pidl && pidl->mkid.cb == 0x00) ); +} + +BOOL WINAPI _ILIsMyComputer(LPCITEMIDLIST pidl) +{ + REFIID iid = _ILGetGUIDPointer(pidl); + + TRACE_(pidl)("(%p)\n",pidl); + + if (iid) + return IsEqualIID(iid, &IID_MyComputer); + return FALSE; +} + +BOOL WINAPI _ILIsSpecialFolder (LPCITEMIDLIST pidl) +{ + LPPIDLDATA lpPData = _ILGetDataPointer(pidl); + TRACE_(pidl)("(%p)\n",pidl); + return (pidl && ( (lpPData && (PT_MYCOMP== lpPData->type || PT_SPECIAL== lpPData->type)) || + (pidl && pidl->mkid.cb == 0x00) + )); +} + +BOOL WINAPI _ILIsDrive(LPCITEMIDLIST pidl) +{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl); + TRACE_(pidl)("(%p)\n",pidl); + return (pidl && lpPData && (PT_DRIVE == lpPData->type || + PT_DRIVE1 == lpPData->type || + PT_DRIVE2 == lpPData->type || + PT_DRIVE3 == lpPData->type)); +} + +BOOL WINAPI _ILIsFolder(LPCITEMIDLIST pidl) +{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl); + TRACE_(pidl)("(%p)\n",pidl); + return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type)); +} + +BOOL WINAPI _ILIsValue(LPCITEMIDLIST pidl) +{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl); + TRACE_(pidl)("(%p)\n",pidl); + return (pidl && lpPData && PT_VALUE == lpPData->type); +} + +/************************************************************************** + * _ILIsPidlSimple + */ +BOOL WINAPI _ILIsPidlSimple ( LPCITEMIDLIST pidl) +{ + BOOL ret = TRUE; + + if(! _ILIsDesktop(pidl)) /* pidl=NULL or mkid.cb=0 */ + { + WORD len = pidl->mkid.cb; + LPCITEMIDLIST pidlnext = (LPCITEMIDLIST) (((LPBYTE)pidl) + len ); + if (pidlnext->mkid.cb) + ret = FALSE; } - *(LPSTR)pOut = 0; + TRACE_(pidl)("%s\n", ret ? "Yes" : "No"); + return ret; +} + +/************************************************************************** + * + * ### 3. section getting values from pidls ### + */ + + /************************************************************************** + * _ILSimpleGetText + * + * gets the text for the first item in the pidl (eg. simple pidl) + * + * returns the lenght of the string + */ +DWORD WINAPI _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize) +{ + LPPIDLDATA pData; + DWORD dwReturn=0; + LPSTR szSrc; + GUID const * riid; + char szTemp[MAX_PATH]; + + TRACE_(pidl)("(%p %p %x)\n",pidl,szOut,uOutSize); + + if (!pidl) return 0; + + if (szOut) + *szOut = 0; pData = _ILGetDataPointer(pidl); - assert ( pData->type == type); + if (!pData) + { + /* desktop */ + if (HCR_GetClassName(&CLSID_ShellDesktop, szTemp, MAX_PATH)) + { + if (szOut) + lstrcpynA(szOut, szTemp, uOutSize); - pszSrc = _ILGetTextPointer(pData->type, pData); + dwReturn = strlen (szTemp); + } + } + else if (( szSrc = _ILGetTextPointer(pData->type, pData) )) + { + /* filesystem */ + if (szOut) + lstrcpynA(szOut, szSrc, MAX_PATH); - if (pszSrc) - { strncpy((LPSTR)pOut, pszSrc, uOutSize); - dwReturn = strlen((LPSTR)pOut)+1; + dwReturn = strlen(szSrc); + } + else if (( riid = _ILGetGUIDPointer(pidl) )) + { + /* special folder */ + if ( HCR_GetClassName(riid, szTemp, MAX_PATH) ) + { + if (szOut) + lstrcpynA(szOut, szTemp, uOutSize); + + dwReturn = strlen (szTemp); + } } else - { ERR_(pidl)("-- no data\n"); + { + ERR_(pidl)("-- no text\n"); } - TRACE_(pidl)("-- (%p=%s 0x%08lx)\n",pOut,(char*)pOut,dwReturn); + TRACE_(pidl)("-- (%p=%s 0x%08lx)\n",szOut,(char*)szOut,dwReturn); return dwReturn; } - /************************************************************************** + * + * ### 4. getting pointers to parts of pidls ### + * + ************************************************************************** * _ILGetDataPointer() */ LPPIDLDATA WINAPI _ILGetDataPointer(LPITEMIDLIST pidl) -{ if(pidl && pidl->mkid.cb != 0x00) - return (LPPIDLDATA)(&pidl->mkid.abID); +{ + if(pidl && pidl->mkid.cb != 0x00) + return (LPPIDLDATA) &(pidl->mkid.abID); return NULL; } + /************************************************************************** * _ILGetTextPointer() * gets a pointer to the long filename string stored in the pidl @@ -1177,18 +1367,17 @@ LPSTR WINAPI _ILGetTextPointer(PIDLTYPE type, LPPIDLDATA pidldata) } switch (type) - { case PT_DRIVE: + { + case PT_MYCOMP: + case PT_SPECIAL: + return NULL; + + case PT_DRIVE: case PT_DRIVE1: case PT_DRIVE2: case PT_DRIVE3: return (LPSTR)&(pidldata->u.drive.szDriveName); - case PT_MYCOMP: - return szMyComp; - - case PT_SPECIAL: - return szNetHood; - case PT_FOLDER: case PT_FOLDER1: case PT_VALUE: @@ -1203,26 +1392,51 @@ LPSTR WINAPI _ILGetTextPointer(PIDLTYPE type, LPPIDLDATA pidldata) } return NULL; } + /************************************************************************** * _ILGetSTextPointer() - * gets a pointer to the long filename string stored in the pidl + * gets a pointer to the short filename string stored in the pidl */ LPSTR WINAPI _ILGetSTextPointer(PIDLTYPE type, LPPIDLDATA pidldata) {/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/ if(!pidldata) - { return NULL; - } + return NULL; + switch (type) - { case PT_FOLDER: + { + case PT_FOLDER: case PT_VALUE: case PT_IESPECIAL: return (LPSTR)(pidldata->u.file.szNames + strlen (pidldata->u.file.szNames) + 1); + case PT_WORKGRP: return (LPSTR)(pidldata->u.network.szNames + strlen (pidldata->u.network.szNames) + 1); } return NULL; } + +/************************************************************************** + * _ILGetGUIDPointer() + * + * returns reference to guid stored in some pidls + */ +REFIID WINAPI _ILGetGUIDPointer(LPCITEMIDLIST pidl) +{ + LPPIDLDATA pdata =_ILGetDataPointer(pidl); + + if (pdata) + { + switch (pdata->type) + { + case PT_SPECIAL: + case PT_MYCOMP: + return (REFIID) &(pdata->u.mycomp.guid); + } + } + return NULL; +} + BOOL WINAPI _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize) { LPPIDLDATA pdata =_ILGetDataPointer(pidl); FILETIME ft; @@ -1241,9 +1455,9 @@ BOOL WINAPI _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize) FileTimeToSystemTime (&ft, &time); return GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL, pOut, uOutSize); } + BOOL WINAPI _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize) { LPPIDLDATA pdata =_ILGetDataPointer(pidl); - char stemp[20]; /* for filesize */ switch (pdata->type) { case PT_VALUE: @@ -1251,29 +1465,33 @@ BOOL WINAPI _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize) default: return FALSE; } - StrFormatByteSizeA(pdata->u.file.dwFileSize, stemp, 20); - strncpy( pOut, stemp, 20); + StrFormatByteSizeA(pdata->u.file.dwFileSize, pOut, uOutSize); return TRUE; } BOOL WINAPI _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize) -{ char pTemp[MAX_PATH]; +{ + char szTemp[MAX_PATH]; const char * pPoint; - + LPITEMIDLIST pidlTemp=pidl; + TRACE_(pidl)("pidl=%p\n",pidl); - if ( ! _ILGetValueText(pidl, pTemp, MAX_PATH)) - { return FALSE; - } + if (!pidl) return FALSE; + + pidlTemp = ILFindLastID(pidl); + + if (!_ILIsValue(pidlTemp)) return FALSE; + if (!_ILSimpleGetText(pidlTemp, szTemp, MAX_PATH)) return FALSE; - pPoint = PathFindExtensionA(pTemp); + pPoint = PathFindExtensionA(szTemp); - if (! *pPoint) - return FALSE; + if (! *pPoint) return FALSE; pPoint++; - strncpy(pOut, pPoint, uOutSize); + lstrcpynA(pOut, pPoint, uOutSize); TRACE_(pidl)("%s\n",pOut); return TRUE; } + diff --git a/dlls/shell32/pidl.h b/dlls/shell32/pidl.h index 074933243d8..bc2bcf7570b 100644 --- a/dlls/shell32/pidl.h +++ b/dlls/shell32/pidl.h @@ -32,7 +32,7 @@ * drive 0x23/25 drive (usual) * drive 0x25/25 drive (lnk/persistant) * drive 0x29/25 drive -* control/printer 0x2E +* shell extension 0x2E mycomp * drive 0x2F drive (lnk/persistant) * folder/file 0x30 folder/file (1) (lnk/persistant) * folder 0x31 folder (usual) @@ -40,8 +40,9 @@ * workgroup 0x41 network (3) * computer 0x42 network (4) * whole network 0x47 network (5) +* MSITStore 0x61 htmlhlp (7) * history/favorites 0xb1 file -* share 0xc3 metwork (6) +* share 0xc3 network (6) * * guess: the persistant elements are non tracking * @@ -51,6 +52,8 @@ * (4) one string "\\sirius" * (5) one string "whole network" * (6) one string "\\sirius\c" +* (7) contains string "mk:@MSITStore:C:\path\file.chm::/path/filename.htm" +* GUID 871C5380-42A0-1069-A2EA-08002B30309D */ #define PT_DESKTOP 0x00 /* internal */ @@ -76,8 +79,9 @@ typedef struct tagPIDLDATA { PIDLTYPE type; /*00*/ union { struct - { BYTE dummy; - GUID guid; + { BYTE dummy; /*01*/ + GUID guid; /*02*/ + BYTE dummy1; /*18*/ } mycomp; struct { CHAR szDriveName[20]; /*01*/ @@ -98,6 +102,11 @@ typedef struct tagPIDLDATA { WORD dummy; /*01*/ CHAR szNames[1]; /*03*/ } network; + struct + { WORD dummy; /*01*/ + DWORD dummy1; /*02*/ + CHAR szName[1]; /*06*/ /* teminated by 0x00 0x00 */ + } htmlhelp; }u; } PIDLDATA, *LPPIDLDATA; #include "poppack.h" @@ -108,10 +117,12 @@ typedef struct tagPIDLDATA * return value is strlen() */ DWORD WINAPI _ILGetDrive(LPCITEMIDLIST,LPSTR,UINT16); +/* DWORD WINAPI _ILGetItemText(LPCITEMIDLIST,LPSTR,UINT16); DWORD WINAPI _ILGetFolderText(LPCITEMIDLIST,LPSTR,DWORD); DWORD WINAPI _ILGetValueText(LPCITEMIDLIST,LPSTR,DWORD); DWORD WINAPI _ILGetPidlPath(LPCITEMIDLIST,LPSTR,DWORD); +*/ /* * getting special values from simple pidls @@ -129,22 +140,22 @@ BOOL WINAPI _ILIsMyComputer(LPCITEMIDLIST); BOOL WINAPI _ILIsDrive(LPCITEMIDLIST); BOOL WINAPI _ILIsFolder(LPCITEMIDLIST); BOOL WINAPI _ILIsValue(LPCITEMIDLIST); +BOOL WINAPI _ILIsSpecialFolder (LPCITEMIDLIST pidl); +BOOL WINAPI _ILIsPidlSimple ( LPCITEMIDLIST pidl); /* * simple pidls from strings */ LPITEMIDLIST WINAPI _ILCreateDesktop(void); LPITEMIDLIST WINAPI _ILCreateMyComputer(void); +LPITEMIDLIST WINAPI _ILCreateIExplore(void); LPITEMIDLIST WINAPI _ILCreateDrive(LPCSTR); -LPITEMIDLIST WINAPI _ILCreateFolder(LPCSTR, LPCSTR); -LPITEMIDLIST WINAPI _ILCreateValue(LPCSTR, LPCSTR); +LPITEMIDLIST WINAPI _ILCreateFolder(WIN32_FIND_DATAA * stffile); +LPITEMIDLIST WINAPI _ILCreateValue(WIN32_FIND_DATAA * stffile); +LPITEMIDLIST WINAPI _ILCreateSpecial(LPCSTR szGUID); + +DWORD WINAPI _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize); -/* - * raw pidl handling (binary) - * - * data is binary / sizes are bytes - */ -DWORD WINAPI _ILGetData(PIDLTYPE,LPCITEMIDLIST,LPVOID,UINT); LPITEMIDLIST WINAPI _ILCreate(PIDLTYPE,LPCVOID,UINT16); /* @@ -153,8 +164,7 @@ LPITEMIDLIST WINAPI _ILCreate(PIDLTYPE,LPCVOID,UINT16); LPPIDLDATA WINAPI _ILGetDataPointer(LPCITEMIDLIST); LPSTR WINAPI _ILGetTextPointer(PIDLTYPE type, LPPIDLDATA pidldata); LPSTR WINAPI _ILGetSTextPointer(PIDLTYPE type, LPPIDLDATA pidldata); - -LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2); +REFIID WINAPI _ILGetGUIDPointer(LPCITEMIDLIST pidl); void pdump (LPCITEMIDLIST pidl); BOOL pcheck (LPCITEMIDLIST pidl); diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c index 3ae46b64bcd..ffbcf875267 100644 --- a/dlls/shell32/shell32_main.c +++ b/dlls/shell32/shell32_main.c @@ -21,10 +21,11 @@ #include "shellapi.h" #include "pidl.h" + #include "shlobj.h" #include "shell32_main.h" - #include "shlguid.h" +#include "wine/undocshell.h" DECLARE_DEBUG_CHANNEL(exec) DECLARE_DEBUG_CHANNEL(shell) @@ -126,7 +127,7 @@ DWORD WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes, * NULL on the desktop folder. */ if (_ILIsDesktop((LPCITEMIDLIST)path)) - { psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK; + { psfi->dwAttributes = 0xb0000154; ret = TRUE; } else @@ -134,19 +135,17 @@ DWORD WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes, switch (pData->type) { case PT_DESKTOP: - psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK; + psfi->dwAttributes = 0xb0000154; case PT_MYCOMP: - psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | - SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK ; + psfi->dwAttributes = 0xb0000154; case PT_SPECIAL: - psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CAPABILITYMASK; + psfi->dwAttributes = 0xa0000000; case PT_DRIVE: - psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | - SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANLINK; + psfi->dwAttributes = 0xf0000144; case PT_FOLDER: - psfi->dwAttributes = SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_CAPABILITYMASK; + psfi->dwAttributes = 0xe0000177; case PT_VALUE: - psfi->dwAttributes = SFGAO_FILESYSTEM | SFGAO_CAPABILITYMASK; + psfi->dwAttributes = 0x40000177; } ret=TRUE; } @@ -164,11 +163,14 @@ DWORD WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes, } if (flags & SHGFI_DISPLAYNAME) - { if (flags & SHGFI_PIDL) - { strcpy(psfi->szDisplayName,szTemp); + { + if (flags & SHGFI_PIDL) + { + _ILSimpleGetText(ILFindLastID(pPidlTemp), psfi->szDisplayName, MAX_PATH); } else - { strcpy(psfi->szDisplayName,path); + { + lstrcpynA(psfi->szDisplayName,PathFindFilenameA(path), MAX_PATH); } TRACE_(shell)("displayname=%s\n", psfi->szDisplayName); ret=TRUE; @@ -391,292 +393,6 @@ UINT WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data) return 0; } - -/************************************************************************* - * SHGetDesktopFolder [SHELL32.216] - * - * SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with - * CLSID_ShellDesktop - * CoCreateInstance(CLSID_Desktop, NULL, CLSCTX_INPROC, IID_IShellFolder, &pshf); - * - * RETURNS - * the interface to the shell desktop folder. - * - * FIXME - * the pdesktopfolder has to be released at the end (at dll unloading???) - */ -LPSHELLFOLDER pdesktopfolder=NULL; - -DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder) -{ HRESULT hres = E_OUTOFMEMORY; - LPCLASSFACTORY lpclf; - TRACE_(shell)("%p->(%p)\n",shellfolder,*shellfolder); - - if (pdesktopfolder) - { hres = NOERROR; - } - else - { lpclf = IClassFactory_Constructor(&CLSID_ShellDesktop); - if(lpclf) - { hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder); - IClassFactory_Release(lpclf); - } - } - - if (pdesktopfolder) - { *shellfolder = pdesktopfolder; - IShellFolder_AddRef(pdesktopfolder); - } - else - { *shellfolder=NULL; - } - - TRACE_(shell)("-- %p->(%p)\n",shellfolder, *shellfolder); - return hres; -} - -/************************************************************************* - * SHGetSpecialFolderLocation [SHELL32.223] - * - * gets the folder locations from the registry and creates a pidl - * creates missing reg keys and directorys - * - * PARAMS - * hwndOwner [I] - * nFolder [I] CSIDL_xxxxx - * ppidl [O] PIDL of a special folder - * - * RETURNS - * HResult - * - * FIXME - * - look for "User Shell Folder" first - * - */ -HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST * ppidl) -{ LPSHELLFOLDER shellfolder; - DWORD pchEaten, tpathlen=MAX_PATH, type, dwdisp, res, dwLastError; - CHAR pszTemp[256], buffer[256], tpath[MAX_PATH], npath[MAX_PATH]; - LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0]; - HKEY key; - - enum - { FT_UNKNOWN= 0x00000000, - FT_DIR= 0x00000001, - FT_DESKTOP= 0x00000002, - FT_SPECIAL= 0x00000003 - } tFolder; - - TRACE_(shell)("(%04x,0x%x,%p)\n", hwndOwner,nFolder,ppidl); - - strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\"); - - res=RegCreateKeyExA(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp); - if (res) - { ERR_(shell)("Could not create key %s %08lx \n",buffer,res); - return E_OUTOFMEMORY; - } - - tFolder=FT_DIR; - switch (nFolder) - { case CSIDL_BITBUCKET: - strcpy (buffer,"xxx"); /*not in the registry*/ - TRACE_(shell)("looking for Recycler\n"); - tFolder=FT_UNKNOWN; - break; - case CSIDL_CONTROLS: - strcpy (buffer,"xxx"); /*virtual folder*/ - TRACE_(shell)("looking for Control\n"); - tFolder=FT_UNKNOWN; - break; - case CSIDL_DESKTOP: - strcpy (buffer,"xxx"); /*virtual folder*/ - TRACE_(shell)("looking for Desktop\n"); - tFolder=FT_DESKTOP; - break; - case CSIDL_DESKTOPDIRECTORY: - case CSIDL_COMMON_DESKTOPDIRECTORY: - strcpy (buffer,"Desktop"); - break; - case CSIDL_DRIVES: - strcpy (buffer,"xxx"); /*virtual folder*/ - TRACE_(shell)("looking for Drives\n"); - tFolder=FT_SPECIAL; - break; - case CSIDL_FONTS: - strcpy (buffer,"Fonts"); - break; - case CSIDL_NETHOOD: - strcpy (buffer,"NetHood"); - break; - case CSIDL_PRINTHOOD: - strcpy (buffer,"PrintHood"); - break; - case CSIDL_NETWORK: - strcpy (buffer,"xxx"); /*virtual folder*/ - TRACE_(shell)("looking for Network\n"); - tFolder=FT_UNKNOWN; - break; - case CSIDL_APPDATA: - strcpy (buffer,"Appdata"); - break; - case CSIDL_PERSONAL: - strcpy (buffer,"Personal"); - break; - case CSIDL_FAVORITES: - strcpy (buffer,"Favorites"); - break; - case CSIDL_PRINTERS: - strcpy (buffer,"PrintHood"); - break; - case CSIDL_COMMON_PROGRAMS: - case CSIDL_PROGRAMS: - strcpy (buffer,"Programs"); - break; - case CSIDL_RECENT: - strcpy (buffer,"Recent"); - break; - case CSIDL_SENDTO: - strcpy (buffer,"SendTo"); - break; - case CSIDL_COMMON_STARTMENU: - case CSIDL_STARTMENU: - strcpy (buffer,"Start Menu"); - break; - case CSIDL_COMMON_STARTUP: - case CSIDL_STARTUP: - strcpy (buffer,"Startup"); - break; - case CSIDL_TEMPLATES: - strcpy (buffer,"Templates"); - break; - case CSIDL_INTERNET_CACHE: - strcpy (buffer,"Cache"); - break; - case CSIDL_HISTORY: - strcpy (buffer,"History"); - break; - case CSIDL_COOKIES: - strcpy(buffer,"Cookies"); - break; - default: - ERR_(shell)("unknown CSIDL 0x%08x\n", nFolder); - tFolder=FT_UNKNOWN; - break; - } - - TRACE_(shell)("Key=%s\n",buffer); - - type=REG_SZ; - - switch (tFolder) - { case FT_DIR: - /* Directory: get the value from the registry, if its not there - create it and the directory*/ - if (RegQueryValueExA(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen)) - { GetWindowsDirectoryA(npath,MAX_PATH); - PathAddBackslashA(npath); - switch (nFolder) - { case CSIDL_DESKTOPDIRECTORY: - case CSIDL_COMMON_DESKTOPDIRECTORY: - strcat (npath,"Desktop"); - break; - case CSIDL_FONTS: - strcat (npath,"Fonts"); - break; - case CSIDL_NETHOOD: - strcat (npath,"NetHood"); - break; - case CSIDL_PRINTHOOD: - strcat (npath,"PrintHood"); - break; - case CSIDL_APPDATA: - strcat (npath,"Appdata"); - break; - case CSIDL_PERSONAL: - strcpy (npath,"C:\\Personal"); - break; - case CSIDL_FAVORITES: - strcat (npath,"Favorites"); - break; - case CSIDL_PRINTERS: - strcat (npath,"PrintHood"); - break; - case CSIDL_COMMON_PROGRAMS: - case CSIDL_PROGRAMS: - strcat (npath,"Start Menu"); - CreateDirectoryA(npath,NULL); - strcat (npath,"\\Programs"); - break; - case CSIDL_RECENT: - strcat (npath,"Recent"); - break; - case CSIDL_SENDTO: - strcat (npath,"SendTo"); - break; - case CSIDL_COMMON_STARTMENU: - case CSIDL_STARTMENU: - strcat (npath,"Start Menu"); - break; - case CSIDL_COMMON_STARTUP: - case CSIDL_STARTUP: - strcat (npath,"Start Menu"); - CreateDirectoryA(npath,NULL); - strcat (npath,"\\Startup"); - break; - case CSIDL_TEMPLATES: - strcat (npath,"Templates"); - break; - case CSIDL_INTERNET_CACHE: - strcat(npath,"Temporary Internet Files"); - break; - case CSIDL_HISTORY: - strcat (npath,"History"); - break; - case CSIDL_COOKIES: - strcat (npath,"Cookies"); - break; - default: - RegCloseKey(key); - return E_OUTOFMEMORY; - } - if (RegSetValueExA(key,buffer,0,REG_SZ,(LPBYTE)npath,sizeof(npath)+1)) - { ERR_(shell)("could not create value %s\n",buffer); - RegCloseKey(key); - return E_OUTOFMEMORY; - } - TRACE_(shell)("value %s=%s created\n",buffer,npath); - dwLastError = GetLastError(); - CreateDirectoryA(npath,NULL); - SetLastError (dwLastError); - strcpy(tpath,npath); - } - break; - case FT_DESKTOP: - strcpy (tpath,"Desktop"); - break; - case FT_SPECIAL: - if (nFolder==CSIDL_DRIVES) - strcpy (tpath,"My Computer"); - break; - default: - RegCloseKey(key); - return E_OUTOFMEMORY; - } - - RegCloseKey(key); - - TRACE_(shell)("Value=%s\n",tpath); - LocalToWideChar(lpszDisplayName, tpath, 256); - - if (SHGetDesktopFolder(&shellfolder)==S_OK) - { IShellFolder_ParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL); - IShellFolder_Release(shellfolder); - } - - TRACE_(shell)("-- (new pidl %p)\n",*ppidl); - return NOERROR; -} /************************************************************************* * SHHelpShortcuts_RunDLL [SHELL32.224] * @@ -940,88 +656,6 @@ void WINAPI FreeIconList( DWORD dw ) { FIXME_(shell)("(%lx): stub\n",dw); } -/************************************************************************* - * SHGetPathFromIDListA [SHELL32.261][NT 4.0: SHELL32.220] - * - * PARAMETERS - * pidl, [IN] pidl - * pszPath [OUT] path - * - * RETURNS - * path from a passed PIDL. - * - * NOTES - * exported by name - * - * FIXME - * fnGetDisplayNameOf can return different types of OLEString - */ -DWORD WINAPI SHGetPathFromIDListA (LPCITEMIDLIST pidl,LPSTR pszPath) -{ STRRET lpName; - LPSHELLFOLDER shellfolder; - CHAR buffer[MAX_PATH],tpath[MAX_PATH]; - DWORD type,tpathlen=MAX_PATH,dwdisp; - HKEY key; - - TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath); - - if (!pidl) - { strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\"); - - if (RegCreateKeyExA(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp)) - { return E_OUTOFMEMORY; - } - type=REG_SZ; - strcpy (buffer,"Desktop"); /*registry name*/ - if ( RegQueryValueExA(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen)) - { GetWindowsDirectoryA(tpath,MAX_PATH); - PathAddBackslashA(tpath); - strcat (tpath,"Desktop"); /*folder name*/ - RegSetValueExA(key,buffer,0,REG_SZ,(LPBYTE)tpath,tpathlen); - CreateDirectoryA(tpath,NULL); - } - RegCloseKey(key); - strcpy(pszPath,tpath); - } - else - { if (SHGetDesktopFolder(&shellfolder)==S_OK) - { IShellFolder_GetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName); - IShellFolder_Release(shellfolder); - } - strcpy(pszPath,lpName.u.cStr); - } - TRACE_(shell)("-- (%s)\n",pszPath); - - return TRUE; -} -/************************************************************************* - * SHGetPathFromIDListW [SHELL32.262] - */ -DWORD WINAPI SHGetPathFromIDListW (LPCITEMIDLIST pidl,LPWSTR pszPath) -{ char sTemp[MAX_PATH]; - - TRACE_(shell)("(pidl=%p)\n", pidl); - - SHGetPathFromIDListA (pidl, sTemp); - lstrcpyAtoW(pszPath, sTemp); - - TRACE_(shell)("-- (%s)\n",debugstr_w(pszPath)); - - return TRUE; -} - -/************************************************************************* - * SHGetPathFromIDListAW [SHELL32.221][NT 4.0: SHELL32.219] - */ -BOOL WINAPI SHGetPathFromIDListAW(LPCITEMIDLIST pidl,LPVOID pszPath) -{ - TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath); - - if (VERSION_OsIsUnicode()) - return SHGetPathFromIDListW(pidl,pszPath); - return SHGetPathFromIDListA(pidl,pszPath); -} - /*********************************************************************** * DllGetVersion [COMCTL32.25] * @@ -1068,6 +702,7 @@ HIMAGELIST (WINAPI * pImageList_Create) (INT,INT,UINT,INT,INT); BOOL (WINAPI* pImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle); HICON (WINAPI * pImageList_GetIcon) (HIMAGELIST, INT, UINT); INT (WINAPI* pImageList_GetImageCount)(HIMAGELIST); +COLORREF (WINAPI *pImageList_SetBkColor)(HIMAGELIST, COLORREF); LPVOID (WINAPI* pCOMCTL32_Alloc) (INT); BOOL (WINAPI* pCOMCTL32_Free) (LPVOID); @@ -1127,7 +762,8 @@ BOOL WINAPI Shell32LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) pImageList_GetIcon=(void*)GetProcAddress(hComctl32,"ImageList_GetIcon"); pImageList_GetImageCount=(void*)GetProcAddress(hComctl32,"ImageList_GetImageCount"); pImageList_Draw=(void*)GetProcAddress(hComctl32,"ImageList_Draw"); - + pImageList_SetBkColor=(void*)GetProcAddress(hComctl32,"ImageList_SetBkColor"); + /* imports by ordinal, pray that it works*/ pCOMCTL32_Alloc=(void*)GetProcAddress(hComctl32, (LPCSTR)71L); pCOMCTL32_Free=(void*)GetProcAddress(hComctl32, (LPCSTR)73L); diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h index a24f3706fd7..7a7ef036604 100644 --- a/dlls/shell32/shell32_main.h +++ b/dlls/shell32/shell32_main.h @@ -36,6 +36,7 @@ extern HIMAGELIST (WINAPI* pImageList_Create) (INT,INT,UINT,INT,INT); extern BOOL (WINAPI* pImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle); extern HICON (WINAPI* pImageList_GetIcon) (HIMAGELIST, INT, UINT); extern INT (WINAPI* pImageList_GetImageCount)(HIMAGELIST); +extern COLORREF (WINAPI *pImageList_SetBkColor)(HIMAGELIST, COLORREF); extern LPVOID (WINAPI* pCOMCTL32_Alloc) (INT); extern BOOL (WINAPI* pCOMCTL32_Free) (LPVOID); @@ -52,23 +53,6 @@ extern LPVOID (WINAPI* pDPA_DeletePtr) (const HDPA hdpa, INT i); extern HICON (WINAPI *pLookupIconIdFromDirectoryEx)(LPBYTE dir, BOOL bIcon, INT width, INT height, UINT cFlag); extern HICON (WINAPI *pCreateIconFromResourceEx)(LPBYTE bits,UINT cbSize, BOOL bIcon, DWORD dwVersion, INT width, INT height,UINT cFlag); -/* undocumented WINAPI functions not globaly exported */ -LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl); -LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl); -LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST iil1,LPCITEMIDLIST iil2); -LPITEMIDLIST WINAPI ILFindLastID(LPITEMIDLIST pidl); -DWORD WINAPI ILGetSize(LPITEMIDLIST pidl); -BOOL WINAPI ILGetDisplayName(LPCITEMIDLIST pidl,LPSTR path); -DWORD WINAPI ILFree(LPITEMIDLIST pidl); - -HRESULT WINAPI SHILCreateFromPathA (LPSTR path, LPITEMIDLIST * ppidl, DWORD attributes); -HRESULT WINAPI SHILCreateFromPathW (LPWSTR path, LPITEMIDLIST * ppidl, DWORD attributes); -HRESULT WINAPI SHILCreateFromPathAW (LPVOID path, LPITEMIDLIST * ppidl, DWORD attributes); - -LPITEMIDLIST WINAPI ILCreateFromPathA(LPSTR path); -LPITEMIDLIST WINAPI ILCreateFromPathW(LPWSTR path); -LPITEMIDLIST WINAPI ILCreateFromPathAW(LPVOID path); - BOOL WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList); HRESULT WINAPI StrRetToStrN (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl); @@ -82,43 +66,51 @@ BOOL PidlToSicIndex (IShellFolder * sh, LPITEMIDLIST pidl, BOOL bBigIcon, UINT * BOOL HCR_MapTypeToValue ( LPCSTR szExtension, LPSTR szFileType, DWORD len); BOOL HCR_GetExecuteCommand ( LPCSTR szClass, LPCSTR szVerb, LPSTR szDest, DWORD len ); BOOL HCR_GetDefaultIcon (LPCSTR szClass, LPSTR szDest, DWORD len, LPDWORD dwNr); +BOOL HCR_GetClassName (REFIID riid, LPSTR szDest, DWORD len); +BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest); -DWORD WINAPI ParseFieldA(LPCSTR src,DWORD field,LPSTR dst,DWORD len); +DWORD WINAPI ParseFieldA(LPCSTR src,DWORD field,LPSTR dst,DWORD len); HGLOBAL WINAPI SHAllocShared(LPVOID psrc, DWORD size, DWORD procID); -LPVOID WINAPI SHLockShared(HANDLE hmem, DWORD procID); -BOOL WINAPI SHUnlockShared(HANDLE pmem); +LPVOID WINAPI SHLockShared(HANDLE hmem, DWORD procID); +BOOL WINAPI SHUnlockShared(HANDLE pmem); HANDLE WINAPI SHFreeShared(HANDLE hmem, DWORD procID); /**************************************************************************** * Class constructors */ -extern LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner, LPSHELLFOLDER psf, LPITEMIDLIST * apidl, UINT cidl); -extern LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT, const FORMATETC []); +LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner, LPITEMIDLIST myPidl, LPITEMIDLIST * apidl, UINT cidl); +LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT, const FORMATETC []); -extern LPCLASSFACTORY IClassFactory_Constructor(REFCLSID); -extern LPCONTEXTMENU IContextMenu_Constructor(LPSHELLFOLDER, LPCITEMIDLIST *, UINT); -extern LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER, LPCITEMIDLIST); -extern LPSHELLLINK IShellLink_Constructor(BOOL); -extern LPENUMIDLIST IEnumIDList_Constructor(LPCSTR,DWORD); -extern LPEXTRACTICONA IExtractIconA_Constructor(LPITEMIDLIST); -extern HRESULT CreateStreamOnFile (LPCSTR pszFilename, IStream ** ppstm); +LPCLASSFACTORY IClassFactory_Constructor(REFCLSID); +IContextMenu * IContextMenu_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, LPCITEMIDLIST *aPidls, UINT uItemCount); +IContextMenu * ISvBgCm_Constructor(void); +LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER); +LPSHELLLINK IShellLink_Constructor(BOOL); + +IShellFolder * ISF_Desktop_Constructor(void); + +/* 3th parameter */ +#define EIDL_DESK 0 +#define EIDL_MYCOMP 1 +#define EIDL_FILE 2 + +LPENUMIDLIST IEnumIDList_Constructor(LPCSTR,DWORD,DWORD); + +LPEXTRACTICONA IExtractIconA_Constructor(LPITEMIDLIST); +HRESULT CreateStreamOnFile (LPCSTR pszFilename, IStream ** ppstm); /* fixme: rename the functions when the shell32.dll has it's own exports namespace */ HRESULT WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv); HRESULT WINAPI SHELL32_DllCanUnloadNow(void); +LRESULT WINAPI SHCoCreateInstance(LPSTR,REFCLSID,LPUNKNOWN,REFIID,LPVOID *); -/* elements of this structure are accessed directly from within shell32 */ -typedef struct -{ - ICOM_VTABLE(IShellFolder)* lpvtbl; - DWORD ref; - ICOM_VTABLE(IPersistFolder)* lpvtblPersistFolder; +/* fixme: move away */ +#define ResultFromShort(i) MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(i)) - LPSTR sMyPath; - LPITEMIDLIST pMyPidl; - LPITEMIDLIST mpidl; -} IGenericSFImpl; -extern LPSHELLFOLDER IShellFolder_Constructor(IGenericSFImpl*,LPITEMIDLIST); +/* menu merging */ +#define MM_ADDSEPARATOR 0x00000001L +#define MM_SUBMENUSHAVEIDS 0x00000002L +HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags); #endif diff --git a/dlls/shell32/shlmenu.c b/dlls/shell32/shlmenu.c index 861ec450359..a5cec39eb93 100644 --- a/dlls/shell32/shlmenu.c +++ b/dlls/shell32/shlmenu.c @@ -7,6 +7,7 @@ #include "wine/obj_base.h" #include "wine/obj_enumidlist.h" #include "wine/obj_shellfolder.h" +#include "wine/undocshell.h" #include "heap.h" #include "debugtools.h" @@ -111,7 +112,7 @@ static int FM_InitMenuPopup(HMENU hmenu, LPITEMIDLIST pAlternatePidl) MENUINFO MenuInfo; LPFMINFO menudata; - TRACE("\n"); + TRACE("0x%04x %p\n", hmenu, pAlternatePidl); MenuInfo.cbSize = sizeof(MENUINFO); MenuInfo.fMask = MIM_MENUDATA; @@ -765,26 +766,27 @@ BOOL _SHIsMenuSeparator(HMENU hm, int i) mii.fMask = MIIM_TYPE; mii.cch = 0; /* WARNING: We MUST initialize it to 0*/ if (!GetMenuItemInfoA(hm, i, TRUE, &mii)) - { return(FALSE); + { + return(FALSE); } if (mii.fType & MFT_SEPARATOR) - { return(TRUE); + { + return(TRUE); } - return(FALSE); + return(FALSE); } -#define MM_ADDSEPARATOR 0x00000001L -#define MM_SUBMENUSHAVEIDS 0x00000002L + HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags) { int nItem; HMENU hmSubMenu; BOOL bAlreadySeparated; - MENUITEMINFOA miiSrc; + MENUITEMINFOA miiSrc; char szName[256]; UINT uTemp, uIDMax = uIDAdjust; - FIXME("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx stub\n", + TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x 0x%04lx\n", hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags); if (!hmDst || !hmSrc) @@ -792,15 +794,20 @@ HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uI } nItem = GetMenuItemCount(hmDst); - if (uInsert >= (UINT)nItem) - { uInsert = (UINT)nItem; + + if (uInsert >= (UINT)nItem) /* insert position inside menu? */ + { + uInsert = (UINT)nItem; /* append on the end */ bAlreadySeparated = TRUE; } else - { bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);; + { + bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);; } + if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated) - { /* Add a separator between the menus */ + { + /* Add a separator between the menus */ InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); bAlreadySeparated = TRUE; } @@ -808,83 +815,104 @@ HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uI /* Go through the menu items and clone them*/ for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--) - { miiSrc.cbSize = sizeof(MENUITEMINFOA); - miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA; - /* We need to reset this every time through the loop in case - menus DON'T have IDs*/ + { + miiSrc.cbSize = sizeof(MENUITEMINFOA); + miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA; + + /* We need to reset this every time through the loop in case menus DON'T have IDs*/ miiSrc.fType = MFT_STRING; miiSrc.dwTypeData = szName; miiSrc.dwItemData = 0; miiSrc.cch = sizeof(szName); if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc)) - { continue; + { + continue; } + +/* TRACE("found menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmSrc, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask, miiSrc.hSubMenu); +*/ if (miiSrc.fType & MFT_SEPARATOR) - { /* This is a separator; don't put two of them in a row*/ + { + /* This is a separator; don't put two of them in a row */ if (bAlreadySeparated) - { continue; - } + continue; + bAlreadySeparated = TRUE; } else if (miiSrc.hSubMenu) - { if (uFlags & MM_SUBMENUSHAVEIDS) - { /* Adjust the ID and check it*/ - miiSrc.wID += uIDAdjust; - if (miiSrc.wID > uIDAdjustMax) - { continue; - } - if (uIDMax <= miiSrc.wID) - { uIDMax = miiSrc.wID + 1; - } + { + if (uFlags & MM_SUBMENUSHAVEIDS) + { + miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */ + + if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */ + continue; + + if (uIDMax <= miiSrc.wID) /* remember the highest ID */ + uIDMax = miiSrc.wID + 1; } else - { /* Don't set IDs for submenus that didn't have them already */ - miiSrc.fMask &= ~MIIM_ID; + { + miiSrc.fMask &= ~MIIM_ID; /* Don't set IDs for submenus that didn't have them already */ } hmSubMenu = miiSrc.hSubMenu; + miiSrc.hSubMenu = CreatePopupMenu(); - if (!miiSrc.hSubMenu) - { return(uIDMax); - } - uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags&MM_SUBMENUSHAVEIDS); + + if (!miiSrc.hSubMenu) return(uIDMax); + + uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS); + if (uIDMax <= uTemp) - { uIDMax = uTemp; - } + uIDMax = uTemp; + bAlreadySeparated = FALSE; } - else - { /* Adjust the ID and check it*/ - miiSrc.wID += uIDAdjust; - if (miiSrc.wID > uIDAdjustMax) - { continue; - } - if (uIDMax <= miiSrc.wID) - { uIDMax = miiSrc.wID + 1; - } + else /* normal menu item */ + { + miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */ + + if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */ + continue; + + if (uIDMax <= miiSrc.wID) /* remember the highest ID */ + uIDMax = miiSrc.wID + 1; + bAlreadySeparated = FALSE; } + +/* TRACE("inserting menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmDst, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask, miiSrc.hSubMenu); +*/ if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc)) - { return(uIDMax); + { + return(uIDMax); } } /* Ensure the correct number of separators at the beginning of the inserted menu items*/ if (uInsert == 0) - { if (bAlreadySeparated) - { DeleteMenu(hmDst, uInsert, MF_BYPOSITION); + { + if (bAlreadySeparated) + { + DeleteMenu(hmDst, uInsert, MF_BYPOSITION); } } else - { if (_SHIsMenuSeparator(hmDst, uInsert-1)) - { if (bAlreadySeparated) - { DeleteMenu(hmDst, uInsert, MF_BYPOSITION); + { + if (_SHIsMenuSeparator(hmDst, uInsert-1)) + { + if (bAlreadySeparated) + { + DeleteMenu(hmDst, uInsert, MF_BYPOSITION); } } else - { if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated) - { /* Add a separator between the menus*/ + { + if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated) + { + /* Add a separator between the menus*/ InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); } } diff --git a/include/shell.h b/include/shell.h index 2621b281733..1cc85be22d4 100644 --- a/include/shell.h +++ b/include/shell.h @@ -73,8 +73,8 @@ typedef struct } ITEMIDLIST,*LPITEMIDLIST,*LPCITEMIDLIST; #include "poppack.h" -DWORD WINAPI SHGetPathFromIDListA (LPCITEMIDLIST pidl,LPSTR pszPath); -DWORD WINAPI SHGetPathFromIDListW (LPCITEMIDLIST pidl,LPWSTR pszPath); +BOOL WINAPI SHGetPathFromIDListA (LPCITEMIDLIST pidl,LPSTR pszPath); +BOOL WINAPI SHGetPathFromIDListW (LPCITEMIDLIST pidl,LPWSTR pszPath); #define SHGetPathFromIDList WINELIB_NAME_AW(SHGetPathFromIDList) diff --git a/include/shlguid.h b/include/shlguid.h index e34291df2c4..039b5dd6374 100644 --- a/include/shlguid.h +++ b/include/shlguid.h @@ -31,8 +31,11 @@ DEFINE_GUID (IID_IDockingWindow, 0x012dd920L, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, DEFINE_GUID (IID_IDockingWindowSite, 0x2A342FC2L, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); /**************************************************************************** -* the following should be moved to the right place +* undocumented stuff */ -DEFINE_GUID (IID_MyComputer, 0x20D04FE0L, 0x3AEA, 0x1069, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); +/* the next two IID's are the namespace elements in the desktop folder */ +DEFINE_GUID (IID_MyComputer, 0x20D04FE0L, 0x3AEA, 0x1069, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); +DEFINE_GUID (IID_IExplore, 0x871C5380L, 0x42A0, 0x1069, 0xA2, 0xEA, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); +DEFINE_GUID (CLSID_PaperBin, 0x645FF040L, 0x5081, 0x101B, 0x9F, 0x08, 0x00, 0xAA, 0x00, 0x2F, 0x95, 0x4E); #endif /* __WINE_SHLGUID_H */ diff --git a/include/shlobj.h b/include/shlobj.h index 880fc74fbbe..766426bdebc 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -41,7 +41,7 @@ extern UINT cfShellIDList; typedef struct { UINT cidl; UINT aoffset[1]; -} CIDA, *LPCIDA; +} CIDA, *LPCIDA,*LPIDA; #define CFSTR_SHELLIDLISTOFFSET "Shell Object Offsets" /* CF_OBJECTPOSITIONS */ #define CFSTR_NETRESOURCES "Net Resource" /* CF_NETRESOURCE */ @@ -299,6 +299,11 @@ HRESULT WINAPI SHGetDataFromIDListA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int n HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID pv, int cb); #define SHGetDataFromIDList WINELIB_NAME_AW(SHGetDataFromIDList) +BOOL WINAPI SHGetSpecialFolderPathA (HWND hwndOwner,LPSTR szPath,DWORD csidl,BOOL bCreate); +BOOL WINAPI SHGetSpecialFolderPathW (HWND hwndOwner,LPWSTR szPath,DWORD csidl,BOOL bCreate); +#define SHGetSpecialFolderPath WINELIB_NAME_AW(SHGetSpecialFolderPath) + +HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST * ppidl); /**************************************************************************** * shlview structures diff --git a/include/wine/obj_enumidlist.h b/include/wine/obj_enumidlist.h index 337ab44bf25..e13e46ff76c 100644 --- a/include/wine/obj_enumidlist.h +++ b/include/wine/obj_enumidlist.h @@ -26,10 +26,7 @@ typedef struct IEnumIDList IEnumIDList, *LPENUMIDLIST; ICOM_METHOD3(HRESULT, Next, ULONG, celt, LPITEMIDLIST*, rgelt, ULONG*, pceltFetched) \ ICOM_METHOD1(HRESULT, Skip, ULONG, celt) \ ICOM_METHOD (HRESULT, Reset) \ - ICOM_METHOD1(HRESULT, Clone, IEnumIDList**, ppenum) \ - ICOM_METHOD2(BOOL, CreateEnumList, LPCSTR,, DWORD,) \ - ICOM_METHOD1(BOOL, AddToEnumList, LPITEMIDLIST,) \ - ICOM_METHOD (BOOL, DeleteList) + ICOM_METHOD1(HRESULT, Clone, IEnumIDList**, ppenum) #define IEnumIDList_IMETHODS \ IUnknown_IMETHODS \ IEnumIDList_METHODS @@ -46,9 +43,6 @@ ICOM_DEFINE(IEnumIDList,IUnknown) #define IEnumIDList_Skip(p,a) ICOM_CALL1(Skip,p,a) #define IEnumIDList_Reset(p) ICOM_CALL(Reset,p) #define IEnumIDList_Clone(p,a) ICOM_CALL1(Clone,p,a) -#define IEnumIDList_CreateEnumList(p,a,b) ICOM_CALL2(CreateEnumList,p,a,b) -#define IEnumIDList_AddToEnumList(p,a) ICOM_CALL1(AddToEnumList,p,a) -#define IEnumIDList_DeleteList(p) ICOM_CALL(DeleteList,p) #endif #ifdef __cplusplus diff --git a/include/wine/obj_shellfolder.h b/include/wine/obj_shellfolder.h index 0568e0b44a4..0e3ac5518d3 100644 --- a/include/wine/obj_shellfolder.h +++ b/include/wine/obj_shellfolder.h @@ -82,6 +82,7 @@ typedef enum tagSHCONTF #define SFGAO_SHARE 0x00020000L /* shared */ #define SFGAO_READONLY 0x00040000L /* read-only */ #define SFGAO_GHOSTED 0x00080000L /* ghosted icon */ +#define SFGAO_HIDDEN 0x00080000L /* hidden object */ #define SFGAO_DISPLAYATTRMASK 0x000F0000L #define SFGAO_FILESYSANCESTOR 0x10000000L /* It contains file system folder */ #define SFGAO_FOLDER 0x20000000L /* It's a folder. */ @@ -90,6 +91,9 @@ typedef enum tagSHCONTF #define SFGAO_CONTENTSMASK 0x80000000L #define SFGAO_VALIDATE 0x01000000L /* invalidate cached information */ #define SFGAO_REMOVABLE 0x02000000L /* is this removeable media? */ +#define SFGAO_BROWSABLE 0x08000000L /* is in-place browsable */ +#define SFGAO_NONENUMERATED 0x00100000L /* is a non-enumerated object */ +#define SFGAO_NEWCONTENT 0x00200000L /* should show bold in explorer tree */ /************************************************************************ * @@ -182,6 +186,11 @@ ICOM_DEFINE(IShellFolder,IUnknown) /***************************************************************************** * IPersistFolder interface */ + +DEFINE_GUID (CLSID_SFMyComp,0x20D04FE0,0x3AEA,0x1069,0xA2,0xD8,0x08,0x00,0x2B,0x30,0x30,0x9D); +DEFINE_GUID (CLSID_SFINet, 0x871C5380,0x42A0,0x1069,0xA2,0xEA,0x08,0x00,0x2B,0x30,0x30,0x9D); +DEFINE_GUID (CLSID_SFFile, 0xF3364BA0,0x65B9,0x11CE,0xA9,0xBA,0x00,0xAA,0x00,0x4A,0xE8,0x37); + #define ICOM_INTERFACE IPersistFolder #define IPersistFolder_METHODS \ ICOM_METHOD1( HRESULT, Initialize, LPCITEMIDLIST, pidl) diff --git a/relay32/shell32.spec b/relay32/shell32.spec index 202d97e5bde..49474dfda0d 100644 --- a/relay32/shell32.spec +++ b/relay32/shell32.spec @@ -75,7 +75,7 @@ init Shell32LibMain 67 stdcall Shell_MergeMenus (long long long long long long) Shell_MergeMenus 68 stdcall SHGetSettings(ptr long long) SHGetSettings 69 stub SHGetNetResource - 70 stub SHCreateDefClassObject + 70 stdcall SHCreateDefClassObject(long long long long long)SHCreateDefClassObject 71 stdcall Shell_GetImageList(ptr ptr) Shell_GetImageList 72 stdcall Shell_GetCachedImageIndex(ptr ptr long) Shell_GetCachedImageIndexA # ASCII!!! 73 stub SHShellFolderView_Message @@ -83,7 +83,7 @@ init Shell32LibMain 75 stdcall PathYetAnotherMakeUniqueName(ptr ptr) PathYetAnotherMakeUniqueNameA 76 stub DragQueryInfo 77 stdcall SHMapPIDLToSystemImageListIndex(long long long) SHMapPIDLToSystemImageListIndex - 78 stdcall OleStrToStrN(str long wstr long) OleStrToStrN + 78 stdcall OleStrToStrN(str long wstr long) OleStrToStrNAW 79 stdcall StrToOleStrN(wstr long str long) StrToOleStrNAW 80 stdcall DragFinish(long) DragFinish 81 stdcall DragQueryFile(long long ptr long) DragQueryFileA @@ -152,7 +152,7 @@ init Shell32LibMain 144 stdcall FileMenu_GetItemExtent (long long) FileMenu_GetItemExtent 145 stdcall PathFindOnPath (ptr ptr) PathFindOnPathAW 146 stdcall RLBuildListOfPaths()RLBuildListOfPaths - 147 stdcall SHCLSIDFromString(long long) SHCLSIDFromString + 147 stdcall SHCLSIDFromString(long long) SHCLSIDFromStringAW 148 stdcall ExtractAssociatedIconA(long ptr long) ExtractAssociatedIconA # exported by name 149 stdcall SHFind_InitMenuPopup(long long long long) SHFind_InitMenuPopup 150 stub ExtractAssociatedIconExA # exported by name @@ -180,7 +180,7 @@ init Shell32LibMain 172 stub SHCreateLinks 173 stdcall SHValidateUNC(long long long)SHValidateUNC 174 stdcall SHCreateShellFolderViewEx (ptr ptr) SHCreateShellFolderViewEx - 175 stdcall SHGetSpecialFolderPath(long long long long) SHGetSpecialFolderPath + 175 stdcall SHGetSpecialFolderPath(long long long long) SHGetSpecialFolderPathAW 176 stdcall SHSetInstanceExplorer (long) SHSetInstanceExplorer 177 stub DAD_SetDragImageFromListView 178 stub SHObjectProperties