0

I'm having some difficulties with the PathCombine function. It does not seem to work correctly in conjunction with SHFileOperation(). My code is as follows:

    //beginning of method
    TCHAR* root = new TCHAR[MAX_PATH];
    root = L"C:\\Users\\jhow\\Desktop\\\0";

    //later on in the method
    TCHAR* t1Dir = new TCHAR[MAX_PATH]; //root
    TCHAR* t2Dir = new TCHAR[MAX_PATH]; //temp
    PathCombine(t1Dir,root,L"Folder1\\%REPLACE_THIS%\\\0");
    PathCombine(t2Dir,root,L"Folder1\\temp\0");

    sf.pFrom = t1Dir;
    //sf.pFrom = L"C:\\Users\\jhow\\Desktop\\Folder1\\%REPLACE_THIS%";
    sf.pTo = temporaryDir;

    //Copy files
    int n = SHFileOperation(&sf);

When I have it like it is above, the method sees sf.pTo, but for some reason it does not see sf.pFrom (even after playing around with different combinations of the \ and \0 at the end of the path name). n becomes 2, which I think means file not found... But for example, when I comment out.

    sf.pFrom = t1Dir;

and replace it with:

    sf.pFrom = L"C:\\Users\\jhow\\Desktop\\Folder1\\%REPLACE_THIS%";

SHFileOperation() works... it returns zero and I can see that all the files are copied into the directory. I find this odd seeing as they appear to be the same exact string (even when I debug and hover over the variables)... Anyone happen to know why this is happening? Is there something wrong with my syntax or logic? Because I don't see it. I am using Visual Studio 2008. Thank you very much for your time.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
JHowzer
  • 3,684
  • 4
  • 30
  • 36
  • First thing that jumps out at me is why are you explicitly null-terminating your string literals? The `"..."` instructs the compiler to do that for you, so by adding the `\0` yourself you end up with a doubly-null-terminated string. – Cody Gray - on strike May 15 '12 at 00:17

1 Answers1

5

You are allocating a buffer on the heap for your root variable, but then immediately pointing that variable to a read-only string literal instead, leaking the allocated buffer.

More importantly, you are not taking into account that SHFileOperation() operates on double-null-terminated strings, but PathCombine() returns a single-null-terminated string instead. You are trying to include an extra null in your input to PathCombine(), but that will not work since PathCombine() take single-null-terminated strings as input, so it will never see your extra nulls. You ned to allocate enough space in your output buffers to hold the extra null terminators, and then make sure they are set to zeros before passing those buffers to SHFileOperation().

Try this:

LPTSTR root = TEXT("C:\\Users\\jhow\\Desktop\\"); 

TCHAR t1Dir[MAX_PATH+2] = {0};
TCHAR t2Dir[MAX_PATH+2] = {0};
PathCombine(t1Dir, root, TEXT("Folder1\\%REPLACE_THIS%\\")); 
PathCombine(t2Dir, root, TEXT("Folder1\\temp")); 

sf.pFrom = t1Dir; 
sf.pTo = t2Dir; 

int n = SHFileOperation(&sf); 
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you. This was very helpful. If you don't mind me asking, what exactly does `TCHAR t1Dir[MAX_PATH+2] = {0};` do? – JHowzer May 15 '12 at 13:25
  • 1
    It allocates an array of `MAX_PATH+2` number of `TCHAR` elements on the stack, and initializes the entire array to zeros, all in one statement. The `= {0}` systax is common shorthand for initializing an array at the same time it is declared. You could just as easily declare the array by itself and then use `memset()` or `ZeroMemory()` to zero out the array separately. – Remy Lebeau May 15 '12 at 16:49