From c3cb9779e329d8ea9435da74f80e3f32c1df495a Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Wed, 7 Apr 2004 20:41:31 +0000 Subject: [PATCH] Merge latest Wine commits: Juan Lang Use symbolic constants for magic numbers in SHGetFolderPathW, avoid doing MultiByteToWideChar on values that don't need it, Juan Lang Rename PT_MYCOMP to PT_GUID, and the corresponding union member from mycomp to guid. Martin Fuchs Resolve shell shortcuts and process ID lists in ShellExecute() functions. Juan Lang - comment fixes - improved error checking and conformance with Windows - remove some spurious error messages svn path=/trunk/; revision=9017 --- reactos/lib/shell32/cpanelfolder.c | 2 +- reactos/lib/shell32/debughlp.c | 14 +- reactos/lib/shell32/enumidlist.c | 10 +- reactos/lib/shell32/folders.c | 24 +- reactos/lib/shell32/pidl.c | 496 ++++++++++----------------- reactos/lib/shell32/pidl.h | 53 +-- reactos/lib/shell32/shelllink.c | 24 +- reactos/lib/shell32/shellpath.c | 223 +++++++++--- reactos/lib/shell32/shfldr_desktop.c | 7 +- reactos/lib/shell32/shfldr_mycomp.c | 8 +- reactos/lib/shell32/shlexec.c | 2 +- 11 files changed, 450 insertions(+), 413 deletions(-) diff --git a/reactos/lib/shell32/cpanelfolder.c b/reactos/lib/shell32/cpanelfolder.c index 0bf054b3101..e4531b5c9cb 100644 --- a/reactos/lib/shell32/cpanelfolder.c +++ b/reactos/lib/shell32/cpanelfolder.c @@ -131,7 +131,7 @@ HRESULT WINAPI IControlPanel_Constructor(IUnknown* pUnkOuter, REFIID riid, LPVOI sf->lpVtblPersistFolder2 = &vt_PersistFolder2; sf->lpVtblShellExecuteHookW = &vt_ShellExecuteHookW; sf->lpVtblShellExecuteHookA = &vt_ShellExecuteHookA; - sf->pidlRoot = _ILCreateControl(); /* my qualified pidl */ + sf->pidlRoot = _ILCreateControlPanel(); /* my qualified pidl */ sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_ (sf); if (!SUCCEEDED(IUnknown_QueryInterface(_IUnknown_(sf), riid, ppv))) { diff --git a/reactos/lib/shell32/debughlp.c b/reactos/lib/shell32/debughlp.c index 6f4d58725cc..2c3cb9d32cf 100644 --- a/reactos/lib/shell32/debughlp.c +++ b/reactos/lib/shell32/debughlp.c @@ -69,8 +69,8 @@ LPSTR _dbg_ILGetTextPointer(LPCITEMIDLIST pidl) { switch (pdata->type) { - case PT_MYCOMP: - case PT_SPECIAL: + case PT_GUID: + case PT_SHELLEXT: return NULL; case PT_DRIVE: @@ -128,9 +128,9 @@ REFIID _dbg_ILGetGUIDPointer(LPCITEMIDLIST pidl) { switch (pdata->type) { - case PT_SPECIAL: - case PT_MYCOMP: - return (REFIID) &(pdata->u.mycomp.guid); + case PT_SHELLEXT: + case PT_GUID: + return (REFIID) &(pdata->u.guid.guid); } } return NULL; @@ -230,8 +230,8 @@ BOOL pcheck (LPCITEMIDLIST pidl) { type = _dbg_ILGetDataPointer(pidltemp)->type; switch (type) { case PT_DESKTOP: - case PT_MYCOMP: - case PT_SPECIAL: + case PT_GUID: + case PT_SHELLEXT: case PT_DRIVE: case PT_DRIVE1: case PT_DRIVE2: diff --git a/reactos/lib/shell32/enumidlist.c b/reactos/lib/shell32/enumidlist.c index cb129f4dcf3..bb3b0529cd2 100644 --- a/reactos/lib/shell32/enumidlist.c +++ b/reactos/lib/shell32/enumidlist.c @@ -133,7 +133,7 @@ static BOOL CreateFolderEnumList( if( !(dwFlags & SHCONTF_INCLUDEHIDDEN) && (stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ) continue; if( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, "..")) { - pidl = _ILCreateFolder (&stffile); + pidl = _ILCreateFromFindDataA (&stffile); if(pidl && AddToEnumList((IEnumIDList*)This, pidl)) { continue; @@ -157,7 +157,7 @@ static BOOL CreateFolderEnumList( if( !(dwFlags & SHCONTF_INCLUDEHIDDEN) && (stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ) continue; if(! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { - pidl = _ILCreateValue(&stffile); + pidl = _ILCreateFromFindDataA(&stffile); if(pidl && AddToEnumList((IEnumIDList*)This, pidl)) { continue; @@ -259,7 +259,7 @@ int SHELL_RegisterCPanelFolders(IEnumIDList* list, HKEY hkey_root, LPCSTR szRepP break; if (*name == '{') { - LPITEMIDLIST pidl = _ILCreateSpecial(name); + LPITEMIDLIST pidl = _ILCreateGuidFromStrA(name); if (pidl && AddToEnumList(list, pidl)) ++cnt; @@ -364,7 +364,7 @@ static BOOL CreateDesktopEnumList( if(ERROR_SUCCESS!=RegEnumKeyExA(hkey, i, iid, &size, 0, NULL, NULL, NULL)) break; - pidl = _ILCreateSpecial(iid); + pidl = _ILCreateGuidFromStrA(iid); if(pidl) AddToEnumList((IEnumIDList*)This, pidl); @@ -435,7 +435,7 @@ static BOOL CreateMyCompEnumList( if(ERROR_SUCCESS!=RegEnumKeyExA(hkey, i, iid, &size, 0, NULL, NULL, NULL)) break; - pidl = _ILCreateSpecial(iid); + pidl = _ILCreateGuidFromStrA(iid); if(pidl) AddToEnumList((IEnumIDList*)This, pidl); diff --git a/reactos/lib/shell32/folders.c b/reactos/lib/shell32/folders.c index ca3f3e3f1f6..87bfa6c08bb 100644 --- a/reactos/lib/shell32/folders.c +++ b/reactos/lib/shell32/folders.c @@ -186,16 +186,19 @@ static HRESULT WINAPI IExtractIconW_fnGetIconLocation( /* my computer and other shell extensions */ else if ((riid = _ILGetGUIDPointer(pSimplePidl))) { - char xriid[50]; + static WCHAR fmt[] = { 'C','L','S','I','D','\\','{','%','0','8','l','x', + '-','%','0','4','x','-','%','0','4','x','-','%','0','2','x', + '%','0','2','x','-','%','0','2','x', '%','0','2','x', '%','0','2','x', + '%','0','2','x','%','0','2','x','%','0','2','x','}',0 }; + WCHAR xriid[50]; - sprintf(xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + sprintfW(xriid, fmt, riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]); - if (HCR_GetDefaultIconA(xriid, sTemp, MAX_PATH, &dwNr)) + if (HCR_GetDefaultIconW(xriid, szIconFile, cchMax, &dwNr)) { - MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax); *piIndex = dwNr; } else @@ -207,9 +210,10 @@ static HRESULT WINAPI IExtractIconW_fnGetIconLocation( else if (_ILIsDrive (pSimplePidl)) { - if (HCR_GetDefaultIconA("Drive", sTemp, MAX_PATH, &dwNr)) + static WCHAR drive[] = { 'D','r','i','v','e',0 }; + + if (HCR_GetDefaultIconW(drive, szIconFile, cchMax, &dwNr)) { - MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax); *piIndex = dwNr; } else @@ -221,11 +225,9 @@ static HRESULT WINAPI IExtractIconW_fnGetIconLocation( else if (_ILIsFolder (pSimplePidl)) { - if (HCR_GetDefaultIconA("Folder", sTemp, MAX_PATH, &dwNr)) - { - MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax); - } - else + static WCHAR folder[] = { 'F','o','l','d','e','r',0 }; + + if (!HCR_GetDefaultIconW(folder, szIconFile, cchMax, &dwNr)) { lstrcpynW(szIconFile, swShell32Name, cchMax); dwNr = 3; diff --git a/reactos/lib/shell32/pidl.c b/reactos/lib/shell32/pidl.c index 498c6b3a790..cd703cfa7ff 100644 --- a/reactos/lib/shell32/pidl.c +++ b/reactos/lib/shell32/pidl.c @@ -278,6 +278,7 @@ HRESULT WINAPI ILLoadFromStream (IStream * pStream, LPITEMIDLIST * ppPidl) DWORD dwBytesRead; HRESULT ret = E_FAIL; + TRACE_(shell)("%p %p\n", pStream , ppPidl); if (*ppPidl) @@ -699,7 +700,7 @@ LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) * * NOTES */ -HRESULT WINAPI SHGetRealIDL(LPSHELLFOLDER lpsf, LPCITEMIDLIST pidlSimple, LPITEMIDLIST* pidlReal) +HRESULT WINAPI SHGetRealIDL(LPSHELLFOLDER lpsf, LPCITEMIDLIST pidlSimple, LPITEMIDLIST *pidlReal) { IDataObject* pDataObj; HRESULT hr = IShellFolder_GetUIObjectOf(lpsf, 0, 1, &pidlSimple, &IID_IDataObject, 0, (LPVOID*)&pDataObj); @@ -1078,98 +1079,6 @@ LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW(LPCVOID lpszPath) return SHSimpleIDListFromPathA (lpszPath); } -/************************************************************************* - * SHGetSpecialFolderLocation [SHELL32.@] - * - * gets the folder locations from the registry and creates a pidl - * creates missing reg keys and directories - * - * PARAMS - * hwndOwner [I] - * nFolder [I] CSIDL_xxxxx - * ppidl [O] PIDL of a special folder - * - * NOTES - * In NT5, SHGetSpecialFolderLocation needs the /Recent - * directory. If the directory is missing it returns a x80070002. - */ -HRESULT WINAPI SHGetSpecialFolderLocation( - HWND hwndOwner, - INT nFolder, - LPITEMIDLIST * ppidl) -{ - CHAR szPath[MAX_PATH]; - HRESULT hr = E_INVALIDARG; - - TRACE_(shell)("(%p,0x%x,%p)\n", hwndOwner,nFolder,ppidl); - - if (ppidl) - { - *ppidl = NULL; - switch (nFolder) - { - case CSIDL_DESKTOP: - *ppidl = _ILCreateDesktop(); - break; - - case CSIDL_DRIVES: - *ppidl = _ILCreateMyComputer(); - break; - - case CSIDL_NETWORK: - *ppidl = _ILCreateNetwork (); - break; - - case CSIDL_CONTROLS: - *ppidl = _ILCreateControl (); - break; - - case CSIDL_FONTS: - FIXME("virtual font folder"); - break; - - case CSIDL_PRINTERS: - *ppidl = _ILCreatePrinter (); - break; - - case CSIDL_BITBUCKET: - *ppidl = _ILCreateBitBucket (); - break; - - default: - if (SHGetSpecialFolderPathA(hwndOwner, szPath, nFolder, TRUE)) - { - DWORD attributes=0; - TRACE_(shell)("Value=%s\n",szPath); - hr = SHILCreateFromPathA(szPath, ppidl, &attributes); - } - } - if(*ppidl) hr = NOERROR; - } - - TRACE_(shell)("-- (new pidl %p)\n",*ppidl); - return hr; -} - -/************************************************************************* - * SHGetFolderLocation [SHELL32.@] - * - * NOTES - * the pidl can be a simple one. since we can't get the path out of the pidl - * we have to take all data from the pidl - */ -HRESULT WINAPI SHGetFolderLocation( - HWND hwnd, - int csidl, - HANDLE hToken, - DWORD dwFlags, - LPITEMIDLIST *ppidl) -{ - FIXME("%p 0x%08x %p 0x%08lx %p\n", - hwnd, csidl, hToken, dwFlags, ppidl); - return SHGetSpecialFolderLocation(hwnd, csidl, ppidl); -} - /************************************************************************* * SHGetDataFromIDListA [SHELL32.247] * @@ -1288,18 +1197,16 @@ HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int n */ HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSize) { - LPSTR pstr = pszPath; - LPSTR end = pszPath + uOutSize; HRESULT hr = S_OK; - pszPath[0] = '\0'; + pszPath[0]=0; /* One case is a PIDL rooted at desktop level */ if (_ILIsValue(pidl) || _ILIsFolder(pidl)) { - hr = SHGetSpecialFolderPathA(0, pstr, CSIDL_DESKTOP, FALSE); + hr = SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOP, FALSE); if (SUCCEEDED(hr)) - pstr = PathAddBackslashA(pstr); + PathAddBackslashA(pszPath); } /* The only other valid case is a item ID list beginning at "My Computer" */ else if (_ILIsMyComputer(pidl)) @@ -1308,7 +1215,7 @@ HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSiz if (SUCCEEDED(hr)) { LPSTR txt; - while(pidl && pidl->mkid.cb && pstrmkid.cb) { if (_ILIsSpecialFolder(pidl)) {hr = E_INVALIDARG; break;} @@ -1316,11 +1223,13 @@ HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSiz if (!txt) {hr = E_INVALIDARG; break;} - /* make sure there's enough space for the next segment */ - if (pstr+lstrlenA(txt) >= end) - {hr = E_INVALIDARG; break;} + if (lstrlenA(txt) > pidl->mkid.cb) + ERR("pidl %p is borked\n",pidl); - lstrcpynA(pstr, txt, end-pstr); + /* make sure there's enough space for the next segment */ + if ( (lstrlenA(txt) + lstrlenA(pszPath)) > uOutSize) + {hr = E_INVALIDARG; break;} + lstrcatA( pszPath, txt ); pidl = ILGetNext(pidl); if (!pidl) @@ -1331,11 +1240,9 @@ HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSiz break; } - if (pstr+1 >= end) + if( (lstrlenA(pszPath) + 1) > uOutSize) {hr = E_INVALIDARG; break;} - - pstr = PathAddBackslashA(pstr); - if (!pstr) + if (!PathAddBackslashA(pszPath)) {hr = E_INVALIDARG; break;} } } else @@ -1380,18 +1287,17 @@ BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath) */ HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize) { - LPWSTR pstr = pszPath; - LPWSTR end = pszPath + uOutSize; HRESULT hr = S_OK; + UINT len; - pszPath[0] = '\0'; + pszPath[0]=0; /* One case is a PIDL rooted at desktop level */ if (_ILIsValue(pidl) || _ILIsFolder(pidl)) { - hr = SHGetSpecialFolderPathW(0, pstr, CSIDL_DESKTOP, FALSE); + hr = SHGetSpecialFolderPathW(0, pszPath, CSIDL_DESKTOP, FALSE); if (SUCCEEDED(hr)) - pstr = PathAddBackslashW(pstr); + PathAddBackslashW(pszPath); } /* The only other valid case is a item ID list beginning at "My Computer" */ else if (_ILIsMyComputer(pidl)) @@ -1400,7 +1306,7 @@ HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSi if (SUCCEEDED(hr)) { LPSTR txt; - while(pidl && pidl->mkid.cb && pstrmkid.cb) { if (_ILIsSpecialFolder(pidl)) {hr = E_INVALIDARG; break;} @@ -1408,12 +1314,14 @@ HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSi if (!txt) {hr = E_INVALIDARG; break;} - /* make sure there's enough space for the next segment */ - if (pstr+lstrlenA(txt) >= end) + if (lstrlenA(txt) > pidl->mkid.cb) + ERR("pidl %p is borked\n",pidl); + len = MultiByteToWideChar(CP_ACP, 0, txt, -1, NULL, 0); + if ( (lstrlenW(pszPath) + len) > uOutSize ) {hr = E_INVALIDARG; break;} - if (!MultiByteToWideChar(CP_ACP, 0, txt, -1, pstr, uOutSize)) - {hr = E_OUTOFMEMORY; break;} + MultiByteToWideChar(CP_ACP, 0, txt, -1, + &pszPath[lstrlenW(pszPath)], len); pidl = ILGetNext(pidl); if (!pidl) @@ -1424,11 +1332,9 @@ HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSi break; } - if (pstr+1 >= end) + if ( (lstrlenW(pszPath) + 1) > uOutSize ) {hr = E_INVALIDARG; break;} - - pstr = PathAddBackslashW(pstr); - if (!pstr) + if (!PathAddBackslashW(pszPath)) {hr = E_INVALIDARG; break;} } } else @@ -1466,7 +1372,6 @@ BOOL WINAPI SHGetPathFromIDListAW(LPCITEMIDLIST pidl,LPVOID pszPath) if (SHELL_OsIsUnicode()) return SHGetPathFromIDListW(pidl,pszPath); - return SHGetPathFromIDListA(pidl,pszPath); } @@ -1519,11 +1424,10 @@ HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCI ILFree (pidlChild); SHFree (pidlParent); - - if (psf) - IShellFolder_Release(psf); + if (psf) IShellFolder_Release(psf); } + TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr); return hr; } @@ -1535,119 +1439,169 @@ HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCI * ### 1. section creating pidls ### * ************************************************************************* - * _ILCreateDesktop() - * _ILCreateIExplore() - * _ILCreateMyComputer() - * _ILCreateDrive() - * _ILCreateFolder() - * _ILCreateValue() */ LPITEMIDLIST _ILCreateDesktop() { TRACE("()\n"); - return _ILCreate(PT_DESKTOP, NULL, 0); + return _ILCreateWithTypeAndSize(PT_DESKTOP, 0); } LPITEMIDLIST _ILCreateMyComputer() { TRACE("()\n"); - return _ILCreate(PT_MYCOMP, &CLSID_MyComputer, sizeof(GUID)); + return _ILCreateGuid(PT_GUID, &CLSID_MyComputer); } LPITEMIDLIST _ILCreateIExplore() { TRACE("()\n"); - return _ILCreate(PT_MYCOMP, &CLSID_Internet, sizeof(GUID)); + return _ILCreateGuid(PT_GUID, &CLSID_Internet); } -LPITEMIDLIST _ILCreateControl() -{ TRACE("()\n"); - return _ILCreate(PT_SPECIAL, &CLSID_ControlPanel, sizeof(GUID)); +LPITEMIDLIST _ILCreateControlPanel() +{ + LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL; + + TRACE("()\n"); + if (parent) + { + LPITEMIDLIST cpl = _ILCreateGuid(PT_GUID, &CLSID_ControlPanel); + + if (cpl) + { + ret = ILCombine(parent, cpl); + SHFree(cpl); + } + SHFree(parent); + } + return ret; } -LPITEMIDLIST _ILCreatePrinter() -{ TRACE("()\n"); - return _ILCreate(PT_SPECIAL, &CLSID_Printers, sizeof(GUID)); +LPITEMIDLIST _ILCreatePrinters() +{ + LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL; + + TRACE("()\n"); + if (parent) + { + LPITEMIDLIST printers = _ILCreateGuid(PT_GUID, &CLSID_ControlPanel); + + if (printers) + { + ret = ILCombine(parent, printers); + SHFree(printers); + } + SHFree(parent); + } + return ret; } LPITEMIDLIST _ILCreateNetwork() { TRACE("()\n"); - return _ILCreate(PT_MYCOMP, &CLSID_NetworkPlaces, sizeof(GUID)); + return _ILCreateGuid(PT_GUID, &CLSID_NetworkPlaces); } LPITEMIDLIST _ILCreateBitBucket() { TRACE("()\n"); - return _ILCreate(PT_MYCOMP, &CLSID_RecycleBin, sizeof(GUID)); + return _ILCreateGuid(PT_GUID, &CLSID_RecycleBin); } -LPITEMIDLIST _ILCreateDrive( LPCSTR lpszNew) -{ char sTemp[4]; - lstrcpynA (sTemp,lpszNew,4); - sTemp[2]='\\'; - sTemp[3]=0x00; - TRACE("(%s)\n",sTemp); - return _ILCreate(PT_DRIVE,(LPVOID)&sTemp[0],4); -} - -LPITEMIDLIST _ILCreateFolder( WIN32_FIND_DATAA * stffile ) +LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid) { - char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */ - char * pbuff = buff; - ULONG len, len1; - LPITEMIDLIST pidl; + LPITEMIDLIST pidlOut; - TRACE("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName); + if (type == PT_SHELLEXT || type == PT_GUID) + { + pidlOut = _ILCreateWithTypeAndSize(type, 2 + 2 + sizeof(GUID)); + if (pidlOut) + { + LPPIDLDATA pData = _ILGetDataPointer(pidlOut); - /* prepare buffer with both names */ - len = strlen (stffile->cFileName) + 1; - memcpy (pbuff, stffile->cFileName, len); - pbuff += len; + memcpy(&(pData->u.guid.guid), guid, sizeof(GUID)); + TRACE("-- create GUID-pidl %s\n", + debugstr_guid(&(pData->u.guid.guid))); + } + } + else + { + WARN("%d: invalid type for GUID\n", type); + pidlOut = NULL; + } + return pidlOut; +} + +LPITEMIDLIST _ILCreateGuidFromStrA(LPCSTR szGUID) +{ + IID iid; + + if (!SUCCEEDED(SHCLSIDFromStringA(szGUID, &iid))) + { + ERR("%s is not a GUID\n", szGUID); + return NULL; + } + return _ILCreateGuid(PT_GUID, &iid); +} + +LPITEMIDLIST _ILCreateWithTypeAndSize(PIDLTYPE type, UINT size) +{ + LPITEMIDLIST pidlOut = NULL, pidlTemp = NULL; + LPPIDLDATA pData; + + if(!(pidlOut = SHAlloc(size + 2))) return NULL; + ZeroMemory(pidlOut, size + 2); + pidlOut->mkid.cb = size; + + if ((pData = _ILGetDataPointer(pidlOut))) + pData->type = type; + + if ((pidlTemp = ILGetNext(pidlOut))) + pidlTemp->mkid.cb = 0x00; + + TRACE("-- (pidl=%p, size=%u)\n", pidlOut, size); + return pidlOut; +} + +LPITEMIDLIST _ILCreateFromFindDataA(WIN32_FIND_DATAA * stffile ) +{ + char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */ + char * pbuff = buff; + ULONG len, len1; + LPITEMIDLIST pidl; + PIDLTYPE type; + + if (!stffile) + return NULL; + + TRACE("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName); + + /* prepare buffer with both names */ + len = strlen (stffile->cFileName) + 1; + memcpy (pbuff, stffile->cFileName, len); + pbuff += len; len1 = strlen (stffile->cAlternateFileName)+1; memcpy (pbuff, stffile->cAlternateFileName, len1); - pidl = _ILCreate(PT_FOLDER, (LPVOID)buff, len + len1); + type = (stffile->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? PT_FOLDER : + PT_VALUE; + /* FIXME: magic #s! */ + if ((pidl = _ILCreateWithTypeAndSize(type, 2 + 12 + len + len1))) + { + LPPIDLDATA pData; + LPSTR pszDest; - /* 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 = (WORD)stffile->dwFileAttributes; - } - - return pidl; -} - -LPITEMIDLIST _ILCreateValue(WIN32_FIND_DATAA * stffile) -{ - char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */ - char * pbuff = buff; - ULONG len, len1; - LPITEMIDLIST pidl; - - TRACE("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName); - - /* prepare buffer with both names */ - len = strlen (stffile->cFileName) + 1; - memcpy (pbuff, stffile->cFileName, len); - pbuff += len; - - len1 = strlen (stffile->cAlternateFileName)+1; - memcpy (pbuff, stffile->cAlternateFileName, len1); - - pidl = _ILCreate(PT_VALUE, (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 = (WORD)stffile->dwFileAttributes; - } - - return pidl; + /* set attributes */ + if ((pData = _ILGetDataPointer(pidl))) + { + pData->type = type; + FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime); + pData->u.folder.dwFileSize = stffile->nFileSizeLow; + pData->u.folder.uFileAttribs = (WORD)stffile->dwFileAttributes; + } + if ((pszDest = _ILGetTextPointer(pidl))) + { + memcpy(pszDest, buff, len + len1); + TRACE("-- create Value: %s\n",debugstr_a(pszDest)); + } + } + return pidl; } LPITEMIDLIST _ILCreateFromPathA(LPCSTR szPath) @@ -1659,25 +1613,35 @@ LPITEMIDLIST _ILCreateFromPathA(LPCSTR szPath) hFile = FindFirstFileA(szPath, &stffile); if (hFile != INVALID_HANDLE_VALUE) { - if (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - pidl = _ILCreateFolder(&stffile); - else - pidl = _ILCreateValue(&stffile); + pidl = _ILCreateFromFindDataA(&stffile); FindClose(hFile); } return pidl; } -LPITEMIDLIST _ILCreateSpecial(LPCSTR szGUID) +LPITEMIDLIST _ILCreateDrive( LPCSTR lpszNew) { - IID iid; + char sTemp[4]; + LPITEMIDLIST pidlOut; - if (!SUCCEEDED(SHCLSIDFromStringA(szGUID, &iid))) - { - ERR("%s is not a GUID\n", szGUID); - return NULL; - } - return _ILCreate(PT_MYCOMP, &iid, sizeof(IID)); + sTemp[0]=lpszNew[0]; + sTemp[1]=':'; + sTemp[2]='\\'; + sTemp[3]=0x00; + TRACE("(%s)\n",sTemp); + + /* FIXME: magic #s! */ + if ((pidlOut = _ILCreateWithTypeAndSize(PT_DRIVE, 25))) + { + LPSTR pszDest; + + if ((pszDest = _ILGetTextPointer(pidlOut))) + { + memcpy(pszDest, sTemp, sizeof(sTemp)); + TRACE("-- create Drive: %s\n", debugstr_a(pszDest)); + } + } + return pidlOut; } LPITEMIDLIST _ILCreateCPanel(LPCSTR name, LPCSTR displayName, LPCSTR comment, int iconIdx) @@ -1723,88 +1687,6 @@ LPITEMIDLIST _ILCreateCPanel(LPCSTR name, LPCSTR displayName, LPCSTR comment, in return pidl; } -/************************************************************************** - * _ILCreate() - * Creates a new PIDL - * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE - * pIn = data - * uInSize = size of data (raw) - */ - -LPITEMIDLIST _ILCreate(PIDLTYPE type, LPCVOID pIn, UINT uInSize) -{ - LPITEMIDLIST pidlOut = NULL, pidlTemp = NULL; - LPPIDLDATA pData; - UINT uSize = 0; - LPSTR pszDest; - - TRACE("(0x%02x %p %i)\n",type,pIn,uInSize); - - switch (type) - { - case PT_DESKTOP: - uSize = 0; - break; - case PT_SPECIAL: - case PT_MYCOMP: - uSize = 2 + 2 + sizeof(GUID); - break; - case PT_DRIVE: - uSize = 2 + 23; - break; - case PT_FOLDER: - case PT_VALUE: - uSize = 2 + 12 + uInSize; - break; - default: - FIXME("can't create type: 0x%08x\n",type); - return NULL; - } - - if(!(pidlOut = SHAlloc(uSize + 2))) return NULL; - ZeroMemory(pidlOut, uSize + 2); - pidlOut->mkid.cb = uSize; - - switch (type) - { - case PT_DESKTOP: - TRACE("- create Desktop\n"); - break; - - case PT_SPECIAL: - case PT_MYCOMP: - pData = _ILGetDataPointer(pidlOut); - pData->type = type; - memcpy(&(pData->u.mycomp.guid), pIn, uInSize); - TRACE("-- create GUID-pidl %s\n", debugstr_guid(&(pData->u.mycomp.guid))); - break; - - case PT_DRIVE: - pData = _ILGetDataPointer(pidlOut); - pData->type = type; - pszDest = _ILGetTextPointer(pidlOut); - memcpy(pszDest, pIn, uInSize); - TRACE("-- create Drive: %s\n",debugstr_a(pszDest)); - break; - - case PT_FOLDER: - case PT_VALUE: - pData = _ILGetDataPointer(pidlOut); - pData->type = type; - pszDest = _ILGetTextPointer(pidlOut); - memcpy(pszDest, pIn, uInSize); - TRACE("-- create Value: %s\n",debugstr_a(pszDest)); - break; - } - - pidlTemp = ILGetNext(pidlOut); - if (pidlTemp) - pidlTemp->mkid.cb = 0x00; - - TRACE("-- (pidl=%p, size=%u)\n", pidlOut, uSize); - return pidlOut; -} - /************************************************************************** * _ILGetDrive() * @@ -1858,7 +1740,7 @@ BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl) { LPPIDLDATA lpPData = _ILGetDataPointer(pidl); TRACE("(%p)\n",pidl); - return (pidl && ( (lpPData && (PT_MYCOMP== lpPData->type || PT_SPECIAL== lpPData->type)) || + return (pidl && ( (lpPData && (PT_GUID== lpPData->type || PT_SHELLEXT== lpPData->type)) || (pidl && pidl->mkid.cb == 0x00) )); } @@ -2024,8 +1906,8 @@ LPSTR _ILGetTextPointer(LPCITEMIDLIST pidl) { switch (pdata->type) { - case PT_MYCOMP: - case PT_SPECIAL: + case PT_GUID: + case PT_SHELLEXT: return NULL; case PT_DRIVE: @@ -2060,7 +1942,7 @@ LPSTR _ILGetTextPointer(LPCITEMIDLIST pidl) LPSTR _ILGetSTextPointer(LPCITEMIDLIST pidl) {/* TRACE(pidl,"(pidl%p)\n", pidl);*/ - LPPIDLDATA pdata = _ILGetDataPointer(pidl); + LPPIDLDATA pdata =_ILGetDataPointer(pidl); if (pdata) { @@ -2087,7 +1969,7 @@ LPSTR _ILGetSTextPointer(LPCITEMIDLIST pidl) */ REFIID _ILGetGUIDPointer(LPCITEMIDLIST pidl) { - LPPIDLDATA pdata = _ILGetDataPointer(pidl); + LPPIDLDATA pdata =_ILGetDataPointer(pidl); TRACE("%p\n", pidl); @@ -2096,9 +1978,9 @@ REFIID _ILGetGUIDPointer(LPCITEMIDLIST pidl) TRACE("pdata->type 0x%04x\n", pdata->type); switch (pdata->type) { - case PT_SPECIAL: - case PT_MYCOMP: - return (REFIID) &(pdata->u.mycomp.guid); + case PT_SHELLEXT: + case PT_GUID: + return (REFIID) &(pdata->u.guid.guid); default: TRACE("Unknown pidl type 0x%04x\n", pdata->type); diff --git a/reactos/lib/shell32/pidl.h b/reactos/lib/shell32/pidl.h index 0b73bc0b6be..7a2456ecb2b 100644 --- a/reactos/lib/shell32/pidl.h +++ b/reactos/lib/shell32/pidl.h @@ -53,13 +53,13 @@ * object ! first byte / ! format ! living space * ! size * ---------------------------------------------------------------- -* my computer 0x1F/20 mycomp (2) (usual) -* network 0x1F mycomp -* bitbucket 0x1F mycomp +* my computer 0x1F/20 guid (2) (usual) +* network 0x1F guid +* bitbucket 0x1F guid * drive 0x23/25 drive (usual) * drive 0x25/25 drive (lnk/persistent) * drive 0x29/25 drive -* shell extension 0x2E mycomp +* shell extension 0x2E guid * drive 0x2F drive (lnk/persistent) * folder/file 0x30 folder/file (1) (lnk/persistent) * folder 0x31 folder (usual) @@ -77,20 +77,20 @@ * * (1) dummy byte is used, attributes are empty * (2) IID_MyComputer = 20D04FE0L-3AEA-1069-A2D8-08002B30309D -* (3) two strings "workgroup" "microsoft network" -* (4) one string "\\sirius" -* (5) one string "whole network" -* (6) one string "\\sirius\c" +* (3) two strings "workgroup" "Microsoft Network" +* (4) two strings "\\sirius" "Microsoft Network" +* (5) one string "Entire Network" +* (6) two strings "\\sirius\c" "Microsoft Network" * (7) contains string "mk:@MSITStore:C:\path\file.chm::/path/filename.htm" * GUID 871C5380-42A0-1069-A2EA-08002B30309D */ #define PT_DESKTOP 0x00 /* internal */ -#define PT_MYCOMP 0x1F +#define PT_GUID 0x1F #define PT_DRIVE 0x23 #define PT_DRIVE2 0x25 #define PT_DRIVE3 0x29 -#define PT_SPECIAL 0x2E +#define PT_SHELLEXT 0x2E #define PT_DRIVE1 0x2F #define PT_FOLDER1 0x30 #define PT_FOLDER 0x31 @@ -123,7 +123,7 @@ typedef struct tagPIDLDATA { BYTE dummy; /*01*/ GUID guid; /*02*/ BYTE dummy1; /*18*/ - } mycomp; + } guid; struct { CHAR szDriveName[20]; /*01*/ DWORD dwUnknown; /*21*/ @@ -136,7 +136,7 @@ typedef struct tagPIDLDATA WORD uFileTime; /*08*/ WORD uFileAttribs; /*10*/ CHAR szNames[1]; /*12*/ - /* Here are comming two strings. The first is the long name. + /* Here are coming two strings. The first is the long name. The second the dos name when needed or just 0x00 */ } file, folder, generic; struct @@ -180,22 +180,35 @@ BOOL _ILIsPidlSimple (LPCITEMIDLIST pidl); BOOL _ILIsCPanelStruct (LPCITEMIDLIST pidl); /* - * simple pidls from strings + * simple pidls */ -LPITEMIDLIST _ILCreate (PIDLTYPE,LPCVOID,UINT); +/* Basic PIDL constructor. Allocates size + 2 bytes (to include space for the + * NULL PIDL terminator), and sets type to type. + */ +LPITEMIDLIST _ILCreateWithTypeAndSize(PIDLTYPE type, UINT size); + +/* Creates a PIDL with guid format and type type, which must be either PT_GUID + * or PT_SHELLEXT. + */ +LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid); + +/* Like _ILCreateGuid, but using the string szGUID. */ +LPITEMIDLIST _ILCreateGuidFromStrA(LPCSTR szGUID); + +/* Commonly used PIDLs representing file system objects. */ LPITEMIDLIST _ILCreateDesktop (void); +LPITEMIDLIST _ILCreateFromFindDataA(WIN32_FIND_DATAA *stffile); +LPITEMIDLIST _ILCreateFromPathA (LPCSTR szPath); + +/* Other helpers */ LPITEMIDLIST _ILCreateMyComputer (void); LPITEMIDLIST _ILCreateIExplore (void); -LPITEMIDLIST _ILCreateControl (void); -LPITEMIDLIST _ILCreatePrinter (void); +LPITEMIDLIST _ILCreateControlPanel (void); +LPITEMIDLIST _ILCreatePrinters (void); LPITEMIDLIST _ILCreateNetwork (void); LPITEMIDLIST _ILCreateBitBucket (void); LPITEMIDLIST _ILCreateDrive (LPCSTR); -LPITEMIDLIST _ILCreateFolder (WIN32_FIND_DATAA * stffile); -LPITEMIDLIST _ILCreateValue (WIN32_FIND_DATAA * stffile); -LPITEMIDLIST _ILCreateSpecial (LPCSTR szGUID); -LPITEMIDLIST _ILCreateFromPathA (LPCSTR szPath); LPITEMIDLIST _ILCreateCPanel (LPCSTR name, LPCSTR displayName, LPCSTR comment, int iconIdx); /* diff --git a/reactos/lib/shell32/shelllink.c b/reactos/lib/shell32/shelllink.c index 4f1a43e6aed..7a0503d1f56 100644 --- a/reactos/lib/shell32/shelllink.c +++ b/reactos/lib/shell32/shelllink.c @@ -24,6 +24,7 @@ */ #include "config.h" +#include "wine/port.h" #include #include @@ -38,7 +39,6 @@ # include #endif #include "wine/debug.h" -#include "wine/port.h" #include "winerror.h" #include "windef.h" #include "winbase.h" @@ -135,14 +135,14 @@ typedef struct SYSTEMTIME time2; SYSTEMTIME time3; - DWORD iShowCmd; - LPWSTR sIcoPath; - INT iIcoNdx; - LPWSTR sPath; - LPWSTR sArgs; - LPWSTR sWorkDir; - LPWSTR sDescription; - LPWSTR sPathRel; + DWORD iShowCmd; + LPWSTR sIcoPath; + INT iIcoNdx; + LPWSTR sPath; + LPWSTR sArgs; + LPWSTR sWorkDir; + LPWSTR sDescription; + LPWSTR sPathRel; BOOL bDirty; } IShellLinkImpl; @@ -303,7 +303,7 @@ static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFile This->bDirty = FALSE; } - else + else { DeleteFileW( pszFileName ); WARN("Failed to create shortcut %s\n", debugstr_w(pszFileName) ); @@ -1808,10 +1808,10 @@ static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile This->sPath = HeapAlloc( GetProcessHeap(), 0, (lstrlenW( buffer )+1) * sizeof (WCHAR) ); - if ( !This->sPath ) + if (!This->sPath) return E_OUTOFMEMORY; - lstrcpyW( This->sPath, buffer ); + lstrcpyW(This->sPath, buffer); This->bDirty = TRUE; return S_OK; diff --git a/reactos/lib/shell32/shellpath.c b/reactos/lib/shell32/shellpath.c index c1912ccce58..1de67af0c86 100644 --- a/reactos/lib/shell32/shellpath.c +++ b/reactos/lib/shell32/shellpath.c @@ -40,6 +40,7 @@ #include "shlobj.h" #include "shell32_main.h" #include "undocshell.h" +#include "pidl.h" #include "wine/unicode.h" #include "shlwapi.h" @@ -714,6 +715,10 @@ typedef struct #define HKLM HKEY_LOCAL_MACHINE #define HKCU HKEY_CURRENT_USER +#define HKEY_DISALLOWED (HKEY)0 +#define HKEY_UNIMPLEMENTED (HKEY)1 +#define HKEY_WINDOWSPATH (HKEY)2 +#define HKEY_NONEXISTENT (HKEY)3 static const CSIDL_DATA CSIDL_Data[] = { { /* CSIDL_DESKTOP */ @@ -722,14 +727,14 @@ static const CSIDL_DATA CSIDL_Data[] = "Desktop" }, { /* CSIDL_INTERNET */ - 0, (HKEY)1, /* FIXME */ + 0, HKEY_DISALLOWED, NULL, NULL, }, { /* CSIDL_PROGRAMS */ - 9, HKCU, - "Programs", - "Start Menu\\Programs" + 0, HKEY_DISALLOWED, + NULL, + NULL, }, { /* CSIDL_CONTROLS (.CPL files) */ 10, HKLM, @@ -767,9 +772,9 @@ static const CSIDL_DATA CSIDL_Data[] = "SendTo" }, { /* CSIDL_BITBUCKET - Recycle Bin */ - 0, (HKEY)1, /* FIXME */ + 0, HKEY_DISALLOWED, + NULL, NULL, - "recycled" }, { /* CSIDL_STARTMENU */ 9, HKCU, @@ -777,7 +782,7 @@ static const CSIDL_DATA CSIDL_Data[] = "Start Menu" }, { /* CSIDL_MYDOCUMENTS */ - 0, (HKEY)1, /* FIXME */ + 0, HKEY_UNIMPLEMENTED, /* FIXME */ NULL, NULL }, @@ -786,7 +791,7 @@ static const CSIDL_DATA CSIDL_Data[] = "My Music", "My Documents\\My Music" }, - { /* CSIDL_MYMUSIC */ + { /* CSIDL_MYVIDEO */ 1, HKCU, "My Video", "My Documents\\My Video" @@ -802,14 +807,14 @@ static const CSIDL_DATA CSIDL_Data[] = "Desktop" }, { /* CSIDL_DRIVES */ - 0, (HKEY)1, /* FIXME */ + 0, HKEY_DISALLOWED, + NULL, NULL, - "My Computer" }, { /* CSIDL_NETWORK */ - 0, (HKEY)1, /* FIXME */ + 0, HKEY_DISALLOWED, + NULL, NULL, - "Network Neighborhood" }, { /* CSIDL_NETHOOD */ 9, HKCU, @@ -862,12 +867,12 @@ static const CSIDL_DATA CSIDL_Data[] = "Local Settings\\Application Data", }, { /* CSIDL_ALTSTARTUP */ - 0, (HKEY)1, /* FIXME */ + 0, HKEY_NONEXISTENT, NULL, NULL }, { /* CSIDL_COMMON_ALTSTARTUP */ - 0, (HKEY)1, /* FIXME */ + 0, HKEY_NONEXISTENT, NULL, NULL }, @@ -962,22 +967,22 @@ static const CSIDL_DATA CSIDL_Data[] = "Start Menu\\Programs\\Administrative Tools" }, { /* CSIDL_CONNECTIONS */ - 0, 0, /* FIXME */ + 0, HKEY_DISALLOWED, NULL, NULL }, { /* unassigned 32 */ - 0, 0, + 0, HKEY_DISALLOWED, NULL, NULL }, { /* unassigned 33 */ - 0, 0, + 0, HKEY_DISALLOWED, NULL, NULL }, { /* unassigned 34 */ - 0, 0, + 0, HKEY_DISALLOWED, NULL, NULL }, @@ -997,7 +1002,7 @@ static const CSIDL_DATA CSIDL_Data[] = /*"Documents and Settings\\"*/"All Users\\Documents\\My Video" }, { /* CSIDL_RESOURCES */ - 0, (HKEY)2, + 0, HKEY_WINDOWSPATH, NULL, "Resources" }, @@ -1053,25 +1058,23 @@ HRESULT WINAPI SHGetFolderPathW( TRACE("%p,%p,csidl=0x%04x\n", hwndOwner,pszPath,csidl); + if (!pszPath) + return E_INVALIDARG; + + *pszPath = '\0'; if ((folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0])) || - (CSIDL_Data[folder].hRootKey == 0)) - { - ERR("folder 0x%04lx unknown or not allowed\n", folder); - return E_FAIL; - } - if (CSIDL_Data[folder].hRootKey == (HKEY)1) + (CSIDL_Data[folder].hRootKey == HKEY_DISALLOWED)) + return E_INVALIDARG; + if (CSIDL_Data[folder].hRootKey == HKEY_UNIMPLEMENTED) { FIXME("folder 0x%04lx unknown, please add.\n", folder); return E_FAIL; } - - dwCsidlFlags = CSIDL_Data[folder].dwFlags; - hRootKey = CSIDL_Data[folder].hRootKey; - MultiByteToWideChar(CP_ACP, 0, CSIDL_Data[folder].szValueName, -1, szValueName, MAX_PATH); - MultiByteToWideChar(CP_ACP, 0, CSIDL_Data[folder].szDefaultPath, -1, szDefaultPath, MAX_PATH); + if (CSIDL_Data[folder].hRootKey == HKEY_NONEXISTENT) + return S_FALSE; /* Special case for some values that don't exist in registry */ - if (CSIDL_Data[folder].hRootKey == (HKEY)2) + if (CSIDL_Data[folder].hRootKey == HKEY_WINDOWSPATH) { GetWindowsDirectoryW(pszPath, MAX_PATH); PathAddBackslashW(pszPath); @@ -1079,6 +1082,11 @@ HRESULT WINAPI SHGetFolderPathW( return S_OK; } + dwCsidlFlags = CSIDL_Data[folder].dwFlags; + hRootKey = CSIDL_Data[folder].hRootKey; + MultiByteToWideChar(CP_ACP, 0, CSIDL_Data[folder].szValueName, -1, szValueName, MAX_PATH); + MultiByteToWideChar(CP_ACP, 0, CSIDL_Data[folder].szDefaultPath, -1, szDefaultPath, MAX_PATH); + if (dwCsidlFlags & CSIDL_MYFLAG_SHFOLDER) { /* user shell folders */ @@ -1203,19 +1211,21 @@ HRESULT WINAPI SHGetFolderPathA( DWORD dwFlags, LPSTR pszPath) { - WCHAR szTemp[MAX_PATH]; - HRESULT hr; + WCHAR szTemp[MAX_PATH]; + HRESULT hr; - hr = SHGetFolderPathW(hwndOwner, csidl, hToken, dwFlags, szTemp); - if (hr == S_OK) - { - if (!WideCharToMultiByte( CP_ACP, 0, szTemp, -1, pszPath, MAX_PATH, NULL, NULL )) - pszPath[MAX_PATH - 1] = 0; - } + if (!pszPath) + return E_INVALIDARG; - TRACE("%p,%p,csidl=0x%04x\n",hwndOwner,pszPath,csidl); + *pszPath = '\0'; + hr = SHGetFolderPathW(hwndOwner, csidl, hToken, dwFlags, szTemp); + if (SUCCEEDED(hr)) + WideCharToMultiByte(CP_ACP, 0, szTemp, -1, pszPath, MAX_PATH, NULL, + NULL); - return hr; + TRACE("%p,%p,csidl=0x%04x\n",hwndOwner,pszPath,csidl); + + return hr; } /************************************************************************* @@ -1266,3 +1276,134 @@ BOOL WINAPI SHGetSpecialFolderPathAW ( return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate); return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate); } + +/************************************************************************* + * SHGetSpecialFolderLocation [SHELL32.@] + * + * gets the folder locations from the registry and creates a pidl + * creates missing reg keys and directories + * + * PARAMS + * hwndOwner [I] + * nFolder [I] CSIDL_xxxxx + * ppidl [O] PIDL of a special folder + * + * NOTES + * In NT5, SHGetSpecialFolderLocation needs the /Recent + * directory. If the directory is missing it returns a x80070002. + * In most cases, this forwards to SHGetSpecialFolderPath, but + * CSIDLs with virtual folders (not real paths) must be handled + * here. + */ +HRESULT WINAPI SHGetSpecialFolderLocation( + HWND hwndOwner, + INT nFolder, + LPITEMIDLIST * ppidl) +{ + HRESULT hr = E_INVALIDARG; + + TRACE("(%p,0x%x,%p)\n", hwndOwner,nFolder,ppidl); + + if (!ppidl) + return E_INVALIDARG; + + *ppidl = NULL; + switch (nFolder) + { + case CSIDL_DESKTOP: + *ppidl = _ILCreateDesktop(); + break; + + case CSIDL_INTERNET: + *ppidl = _ILCreateIExplore(); + break; + + case CSIDL_CONTROLS: + *ppidl = _ILCreateControlPanel(); + break; + + case CSIDL_FONTS: + FIXME("virtual font folder"); + break; + + case CSIDL_PRINTERS: + *ppidl = _ILCreatePrinters(); + break; + + case CSIDL_BITBUCKET: + *ppidl = _ILCreateBitBucket(); + break; + + case CSIDL_DRIVES: + *ppidl = _ILCreateMyComputer(); + break; + + case CSIDL_NETWORK: + *ppidl = _ILCreateNetwork(); + break; + + case CSIDL_ALTSTARTUP: + case CSIDL_COMMON_ALTSTARTUP: + hr = E_FAIL; + break; + + case CSIDL_COMPUTERSNEARME: + hr = E_FAIL; + break; + + default: + { + WCHAR szPath[MAX_PATH]; + + if (SHGetSpecialFolderPathW(hwndOwner, szPath, nFolder, TRUE)) + { + DWORD attributes=0; + + TRACE("Value=%s\n", debugstr_w(szPath)); + hr = SHILCreateFromPathW(szPath, ppidl, &attributes); + } + } + } + if(*ppidl) + hr = NOERROR; + + TRACE("-- (new pidl %p)\n",*ppidl); + return hr; +} + +/************************************************************************* + * SHGetFolderLocation [SHELL32.@] + * + * NOTES + * the pidl can be a simple one. since we can't get the path out of the pidl + * we have to take all data from the pidl + * Mostly we forward to SHGetSpecialFolderLocation, but a few special cases + * we handle here. + */ +HRESULT WINAPI SHGetFolderLocation( + HWND hwnd, + int csidl, + HANDLE hToken, + DWORD dwFlags, + LPITEMIDLIST *ppidl) +{ + HRESULT hr; + + TRACE_(shell)("%p 0x%08x %p 0x%08lx %p\n", + hwnd, csidl, hToken, dwFlags, ppidl); + + if (!ppidl) + return E_INVALIDARG; + + switch (csidl) + { + case CSIDL_ALTSTARTUP: + case CSIDL_COMMON_ALTSTARTUP: + *ppidl = NULL; + hr = S_FALSE; + break; + default: + hr = SHGetSpecialFolderLocation(hwnd, csidl, ppidl); + } + return hr; +} diff --git a/reactos/lib/shell32/shfldr_desktop.c b/reactos/lib/shell32/shfldr_desktop.c index 9eb17dc74e9..ef053570855 100644 --- a/reactos/lib/shell32/shfldr_desktop.c +++ b/reactos/lib/shell32/shfldr_desktop.c @@ -216,7 +216,7 @@ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName (IShellFolder2 * iface, szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH); TRACE ("-- element: %s\n", debugstr_w (szElement)); SHCLSIDFromStringW (szElement + 2, &clsid); - pidlTemp = _ILCreate (PT_MYCOMP, &clsid, sizeof (clsid)); + pidlTemp = _ILCreateGuid (PT_GUID, &clsid); } else if (PathGetDriveNumberW (lpszDisplayName) >= 0) { /* it's a filesystem path with a drive. Let MyComputer parse it */ pidlTemp = _ILCreateMyComputer (); @@ -466,7 +466,7 @@ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface, GUID const *clsid; HRESULT hr = S_OK; - *szPath = '\0'; + *szPath = '\0'; TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet); pdump (pidl); @@ -681,5 +681,4 @@ static ICOM_VTABLE (IShellFolder2) vt_MCFldr_ShellFolder2 = ISF_Desktop_fnGetDefaultColumnState, ISF_Desktop_fnGetDetailsEx, ISF_Desktop_fnGetDetailsOf, - ISF_Desktop_fnMapColumnToSCID -}; + ISF_Desktop_fnMapColumnToSCID}; diff --git a/reactos/lib/shell32/shfldr_mycomp.c b/reactos/lib/shell32/shfldr_mycomp.c index 61fc25c7ec5..9923ab7d0aa 100644 --- a/reactos/lib/shell32/shfldr_mycomp.c +++ b/reactos/lib/shell32/shfldr_mycomp.c @@ -212,7 +212,7 @@ ISF_MyComputer_fnParseDisplayName (IShellFolder2 * iface, szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH); TRACE ("-- element: %s\n", debugstr_w (szElement)); SHCLSIDFromStringW (szElement + 2, &clsid); - pidlTemp = _ILCreate (PT_MYCOMP, &clsid, sizeof (clsid)); + pidlTemp = _ILCreateGuid (PT_GUID, &clsid); } /* do we have an absolute path name ? */ else if (PathGetDriveNumberW (lpszDisplayName) >= 0 && lpszDisplayName[2] == (WCHAR) '\\') { @@ -433,7 +433,7 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 * iface, ICOM_THIS (IGenericSFImpl, iface); char szPath[MAX_PATH], - szDrive[18]; + szDrive[18]; int len = 0; BOOL bSimplePidl; HRESULT hr = S_OK; @@ -658,7 +658,7 @@ static HRESULT WINAPI ISF_MyComputer_fnMapColumnToSCID (IShellFolder2 * iface, U static ICOM_VTABLE (IShellFolder2) vt_ShellFolder2 = { - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE ISF_MyComputer_fnQueryInterface, ISF_MyComputer_fnAddRef, ISF_MyComputer_fnRelease, @@ -673,7 +673,7 @@ static ICOM_VTABLE (IShellFolder2) vt_ShellFolder2 = ISF_MyComputer_fnGetDisplayNameOf, ISF_MyComputer_fnSetNameOf, /* ShellFolder2 */ - ISF_MyComputer_fnGetDefaultSearchGUID, + ISF_MyComputer_fnGetDefaultSearchGUID, ISF_MyComputer_fnEnumSearches, ISF_MyComputer_fnGetDefaultColumn, ISF_MyComputer_fnGetDefaultColumnState, diff --git a/reactos/lib/shell32/shlexec.c b/reactos/lib/shell32/shlexec.c index 08d47116467..fac6240f332 100644 --- a/reactos/lib/shell32/shlexec.c +++ b/reactos/lib/shell32/shlexec.c @@ -230,7 +230,7 @@ HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR pszPath, U /************************************************************************* * SHELL_ResolveShortCutW [Internal] - * read shortcut file at 'wcmd' and fill psei with its content + * read shortcut file at 'wcmd' */ static HRESULT SHELL_ResolveShortCutW(LPWSTR wcmd, LPWSTR wargs, LPWSTR wdir, HWND hwnd, LPCWSTR lpVerb, int* pshowcmd, LPITEMIDLIST* ppidl) {