Michael Jung : shell32: Helper function for unicode support in folder and file pidls.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jan 3 06:38:08 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 5136f57f12e99f2be686e3a6d9b4eaad2e436428
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=5136f57f12e99f2be686e3a6d9b4eaad2e436428

Author: Michael Jung <mjung at iss.tu-darmstadt.de>
Date:   Tue Jan  3 13:23:44 2006 +0100

shell32: Helper function for unicode support in folder and file pidls.

---

 dlls/shell32/pidl.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++----
 dlls/shell32/pidl.h |   15 ++++++++++++++
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c
index b39fb24..fb85949 100644
--- a/dlls/shell32/pidl.c
+++ b/dlls/shell32/pidl.c
@@ -1811,15 +1811,21 @@ DWORD _ILSimpleGetText (LPCITEMIDLIST pi
  */
 DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR szOut, UINT uOutSize)
 {
-    DWORD    dwReturn;
+    DWORD   dwReturn;
     char    szTemp[MAX_PATH];
+    FileStructW *pFileStructW = _ILGetFileStructW(pidl);
 
     TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);
 
-    dwReturn = _ILSimpleGetText(pidl, szTemp, uOutSize);
+    if (pFileStructW) {
+        lstrcpynW(szOut, pFileStructW->wszName, uOutSize);
+        dwReturn = lstrlenW(pFileStructW->wszName);
+    } else {
+        dwReturn = _ILSimpleGetText(pidl, szTemp, MAX_PATH);
 
-    if (!MultiByteToWideChar(CP_ACP, 0, szTemp, -1, szOut, MAX_PATH))
-        *szOut = 0;
+        if (!MultiByteToWideChar(CP_ACP, 0, szTemp, -1, szOut, uOutSize))
+            *szOut = 0;
+    }
 
     TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_w(szOut),dwReturn);
     return dwReturn;
@@ -1938,6 +1944,45 @@ IID* _ILGetGUIDPointer(LPCITEMIDLIST pid
     return NULL;
 }
 
+/******************************************************************************
+ * _ILGetFileStructW [Internal]
+ *
+ * Get pointer the a SHITEMID's FileStructW field if present
+ *
+ * PARAMS
+ *  pidl [I] The SHITEMID
+ *
+ * RETURNS
+ *  Success: Pointer to pidl's FileStructW field.
+ *  Failure: NULL
+ */
+FileStructW* _ILGetFileStructW(LPCITEMIDLIST pidl) {
+    FileStructW *pFileStructW;
+    WORD cbOffset;
+    
+    if (!(_ILIsValue(pidl) || _ILIsFolder(pidl)))
+        return NULL;
+
+    cbOffset = *(WORD*)((LPBYTE)pidl + pidl->mkid.cb - sizeof(WORD));
+    pFileStructW = (FileStructW*)((LPBYTE)pidl + cbOffset);
+
+    /* Currently I don't see a fool prove way to figure out if a pidl is for sure of WinXP
+     * style with a FileStructW member. If we switch all our shellfolder-implementations to
+     * the new format, this won't be a problem. For now, we do as many sanity checks as possible. */
+    if (cbOffset & 0x1 || /* FileStructW member is word aligned in the pidl */
+        /* FileStructW is positioned after FileStruct */
+        cbOffset < sizeof(pidl->mkid.cb) + sizeof(PIDLTYPE) + sizeof(FileStruct) ||
+        /* There has to be enough space at cbOffset in the pidl to hold FileStructW and cbOffset */
+        cbOffset > pidl->mkid.cb - sizeof(cbOffset) - sizeof(FileStructW) ||
+        pidl->mkid.cb != cbOffset + pFileStructW->cbLen)
+    {
+        WARN("Invalid pidl format (cbOffset = %d)!\n", cbOffset);
+        return NULL;
+    }
+
+    return pFileStructW;
+}
+
 /*************************************************************************
  * _ILGetFileDateTime
  *
diff --git a/dlls/shell32/pidl.h b/dlls/shell32/pidl.h
index df3d1f2..691aa2a 100644
--- a/dlls/shell32/pidl.h
+++ b/dlls/shell32/pidl.h
@@ -143,6 +143,20 @@ typedef struct tagFileStruct
     The second the dos name when needed or just 0x00 */
 } FileStruct;
 
+/* At least on WinXP, this struct is appended with 2-byte-alignment to FileStruct. There follows 
+ * a WORD member after the wszName string, which gives the offset from the beginning of the PIDL 
+ * to the FileStructW member. */
+typedef struct tagFileStructW {
+    WORD cbLen;
+    BYTE dummy1[6];
+    WORD uCreationDate;
+    WORD uCreationTime;
+    WORD uLastAccessDate;
+    WORD uLastAccessTime;
+    BYTE dummy2[4];
+    WCHAR wszName[1];
+} FileStructW;
+
 typedef struct tagValueW
 {
     WCHAR name[1];
@@ -240,6 +254,7 @@ LPPIDLDATA	_ILGetDataPointer	(LPCITEMIDL
 LPSTR		_ILGetTextPointer	(LPCITEMIDLIST);
 LPSTR		_ILGetSTextPointer	(LPCITEMIDLIST);
 IID		*_ILGetGUIDPointer	(LPCITEMIDLIST pidl);
+FileStructW     *_ILGetFileStructW      (LPCITEMIDLIST pidl);
 
 /*
  * debug helper




More information about the wine-cvs mailing list