- Timestamp:
- Dec 5, 2017 12:06:59 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp
r69924 r69925 35 35 #include <iprt/avl.h> 36 36 #include <iprt/assert.h> 37 #include <iprt/ctype.h> 37 38 #include <iprt/file.h> 38 39 #include <iprt/log.h> … … 43 44 #include <iprt/utf16.h> 44 45 #include <iprt/formats/ntfs.h> 46 47 #include <internal/fs.h> /* For RTFSMODE_SYMLINK_REPARSE_TAG. */ 45 48 46 49 … … 1814 1817 1815 1818 1819 /** 1820 * Worker for various QueryInfo methods. 1821 * 1822 * @returns IPRT status code. 1823 * @param pThis The core object structure to return info for. 1824 * @param pAttr The attribute that's being presented. Take the 1825 * allocation and timestamp info from it, if 1826 * non-resident. 1827 * @param pObjInfo Where to return object info. 1828 * @param enmAddAttr What additional info to return. 1829 */ 1830 static int rtFsNtfsCore_QueryInfo(PRTFSNTFSCORE pThis, PRTFSNTFSATTR pAttr, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 1831 { 1832 /* 1833 * Wipe the structure and fill in common dummy value. 1834 */ 1835 RT_ZERO(*pObjInfo); 1836 switch (enmAddAttr) 1837 { 1838 case RTFSOBJATTRADD_UNIX: 1839 pObjInfo->Attr.u.Unix.uid = NIL_RTUID; 1840 pObjInfo->Attr.u.Unix.gid = NIL_RTGID; 1841 pObjInfo->Attr.u.Unix.cHardlinks = 1; 1842 //pObjInfo->Attr.u.Unix.INodeIdDevice = 0; 1843 pObjInfo->Attr.u.Unix.INodeId = pThis->pMftRec->TreeNode.Key; 1844 //pObjInfo->Attr.u.Unix.fFlags = 0; 1845 //pObjInfo->Attr.u.Unix.GenerationId = 0; 1846 //pObjInfo->Attr.u.Unix.Device = 0; 1847 break; 1848 1849 case RTFSOBJATTRADD_UNIX_OWNER: 1850 pObjInfo->Attr.u.UnixOwner.uid = NIL_RTUID; 1851 break; 1852 1853 case RTFSOBJATTRADD_UNIX_GROUP: 1854 pObjInfo->Attr.u.UnixGroup.gid = NIL_RTGID; 1855 break; 1856 1857 default: 1858 break; 1859 } 1860 1861 /* 1862 * Look for the standard information attribute and use that as basis. 1863 */ 1864 uint32_t fFileAttrs; 1865 PRTFSNTFSATTR pStdInfoAttr = rtFsNtfsCore_FindUnnamedAttribute(pThis, NTFS_AT_STANDARD_INFORMATION); 1866 if ( pStdInfoAttr 1867 && pStdInfoAttr->cbResident >= sizeof(NTFSATSTDINFO) ) 1868 { 1869 Assert(!pStdInfoAttr->pAttrHdr->fNonResident); 1870 PCNTFSATSTDINFO pStdInfo = (PCNTFSATSTDINFO)NTFSATTRIBHDR_GET_RES_VALUE_PTR(pStdInfoAttr->pAttrHdr); 1871 RTTimeSpecSetNtTime(&pObjInfo->BirthTime, RT_LE2H_U64(pStdInfo->iCreationTime)); 1872 RTTimeSpecSetNtTime(&pObjInfo->ModificationTime, RT_LE2H_U64(pStdInfo->iLastDataModTime)); 1873 RTTimeSpecSetNtTime(&pObjInfo->ChangeTime, RT_LE2H_U64(pStdInfo->iLastMftModTime)); 1874 RTTimeSpecSetNtTime(&pObjInfo->AccessTime, RT_LE2H_U64(pStdInfo->iLastAccessTime)); 1875 if (enmAddAttr == RTFSOBJATTRADD_UNIX) 1876 { 1877 pObjInfo->Attr.u.Unix.uid = pStdInfo->idOwner; 1878 pObjInfo->Attr.u.Unix.GenerationId = pStdInfo->uFileVersion; 1879 } 1880 else if (enmAddAttr == RTFSOBJATTRADD_UNIX_OWNER) 1881 pObjInfo->Attr.u.UnixOwner.uid = pStdInfo->idOwner; 1882 fFileAttrs = pStdInfo->fFileAttribs; 1883 } 1884 else 1885 { 1886 /** @todo check out the filename record? */ 1887 switch (pAttr->pAttrHdr->uAttrType) 1888 { 1889 default: 1890 AssertFailed(); 1891 case NTFS_AT_DATA: 1892 fFileAttrs = NTFS_FA_NORMAL; 1893 break; 1894 1895 case NTFS_AT_INDEX_ROOT: 1896 case NTFS_AT_INDEX_ALLOCATION: 1897 fFileAttrs = NTFS_FA_DIRECTORY; 1898 break; 1899 } 1900 } 1901 1902 /* 1903 * Take the allocation info from the destilled attribute data. 1904 */ 1905 pObjInfo->cbObject = pAttr->cbValue; 1906 pObjInfo->cbAllocated = pAttr->Extents.cbData; 1907 if ( pAttr->pAttrHdr->fNonResident 1908 && (int64_t)pObjInfo->cbAllocated < (int64_t)RT_LE2H_U64(pAttr->pAttrHdr->u.NonRes.cbAllocated)) 1909 pObjInfo->cbAllocated = RT_LE2H_U64(pAttr->pAttrHdr->u.NonRes.cbAllocated); 1910 1911 1912 /* 1913 * See if we can find a filename record before we try convert the file attributes to mode. 1914 */ 1915 PCNTFSATFILENAME pFilename = NULL; 1916 PRTFSNTFSATTR pFilenameAttr = rtFsNtfsCore_FindUnnamedAttribute(pThis, NTFS_AT_FILENAME); 1917 if ( pFilenameAttr 1918 && pFilenameAttr->cbResident >= RT_UOFFSETOF(NTFSATFILENAME, wszFilename) ) 1919 { 1920 Assert(!pFilenameAttr->pAttrHdr->fNonResident); 1921 pFilename = (PCNTFSATFILENAME)NTFSATTRIBHDR_GET_RES_VALUE_PTR(pFilenameAttr->pAttrHdr); 1922 if (pStdInfoAttr) 1923 fFileAttrs |= pFilename->fFileAttribs; 1924 else 1925 fFileAttrs = pFilename->fFileAttribs; 1926 } 1927 1928 /* 1929 * This attribute conversion code is a slightly modified version of rtFsModeFromDos. 1930 */ 1931 pObjInfo->Attr.fMode = (fFileAttrs << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_NT; 1932 if (fFileAttrs & NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT) 1933 pObjInfo->Attr.fMode |= RTFS_DOS_DIRECTORY; 1934 1935 /* everything is readable. */ 1936 pObjInfo->Attr.fMode |= RTFS_UNIX_IRUSR | RTFS_UNIX_IRGRP | RTFS_UNIX_IROTH; 1937 if (pObjInfo->Attr.fMode & RTFS_DOS_DIRECTORY) 1938 /* directories are executable. */ 1939 pObjInfo->Attr.fMode |= RTFS_TYPE_DIRECTORY | RTFS_UNIX_IXUSR | RTFS_UNIX_IXGRP | RTFS_UNIX_IXOTH; 1940 else 1941 { 1942 pObjInfo->Attr.fMode |= RTFS_TYPE_FILE; 1943 if ( pFilename 1944 && pFilename->cwcFilename >= 4 1945 && RT_UOFFSETOF(NTFSATFILENAME, wszFilename[pFilename->cwcFilename]) <= pFilenameAttr->cbResident) 1946 { 1947 PCRTUTF16 pwcExt = &pFilename->wszFilename[pFilename->cwcFilename - 4]; 1948 if ( *pwcExt++ == '.') 1949 { 1950 /* check for executable extension. */ 1951 if ( (unsigned)pwcExt[0] < 0x7fU 1952 && (unsigned)pwcExt[1] < 0x7fU 1953 && (unsigned)pwcExt[2] < 0x7fU) 1954 { 1955 char szExt[4]; 1956 szExt[0] = RT_C_TO_LOWER(pwcExt[0]); 1957 szExt[1] = RT_C_TO_LOWER(pwcExt[1]); 1958 szExt[2] = RT_C_TO_LOWER(pwcExt[2]); 1959 szExt[3] = '\0'; 1960 if ( !memcmp(szExt, "exe", 4) 1961 || !memcmp(szExt, "bat", 4) 1962 || !memcmp(szExt, "com", 4) 1963 || !memcmp(szExt, "cmd", 4) 1964 || !memcmp(szExt, "btm", 4) 1965 ) 1966 pObjInfo->Attr.fMode |= RTFS_UNIX_IXUSR | RTFS_UNIX_IXGRP | RTFS_UNIX_IXOTH; 1967 } 1968 } 1969 } 1970 } 1971 1972 /* Is it really a symbolic link? */ 1973 if ( (pObjInfo->Attr.fMode & RTFS_DOS_NT_REPARSE_POINT) 1974 && pFilename 1975 && pFilename->u.uReparseTag == RTFSMODE_SYMLINK_REPARSE_TAG) 1976 pObjInfo->Attr.fMode = (pObjInfo->Attr.fMode & ~RTFS_TYPE_MASK) | RTFS_TYPE_SYMLINK; 1977 1978 /* writable? */ 1979 if (!(pObjInfo->Attr.fMode & RTFS_DOS_READONLY)) 1980 pObjInfo->Attr.fMode |= RTFS_UNIX_IWUSR | RTFS_UNIX_IWGRP | RTFS_UNIX_IWOTH; 1981 1982 return VINF_SUCCESS; 1983 } 1984 1816 1985 1817 1986 /* … … 2496 2665 RTUTF16 uc1 = *pwszUpper1++; 2497 2666 RTUTF16 uc2 = *pawcFilename2++; 2498 if ( uc1 != uc2 2499 && uc1 != pawcUpcase[uc2]) 2500 return uc1 < uc2 ? -1 : 1; 2667 if (uc1 != uc2) 2668 { 2669 uc2 = pawcUpcase[uc2]; 2670 if (uc1 != uc2) 2671 return uc1 < uc2 ? -1 : 1; 2672 } 2501 2673 2502 2674 /* Decrement the lengths and loop. */ … … 2615 2787 } 2616 2788 else 2617 { 2618 rtFsNtfsIdxNode_Release(pNode); 2619 LogFlow(("rtFsNtfsDirShrd_Lookup(%s): Not found!\n", pszEntry)); 2620 return VERR_FILE_NOT_FOUND; 2621 } 2789 break; 2622 2790 } 2623 2791 } … … 2812 2980 static DECLCALLBACK(int) rtFsNtfsDir_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 2813 2981 { 2982 PRTFSNTFSDIR pThis = (PRTFSNTFSDIR)pvThis; 2814 2983 Log(("rtFsNtfsDir_QueryInfo\n")); 2815 //PRTFSNTFSDIR pThis = (PRTFSNTFSDIR)pvThis;2816 //return rtFsNtfsCore_QueryInfo(&pThis->pShared->Core, pObjInfo, enmAddAttr);2817 NOREF(pvThis); NOREF(pObjInfo); NOREF(enmAddAttr);2818 return VERR_NOT_IMPLEMENTED;2984 return rtFsNtfsCore_QueryInfo(pThis->pShared->RootInfo.pRootAttr->pCore, 2985 pThis->pShared->RootInfo.pAlloc ? pThis->pShared->RootInfo.pAlloc 2986 : pThis->pShared->RootInfo.pRootAttr, 2987 pObjInfo, enmAddAttr); 2819 2988 } 2820 2989 … … 2939 3108 { 2940 3109 uint32_t fFileAttribs = RT_LE2H_U32(pFilename->fFileAttribs); 2941 switch (fFileAttribs & (NTFS_FA_DIRECTORY | NTFS_FA_REPARSE_POINT ))3110 switch (fFileAttribs & (NTFS_FA_DIRECTORY | NTFS_FA_REPARSE_POINT | NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT)) 2942 3111 { 2943 3112 /* … … 2965 3134 * Directory 2966 3135 */ 3136 case NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT: 3137 case NTFS_FA_DIRECTORY | NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT: 2967 3138 case NTFS_FA_DIRECTORY: 2968 3139 if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY) … … 2992 3163 */ 2993 3164 case NTFS_FA_REPARSE_POINT: 2994 case NTFS_FA_DIRECTORY | NTFS_FA_REPARSE_POINT: 3165 case NTFS_FA_REPARSE_POINT | NTFS_FA_DIRECTORY: 3166 case NTFS_FA_REPARSE_POINT | NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT: 3167 case NTFS_FA_REPARSE_POINT | NTFS_FA_DIRECTORY | NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT: 2995 3168 rc = VERR_NOT_IMPLEMENTED; 2996 3169 break; 2997 3170 2998 3171 default: 2999 rc = VERR_IPE_NOT_REACHED_DEFAULT_CASE; 3172 AssertFailed(); 3173 rc = VERR_FILE_NOT_FOUND; 3000 3174 break; 3001 3175 }
Note:
See TracChangeset
for help on using the changeset viewer.