0

i write this code in C++ Builder to copy some folders from a network folder mounted on x: (eg x:\games\foldername) to a local path: d:\program files. I use shfileopstruct as follow.

The source path (s variable) is taken from database using FieldByName("path") and then it is given a prefix ("x:\games\" and a "\0" as MSDN suggests . SHFILEOPERATION works fine as it is.. but the unusual thing is than when i remove the code about ShowMessage(path) (which i have for validation), SHFILEOPERATION do fail.

Any suggestions about this? Am I missing something? I would appreciate your help as i am not experienced. Thanks in advance.

UnicodeString s="";   //source path   
UnicodeString d="";  //destination        
UnicodeString path="";   //path from database field

if(ClientDataSet1->Active==false)
    ClientDataSet1->Open();

path=ClientDataSet1->FieldByName("path")->Text;   //get [path] value from db
ShowMessage(path);            /// !!!! <<<-------- ???  SHOWMESSAGE ???

s="x:\\games\\" + path + "\0" ;
d="d:\\program files\0"  ;

// Create the SHFILEOPSTRUCT and zero it.
SHFILEOPSTRUCT fos;

memset(&fos, 0, sizeof(fos));
fos.hwnd = Handle;
fos.wFunc = FO_COPY;
fos.pFrom = s.c_str();
fos.pTo = d.c_str();
fos.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;

int n=SHFileOperation(&fos);
    if(n)
        ShowMessage(n);
    else
        ShowMessage("OK");
apo
  • 69
  • 2
  • 9

1 Answers1

0

When building up your s variable, you are appending "\0" (double quotes), which gets interpreted as a 0-length string concatenation and thus a no-op, so s is effectively NOT double null terminated correctly. In other words, this code:

s="x:\\games\\" + path + "\0" ; 

Is effectively the same as this code, from the + operator's perspective:

s="x:\\games\\" + path + "" ; 

In order to actually append a null character, use '\0' (single quotes) instead (yes, a single Char can be appended to a String):

s="x:\\games\\" + path + '\0' ; 

Your d variable is double null terminated correctly because the \0 is included in a larger string literal so it is not lost.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • `UnicodeString::operator+` take UnicodeString as parameter so string `"\0"` is first converd by constructor `UnicodeString(const wchar_t* src, int len = -1)`. This constructor copies the string until finds `\0`, so result is null string. You can use this constructor and specify length: `s="x:\\games\\" + path + UnicodeString("\0", 1);`. As Remy Lebeau wrote, you can also use `'\0'` which is equivalent to `s="x:\\games\\" + path + UnicodeString('\0');`. I suggest that if you are going to use `'\0'`, add a comment to this line :) – marbel82 Jun 10 '13 at 09:11