Changeset 69943 in vbox
- Timestamp:
- Dec 5, 2017 11:40:52 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119441
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp
r69938 r69943 296 296 297 297 /** 298 * Pointer to a shared NTFS directory object.298 * Shared NTFS directory object. 299 299 */ 300 300 typedef struct RTFSNTFSDIRSHRD … … 341 341 typedef RTFSNTFSDIR *PRTFSNTFSDIR; 342 342 343 344 /** 345 * Shared NTFS file object. 346 */ 347 typedef struct RTFSNTFSFILESHRD 348 { 349 /** Reference counter. */ 350 uint32_t volatile cRefs; 351 /** Pointer to the data attribute (core is referenced thru this). */ 352 PRTFSNTFSATTR pData; 353 } RTFSNTFSFILESHRD; 354 /** Pointer to shared data for a file or data stream. */ 355 typedef RTFSNTFSFILESHRD *PRTFSNTFSFILESHRD; 356 357 358 /** 359 * Open NTFS file instance. 360 */ 361 typedef struct RTFSNTFSFILE 362 { 363 /** Pointer to the shared file data (referenced). */ 364 PRTFSNTFSFILESHRD pShared; 365 /** Current file offset. */ 366 uint64_t offFile; 367 } RTFSNTFSFILE; 368 /** Pointer to an NTFS open file instance. */ 369 typedef RTFSNTFSFILE *PRTFSNTFSFILE; 343 370 344 371 /** … … 1987 2014 pObjInfo->cbAllocated = RT_LE2H_U64(pAttr->pAttrHdr->u.NonRes.cbAllocated); 1988 2015 1989 1990 2016 /* 1991 2017 * See if we can find a filename record before we try convert the file attributes to mode. … … 2012 2038 return VINF_SUCCESS; 2013 2039 } 2040 2041 2042 2043 2044 /* 2045 * 2046 * File operations. 2047 * File operations. 2048 * File operations. 2049 * 2050 */ 2051 2052 /** 2053 * Releases a reference to a shared NTFS file structure. 2054 * 2055 * @returns New reference count. 2056 * @param pShared The shared NTFS file structure. 2057 */ 2058 static uint32_t rtFsNtfsFileShrd_Release(PRTFSNTFSFILESHRD pShared) 2059 { 2060 uint32_t cRefs = ASMAtomicDecU32(&pShared->cRefs); 2061 Assert(cRefs < 64); 2062 if (cRefs == 0) 2063 { 2064 LogFlow(("rtFsNtfsFileShrd_Release(%p): Destroying it\n", pShared)); 2065 Assert(pShared->pData->uObj.pSharedFile == pShared); 2066 pShared->pData->uObj.pSharedFile = NULL; 2067 rtFsNtfsCore_Release(pShared->pData->pCore); 2068 pShared->pData = NULL; 2069 RTMemFree(pShared); 2070 } 2071 return cRefs; 2072 } 2073 2074 2075 /** 2076 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 2077 */ 2078 static DECLCALLBACK(int) rtFsNtfsFile_Close(void *pvThis) 2079 { 2080 PRTFSNTFSFILE pThis = (PRTFSNTFSFILE)pvThis; 2081 LogFlow(("rtFsNtfsFile_Close(%p/%p)\n", pThis, pThis->pShared)); 2082 2083 PRTFSNTFSFILESHRD pShared = pThis->pShared; 2084 pThis->pShared = NULL; 2085 if (pShared) 2086 rtFsNtfsFileShrd_Release(pShared); 2087 return VINF_SUCCESS; 2088 } 2089 2090 2091 /** 2092 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo} 2093 */ 2094 static DECLCALLBACK(int) rtFsNtfsFile_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 2095 { 2096 PRTFSNTFSFILE pThis = (PRTFSNTFSFILE)pvThis; 2097 PRTFSNTFSATTR pDataAttr = pThis->pShared->pData; 2098 return rtFsNtfsCore_QueryInfo(pDataAttr->pCore, pDataAttr, pObjInfo, enmAddAttr); 2099 } 2100 2101 2102 /** 2103 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead} 2104 */ 2105 static DECLCALLBACK(int) rtFsNtfsFile_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead) 2106 { 2107 PRTFSNTFSFILE pThis = (PRTFSNTFSFILE)pvThis; 2108 AssertReturn(pSgBuf->cSegs == 1, VERR_INTERNAL_ERROR_3); 2109 RT_NOREF(fBlocking); 2110 2111 if (off == -1) 2112 off = pThis->offFile; 2113 else 2114 AssertReturn(off >= 0, VERR_INTERNAL_ERROR_3); 2115 2116 int rc; 2117 size_t cbRead = pSgBuf->paSegs[0].cbSeg; 2118 if (!pcbRead) 2119 { 2120 rc = rtFsNtfsAttr_Read(pThis->pShared->pData, off, pSgBuf->paSegs[0].pvSeg, cbRead); 2121 if (RT_SUCCESS(rc)) 2122 pThis->offFile = off + cbRead; 2123 Log6(("rtFsNtfsFile_Read: off=%#RX64 cbSeg=%#x -> %Rrc\n", off, pSgBuf->paSegs[0].cbSeg, rc)); 2124 } 2125 else 2126 { 2127 PRTFSNTFSATTR pDataAttr = pThis->pShared->pData; 2128 if ((uint64_t)off >= pDataAttr->cbValue) 2129 { 2130 *pcbRead = 0; 2131 rc = VINF_EOF; 2132 } 2133 else 2134 { 2135 if ((uint64_t)off + cbRead <= pDataAttr->cbValue) 2136 rc = rtFsNtfsAttr_Read(pThis->pShared->pData, off, pSgBuf->paSegs[0].pvSeg, cbRead); 2137 else 2138 { 2139 /* Return VINF_EOF if beyond end-of-file. */ 2140 cbRead = (size_t)(pDataAttr->cbValue - (uint64_t)off); 2141 rc = rtFsNtfsAttr_Read(pThis->pShared->pData, off, pSgBuf->paSegs[0].pvSeg, cbRead); 2142 if (RT_SUCCESS(rc)) 2143 rc = VINF_EOF; 2144 } 2145 if (RT_SUCCESS(rc)) 2146 { 2147 pThis->offFile = off + cbRead; 2148 *pcbRead = cbRead; 2149 } 2150 else 2151 *pcbRead = 0; 2152 } 2153 Log6(("rtFsNtfsFile_Read: off=%#RX64 cbSeg=%#x -> %Rrc *pcbRead=%#x\n", off, pSgBuf->paSegs[0].cbSeg, rc, *pcbRead)); 2154 } 2155 2156 return rc; 2157 } 2158 2159 2160 /** 2161 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite} 2162 */ 2163 static DECLCALLBACK(int) rtFsNtfsFile_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten) 2164 { 2165 RT_NOREF(pvThis, off, pSgBuf, fBlocking, pcbWritten); 2166 return VERR_WRITE_PROTECT; 2167 } 2168 2169 2170 /** 2171 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush} 2172 */ 2173 static DECLCALLBACK(int) rtFsNtfsFile_Flush(void *pvThis) 2174 { 2175 RT_NOREF(pvThis); 2176 return VINF_SUCCESS; 2177 } 2178 2179 2180 /** 2181 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell} 2182 */ 2183 static DECLCALLBACK(int) rtFsNtfsFile_Tell(void *pvThis, PRTFOFF poffActual) 2184 { 2185 PRTFSNTFSFILE pThis = (PRTFSNTFSFILE)pvThis; 2186 *poffActual = pThis->offFile; 2187 return VINF_SUCCESS; 2188 } 2189 2190 2191 /** 2192 * @interface_method_impl{RTVFSOBJSETOPS,pfnMode} 2193 */ 2194 static DECLCALLBACK(int) rtFsNtfsFile_SetMode(void *pvThis, RTFMODE fMode, RTFMODE fMask) 2195 { 2196 RT_NOREF(pvThis, fMode, fMask); 2197 return VERR_WRITE_PROTECT; 2198 } 2199 2200 2201 /** 2202 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetTimes} 2203 */ 2204 static DECLCALLBACK(int) rtFsNtfsFile_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 2205 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) 2206 { 2207 RT_NOREF(pvThis, pAccessTime, pModificationTime, pChangeTime, pBirthTime); 2208 return VERR_WRITE_PROTECT; 2209 } 2210 2211 2212 /** 2213 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetOwner} 2214 */ 2215 static DECLCALLBACK(int) rtFsNtfsFile_SetOwner(void *pvThis, RTUID uid, RTGID gid) 2216 { 2217 RT_NOREF(pvThis, uid, gid); 2218 return VERR_WRITE_PROTECT; 2219 } 2220 2221 2222 /** 2223 * @interface_method_impl{RTVFSFILEOPS,pfnSeek} 2224 */ 2225 static DECLCALLBACK(int) rtFsNtfsFile_Seek(void *pvThis, RTFOFF offSeek, unsigned uMethod, PRTFOFF poffActual) 2226 { 2227 PRTFSNTFSFILE pThis = (PRTFSNTFSFILE)pvThis; 2228 RTFOFF offNew; 2229 switch (uMethod) 2230 { 2231 case RTFILE_SEEK_BEGIN: 2232 offNew = offSeek; 2233 break; 2234 case RTFILE_SEEK_END: 2235 offNew = (RTFOFF)pThis->pShared->pData->cbValue + offSeek; 2236 break; 2237 case RTFILE_SEEK_CURRENT: 2238 offNew = (RTFOFF)pThis->offFile + offSeek; 2239 break; 2240 default: 2241 return VERR_INVALID_PARAMETER; 2242 } 2243 if (offNew >= 0) 2244 { 2245 pThis->offFile = offNew; 2246 *poffActual = offNew; 2247 return VINF_SUCCESS; 2248 } 2249 return VERR_NEGATIVE_SEEK; 2250 } 2251 2252 2253 /** 2254 * @interface_method_impl{RTVFSFILEOPS,pfnQuerySize} 2255 */ 2256 static DECLCALLBACK(int) rtFsNtfsFile_QuerySize(void *pvThis, uint64_t *pcbFile) 2257 { 2258 PRTFSNTFSFILE pThis = (PRTFSNTFSFILE)pvThis; 2259 *pcbFile = pThis->pShared->pData->cbValue; 2260 return VINF_SUCCESS; 2261 } 2262 2263 2264 /** 2265 * NTFS FS file operations. 2266 */ 2267 DECL_HIDDEN_CONST(const RTVFSFILEOPS) g_rtFsNtfsFileOps = 2268 { 2269 { /* Stream */ 2270 { /* Obj */ 2271 RTVFSOBJOPS_VERSION, 2272 RTVFSOBJTYPE_FILE, 2273 "NTFS File", 2274 rtFsNtfsFile_Close, 2275 rtFsNtfsFile_QueryInfo, 2276 RTVFSOBJOPS_VERSION 2277 }, 2278 RTVFSIOSTREAMOPS_VERSION, 2279 RTVFSIOSTREAMOPS_FEAT_NO_SG, 2280 rtFsNtfsFile_Read, 2281 rtFsNtfsFile_Write, 2282 rtFsNtfsFile_Flush, 2283 NULL /*PollOne*/, 2284 rtFsNtfsFile_Tell, 2285 NULL /*pfnSkip*/, 2286 NULL /*pfnZeroFill*/, 2287 RTVFSIOSTREAMOPS_VERSION, 2288 }, 2289 RTVFSFILEOPS_VERSION, 2290 0, 2291 { /* ObjSet */ 2292 RTVFSOBJSETOPS_VERSION, 2293 RT_OFFSETOF(RTVFSFILEOPS, Stream.Obj) - RT_OFFSETOF(RTVFSFILEOPS, ObjSet), 2294 rtFsNtfsFile_SetMode, 2295 rtFsNtfsFile_SetTimes, 2296 rtFsNtfsFile_SetOwner, 2297 RTVFSOBJSETOPS_VERSION 2298 }, 2299 rtFsNtfsFile_Seek, 2300 rtFsNtfsFile_QuerySize, 2301 RTVFSFILEOPS_VERSION 2302 }; 2303 2304 2305 static int rtFsNtfsVol_NewFile(PRTFSNTFSVOL pThis, uint64_t fOpen, PCNTFSIDXENTRYHDR pEntryHdr, const char *pszStreamName, 2306 PRTVFSFILE phVfsFile, PRTERRINFO pErrInfo, const char *pszWhat) 2307 { 2308 /* 2309 * Get the core structure for the MFT record and check that it's a directory we've got. 2310 */ 2311 PRTFSNTFSCORE pCore; 2312 int rc = rtFsNtfsVol_QueryCoreForMftRef(pThis, &pEntryHdr->u.FileMftRec, false /*fRelaxedUsa*/, &pCore, pErrInfo); 2313 if (RT_SUCCESS(rc)) 2314 { 2315 if (!(pCore->pMftRec->pFileRec->fFlags & NTFSRECFILE_F_DIRECTORY)) 2316 { 2317 /* 2318 * Locate the data attribute. 2319 */ 2320 PRTFSNTFSATTR pDataAttr; 2321 if (pszStreamName == NULL) 2322 { 2323 pDataAttr = rtFsNtfsCore_FindUnnamedAttribute(pCore, NTFS_AT_DATA); 2324 if (pDataAttr) 2325 rc = VINF_SUCCESS; 2326 else 2327 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_NOT_A_FILE, "%s: no unamed data stream", pszWhat); 2328 } 2329 else 2330 { 2331 NOREF(pszStreamName); 2332 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_NOT_IMPLEMENTED, "%s: named data streams not implemented yet", pszWhat); 2333 pDataAttr = NULL; 2334 } 2335 if (RT_SUCCESS(rc)) 2336 { 2337 /* 2338 * Get a referenced shared file structure, creating it if necessary. 2339 */ 2340 PRTFSNTFSFILESHRD pShared = pDataAttr->uObj.pSharedFile; 2341 if (pShared) 2342 { 2343 uint32_t cRefs = ASMAtomicIncU32(&pShared->cRefs); 2344 Assert(cRefs > 1); NOREF(cRefs); 2345 } 2346 else 2347 { 2348 pShared = (PRTFSNTFSFILESHRD)RTMemAllocZ(sizeof(*pShared)); 2349 if (pShared) 2350 { 2351 pShared->cRefs = 1; 2352 pShared->pData = pDataAttr; 2353 rtFsNtfsCore_Retain(pCore); 2354 pDataAttr->uObj.pSharedFile = pShared; 2355 } 2356 } 2357 if (pShared) 2358 { 2359 /* 2360 * Create the open file instance. 2361 */ 2362 PRTFSNTFSFILE pNewFile; 2363 rc = RTVfsNewFile(&g_rtFsNtfsFileOps, sizeof(*pNewFile), fOpen, pThis->hVfsSelf, NIL_RTVFSLOCK, 2364 phVfsFile, (void **)&pNewFile); 2365 if (RT_SUCCESS(rc)) 2366 { 2367 pNewFile->offFile = 0; 2368 pNewFile->pShared = pShared; 2369 return VINF_SUCCESS; 2370 } 2371 2372 rtFsNtfsFileShrd_Release(pShared); 2373 } 2374 else 2375 rc = VERR_NO_MEMORY; 2376 } 2377 } 2378 else 2379 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_NOT_A_FILE, "%s: fFlags=%#x", pszWhat, pCore->pMftRec->pFileRec->fFlags); 2380 rtFsNtfsCore_Release(pCore); 2381 } 2382 return rc; 2383 } 2384 2014 2385 2015 2386 … … 3186 3557 if (fFlags & RTVFSOBJ_F_OPEN_FILE) 3187 3558 { 3188 //RTVFSFILE hVfsFile; 3189 //rc = rtFsIsoFile_New9660(pVol, pShared, pDirRec, cDirRecs, 3190 // offDirRec, fOpen, uVersion, &hVfsFile); 3191 //if (RT_SUCCESS(rc)) 3192 //{ 3193 // *phVfsObj = RTVfsObjFromFile(hVfsFile); 3194 // RTVfsFileRelease(hVfsFile); 3195 // AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 3196 //} 3197 rc = VERR_NOT_IMPLEMENTED; 3559 RTVFSFILE hVfsFile; 3560 rc = rtFsNtfsVol_NewFile(pVol, fOpen, pEntryHdr, NULL /*pszStreamName*/, &hVfsFile, NULL, pszEntry); 3561 if (RT_SUCCESS(rc)) 3562 { 3563 *phVfsObj = RTVfsObjFromFile(hVfsFile); 3564 RTVfsFileRelease(hVfsFile); 3565 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 3566 } 3198 3567 } 3199 3568 else
Note:
See TracChangeset
for help on using the changeset viewer.