Skip to content

Commit 82ff97c

Browse files
committed
Handling of symlinks
1 parent 6e1321e commit 82ff97c

58 files changed

Lines changed: 197 additions & 1 deletion

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ParseInput.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public class ParseInput
1414
/// </summary>
1515
private string _rawFilePath;
1616

17+
private string _userProvidedFilePath;
18+
1719
private int _errors;
1820

1921
private int _warnings;
@@ -29,12 +31,17 @@ public string RawFilePath
2931
set
3032
{
3133
_rawFilePath = value;
34+
_userProvidedFilePath = value;
3235
if (value != null)
3336
{
3437
RawFileNameWithoutExtension = Path.GetFileNameWithoutExtension(value);
3538
}
3639
}
3740
}
41+
public string UserProvidedPath
42+
{
43+
get => _userProvidedFilePath;
44+
}
3845

3946
public int Errors
4047
{
@@ -155,5 +162,15 @@ public void NewWarn()
155162
{
156163
_warnings++;
157164
}
165+
166+
public void UpdateRealPath(string path)
167+
{
168+
if (path != null)
169+
{
170+
_userProvidedFilePath = _rawFilePath;
171+
_rawFilePath = path;
172+
173+
}
174+
}
158175
}
159176
}

RawFileParser.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
using System;
22
using System.IO;
33
using System.Linq;
4+
using System.Runtime.InteropServices;
45
using ThermoFisher.CommonCore.Data;
56
using ThermoFisher.CommonCore.Data.Business;
67
using ThermoFisher.CommonCore.Data.Interfaces;
78
using ThermoRawFileParser.Writer;
9+
using ThermoRawFileParser.Util;
810

911
namespace ThermoRawFileParser
1012
{
@@ -93,6 +95,26 @@ private static void ProcessFile(ParseInput parseInput)
9395
{
9496
// Create the IRawDataPlus object for accessing the RAW file
9597
IRawDataPlus rawFile;
98+
99+
//checking for symlinks
100+
var fileInfo = new FileInfo(parseInput.RawFilePath);
101+
102+
if (fileInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) //detected path is a symlink
103+
{
104+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
105+
{
106+
var realPath = NativeMethods.GetFinalPathName(parseInput.RawFilePath);
107+
Log.DebugFormat("Detected reparse point, real path: {0}", realPath);
108+
parseInput.UpdateRealPath(realPath);
109+
}
110+
else //Mono should handle all non-windows platforms
111+
{
112+
var realPath = Path.Combine(Path.GetDirectoryName(parseInput.RawFilePath), Mono.Unix.UnixPath.ReadLink(parseInput.RawFilePath));
113+
Log.DebugFormat("Detected reparse point, real path: {0}", realPath);
114+
parseInput.UpdateRealPath(realPath);
115+
}
116+
}
117+
96118
using (rawFile = RawFileReaderFactory.ReadFile(parseInput.RawFilePath))
97119
{
98120
if (!rawFile.IsOpen)
@@ -155,7 +177,7 @@ private static void ProcessFile(ParseInput parseInput)
155177
}
156178
}
157179

158-
Log.Info("Finished parsing " + parseInput.RawFilePath);
180+
Log.Info("Finished parsing " + parseInput.UserProvidedPath);
159181
}
160182
}
161183
}

