safer shortcut migration
This commit is contained in:
parent
2da4ef2a01
commit
7c9c0c999d
|
@ -12,8 +12,8 @@ namespace MediaBrowser.Api.Library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class LibraryHelpers
|
public static class LibraryHelpers
|
||||||
{
|
{
|
||||||
private const string ShortcutFileExtension = ".lnk";
|
private const string ShortcutFileExtension = ".mblink";
|
||||||
private const string ShortcutFileSearch = "*.lnk";
|
private const string ShortcutFileSearch = "*" + ShortcutFileExtension;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the virtual folder.
|
/// Adds the virtual folder.
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using MediaBrowser.Model.Logging;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using MediaBrowser.Model.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -130,16 +132,21 @@ namespace MediaBrowser.Controller.IO
|
||||||
throw new ArgumentNullException("filename");
|
throw new ArgumentNullException("filename");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new WindowsShortcut(filename).ResolvedPath;
|
if (string.Equals(Path.GetExtension(filename), ".mblink", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return File.ReadAllText(filename);
|
||||||
|
}
|
||||||
|
|
||||||
//var link = new ShellLink();
|
//return new WindowsShortcut(filename).ResolvedPath;
|
||||||
//((IPersistFile)link).Load(filename, NativeMethods.STGM_READ);
|
|
||||||
//// TODO: if I can get hold of the hwnd call resolve first. This handles moved and renamed files.
|
var link = new ShellLink();
|
||||||
//// ((IShellLinkW)link).Resolve(hwnd, 0)
|
((IPersistFile)link).Load(filename, NativeMethods.STGM_READ);
|
||||||
//var sb = new StringBuilder(NativeMethods.MAX_PATH);
|
// TODO: if I can get hold of the hwnd call resolve first. This handles moved and renamed files.
|
||||||
//WIN32_FIND_DATA data;
|
// ((IShellLinkW)link).Resolve(hwnd, 0)
|
||||||
//((IShellLinkW)link).GetPath(sb, sb.Capacity, out data, 0);
|
var sb = new StringBuilder(NativeMethods.MAX_PATH);
|
||||||
//return sb.ToString();
|
WIN32_FIND_DATA data;
|
||||||
|
((IShellLinkW)link).GetPath(sb, sb.Capacity, out data, 0);
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -160,13 +167,18 @@ namespace MediaBrowser.Controller.IO
|
||||||
throw new ArgumentNullException("target");
|
throw new ArgumentNullException("target");
|
||||||
}
|
}
|
||||||
|
|
||||||
var link = new ShellLink();
|
File.WriteAllText(shortcutPath, target);
|
||||||
|
|
||||||
((IShellLinkW)link).SetPath(target);
|
//var link = new ShellLink();
|
||||||
|
|
||||||
((IPersistFile)link).Save(shortcutPath, true);
|
//((IShellLinkW)link).SetPath(target);
|
||||||
|
|
||||||
|
//((IPersistFile)link).Save(shortcutPath, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, string> ShortcutExtensionsDictionary = new[] { ".mblink", ".lnk" }
|
||||||
|
.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the specified filename is shortcut.
|
/// Determines whether the specified filename is shortcut.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -180,7 +192,9 @@ namespace MediaBrowser.Controller.IO
|
||||||
throw new ArgumentNullException("filename");
|
throw new ArgumentNullException("filename");
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Equals(Path.GetExtension(filename), ".lnk", StringComparison.OrdinalIgnoreCase);
|
var extension = Path.GetExtension(filename);
|
||||||
|
|
||||||
|
return !string.IsNullOrEmpty(extension) && ShortcutExtensionsDictionary.ContainsKey(extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -258,7 +272,7 @@ namespace MediaBrowser.Controller.IO
|
||||||
|
|
||||||
public WindowsShortcut(string file)
|
public WindowsShortcut(string file)
|
||||||
{
|
{
|
||||||
ParseLink(File.ReadAllBytes(file));
|
ParseLink(File.ReadAllBytes(file), Encoding.UTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool isMagicPresent(byte[] link)
|
private static bool isMagicPresent(byte[] link)
|
||||||
|
@ -274,7 +288,7 @@ namespace MediaBrowser.Controller.IO
|
||||||
* Gobbles up link data by parsing it and storing info in member fields
|
* Gobbles up link data by parsing it and storing info in member fields
|
||||||
* @param link all the bytes from the .lnk file
|
* @param link all the bytes from the .lnk file
|
||||||
*/
|
*/
|
||||||
private void ParseLink(byte[] link)
|
private void ParseLink(byte[] link, Encoding encoding)
|
||||||
{
|
{
|
||||||
if (!isMagicPresent(link))
|
if (!isMagicPresent(link))
|
||||||
throw new IOException("Invalid shortcut; magic is missing", 0);
|
throw new IOException("Invalid shortcut; magic is missing", 0);
|
||||||
|
@ -317,11 +331,11 @@ namespace MediaBrowser.Controller.IO
|
||||||
const int networkVolumeTable_offset_offset = 0x14;
|
const int networkVolumeTable_offset_offset = 0x14;
|
||||||
const int finalname_offset_offset = 0x18;
|
const int finalname_offset_offset = 0x18;
|
||||||
int finalname_offset = link[file_start + finalname_offset_offset] + file_start;
|
int finalname_offset = link[file_start + finalname_offset_offset] + file_start;
|
||||||
String finalname = getNullDelimitedString(link, finalname_offset);
|
String finalname = getNullDelimitedString(link, finalname_offset, encoding);
|
||||||
if (IsLocal)
|
if (IsLocal)
|
||||||
{
|
{
|
||||||
int basename_offset = link[file_start + basename_offset_offset] + file_start;
|
int basename_offset = link[file_start + basename_offset_offset] + file_start;
|
||||||
String basename = getNullDelimitedString(link, basename_offset);
|
String basename = getNullDelimitedString(link, basename_offset, encoding);
|
||||||
ResolvedPath = basename + finalname;
|
ResolvedPath = basename + finalname;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -330,12 +344,12 @@ namespace MediaBrowser.Controller.IO
|
||||||
int shareName_offset_offset = 0x08;
|
int shareName_offset_offset = 0x08;
|
||||||
int shareName_offset = link[networkVolumeTable_offset + shareName_offset_offset]
|
int shareName_offset = link[networkVolumeTable_offset + shareName_offset_offset]
|
||||||
+ networkVolumeTable_offset;
|
+ networkVolumeTable_offset;
|
||||||
String shareName = getNullDelimitedString(link, shareName_offset);
|
String shareName = getNullDelimitedString(link, shareName_offset, encoding);
|
||||||
ResolvedPath = shareName + "\\" + finalname;
|
ResolvedPath = shareName + "\\" + finalname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string getNullDelimitedString(byte[] bytes, int off)
|
private static string getNullDelimitedString(byte[] bytes, int off, Encoding encoding)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
|
@ -349,7 +363,7 @@ namespace MediaBrowser.Controller.IO
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Encoding.UTF8.GetString(bytes, off, len);
|
return encoding.GetString(bytes, off, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1084,7 +1084,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
{
|
{
|
||||||
Name = Path.GetFileName(dir),
|
Name = Path.GetFileName(dir),
|
||||||
|
|
||||||
Locations = Directory.EnumerateFiles(dir, "*.lnk", SearchOption.TopDirectoryOnly)
|
Locations = Directory.EnumerateFiles(dir, "*.mblink", SearchOption.TopDirectoryOnly)
|
||||||
.Select(FileSystem.ResolveShortcut)
|
.Select(FileSystem.ResolveShortcut)
|
||||||
.OrderBy(i => i)
|
.OrderBy(i => i)
|
||||||
.ToList(),
|
.ToList(),
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using MediaBrowser.Common.Constants;
|
using MediaBrowser.Common.Constants;
|
||||||
using MediaBrowser.Common.Implementations.Logging;
|
using MediaBrowser.Common.Implementations.Logging;
|
||||||
using MediaBrowser.Common.Implementations.Updates;
|
using MediaBrowser.Common.Implementations.Updates;
|
||||||
|
using MediaBrowser.Controller.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Server.Implementations;
|
using MediaBrowser.Server.Implementations;
|
||||||
using MediaBrowser.ServerApplication.Native;
|
using MediaBrowser.ServerApplication.Native;
|
||||||
|
@ -187,6 +188,8 @@ namespace MediaBrowser.ServerApplication
|
||||||
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
|
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
|
||||||
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
|
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
|
||||||
|
|
||||||
|
MigrateShortcuts(appPaths.RootFolderPath);
|
||||||
|
|
||||||
_appHost = new ApplicationHost(appPaths, logManager);
|
_appHost = new ApplicationHost(appPaths, logManager);
|
||||||
|
|
||||||
_app = new App(_appHost, _appHost.LogManager.GetLogger("App"), runService);
|
_app = new App(_appHost, _appHost.LogManager.GetLogger("App"), runService);
|
||||||
|
@ -523,5 +526,34 @@ namespace MediaBrowser.ServerApplication
|
||||||
/// </summary>
|
/// </summary>
|
||||||
SEM_NOOPENFILEERRORBOX = 0x8000
|
SEM_NOOPENFILEERRORBOX = 0x8000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void MigrateShortcuts(string directory)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(directory);
|
||||||
|
|
||||||
|
foreach (var file in Directory.EnumerateFiles(directory, "*.lnk", SearchOption.AllDirectories).ToList())
|
||||||
|
{
|
||||||
|
MigrateShortcut(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MigrateShortcut(string file)
|
||||||
|
{
|
||||||
|
var newFile = Path.ChangeExtension(file, ".mblink");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var resolvedPath = FileSystem.ResolveShortcut(file);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(resolvedPath))
|
||||||
|
{
|
||||||
|
FileSystem.CreateShortcut(newFile, resolvedPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user