Menu

#256 Fix for inputfiles with paths of more than 260 chars.

Unstable
open
nobody
None
5
2022-02-09
2014-10-06
No

When reading an input file using a path with more than MAXPATH (260) characters, NSIS will stop processing because it cannot open the file. When using the Unicode version of Createfile it IS possible to open file with a path of max 32767 characters, when you prefix the path with \?\
Unfortunately this is not possible with relative paths. I have created a patch which will create an absolute path, while not using GetFullPathName (which is again limited to MAXPATH), prefix the generated name with \?\ and use this for Createfile.

1 Attachments

Discussion

  • Anders

    Anders - 2014-10-06

    Is this going to move the long path problem to the stub/run-time when someone uses "File /r"?

    MSDN says GetFullPathName supports \\?\ and it can probably be used for the "..\" part after the base/current directory has been resolved. This function does however suffer from problems when the path contains trailing dots and spaces as noted in the comments on MSDN.

    util.cpp already has get_full_path(), why not fix that instead?

    "#ifdef _WIN32" should be "#if defined(_WIN32) && defined(_UNICODE)"

    The absolute_path function is going to need more work:

    • Why is it just returning if the path shorter than 3 characters? "x" is a file/folder in the current directory and should be expanded since the function is named absolute_path.

    • "if (p[1] == _T(':'))" is too simple, "x:y" is alternate stream y in file/folder x in the current directory or file/folder y in the current directory for drive x: depending on how you look at it. (I don't remember if "a:b:c" is a legal path or not). PathGetDosDriveNumber in util.cpp can help a little bit here but that just means it starts with a drive letter, the path can still contain "..\" and so you cannot just return.

     
  • Arno de Vries

    Arno de Vries - 2014-10-07

    I have tested it, and so far the run-time installer installs the files in a path deeper than 260 characters. I have not checked the code though.

    Strange as it may sound GetFullPathName does not support \\?\ when you have a relative path. I have tried it with a simple test program. It makes GetFullPathName rather useless in these circumstances.

    I have renamed the absolute_path function to better describe what is does. Its primary function is to create a pathname CreateFile can handle.

    The get_full_path from util.cpp function is used in more places. Not all file functions support the \\?\ syntax. It would be risky to change it.

    Another solution would be to make a CreateFileEx function which resembles CreateFile which takes a tstring as first parameter which will handle the long pathname problem and call it instead of CreateFile throughout the code.

     
  • Arno de Vries

    Arno de Vries - 2015-04-01

    Any news on this? We are now using a patched version of NSIS because we install nodejs modules which creates very deep paths because of their dependencies. We prefer to run an original version.

     
    • JJ Lee

      JJ Lee - 2021-05-19

      I have also met same issue because of including nodejs modules, is there nay news on this?

       
  • Frank Palm

    Frank Palm - 2022-02-09

    Arno, I tried to build NSIS with your patch but I was not successful there.
    Not sure what I did wrong...
    In my case the NSIS should use the "File /r "${BUNDLEDJRE}*" " command with BUNDLEDJRE more than 260 chars . Is there a downloadable installation package available or could you provide yours somehow.
    Thanks in advance

     

Log in to post a comment.