none
creating double null ended CString

    Question



  • Hi All,
    How so I convert a CString s to double null terminated string[since this is needed by SHFILEOPSTRUCT].
    I have been trying
    ::ZeroMemory(&s1,MAX_PATH);
    memcpy(&s1,&ToDir,ToDir.GetLength());
    But then I am getting buffer overflow.

    How can I correct this?

    Cheers,
    Sam
    Monday, March 17, 2008 4:46 AM

Answers

  •  

    Glad you found something that does what you want.

     

    As a postscript, any examples I post have been tested by me first

    and demonstrated to be working to my satisfaction. The sample

    code I posted in this thread correctly performed a single file copy

    using SHFileOperation. If it failed for you there must be factors

    in your code or requirements which are not evident from your posts.

     

    - Wayne

     

     

    Monday, March 17, 2008 11:19 AM

All replies

  • I tried
    s+=L'\0';

    I still get the return value of SHFILEOPSTRUCT as 1026
    Monday, March 17, 2008 5:04 AM
  • It is possible to use CString for that but it is not easy in the sense that you need to understand how C-style strings work. I suggest using a C-style string, not CString.

    Monday, March 17, 2008 5:47 AM
  • Quote>How so I convert a CString s to double null terminated string
    Quote>[since this is needed by SHFILEOPSTRUCT].

     

    Don't try to pass a CString directly to SHFileOperation.
    Convert it to a double-nul terminated C-style string and pass it instead.

     

    Simplified example:

    Code Snippet

     

    CString s3,s4;
    s3="C:\\to";
    s4="C:\\from\\testfile.txt";

    char dest[MAX_PATH] = {0};
    char src[MAX_PATH] = {0};

    strcpy(dest, s3);
    strcpy(src, s4);

    SHFILEOPSTRUCT s = { 0 };
    s.wFunc = FO_COPY;
    s.pTo =dest;
    s.pFrom =src;
    int i =SHFileOperation( &s );

     

     

     

    Clearly, this could be made more robust by checking lengths, etc.

     

    - Wayne

     

    Monday, March 17, 2008 8:15 AM
  •  WayneAKing wrote:

    Convert it to a double-nul terminated C-style string and pass it instead.

     

    Simplified example:

    Code Snippet

     

    CString s3,s4;
    s3="C:\\to";
    s4="C:\\from\\testfile.txt";

    char dest[MAX_PATH] = {0};
    char src[MAX_PATH] = {0};

    strcpy(dest, s3);
    strcpy(src, s4);

    SHFILEOPSTRUCT s = { 0 };
    s.wFunc = FO_COPY;
    s.pTo =dest;
    s.pFrom =src;
    int i =SHFileOperation( &s );

     

     

     

    I don't see double null-termination. Also, the original question does not specify whether there is a single destination or multiple destinations. I think the double null-termination is needed only when there are multiple destinations, so I assume the requirement is for creation of the buffer with multiple filenames, each one null-terminated and the entire list ending with an additional null. One thing that might be overlooked is that with multiple destinations, MAX_PATH might be too short.

     

    If the multiple destination stuff is not clear, have a look at the SHFILEOPSTRUCT structure.

    Monday, March 17, 2008 8:40 AM
  • Quote>I don't see double null-termination

     

    Look again. The buffers src and dest are preset to all nul values.
    Whatever the length of the string copied, the remainder of the
    buffer will be nuls.

     

    Quote>I think the double null-termination is needed only when
    Quote>there are multiple destinations,

     

    Wrong. The second nul is needed to terminate the list(s) regardless
    of how many strings are in the list(s). That's how it knows that the
    list has ended. (Effectively, a zero-length string.)

     

    Quote>One thing that might be overlooked is that with multiple
    Quote>destinations, MAX_PATH might be too short.

     

    Right. As with all simplified examples, this one needs to be made
    more robust in a serious application as I noted in my final comment.

     

    - Wayne

     

    Monday, March 17, 2008 8:59 AM
  • As a footnote and addendum to my example, a buffer of exactly

    MAX_PATH size will be inadequate if a file name with full path

    info prepended is passed which is exactly MAX_PATH long.

    The buffers should be made slightly larger to allow for appending

    two nul characters.

     

    Code Snippet

     

    char dest[MAX_PATH+2] = {0};
    char src[MAX_PATH+2] = {0};

     

     

     

    As already noted, this example presupposes that a single file is

    being worked with.

     

    - Wayne

     

    Monday, March 17, 2008 9:33 AM

  • Thanks for your help guys.
    Even with above suggestions it was not working.Finally I have decided to use MoveFileEx();

    Monday, March 17, 2008 10:18 AM
  •  

    Glad you found something that does what you want.

     

    As a postscript, any examples I post have been tested by me first

    and demonstrated to be working to my satisfaction. The sample

    code I posted in this thread correctly performed a single file copy

    using SHFileOperation. If it failed for you there must be factors

    in your code or requirements which are not evident from your posts.

     

    - Wayne

     

     

    Monday, March 17, 2008 11:19 AM
  • Hello Sam,

     

    as for your original question:  Here is a simple way to concatenate CStrings into a single string list which is separated by zeroes and terminated by double zeroes.

     

    Code Snippet

    CString strString[COUNT];  // filled with some strings

     

     

    CString strStringList;

    for (int i=0 ; i<COUNT ; ++i)

    {

    strStringList += strString[i];

    strStringList += (TCHAR)'\0'; // next string please

    }

     

     

     

    You can find a 'real life' example of this technique in MFC: Just search for the comment text "next string please" in the file DOCMGR.CPP. You will end up in the function _AfxAppendFilterSuffix() used by CDocManager.

     

    Regards,

     

    Matthias

    Thursday, April 24, 2008 9:04 AM