VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Boot/Windows/Boot.vcxproj
blob: b9a04d80881b5dc73bcadddefdd889455ad1dd8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Release Loader|Win32">
      <Configuration>Release Loader</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{8B7F059F-E4C7-4E11-88F5-EE8B8433072E}</ProjectGuid>
    <RootNamespace>Boot</RootNamespace>
    <Keyword>MakeFileProj</Keyword>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'" Label="Configuration">
    <ConfigurationType>Makefile</ConfigurationType>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Makefile</ConfigurationType>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</OutDir>
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">md Release 2&gt;NUL:
nmake.exe /nologo RELEASE=1

md Release_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2

md Release_AES 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

md Release_AES_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2

md Release_Serpent 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

md Release_Serpent_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2

md Release_Twofish 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

md Release_Twofish_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2

md Release_Camellia 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=CAMELLIA

md Release_Camellia_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=CAMELLIA SINGLE_PRF=SHA2

md Rescue 2&gt;NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

md Rescue_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_AES 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

md Rescue_AES_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_Serpent 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

md Rescue_Serpent_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_Twofish 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1

md Rescue_Twofish_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_Camellia 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=CAMELLIA RESCUE_DISK=1

md Rescue_Camellia_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=CAMELLIA RESCUE_DISK=1 SINGLE_PRF=SHA2</NMakeBuildCommandLine>
    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">del /q /s Release &gt;NUL:
md Release 2&gt;NUL:
nmake.exe /nologo RELEASE=1

del /q /s Release_SHA2 &gt;NUL:
md Release_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2

del /q /s Release_AES &gt;NUL:
md Release_AES 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

del /q /s Release_AES_SHA2 &gt;NUL:
md Release_AES_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2

del /q /s Release_Serpent &gt;NUL:
md Release_Serpent 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

del /q /s Release_Serpent_SHA2 &gt;NUL:
md Release_Serpent_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2

del /q /s Release_Twofish &gt;NUL:
md Release_Twofish 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

del /q /s Release_Twofish_SHA2 &gt;NUL:
md Release_Twofish_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2

del /q /s Release_Camellia &gt;NUL:
md Release_Camellia 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=CAMELLIA

del /q /s Release_Camellia_SHA2 &gt;NUL:
md Release_Camellia_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=CAMELLIA SINGLE_PRF=SHA2

del /q /s Rescue &gt;NUL:
md Rescue 2&gt;NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

del /q /s Rescue_SHA2 &gt;NUL:
md Rescue_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_AES &gt;NUL:
md Rescue_AES 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

del /q /s Rescue_AES_SHA2 &gt;NUL:
md Rescue_AES_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_Serpent &gt;NUL:
md Rescue_Serpent 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

del /q /s Rescue_Serpent_SHA2 &gt;NUL:
md Rescue_Serpent_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_Twofish &gt;NUL:
md Rescue_Twofish 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1

del /q /s Rescue_Twofish_SHA2 &gt;NUL:
md Rescue_Twofish_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_Camellia &gt;NUL:
md Rescue_Camellia 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=CAMELLIA RESCUE_DISK=1

del /q /s Rescue_Camellia_SHA2 &gt;NUL:
md Rescue_Camellia_SHA2 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=CAMELLIA RESCUE_DISK=1 SINGLE_PRF=SHA2</NMakeReBuildCommandLine>
    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">del /q /s Release Release_AES Release_Serpent Release_Twofish Release_Camellia Rescue Rescue_AES Rescue_Serpent Rescue_Twofish Rescue_Camellia &gt;NUL:
del /q /s Release_SHA2 Release_AES_SHA2 Release_Serpent_SHA2 Release_Twofish_SHA2 Release_Camellia_SHA2 Rescue_SHA2 Rescue_AES_SHA2 Rescue_Serpent_SHA2 Rescue_Twofish_SHA2 Rescue_Camellia_SHA2 &gt;NUL:
</NMakeCleanCommandLine>
    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\BootLoader.com</NMakeOutput>
    <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
    <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir);$(SolutionDir)\Common;$(SolutionDir)\Crypto;$(MSVC16_ROOT)\Include;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>
    <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
    <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
    <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">$(Configuration)\</OutDir>
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">$(Configuration)\</IntDir>
    <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">md Release 2&gt;NUL:
