| 1390 | |
| 1391 | |
| 1392 | bool Line::Util_CopyDir(LPCTSTR szInputSource, LPCTSTR szInputDest, int OverwriteMode, bool bMove) |
| 1393 | { |
| 1394 | bool bOverwrite = OverwriteMode == 1 || OverwriteMode == 2; // Strict validation for safety. |
| 1395 | |
| 1396 | // Get the fullpathnames and strip trailing \s |
| 1397 | TCHAR szSource[_MAX_PATH+2]; |
| 1398 | TCHAR szDest[_MAX_PATH+2]; |
| 1399 | Util_GetFullPathName(szInputSource, szSource); |
| 1400 | Util_GetFullPathName(szInputDest, szDest); |
| 1401 | |
| 1402 | // Ensure source is a directory |
| 1403 | if (Util_IsDir(szSource) == false) |
| 1404 | return false; // Nope |
| 1405 | |
| 1406 | // Jon on the AutoIt forums says "Well SHFileOp is way too unpredictable under 9x. Grrr." |
| 1407 | // So the comments below about some OSes/old versions are probably just referring to 9x, |
| 1408 | // which we don't support anymore. Testing on Windows 2000 and Windows 10 showed that |
| 1409 | // SHFileOperation can move a directory between two volumes. However, performing copy |
| 1410 | // then remove ensures nothing is removed if the copy partially fails, so it's kept this |
| 1411 | // way for backward-compatibility, even though it may be inconsistent with local moves. |
| 1412 | // Obsolete comment from Util_MoveDir: |
| 1413 | // If the source and dest are on different volumes then we must copy rather than move |
| 1414 | // as move in this case only works on some OSes. Copy and delete (poor man's move). |
| 1415 | if (bMove && (ctolower(szSource[0]) != ctolower(szDest[0]) || szSource[1] != ':')) |
| 1416 | { |
| 1417 | if (!Util_CopyDir(szSource, szDest, bOverwrite, false)) |
| 1418 | return false; |
| 1419 | return Util_RemoveDir(szSource, true); |
| 1420 | } |
| 1421 | |
| 1422 | // Does the destination dir exist? |
| 1423 | DWORD attr = GetFileAttributes(szDest); |
| 1424 | if (attr != 0xFFFFFFFF) // Destination already exists as a file or directory. |
| 1425 | { |
| 1426 | if (attr & FILE_ATTRIBUTE_DIRECTORY) // Dest already exists as a directory. |
| 1427 | { |
| 1428 | if (!bOverwrite) // Overwrite Mode is "Never". |
| 1429 | return false; |
| 1430 | } |
| 1431 | else // Dest already exists as a file. |
| 1432 | return false; // Don't even attempt to overwrite a file with a dir, regardless of mode (I think SHFileOperation refuses to do it anyway). |
| 1433 | } |
| 1434 | else // Dest doesn't exist. |
| 1435 | { |
| 1436 | // We must create the top level directory |
| 1437 | // FOF_SILENT (which is included in FOF_NO_UI and means "Do not display a progress dialog box") |
| 1438 | // seems to be bugged on some older OSes (such as 2k and XP). Specifically, it answers "No" to |
| 1439 | // the "confirmmkdir" dialog, which it isn't supposed to suppress, and ignores FOF_NOCONFIRMMKDIR. |
| 1440 | // Creating the directory first works around this. Win 7 is okay without this; Vista wasn't tested. |
| 1441 | if (!bMove && !FileCreateDir(szDest)) |
| 1442 | return false; |
| 1443 | } |
| 1444 | |
| 1445 | // The wildcard below is kept for backward-compatibility, although as indicated above, the |
| 1446 | // issues alluded to below are probably only on 9x, which is no longer supported. Adding the |
| 1447 | // wildcard appears to permit copying a directory into itself (perhaps because the directory |
| 1448 | // itself isn't being copied), although we still document the result as "undefined". |
| 1449 | // Really old comment: |
nothing calls this directly
no test coverage detected