Changeset 70309 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Dec 22, 2017 11:46:23 AM (7 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r70291 r70309 438 438 common/ldr/ldrEx.cpp \ 439 439 common/ldr/ldrFile.cpp \ 440 common/ldr/ldrVfsFile.cpp \ 440 441 common/ldr/ldrMemory.cpp \ 441 442 common/ldr/ldrNative.cpp \ -
trunk/src/VBox/Runtime/common/ldr/ldrVfsFile.cpp
r70228 r70309 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - Binary Image Loader, The File Oriented Parts .3 * IPRT - Binary Image Loader, The File Oriented Parts, VFS variant. 4 4 */ 5 5 … … 39 39 #include <iprt/err.h> 40 40 #include <iprt/string.h> 41 #include <iprt/vfs.h> 41 42 #include <iprt/formats/mz.h> 42 43 #include "internal/ldr.h" … … 47 48 *********************************************************************************************************************************/ 48 49 /** 49 * File Reader instance.50 * VFS file Reader instance. 50 51 * This provides raw image bits from a file. 51 52 */ 52 typedef struct RTLDRREADER FILE53 typedef struct RTLDRREADERVFSFILE 53 54 { 54 55 /** The core. */ 55 56 RTLDRREADER Core; 56 /** The file. */ 57 RTFILE hFile; 58 /** The file size. */ 59 RTFOFF cbFile; 60 /** The current offset. */ 61 RTFOFF off; 57 /** The VFS file. */ 58 RTVFSFILE hVfsFile; 62 59 /** Number of users or the mapping. */ 63 60 RTUINT cMappings; … … 66 63 /** The filename (variable size). */ 67 64 char szFilename[1]; 68 } RTLDRREADERFILE, *PRTLDRREADERFILE; 65 } RTLDRREADERVFSFILE; 66 typedef RTLDRREADERVFSFILE *PRTLDRREADERVFSFILE; 69 67 70 68 71 69 /** @copydoc RTLDRREADER::pfnRead */ 72 static DECLCALLBACK(int) rtldrFileRead(PRTLDRREADER pReader, void *pvBuf, size_t cb, RTFOFF off) 73 { 74 PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader; 75 76 /* 77 * Seek. 78 */ 79 if (pFileReader->off != off) 80 { 81 int rc = RTFileSeek(pFileReader->hFile, off, RTFILE_SEEK_BEGIN, NULL); 82 if (RT_FAILURE(rc)) 83 { 84 pFileReader->off = -1; 85 return rc; 86 } 87 pFileReader->off = off; 88 } 89 90 /* 91 * Read. 92 */ 93 int rc = RTFileRead(pFileReader->hFile, pvBuf, cb, NULL); 70 static DECLCALLBACK(int) rtldrVfsFileRead(PRTLDRREADER pReader, void *pvBuf, size_t cb, RTFOFF off) 71 { 72 PRTLDRREADERVFSFILE pFileReader = (PRTLDRREADERVFSFILE)pReader; 73 return RTVfsFileReadAt(pFileReader->hVfsFile, off, pvBuf, cb, NULL); 74 } 75 76 77 /** @copydoc RTLDRREADER::pfnTell */ 78 static DECLCALLBACK(RTFOFF) rtldrVfsFileTell(PRTLDRREADER pReader) 79 { 80 PRTLDRREADERVFSFILE pFileReader = (PRTLDRREADERVFSFILE)pReader; 81 return RTVfsFileTell(pFileReader->hVfsFile); 82 } 83 84 85 /** @copydoc RTLDRREADER::pfnSize */ 86 static DECLCALLBACK(RTFOFF) rtldrVfsFileSize(PRTLDRREADER pReader) 87 { 88 PRTLDRREADERVFSFILE pFileReader = (PRTLDRREADERVFSFILE)pReader; 89 uint64_t cbFile; 90 int rc = RTVfsFileGetSize(pFileReader->hVfsFile, &cbFile); 94 91 if (RT_SUCCESS(rc)) 95 pFileReader->off += cb; 96 else 97 pFileReader->off = -1; 98 return rc; 99 } 100 101 102 /** @copydoc RTLDRREADER::pfnTell */ 103 static DECLCALLBACK(RTFOFF) rtldrFileTell(PRTLDRREADER pReader) 104 { 105 PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader; 106 return pFileReader->off; 107 } 108 109 110 /** @copydoc RTLDRREADER::pfnSize */ 111 static DECLCALLBACK(RTFOFF) rtldrFileSize(PRTLDRREADER pReader) 112 { 113 PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader; 114 return pFileReader->cbFile; 92 return cbFile; 93 return 0; 115 94 } 116 95 117 96 118 97 /** @copydoc RTLDRREADER::pfnLogName */ 119 static DECLCALLBACK(const char *) rtldr FileLogName(PRTLDRREADER pReader)120 { 121 PRTLDRREADER FILE pFileReader = (PRTLDRREADERFILE)pReader;98 static DECLCALLBACK(const char *) rtldrVfsFileLogName(PRTLDRREADER pReader) 99 { 100 PRTLDRREADERVFSFILE pFileReader = (PRTLDRREADERVFSFILE)pReader; 122 101 return pFileReader->szFilename; 123 102 } … … 125 104 126 105 /** @copydoc RTLDRREADER::pfnMap */ 127 static DECLCALLBACK(int) rtldr FileMap(PRTLDRREADER pReader, const void **ppvBits)128 { 129 PRTLDRREADER FILE pFileReader = (PRTLDRREADERFILE)pReader;106 static DECLCALLBACK(int) rtldrVfsFileMap(PRTLDRREADER pReader, const void **ppvBits) 107 { 108 PRTLDRREADERVFSFILE pFileReader = (PRTLDRREADERVFSFILE)pReader; 130 109 131 110 /* … … 142 121 * Allocate memory. 143 122 */ 144 size_t cb = (size_t)pFileReader->cbFile; 145 if ((RTFOFF)cb != pFileReader->cbFile) 123 RTFOFF cbFile = rtldrVfsFileSize(pReader); 124 size_t cb = (size_t)cbFile; 125 if ((RTFOFF)cb != cbFile) 146 126 return VERR_IMAGE_TOO_BIG; 147 127 pFileReader->pvMapping = RTMemAlloc(cb); 148 128 if (!pFileReader->pvMapping) 149 129 return VERR_NO_MEMORY; 150 int rc = rtldr FileRead(pReader, pFileReader->pvMapping, cb, 0);130 int rc = rtldrVfsFileRead(pReader, pFileReader->pvMapping, cb, 0); 151 131 if (RT_SUCCESS(rc)) 152 132 { … … 165 145 166 146 /** @copydoc RTLDRREADER::pfnUnmap */ 167 static DECLCALLBACK(int) rtldr FileUnmap(PRTLDRREADER pReader, const void *pvBits)168 { 169 PRTLDRREADER FILE pFileReader = (PRTLDRREADERFILE)pReader;147 static DECLCALLBACK(int) rtldrVfsFileUnmap(PRTLDRREADER pReader, const void *pvBits) 148 { 149 PRTLDRREADERVFSFILE pFileReader = (PRTLDRREADERVFSFILE)pReader; 170 150 AssertReturn(pFileReader->cMappings > 0, VERR_INVALID_PARAMETER); 171 151 … … 182 162 183 163 /** @copydoc RTLDRREADER::pfnDestroy */ 184 static DECLCALLBACK(int) rtldrFileDestroy(PRTLDRREADER pReader) 185 { 186 int rc = VINF_SUCCESS; 187 PRTLDRREADERFILE pFileReader = (PRTLDRREADERFILE)pReader; 188 if (pFileReader->hFile != NIL_RTFILE) 189 { 190 rc = RTFileClose(pFileReader->hFile); 191 AssertRC(rc); 192 pFileReader->hFile = NIL_RTFILE; 164 static DECLCALLBACK(int) rtldrVfsFileDestroy(PRTLDRREADER pReader) 165 { 166 PRTLDRREADERVFSFILE pFileReader = (PRTLDRREADERVFSFILE)pReader; 167 if (pFileReader->hVfsFile != NIL_RTVFSFILE) 168 { 169 RTVfsFileRelease(pFileReader->hVfsFile); 170 pFileReader->hVfsFile = NIL_RTVFSFILE; 193 171 } 194 172 RTMemFree(pFileReader); 195 return rc;173 return VINF_SUCCESS; 196 174 } 197 175 … … 201 179 * 202 180 * @returns iprt status code. 181 * @param pszFilename The file to open, can be VFS chain. 203 182 * @param ppReader Where to store the reader instance on success. 204 * @param pszFilename The file to open. 205 */ 206 static int rtldrFileCreate(PRTLDRREADER *ppReader, const char *pszFilename) 207 { 208 size_t cchFilename = strlen(pszFilename); 183 * @param poffError Where to return the offset into @a pszFilename of an VFS 184 * chain element causing trouble. Optional. 185 * @param pErrInfo Where to return extended error information. Optional. 186 */ 187 static int rtldrVfsFileCreate(const char *pszFilename, PRTLDRREADER *ppReader, uint32_t *poffError, PRTERRINFO pErrInfo) 188 { 189 size_t cbFilename = strlen(pszFilename) + 1; 209 190 int rc = VERR_NO_MEMORY; 210 PRTLDRREADER FILE pFileReader = (PRTLDRREADERFILE)RTMemAlloc(sizeof(*pFileReader) + cchFilename);191 PRTLDRREADERVFSFILE pFileReader = (PRTLDRREADERVFSFILE)RTMemAlloc(RT_OFFSETOF(RTLDRREADERVFSFILE, szFilename[cbFilename])); 211 192 if (pFileReader) 212 193 { 213 memcpy(pFileReader->szFilename, pszFilename, cchFilename + 1); 214 rc = RTFileOpen(&pFileReader->hFile, pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 194 memcpy(pFileReader->szFilename, pszFilename, cbFilename); 195 pFileReader->szFilename[0] = '\0'; 196 rc = RTVfsChainOpenFile(pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &pFileReader->hVfsFile, 197 poffError, pErrInfo); 215 198 if (RT_SUCCESS(rc)) 216 199 { 217 rc = RTFileGetSize(pFileReader->hFile, (uint64_t *)&pFileReader->cbFile); 218 if (RT_SUCCESS(rc)) 219 { 220 pFileReader->Core.uMagic = RTLDRREADER_MAGIC; 221 pFileReader->Core.pfnRead = rtldrFileRead; 222 pFileReader->Core.pfnTell = rtldrFileTell; 223 pFileReader->Core.pfnSize = rtldrFileSize; 224 pFileReader->Core.pfnLogName = rtldrFileLogName; 225 pFileReader->Core.pfnMap = rtldrFileMap; 226 pFileReader->Core.pfnUnmap = rtldrFileUnmap; 227 pFileReader->Core.pfnDestroy = rtldrFileDestroy; 228 pFileReader->off = 0; 229 pFileReader->cMappings = 0; 230 pFileReader->pvMapping = NULL; 231 *ppReader = &pFileReader->Core; 232 return VINF_SUCCESS; 233 } 234 235 RTFileClose(pFileReader->hFile); 200 pFileReader->Core.uMagic = RTLDRREADER_MAGIC; 201 pFileReader->Core.pfnRead = rtldrVfsFileRead; 202 pFileReader->Core.pfnTell = rtldrVfsFileTell; 203 pFileReader->Core.pfnSize = rtldrVfsFileSize; 204 pFileReader->Core.pfnLogName = rtldrVfsFileLogName; 205 pFileReader->Core.pfnMap = rtldrVfsFileMap; 206 pFileReader->Core.pfnUnmap = rtldrVfsFileUnmap; 207 pFileReader->Core.pfnDestroy = rtldrVfsFileDestroy; 208 pFileReader->cMappings = 0; 209 pFileReader->pvMapping = NULL; 210 *ppReader = &pFileReader->Core; 211 return VINF_SUCCESS; 236 212 } 237 213 RTMemFree(pFileReader); … … 243 219 244 220 /** 245 * Open a binary image file .221 * Open a binary image file allowing VFS chains in the filename. 246 222 * 247 223 * @returns iprt status code. 248 * @param pszFilename Image filename .224 * @param pszFilename Image filename, VFS chain specifiers allowed. 249 225 * @param fFlags Valid RTLDR_O_XXX combination. 250 226 * @param enmArch CPU architecture specifier for the image to be loaded. 251 227 * @param phLdrMod Where to store the handle to the loader module. 252 */ 253 RTDECL(int) RTLdrOpen(const char *pszFilename, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod) 254 { 255 return RTLdrOpenEx(pszFilename, fFlags, enmArch, phLdrMod, NULL /*pErrInfo*/); 256 } 257 RT_EXPORT_SYMBOL(RTLdrOpen); 258 259 260 /** 261 * Open a binary image file, extended version. 262 * 263 * @returns iprt status code. 264 * @param pszFilename Image filename. 265 * @param fFlags Valid RTLDR_O_XXX combination. 266 * @param enmArch CPU architecture specifier for the image to be loaded. 267 * @param phLdrMod Where to store the handle to the loader module. 268 * @param pErrInfo Where to return extended error information. Optional. 269 */ 270 RTDECL(int) RTLdrOpenEx(const char *pszFilename, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo) 271 { 272 LogFlow(("RTLdrOpenEx: pszFilename=%p:{%s} fFlags=%#x enmArch=%d phLdrMod=%p\n", 228 * @param poffError Where to return the offset into @a pszFilename of an VFS 229 * chain element causing trouble. Optional. 230 * @param pErrInfo Where to return extended error information. Optional. 231 */ 232 RTDECL(int) RTLdrOpenVfsChain(const char *pszFilename, uint32_t fFlags, RTLDRARCH enmArch, 233 PRTLDRMOD phLdrMod, uint32_t *poffError, PRTERRINFO pErrInfo) 234 { 235 LogFlow(("RTLdrOpenVfsChain: pszFilename=%p:{%s} fFlags=%#x enmArch=%d phLdrMod=%p\n", 273 236 pszFilename, pszFilename, fFlags, enmArch, phLdrMod)); 274 237 AssertMsgReturn(!(fFlags & ~RTLDR_O_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); … … 279 242 */ 280 243 PRTLDRREADER pReader; 281 int rc = rtldr FileCreate(&pReader, pszFilename);244 int rc = rtldrVfsFileCreate(pszFilename, &pReader, poffError, pErrInfo); 282 245 if (RT_SUCCESS(rc)) 283 246 { 247 if (poffError) 248 *poffError = 0; 284 249 rc = RTLdrOpenWithReader(pReader, fFlags, enmArch, phLdrMod, pErrInfo); 285 250 if (RT_SUCCESS(rc)) … … 294 259 return rc; 295 260 } 296 RT_EXPORT_SYMBOL(RTLdrOpen Ex);261 RT_EXPORT_SYMBOL(RTLdrOpenVfsChain); 297 262 298 263 299 264 /** 300 * Open s a binary image file using kLdr.265 * Open a binary image file using kLdr allowing VFS chains in the filename. 301 266 * 302 267 * @returns iprt status code. … … 305 270 * @param enmArch CPU architecture specifier for the image to be loaded. 306 271 * @param phLdrMod Where to store the handle to the loaded module. 272 * @param poffError Where to return the offset into @a pszFilename of an VFS 273 * chain element causing trouble. Optional. 274 * @param pErrInfo Where to return extended error information. Optional. 307 275 * @remark Primarily for testing the loader. 308 276 */ 309 RTDECL(int) RTLdrOpenkLdr(const char *pszFilename, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod) 277 RTDECL(int) RTLdrOpenVfsChainkLdr(const char *pszFilename, uint32_t fFlags, RTLDRARCH enmArch, 278 PRTLDRMOD phLdrMod, uint32_t *poffError, PRTERRINFO pErrInfo) 310 279 { 311 280 #ifdef LDR_WITH_KLDR 312 LogFlow(("RTLdrOpen kLdr: pszFilename=%p:{%s} fFlags=%#x enmArch=%d phLdrMod=%p\n",281 LogFlow(("RTLdrOpenVfsChainkLdr: pszFilename=%p:{%s} fFlags=%#x enmArch=%d phLdrMod=%p\n", 313 282 pszFilename, pszFilename, fFlags, enmArch, phLdrMod)); 314 283 AssertMsgReturn(!(fFlags & ~RTLDR_O_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); … … 318 287 */ 319 288 PRTLDRREADER pReader; 320 int rc = rtldr FileCreate(&pReader, pszFilename);289 int rc = rtldrVfsFileCreate(pszFilename, &pReader, poffError, pErrInfo); 321 290 if (RT_SUCCESS(rc)) 322 291 { 323 rc = rtldrkLdrOpen(pReader, fFlags, enmArch, phLdrMod, NULL); 292 if (poffError) 293 *poffError = 0; 294 rc = rtldrkLdrOpen(pReader, fFlags, enmArch, phLdrMod, pErrInfo); 324 295 if (RT_SUCCESS(rc)) 325 296 { … … 330 301 } 331 302 *phLdrMod = NIL_RTLDRMOD; 332 LogFlow(("RTLdrOpen kLdr: return %Rrc\n", rc));303 LogFlow(("RTLdrOpenVfsChainkLdr: return %Rrc\n", rc)); 333 304 return rc; 334 305 335 306 #else 336 return RTLdrOpen (pszFilename, fFlags, enmArch, phLdrMod);307 return RTLdrOpenVfsChain(pszFilename, fFlags, enmArch, phLdrMod, poffError, pErrInfo); 337 308 #endif 338 309 } 339 RT_EXPORT_SYMBOL(RTLdrOpen kLdr);340 310 RT_EXPORT_SYMBOL(RTLdrOpenVfsChainkLdr); 311
Note:
See TracChangeset
for help on using the changeset viewer.