0

I am trying to copy the running executable to a specific folder. I would like to copy it with the same security resource properties. However, I am not sure if I am "double escaping" the file names correctly as described in this doc

My code is as follows:

#include <shlobj.h>
#include <shellapi.h>

#define LIVE_FOLDER "Cloud9"

bool CopySelf()
{
  TCHAR buf[MAX_PATH];
  TCHAR path[MAX_PATH];
  TCHAR ogpath[MAX_PATH];
  // The function gets the current module for you.
  SHGetFolderPath(NULL,CSIDL_APPDATA, NULL, 0, path);


  GetCurrentDirectory(MAX_PATH, ogpath);
  std::string dir =  std::string(path)+"\\"+LIVE_FOLDER ;
  std::string dirog = std::string(ogpath);

  if(dir==dirog)
  {
    return false;
  }
  if (CreateDirectory(dir.c_str(), NULL) ||
        ERROR_ALREADY_EXISTS == GetLastError())
  {
        std::string newprocessName = dir + "\\test.exe\0\0";

        GetModuleFileName(0, buf, MAX_PATH);
        std::string oldprocessName = std::string(buf)+"\0\0";

        SHFILEOPSTRUCT a=
        {
            NULL,
            FO_COPY,
            oldprocessName.c_str(),
            newprocessName.c_str(),
            FOF_SILENT|FOF_NOERRORUI|FOF_NOCONFIRMATION,
            FALSE,
            NULL,
            NULL,
        };



        SHFileOperation(&a);

        return true;
  }
  else
  {
      throw ERROR;
   // return false;
  }
  return false;
}

When I run this code, instead of an executable at the destination, there is a folder named "test.exe".Image is here - not enough points to embed it.

If I use CopyFile or CopyFileEx with the following code, the file gets copied correctly.

std::string newprocessName = dir + "\\test.exe";
GetModuleFileName(0, buf, MAX_PATH);
CopyFile(buf, newprocessName.c_str(), TRUE);

The problem with this is that the security attributes are not copied. At this point, I am not sure whether I am failing the "double escaping"/"double null terminating" or I am doing something else wrong. Why is it creating a folder named "test.exe" instead of copying the file?

I am using Code::Blocks with GCC compiler and I have tried this on Windows 8.1 Professional and on Windows 7 Professional.

  • I suspect the problem is that the original file is not named test.exe so it assumes you want it to create the directory. Look inside the test.exe directory that was created, do you see a copy of the original .exe file with its original name? Try using the FOF_MULTIDESTFILES option. – Hans Passant Oct 15 '15 at 12:11
  • The test.exe directory is empty. I tried using FOF_MULTIDESTFILES and it wasn't creating the test.exe directory any more. I also changed the destination file name to match the source file name and I got the same result. I am not completely sure how FOF_MULTIDESTFILES works though, – Tsuro Na Gudo Oct 15 '15 at 12:41
  • Thanks Hans Passant, your comment steered me in the right direction – Tsuro Na Gudo Oct 15 '15 at 13:20

1 Answers1

1

Finally figured it out. The problem was indeed with the double null termination

I appended a null terminator using append as shown below and using a single null terminator when declaring the strings:

std::string newprocessName = dir + "\\test.exe\0";
GetModuleFileName(0, buf, MAX_PATH);
std::string oldprocessName = std::string(buf)+"\0";
newprocessName.append(1, '\0');
oldprocessName.append(1, '\0');

Not sure how this is different, but it's now working. The accepted answer at this SO page was just what i needed.

Community
  • 1
  • 1