| 275 | } |
| 276 | |
| 277 | int __stdcall ProcessFile(WCX_HANDLE hArcData, int Operation, char* DestPath, char* DestName) |
| 278 | { |
| 279 | auto* arc = reinterpret_cast<PboArchive*>(hArcData); |
| 280 | if (!arc || arc->currentIndex >= static_cast<int>(arc->entries.size())) |
| 281 | return E_END_ARCHIVE; |
| 282 | |
| 283 | const auto& e = arc->entries[arc->currentIndex]; |
| 284 | arc->currentIndex++; |
| 285 | |
| 286 | if (Operation == PK_SKIP || Operation == PK_TEST) |
| 287 | return 0; |
| 288 | |
| 289 | if (Operation == PK_EXTRACT) |
| 290 | { |
| 291 | std::string outPath; |
| 292 | if (DestPath && DestPath[0]) |
| 293 | { |
| 294 | outPath = DestPath; |
| 295 | if (outPath.back() != '\\' && outPath.back() != '/') |
| 296 | outPath += PathSeparator(); |
| 297 | } |
| 298 | if (DestName && DestName[0]) |
| 299 | outPath += DestName; |
| 300 | else |
| 301 | { |
| 302 | std::string name = e.name; |
| 303 | NormalizePathSeparators(name); |
| 304 | outPath += name; |
| 305 | } |
| 306 | |
| 307 | CreateParentDirs(outPath); |
| 308 | |
| 309 | Ref<IFileBuffer> data = arc->bank.Read(e.name.c_str()); |
| 310 | if (!data) |
| 311 | return E_EREAD; |
| 312 | |
| 313 | #ifdef _WIN32 |
| 314 | HANDLE hFile = |
| 315 | CreateFileA(outPath.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); |
| 316 | if (hFile == INVALID_HANDLE_VALUE) |
| 317 | return E_ECREATE; |
| 318 | |
| 319 | if (data->GetSize() > 0) |
| 320 | { |
| 321 | DWORD written = 0; |
| 322 | if (!WriteFile(hFile, data->GetData(), static_cast<DWORD>(data->GetSize()), &written, nullptr)) |
| 323 | { |
| 324 | CloseHandle(hFile); |
| 325 | return E_EWRITE; |
| 326 | } |
| 327 | } |
| 328 | CloseHandle(hFile); |
| 329 | #else |
| 330 | if (!WriteFileData(outPath, data->GetData(), data->GetSize())) |
| 331 | return E_ECREATE; |
| 332 | #endif |
| 333 | |
| 334 | if (arc->processDataProc) |
nothing calls this directly
no test coverage detected