Allow for unixfs folders to be rooted at desktop level.
Moved dos->unix path conversion into canonicalize_path. Fail in BindToObject, if called with empty pidl.
This commit is contained in:
parent
5c9b7cf55f
commit
d20fde8a80
@ -175,29 +175,33 @@ static char* UNIXFS_build_shitemid(char *name, struct stat *pStat, void *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* UNIXFS_canonicalize_path [Internal]
|
* UNIXFS_get_unix_path [Internal]
|
||||||
*
|
*
|
||||||
* Evaluate "/.", "/.." and symbolic links for an absolute unix path.
|
* Convert an absolute dos path to an absolute canonicalized unix path.
|
||||||
|
* Evaluate "/.", "/.." and symbolic links.
|
||||||
*
|
*
|
||||||
* PARAMS
|
* PARAMS
|
||||||
* pszUnixPath [I] An absolute unix path
|
* pszDosPath [I] An absolute dos path
|
||||||
* pszCanonicalPath [O] Buffer of length FILENAME_MAX. Will receive the canonical path.
|
* pszCanonicalPath [O] Buffer of length FILENAME_MAX. Will receive the canonical path.
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Success, TRUE
|
* Success, TRUE
|
||||||
* Failure, FALSE - Path not existent, too long, insufficient rights, to many symlinks
|
* Failure, FALSE - Path not existent, too long, insufficient rights, to many symlinks
|
||||||
*/
|
*/
|
||||||
static BOOL UNIXFS_canonicalize_path(const char *pszUnixPath, char *pszCanonicalPath)
|
static BOOL UNIXFS_get_unix_path(LPCWSTR pszDosPath, char *pszCanonicalPath)
|
||||||
{
|
{
|
||||||
char *pPathTail, *pElement, *pCanonicalTail, szPath[FILENAME_MAX];
|
char *pPathTail, *pElement, *pCanonicalTail, szPath[FILENAME_MAX], *pszUnixPath;
|
||||||
struct stat fileStat;
|
struct stat fileStat;
|
||||||
|
|
||||||
TRACE("(pszUnixPath=%s, pszCanonicalPath=%p)\n", debugstr_a(pszUnixPath), pszCanonicalPath);
|
TRACE("(pszDosPath=%s, pszCanonicalPath=%p)\n", debugstr_w(pszDosPath), pszCanonicalPath);
|
||||||
|
|
||||||
if (!pszUnixPath || *pszUnixPath != '/')
|
if (!pszDosPath || pszDosPath[1] != ':')
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
pszUnixPath = wine_get_unix_file_name(pszDosPath);
|
||||||
|
if (!pszUnixPath) return FALSE;
|
||||||
strcpy(szPath, pszUnixPath);
|
strcpy(szPath, pszUnixPath);
|
||||||
|
HeapFree(GetProcessHeap(), 0, pszUnixPath);
|
||||||
|
|
||||||
/* pCanonicalTail always points to the end of the canonical path constructed
|
/* pCanonicalTail always points to the end of the canonical path constructed
|
||||||
* thus far. pPathTail points to the still to be processed part of the input
|
* thus far. pPathTail points to the still to be processed part of the input
|
||||||
@ -328,12 +332,8 @@ static BOOL UNIXFS_path_to_pidl(UnixFolder *pUnixFolder, const WCHAR *path, LPIT
|
|||||||
if ((pUnixFolder->m_dwPathMode == PATHMODE_DOS) && (path[1] == ':'))
|
if ((pUnixFolder->m_dwPathMode == PATHMODE_DOS) && (path[1] == ':'))
|
||||||
{
|
{
|
||||||
/* Absolute dos path. Convert to unix */
|
/* Absolute dos path. Convert to unix */
|
||||||
char *pszUnixPath = wine_get_unix_file_name(path);
|
if (!UNIXFS_get_unix_path(path, szCompletePath))
|
||||||
if (!UNIXFS_canonicalize_path(pszUnixPath, szCompletePath)) {
|
|
||||||
HeapFree(GetProcessHeap(), 0, pszUnixPath);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
HeapFree(GetProcessHeap(), 0, pszUnixPath);
|
|
||||||
pNextPathElement = szCompletePath + 1;
|
pNextPathElement = szCompletePath + 1;
|
||||||
}
|
}
|
||||||
else if ((pUnixFolder->m_dwPathMode == PATHMODE_UNIX) && (path[0] == '/'))
|
else if ((pUnixFolder->m_dwPathMode == PATHMODE_UNIX) && (path[0] == '/'))
|
||||||
@ -423,29 +423,45 @@ static BOOL UNIXFS_path_to_pidl(UnixFolder *pUnixFolder, const WCHAR *path, LPIT
|
|||||||
static BOOL UNIXFS_pidl_to_path(LPCITEMIDLIST pidl, UnixFolder *pUnixFolder) {
|
static BOOL UNIXFS_pidl_to_path(LPCITEMIDLIST pidl, UnixFolder *pUnixFolder) {
|
||||||
LPCITEMIDLIST current = pidl, root;
|
LPCITEMIDLIST current = pidl, root;
|
||||||
DWORD dwPathLen;
|
DWORD dwPathLen;
|
||||||
char *pNextDir;
|
char *pNextDir, szBasePath[FILENAME_MAX] = "/";
|
||||||
|
|
||||||
TRACE("(pidl=%p, pUnixFolder=%p)\n", pidl, pUnixFolder);
|
TRACE("(pidl=%p, pUnixFolder=%p)\n", pidl, pUnixFolder);
|
||||||
|
pdump(pidl);
|
||||||
|
|
||||||
pUnixFolder->m_pszPath = NULL;
|
pUnixFolder->m_pszPath = NULL;
|
||||||
|
|
||||||
/* Find the UnixFolderClass root */
|
/* Find the UnixFolderClass root */
|
||||||
while (current->mkid.cb) {
|
while (current->mkid.cb) {
|
||||||
LPPIDLDATA pData = _ILGetDataPointer(current);
|
if (_ILIsDrive(current) || /* The dos drive, which maps to '/' */
|
||||||
if (!pData) return FALSE;
|
(_ILIsSpecialFolder(current) &&
|
||||||
if (pData->type == PT_GUID &&
|
(IsEqualIID(&CLSID_UnixFolder, _ILGetGUIDPointer(current)) ||
|
||||||
(IsEqualIID(&CLSID_UnixFolder, &pData->u.guid.guid) ||
|
IsEqualIID(&CLSID_UnixDosFolder, _ILGetGUIDPointer(current)))))
|
||||||
IsEqualIID(&CLSID_UnixDosFolder, &pData->u.guid.guid)))
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
current = ILGetNext(current);
|
current = ILGetNext(current);
|
||||||
}
|
}
|
||||||
root = current = ILGetNext(current);
|
|
||||||
|
if (current && current->mkid.cb) {
|
||||||
|
root = current = ILGetNext(current);
|
||||||
|
dwPathLen = 2; /* For the '/' prefix and the terminating '\0' */
|
||||||
|
} else if (_ILIsDesktop(pidl) || _ILIsValue(pidl) || _ILIsFolder(pidl)) {
|
||||||
|
/* Path rooted at Desktop */
|
||||||
|
WCHAR wszDesktopPath[MAX_PATH];
|
||||||
|
if (FAILED(SHGetSpecialFolderPathW(0, wszDesktopPath, CSIDL_DESKTOP, FALSE)))
|
||||||
|
return FALSE;
|
||||||
|
if (!UNIXFS_get_unix_path(wszDesktopPath, szBasePath))
|
||||||
|
return FALSE;
|
||||||
|
dwPathLen = strlen(szBasePath) + 1;
|
||||||
|
root = current;
|
||||||
|
} else {
|
||||||
|
ERR("Unknown pidl type!\n");
|
||||||
|
pdump(pidl);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine the path's length bytes */
|
/* Determine the path's length bytes */
|
||||||
dwPathLen = 2; /* For the '/' prefix and the terminating '\0' */
|
while (current && current->mkid.cb) {
|
||||||
while (current->mkid.cb) {
|
|
||||||
dwPathLen += NAME_LEN_FROM_LPSHITEMID(current) + 1; /* For the '/' */
|
dwPathLen += NAME_LEN_FROM_LPSHITEMID(current) + 1; /* For the '/' */
|
||||||
current = ILGetNext(current);
|
current = ILGetNext(current);
|
||||||
};
|
};
|
||||||
@ -457,8 +473,9 @@ static BOOL UNIXFS_pidl_to_path(LPCITEMIDLIST pidl, UnixFolder *pUnixFolder) {
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
current = root;
|
current = root;
|
||||||
*pNextDir++ = '/';
|
strcpy(pNextDir, szBasePath);
|
||||||
while (current->mkid.cb) {
|
pNextDir += strlen(szBasePath);
|
||||||
|
while (current && current->mkid.cb) {
|
||||||
memcpy(pNextDir, _ILGetTextPointer(current), NAME_LEN_FROM_LPSHITEMID(current));
|
memcpy(pNextDir, _ILGetTextPointer(current), NAME_LEN_FROM_LPSHITEMID(current));
|
||||||
pNextDir += NAME_LEN_FROM_LPSHITEMID(current);
|
pNextDir += NAME_LEN_FROM_LPSHITEMID(current);
|
||||||
*pNextDir++ = '/';
|
*pNextDir++ = '/';
|
||||||
@ -782,6 +799,9 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_BindToObject(IShellFolder2* iface
|
|||||||
TRACE("(iface=%p, pidl=%p, pbcReserver=%p, riid=%p, ppvOut=%p)\n",
|
TRACE("(iface=%p, pidl=%p, pbcReserver=%p, riid=%p, ppvOut=%p)\n",
|
||||||
iface, pidl, pbcReserved, riid, ppvOut);
|
iface, pidl, pbcReserved, riid, ppvOut);
|
||||||
|
|
||||||
|
if (!pidl || !pidl->mkid.cb)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (This->m_dwPathMode == PATHMODE_DOS)
|
if (This->m_dwPathMode == PATHMODE_DOS)
|
||||||
hr = UnixDosFolder_Constructor(NULL, &IID_IPersistFolder2, (void**)&persistFolder);
|
hr = UnixDosFolder_Constructor(NULL, &IID_IPersistFolder2, (void**)&persistFolder);
|
||||||
else
|
else
|
||||||
@ -1157,7 +1177,8 @@ static HRESULT WINAPI UnixFolder_IPersistFolder2_Initialize(IPersistFolder2* ifa
|
|||||||
|
|
||||||
pdump(pidl);
|
pdump(pidl);
|
||||||
|
|
||||||
UNIXFS_pidl_to_path(pidl, This);
|
if (!UNIXFS_pidl_to_path(pidl, This))
|
||||||
|
return E_FAIL;
|
||||||
UNIXFS_build_subfolder_pidls(This);
|
UNIXFS_build_subfolder_pidls(This);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user