@@ -257,16 +257,6 @@ OpenEffectiveToken(
257257 return ret;
258258}
259259
260- HRESULT
261- Shell_TranslateIDListAlias (
262- _In_ LPCITEMIDLIST pidl,
263- _In_ HANDLE hToken,
264- _Out_ LPITEMIDLIST *ppidlAlias,
265- _In_ DWORD dwFlags)
266- {
267- return E_FAIL; // FIXME
268- }
269-
270260BOOL BindCtx_ContainsObject (_In_ IBindCtx *pBindCtx, _In_ LPCWSTR pszName)
271261{
272262 CComPtr<IUnknown> punk;
@@ -2091,3 +2081,113 @@ SHGetComputerDisplayNameW(
20912081 // Build a string like "Description (SERVERNAME)"
20922082 return SHELL_BuildDisplayMachineName (pszName, cchNameMax, pszServerName, szDesc);
20932083}
2084+
2085+ typedef struct tagALIAS_MAPPING
2086+ {
2087+ BYTE bFlagMask; // The combination of ALIAS_USER_FOLDER and/or ALIAS_DESKTOP
2088+ BYTE bCommonDesktop;
2089+ WORD nCsidlSrc; // CSIDL_... (source)
2090+ WORD nCsidlDest; // CSIDL_... (destination)
2091+ } ALIAS_MAPPING, *PALIAS_MAPPING;
2092+
2093+ // ! PIDL alias table
2094+ static const ALIAS_MAPPING g_AliasTable[] =
2095+ {
2096+ {
2097+ ALIAS_USER_FOLDER,
2098+ FALSE ,
2099+ CSIDL_PERSONAL | CSIDL_FLAG_NO_ALIAS,
2100+ CSIDL_PERSONAL
2101+ },
2102+ {
2103+ ALIAS_USER_FOLDER | ALIAS_DESKTOP,
2104+ FALSE ,
2105+ CSIDL_COMMON_DOCUMENTS | CSIDL_FLAG_NO_ALIAS,
2106+ CSIDL_COMMON_DOCUMENTS
2107+ },
2108+ {
2109+ ALIAS_DESKTOP,
2110+ FALSE ,
2111+ CSIDL_DESKTOPDIRECTORY,
2112+ CSIDL_DESKTOP
2113+ },
2114+ {
2115+ ALIAS_DESKTOP,
2116+ TRUE ,
2117+ CSIDL_COMMON_DESKTOPDIRECTORY,
2118+ CSIDL_DESKTOP
2119+ }
2120+ };
2121+
2122+ // ! Translate a PIDL to an "alias" PIDL.
2123+ EXTERN_C BOOL
2124+ SHELL32_ReparentAsAliasPidl (
2125+ _In_opt_ HWND hwnd,
2126+ _In_opt_ HANDLE hToken,
2127+ _In_ LPCITEMIDLIST pidlTarget,
2128+ _Out_ LPITEMIDLIST *ppidlNew,
2129+ _In_ DWORD dwFlags)
2130+ {
2131+ if (!pidlTarget || !ppidlNew)
2132+ return FALSE ;
2133+
2134+ *ppidlNew = NULL ;
2135+
2136+ for (SIZE_T iEntry = 0 ; iEntry < _countof (g_AliasTable); ++iEntry)
2137+ {
2138+ const ALIAS_MAPPING *pEntry = &g_AliasTable[iEntry];
2139+
2140+ if (!(dwFlags & pEntry->bFlagMask ))
2141+ continue ;
2142+
2143+ // Get the source root PIDL
2144+ LPITEMIDLIST pidlSrcRoot = NULL ;
2145+ HRESULT hr = SHGetFolderLocation (hwnd, pEntry->nCsidlSrc , hToken, 0 , &pidlSrcRoot);
2146+ if (FAILED (hr))
2147+ continue ;
2148+
2149+ // Check whether the input pidlTarget is under the source folder.
2150+ // If it matches, ILFindChild returns the relative PIDL in the pidlTarget.
2151+ LPCITEMIDLIST pidlRelative = ILFindChild (pidlSrcRoot, pidlTarget);
2152+ if (!pidlRelative) // Not found?
2153+ {
2154+ ILFree (pidlSrcRoot);
2155+ continue ;
2156+ }
2157+
2158+ // Found. Get the destination root PIDL
2159+ LPITEMIDLIST pidlDestRoot = NULL ;
2160+ hr = SHGetFolderLocation (hwnd, pEntry->nCsidlDest , hToken, 0 , &pidlDestRoot);
2161+ if (SUCCEEDED (hr))
2162+ {
2163+ // Create a new PIDL by combining the destination root PIDL and the relative PIDL
2164+ *ppidlNew = ILCombine (pidlDestRoot, pidlRelative);
2165+ if (*ppidlNew)
2166+ {
2167+ // Manipulate specific flags in the PIDL if necessary
2168+ if (pEntry->bCommonDesktop && (*ppidlNew)->mkid .cb )
2169+ {
2170+ UINT cbRoot = ILGetSize (pidlDestRoot);
2171+ PBYTE pAttr = (PBYTE)(*ppidlNew) + cbRoot - sizeof (USHORT);
2172+ *pAttr |= (PT_FS | PT_FS_COMMON_FLAG);
2173+ }
2174+ }
2175+ ILFree (pidlDestRoot);
2176+ }
2177+
2178+ ILFree (pidlSrcRoot);
2179+ break ; // A match was found, so exit the loop
2180+ }
2181+
2182+ return (*ppidlNew != NULL );
2183+ }
2184+
2185+ // ! Translate a PIDL to an "alias" PIDL.
2186+ EXTERN_C HRESULT
2187+ SHELL32_AliasTranslatePidl (
2188+ _In_ LPCITEMIDLIST pidl,
2189+ _Out_ LPITEMIDLIST *ppidlNew,
2190+ _In_ DWORD dwFlags)
2191+ {
2192+ return SHELL32_ReparentAsAliasPidl (NULL , NULL , pidl, ppidlNew, dwFlags) ? S_OK : E_FAIL;
2193+ }
0 commit comments