nmake.exe /nologo RELEASE=1

md Release_AES 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

md Release_Serpent 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

md Release_Twofish 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH</NMakeBuildCommandLine>
    <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">del /q /s Release &gt;NUL:
md Release 2&gt;NUL:
nmake.exe /nologo RELEASE=1

del /q /s Release_AES &gt;NUL:
md Release_AES 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

del /q /s Release_Serpent &gt;NUL:
md Release_Serpent 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

del /q /s Release_Twofish &gt;NUL:
md Release_Twofish 2&gt;NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH</NMakeReBuildCommandLine>
    <NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">del /q /s Release Release_AES Release_Serpent Release_Twofish &gt;NUL:</NMakeCleanCommandLine>
    <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">Release\BootLoader.com</NMakeOutput>
    <NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">WIN32;NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
    <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">$(SolutionDir);$(SolutionDir)\Common;$(SolutionDir)\Crypto;$(MSVC16_ROOT)\Include;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>
    <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
    <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
    <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release Loader|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
  </PropertyGroup>
  <ItemDefinitionGroup>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="..\..\Crypto\blake2s-ref.c" />
    <ClCompile Include="BootConfig.cpp" />
    <ClCompile Include="BootConsoleIo.cpp" />
    <ClCompile Include="BootDebug.cpp" />
    <ClCompile Include="BootDiskIo.cpp" />
    <ClCompile Include="BootEncryptedIo.cpp" />
    <ClCompile Include="BootMain.cpp" />
    <ClCompile Include="BootMemory.cpp" />
    <ClCompile Include="Decompressor.c" />
    <ClCompile Include="IntFilter.cpp" />
    <ClCompile Include="Platform.cpp" />
    <ClCompile Include="..\..\Common\Crc.c" />
    <ClCompile Include="..\..\Common\Crypto.c" />
    <ClCompile Include="..\..\Common\Endian.c" />
    <ClCompile Include="..\..\Common\Pkcs5.c" />
    <ClCompile Include="..\..\Common\Volumes.c" />
    <ClCompile Include="..\..\Common\Xts.c" />
    <ClCompile Include="..\..\Crypto\AesSmall.c" />
    <ClCompile Include="..\..\Crypto\CamelliaSmall.c" />
    <ClCompile Include="..\..\Crypto\Serpent.c" />
    <ClCompile Include="..\..\Crypto\Sha2Small.c" />
    <ClCompile Include="..\..\Crypto\Twofish.c" />
  </ItemGroup>
  <ItemGroup>
    <None Include="BootCrt.asm" />
    <None Include="BootSector.asm" />
    <None Include="..\..\Crypto\Aes_hw_cpu.asm" />
    <None Include="..\..\Crypto\AesSmall_x86.asm" />
    <None Include="Makefile" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="Bios.h" />
    <ClInclude Include="BootCommon.h" />
    <ClInclude Include="BootConfig.h" />
    <ClInclude Include="BootConsoleIo.h" />
    <ClInclude Include="BootDebug.h" />
    <ClInclude Include="BootDefs.h" />
    <ClInclude Include="BootDiskIo.h" />
    <ClInclude Include="BootEncryptedIo.h" />
    <ClInclude Include="BootMain.h" />
    <ClInclude Include="BootMemory.h" />
    <ClInclude Include="BootStrings.h" />
    <ClInclude Include="IntFilter.h" />
    <ClInclude Include="Platform.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>
