Michael Jung : shell32: Added some test to document native ITEMIDLIST
format.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Dec 22 11:11:25 CST 2005
Module: wine
Branch: refs/heads/master
Commit: 259fd0340752477dbed99d5fdb6d82276911a838
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=259fd0340752477dbed99d5fdb6d82276911a838
Author: Michael Jung <mjung at iss.tu-darmstadt.de>
Date: Thu Dec 22 17:16:11 2005 +0100
shell32: Added some test to document native ITEMIDLIST format.
---
dlls/shell32/tests/shlfolder.c | 150 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 150 insertions(+), 0 deletions(-)
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index 8c0d7f7..7a51844 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -1059,6 +1059,155 @@ void test_FolderShortcut(void) {
IPersistFolder3_Release(pPersistFolder3);
}
+#include "pshpack1.h"
+struct FileStructA {
+ BYTE type;
+ BYTE dummy;
+ DWORD dwFileSize;
+ WORD uFileDate; /* In our current implementation this is */
+ WORD uFileTime; /* FileTimeToDosDate(WIN32_FIND_DATA->ftLastWriteTime) */
+ WORD uFileAttribs;
+ CHAR szName[1];
+};
+
+struct FileStructW {
+ WORD cbLen; /* Length of this element. */
+ BYTE abFooBar1[6]; /* Beyond any recognition. */
+ WORD uDate; /* FileTimeToDosDate(WIN32_FIND_DATA->ftCreationTime)? */
+ WORD uTime; /* (this is currently speculation) */
+ WORD uDate2; /* FileTimeToDosDate(WIN32_FIND_DATA->ftLastAccessTime)? */
+ WORD uTime2; /* (this is currently speculation) */
+ BYTE abFooBar2[4]; /* Beyond any recognition. */
+ WCHAR wszName[1]; /* The long filename in unicode. */
+ /* Just for documentation: Right after the unicode string: */
+ WORD cbOffset; /* FileStructW's offset from the beginning of the SHITMEID.
+ * SHITEMID->cb == uOffset + cbLen */
+};
+#include "poppack.h"
+
+void test_ITEMIDLIST_format(void) {
+ WCHAR wszPersonal[MAX_PATH];
+ LPSHELLFOLDER psfDesktop, psfPersonal;
+ LPITEMIDLIST pidlPersonal, pidlFile;
+ HANDLE hFile;
+ HRESULT hr;
+ BOOL bResult;
+ WCHAR wszFile[3][17] = { { 'e','v','e','n','_',0 }, { 'o','d','d','_',0 },
+ { 'l','o','n','g','e','r','_','t','h','a','n','.','8','_','3',0 } };
+ int i;
+
+ if(!pSHGetSpecialFolderPathW) return;
+
+ bResult = pSHGetSpecialFolderPathW(NULL, wszPersonal, CSIDL_PERSONAL, FALSE);
+ ok(bResult, "SHGetSpecialFolderPathW failed! Last error: %08lx\n", GetLastError());
+ if (!bResult) return;
+
+ bResult = SetCurrentDirectoryW(wszPersonal);
+ ok(bResult, "SetCurrentDirectory failed! Last error: %ld\n", GetLastError());
+ if (!bResult) return;
+
+ hr = SHGetDesktopFolder(&psfDesktop);
+ ok(SUCCEEDED(hr), "SHGetDesktopFolder failed! hr: %08lx\n", hr);
+ if (FAILED(hr)) return;
+
+ hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, wszPersonal, NULL, &pidlPersonal, NULL);
+ ok(SUCCEEDED(hr), "psfDesktop->ParseDisplayName failed! hr = %08lx\n", hr);
+ if (FAILED(hr)) {
+ IShellFolder_Release(psfDesktop);
+ return;
+ }
+
+ hr = IShellFolder_BindToObject(psfDesktop, pidlPersonal, NULL, &IID_IShellFolder,
+ (LPVOID*)&psfPersonal);
+ IShellFolder_Release(psfDesktop);
+ ILFree(pidlPersonal);
+ ok(SUCCEEDED(hr), "psfDesktop->BindToObject failed! hr = %08lx\n", hr);
+ if (FAILED(hr)) return;
+
+ for (i=0; i<3; i++) {
+ CHAR szFile[MAX_PATH];
+ struct FileStructA *pFileStructA;
+ WORD cbOffset;
+
+ WideCharToMultiByte(CP_ACP, 0, wszFile[i], -1, szFile, MAX_PATH, NULL, NULL);
+
+ hFile = CreateFileW(wszFile[i], GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_FLAG_WRITE_THROUGH, NULL);
+ ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed! (%ld)\n", GetLastError());
+ if (hFile == INVALID_HANDLE_VALUE) {
+ IShellFolder_Release(psfPersonal);
+ return;
+ }
+ CloseHandle(hFile);
+
+ hr = IShellFolder_ParseDisplayName(psfPersonal, NULL, NULL, wszFile[i], NULL, &pidlFile, NULL);
+ DeleteFileW(wszFile[i]);
+ ok(SUCCEEDED(hr), "psfPersonal->ParseDisplayName failed! hr: %08lx\n", hr);
+ if (FAILED(hr)) {
+ IShellFolder_Release(psfPersonal);
+ return;
+ }
+
+ pFileStructA = (struct FileStructA *)pidlFile->mkid.abID;
+ ok(pFileStructA->type == 0x32, "PIDLTYPE should be 0x32!\n");
+ ok(pFileStructA->dummy == 0x00, "Dummy Byte should be 0x00!\n");
+ ok(pFileStructA->dwFileSize == 0, "Filesize should be zero!\n");
+
+ if (i < 2) /* First two file names are already in valid 8.3 format */
+ ok(!strcmp(szFile, (CHAR*)&pidlFile->mkid.abID[12]), "Wrong file name!\n");
+ else
+ /* WinXP stores a derived 8.3 dos name (LONGER~1.8_3) here. We probably
+ * can't implement this correctly, since unix filesystems don't support
+ * this nasty short/long filename stuff. So we'll probably stay with our
+ * current habbit of storing the long filename here, which seems to work
+ * just fine. */
+ todo_wine { ok(pidlFile->mkid.abID[18] == '~', "Should be derived 8.3 name!\n"); }
+
+ if (i == 0) /* First file name has an even number of chars. No need for alignment. */
+ todo_wine { ok(pidlFile->mkid.abID[12 + strlen(szFile) + 1] != '\0',
+ "Alignment byte, where there shouldn't be!\n"); }
+
+ if (i == 1) /* Second file name has an uneven number of chars => alignment byte */
+ ok(pidlFile->mkid.abID[12 + strlen(szFile) + 1] == '\0',
+ "There should be an alignment byte, but isn't!\n");
+
+ /* The offset of the FileStructW member is stored as a WORD at the end of the pidl. */
+ cbOffset = *(WORD*)(((LPBYTE)pidlFile)+pidlFile->mkid.cb-sizeof(WORD));
+ todo_wine { ok (cbOffset >= sizeof(struct FileStructA) &&
+ cbOffset <= pidlFile->mkid.cb - sizeof(struct FileStructW),
+ "Wrong offset value (%d) stored at the end of the PIDL\n", cbOffset); }
+
+ if (cbOffset >= sizeof(struct FileStructA) &&
+ cbOffset <= pidlFile->mkid.cb - sizeof(struct FileStructW))
+ {
+ struct FileStructW *pFileStructW = (struct FileStructW *)(((LPBYTE)pidlFile)+cbOffset);
+
+ ok(pidlFile->mkid.cb == cbOffset + pFileStructW->cbLen,
+ "FileStructW's offset and length should add up to the PIDL's length!\n");
+
+ if (pidlFile->mkid.cb == cbOffset + pFileStructW->cbLen) {
+ /* Since we just created the file, time of creation,
+ * time of last access and time of last write access just be the same.
+ * These tests seem to fail sometimes (on WinXP), if the test is run again shortly
+ * after the first run. I do remember something with NTFS keeping the creation time
+ * if a file is deleted and then created again within a couple of seconds or so.
+ * Might be the reason. */
+ ok (pFileStructA->uFileDate == pFileStructW->uDate &&
+ pFileStructA->uFileTime == pFileStructW->uTime,
+ "Last write time should match creation time!\n");
+
+ ok (pFileStructA->uFileDate == pFileStructW->uDate2 &&
+ pFileStructA->uFileTime == pFileStructW->uTime2,
+ "Last write time should match last access time!\n");
+
+ ok (!lstrcmpW(wszFile[i], pFileStructW->wszName),
+ "The filename should be stored in unicode at this position!\n");
+ }
+ }
+
+ ILFree(pidlFile);
+ }
+}
+
START_TEST(shlfolder)
{
init_function_pointers();
@@ -1074,6 +1223,7 @@ START_TEST(shlfolder)
test_SHGetPathFromIDList();
test_CallForAttributes();
test_FolderShortcut();
+ test_ITEMIDLIST_format();
OleUninitialize();
}
More information about the wine-cvs
mailing list