2

I'm performing an xcopy backup of a disk on Windows using the following command line:

xcopy "d:\" "r:\" /v /h /k /e /b /d

I know that the verify switch doesn't do much but a file size comparison is better than nothing for the initial copy.

The problem I'm having is that xcopy is throwing a file verification error and I don't know why. The file in question is a symbolic link and the file it points to already exists.

I have Cygwin present and I ran both a diff, diff --no-dereference, and cmp on both the links as well as the actual file that it points to on both disks with no difference.

Both files are exactly 73 bytes.

I cannot reproduce this by creating a test folder with valid or invalid links while using xcopy with the same options to perform a copy on the same or different disks.

Why would xcopy fail in this way?

1
  • This article may be helpful with explanation that it is MS-DOS results the behavior of verification when copying. With Verify ON, MS-DOS will issue command to write with verify however in the new I/O model, there is no “write and verify” command but only write. As a result, XCOPY.EXE fakes it by simply checking whether the file sizes match. devblogs.microsoft.com/oldnewthing/20160121-00/?p=92911
    – Jenny
    Commented Jan 4, 2021 at 6:19

2 Answers 2

2

Xcopy doesn't record a file size when copying a symbolic link, but the verification pass is unaware of symlinks and tries to compare the size of the target file against the (unset) record anyway.

This can be observed with Sysinternals Process Monitor. It's most enlightening to copy only a single file at once and only begin capturing file IO events from the xcopy.exe process after Xcopy has asked you whether the destination is a directory but before you answer—that way, you skip all the process startup IO. When /B is passed, Xcopy sets the "Open Reparse Point" option in the CreateFile operation that opens the source file, telling Windows that if the file turns out to be a symlink (reparse point) it wants to open the symlink itself rather than the target file. Later, after creating the destination file, setting it as a symlink, and shuffling some file attributes around, if /V is passed, Xcopy issues another CreateFile to open the destination file again, but without the "Open Reparse Point" option. If that's a symlink, the result is REPARSE and Windows actually opens the target file for Xcopy in the immediately following CreateFile operation. Soon, Xcopy performs a QueryStandardInformationFile operation, getting the file size of what it thought was the destination. But looking back up the log, we remind ourselves that no QueryStandardInformationFile operation on/through the source file occurred previously to compare the file size with. In contrast, if you monitor an Xcopy of a normal file (even with /B), you will see a QueryStandardInformationFile operation on the source file very shortly after it's opened with CreateFile.

In further support of this hypothesis, Xcopy can copy and successfully verify a symbolic link to a zero-byte file. Apparently the file size record is zero-initialized, so even though it's not set when copying the symlink, when the verification pass blindly opens the target of the copied symlink to get its size, the answer of zero matches the default zero.

0

The /v option verifies each file as it's written, based on its size, to ensure they're identical.

Verification was built into the xcopy command beginning in Windows XP, but is supposed to do nothing in later versions of Windows. It is only included for compatibility with older MS-DOS files.

It's no wonder that this ancient verification code does not work well with a newer feature such as symbolic links.

I would recommend not using xcopy if you have symbolic links. Use a more modern application that can do verification, such as TeraCopy.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .