QDir Won't Show Symbolically Linked Shadow Copy Directory Contents Using EntryList()

85 views Asked by At

Hi I have a very unique situation hopefully the solution is simple...

I am writing a backup program that uses Volume Shadow Copy Service to freeze the state of files to be backed up. I cannot traverse the shadow copy directly using QDir set to the copy ie \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy37 since QDir doesn't like that for some reason (perhaps the same reason is giving me this headache?). Instead I programmatically traverse a symbolic link to the volume shadow copy of the drive to be backed up. If I try to back up a whole drive and traverse the root of the folder symbolically linked to the shadow copy, QDir gives empty entryList() QStringLists. If I back up a folder located on the drive and traverse only that folder in the symbolically linked shadow copy folder everything works fine.

So...If I try to back up O:\ entryList() is empty. If I try to backup O:\backupfolder entryList() lists the contents and everybody is happy.

I have verified the shadow copy is created successfully using Nirsoft's ShadowCopyView. Also I added source.append("awef"); before the scanDir call when trying to back up the whole drive and the subdirectory awef is backed up successfully so we know the shadow copy and symbolic link are successfully created.

Here is the code:

CreateSymbolicLink(vssDir.path().toStdWString().c_str(), snapVol.toStdWString().c_str(), SYMBOLIC_LINK_FLAG_DIRECTORY)
//vssDir is a folder on the root of the C drive to be traversed programmatically
//snapVol is the shadow copy ie \\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy37
HANDLE hFile = CreateFile(vssDir.absolutePath().toStdWString().c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0);
//locks the link IIRC

scanDir(source,target); //called from arbitrary location in program

void Worker::scanDir(QDir source, QDir target, BackupJob &job)
{
    source.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
    target.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
    getFileSizes(source, target, job);

    QStringList dirList = source.entryList(); //empty for root of symbolically linked folder
    for (int count = 0; count < dirList.count() && cancel == false; ++count)
    {
        QString newPath = QString("%1/%2").arg(source.absolutePath()).arg(dirList.at(count));
        QString newPath2 = QString("%1/%2").arg(target.absolutePath()).arg(dirList.at(count));
        scanDir(QDir(newPath),QDir(newPath2),job);
    }
}

void Worker::getFileSizes(QDir source, QDir target, BackupJob &job)
{
    source.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks);
    target.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks);

    QStringList sourceFileList = source.entryList(); //empty for root of symbolically linked folder
    QStringList targetFileList = target.entryList(); //empty for root of symbolically linked folder
    for (int aCount = 0; aCount < sourceFileList.count(); aCount++)
    {
        //code to add files to be backed up...
    }
}
1

There are 1 answers

0
riverofwind On

I found the problem, something very silly... I needed to add a backslash to the end of the snapVol QString to make the shadow copy path \?\GLOBALROOT\Device\HarddiskVolumeShadowCopy37\ Here is the page that led me to this info...