ion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "zipint.h" #include <stdio.h> #include <stdlib.h> #ifdef _WIN32 #include <fcntl.h> #include <io.h> #endif static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_t); static int copy_data(zip_t *, zip_uint64_t); static int copy_source(zip_t *, zip_source_t *, zip_int64_t); static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t); static int write_data_descriptor(zip_t *za, const zip_dirent_t *dirent, int is_zip64); ZIP_EXTERN int zip_close(zip_t *za) { zip_uint64_t i, j, survivors, unchanged_offset; zip_int64_t off; int error; zip_filelist_t *filelist; int changed; if (za == NULL) return -1; changed = _zip_changed(za, &survivors); /* don't create zip files with no entries */ if (survivors == 0) { if ((za->open_flags & ZIP_TRUNCATE) || changed) { if (zip_source_remove(za->src) < 0) { if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) { _zip_error_set_from_source(&za->error, za->src); return -1; } } } zip_discard(za); return 0; } if (!changed) { zip_discard(za); return 0; } if (survivors > za->nentry) { zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); return -1; } if ((filelist = (zip_filelist_t *)malloc(sizeof(filelist[0]) * (size_t)survivors)) == NULL) return -1; unchanged_offset = ZIP_UINT64_MAX; /* create list of files with index into original archive */ for (i = j = 0; i < za->nentry; i++) { if (za->entry[i].orig != NULL && ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { unchanged_offset = ZIP_MIN(unchanged_offset, za->entry[i].orig->offset); } if (za->entry[i].deleted) { continue; } if (j >= survivors) { free(filelist); zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); return -1; } filelist[j].idx = i; j++; } if (j < survivors) { free(filelist); zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); return -1; } if ((zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) { unchanged_offset = 0; } else { if (unchanged_offset == ZIP_UINT64_MAX) { /* we're keeping all file data, find the end of the last one */ zip_uint64_t last_index = ZIP_UINT64_MAX; unchanged_offset = 0; for (i = 0; i < za->nentry; i++) { if (za->entry[i].orig != NULL) { if (za->entry[i].orig->offset >= unchanged_offset) { unchanged_offset = za->entry[i].orig->offset; last_index = i; } } } if (last_index != ZIP_UINT64_MAX) { if ((unchanged_offset = _zip_file_get_end(za, last_index, &za->error)) == 0) { free(filelist); return -1; } } } if (unchanged_offset > 0) { if (zip_source_begin_write_cloning(za->src, unchanged_offset) < 0) { /* cloning not supported, need to copy everything */ unchanged_offset = 0; } } } if (unchanged_offset == 0) { if (zip_source_begin_write(za->src) < 0) { _zip_error_set_from_source(&za->error, za->src); free(filelist); return -1; } } if (_zip_progress_start(za->progress) != 0) { zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); zip_source_rollback_write(za->src); free(filelist); return -1; } error = 0; for (j = 0; j < survivors; j++) { int new_data; zip_entry_t *entry; zip_dirent_t *de; if (_zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors) != 0) { zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); error = 1; break; } i = filelist[j].idx; entry = za->entry + i; if (entry->orig != NULL && entry->orig->offset < unchanged_offset) { /* already implicitly copied by cloning */ continue; } new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD)); /* create new local directory entry */ if (entry->changes == NULL) { if ((entry->changes = _zip_dirent_clone(entry->orig)) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); error = 1; break; } } de = entry->changes; if (_zip_read_local_ef(za, i) < 0) { error = 1; break; } if ((off = zip_source_tell_write(za->src)) < 0) { _zip_error_set_from_source(&za->error, za->src); error = 1; break; } de->offset = (zip_uint64_t)off; if (new_data) { zip_source_t *zs; zs = NULL; if (!ZIP_ENTRY_DATA_CHANGED(entry)) { if ((zs = _zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { error = 1; break; } } /* add_data writes dirent */ if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) { error = 1; if (zs) zip_source_free(zs); break; } if (zs) zip_source_free(zs); } else { zip_uint64_t offset; if (de->encryption_method != ZIP_EM_TRAD_PKWARE) { /* when copying data, all sizes are known -> no data descriptor needed */ /* except for PKWare encryption, where removing the data descriptor breaks password validation */ de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; } if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) { error = 1; break; } if ((offset = _zip_file_get_offset(za, i, &za->error)) == 0) { error = 1; break; } if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { _zip_error_set_from_source(&za->error, za->src); error = 1; break; } if (copy_data(za, de->comp_size) < 0) { error = 1; break; } if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { if (write_data_descriptor(za, de, _zip_dirent_needs_zip64(de, 0)) < 0) { error = 1; break; } } } } if (!error) { if (write_cdir(za, filelist, survivors) < 0) error = 1; } free(filelist); if (!error) { if (zip_source_commit_write(za->src) != 0) { _zip_error_set_from_source(&za->error, za->src); error = 1; } _zip_progress_end(za->progress); } if (error) { zip_source_rollback_write(za->src); return -1; } zip_discard(za); return 0; } static int add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { zip_int64_t offstart, offdata, offend, data_length; zip_stat_t st; zip_file_attributes_t attributes; zip_source_t *src_final, *src_tmp; int ret; int is_zip64; zip_flags_t flags; bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt; if (zip_source_stat(src, &st) < 0) { _zip_error_set_from_source(&za->error, src); return -1; } if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) { st.valid |= ZIP_STAT_COMP_METHOD; st.comp_method = ZIP_CM_STORE; } if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE) de->comp_method = st.comp_method; else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) { st.valid |= ZIP_STAT_COMP_SIZE; st.comp_size = st.size; } else { /* we'll recompress */ st.valid &= ~ZIP_STAT_COMP_SIZE; } if ((st.valid & ZIP_STAT_ENCRYPTION_METHOD) == 0) { st.valid |= ZIP_STAT_ENCRYPTION_METHOD; st.encryption_method = ZIP_EM_NONE; } flags = ZIP_EF_LOCAL; if ((st.valid & ZIP_STAT_SIZE) == 0) { flags |= ZIP_FL_FORCE_ZIP64; data_length = -1; } else { de->uncomp_size = st.size; /* this is technically incorrect (copy_source counts compressed data), but it's the best we have */ data_length = (zip_int64_t)st.size; if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { zip_uint64_t max_size; switch (ZIP_CM_ACTUAL(de->comp_method)) { case ZIP_CM_BZIP2: /* computed by looking at increase of 10 random files of size 1MB when * compressed with bzip2, rounded up: 1.006 */ max_size = 4269351188u; break; case ZIP_CM_DEFLATE: /* max deflate size increase: size + ceil(size/16k)*5+6 */ max_size = 4293656963u; break; case ZIP_CM_STORE: max_size = 0xffffffffu; break; default: max_size = 0; } if (st.size > max_size) { flags |= ZIP_FL_FORCE_ZIP64; } } else de->comp_size = st.comp_size; } if ((offstart = zip_source_tell_write(za->src)) < 0) { _zip_error_set_from_source(&za->error, za->src); return -1; } /* as long as we don't support non-seekable output, clear data descriptor bit */ de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; if ((is_zip64 = _zip_dirent_write(za, de, flags)) < 0) { return -1; } needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method); needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE); needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress; needs_compress = needs_recompress && (de->comp_method != ZIP_CM_STORE); needs_reencrypt = needs_recompress || (de->changed & ZIP_DIRENT_PASSWORD) || (de->encryption_method != st.encryption_method); needs_decrypt = needs_reencrypt && (st.encryption_method != ZIP_EM_NONE); needs_encrypt = needs_reencrypt && (de->encryption_method != ZIP_EM_NONE); src_final = src; zip_source_keep(src_final); if (needs_decrypt) { zip_encryption_implementation impl; if ((impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); zip_source_free(src_final); return -1; } if ((src_tmp = impl(za, src_final, st.encryption_method, ZIP_CODEC_DECODE, za->default_password)) == NULL) { /* error set by impl */ zip_source_free(src_final); return -1; } zip_source_free(src_final); src_final = src_tmp; } if (needs_decompress) { if ((src_tmp = zip_source_decompress(za, src_final, st.comp_method)) == NULL) { zip_source_free(src_final); return -1; } zip_source_free(src_final); src_final = src_tmp; } if (needs_crc) { if ((src_tmp = zip_source_crc(za, src_final, 0)) == NULL) { zip_source_free(src_final); return -1; } zip_source_free(src_final); src_final = src_tmp; } if (needs_compress) { if ((src_tmp = zip_source_compress(za, src_final, de->comp_method, de->compression_level)) == NULL) { zip_source_free(src_final); return -1; } zip_source_free(src_final); src_final = src_tmp; } if (needs_encrypt) { zip_encryption_implementation impl; const char *password = NULL; if (de->password) { password = de->password; } else if (za->default_password) { password = za->default_password; } if ((impl = _zip_get_encryption_implementation(de->encryption_method, ZIP_CODEC_ENCODE)) == NULL) { zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); zip_source_free(src_final); return -1; } if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) { /* error set by impl */ zip_source_free(src_final); return -1; } if (de->encryption_method == ZIP_EM_TRAD_PKWARE) { de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR; } zip_source_free(src_final); src_final = src_tmp; } if ((offdata = zip_source_tell_write(za->src)) < 0) { _zip_error_set_from_source(&za->error, za->src); return -1; } ret = copy_source(za, src_final, data_length); if (zip_source_stat(src_final, &st) < 0) { _zip_error_set_from_source(&za->error, src_final); ret = -1; } if (zip_source_get_file_attributes(src_final, &attributes) != 0) { _zip_error_set_from_source(&za->error, src_final); ret = -1; } zip_source_free(src_final); if (ret < 0) { return -1; } if ((offend = zip_source_tell_write(za->src)) < 0) { _zip_error_set_from_source(&za->error, za->src); return -1; } if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) { _zip_error_set_from_source(&za->error, za->src); return -1; } if ((st.valid & (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) { zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); return -1; } if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) { if (st.valid & ZIP_STAT_MTIME) de->last_mod = st.mtime; else time(&de->last_mod); } de->comp_method = st.comp_method; de->crc = st.crc; de->uncomp_size = st.size; de->comp_size = (zip_uint64_t)(offend - offdata); _zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed); if ((ret = _zip_dirent_write(za, de, flags)) < 0) return -1; if (is_zip64 != ret) { /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */ zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); return -1; } if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) { _zip_error_set_from_source(&za->error, za->src); return -1; } if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { if (write_data_descriptor(za, de, is_zip64) < 0) { return -1; } } return 0; } static int copy_data(zip_t *za, zip_uint64_t len) { DEFINE_BYTE_ARRAY(buf, BUFSIZE); size_t n; double total = (double)len; if (!byte_array_init(buf, BUFSIZE)) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return -1; } while (len > 0) { n = len > BUFSIZE ? BUFSIZE : len; if (_zip_read(za->src, buf, n, &za->error) < 0) { byte_array_fini(buf); return -1; } if (_zip_write(za, buf, n) < 0) { byte_array_fini(buf); return -1; } len -= n; if (_zip_progress_update(za->progress, (total - (double)len) / total) != 0) { zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); return -1; } } byte_array_fini(buf); return 0; } static int copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) { DEFINE_BYTE_ARRAY(buf, BUFSIZE); zip_int64_t n, current; int ret; if (zip_source_open(src) < 0) { _zip_error_set_from_source(&za->error, src); return -1; } if (!byte_array_init(buf, BUFSIZE)) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return -1; } ret = 0; current = 0; while ((n = zip_source_read(src, buf, BUFSIZE)) > 0) { if (_zip_write(za, buf, (zip_uint64_t)n) < 0) { ret = -1; break; } if (n == BUFSIZE && za->progress && data_length > 0) { current += n; if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) { zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); ret = -1; break; } } } if (n < 0) { _zip_error_set_from_source(&za->error, src); ret = -1; } byte_array_fini(buf); zip_source_close(src); return ret; } static int write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) { zip_int64_t cd_start, end, size; if ((cd_start = zip_source_tell_write(za->src)) < 0) { return -1; } if ((size = _zip_cdir_write(za, filelist, survivors)) < 0) { return -1; } if ((end = zip_source_tell_write(za->src)) < 0) { return -1; } return 0; } int _zip_changed(const zip_t *za, zip_uint64_t *survivorsp) { int changed; zip_uint64_t i, survivors; changed = 0; survivors = 0; if (za->comment_changed || za->ch_flags != za->flags) { changed = 1; } for (i = 0; i < za->nentry; i++) { if (ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { changed = 1; } if (!za->entry[i].deleted) { survivors++; } } if (survivorsp) { *survivorsp = survivors; } return changed; } static int write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) { zip_buffer_t *buffer = _zip_buffer_new(NULL, MAX_DATA_DESCRIPTOR_LENGTH); int ret = 0; if (buffer == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return -1; } _zip_buffer_put(buffer, DATADES_MAGIC, 4); _zip_buffer_put_32(buffer, de->crc); if (is_zip64) { _zip_buffer_put_64(buffer, de->comp_size); _zip_buffer_put_64(buffer, de->uncomp_size); } else { _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size); _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size); } if (!_zip_buffer_ok(buffer)) { zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); ret = -1; } else { ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)); } _zip_buffer_free(buffer); return ret; }