Commit ad220105 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

shell32: Try to get file status from FileSystemBindData in UNIXFS_path_to_pidl.

parent e6e454ab
...@@ -462,28 +462,6 @@ static BOOL UNIXFS_get_unix_path(LPCWSTR pszDosPath, char *pszCanonicalPath) ...@@ -462,28 +462,6 @@ static BOOL UNIXFS_get_unix_path(LPCWSTR pszDosPath, char *pszCanonicalPath)
} }
/****************************************************************************** /******************************************************************************
* UNIXFS_seconds_since_1970_to_dos_date_time [Internal]
*
* Convert unix time to FAT time
*
* PARAMS
* ss1970 [I] Unix time (seconds since 1970)
* pDate [O] Corresponding FAT date
* pTime [O] Corresponding FAT time
*/
static inline void UNIXFS_seconds_since_1970_to_dos_date_time(
time_t ss1970, LPWORD pDate, LPWORD pTime)
{
LARGE_INTEGER time;
FILETIME fileTime;
RtlSecondsSince1970ToTime( ss1970, &time );
fileTime.dwLowDateTime = time.u.LowPart;
fileTime.dwHighDateTime = time.u.HighPart;
FileTimeToDosDateTime(&fileTime, pDate, pTime);
}
/******************************************************************************
* UNIXFS_build_shitemid [Internal] * UNIXFS_build_shitemid [Internal]
* *
* Constructs a new SHITEMID for the last component of path 'pszUnixPath' into * Constructs a new SHITEMID for the last component of path 'pszUnixPath' into
...@@ -503,45 +481,52 @@ static inline void UNIXFS_seconds_since_1970_to_dos_date_time( ...@@ -503,45 +481,52 @@ static inline void UNIXFS_seconds_since_1970_to_dos_date_time(
* If what you need is a PIDLLIST with a single SHITEMID, don't forget to append * If what you need is a PIDLLIST with a single SHITEMID, don't forget to append
* a 0 USHORT value. * a 0 USHORT value.
*/ */
static char* UNIXFS_build_shitemid(char *pszUnixPath, LPBC pbc, void *pIDL) { static char* UNIXFS_build_shitemid(char *pszUnixPath, BOOL bMustExist, WIN32_FIND_DATAW *pFindData, void *pIDL) {
LPPIDLDATA pIDLData; LPPIDLDATA pIDLData;
struct stat fileStat; struct stat fileStat;
WIN32_FIND_DATAW findData;
char *pszComponentU, *pszComponentA; char *pszComponentU, *pszComponentA;
WCHAR *pwszComponentW; WCHAR *pwszComponentW;
int cComponentULen, cComponentALen; int cComponentULen, cComponentALen;
USHORT cbLen; USHORT cbLen;
FileStructW *pFileStructW; FileStructW *pFileStructW;
WORD uOffsetW, *pOffsetW; WORD uOffsetW, *pOffsetW;
BOOL must_exist = TRUE;
TRACE("(pszUnixPath=%s, pbc=%p, pIDL=%p)\n", debugstr_a(pszUnixPath), pbc, pIDL); TRACE("(pszUnixPath=%s, bMustExsist=%s, pFindData=%p, pIDL=%p)\n",
debugstr_a(pszUnixPath), bMustExist ? "T" : "F", pFindData, pIDL);
if (pbc){ if (pFindData)
IUnknown *unk; memcpy(&findData, pFindData, sizeof(WIN32_FIND_DATAW));
IFileSystemBindData *fsb; else {
HRESULT hr; memset(&findData, 0, sizeof(WIN32_FIND_DATAW));
findData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
hr = IBindCtx_GetObjectParam(pbc, (LPOLESTR)wFileSystemBindData, &unk);
if (SUCCEEDED(hr)) {
hr = IUnknown_QueryInterface(unk, &IID_IFileSystemBindData, (LPVOID*)&fsb);
if (SUCCEEDED(hr)) {
/* Windows tries to get WIN32_FIND_DATAW structure from
* fsb here for no known reason */
must_exist = FALSE;
IFileSystemBindData_Release(fsb);
}
IUnknown_Release(unk);
}
} }
/* We are only interested in regular files and directories. */ /* We are only interested in regular files and directories. */
if (stat(pszUnixPath, &fileStat)){ if (stat(pszUnixPath, &fileStat)){
if (must_exist || errno != ENOENT) if (bMustExist || errno != ENOENT)
return NULL; return NULL;
}else } else {
if (!S_ISDIR(fileStat.st_mode) && !S_ISREG(fileStat.st_mode)) LARGE_INTEGER time;
if (S_ISDIR(fileStat.st_mode))
findData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
else if (S_ISREG(fileStat.st_mode))
findData.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
else
return NULL; return NULL;
findData.nFileSizeLow = (DWORD)fileStat.st_size;
findData.nFileSizeHigh = fileStat.st_size >> 32;
RtlSecondsSince1970ToTime(fileStat.st_mtime, &time);
findData.ftLastWriteTime.dwLowDateTime = time.u.LowPart;
findData.ftLastWriteTime.dwHighDateTime = time.u.HighPart;
RtlSecondsSince1970ToTime(fileStat.st_atime, &time);
findData.ftLastAccessTime.dwLowDateTime = time.u.LowPart;
findData.ftLastAccessTime.dwHighDateTime = time.u.HighPart;
}
/* Compute the SHITEMID's length and wipe it. */ /* Compute the SHITEMID's length and wipe it. */
pszComponentU = strrchr(pszUnixPath, '/') + 1; pszComponentU = strrchr(pszUnixPath, '/') + 1;
cComponentULen = strlen(pszComponentU); cComponentULen = strlen(pszComponentU);
...@@ -552,12 +537,12 @@ static char* UNIXFS_build_shitemid(char *pszUnixPath, LPBC pbc, void *pIDL) { ...@@ -552,12 +537,12 @@ static char* UNIXFS_build_shitemid(char *pszUnixPath, LPBC pbc, void *pIDL) {
/* Set shell32's standard SHITEMID data fields. */ /* Set shell32's standard SHITEMID data fields. */
pIDLData = _ILGetDataPointer(pIDL); pIDLData = _ILGetDataPointer(pIDL);
pIDLData->type = S_ISDIR(fileStat.st_mode) ? PT_FOLDER : PT_VALUE; pIDLData->type = (findData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) ? PT_FOLDER : PT_VALUE;
pIDLData->u.file.dwFileSize = (DWORD)fileStat.st_size; pIDLData->u.file.dwFileSize = findData.nFileSizeLow;
UNIXFS_seconds_since_1970_to_dos_date_time(fileStat.st_mtime, &pIDLData->u.file.uFileDate, FileTimeToDosDateTime(&findData.ftLastWriteTime, &pIDLData->u.file.uFileDate,
&pIDLData->u.file.uFileTime); &pIDLData->u.file.uFileTime);
pIDLData->u.file.uFileAttribs = 0; pIDLData->u.file.uFileAttribs = 0;
if (S_ISDIR(fileStat.st_mode)) pIDLData->u.file.uFileAttribs |= FILE_ATTRIBUTE_DIRECTORY; pIDLData->u.file.uFileAttribs |= findData.dwFileAttributes;
if (pszComponentU[0] == '.') pIDLData->u.file.uFileAttribs |= FILE_ATTRIBUTE_HIDDEN; if (pszComponentU[0] == '.') pIDLData->u.file.uFileAttribs |= FILE_ATTRIBUTE_HIDDEN;
cComponentALen = lstrlenA(pszComponentA) + 1; cComponentALen = lstrlenA(pszComponentA) + 1;
memcpy(pIDLData->u.file.szNames, pszComponentA, cComponentALen); memcpy(pIDLData->u.file.szNames, pszComponentA, cComponentALen);
...@@ -565,9 +550,9 @@ static char* UNIXFS_build_shitemid(char *pszUnixPath, LPBC pbc, void *pIDL) { ...@@ -565,9 +550,9 @@ static char* UNIXFS_build_shitemid(char *pszUnixPath, LPBC pbc, void *pIDL) {
pFileStructW = (FileStructW*)(pIDLData->u.file.szNames + cComponentALen + (cComponentALen & 0x1)); pFileStructW = (FileStructW*)(pIDLData->u.file.szNames + cComponentALen + (cComponentALen & 0x1));
uOffsetW = (WORD)(((LPBYTE)pFileStructW) - ((LPBYTE)pIDL)); uOffsetW = (WORD)(((LPBYTE)pFileStructW) - ((LPBYTE)pIDL));
pFileStructW->cbLen = cbLen - uOffsetW; pFileStructW->cbLen = cbLen - uOffsetW;
UNIXFS_seconds_since_1970_to_dos_date_time(fileStat.st_mtime, &pFileStructW->uCreationDate, FileTimeToDosDateTime(&findData.ftLastWriteTime, &pFileStructW->uCreationDate,
&pFileStructW->uCreationTime); &pFileStructW->uCreationTime);
UNIXFS_seconds_since_1970_to_dos_date_time(fileStat.st_atime, &pFileStructW->uLastAccessDate, FileTimeToDosDateTime(&findData.ftLastAccessTime, &pFileStructW->uLastAccessDate,
&pFileStructW->uLastAccessTime); &pFileStructW->uLastAccessTime);
lstrcpyW(pFileStructW->wszName, pwszComponentW); lstrcpyW(pFileStructW->wszName, pwszComponentW);
...@@ -601,6 +586,8 @@ static HRESULT UNIXFS_path_to_pidl(UnixFolder *pUnixFolder, LPBC pbc, const WCHA ...@@ -601,6 +586,8 @@ static HRESULT UNIXFS_path_to_pidl(UnixFolder *pUnixFolder, LPBC pbc, const WCHA
int cPidlLen, cPathLen; int cPidlLen, cPathLen;
char *pSlash, *pNextSlash, szCompletePath[FILENAME_MAX], *pNextPathElement, *pszAPath; char *pSlash, *pNextSlash, szCompletePath[FILENAME_MAX], *pNextPathElement, *pszAPath;
WCHAR *pwszPath; WCHAR *pwszPath;
WIN32_FIND_DATAW find_data;
BOOL must_exist = TRUE;
TRACE("pUnixFolder=%p, pbc=%p, path=%s, ppidl=%p\n", pUnixFolder, pbc, debugstr_w(path), ppidl); TRACE("pUnixFolder=%p, pbc=%p, path=%s, ppidl=%p\n", pUnixFolder, pbc, debugstr_w(path), ppidl);
...@@ -691,11 +678,32 @@ static HRESULT UNIXFS_path_to_pidl(UnixFolder *pUnixFolder, LPBC pbc, const WCHA ...@@ -691,11 +678,32 @@ static HRESULT UNIXFS_path_to_pidl(UnixFolder *pUnixFolder, LPBC pbc, const WCHA
*ppidl = pidl = SHAlloc(cPidlLen); *ppidl = pidl = SHAlloc(cPidlLen);
if (!pidl) return E_FAIL; if (!pidl) return E_FAIL;
if (pbc) {
IUnknown *unk;
IFileSystemBindData *fsb;
HRESULT hr;
hr = IBindCtx_GetObjectParam(pbc, (LPOLESTR)wFileSystemBindData, &unk);
if (SUCCEEDED(hr)) {
hr = IUnknown_QueryInterface(unk, &IID_IFileSystemBindData, (LPVOID*)&fsb);
if (SUCCEEDED(hr)) {
hr = IFileSystemBindData_GetFindData(fsb, &find_data);
if (FAILED(hr))
memset(&find_data, 0, sizeof(WIN32_FIND_DATAW));
must_exist = FALSE;
IFileSystemBindData_Release(fsb);
}
IUnknown_Release(unk);
}
}
/* Concatenate the SHITEMIDs of the sub-directories. */ /* Concatenate the SHITEMIDs of the sub-directories. */
while (*pNextPathElement) { while (*pNextPathElement) {
pSlash = strchr(pNextPathElement+1, '/'); pSlash = strchr(pNextPathElement+1, '/');
if (pSlash) *pSlash = '\0'; if (pSlash) *pSlash = '\0';
pNextPathElement = UNIXFS_build_shitemid(szCompletePath, pbc, pidl); pNextPathElement = UNIXFS_build_shitemid(szCompletePath, must_exist,
must_exist&&!pSlash ? &find_data : NULL, pidl);
if (pSlash) *pSlash = '/'; if (pSlash) *pSlash = '/';
if (!pNextPathElement) { if (!pNextPathElement) {
...@@ -2426,7 +2434,7 @@ static HRESULT WINAPI UnixSubFolderIterator_IEnumIDList_Next(IEnumIDList* iface, ...@@ -2426,7 +2434,7 @@ static HRESULT WINAPI UnixSubFolderIterator_IEnumIDList_Next(IEnumIDList* iface,
lstrcpyA(pszRelativePath, pDirEntry->d_name); lstrcpyA(pszRelativePath, pDirEntry->d_name);
rgelt[i] = SHAlloc( rgelt[i] = SHAlloc(
UNIXFS_shitemid_len_from_filename(pszRelativePath, NULL, NULL)+sizeof(USHORT)); UNIXFS_shitemid_len_from_filename(pszRelativePath, NULL, NULL)+sizeof(USHORT));
if (!UNIXFS_build_shitemid(This->m_szFolder, NULL, rgelt[i]) || if (!UNIXFS_build_shitemid(This->m_szFolder, TRUE, NULL, rgelt[i]) ||
!UNIXFS_is_pidl_of_type(rgelt[i], This->m_fFilter)) !UNIXFS_is_pidl_of_type(rgelt[i], This->m_fFilter))
{ {
SHFree(rgelt[i]); SHFree(rgelt[i]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment