/// <inheritdoc /> public Task CreateSymbolicLink(string targetPath, string linkPath, CancellationToken cancellationToken) => Task.Factory.StartNew(() => { if (targetPath == null) { throw new ArgumentNullException(nameof(targetPath)); } if (linkPath == null) { throw new ArgumentNullException(nameof(linkPath)); } //check if its not a file var flags = File.Exists(targetPath) ? NativeMethods.CreateSymbolicLinkFlags.None : NativeMethods.CreateSymbolicLinkFlags.Directory; flags |= NativeMethods.CreateSymbolicLinkFlags.AllowUnprivilegedCreate; cancellationToken.ThrowIfCancellationRequested(); if (!NativeMethods.CreateSymbolicLink(linkPath, targetPath, flags)) { if (Win32Exception.GetLastWin32Error() == Win32Error.ERROR_INVALID_PARAMETER) //SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE isn't supported { flags &= ~NativeMethods.CreateSymbolicLinkFlags.AllowUnprivilegedCreate; if (NativeMethods.CreateSymbolicLink(linkPath, targetPath, flags)) { return; } } throw new Win32Exception(); } }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
protected AbstractJournalScanner(string scanFolder, IFileRecordListener recordListener, IFileRecordFilter recordFilter = null) { this.scanFolder = Path.GetFullPath(scanFolder); this.recordFilter = recordFilter; this.recordListener = recordListener; var driveLetterRegex = new Regex(DriveLetterRegexString); var driveLetterMatch = driveLetterRegex.Match(this.scanFolder); if (driveLetterMatch.Success) { this.driveLetter = driveLetterMatch.Groups.Values.ElementAt(1).Value.ToUpper()[0]; //extract first letter in upper case } else { throw new ArgumentException($"invalid scanFolder path: {this.scanFolder}"); } var drivePath = $"\\\\.\\{driveLetter}:"; this.volumeHandle = Kernel32.CreateFile(drivePath, FileAccess.Read, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); if (volumeHandle.IsInvalid) { var lastError = Win32Exception.GetLastWin32Error(); var hintMessage = lastError == Win32Error.ERROR_ACCESS_DENIED ? ". Try Run As Administrator" : string.Empty; throw new Win32Exception(lastError, $"{new Win32Exception(lastError).Message} for path: \"{drivePath}\" {hintMessage}"); } this.usnIo = new UsnDeviceWrapper(volumeHandle, true); }