RAR 5.0 and symbolic links
Moderators: Hacker, petermad, Stefan2, white
RAR 5.0 and symbolic links
WinRAR 5.x can add symbolic links to archives using the -ol switch. It will also extract the symbolic link, at least on NTFS.
Total Commander 8.50 with "Use internal un-RAR if possible" will not recreate the symlinks from the RAR, but creates an empty directory instead.
Any idea if this will be addressed, or is there some INI setting? I wouldn't mind unchecking "Use internal un-RAR", but then I lose the ability to selectively extract subfolders from RARs, with the error "Unfortunately, unpacking directories containing other dirs..."
Total Commander 8.50 with "Use internal un-RAR if possible" will not recreate the symlinks from the RAR, but creates an empty directory instead.
Any idea if this will be addressed, or is there some INI setting? I wouldn't mind unchecking "Use internal un-RAR", but then I lose the ability to selectively extract subfolders from RARs, with the error "Unfortunately, unpacking directories containing other dirs..."
Last edited by quantum on 2014-04-04, 17:51 UTC, edited 1 time in total.
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
I tried to analyze this, but I couldn't even get it to work with RAR itself. Can you help? I tried (using WinRAR 5.01, registered) to create the archive in two ways:
1. Select the links, press Alt+F5, added -ol behind archive name
2. With command line:
C:\utils\WinRAR5\Rar.exe a -ol c:\test\testlinks2.rar C:\testlinks\*.*
Unfortunately neither archive seems to store the target of the links (when checked with F3), and neither WinRAR nor RAR seems to be able to unpack them. What am I doing wrong?
1. Select the links, press Alt+F5, added -ol behind archive name
2. With command line:
C:\utils\WinRAR5\Rar.exe a -ol c:\test\testlinks2.rar C:\testlinks\*.*
Unfortunately neither archive seems to store the target of the links (when checked with F3), and neither WinRAR nor RAR seems to be able to unpack them. What am I doing wrong?
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
Glad to help.
NOTE: I just realized, you must select RAR5 format (it will default to RAR). There is a setting in the gui, or add -ma5 to the command line.
I created a test link via elevated cmd prompt and:
mklink /d "SourceDir" "SymlinkDir"
Then added to RAR using either WinRAR gui, or RAR with -ol and -ma5 switches. With the gui, you need to select "store symbolic links as links", and select RAR5 format. The easiest way to check the symlink is in the RAR is check with the gui as follows:
Image: http://i.imgur.com/I2Gn1OA.png
Note that I also used WinRAR 5.01, but version 5.00 is listed as supporting symlinks.
To extract, you need to run WinRAR or RAR elevated, or you will get an error.
I'll attach a sample RAR if that will help.
NOTE: I just realized, you must select RAR5 format (it will default to RAR). There is a setting in the gui, or add -ma5 to the command line.
I created a test link via elevated cmd prompt and:
mklink /d "SourceDir" "SymlinkDir"
Then added to RAR using either WinRAR gui, or RAR with -ol and -ma5 switches. With the gui, you need to select "store symbolic links as links", and select RAR5 format. The easiest way to check the symlink is in the RAR is check with the gui as follows:
Image: http://i.imgur.com/I2Gn1OA.png
Note that I also used WinRAR 5.01, but version 5.00 is listed as supporting symlinks.
To extract, you need to run WinRAR or RAR elevated, or you will get an error.
I'll attach a sample RAR if that will help.
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Thanks, that worked! I will investigate further whether I can support it or not.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
I have checked this now: TC does not call the unrar.dll for unpacking folders, it just creates them by itself. But even when it calls the unrar.dll for folders, and runs as admin, the links are not restored. The RARHeaderDataEx structure doesn't contain any indication either that these are links and not normal folders. Therefore I don't currently see any way to extract them.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
uhm, how about contacting WinRar's devs?ghisler(Author) wrote:I have checked this now: TC does not call the unrar.dll for unpacking folders, it just creates them by itself. But even when it calls the unrar.dll for folders, and runs as admin, the links are not restored. The RARHeaderDataEx structure doesn't contain any indication either that these are links and not normal folders. Therefore I don't currently see any way to extract them.
Actually UnRAR sources are opened... Here is some parts of CmdExtract::ExtractCurrentFile function:
However it is interesting how to detect symlinks using UnRAR.dll interface.
As I see, hardlink may only be detected by zero packed size and CRC (while unpacked size is nonzero).
For dirs, there is an additional RARHeaderDataEx::FileAttr bit 0x400 which is set only for reparse points and not for regular directory. It seems that this field simply keeps Windows file attributes: iit is tested for different FILE_ATTRIBUTE_* flags in code, and 0x400 bit is exactly FILE_ATTRIBUTE_REPARSE_POINT.
In my test UnRAR.dll was able to restore junctions and symlinks correctly (symlinks of course only when elevated), however it is strange that it have restored reparse points with forward slashes instead of back ones so I can't enter them. UnRAR.exe have done the same stupid thing. After reading archive I noticed that link path is stored with forward slashes (tested with links to C:\Users) so most probably it is a RAR.exe bug.
Code: Select all
bool LinkEntry=Arc.FileHead.RedirType!=FSREDIR_NONE;
FILE_SYSTEM_REDIRECT Type=Arc.FileHead.RedirType;
if (Type==FSREDIR_UNIXSYMLINK || Type==FSREDIR_WINSYMLINK || Type==FSREDIR_JUNCTION) ...
As I see, hardlink may only be detected by zero packed size and CRC (while unpacked size is nonzero).
For dirs, there is an additional RARHeaderDataEx::FileAttr bit 0x400 which is set only for reparse points and not for regular directory. It seems that this field simply keeps Windows file attributes: iit is tested for different FILE_ATTRIBUTE_* flags in code, and 0x400 bit is exactly FILE_ATTRIBUTE_REPARSE_POINT.
In my test UnRAR.dll was able to restore junctions and symlinks correctly (symlinks of course only when elevated), however it is strange that it have restored reparse points with forward slashes instead of back ones so I can't enter them. UnRAR.exe have done the same stupid thing. After reading archive I noticed that link path is stored with forward slashes (tested with links to C:\Users) so most probably it is a RAR.exe bug.
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
2MVV
Interesting that it worked for you, it didn't restore them here - I just got normal folders.
Btw, did you find a way to read the link targets somehow from the data in RARHeaderDataEx?
Interesting that it worked for you, it didn't restore them here - I just got normal folders.
Btw, did you find a way to read the link targets somehow from the data in RARHeaderDataEx?
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
It seems that this information is only available internally, archive handle is a pointer to DataSet, and only DataSet::Arc::FileHead contains reparse information.
I don't understand why UnRAR doesn't restore reparse points for you, my simplest code does it well:
Test archive:
Actually this code doesn't unpack hardlink, but it recreates junction and symlink correctly.
I don't understand why UnRAR doesn't restore reparse points for you, my simplest code does it well:
Code: Select all
RAROpenArchiveData road={0};
road.ArcName="..\\test_links.rar";
road.OpenMode=RAR_OM_EXTRACT;
HANDLE hrar=RAROpenArchive(&road);
int r=ERAR_SUCCESS;
RARHeaderDataEx rex;
while ((r=RARReadHeaderEx(hrar, &rex))==ERAR_SUCCESS) {
printf("Name: %s\nFlags: %08x\nFileAttr: %08x\n\n", rex.FileName, rex.Flags, rex.FileAttr);
RARProcessFile(hrar, RAR_EXTRACT, "dest", rex.FileName);
}
printf("Listing done: %d\n", r);
Code: Select all
MIME-Version: 1.0
Content-Type: application/octet-stream; name="test_links.rar"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test_links.rar"
UmFyIRoHAQAzkrXlCgEFBgAFAQGAgADkOC62MQIDC7YABLYAoFDKPIekgEAAFHRlc3RfZGlyL0xp
Y2Vuc2UudHh0CgMCFW5ePdJUzwEgICAgIEVORCBVU0VSIExJQ0VOU0UgQUdSRUVNRU5UDQoNCiAg
ICAgQmxhaC1ibGFoLWJsYWgdgxYRTQIDJAAENqBQAAAAAIBAABl0ZXN0X2Rpci9MaWNlbnNlX2Nv
cHkudHh0CgMCFW5ePdJUzwEYBQQAFHRlc3RfZGlyL0xpY2Vuc2UudHh0S2xk6CMCAwsABQCQUAAA
AACAAAAIdGVzdF9kaXIKAwIelgyyh1TPASrfcuo5AgMcAAUAkFgAAAAAgAAADXRlc3RfanVuY3Rp
b24KAwIRuqNchlTPARAFAwEMLz8/L0M6L1VzZXJz2EdpQDgCAxwABQCQWAAAAACAAAAMdGVzdF9z
eW1saW5rCgMCI8f0Y4ZUzwEQBQIBDC8/Py9DOi9Vc2Vycx13VlEDBQQA
2MVV
ghisler(Author)
Please look here WinRar's author Eugene Rochal comment (in Russian) for this subject. http://forum.ru-board.com/topic.cgi?forum=5&topic=32358&start=3120#16
ghisler(Author)
Please look here WinRar's author Eugene Rochal comment (in Russian) for this subject. http://forum.ru-board.com/topic.cgi?forum=5&topic=32358&start=3120#16
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
I don't know why unrar.dll doesn't create links here. It would be great if unrar.dll could somehow return the link target, then TC could handle it and create them with elevation if necessary without running the whole TC with admin rights.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com