MCPcopy Create free account
hub / github.com/Ahli/Galaxy-Observer-UI / ExtractFile

Function ExtractFile

tools/CascExtractor/CascExtractor/CascExtractor.cpp:214–344  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

212}
213
214static bool ExtractFile(HANDLE hStorage, const CASC_FIND_DATA& findData, const char* targetDirPath, const char* targetFilePath) {
215 namespace fs = std::filesystem;
216
217 PCASC_FILE_SPAN_INFO pSpans = nullptr;
218 HANDLE hFile = nullptr;
219 CASC_FILE_FULL_INFO fileInfo{};
220 LPCSTR szOpenName = findData.szFileName;
221 DWORD dwErrCode = ERROR_SUCCESS;
222
223 if (CascOpenFile(hStorage, szOpenName, NULL /*dwLocaleFlags*/, CASC_STRICT_DATA_CHECK, &hFile))
224 {
225 // Retrieve the information about file spans.
226 if ((pSpans = GetFileInfo(hFile, fileInfo)) != nullptr && fileInfo.ContentSize > 0)
227 {
228 DWORD dwBytesRead = 0;
229 ULONGLONG totalWritten = 0;
230 FILE* pOutFile = nullptr;
231
232 // Load the entire file, one read request per span.
233 // Using span-aligned reads will cause CascReadFile not to do any caching,
234 // and the amount of memcpys will be almost zero
235 for (DWORD i = 0; i < fileInfo.SpanCount && dwErrCode == ERROR_SUCCESS; ++i)
236 {
237 const CASC_FILE_SPAN_INFO* const pFileSpan = pSpans + i;
238 LPBYTE pbFileSpan = nullptr;
239 const auto cbFileSpan = (DWORD) (pFileSpan->EndOffset - pFileSpan->StartOffset);
240 bool bReadOk = true;
241
242 // Do not read empty spans.
243 if (cbFileSpan == 0)
244 {
245 continue;
246 }
247
248 // Allocate span buffer
249 pbFileSpan = CASC_ALLOC<BYTE>(cbFileSpan);
250 if (pbFileSpan == nullptr)
251 {
252 std::cerr << " ERROR: Not enough memory to allocate " << cbFileSpan << " bytes" << std::endl;
253 dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
254 break;
255 }
256
257 // CascReadFile will read as much as possible. If there is a frame error
258 // (e.g. MD5 mismatch, missing encryption key or disc error),
259 // CascReadFile only returns frames that are loaded entirely.
260 bReadOk = CascReadFile(hFile, pbFileSpan, cbFileSpan, &dwBytesRead);
261 if (bReadOk) {
262 // prepare file stream
263 if (!pOutFile) {
264
265 if (fs::exists(targetDirPath) || fs::create_directories(targetDirPath)) {
266
267 // create filestream and empty file
268 if ((pOutFile = OpenExtractedFile(targetFilePath)) == nullptr) {
269 std::cerr << " ERROR: Could not create file: " << targetFilePath << std::endl;
270 }
271 }

Callers 1

mainFunction · 0.85

Calls 3

GetFileInfoFunction · 0.85
OpenExtractedFileFunction · 0.85
CASC_FREEFunction · 0.85

Tested by

no test coverage detected