Repository navigation
Expand file tree
/
Copy pathzip_extractor.cpp
More file actions
149 lines (121 loc) · 4.18 KB
/
Copy pathzip_extractor.cpp
File metadata and controls
149 lines (121 loc) · 4.18 KB
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
/*
* ZIP Extractor using minizip-ng library
*
* Copyright 2020-2026 Vector 35 Inc.
* Licensed under the Apache License, Version 2.0
*/
#ifdef _WIN32
#include "zip_extractor.h"
#include "../vendor/minizip-ng/mz_zip.h"
#include <filesystem>
namespace fs = std::filesystem;
namespace WinDbgInstaller {
namespace {
/* Log levels */
enum LogLevel {
LOG_DEBUG = 0,
LOG_INFO = 1,
LOG_WARN = 2,
LOG_ERROR = 3
};
void Log(LogCallback logCallback, int level, const std::string& message) {
if (logCallback) {
logCallback(level, message);
}
}
} // anonymous namespace
bool ExtractZipArchive(
const std::string& zipPath,
const std::string& extractPath,
ExtractionProgressCallback progressCallback,
LogCallback logCallback)
{
Log(logCallback, LOG_INFO, "Extracting " + zipPath + " to " + extractPath);
mz::ZipReader reader;
int result = reader.Open(zipPath);
if (result != MZ_OK) {
Log(logCallback, LOG_ERROR, "Failed to open ZIP file: " + zipPath + " (error: " + std::to_string(result) + ")");
return false;
}
/* Create destination directory */
std::error_code ec;
fs::create_directories(extractPath, ec);
if (ec) {
Log(logCallback, LOG_ERROR, "Failed to create extract directory: " + extractPath);
reader.Close();
return false;
}
/* Wrapper callback to convert from mz:: format to our format */
auto mzProgressCallback = [&](const std::string& filename, int filesExtracted, int totalFiles) {
if (progressCallback) {
ExtractionProgress progress;
progress.currentFile = filename;
progress.filesExtracted = filesExtracted;
progress.totalFiles = totalFiles;
progressCallback(progress);
}
if (!filename.empty()) {
Log(logCallback, LOG_DEBUG, "Extracting: " + filename);
}
};
result = reader.ExtractAll(extractPath, mzProgressCallback);
reader.Close();
if (result != MZ_OK) {
Log(logCallback, LOG_ERROR, "Failed to extract ZIP file (error: " + std::to_string(result) + ")");
return false;
}
Log(logCallback, LOG_INFO, "Successfully extracted " + std::to_string(reader.GetEntryCount()) + " entries");
return true;
}
std::string ExtractFileFromZipArchive(
const std::string& zipPath,
const std::string& fileName,
const std::string& extractDir,
LogCallback logCallback)
{
Log(logCallback, LOG_INFO, "Extracting " + fileName + " from " + zipPath);
mz::ZipReader reader;
int result = reader.Open(zipPath);
if (result != MZ_OK) {
Log(logCallback, LOG_ERROR, "Failed to open ZIP file: " + zipPath + " (error: " + std::to_string(result) + ")");
return "";
}
/* Find the entry */
const mz::ZipEntry* entry = reader.FindEntry(fileName);
if (!entry) {
Log(logCallback, LOG_ERROR, "File not found in ZIP: " + fileName);
/* List available files for debugging */
Log(logCallback, LOG_DEBUG, "Available files in ZIP:");
for (const auto& e : reader.GetEntries()) {
Log(logCallback, LOG_DEBUG, " " + e.filename);
}
reader.Close();
return "";
}
/* Create destination directory */
std::error_code ec;
fs::create_directories(extractDir, ec);
if (ec) {
Log(logCallback, LOG_ERROR, "Failed to create extract directory: " + extractDir);
reader.Close();
return "";
}
/* Build output path using the entry's actual filename */
fs::path outputPath = fs::path(extractDir) / entry->filename;
/* Extract the file */
result = reader.ExtractFileTo(entry->filename, outputPath.string());
reader.Close();
if (result != MZ_OK) {
Log(logCallback, LOG_ERROR, "Failed to extract file (error: " + std::to_string(result) + ")");
return "";
}
/* Verify the file exists */
if (!fs::exists(outputPath)) {
Log(logCallback, LOG_ERROR, "Extracted file does not exist: " + outputPath.string());
return "";
}
Log(logCallback, LOG_INFO, "Successfully extracted to: " + outputPath.string());
return outputPath.string();
}
} // namespace WinDbgInstaller
#endif // _WIN32