Module: wine Branch: refs/heads/master Commit: 5136f57f12e99f2be686e3a6d9b4eaad2e436428 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=5136f57f12e99f2be686e3a6...
Author: Michael Jung mjung@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