ThermoRawFileParser.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@
9696
<HintPath>packages\Mono.Options.6.6.0.161\lib\net40\Mono.Options.dll</HintPath>
9797
<Private>True</Private>
9898
</Reference>
99+
<Reference Include="Mono.Unix, Version=7.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
100+
<HintPath>packages\Mono.Unix.7.1.0-final.1.21458.1\lib\net45\Mono.Unix.dll</HintPath>
101+
</Reference>
99102
<Reference Include="mscorlib" />
100103
<Reference Include="Namotion.Reflection, Version=1.0.18.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102">
101104
<HintPath>packages\Namotion.Reflection.1.0.18\lib\net45\Namotion.Reflection.dll</HintPath>
@@ -198,6 +201,7 @@
198201
<Compile Include="RawFileParser.cs" />
199202
<Compile Include="Util\LimitedSizeDictionary.cs" />
200203
<Compile Include="Util\MZArray.cs" />
204+
<Compile Include="Util\NativeMethods.cs" />
201205
<Compile Include="Util\Peptide.cs" />
202206
<Compile Include="Writer\PrecursorInfo.cs" />
203207
<Compile Include="Writer\ScanTrailer.cs" />
@@ -248,7 +252,9 @@
248252
</PropertyGroup>
249253
<Error Condition="!Exists('packages\NUnit.3.13.1\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\NUnit.3.13.1\build\NUnit.props'))" />
250254
<Error Condition="!Exists('packages\NUnit3TestAdapter.4.1.0\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\NUnit3TestAdapter.4.1.0\build\net35\NUnit3TestAdapter.props'))" />
255+
<Error Condition="!Exists('packages\Mono.Unix.7.1.0-final.1.21458.1\build\Mono.Unix.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Mono.Unix.7.1.0-final.1.21458.1\build\Mono.Unix.targets'))" />
251256
</Target>
257+
<Import Project="packages\Mono.Unix.7.1.0-final.1.21458.1\build\Mono.Unix.targets" Condition="Exists('packages\Mono.Unix.7.1.0-final.1.21458.1\build\Mono.Unix.targets')" />
252258
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
253259
Other similar extension points exist, see Microsoft.Common.targets.
254260
<Target Name="BeforeBuild">

Util/NativeMethods.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.IO;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
7+
namespace ThermoRawFileParser.Util
8+
{
9+
/// <summary>
10+
/// Uses Windows API to resolve reparse point target
11+
///
12+
/// Kudos to user Knagis from StackOverflow
13+
/// https://stackoverflow.com/questions/2302416/how-to-obtain-the-target-of-a-symbolic-link-or-reparse-point-using-net
14+
/// </summary>
15+
public static class NativeMethods
16+
{
17+
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
18+
19+
private const uint FILE_READ_EA = 0x0008;
20+
private const uint FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;
21+
22+
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
23+
static extern uint GetFinalPathNameByHandle(IntPtr hFile, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath, uint cchFilePath, uint dwFlags);
24+
25+
[DllImport("kernel32.dll", SetLastError = true)]
26+
[return: MarshalAs(UnmanagedType.Bool)]
27+
static extern bool CloseHandle(IntPtr hObject);
28+
29+
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
30+
public static extern IntPtr CreateFile(
31+
[MarshalAs(UnmanagedType.LPTStr)] string filename,
32+
[MarshalAs(UnmanagedType.U4)] uint access,
33+
[MarshalAs(UnmanagedType.U4)] FileShare share,
34+
IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
35+
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
36+
[MarshalAs(UnmanagedType.U4)] uint flagsAndAttributes,
37+
IntPtr templateFile);
38+
39+
public static string GetFinalPathName(string path)
40+
{
41+
var h = CreateFile(path,
42+
FILE_READ_EA,
43+
FileShare.ReadWrite | FileShare.Delete,
44+
IntPtr.Zero,
45+
FileMode.Open,
46+
FILE_FLAG_BACKUP_SEMANTICS,
47+
IntPtr.Zero);
48+
if (h == INVALID_HANDLE_VALUE)
49+
throw new Win32Exception();
50+
51+
try
52+
{
53+
var sb = new StringBuilder(1024);
54+
var res = GetFinalPathNameByHandle(h, sb, 1024, 0);
55+
if (res == 0)
56+
throw new Win32Exception();
57+
58+
return sb.ToString();
59+
}
60+
finally
61+
{
62+
CloseHandle(h);
63+
}
64+
}
65+
}
66+
}

packages.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<package id="log4net" version="2.0.12" targetFramework="net472" />
99
<package id="MathNet.Numerics" version="4.15.0" targetFramework="net472" />
1010
<package id="Mono.Options" version="6.6.0.161" targetFramework="net472" />
11+
<package id="Mono.Unix" version="7.1.0-final.1.21458.1" targetFramework="net472" />
1112
<package id="Namotion.Reflection" version="1.0.18" targetFramework="net472" />
1213
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
1314
<package id="NJsonSchema" version="10.4.0" targetFramework="net472" />
18.3 KB
Binary file not shown.
6.84 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)