- Timestamp:
- Apr 17, 2017 3:29:05 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
-
include/iprt/err.h (modified) (1 diff)
-
include/iprt/formats/fat.h (modified) (24 diffs)
-
include/iprt/mangling.h (modified) (2 diffs)
-
include/iprt/message.h (modified) (1 diff)
-
include/iprt/vfs.h (modified) (3 diffs)
-
include/iprt/vfslowlevel.h (modified) (6 diffs)
-
src/VBox/Runtime/common/misc/message.cpp (modified) (1 diff)
-
src/VBox/Runtime/common/vfs/vfschain.cpp (modified) (22 diffs)
-
src/VBox/Runtime/common/vfs/vfsstdfile.cpp (modified) (2 diffs)
-
src/VBox/Runtime/common/zip/gzipvfs.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/err.h
r64818 r66594 1854 1854 /** Expected a provider name. */ 1855 1855 #define VERR_VFS_CHAIN_EXPECTED_PROVIDER_NAME (-22106) 1856 /** Expected an action (> or |). */ 1857 #define VERR_VFS_CHAIN_EXPECTED_ACTION (-22107) 1858 /** Only one action element is currently supported. */ 1859 #define VERR_VFS_CHAIN_MULTIPLE_ACTIONS (-22108) 1860 /** Expected to find a driving action (>), but there is none. */ 1861 #define VERR_VFS_CHAIN_NO_ACTION (-22109) 1862 /** Expected pipe action. */ 1863 #define VERR_VFS_CHAIN_EXPECTED_PIPE (-22110) 1864 /** Unexpected action type. */ 1865 #define VERR_VFS_CHAIN_UNEXPECTED_ACTION_TYPE (-22111) 1856 /** Expected an element separator (| or :). */ 1857 #define VERR_VFS_CHAIN_EXPECTED_SEPARATOR (-22107) 1858 /** Leading element separator not permitted. */ 1859 #define VERR_VFS_CHAIN_LEADING_SEPARATOR (-22108) 1860 /** Trailing element separator not permitted. */ 1861 #define VERR_VFS_CHAIN_TRAILING_SEPARATOR (-22109) 1862 /** The provider is only allowed as the first element. */ 1863 #define VERR_VFS_CHAIN_MUST_BE_FIRST_ELEMENT (-22110) 1864 /** The provider cannot be the first element. */ 1865 #define VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT (-22111) 1866 /** VFS object cast failed. */ 1867 #define VERR_VFS_CHAIN_CAST_FAILED (-22112) 1868 /** Internal error in the VFS chain code. */ 1869 #define VERR_VFS_CHAIN_IPE (-22113) 1870 /** VFS chain element provider not found. */ 1871 #define VERR_VFS_CHAIN_PROVIDER_NOT_FOUND (-22114) 1872 /** VFS chain does not terminate with the desired object type. */ 1873 #define VERR_VFS_CHAIN_FINAL_TYPE_MISMATCH (-22115) 1874 /** VFS chain element takes no arguments. */ 1875 #define VERR_VFS_CHAIN_NO_ARGS (-22116) 1876 /** VFS chain element takes exactly one argument. */ 1877 #define VERR_VFS_CHAIN_ONE_ARG (-22117) 1878 /** VFS chain element expected at most one argument. */ 1879 #define VERR_VFS_CHAIN_AT_MOST_ONE_ARG (-22118) 1880 /** VFS chain element expected at least one argument. */ 1881 #define VERR_VFS_CHAIN_AT_LEAST_ONE_ARG (-22119) 1882 /** VFS chain element takes exactly two arguments. */ 1883 #define VERR_VFS_CHAIN_TWO_ARGS (-22120) 1884 /** VFS chain element expected at least two arguments. */ 1885 #define VERR_VFS_CHAIN_AT_LEAST_TWO_ARGS (-22121) 1886 /** VFS chain element expected at most two arguments. */ 1887 #define VERR_VFS_CHAIN_AT_MOST_TWO_ARGS (-22122) 1888 /** VFS chain element takes exactly three arguments. */ 1889 #define VERR_VFS_CHAIN_THREE_ARGS (-22123) 1890 /** VFS chain element expected at least three arguments. */ 1891 #define VERR_VFS_CHAIN_AT_LEAST_THREE_ARGS (-22124) 1892 /** VFS chain element expected at most three arguments. */ 1893 #define VERR_VFS_CHAIN_AT_MOST_THREE_ARGS (-22125) 1894 /** VFS chain element takes exactly four arguments. */ 1895 #define VERR_VFS_CHAIN_FOUR_ARGS (-22126) 1896 /** VFS chain element expected at least four arguments. */ 1897 #define VERR_VFS_CHAIN_AT_LEAST_FOUR_ARGS (-22127) 1898 /** VFS chain element expected at most four arguments. */ 1899 #define VERR_VFS_CHAIN_AT_MOST_FOUR_ARGS (-22128) 1900 /** VFS chain element takes exactly five arguments. */ 1901 #define VERR_VFS_CHAIN_FIVE_ARGS (-22129) 1902 /** VFS chain element expected at least five arguments. */ 1903 #define VERR_VFS_CHAIN_AT_LEAST_FIVE_ARGS (-22130) 1904 /** VFS chain element expected at most five arguments. */ 1905 #define VERR_VFS_CHAIN_AT_MOST_FIVE_ARGS (-22131) 1906 /** VFS chain element takes exactly six arguments. */ 1907 #define VERR_VFS_CHAIN_SIX_ARGS (-22132) 1908 /** VFS chain element expected at least six arguments. */ 1909 #define VERR_VFS_CHAIN_AT_LEAST_SIX_ARGS (-22133) 1910 /** VFS chain element expected at most six arguments. */ 1911 #define VERR_VFS_CHAIN_AT_MOST_SIX_ARGS (-22134) 1912 /** VFS chain element expected at most six arguments. */ 1913 #define VERR_VFS_CHAIN_TOO_FEW_ARGS (-22135) 1914 /** VFS chain element expected at most six arguments. */ 1915 #define VERR_VFS_CHAIN_TOO_MANY_ARGS (-22136) 1916 /** VFS chain element expected non-empty argument. */ 1917 #define VERR_VFS_CHAIN_EMPTY_ARG (-22137) 1918 /** Invalid argument to VFS chain element. */ 1919 #define VERR_VFS_CHAIN_INVALID_ARGUMENT (-22138) 1920 /** VFS chain element only provides file and I/O stream (ios) objects. */ 1921 #define VERR_VFS_CHAIN_ONLY_FILE_OR_IOS (-22139) 1922 /** VFS chain element only provides I/O stream (ios) objects. */ 1923 #define VERR_VFS_CHAIN_ONLY_IOS (-22140) 1924 /** VFS chain element only provides directory (dir) objects. */ 1925 #define VERR_VFS_CHAIN_ONLY_DIR (-22141) 1926 /** VFS chain element only provides file system stream (fss) objects. */ 1927 #define VERR_VFS_CHAIN_ONLY_FSS (-22142) 1928 /** VFS chain element only provides file system (vfs) objects. */ 1929 #define VERR_VFS_CHAIN_ONLY_VFS (-22143) 1930 /** VFS chain element only provides a read-only I/O stream, while the chain 1931 * requires write access. */ 1932 #define VERR_VFS_CHAIN_READ_ONLY_IOS (-22144) 1933 /** VFS chain element only provides a read-only I/O stream, while the chain 1934 * read access. */ 1935 #define VERR_VFS_CHAIN_WRITE_ONLY_IOS (-22145) 1866 1936 /** @} */ 1867 1937 -
trunk/include/iprt/formats/fat.h
r66578 r66594 31 31 #include <iprt/assert.h> 32 32 33 #pragma pack(1)34 33 35 34 /** @name FAT Media byte values … … 47 46 * This was the first DOS version with a BPB. 48 47 */ 48 #pragma pack(1) 49 49 typedef struct FATBPB20 50 50 { … … 66 66 uint16_t cSectorsPerFat; 67 67 } FATBPB20; 68 #pragma pack() 68 69 AssertCompileSize(FATBPB20, 0xd); 69 70 /** Pointer to a DOS 2.0 BPB. */ … … 76 77 * The DOS 3.0 BPB changes that survived. 77 78 */ 79 #pragma pack(1) 78 80 typedef struct FATBPB30CMN 79 81 { … … 85 87 uint16_t cTracksPerCylinder; 86 88 } FATBPB30CMN; 89 #pragma pack() 87 90 AssertCompileSize(FATBPB30CMN, 0x11); 88 91 … … 90 93 * The DOS 3.0 BPB. 91 94 */ 95 #pragma pack(1) 92 96 typedef struct FATBPB30 93 97 { … … 98 102 uint16_t cHiddenSectors; 99 103 } FATBPB30; 104 #pragma pack() 100 105 AssertCompileSize(FATBPB30, 0x13); 101 106 /** Pointer to a DOS 3.0 BPB. */ … … 107 112 * The DOS 3.0 BPB, flattened structure. 108 113 */ 114 #pragma pack(1) 109 115 typedef struct FATBPB30FLAT 110 116 { … … 139 145 /** @} */ 140 146 } FATBPB30FLAT; 147 #pragma pack() 141 148 AssertCompileSize(FATBPB30FLAT, 0x13); 142 149 /** Pointer to a flattened DOS 3.0 BPB. */ … … 149 156 * The DOS 3.2 BPB. 150 157 */ 158 #pragma pack(1) 151 159 typedef struct FATBPB32 152 160 { … … 157 165 uint16_t cAnotherTotalSectors; 158 166 } FATBPB32; 167 #pragma pack() 159 168 AssertCompileSize(FATBPB32, 0x15); 160 169 /** Pointer to a DOS 3.2 BPB. */ … … 166 175 * The DOS 3.2 BPB, flattened structure. 167 176 */ 177 #pragma pack(1) 168 178 typedef struct FATBPB32FLAT 169 179 { … … 204 214 /** @} */ 205 215 } FATBPB32FLAT; 216 #pragma pack() 206 217 AssertCompileSize(FATBPB32FLAT, 0x15); 207 218 /** Pointer to a flattened DOS 3.2 BPB. */ … … 214 225 * The DOS 3.31 BPB. 215 226 */ 227 #pragma pack(1) 216 228 typedef struct FATBPB331 217 229 { … … 226 238 uint32_t cTotalSectors32; 227 239 } FATBPB331; 240 #pragma pack() 228 241 AssertCompileSize(FATBPB331, 0x19); 229 242 /** Pointer to a DOS 3.31 BPB. */ … … 235 248 * The DOS 3.31 BPB, flattened structure. 236 249 */ 250 #pragma pack(1) 237 251 typedef struct FATBPB331FLAT 238 252 { … … 274 288 /** @} */ 275 289 } FATBPB331FLAT; 290 #pragma pack() 276 291 AssertCompileSize(FATBPB331FLAT, 0x19); 277 292 /** Pointer to a flattened DOS 3.31 BPB. */ … … 284 299 * Extended BIOS parameter block (EBPB). 285 300 */ 301 #pragma pack(1) 286 302 typedef struct FATEBPB 287 303 { … … 306 322 char achType[8]; 307 323 } FATEBPB; 324 #pragma pack() 308 325 AssertCompileSize(FATEBPB, 0x33); 309 326 /** Pointer to an extended BIOS parameter block. */ … … 329 346 * FAT32 Extended BIOS parameter block (EBPB). 330 347 */ 348 #pragma pack(1) 331 349 typedef struct FAT32EBPB 332 350 { … … 376 394 union 377 395 { 396 /** Type string variant. */ 378 397 char achType[8]; 398 /** Total sector count if 4G or higher. */ 379 399 uint64_t cTotalSectors64; 380 400 } u; 381 401 } FAT32EBPB; 402 #pragma pack() 382 403 AssertCompileSize(FAT32EBPB, 0x4f); 383 404 /** Pointer to a FAT32 extended BIOS parameter block. */ … … 393 414 * FAT boot sector layout. 394 415 */ 416 #pragma pack(1) 395 417 typedef struct FATBOOTSECTOR 396 418 { … … 417 439 uint16_t uSignature; 418 440 } FATBOOTSECTOR; 441 #pragma pack() 419 442 AssertCompileSize(FATBOOTSECTOR, 0x200); 420 443 /** Pointer to a FAT boot sector. */ … … 426 449 #define FATBOOTSECTOR_SIGNATURE UINT16_C(0xaa55) 427 450 428 #pragma pack() 451 452 453 /** 454 * FAT32 info sector (follows the boot sector). 455 */ 456 typedef struct FAT32INFOSECTOR 457 { 458 /** 0x000: Signature \#1 (FAT32INFOSECTOR_SIGNATURE_1). */ 459 uint32_t uSignature1; 460 /** Reserved, should be zero. */ 461 uint8_t abReserved1[0x1E0]; 462 /** 0x1e4: Signature \#1 (FAT32INFOSECTOR_SIGNATURE_2). */ 463 uint32_t uSignature2; 464 /** 0x1e8: Last known number of free clusters (informational). */ 465 uint32_t cFreeClusters; 466 /** 0x1ec: Last allocated cluster number (informational). This could be used as 467 * an allocation hint when searching for a free cluster. */ 468 uint32_t cLastAllocatedCluster; 469 /** 0x1f0: Reserved, should be zero, preserve. */ 470 uint8_t abReserved2[12]; 471 /** 0x1fc: Signature \#3 (FAT32INFOSECTOR_SIGNATURE_3). */ 472 uint32_t uSignature3; 473 } FAT32INFOSECTOR; 474 AssertCompileSize(FAT32INFOSECTOR, 0x200); 475 /** Pointer to a FAT32 info sector. */ 476 typedef FAT32INFOSECTOR *PFAT32INFOSECTOR; 477 /** Pointer to a const FAT32 info sector. */ 478 typedef FAT32INFOSECTOR const *PCFAT32INFOSECTOR; 479 480 #define FAT32INFOSECTOR_SIGNATURE_1 UINT32_C(0x41615252) 481 #define FAT32INFOSECTOR_SIGNATURE_2 UINT32_C(0x61417272) 482 #define FAT32INFOSECTOR_SIGNATURE_3 UINT32_C(0xaa550000) 429 483 430 484 #endif -
trunk/include/iprt/mangling.h
r66395 r66594 1338 1338 # define RTMsgErrorExit RT_MANGLER(RTMsgErrorExit) 1339 1339 # define RTMsgErrorExitV RT_MANGLER(RTMsgErrorExitV) 1340 # define RTMsgErrorExitFailure RT_MANGLER(RTMsgErrorExitFailure) 1341 # define RTMsgErrorExitFailureV RT_MANGLER(RTMsgErrorExitFailureV) 1340 1342 # define RTMsgErrorRc RT_MANGLER(RTMsgErrorRc) 1341 1343 # define RTMsgErrorRcV RT_MANGLER(RTMsgErrorRcV) … … 2281 2283 # define RTVfsChainOpenFile RT_MANGLER(RTVfsChainOpenFile) 2282 2284 # define RTVfsChainOpenIoStream RT_MANGLER(RTVfsChainOpenIoStream) 2285 # define RTVfsChainSpecCheckAndSetup RT_MANGLER(RTVfsChainSpecCheckAndSetup) 2283 2286 # define RTVfsChainSpecFree RT_MANGLER(RTVfsChainSpecFree) 2284 2287 # define RTVfsChainSpecParse RT_MANGLER(RTVfsChainSpecParse) -
trunk/include/iprt/message.h
r62473 r66594 98 98 99 99 /** 100 * Same as RTMsgError() except for always returning RTEXITCODE_FAILURE. 101 * 102 * @returns RTEXITCODE_FAILURE 103 * @param pszFormat The message format string. 104 * @param ... Format arguments. 105 */ 106 RTDECL(RTEXITCODE) RTMsgErrorExitFailure(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3); 107 108 /** 109 * Same as RTMsgErrorV() except for always returning RTEXITCODE_FAILURE. 110 * 111 * @returns RTEXITCODE_FAILURE 112 * @param pszFormat The message format string. 113 * @param va Format arguments. 114 */ 115 RTDECL(RTEXITCODE) RTMsgErrorExitFailureV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0); 116 117 /** 100 118 * Same as RTMsgError() except for the return value. 101 119 * -
trunk/include/iprt/vfs.h
r62473 r66594 1058 1058 * line. Imagine you want to cat the readme.gz of an ISO you could do 1059 1059 * something like: 1060 * RTCat :iprtvfs: vfs(isofs,./mycd.iso)|ios(open,readme.gz)|ios(gunzip)1060 * RTCat :iprtvfs:file(stdfile,live.iso)|vfs(isofs)|iso(open,readme.gz)|ios(gunzip) 1061 1061 * or 1062 * RTCat :iprtvfs:ios(isofs,./mycd.iso,/readme.gz)|ios(gunzip) 1063 * 1064 * The "isofs", "open" and "gunzip" bits in the above examples are chain 1065 * element providers registered with IPRT. See RTVFSCHAINELEMENTREG for how 1066 * these works. 1067 * 1068 * @{ */ 1062 * RTCat :iprtvfs:file(stdfile,live.iso)|ios(isofs,readme.gz)|ios(gunzip) 1063 * 1064 * Or say you want to read the README.TXT on a floppy image: 1065 * RTCat :iprtvfs:file(stdfile,floppy.img,r)|vfs(fat)|ios(open,README.TXT) 1066 * 1067 * Or in the other direction, you want to write a STUFF.TGZ file to the above 1068 * floppy image, using a lazy writer thread for compressing the data: 1069 * RTTar cf :iprtvfs:file(stdfile,floppy.img,rw)|ios(fat,STUFF.TGZ)|ios(gzip)|ios(push) . 1070 * 1071 * 1072 * A bit more formally: 1073 * :iprtvfs:<type>(<provider>[,provider-args])[<separator><type>...] 1074 * 1075 * The @c type refers to VFS object that should be created by the @c provider. 1076 * Valid types: 1077 * - vfs: A virtual file system (volume). 1078 * - fss: A file system stream (e.g. tar). 1079 * - ios: An I/O stream. 1080 * - file: A file. 1081 * - dir: A directory. 1082 * - sym: A symbolic link (not sure how useful this is). 1083 * 1084 * The @c provider refers to registered chain element providers (see 1085 * RTVFSCHAINELEMENTREG for how that works internally). These are asked to 1086 * create a VFS object of the specified type using the given arguments (if any). 1087 * Default providers: 1088 * - std: Standard file, directory and file system. 1089 * - open: Opens a file, I/O stream or directory in a vfs or directory object. 1090 * - pull: Read-ahead buffering thread on file or I/O stream. 1091 * - push: Lazy-writer buffering thread on file or I/O stream. 1092 * - gzip: Compresses an I/O stream. 1093 * - gunzip: Decompresses an I/O stream. 1094 * - fat: FAT file system accessor. 1095 * - isofs: ISOFS file system accessor. 1096 * 1097 * As element @c separator we allow both colon (':') and the pipe character 1098 * ('|'). The latter the conventional one, but since it's inconvenient on the 1099 * command line, colon is provided as an alternative. 1100 * 1101 * @{ 1102 */ 1069 1103 1070 1104 /** The path prefix used to identify an VFS chain specification. */ … … 1075 1109 RTDECL(int) RTVfsChainOpenDir( const char *pszSpec, uint64_t fOpen, PRTVFSDIR phVfsDir, const char **ppszError); 1076 1110 RTDECL(int) RTVfsChainOpenFile( const char *pszSpec, uint64_t fOpen, PRTVFSFILE phVfsFile, const char **ppszError); 1111 RTDECL(int) RTVfsChainOpenIoStream( const char *pszSpec, uint64_t fOpen, PRTVFSIOSTREAM phVfsIos, const char **ppszError); 1077 1112 RTDECL(int) RTVfsChainOpenSymlink( const char *pszSpec, PRTVFSSYMLINK phVfsSym, const char **ppszError); 1078 RTDECL(int) RTVfsChainOpenIoStream( const char *pszSpec, uint64_t fOpen, PRTVFSIOSTREAM phVfsIos, const char **ppszError);1079 1113 1080 1114 /** … … 1086 1120 RTDECL(bool) RTVfsChainIsSpec(const char *pszSpec); 1087 1121 1088 /** @} */1089 1090 1091 1122 /** @} */ 1092 1123 1124 1125 /** @} */ 1126 1093 1127 RT_C_DECLS_END 1094 1128 -
trunk/include/iprt/vfslowlevel.h
r66575 r66594 973 973 */ 974 974 975 976 /** 977 * Chain element input actions. 978 */ 979 typedef enum RTVFSCHAINACTION 980 { 981 /** Invalid action. */982 RTVFSCHAINACTION_INVALID = 0,983 /** No action (start of the chain). */ 984 RTVFSCHAINACTION_NONE, 985 /** Passive filtering (expressed by pipe symbol). */986 RTVFSCHAINACTION_PASSIVE,987 /** Push filtering (expressed by redirection-out symbol). */988 RTVFSCHAINACTION_PUSH,989 /** The end of the valid actions. */990 RTVFSCHAINACTION_END,991 /** Make sure it's a 32-bit type. */ 992 RTVFSCHAINACTION_32BIT_HACK = 0x7fffffff 993 } RTVFSCHAINACTION;975 /** Pointer to a VFS chain element registration record. */ 976 typedef struct RTVFSCHAINELEMENTREG *PRTVFSCHAINELEMENTREG; 977 /** Pointer to a const VFS chain element registration record. */ 978 typedef struct RTVFSCHAINELEMENTREG const *PCRTVFSCHAINELEMENTREG; 979 980 /** 981 * VFS chain element argument. 982 */ 983 typedef struct RTVFSCHAINELEMENTARG 984 { 985 /** The string argument value. */ 986 char *psz; 987 /** The specification offset of this argument. */ 988 uint16_t offSpec; 989 /** Provider specific value. */ 990 uint64_t uProvider; 991 } RTVFSCHAINELEMENTARG; 992 /** Pointer to a VFS chain element argument. */ 993 typedef RTVFSCHAINELEMENTARG *PRTVFSCHAINELEMENTARG; 994 994 995 995 … … 999 999 typedef struct RTVFSCHAINELEMSPEC 1000 1000 { 1001 /** The provider name. */ 1002 char *pszProvider; 1003 /** The input type. */ 1004 RTVFSOBJTYPE enmTypeIn; 1005 /** The output type. */ 1006 RTVFSOBJTYPE enmTypeOut; 1007 /** The action to take (or not). */ 1008 RTVFSCHAINACTION enmAction; 1001 /** The provider name. */ 1002 char *pszProvider; 1003 /** The input type, RTVFSOBJTYPE_INVALID if first. */ 1004 RTVFSOBJTYPE enmTypeIn; 1005 /** The element type. */ 1006 RTVFSOBJTYPE enmType; 1007 /** The input spec offset of this element. */ 1008 uint16_t offSpec; 1009 /** The length of the input spec. */ 1010 uint16_t cchSpec; 1009 1011 /** The number of arguments. */ 1010 uint32_t cArgs;1012 uint32_t cArgs; 1011 1013 /** Arguments. */ 1012 char **papszArgs; 1014 PRTVFSCHAINELEMENTARG paArgs; 1015 1016 /** The provider. */ 1017 PCRTVFSCHAINELEMENTREG pProvider; 1018 /** The object (with reference). */ 1019 RTVFSOBJ hVfsObj; 1013 1020 } RTVFSCHAINELEMSPEC; 1014 1021 /** Pointer to a chain element specification. */ … … 1023 1030 typedef struct RTVFSCHAINSPEC 1024 1031 { 1025 /** The action element, UINT32_MAX if none. 1026 * Currently we only support one action element (RTVFSCHAINACTION_PASSIVE 1027 * is not considered). */ 1028 uint32_t iActionElement; 1032 /** Open directory flags (RTFILE_O_XXX). */ 1033 uint32_t fOpenFile; 1034 /** To be defined. */ 1035 uint32_t fOpenDir; 1036 /** The type desired by the caller. */ 1037 RTVFSOBJTYPE enmDesiredType; 1029 1038 /** The number of elements. */ 1030 1039 uint32_t cElements; 1040 /** Provider specific value. */ 1041 uint64_t uProvider; 1031 1042 /** The elements. */ 1032 1043 PRTVFSCHAINELEMSPEC paElements; … … 1051 1062 /** For chaining the providers. */ 1052 1063 RTLISTNODE ListEntry; 1053 1054 /** 1055 * Create a VFS from the given chain element specficiation. 1056 * 1057 * @returns IPRT status code. 1058 * @param pSpec The chain element specification. 1059 * @param phVfs Where to returned the VFS handle. 1060 */ 1061 DECLCALLBACKMEMBER(int, pfnOpenVfs)( PCRTVFSCHAINELEMSPEC pSpec, PRTVFS phVfs); 1062 1063 /** 1064 * Open a directory from the given chain element specficiation. 1065 * 1066 * @returns IPRT status code. 1067 * @param pSpec The chain element specification. 1068 * @param phVfsDir Where to returned the directory handle. 1069 */ 1070 DECLCALLBACKMEMBER(int, pfnOpenDir)( PCRTVFSCHAINELEMSPEC pSpec, PRTVFSDIR phVfsDir); 1071 1072 /** 1073 * Open a file from the given chain element specficiation. 1074 * 1075 * @returns IPRT status code. 1076 * @param pSpec The chain element specification. 1077 * @param fOpen The open flag. Can be zero and the 1078 * specification may modify it. 1079 * @param phVfsFile Where to returned the file handle. 1080 */ 1081 DECLCALLBACKMEMBER(int, pfnOpenFile)( PCRTVFSCHAINELEMSPEC pSpec, uint32_t fOpen, PRTVFSFILE phVfsFile); 1082 1083 /** 1084 * Open a symlink from the given chain element specficiation. 1085 * 1086 * @returns IPRT status code. 1087 * @param pSpec The chain element specification. 1088 * @param phVfsSym Where to returned the symlink handle. 1089 */ 1090 DECLCALLBACKMEMBER(int, pfnOpenSymlink)( PCRTVFSCHAINELEMSPEC pSpec, PRTVFSSYMLINK phVfsSym); 1091 1092 /** 1093 * Open a I/O stream from the given chain element specficiation. 1094 * 1095 * @returns IPRT status code. 1096 * @param pSpec The chain element specification. 1097 * @param fOpen The open flag. Can be zero and the 1098 * specification may modify it. 1099 * @param phVfsIos Where to returned the I/O stream handle. 1100 */ 1101 DECLCALLBACKMEMBER(int, pfnOpenIoStream)(PCRTVFSCHAINELEMSPEC pSpec, uint32_t fOpen, PRTVFSIOSTREAM phVfsIos); 1102 1103 /** 1104 * Open a filesystem stream from the given chain element specficiation. 1105 * 1106 * @returns IPRT status code. 1107 * @param pSpec The chain element specification. 1108 * @param phVfsFss Where to returned the filesystem stream handle. 1109 */ 1110 DECLCALLBACKMEMBER(int, pfnOpenFsStream)(PCRTVFSCHAINELEMSPEC pSpec, PRTVFSFSSTREAM phVfsFss); 1064 /** Help text. */ 1065 const char *pszHelp; 1066 1067 /** 1068 * Checks the element specification. 1069 * 1070 * This is allowed to parse arguments and use pSpec->uProvider and 1071 * pElement->paArgs[].uProvider to store information that pfnInstantiate and 1072 * pfnCanReuseElement may use later on, thus avoiding duplicating work/code. 1073 * 1074 * @returns IPRT status code. 1075 * @param pProviderReg Pointer to the element provider registration. 1076 * @param pSpec The chain specification. 1077 * @param pElement The chain element specification to validate. 1078 * @param poffError Where to return error offset on failure. This is 1079 * set to the pElement->offSpec on input, so it only 1080 * needs to be adjusted if an argument is at fault. 1081 */ 1082 DECLCALLBACKMEMBER(int, pfnValidate)(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec, 1083 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError); 1084 1085 /** 1086 * Create a VFS object according to the element specification. 1087 * 1088 * @returns IPRT status code. 1089 * @param pProviderReg Pointer to the element provider registration. 1090 * @param pSpec The chain specification. 1091 * @param pElement The chain element specification to instantiate. 1092 * @param hPrevVfsObj Handle to the previous VFS object, NIL_RTVFSOBJ if 1093 * first. 1094 * @param phVfsObj Where to return the VFS object handle. 1095 * @param poffError Where to return error offset on failure. This is 1096 * set to the pElement->offSpec on input, so it only 1097 * needs to be adjusted if an argument is at fault. 1098 */ 1099 DECLCALLBACKMEMBER(int, pfnInstantiate)(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec, 1100 PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj, 1101 PRTVFSOBJ phVfsObj, uint32_t *poffError); 1102 1103 /** 1104 * Determins whether the element can be reused. 1105 * 1106 * This is for handling situations accessing the same file system twice, like 1107 * for both the source and destiation of a copy operation. This allows not only 1108 * sharing resources and avoid doing things twice, but also helps avoid file 1109 * sharing violations and inconsistencies araising from the image being updated 1110 * and read independently. 1111 * 1112 * @returns true if the element from @a pReuseSpec an be reused, false if not. 1113 * @param pProviderReg Pointer to the element provider registration. 1114 * @param pSpec The chain specification. 1115 * @param pElement The chain element specification. 1116 * @param pReuseSpec The chain specification of the existing chain. 1117 * @param pReuseElement The chain element specification of the existing 1118 * element that is being considered for reuse. 1119 */ 1120 DECLCALLBACKMEMBER(bool, pfnCanReuseElement)(PCRTVFSCHAINELEMENTREG pProviderReg, 1121 PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement, 1122 PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement); 1111 1123 1112 1124 /** End marker (RTVFSCHAINELEMENTREG_VERSION). */ 1113 1125 uintptr_t uEndMarker; 1114 1126 } RTVFSCHAINELEMENTREG; 1115 /** Pointer to a VFS chain element registration record. */1116 typedef RTVFSCHAINELEMENTREG *PRTVFSCHAINELEMENTREG;1117 /** Pointer to a const VFS chain element registration record. */1118 typedef RTVFSCHAINELEMENTREG const *PCRTVFSCHAINELEMENTREG;1119 1127 1120 1128 /** The VFS chain element registration record version number. */ … … 1126 1134 * 1127 1135 * @returns IPRT status code. 1128 * @param pszSpec The specification string to parse. 1129 * @param fFlags Flags, see RTVFSCHAIN_PF_XXX. 1130 * @param enmLeadingAction The only allowed leading action type. 1131 * @param enmTrailingAction The only allowed trailing action type. 1132 * @param ppSpec Where to return the pointer to the parsed 1133 * specification. This must be freed by calling 1134 * RTVfsChainSpecFree. Will always be set (unless 1135 * invalid parameters.) 1136 * @param ppszError On failure, this will point at the error 1137 * location in @a pszSpec. Optional. 1138 */ 1139 RTDECL(int) RTVfsChainSpecParse(const char *pszSpec, uint32_t fFlags, RTVFSCHAINACTION enmLeadingAction, 1140 RTVFSCHAINACTION enmTrailingAction, 1141 PRTVFSCHAINSPEC *ppSpec, const char **ppszError); 1136 * @param pszSpec The specification string to parse. 1137 * @param fFlags Flags, see RTVFSCHAIN_PF_XXX. 1138 * @param enmDesiredType The object type the caller wants to interface with. 1139 * @param ppSpec Where to return the pointer to the parsed 1140 * specification. This must be freed by calling 1141 * RTVfsChainSpecFree. Will always be set (unless 1142 * invalid parameters.) 1143 * @param ppszError On failure, this will point at the error location in 1144 * @a pszSpec. Optional. 1145 */ 1146 RTDECL(int) RTVfsChainSpecParse(const char *pszSpec, uint32_t fFlags, RTVFSOBJTYPE enmDesiredType, 1147 PRTVFSCHAINSPEC *ppSpec, const char **ppszError); 1142 1148 1143 1149 /** @name RTVfsChainSpecParse 1144 1150 * @{ */ 1145 /** No real action is permitted, i.e. only passive filtering (aka pipe). */1146 #define RTVFSCHAIN_PF_NO_REAL_ACTION RT_BIT_32(0)1147 /** The specified leading action is optional. */1148 #define RTVFSCHAIN_PF_LEADING_ACTION_OPTIONAL RT_BIT_32(1)1149 /** The specified trailing action is optional. */1150 #define RTVFSCHAIN_PF_TRAILING_ACTION_OPTIONAL RT_BIT_32(2)1151 1151 /** Mask of valid flags. */ 1152 #define RTVFSCHAIN_PF_VALID_MASK UINT32_C(0x0000000 7)1152 #define RTVFSCHAIN_PF_VALID_MASK UINT32_C(0x00000000) 1153 1153 /** @} */ 1154 1155 /** 1156 * Checks and setups the chain. 1157 * 1158 * @returns IPRT status code. 1159 * @param pSpec The parsed specification. 1160 * @param pReuseSpec Spec to reuse if applicable. Optional. 1161 * @param phVfsObj Where to return the VFS object. 1162 * @param poffError Where to return the offset into the input specification 1163 * of what's causing trouble. Always set, unless this 1164 * argument causes an invalid pointer error. 1165 */ 1166 RTDECL(int) RTVfsChainSpecCheckAndSetup(PRTVFSCHAINSPEC pSpec, PCRTVFSCHAINSPEC pReuseSpec, 1167 PRTVFSOBJ phVfsObj, uint32_t *poffError); 1154 1168 1155 1169 /** … … 1159 1173 * quietly ignored. 1160 1174 */ 1161 RTDECL(void) RTVfsChainSpecFree(PRTVFSCHAINSPEC pSpec);1175 RTDECL(void) RTVfsChainSpecFree(PRTVFSCHAINSPEC pSpec); 1162 1176 1163 1177 /** -
trunk/src/VBox/Runtime/common/misc/message.cpp
r62477 r66594 138 138 return enmExitCode; 139 139 } 140 RT_EXPORT_SYMBOL(RTMsgErrorExit); 141 142 143 RTDECL(RTEXITCODE) RTMsgErrorExitV(RTEXITCODE enmExitCode, const char *pszFormat, va_list va) 144 { 145 RTMsgErrorV(pszFormat, va); 146 return enmExitCode; 147 } 140 148 RT_EXPORT_SYMBOL(RTMsgErrorExitV); 141 149 142 150 143 RTDECL(RTEXITCODE) RTMsgErrorExitV(RTEXITCODE enmExitCode, const char *pszFormat, va_list va) 144 { 145 RTMsgErrorV(pszFormat, va); 146 return enmExitCode; 147 } 148 RT_EXPORT_SYMBOL(RTMsgErrorExitV); 151 RTDECL(RTEXITCODE) RTMsgErrorExitFailure(const char *pszFormat, ...) 152 { 153 va_list va; 154 va_start(va, pszFormat); 155 RTMsgErrorV(pszFormat, va); 156 va_end(va); 157 return RTEXITCODE_FAILURE; 158 } 159 RT_EXPORT_SYMBOL(RTMsgErrorExitFailure); 160 161 162 RTDECL(RTEXITCODE) RTMsgErrorExitFailureV(const char *pszFormat, va_list va) 163 { 164 RTMsgErrorV(pszFormat, va); 165 return RTEXITCODE_FAILURE; 166 } 167 RT_EXPORT_SYMBOL(RTMsgErrorExitFailureV); 149 168 150 169 -
trunk/src/VBox/Runtime/common/vfs/vfschain.cpp
r62477 r66594 53 53 *********************************************************************************************************************************/ 54 54 /** Init the critical section once. */ 55 static RTONCE g_rtVfsChainElementInitOnce ;55 static RTONCE g_rtVfsChainElementInitOnce = RTONCE_INITIALIZER; 56 56 /** Critical section protecting g_rtVfsChainElementProviderList. */ 57 static RTCRITSECT g_rtVfsChainElementCritSect;57 static RTCRITSECTRW g_rtVfsChainElementCritSect; 58 58 /** List of VFS chain element providers (RTVFSCHAINELEMENTREG). */ 59 59 static RTLISTANCHOR g_rtVfsChainElementProviderList; 60 60 61 61 62 63 62 64 /** 63 65 * Initializes the globals via RTOnce. … … 69 71 { 70 72 NOREF(pvUser); 71 return RTCritSectInit(&g_rtVfsChainElementCritSect); 73 if (!g_rtVfsChainElementProviderList.pNext) 74 RTListInit(&g_rtVfsChainElementProviderList); 75 int rc = RTCritSectRwInit(&g_rtVfsChainElementCritSect); 76 if (RT_SUCCESS(rc)) 77 { 78 } 79 return rc; 72 80 } 73 81 … … 84 92 AssertMsgReturn(pRegRec->uEndMarker == RTVFSCHAINELEMENTREG_VERSION, ("%#zx", pRegRec->uEndMarker), VERR_INVALID_POINTER); 85 93 AssertReturn(pRegRec->fReserved == 0, VERR_INVALID_POINTER); 86 AssertPtrReturn(pRegRec->pszName, VERR_INVALID_POINTER); 87 AssertPtrNullReturn(pRegRec->pfnOpenVfs, VERR_INVALID_POINTER); 88 AssertPtrNullReturn(pRegRec->pfnOpenDir, VERR_INVALID_POINTER); 89 AssertPtrNullReturn(pRegRec->pfnOpenFile, VERR_INVALID_POINTER); 90 AssertPtrNullReturn(pRegRec->pfnOpenIoStream, VERR_INVALID_POINTER); 91 AssertPtrNullReturn(pRegRec->pfnOpenFsStream, VERR_INVALID_POINTER); 94 AssertPtrReturn(pRegRec->pszName, VERR_INVALID_POINTER); 95 AssertPtrReturn(pRegRec->pfnValidate, VERR_INVALID_POINTER); 96 AssertPtrReturn(pRegRec->pfnInstantiate, VERR_INVALID_POINTER); 97 AssertPtrReturn(pRegRec->pfnCanReuseElement, VERR_INVALID_POINTER); 92 98 93 99 /* … … 99 105 if (RT_FAILURE(rc)) 100 106 return rc; 101 rc = RTCritSect Enter(&g_rtVfsChainElementCritSect);107 rc = RTCritSectRwEnterExcl(&g_rtVfsChainElementCritSect); 102 108 if (RT_FAILURE(rc)) 103 109 return rc; 104 110 } 111 else if (!g_rtVfsChainElementProviderList.pNext) 112 RTListInit(&g_rtVfsChainElementProviderList); 105 113 106 114 /* … … 129 137 */ 130 138 if (!fFromCtor) 131 RTCritSect Leave(&g_rtVfsChainElementCritSect);139 RTCritSectRwLeaveExcl(&g_rtVfsChainElementCritSect); 132 140 return rc; 133 141 } … … 144 152 if (pSpec) 145 153 { 146 pSpec->iActionElement = UINT32_MAX; 154 pSpec->fOpenFile = 0; 155 pSpec->fOpenDir = 0; 147 156 pSpec->cElements = 0; 157 pSpec->uProvider = 0; 148 158 pSpec->paElements = NULL; 149 159 } … … 213 223 * code shorter. -lazy bird) 214 224 */ 215 static PRTVFSCHAINELEMSPEC rtVfsChainSpecAddElement(PRTVFSCHAINSPEC pSpec, int *prc)225 static PRTVFSCHAINELEMSPEC rtVfsChainSpecAddElement(PRTVFSCHAINSPEC pSpec, uint16_t offSpec, int *prc) 216 226 { 217 227 AssertPtr(pSpec); … … 240 250 PRTVFSCHAINELEMSPEC pElement = &pSpec->paElements[iElement]; 241 251 pElement->pszProvider = NULL; 242 pElement->enmTypeIn = iElement ? pSpec->paElements[iElement - 1].enmTypeOut : RTVFSOBJTYPE_INVALID; 243 pElement->enmTypeOut = RTVFSOBJTYPE_INVALID; 244 pElement->enmAction = RTVFSCHAINACTION_INVALID; 252 pElement->enmTypeIn = iElement ? pSpec->paElements[iElement - 1].enmType : RTVFSOBJTYPE_INVALID; 253 pElement->enmType = RTVFSOBJTYPE_INVALID; 254 pElement->offSpec = offSpec; 255 pElement->cchSpec = 0; 245 256 pElement->cArgs = 0; 246 pElement->papszArgs = 0; 247 248 pSpec->cElements = iElement + 1; 257 pElement->paArgs = NULL; 258 pElement->pProvider = NULL; 259 pElement->hVfsObj = NIL_RTVFSOBJ; 260 261 pSpec->cElements = iElement + 1; 249 262 return pElement; 250 263 } … … 260 273 * sequences counted twice. 261 274 */ 262 static int rtVfsChainSpecElementAddArg(PRTVFSCHAINELEMSPEC pElement, const char *psz, size_t cch )275 static int rtVfsChainSpecElementAddArg(PRTVFSCHAINELEMSPEC pElement, const char *psz, size_t cch, uint16_t offSpec) 263 276 { 264 277 uint32_t iArg = pElement->cArgs; 265 278 if ((iArg % 32) == 0) 266 279 { 267 char **papszNew = (char **)RTMemTmpAlloc((iArg + 32 + 1) * sizeof(papszNew[0]));268 if (!pa pszNew)280 PRTVFSCHAINELEMENTARG paNew = (PRTVFSCHAINELEMENTARG)RTMemTmpAlloc((iArg + 32) * sizeof(paNew[0])); 281 if (!paNew) 269 282 return VERR_NO_TMP_MEMORY; 270 memcpy(pa pszNew, pElement->papszArgs, iArg * sizeof(papszNew[0]));271 RTMemTmpFree(pElement->pa pszArgs);272 pElement->pa pszArgs = papszNew;283 memcpy(paNew, pElement->paArgs, iArg * sizeof(paNew[0])); 284 RTMemTmpFree(pElement->paArgs); 285 pElement->paArgs = paNew; 273 286 } 274 287 275 288 int rc = VINF_SUCCESS; 276 pElement->pa pszArgs[iArg]= rtVfsChainSpecDupStrN(psz, cch, &rc);277 pElement->pa pszArgs[iArg + 1] = NULL;289 pElement->paArgs[iArg].psz = rtVfsChainSpecDupStrN(psz, cch, &rc); 290 pElement->paArgs[iArg].offSpec = offSpec; 278 291 pElement->cArgs = iArg + 1; 279 292 return rc; … … 291 304 uint32_t iArg = pSpec->paElements[i].cArgs; 292 305 while (iArg-- > 0) 293 RTMemTmpFree(pSpec->paElements[i].pa pszArgs[iArg]);294 RTMemTmpFree(pSpec->paElements[i].pa pszArgs);306 RTMemTmpFree(pSpec->paElements[i].paArgs[iArg].psz); 307 RTMemTmpFree(pSpec->paElements[i].paArgs); 295 308 RTMemTmpFree(pSpec->paElements[i].pszProvider); 309 if (pSpec->paElements[i].hVfsObj != NIL_RTVFSOBJ) 310 { 311 RTVfsObjRelease(pSpec->paElements[i].hVfsObj); 312 pSpec->paElements[i].hVfsObj = NIL_RTVFSOBJ; 313 } 296 314 } 297 315 … … 326 344 } 327 345 328 /** 329 * Look for action. 330 * 331 * @returns Action. 332 * @param pszSpec The current spec position. 333 * @param pcchAction Where to return the length of the action 334 * string. 335 */ 336 static RTVFSCHAINACTION rtVfsChainSpecEatAction(const char *pszSpec, size_t *pcchAction) 337 { 338 switch (*pszSpec) 339 { 340 case '|': 341 *pcchAction = 1; 342 return RTVFSCHAINACTION_PASSIVE; 343 case '>': 344 *pcchAction = 1; 345 return RTVFSCHAINACTION_PUSH; 346 default: 347 *pcchAction = 0; 348 return RTVFSCHAINACTION_NONE; 349 } 350 } 351 352 353 RTDECL(int) RTVfsChainSpecParse(const char *pszSpec, uint32_t fFlags, RTVFSCHAINACTION enmLeadingAction, 354 RTVFSCHAINACTION enmTrailingAction, 355 PRTVFSCHAINSPEC *ppSpec, const char **ppszError) 346 347 RTDECL(int) RTVfsChainSpecParse(const char *pszSpec, uint32_t fFlags, RTVFSOBJTYPE enmDesiredType, 348 PRTVFSCHAINSPEC *ppSpec, const char **ppszError) 356 349 { 357 350 AssertPtrNullReturn(ppszError, VERR_INVALID_POINTER); … … 362 355 AssertPtrReturn(pszSpec, VERR_INVALID_POINTER); 363 356 AssertReturn(!(fFlags & ~RTVFSCHAIN_PF_VALID_MASK), VERR_INVALID_PARAMETER); 364 AssertReturn(enm LeadingAction > RTVFSCHAINACTION_INVALID && enmLeadingAction < RTVFSCHAINACTION_END, VERR_INVALID_PARAMETER);357 AssertReturn(enmDesiredType > RTVFSOBJTYPE_INVALID && enmDesiredType < RTVFSOBJTYPE_END, VERR_INVALID_PARAMETER); 365 358 366 359 /* … … 369 362 if (strncmp(pszSpec, RTVFSCHAIN_SPEC_PREFIX, sizeof(RTVFSCHAIN_SPEC_PREFIX) - 1)) 370 363 return VERR_VFS_CHAIN_NO_PREFIX; 371 pszSpec = RTStrStripL(pszSpec + sizeof(RTVFSCHAIN_SPEC_PREFIX) - 1);372 if (!*pszS pec)364 const char *pszSrc = RTStrStripL(pszSpec + sizeof(RTVFSCHAIN_SPEC_PREFIX) - 1); 365 if (!*pszSrc) 373 366 return VERR_VFS_CHAIN_EMPTY; 374 367 … … 376 369 if (!pSpec) 377 370 return VERR_NO_TMP_MEMORY; 371 pSpec->enmDesiredType = enmDesiredType; 378 372 379 373 /* 380 374 * Parse the spec one element at a time. 381 375 */ 382 int rc = VINF_SUCCESS; 383 const char *pszSrc = pszSpec; 376 int rc = VINF_SUCCESS; 384 377 while (*pszSrc && RT_SUCCESS(rc)) 385 378 { 386 379 /* 387 * Pipe or redirection action symbol, except maybe the first time. 388 * The pipe symbol may occur at the end of the spec. 380 * Digest element separator, except for the first element. 389 381 */ 390 size_t cch; 391 RTVFSCHAINACTION enmAction = rtVfsChainSpecEatAction(pszSpec, &cch); 392 if (enmAction != RTVFSCHAINACTION_NONE) 393 { 394 pszSrc = RTStrStripL(pszSrc + cch); 395 if (!*pszSrc) 382 if (*pszSrc == '|' || *pszSrc == ':') 383 { 384 if (pSpec->cElements != 0) 385 pszSrc = RTStrStripL(pszSrc + 1); 386 else 396 387 { 397 /* Fail if the caller does not approve of a trailing pipe (all 398 other actions non-trailing). */ 399 if ( enmAction != enmTrailingAction 400 && !(fFlags & RTVFSCHAIN_PF_TRAILING_ACTION_OPTIONAL)) 401 rc = VERR_VFS_CHAIN_EXPECTED_ELEMENT; 388 rc = VERR_VFS_CHAIN_LEADING_SEPARATOR; 402 389 break; 403 390 } 404 405 /* There can only be one real action atm. */ 406 if (enmAction != RTVFSCHAINACTION_PASSIVE) 407 { 408 if (pSpec->iActionElement != UINT32_MAX) 409 { 410 rc = VERR_VFS_CHAIN_MULTIPLE_ACTIONS; 411 break; 412 } 413 pSpec->iActionElement = pSpec->cElements; 414 } 415 } 416 else if (pSpec->cElements > 0) 417 { 418 rc = VERR_VFS_CHAIN_EXPECTED_ACTION; 419 break; 420 } 421 422 /* Check the leading action. */ 423 if ( pSpec->cElements == 0 424 && enmAction != enmLeadingAction 425 && !(fFlags & RTVFSCHAIN_PF_LEADING_ACTION_OPTIONAL)) 426 { 427 rc = VERR_VFS_CHAIN_UNEXPECTED_ACTION_TYPE; 391 } 392 else if (pSpec->cElements != 0) 393 { 394 rc = VERR_VFS_CHAIN_EXPECTED_SEPARATOR; 428 395 break; 429 396 } … … 432 399 * Ok, there should be an element here so add one to the return struct. 433 400 */ 434 PRTVFSCHAINELEMSPEC pElement = rtVfsChainSpecAddElement(pSpec, &rc);401 PRTVFSCHAINELEMSPEC pElement = rtVfsChainSpecAddElement(pSpec, (uint16_t)(pszSrc - pszSpec), &rc); 435 402 if (!pElement) 436 403 break; 437 pElement->enmAction = enmAction;438 404 439 405 /* 440 * First up is the VFS object type followed by a parentheses. 406 * First up is the VFS object type followed by a parentheses, 407 * or this could be the trailing action. 441 408 */ 409 size_t cch; 442 410 if (strncmp(pszSrc, "base", cch = 4) == 0) 443 pElement->enmType Out= RTVFSOBJTYPE_BASE;411 pElement->enmType = RTVFSOBJTYPE_BASE; 444 412 else if (strncmp(pszSrc, "vfs", cch = 3) == 0) 445 pElement->enmType Out= RTVFSOBJTYPE_VFS;413 pElement->enmType = RTVFSOBJTYPE_VFS; 446 414 else if (strncmp(pszSrc, "fss", cch = 3) == 0) 447 pElement->enmType Out= RTVFSOBJTYPE_FS_STREAM;415 pElement->enmType = RTVFSOBJTYPE_FS_STREAM; 448 416 else if (strncmp(pszSrc, "ios", cch = 3) == 0) 449 pElement->enmType Out= RTVFSOBJTYPE_IO_STREAM;417 pElement->enmType = RTVFSOBJTYPE_IO_STREAM; 450 418 else if (strncmp(pszSrc, "dir", cch = 3) == 0) 451 pElement->enmType Out= RTVFSOBJTYPE_DIR;419 pElement->enmType = RTVFSOBJTYPE_DIR; 452 420 else if (strncmp(pszSrc, "file", cch = 4) == 0) 453 pElement->enmType Out= RTVFSOBJTYPE_FILE;421 pElement->enmType = RTVFSOBJTYPE_FILE; 454 422 else if (strncmp(pszSrc, "sym", cch = 3) == 0) 455 pElement->enmType Out= RTVFSOBJTYPE_SYMLINK;423 pElement->enmType = RTVFSOBJTYPE_SYMLINK; 456 424 else 457 425 { 458 rc = VERR_VFS_CHAIN_UNKNOWN_TYPE; 426 if (*pszSrc == '\0') 427 rc = VERR_VFS_CHAIN_TRAILING_SEPARATOR; 428 else 429 rc = VERR_VFS_CHAIN_UNKNOWN_TYPE; 459 430 break; 460 431 } … … 490 461 pszSrc = RTStrStripL(pszSrc + 1); 491 462 cch = rtVfsChainSpecFindArgEnd(pszSrc); 492 rc = rtVfsChainSpecElementAddArg(pElement, pszSrc, cch); 463 rc = rtVfsChainSpecElementAddArg(pElement, pszSrc, cch, (uint16_t)(pszSrc - pszSpec)); 464 if (RT_FAILURE(rc)) 465 break; 493 466 pszSrc += cch; 494 467 } 468 if (RT_FAILURE(rc)) 469 break; 495 470 496 471 /* Must end with a right parentheses. */ … … 500 475 break; 501 476 } 477 pElement->cchSpec = (uint16_t)(pszSrc - pszSpec) - pElement->offSpec + 1; 478 502 479 pszSrc = RTStrStripL(pszSrc + 1); 503 480 } 481 482 #if 1 483 RTAssertMsg2("dbg: cElements=%d rc=%Rrc\n", pSpec->cElements, rc); 484 for (uint32_t i = 0; i < pSpec->cElements; i++) 485 { 486 uint32_t const cArgs = pSpec->paElements[i].cArgs; 487 RTAssertMsg2("dbg: #%u: enmTypeIn=%d enmType=%d cArgs=%d", 488 i, pSpec->paElements[i].enmTypeIn, pSpec->paElements[i].enmType, cArgs); 489 for (uint32_t j = 0; j < cArgs; j++) 490 RTAssertMsg2(j == 0 ? (cArgs > 1 ? " [%s" : " [%s]") : j + 1 < cArgs ? ", %s" : ", %s]", 491 pSpec->paElements[i].paArgs[j].psz); 492 //RTAssertMsg2(" offSpec=%d cchSpec=%d", pSpec->paElements[i].offSpec, pSpec->paElements[i].cchSpec); 493 RTAssertMsg2(" spec: %.*s\n", pSpec->paElements[i].cchSpec, &pszSpec[pSpec->paElements[i].offSpec]); 494 } 495 #endif 504 496 505 497 /* … … 519 511 520 512 521 513 /** 514 * Looks up @a pszProvider among the registered providers. 515 * 516 * @returns Pointer to registration record if found, NULL if not. 517 * @param pszProvider The provider. 518 */ 519 static PCRTVFSCHAINELEMENTREG rtVfsChainFindProviderLocked(const char *pszProvider) 520 { 521 PCRTVFSCHAINELEMENTREG pIterator; 522 RTListForEach(&g_rtVfsChainElementProviderList, pIterator, RTVFSCHAINELEMENTREG, ListEntry) 523 { 524 if (strcmp(pIterator->pszName, pszProvider) == 0) 525 return pIterator; 526 } 527 return NULL; 528 } 529 530 531 /** 532 * Does reusable object type matching. 533 * 534 * @returns true if the types matches, false if not. 535 * @param pElement The target element specification. 536 * @param pReuseElement The source element specification. 537 */ 538 static bool rtVfsChainMatchReusableType(PRTVFSCHAINELEMSPEC pElement, PRTVFSCHAINELEMSPEC pReuseElement) 539 { 540 if (pElement->enmType == pReuseElement->enmType) 541 return true; 542 543 /* File objects can always be cast to I/O streams. */ 544 if ( pElement->enmType == RTVFSOBJTYPE_IO_STREAM 545 && pReuseElement->enmType == RTVFSOBJTYPE_FILE) 546 return true; 547 548 /* I/O stream objects may be file objects. */ 549 if ( pElement->enmType == RTVFSOBJTYPE_FILE 550 && pReuseElement->enmType == RTVFSOBJTYPE_IO_STREAM) 551 { 552 RTVFSFILE hVfsFile = RTVfsObjToFile(pReuseElement->hVfsObj); 553 if (hVfsFile != NIL_RTVFSFILE) 554 { 555 RTVfsFileRelease(hVfsFile); 556 return true; 557 } 558 } 559 return false; 560 } 561 562 563 RTDECL(int) RTVfsChainSpecCheckAndSetup(PRTVFSCHAINSPEC pSpec, PCRTVFSCHAINSPEC pReuseSpec, 564 PRTVFSOBJ phVfsObj, uint32_t *poffError) 565 { 566 AssertPtrReturn(poffError, VERR_INVALID_POINTER); 567 *poffError = 0; 568 AssertPtrReturn(phVfsObj, VERR_INVALID_POINTER); 569 *phVfsObj = NIL_RTVFSOBJ; 570 AssertPtrReturn(pSpec, VERR_INVALID_POINTER); 571 572 /* 573 * Enter the critical section after making sure it has been initialized. 574 */ 575 int rc = RTOnce(&g_rtVfsChainElementInitOnce, rtVfsChainElementRegisterInit, NULL); 576 if (RT_SUCCESS(rc)) 577 rc = RTCritSectRwEnterShared(&g_rtVfsChainElementCritSect); 578 if (RT_SUCCESS(rc)) 579 { 580 /* 581 * Resolve and check each element first. 582 */ 583 for (uint32_t i = 0; i < pSpec->cElements; i++) 584 { 585 PRTVFSCHAINELEMSPEC const pElement = &pSpec->paElements[i]; 586 *poffError = pElement->offSpec; 587 pElement->pProvider = rtVfsChainFindProviderLocked(pElement->pszProvider); 588 if (pElement->pProvider) 589 { 590 rc = pElement->pProvider->pfnValidate(pElement->pProvider, pSpec, pElement, poffError); 591 if (RT_SUCCESS(rc)) 592 continue; 593 } 594 else 595 rc = VERR_VFS_CHAIN_PROVIDER_NOT_FOUND; 596 break; 597 } 598 599 /* 600 * Check that the desired type is compatible with the last element. 601 */ 602 if (RT_SUCCESS(rc)) 603 { 604 if (pSpec->cElements > 0) /* paranoia */ 605 { 606 PRTVFSCHAINELEMSPEC const pLast = &pSpec->paElements[pSpec->cElements - 1]; 607 if ( pLast->enmType == pSpec->enmDesiredType 608 || ( pLast->enmType == RTVFSOBJTYPE_FILE 609 && pSpec->enmDesiredType == RTVFSOBJTYPE_IO_STREAM) ) 610 rc = VINF_SUCCESS; 611 else 612 { 613 *poffError = pLast->offSpec; 614 rc = VERR_VFS_CHAIN_FINAL_TYPE_MISMATCH; 615 } 616 } 617 else 618 rc = VERR_VFS_CHAIN_EMPTY; 619 } 620 621 if (RT_SUCCESS(rc)) 622 { 623 /* 624 * Try construct the chain. 625 */ 626 RTVFSOBJ hPrevVfsObj = NIL_RTVFSOBJ; /* No extra reference, kept in chain structure. */ 627 for (uint32_t i = 0; i < pSpec->cElements; i++) 628 { 629 PRTVFSCHAINELEMSPEC const pElement = &pSpec->paElements[i]; 630 631 /* 632 * Try reuse the VFS objects at the start of the passed in reuse chain. 633 */ 634 if (!pReuseSpec) 635 { /* likely */ } 636 else 637 { 638 if (i < pReuseSpec->cElements) 639 { 640 PRTVFSCHAINELEMSPEC const pReuseElement = &pReuseSpec->paElements[i]; 641 if (pReuseElement->hVfsObj != NIL_RTVFSOBJ) 642 { 643 if (strcmp(pElement->pszProvider, pReuseElement->pszProvider) == 0) 644 { 645 if (rtVfsChainMatchReusableType(pElement, pReuseElement)) 646 { 647 if (pElement->pProvider->pfnCanReuseElement(pElement->pProvider, pSpec, pElement, 648 pReuseSpec, pReuseElement)) 649 { 650 uint32_t cRefs = RTVfsObjRetain(pReuseElement->hVfsObj); 651 if (cRefs != UINT32_MAX) 652 { 653 pElement->hVfsObj = hPrevVfsObj = pReuseElement->hVfsObj; 654 continue; 655 } 656 } 657 } 658 } 659 } 660 } 661 pReuseSpec = NULL; 662 } 663 664 /* 665 * Instantiate a new VFS object. 666 */ 667 RTVFSOBJ hVfsObj = NIL_RTVFSOBJ; 668 rc = pElement->pProvider->pfnInstantiate(pElement->pProvider, pSpec, pElement, hPrevVfsObj, &hVfsObj, poffError); 669 if (RT_FAILURE(rc)) 670 break; 671 pElement->hVfsObj = hVfsObj; 672 hPrevVfsObj = hVfsObj; 673 } 674 675 /* 676 * Add another reference to the final object and return. 677 */ 678 if (RT_SUCCESS(rc)) 679 { 680 uint32_t cRefs = RTVfsObjRetain(hPrevVfsObj); 681 AssertStmt(cRefs != UINT32_MAX, rc = VERR_VFS_CHAIN_IPE); 682 *phVfsObj = hPrevVfsObj; 683 } 684 } 685 686 int rc2 = RTCritSectRwLeaveShared(&g_rtVfsChainElementCritSect); 687 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 688 rc = rc2; 689 } 690 return rc; 691 } 522 692 523 693 … … 538 708 */ 539 709 if (!fFromDtor) 540 RTCritSectEnter(&g_rtVfsChainElementCritSect); 710 RTCritSectRwEnterExcl(&g_rtVfsChainElementCritSect); 711 else if (!g_rtVfsChainElementProviderList.pNext) 712 RTListInit(&g_rtVfsChainElementProviderList); 541 713 542 714 /* … … 559 731 */ 560 732 if (!fFromDtor) 561 RTCritSect Leave(&g_rtVfsChainElementCritSect);733 RTCritSectRwLeaveExcl(&g_rtVfsChainElementCritSect); 562 734 return rc; 563 735 } … … 593 765 { 594 766 PRTVFSCHAINSPEC pSpec; 595 rc = RTVfsChainSpecParse(pszSpec, 596 RTVFSCHAIN_PF_NO_REAL_ACTION 597 | RTVFSCHAIN_PF_LEADING_ACTION_OPTIONAL, 598 RTVFSCHAINACTION_PASSIVE, 599 RTVFSCHAINACTION_NONE, 600 &pSpec, 601 ppszError); 767 rc = RTVfsChainSpecParse(pszSpec, 0 /*fFlags*/, RTVFSOBJTYPE_FILE, &pSpec, ppszError); 602 768 if (RT_SUCCESS(rc)) 603 769 { 604 /** @todo implement this when needed. */ 605 rc = VERR_NOT_IMPLEMENTED; 770 pSpec->fOpenFile = fOpen; 771 772 uint32_t offError = 0; 773 RTVFSOBJ hVfsObj = NIL_RTVFSOBJ; 774 rc = RTVfsChainSpecCheckAndSetup(pSpec, NULL /*pReuseSpec*/, &hVfsObj, &offError); 775 if (RT_SUCCESS(rc)) 776 { 777 *phVfsFile = RTVfsObjToFile(hVfsObj); 778 if (*phVfsFile) 779 rc = VINF_SUCCESS; 780 else 781 rc = VERR_VFS_CHAIN_CAST_FAILED; 782 RTVfsObjRelease(hVfsObj); 783 } 784 else if (ppszError) 785 *ppszError = &pszSpec[offError]; 786 606 787 RTVfsChainSpecFree(pSpec); 607 788 } … … 641 822 } 642 823 } 824 /* 825 * Do the chain thing. 826 */ 643 827 else 644 828 { 645 829 PRTVFSCHAINSPEC pSpec; 646 rc = RTVfsChainSpecParse(pszSpec, 647 RTVFSCHAIN_PF_NO_REAL_ACTION 648 | RTVFSCHAIN_PF_LEADING_ACTION_OPTIONAL, 649 RTVFSCHAINACTION_PASSIVE, 650 RTVFSCHAINACTION_NONE, 651 &pSpec, 652 ppszError); 830 rc = RTVfsChainSpecParse(pszSpec, 0 /*fFlags*/, RTVFSOBJTYPE_IO_STREAM, &pSpec, ppszError); 653 831 if (RT_SUCCESS(rc)) 654 832 { 655 656 657 rc = VERR_NOT_IMPLEMENTED; 833 pSpec->fOpenFile = fOpen; 834 835 uint32_t offError = 0; 836 RTVFSOBJ hVfsObj = NIL_RTVFSOBJ; 837 rc = RTVfsChainSpecCheckAndSetup(pSpec, NULL /*pReuseSpec*/, &hVfsObj, &offError); 838 if (RT_SUCCESS(rc)) 839 { 840 *phVfsIos = RTVfsObjToIoStream(hVfsObj); 841 if (*phVfsIos) 842 rc = VINF_SUCCESS; 843 else 844 rc = VERR_VFS_CHAIN_CAST_FAILED; 845 RTVfsObjRelease(hVfsObj); 846 } 847 else if (ppszError) 848 *ppszError = &pszSpec[offError]; 849 658 850 RTVfsChainSpecFree(pSpec); 659 851 } -
trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp
r62477 r66594 32 32 #include <iprt/vfslowlevel.h> 33 33 34 #include <iprt/assert.h> 34 35 #include <iprt/err.h> 35 36 #include <iprt/file.h> 36 37 #include <iprt/poll.h> 38 #include <iprt/string.h> 37 39 #include <iprt/thread.h> 38 40 … … 509 511 } 510 512 513 514 515 /** 516 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate} 517 */ 518 static DECLCALLBACK(int) rtVfsChainStdFile_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec, 519 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError) 520 { 521 RT_NOREF(pProviderReg); 522 523 /* 524 * Basic checks. 525 */ 526 if (pElement->enmTypeIn != RTVFSOBJTYPE_INVALID) 527 return VERR_VFS_CHAIN_MUST_BE_FIRST_ELEMENT; 528 if (pElement->cArgs < 1) 529 return VERR_VFS_CHAIN_AT_LEAST_ONE_ARG; 530 if (pElement->cArgs > 4) 531 return VERR_VFS_CHAIN_AT_MOST_FOUR_ARGS; 532 if (!*pElement->paArgs[0].psz) 533 return VERR_VFS_CHAIN_EMPTY_ARG; 534 if ( pElement->enmType != RTVFSOBJTYPE_FILE 535 && pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 536 return VERR_VFS_CHAIN_ONLY_FILE_OR_IOS; 537 538 /* 539 * Calculate the flags, storing them in the first argument. 540 */ 541 const char *pszAccess = pElement->cArgs >= 2 ? pElement->paArgs[1].psz : ""; 542 if (!*pszAccess) 543 pszAccess = (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READWRITE ? "rw" 544 : (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READ ? "r" 545 : (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_WRITE ? "w" 546 : "rw"; 547 548 const char *pszDisp = pElement->cArgs >= 3 ? pElement->paArgs[2].psz : ""; 549 if (!*pszDisp) 550 pszDisp = strchr(pszAccess, 'w') != NULL ? "open-create" : "open"; 551 552 const char *pszSharing = pElement->cArgs >= 4 ? pElement->paArgs[3].psz : ""; 553 554 int rc = RTFileModeToFlagsEx(pszAccess, pszDisp, pszSharing, &pElement->paArgs[0].uProvider); 555 if (RT_SUCCESS(rc)) 556 return VINF_SUCCESS; 557 558 /* 559 * Now try figure out which argument offended us. 560 */ 561 AssertReturn(pElement->cArgs > 1, VERR_VFS_CHAIN_IPE); 562 if ( pElement->cArgs == 2 563 || RT_FAILURE(RTFileModeToFlagsEx(pszAccess, "open-create", "", &pElement->paArgs[0].uProvider))) 564 *poffError = pElement->paArgs[1].offSpec; 565 else if ( pElement->cArgs == 3 566 || RT_FAILURE(RTFileModeToFlagsEx(pszAccess, pszDisp, "", &pElement->paArgs[0].uProvider))) 567 *poffError = pElement->paArgs[2].offSpec; 568 else 569 *poffError = pElement->paArgs[3].offSpec; 570 return VERR_VFS_CHAIN_INVALID_ARGUMENT; 571 } 572 573 574 /** 575 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate} 576 */ 577 static DECLCALLBACK(int) rtVfsChainStdFile_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec, 578 PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj, 579 PRTVFSOBJ phVfsObj, uint32_t *poffError) 580 { 581 RT_NOREF(pProviderReg, pSpec, poffError); 582 AssertReturn(hPrevVfsObj == NIL_RTVFSOBJ, VERR_VFS_CHAIN_IPE); 583 584 RTVFSFILE hVfsFile; 585 int rc = RTVfsFileOpenNormal(pElement->paArgs[0].psz, pElement->paArgs[0].uProvider, &hVfsFile); 586 if (RT_SUCCESS(rc)) 587 { 588 *phVfsObj = RTVfsObjFromFile(hVfsFile); 589 RTVfsFileRelease(hVfsFile); 590 if (*phVfsObj != NIL_RTVFSOBJ) 591 return VINF_SUCCESS; 592 rc = VERR_VFS_CHAIN_CAST_FAILED; 593 } 594 return rc; 595 } 596 597 598 /** 599 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement} 600 */ 601 static DECLCALLBACK(bool) rtVfsChainStdFile_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg, 602 PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement, 603 PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement) 604 { 605 RT_NOREF(pProviderReg, pSpec, pReuseSpec); 606 if (strcmp(pElement->paArgs[0].psz, pReuseElement->paArgs[0].psz) == 0) 607 if (pElement->paArgs[0].uProvider == pReuseElement->paArgs[0].uProvider) 608 return true; 609 return false; 610 } 611 612 613 /** VFS chain element 'file'. */ 614 static RTVFSCHAINELEMENTREG g_rtVfsChainStdFileReg = 615 { 616 /* uVersion = */ RTVFSCHAINELEMENTREG_VERSION, 617 /* fReserved = */ 0, 618 /* pszName = */ "stdfile", 619 /* ListEntry = */ { NULL, NULL }, 620 /* pszHelp = */ "Open a real file, providing either a file or an I/O stream object. Initial element.\n" 621 "First argument is the filename path.\n" 622 "Second argument is access mode, optional: r, w, rw.\n" 623 "Third argument is open disposition, optional: create, create-replace, open, open-create, open-append, open-truncate.\n" 624 "Forth argument is file sharing, optional: nr, nw, nrw, d.", 625 /* pfnValidate = */ rtVfsChainStdFile_Validate, 626 /* pfnInstantiate = */ rtVfsChainStdFile_Instantiate, 627 /* pfnCanReuseElement = */ rtVfsChainStdFile_CanReuseElement, 628 /* uEndMarker = */ RTVFSCHAINELEMENTREG_VERSION 629 }; 630 631 RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainStdFileReg, rtVfsChainStdFileReg); 632 -
trunk/src/VBox/Runtime/common/zip/gzipvfs.cpp
r62477 r66594 33 33 34 34 #include <iprt/assert.h> 35 #include <iprt/ctype.h> 35 36 #include <iprt/file.h> 36 37 #include <iprt/err.h> … … 828 829 } 829 830 831 832 833 /** 834 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate} 835 */ 836 static DECLCALLBACK(int) rtVfsChainGunzip_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec, 837 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError) 838 { 839 RT_NOREF(pProviderReg, poffError); 840 841 if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID) 842 return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT; 843 if (pElement->cArgs != 0) 844 return VERR_VFS_CHAIN_NO_ARGS; 845 if (pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 846 return VERR_VFS_CHAIN_ONLY_IOS; 847 if (pSpec->fOpenFile & RTFILE_O_WRITE) 848 return VERR_VFS_CHAIN_READ_ONLY_IOS; 849 850 return VINF_SUCCESS; 851 } 852 853 854 /** 855 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate} 856 */ 857 static DECLCALLBACK(int) rtVfsChainGunzip_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec, 858 PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj, 859 PRTVFSOBJ phVfsObj, uint32_t *poffError) 860 { 861 RT_NOREF(pProviderReg, pSpec, pElement, poffError); 862 AssertReturn(hPrevVfsObj != NIL_RTVFSOBJ, VERR_VFS_CHAIN_IPE); 863 864 RTVFSIOSTREAM hVfsIosIn = RTVfsObjToIoStream(hPrevVfsObj); 865 if (hVfsIosIn == NIL_RTVFSIOSTREAM) 866 return VERR_VFS_CHAIN_CAST_FAILED; 867 868 RTVFSIOSTREAM hVfsIos = NIL_RTVFSIOSTREAM; 869 int rc = RTZipGzipDecompressIoStream(hVfsIosIn, 0 /*fFlags*/, &hVfsIos); 870 if (RT_SUCCESS(rc)) 871 { 872 *phVfsObj = RTVfsObjFromIoStream(hVfsIos); 873 RTVfsIoStrmRelease(hVfsIos); 874 if (*phVfsObj != NIL_RTVFSOBJ) 875 return VINF_SUCCESS; 876 rc = VERR_VFS_CHAIN_CAST_FAILED; 877 } 878 return rc; 879 } 880 881 882 /** 883 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement} 884 */ 885 static DECLCALLBACK(bool) rtVfsChainGunzip_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg, 886 PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement, 887 PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement) 888 { 889 RT_NOREF(pProviderReg, pSpec, pElement, pReuseSpec, pReuseElement); 890 return false; 891 } 892 893 894 /** VFS chain element 'gunzip'. */ 895 static RTVFSCHAINELEMENTREG g_rtVfsChainGunzipReg = 896 { 897 /* uVersion = */ RTVFSCHAINELEMENTREG_VERSION, 898 /* fReserved = */ 0, 899 /* pszName = */ "gunzip", 900 /* ListEntry = */ { NULL, NULL }, 901 /* pszHelp = */ "Takes an I/O stream and gunzips it. No arguments.", 902 /* pfnValidate = */ rtVfsChainGunzip_Validate, 903 /* pfnInstantiate = */ rtVfsChainGunzip_Instantiate, 904 /* pfnCanReuseElement = */ rtVfsChainGunzip_CanReuseElement, 905 /* uEndMarker = */ RTVFSCHAINELEMENTREG_VERSION 906 }; 907 908 RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainGunzipReg, rtVfsChainGunzipReg); 909 910 911 912 /** 913 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate} 914 */ 915 static DECLCALLBACK(int) rtVfsChainGzip_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec, 916 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError) 917 { 918 RT_NOREF(pProviderReg); 919 920 /* 921 * Basics. 922 */ 923 if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID) 924 return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT; 925 if (pElement->cArgs > 1) 926 return VERR_VFS_CHAIN_AT_MOST_ONE_ARG; 927 if (pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 928 return VERR_VFS_CHAIN_ONLY_IOS; 929 if (pSpec->fOpenFile & RTFILE_O_READ) 930 return VERR_VFS_CHAIN_WRITE_ONLY_IOS; 931 932 /* 933 * Optional argument 1..9 indicating the compression level. 934 * We store it in pSpec->uProvider. 935 */ 936 if (pElement->cArgs > 0) 937 { 938 const char *psz = pElement->paArgs[0].psz; 939 if (!*psz || !strcmp(psz, "default")) 940 pSpec->uProvider = 6; 941 else if (!strcmp(psz, "fast")) 942 pSpec->uProvider = 3; 943 else if ( RT_C_IS_DIGIT(*psz) 944 && *psz != '0' 945 && *RTStrStripL(psz + 1) == '\0') 946 pSpec->uProvider = *psz - '0'; 947 else 948 { 949 *poffError = pElement->paArgs[0].offSpec; 950 return VERR_VFS_CHAIN_INVALID_ARGUMENT; 951 } 952 } 953 else 954 pSpec->uProvider = 6; 955 956 return VINF_SUCCESS; 957 } 958 959 960 /** 961 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate} 962 */ 963 static DECLCALLBACK(int) rtVfsChainGzip_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec, 964 PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj, 965 PRTVFSOBJ phVfsObj, uint32_t *poffError) 966 { 967 RT_NOREF(pProviderReg, pSpec, pElement, poffError); 968 AssertReturn(hPrevVfsObj != NIL_RTVFSOBJ, VERR_VFS_CHAIN_IPE); 969 970 RTVFSIOSTREAM hVfsIosOut = RTVfsObjToIoStream(hPrevVfsObj); 971 if (hVfsIosOut == NIL_RTVFSIOSTREAM) 972 return VERR_VFS_CHAIN_CAST_FAILED; 973 974 RTVFSIOSTREAM hVfsIos = NIL_RTVFSIOSTREAM; 975 int rc = RTZipGzipCompressIoStream(hVfsIosOut, 0 /*fFlags*/, pSpec->uProvider, &hVfsIos); 976 if (RT_SUCCESS(rc)) 977 { 978 *phVfsObj = RTVfsObjFromIoStream(hVfsIos); 979 RTVfsIoStrmRelease(hVfsIos); 980 if (*phVfsObj != NIL_RTVFSOBJ) 981 return VINF_SUCCESS; 982 rc = VERR_VFS_CHAIN_CAST_FAILED; 983 } 984 return rc; 985 } 986 987 988 /** 989 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement} 990 */ 991 static DECLCALLBACK(bool) rtVfsChainGzip_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg, 992 PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement, 993 PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement) 994 { 995 RT_NOREF(pProviderReg, pSpec, pElement, pReuseSpec, pReuseElement); 996 return false; 997 } 998 999 1000 /** VFS chain element 'gzip'. */ 1001 static RTVFSCHAINELEMENTREG g_rtVfsChainGzipReg = 1002 { 1003 /* uVersion = */ RTVFSCHAINELEMENTREG_VERSION, 1004 /* fReserved = */ 0, 1005 /* pszName = */ "gzip", 1006 /* ListEntry = */ { NULL, NULL }, 1007 /* pszHelp = */ "Takes an I/O stream and gzips it.\n" 1008 "Optional argument specifying compression level: 1-9, default, fast", 1009 /* pfnValidate = */ rtVfsChainGzip_Validate, 1010 /* pfnInstantiate = */ rtVfsChainGzip_Instantiate, 1011 /* pfnCanReuseElement = */ rtVfsChainGzip_CanReuseElement, 1012 /* uEndMarker = */ RTVFSCHAINELEMENTREG_VERSION 1013 }; 1014 1015 RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainGzipReg, rtVfsChainGzipReg); 1016
Note:
See TracChangeset
for help on using the changeset viewer.

