2

I am trying to copy the contents of the A drive into folder C:\test\disk1. Folder disk1 already exists. The program compiles but when it runs I get error 87. I know error 87 has something to do with an invalid parameter but Im not sure where the problem lies. Has anyone any ideas?

#include <Windows.h>
#include <stdio.h>

int main(int argc, char ** argv)
{
    const wchar_t *const sourceFile = L"A:\\";
    const wchar_t *const outputFile = L"C:\\test\\disk1";

    SHFILEOPSTRUCTW fileOperation;
    memset(&fileOperation, 0, sizeof(SHFILEOPSTRUCTW));

    fileOperation.wFunc = FO_COPY;
    fileOperation.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR |
                               FOF_NOERRORUI | FOF_FILESONLY;
    fileOperation.pFrom = sourceFile;
    fileOperation.pTo = outputFile;

    int result = SHFileOperationW(&fileOperation);
    if (result != 0)
    {
        printf("SHFileOperation Failure: Error%u\n", result);
        return 1;
    }

    memset(&fileOperation, 0, sizeof(SHFILEOPSTRUCTW));

    printf("OK\n");
    return 0;
}
IInspectable
  • 46,945
  • 8
  • 85
  • 181
Robbie J
  • 79
  • 1
  • 9

1 Answers1

3

Note the documentation of SHFILEOPSTRUCT and in particular that of pFrom and pTo:

  PCZZTSTR     pFrom;
  PCZZTSTR     pTo;

What does PCZZTSTR mean?

pFrom
Type: PCZZTSTR
Note  This string must be double-null terminated.

So your fix is to supply an additional trailing zero.

const wchar_t *const sourceFile = L"A:\\\0";
const wchar_t *const outputFile = L"C:\\test\\disk1\0";

Note that Windows API functions accept / as a directory separator, so that can be written as the slightly easier to read:

const wchar_t *const sourceFile = L"A:/\0";
const wchar_t *const outputFile = L"C:/test/disk1\0";

(PCZZSTR is actually a pointer to a list of zero terminated strings which is terminated by an empty string.)

IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • 1
    The file I/O APIs sometimes translate forward slashes to backslahes, and sometimes they don't. The path separator on Windows is a backslash. Suggesting to use the 'wrong' separator to improve readability is questionable. If this is about readability, you can use `L"A:\\" L"\0"` and `L"C:\\test\\disk1" L"\0"` instead. – IInspectable Mar 02 '17 at 13:07
  • @RobbieJ : That's a separate question. Please ask it as such. (And note the tag that IInspectable added.) – Martin Bonner supports Monica Mar 02 '17 at 13:32