MCPcopy Create free account
hub / github.com/Pagghiu/SaneCppLibraries / copyDirectoryRecursive

Method copyDirectoryRecursive

Libraries/FileSystem/FileSystem.cpp:1252–1321  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1250}
1251
1252SC::Result SC::FileSystem::Operations::Internal::copyDirectoryRecursive(const wchar_t* source,
1253 const wchar_t* destination,
1254 FileSystemCopyFlags flags)
1255{
1256 // Create destination directory if it doesn't exist
1257 if (::CreateDirectoryW(destination, nullptr) == FALSE)
1258 {
1259 if (::GetLastError() != ERROR_ALREADY_EXISTS)
1260 {
1261 return Result::Error("copyDirectoryRecursive: Failed to create destination directory");
1262 }
1263 }
1264
1265 // Prepare search pattern
1266 wchar_t searchPattern[StringPath::MaxPath + 6 + 1] = {};
1267 if (::swprintf_s(searchPattern, StringPath::MaxPath + 6 + 1, L"%s\\*", source) == -1)
1268 {
1269 return Result::Error("copyDirectoryRecursive: Path too long");
1270 }
1271
1272 WIN32_FIND_DATAW findData;
1273
1274 HANDLE hFind = ::FindFirstFileW(searchPattern, &findData);
1275 if (hFind == INVALID_HANDLE_VALUE)
1276 {
1277 return Result::Error("copyDirectoryRecursive: Failed to enumerate directory");
1278 }
1279 auto deferClose = MakeDeferred([&]() { ::FindClose(hFind); });
1280
1281 do
1282 {
1283 // Skip . and .. entries
1284 if (::wcscmp(findData.cFileName, L".") == 0 || ::wcscmp(findData.cFileName, L"..") == 0)
1285 continue;
1286
1287 // Build full paths
1288 wchar_t sourcePath[StringPath::MaxPath + 6 + 1] = {};
1289 wchar_t destPath[StringPath::MaxPath + 6 + 1] = {};
1290 if (::swprintf_s(sourcePath, StringPath::MaxPath + 6 + 1, L"%s\\%s", source, findData.cFileName) == -1 ||
1291 ::swprintf_s(destPath, StringPath::MaxPath + 6 + 1, L"%s\\%s", destination, findData.cFileName) == -1)
1292 {
1293 return Result::Error("copyDirectoryRecursive: Path too long");
1294 }
1295
1296 if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1297 {
1298 // Recursively copy subdirectory
1299 SC_TRY(copyDirectoryRecursive(sourcePath, destPath, flags));
1300 }
1301 else
1302 {
1303 // Copy file
1304 DWORD copyFlags = COPY_FILE_FAIL_IF_EXISTS;
1305 if (flags.overwrite)
1306 copyFlags &= ~COPY_FILE_FAIL_IF_EXISTS;
1307
1308 if (::CopyFileExW(sourcePath, destPath, nullptr, nullptr, nullptr, copyFlags) == FALSE)
1309 {

Callers

nothing calls this directly

Calls 3

MakeDeferredFunction · 0.85
ErrorEnum · 0.50
ResultClass · 0.50

Tested by

no test coverage detected