MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / Util_CopyFile

Method Util_CopyFile

source/script_autoit.cpp:1537–1647  ·  view source on GitHub ↗

////////////////////////////////////////////////////////////////////////// Util_CopyFile() (moves files too) Returns the number of files that could not be copied or moved due to error. //////////////////////////////////////////////////////////////////////////

Source from the content-addressed store, hash-verified

1535// Returns the number of files that could not be copied or moved due to error.
1536///////////////////////////////////////////////////////////////////////////////
1537int Line::Util_CopyFile(LPCTSTR szInputSource, LPCTSTR szInputDest, bool bOverwrite, bool bMove, DWORD &aLastError)
1538{
1539 TCHAR szSource[T_MAX_PATH];
1540 TCHAR szDest[T_MAX_PATH];
1541 TCHAR szDestPattern[MAX_PATH];
1542
1543 // Get local version of our source/dest with full path names, strip trailing \s
1544 // and normalize the path separator (replace / with \).
1545 Util_GetFullPathName(szInputSource, szSource, _countof(szSource));
1546 Util_GetFullPathName(szInputDest, szDest, _countof(szDest));
1547
1548 // If the source or dest is a directory then add *.* to the end
1549 if (Util_IsDir(szSource))
1550 _tcscat(szSource, _T("\\*.*"));
1551 if (Util_IsDir(szDest))
1552 _tcscat(szDest, _T("\\*.*"));
1553
1554 WIN32_FIND_DATA findData;
1555 HANDLE hSearch = FindFirstFile(szSource, &findData);
1556 if (hSearch == INVALID_HANDLE_VALUE)
1557 {
1558 aLastError = GetLastError(); // Set even in this case since FindFirstFile can fail due to actual errors, such as an invalid path.
1559 return StrChrAny(const_cast<LPTSTR>(szInputSource), _T("?*")) ? 0 : 1; // Indicate failure only if there were no wildcards.
1560 }
1561 aLastError = 0; // Set default. Overridden only when a failure occurs.
1562
1563 // Otherwise, loop through all the matching files.
1564
1565 // Locate the filename/pattern, which will be overwritten on each iteration.
1566 LPTSTR source_append_pos = _tcsrchr(szSource, '\\') + 1;
1567 LPTSTR dest_append_pos = _tcsrchr(szDest, '\\') + 1;
1568 size_t space_remaining = _countof(szSource) - (source_append_pos - szSource) - 1;
1569
1570 // Copy destination filename or pattern, since it will be overwritten.
1571 tcslcpy(szDestPattern, dest_append_pos, _countof(szDestPattern));
1572
1573 int failure_count = 0;
1574 LONG_OPERATION_INIT
1575
1576 do
1577 {
1578 // Since other script threads can interrupt during LONG_OPERATION_UPDATE, it's important that
1579 // this function and those that call it not refer to sArgDeref[] and sArgVar[] anytime after an
1580 // interruption becomes possible. This is because an interrupting thread usually changes the
1581 // values to something inappropriate for this thread.
1582 LONG_OPERATION_UPDATE
1583
1584 // Make sure the returned handle is a file and not a directory before we
1585 // try and do copy type things on it!
1586 if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // dwFileAttributes should never be invalid (0xFFFFFFFF) in this case.
1587 continue;
1588
1589 if (_tcslen(findData.cFileName) > space_remaining) // v1.0.45.03: Basic check in case of files whose full spec is over 260 characters long.
1590 {
1591 aLastError = ERROR_BUFFER_OVERFLOW; // MSDN: "The file name is too long."
1592 ++failure_count;
1593 continue;
1594 }

Callers

nothing calls this directly

Calls 1

StrChrAnyFunction · 0.85

Tested by

no test coverage detected