Changeset 66249 in vbox
- Timestamp:
- Mar 26, 2017 9:51:14 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 114170
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/testcase/vbox-img.cpp
r65812 r66249 24 24 #include <VBox/version.h> 25 25 #include <iprt/initterm.h> 26 #include <iprt/asm.h> 26 27 #include <iprt/buildconfig.h> 27 28 #include <iprt/path.h> … … 464 465 { 465 466 RTFILE file; 467 /** Size of file. */ 468 uint64_t cb; 466 469 /** Offset in the file. */ 467 470 uint64_t off; … … 494 497 495 498 pFS->file = file; 499 pFS->cb = 0; 496 500 pFS->off = 0; 497 501 pFS->offBuffer = UINT64_MAX; … … 668 672 } 669 673 670 static DECLCALLBACK(int) conv OutOpen(void *pvUser, const char *pszLocation, uint32_t fOpen, PFNVDCOMPLETED pfnCompleted,671 void **ppStorage)674 static DECLCALLBACK(int) convStdOutOpen(void *pvUser, const char *pszLocation, uint32_t fOpen, PFNVDCOMPLETED pfnCompleted, 675 void **ppStorage) 672 676 { 673 677 RT_NOREF2(pvUser, pszLocation); … … 688 692 689 693 pFS->file = file; 694 pFS->cb = 0; 690 695 pFS->off = 0; 691 696 pFS->offBuffer = 0; … … 696 701 } 697 702 698 static DECLCALLBACK(int) conv OutClose(void *pvUser, void *pStorage)703 static DECLCALLBACK(int) convStdOutClose(void *pvUser, void *pStorage) 699 704 { 700 705 NOREF(pvUser); … … 706 711 if (pFS->cbBuffer) 707 712 rc = RTFileWrite(pFS->file, &pFS->abBuffer[0], pFS->cbBuffer, NULL); 713 if ( RT_SUCCESS(rc) 714 && pFS->cb > pFS->off) 715 { 716 /* Write zeros if the set file size is not met. */ 717 uint64_t cbLeft = pFS->cb - pFS->off; 718 RT_ZERO(pFS->abBuffer); 719 720 while (cbLeft) 721 { 722 size_t cbThisWrite = RT_MIN(cbLeft, sizeof(pFS->abBuffer)); 723 rc = RTFileWrite(pFS->file, &pFS->abBuffer[0], 724 cbThisWrite, NULL); 725 cbLeft -= cbThisWrite; 726 } 727 } 708 728 709 729 RTMemFree(pFS); … … 712 732 } 713 733 714 static DECLCALLBACK(int) conv OutDelete(void *pvUser, const char *pcszFilename)734 static DECLCALLBACK(int) convStdOutDelete(void *pvUser, const char *pcszFilename) 715 735 { 716 736 NOREF(pvUser); … … 719 739 } 720 740 721 static DECLCALLBACK(int) conv OutMove(void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove)741 static DECLCALLBACK(int) convStdOutMove(void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove) 722 742 { 723 743 NOREF(pvUser); … … 728 748 } 729 749 730 static DECLCALLBACK(int) conv OutGetFreeSpace(void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace)750 static DECLCALLBACK(int) convStdOutGetFreeSpace(void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace) 731 751 { 732 752 NOREF(pvUser); … … 737 757 } 738 758 739 static DECLCALLBACK(int) conv OutGetModificationTime(void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime)759 static DECLCALLBACK(int) convStdOutGetModificationTime(void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime) 740 760 { 741 761 NOREF(pvUser); … … 745 765 } 746 766 747 static DECLCALLBACK(int) conv OutGetSize(void *pvUser, void *pStorage, uint64_t *pcbSize)767 static DECLCALLBACK(int) convStdOutGetSize(void *pvUser, void *pStorage, uint64_t *pcbSize) 748 768 { 749 769 NOREF(pvUser); … … 753 773 } 754 774 755 static DECLCALLBACK(int) convOutSetSize(void *pvUser, void *pStorage, uint64_t cbSize) 756 { 757 NOREF(pvUser); 758 NOREF(pStorage); 759 NOREF(cbSize); 775 static DECLCALLBACK(int) convStdOutSetSize(void *pvUser, void *pStorage, uint64_t cbSize) 776 { 777 RT_NOREF2(pvUser, cbSize); 778 AssertPtrReturn(pStorage, VERR_INVALID_POINTER); 760 779 AssertFailedReturn(VERR_NOT_SUPPORTED); 761 780 } 762 781 763 static DECLCALLBACK(int) conv OutRead(void *pvUser, void *pStorage, uint64_t uOffset, void *pvBuffer, size_t cbBuffer,764 size_t *pcbRead)782 static DECLCALLBACK(int) convStdOutRead(void *pvUser, void *pStorage, uint64_t uOffset, void *pvBuffer, size_t cbBuffer, 783 size_t *pcbRead) 765 784 { 766 785 NOREF(pvUser); … … 773 792 } 774 793 775 static DECLCALLBACK(int) conv OutWrite(void *pvUser, void *pStorage, uint64_t uOffset, const void *pvBuffer, size_t cbBuffer,776 size_t *pcbWritten)794 static DECLCALLBACK(int) convStdOutWrite(void *pvUser, void *pStorage, uint64_t uOffset, const void *pvBuffer, size_t cbBuffer, 795 size_t *pcbWritten) 777 796 { 778 797 NOREF(pvUser); … … 818 837 } 819 838 820 static DECLCALLBACK(int) convOutFlush(void *pvUser, void *pStorage) 839 static DECLCALLBACK(int) convStdOutFlush(void *pvUser, void *pStorage) 840 { 841 NOREF(pvUser); 842 NOREF(pStorage); 843 return VINF_SUCCESS; 844 } 845 846 static DECLCALLBACK(int) convFileOutOpen(void *pvUser, const char *pszLocation, uint32_t fOpen, PFNVDCOMPLETED pfnCompleted, 847 void **ppStorage) 848 { 849 RT_NOREF1(pvUser); 850 851 /* Validate input. */ 852 AssertPtrReturn(ppStorage, VERR_INVALID_POINTER); 853 AssertPtrNullReturn(pfnCompleted, VERR_INVALID_PARAMETER); 854 AssertReturn((fOpen & RTFILE_O_ACCESS_MASK) == RTFILE_O_WRITE, VERR_INVALID_PARAMETER); 855 RTFILE file; 856 int rc = RTFileOpen(&file, pszLocation, fOpen); 857 if (RT_FAILURE(rc)) 858 return rc; 859 860 /* Must clear buffer, so that skipped over data is initialized properly. */ 861 PFILEIOSTATE pFS = (PFILEIOSTATE)RTMemAllocZ(sizeof(FILEIOSTATE)); 862 if (!pFS) 863 return VERR_NO_MEMORY; 864 865 pFS->file = file; 866 pFS->cb = 0; 867 pFS->off = 0; 868 pFS->offBuffer = 0; 869 pFS->cbBuffer = sizeof(FILEIOSTATE); 870 871 *ppStorage = pFS; 872 return VINF_SUCCESS; 873 } 874 875 static DECLCALLBACK(int) convFileOutClose(void *pvUser, void *pStorage) 876 { 877 NOREF(pvUser); 878 AssertPtrReturn(pStorage, VERR_INVALID_POINTER); 879 PFILEIOSTATE pFS = (PFILEIOSTATE)pStorage; 880 int rc = VINF_SUCCESS; 881 882 /* Flush any remaining buffer contents. */ 883 if (pFS->cbBuffer) 884 rc = RTFileWriteAt(pFS->file, pFS->offBuffer, &pFS->abBuffer[0], pFS->cbBuffer, NULL); 885 RTFileClose(pFS->file); 886 887 RTMemFree(pFS); 888 889 return rc; 890 } 891 892 static DECLCALLBACK(int) convFileOutDelete(void *pvUser, const char *pcszFilename) 893 { 894 NOREF(pvUser); 895 NOREF(pcszFilename); 896 AssertFailedReturn(VERR_NOT_SUPPORTED); 897 } 898 899 static DECLCALLBACK(int) convFileOutMove(void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove) 900 { 901 NOREF(pvUser); 902 NOREF(pcszSrc); 903 NOREF(pcszDst); 904 NOREF(fMove); 905 AssertFailedReturn(VERR_NOT_SUPPORTED); 906 } 907 908 static DECLCALLBACK(int) convFileOutGetFreeSpace(void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace) 909 { 910 NOREF(pvUser); 911 NOREF(pcszFilename); 912 AssertPtrReturn(pcbFreeSpace, VERR_INVALID_POINTER); 913 *pcbFreeSpace = INT64_MAX; 914 return VINF_SUCCESS; 915 } 916 917 static DECLCALLBACK(int) convFileOutGetModificationTime(void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime) 918 { 919 NOREF(pvUser); 920 NOREF(pcszFilename); 921 AssertPtrReturn(pModificationTime, VERR_INVALID_POINTER); 922 AssertFailedReturn(VERR_NOT_SUPPORTED); 923 } 924 925 static DECLCALLBACK(int) convFileOutGetSize(void *pvUser, void *pStorage, uint64_t *pcbSize) 926 { 927 NOREF(pvUser); 928 NOREF(pStorage); 929 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER); 930 AssertFailedReturn(VERR_NOT_SUPPORTED); 931 } 932 933 static DECLCALLBACK(int) convFileOutSetSize(void *pvUser, void *pStorage, uint64_t cbSize) 934 { 935 NOREF(pvUser); 936 AssertPtrReturn(pStorage, VERR_INVALID_POINTER); 937 PFILEIOSTATE pFS = (PFILEIOSTATE)pStorage; 938 939 int rc = RTFileSetSize(pFS->file, cbSize); 940 if (RT_SUCCESS(rc)) 941 pFS->cb = cbSize; 942 return VINF_SUCCESS; 943 } 944 945 static DECLCALLBACK(int) convFileOutRead(void *pvUser, void *pStorage, uint64_t uOffset, void *pvBuffer, size_t cbBuffer, 946 size_t *pcbRead) 947 { 948 NOREF(pvUser); 949 NOREF(pStorage); 950 NOREF(uOffset); 951 NOREF(cbBuffer); 952 NOREF(pcbRead); 953 AssertPtrReturn(pvBuffer, VERR_INVALID_POINTER); 954 AssertFailedReturn(VERR_NOT_SUPPORTED); 955 } 956 957 static DECLCALLBACK(int) convFileOutWrite(void *pvUser, void *pStorage, uint64_t uOffset, const void *pvBuffer, size_t cbBuffer, 958 size_t *pcbWritten) 959 { 960 NOREF(pvUser); 961 AssertPtrReturn(pStorage, VERR_INVALID_POINTER); 962 AssertPtrReturn(pvBuffer, VERR_INVALID_POINTER); 963 PFILEIOSTATE pFS = (PFILEIOSTATE)pStorage; 964 AssertReturn(uOffset >= pFS->off, VERR_INVALID_PARAMETER); 965 int rc; 966 967 /* Write the data to the buffer, flushing as required. */ 968 size_t cbTotalWritten = 0; 969 do 970 { 971 /* Flush the buffer if we need a new one. */ 972 while (uOffset > pFS->offBuffer + sizeof(pFS->abBuffer) - 1) 973 { 974 if (!ASMMemIsZero(pFS->abBuffer, sizeof(pFS->abBuffer))) 975 rc = RTFileWriteAt(pFS->file, pFS->offBuffer, 976 &pFS->abBuffer[0], 977 sizeof(pFS->abBuffer), NULL); 978 RT_ZERO(pFS->abBuffer); 979 pFS->offBuffer += sizeof(pFS->abBuffer); 980 pFS->cbBuffer = 0; 981 } 982 983 uint32_t cbThisWrite = (uint32_t)RT_MIN(cbBuffer, 984 sizeof(pFS->abBuffer) - uOffset % sizeof(pFS->abBuffer)); 985 memcpy(&pFS->abBuffer[uOffset % sizeof(pFS->abBuffer)], pvBuffer, 986 cbThisWrite); 987 uOffset += cbThisWrite; 988 pvBuffer = (uint8_t *)pvBuffer + cbThisWrite; 989 cbBuffer -= cbThisWrite; 990 cbTotalWritten += cbThisWrite; 991 } while (cbBuffer > 0); 992 993 if (pcbWritten) 994 *pcbWritten = cbTotalWritten; 995 996 pFS->cbBuffer = uOffset % sizeof(pFS->abBuffer); 997 if (!pFS->cbBuffer) 998 pFS->cbBuffer = sizeof(pFS->abBuffer); 999 pFS->off = uOffset; 1000 1001 return VINF_SUCCESS; 1002 } 1003 1004 static DECLCALLBACK(int) convFileOutFlush(void *pvUser, void *pStorage) 821 1005 { 822 1006 NOREF(pvUser); … … 831 1015 bool fStdIn = false; 832 1016 bool fStdOut = false; 1017 bool fCreateSparse = false; 833 1018 const char *pszSrcFormat = NULL; 834 1019 VDTYPE enmSrcType = VDTYPE_HDD; … … 853 1038 { "--srcformat", 's', RTGETOPT_REQ_STRING }, 854 1039 { "--dstformat", 'd', RTGETOPT_REQ_STRING }, 855 { "--variant", 'v', RTGETOPT_REQ_STRING } 1040 { "--variant", 'v', RTGETOPT_REQ_STRING }, 1041 { "--create-sparse", 'c', RTGETOPT_REQ_NOTHING } 856 1042 }; 857 1043 int ch; … … 883 1069 case 'v': // --variant 884 1070 pszVariant = ValueUnion.psz; 1071 break; 1072 case 'c': // --create-sparse 1073 fCreateSparse = true; 885 1074 break; 886 1075 … … 936 1125 if (fStdOut) 937 1126 { 938 IfsOutputIO.pfnOpen = conv OutOpen;939 IfsOutputIO.pfnClose = conv OutClose;940 IfsOutputIO.pfnDelete = conv OutDelete;941 IfsOutputIO.pfnMove = conv OutMove;942 IfsOutputIO.pfnGetFreeSpace = conv OutGetFreeSpace;943 IfsOutputIO.pfnGetModificationTime = conv OutGetModificationTime;944 IfsOutputIO.pfnGetSize = conv OutGetSize;945 IfsOutputIO.pfnSetSize = conv OutSetSize;946 IfsOutputIO.pfnReadSync = conv OutRead;947 IfsOutputIO.pfnWriteSync = conv OutWrite;948 IfsOutputIO.pfnFlushSync = conv OutFlush;1127 IfsOutputIO.pfnOpen = convStdOutOpen; 1128 IfsOutputIO.pfnClose = convStdOutClose; 1129 IfsOutputIO.pfnDelete = convStdOutDelete; 1130 IfsOutputIO.pfnMove = convStdOutMove; 1131 IfsOutputIO.pfnGetFreeSpace = convStdOutGetFreeSpace; 1132 IfsOutputIO.pfnGetModificationTime = convStdOutGetModificationTime; 1133 IfsOutputIO.pfnGetSize = convStdOutGetSize; 1134 IfsOutputIO.pfnSetSize = convStdOutSetSize; 1135 IfsOutputIO.pfnReadSync = convStdOutRead; 1136 IfsOutputIO.pfnWriteSync = convStdOutWrite; 1137 IfsOutputIO.pfnFlushSync = convStdOutFlush; 949 1138 VDInterfaceAdd(&IfsOutputIO.Core, "stdout", VDINTERFACETYPE_IO, 1139 NULL, sizeof(VDINTERFACEIO), &pIfsImageOutput); 1140 } 1141 else if (fCreateSparse) 1142 { 1143 IfsOutputIO.pfnOpen = convFileOutOpen; 1144 IfsOutputIO.pfnClose = convFileOutClose; 1145 IfsOutputIO.pfnDelete = convFileOutDelete; 1146 IfsOutputIO.pfnMove = convFileOutMove; 1147 IfsOutputIO.pfnGetFreeSpace = convFileOutGetFreeSpace; 1148 IfsOutputIO.pfnGetModificationTime = convFileOutGetModificationTime; 1149 IfsOutputIO.pfnGetSize = convFileOutGetSize; 1150 IfsOutputIO.pfnSetSize = convFileOutSetSize; 1151 IfsOutputIO.pfnReadSync = convFileOutRead; 1152 IfsOutputIO.pfnWriteSync = convFileOutWrite; 1153 IfsOutputIO.pfnFlushSync = convFileOutFlush; 1154 VDInterfaceAdd(&IfsOutputIO.Core, "fileout", VDINTERFACETYPE_IO, 950 1155 NULL, sizeof(VDINTERFACEIO), &pIfsImageOutput); 951 1156 }
Note:
See TracChangeset
for help on using the changeset viewer.