Module: wine Branch: refs/heads/master Commit: c362d7c35ba3c02d68a9b7e42b48db210a901667 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=c362d7c35ba3c02d68a9b7e4...
Author: Martin Fuchs martin-fuchs@gmx.net Date: Sat Feb 11 12:16:56 2006 +0100
shell32: SHELL32_GetItemAttributes() - correct documentation which incorrectly claimed not to set any attribute bits - retrieve file attributes using SHGetPathFromIDListW() when they are not already present in the internal PIDL structures - add test case to show the previously wrong folder attributes when using absolute PIDLs - fix some memory leaks in the tests
---
dlls/shell32/shlfolder.c | 16 +++++++- dlls/shell32/tests/shlfolder.c | 76 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/shlfolder.c b/dlls/shell32/shlfolder.c index 29fd408..e81056b 100644 --- a/dlls/shell32/shlfolder.c +++ b/dlls/shell32/shlfolder.c @@ -380,11 +380,13 @@ HRESULT SHELL32_GetDisplayNameOfChild (I * file: 0x40400177 FILESYSTEM | CANMONIKER * drive 0xF0400154 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER | CANRENAME (LABEL) * - * This function does not set flags!! It only resets flags when necessary. + * According to the MSDN documentation this function should not set flags. It claimes only to reset flags when necessary. + * However it turns out the native shell32.dll _sets_ flags in several cases - so do we. */ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) { DWORD dwAttributes; + BOOL has_guid; static const DWORD dwSupportedAttr= SFGAO_CANCOPY | /*0x00000001 */ SFGAO_CANMOVE | /*0x00000002 */ @@ -409,16 +411,26 @@ HRESULT SHELL32_GetItemAttributes (IShel *pdwAttributes &= dwSupportedAttr; }
+ has_guid = _ILGetGUIDPointer(pidl) != NULL; + dwAttributes = *pdwAttributes;
if (_ILIsDrive (pidl)) { *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR| SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK; - } else if (_ILGetGUIDPointer (pidl) && HCR_GetFolderAttributes(pidl, &dwAttributes)) { + } else if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes)) { *pdwAttributes = dwAttributes; } else if (_ILGetDataPointer (pidl)) { dwAttributes = _ILGetFileAttributes (pidl, NULL, 0);
+ if (!dwAttributes && has_guid) { + WCHAR path[MAX_PATH]; + + /* File attributes are not present in the internal PIDL structure, so get them from the file system. */ + if (SHGetPathFromIDListW(pidl, path)) + dwAttributes = GetFileAttributesW(path); + } + /* Set common attributes */ *pdwAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY; diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 6ab6044..fbbc06d 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -102,6 +102,9 @@ static void test_ParseDisplayName(void) NULL, NULL, cTestDirW, NULL, &newPIDL, 0); ok((hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) || (hr == E_FAIL) || (hr == E_INVALIDARG), "ParseDisplayName returned %08lx, expected 80070002, E_FAIL or E_INVALIDARG\n", hr); + + hr = IShellFolder_Release(IDesktopFolder); + ok(hr == S_OK, "IShellFolder_Release failed %08lx\n", hr); }
/* creates a file with the specified name for tests */ @@ -602,6 +605,13 @@ static void test_GetAttributesOf(void) WCHAR wszMyComputer[] = { ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-', 'A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}',0 }; + char cCurrDirA [MAX_PATH] = {0}; + WCHAR cCurrDirW [MAX_PATH]; + static const WCHAR cTestDirW[] = {'t','e','s','t','d','i','r',0}; + static const WCHAR cBackSlash[] = {'\',0}; + IShellFolder *IDesktopFolder, *testIShellFolder; + ITEMIDLIST *newPIDL; + int len;
hr = SHGetDesktopFolder(&psfDesktop); ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08lx\n", hr); @@ -658,6 +668,69 @@ static void test_GetAttributesOf(void) "Wrong MyComputer attributes: %08lx, expected: %08lx\n", dwFlags, dwMyComputerFlags); }
IShellFolder_Release(psfMyComputer); + + /* create test directory */ + CreateFilesFolders(); + + GetCurrentDirectoryA(MAX_PATH, cCurrDirA); + len = lstrlenA(cCurrDirA); + + if (len == 0) { + trace("GetCurrentDirectoryA returned empty string. Skipping test_EnumObjects_and_CompareIDs\n"); + return; + } + if(cCurrDirA[len-1] == '\') + cCurrDirA[len-1] = 0; + + MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cCurrDirW, MAX_PATH); + + hr = SHGetDesktopFolder(&IDesktopFolder); + ok(hr == S_OK, "SHGetDesktopfolder failed %08lx\n", hr); + + hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cCurrDirW, NULL, &newPIDL, 0); + ok(hr == S_OK, "ParseDisplayName failed %08lx\n", hr); + + hr = IShellFolder_BindToObject(IDesktopFolder, newPIDL, NULL, (REFIID)&IID_IShellFolder, (LPVOID *)&testIShellFolder); + ok(hr == S_OK, "BindToObject failed %08lx\n", hr); + + IMalloc_Free(ppM, newPIDL); + + /* get relative PIDL */ + hr = IShellFolder_ParseDisplayName(testIShellFolder, NULL, NULL, (LPWSTR)cTestDirW, NULL, &newPIDL, 0); + ok(hr == S_OK, "ParseDisplayName failed %08lx\n", hr); + + /* test the shell attributes of the test directory using the relative PIDL */ + dwFlags = SFGAO_FOLDER; + hr = IShellFolder_GetAttributesOf(testIShellFolder, 1, (LPCITEMIDLIST*)&newPIDL, &dwFlags); + ok (SUCCEEDED(hr), "Desktop->GetAttributesOf() failed! hr = %08lx\n", hr); + ok ((dwFlags&SFGAO_FOLDER), "Wrong directory attribute for relative PIDL: %08lx\n", dwFlags); + + /* free memory */ + IMalloc_Free(ppM, newPIDL); + + /* append testdirectory name to path */ + strcatW(cCurrDirW, cBackSlash); + strcatW(cCurrDirW, cTestDirW); + + hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cCurrDirW, NULL, &newPIDL, 0); + ok(hr == S_OK, "ParseDisplayName failed %08lx\n", hr); + + /* test the shell attributes of the test directory using the absolute PIDL */ + dwFlags = SFGAO_FOLDER; + hr = IShellFolder_GetAttributesOf(IDesktopFolder, 1, (LPCITEMIDLIST*)&newPIDL, &dwFlags); + ok (SUCCEEDED(hr), "Desktop->GetAttributesOf() failed! hr = %08lx\n", hr); + ok ((dwFlags&SFGAO_FOLDER), "Wrong directory attribute for absolute PIDL: %08lx\n", dwFlags); + + /* free memory */ + IMalloc_Free(ppM, newPIDL); + + hr = IShellFolder_Release(testIShellFolder); + ok(hr == S_OK, "IShellFolder_Release failed %08lx\n", hr); + + Cleanup(); + + hr = IShellFolder_Release(IDesktopFolder); + ok(hr == S_OK, "IShellFolder_Release failed %08lx\n", hr); }
static void test_SHGetPathFromIDList(void) @@ -822,6 +895,9 @@ static void test_EnumObjects_and_Compare Cleanup();
IMalloc_Free(ppM, newPIDL); + + hr = IShellFolder_Release(IDesktopFolder); + ok(hr == S_OK, "IShellFolder_Release failed %08lx\n", hr); }
/* A simple implementation of an IPropertyBag, which returns fixed values for