diff --git a/ChangeLog b/ChangeLog index 40be3365e..036d2538b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-10-12 Natalia Portillo + + * DiscImageChef.sln: + Added code to detect OS. + 2015-10-05 Natalia Portillo * DiscImageChef.sln: diff --git a/DiscImageChef.Devices/ChangeLog b/DiscImageChef.Devices/ChangeLog index a96cfbb2f..92ed927b0 100644 --- a/DiscImageChef.Devices/ChangeLog +++ b/DiscImageChef.Devices/ChangeLog @@ -1,3 +1,23 @@ +2015-10-12 Natalia Portillo + + * Command.cs: + Add skeleton for send SCSI command method. + + * Linux/Command.cs: + * Windows/Command.cs: + Added per-platform send SCSI command method. + + * DiscImageChef.Devices.csproj: + Added per-platform send SCSI command method. + Add skeleton for send SCSI command method. + + * Linux/Extern.cs: + * Windows/Extern.cs: + Enhanced externs. + + * Linux/Structs.cs: + Typo. + 2015-10-07 Natalia Portillo * Linux/Enums.cs: diff --git a/DiscImageChef.Devices/Command.cs b/DiscImageChef.Devices/Command.cs new file mode 100644 index 000000000..1938b4cbc --- /dev/null +++ b/DiscImageChef.Devices/Command.cs @@ -0,0 +1,12 @@ +using System; + +namespace DiscImageChef.Devices +{ + public class Command + { + public Command() + { + } + } +} + diff --git a/DiscImageChef.Devices/DiscImageChef.Devices.csproj b/DiscImageChef.Devices/DiscImageChef.Devices.csproj index 3c5e33e9e..dddd62fbd 100644 --- a/DiscImageChef.Devices/DiscImageChef.Devices.csproj +++ b/DiscImageChef.Devices/DiscImageChef.Devices.csproj @@ -42,6 +42,9 @@ + + + @@ -57,4 +60,10 @@ + + + {9183F2E0-A879-4F23-9EE3-C6908F1332B2} + DiscImageChef.Interop + + \ No newline at end of file diff --git a/DiscImageChef.Devices/Linux/Command.cs b/DiscImageChef.Devices/Linux/Command.cs new file mode 100644 index 000000000..6281c74a7 --- /dev/null +++ b/DiscImageChef.Devices/Linux/Command.cs @@ -0,0 +1,52 @@ +using System; +using System.Runtime.InteropServices; + +namespace DiscImageChef.Devices.Linux +{ + static class Command + { + internal static int SendScsiCommand(int fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, ScsiIoctlDirection direction, out double duration, out bool sense) + { + senseBuffer = null; + duration = 0; + sense = false; + + if (buffer == null) + return -1; + + sg_io_hdr_t io_hdr = new sg_io_hdr_t(); + + senseBuffer = new byte[32]; + + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = (byte)cdb.Length; + io_hdr.mx_sb_len = (byte)senseBuffer.Length; + io_hdr.dxfer_direction = direction; + io_hdr.dxfer_len = (uint)buffer.Length; + io_hdr.dxferp = Marshal.AllocHGlobal(buffer.Length); + io_hdr.cmdp = Marshal.AllocHGlobal(cdb.Length); + io_hdr.sbp = Marshal.AllocHGlobal(senseBuffer.Length); + io_hdr.timeout = timeout * 1000; + + Marshal.Copy(buffer, 0, io_hdr.dxferp, buffer.Length); + Marshal.Copy(cdb, 0, io_hdr.cmdp, cdb.Length); + Marshal.Copy(senseBuffer, 0, io_hdr.sbp, senseBuffer.Length); + + int error = Extern.ioctlSg(fd, LinuxIoctl.SG_IO, ref io_hdr); + + if (error < 0) + error = Marshal.GetLastWin32Error(); + + Marshal.Copy(io_hdr.dxferp, buffer, 0, buffer.Length); + Marshal.Copy(io_hdr.cmdp, cdb, 0, cdb.Length); + Marshal.Copy(io_hdr.sbp, senseBuffer, 0, senseBuffer.Length); + + sense |= (io_hdr.info & SgInfo.OkMask) != SgInfo.Ok; + + duration = (double)io_hdr.duration; + + return error; + } + } +} + diff --git a/DiscImageChef.Devices/Linux/Extern.cs b/DiscImageChef.Devices/Linux/Extern.cs index aef712ace..965ec7f75 100644 --- a/DiscImageChef.Devices/Linux/Extern.cs +++ b/DiscImageChef.Devices/Linux/Extern.cs @@ -14,16 +14,16 @@ namespace DiscImageChef.Devices.Linux internal static extern int close(int fd); [DllImport("libc", EntryPoint="ioctl", SetLastError = true)] - internal static extern int ioctlInt(int fd, ulong request, out int value); + internal static extern int ioctlInt(int fd, LinuxIoctl request, out int value); [DllImport("libc", EntryPoint="ioctl", SetLastError = true)] - internal static extern int ioctlSg(int fd, ulong request, ref sg_io_hdr_t value); + internal static extern int ioctlSg(int fd, LinuxIoctl request, ref sg_io_hdr_t value); [DllImport("libc", EntryPoint="ioctl", SetLastError = true)] - internal static extern int ioctlHdTaskfile(int fd, ulong request, ref hd_drive_task_hdr value); + internal static extern int ioctlHdTaskfile(int fd, LinuxIoctl request, ref hd_drive_task_hdr value); [DllImport("libc", EntryPoint="ioctl", SetLastError = true)] - internal static extern int ioctlHdTask(int fd, ulong request, ref byte[] value); + internal static extern int ioctlHdTask(int fd, LinuxIoctl request, ref byte[] value); } } diff --git a/DiscImageChef.Devices/Linux/Structs.cs b/DiscImageChef.Devices/Linux/Structs.cs index 27083b99c..d6269005c 100644 --- a/DiscImageChef.Devices/Linux/Structs.cs +++ b/DiscImageChef.Devices/Linux/Structs.cs @@ -10,11 +10,11 @@ namespace DiscImageChef.Devices.Linux /// Always 'S' for SG v3 /// public int interface_id; /* [i] 'S' (required) */ - public int dxfer_direction; /* [i] */ + public ScsiIoctlDirection dxfer_direction; /* [i] */ public byte cmd_len; /* [i] */ public byte mx_sb_len; /* [i] */ public ushort iovec_count; /* [i] */ - public ScsiIoctlDirection dxfer_len; /* [i] */ + public uint dxfer_len; /* [i] */ public IntPtr dxferp; /* [i], [*io] */ public IntPtr cmdp; /* [i], [*i] */ public IntPtr sbp; /* [i], [*o] */ diff --git a/DiscImageChef.Devices/Windows/Command.cs b/DiscImageChef.Devices/Windows/Command.cs new file mode 100644 index 000000000..92f971418 --- /dev/null +++ b/DiscImageChef.Devices/Windows/Command.cs @@ -0,0 +1,56 @@ +using System; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; + +namespace DiscImageChef.Devices.Windows +{ + static class Command + { + internal static int SendScsiCommand(SafeFileHandle fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, ScsiIoctlDirection direction, out double duration, out bool sense) + { + senseBuffer = null; + duration = 0; + sense = false; + + if (buffer == null) + return -1; + + ScsiPassThroughDirectAndSenseBuffer sptd_sb = new ScsiPassThroughDirectAndSenseBuffer(); + sptd_sb.sptd = new ScsiPassThroughDirect(); + sptd_sb.SenseBuf = new byte[32]; + sptd_sb.sptd.Cdb = new byte[16]; + Array.Copy(cdb, sptd_sb.sptd.Cdb, cdb.Length); + sptd_sb.sptd.Length = (ushort)Marshal.SizeOf(sptd_sb.sptd); + sptd_sb.sptd.CdbLength = (byte)cdb.Length; + sptd_sb.sptd.SenseInfoLength = (byte)sptd_sb.SenseBuf.Length; + sptd_sb.sptd.DataIn = direction; + sptd_sb.sptd.DataTransferLength = (uint)buffer.Length; + sptd_sb.sptd.TimeOutValue = timeout; + sptd_sb.sptd.DataBuffer = Marshal.AllocHGlobal(buffer.Length); + sptd_sb.sptd.SenseInfoOffset = (uint)Marshal.SizeOf(sptd_sb.sptd); + + uint k = 0; + int error = 0; + + DateTime start = DateTime.Now; + bool hasError = Extern.DeviceIoControlScsi(fd, WindowsIoctl.IOCTL_SCSI_PASS_THROUGH_DIRECT, ref sptd_sb, (uint)Marshal.SizeOf(sptd_sb), ref sptd_sb, + (uint)Marshal.SizeOf(sptd_sb), ref k, IntPtr.Zero); + DateTime end = DateTime.Now; + + if (hasError) + error = Marshal.GetLastWin32Error(); + + Marshal.Copy(sptd_sb.sptd.DataBuffer, buffer, 0, buffer.Length); + + sense |= sptd_sb.sptd.ScsiStatus != 0; + + senseBuffer = new byte[32]; + Array.Copy(sptd_sb.SenseBuf, senseBuffer, 32); + + duration = (end - start).TotalMilliseconds; + + return error; + } + } +} + diff --git a/DiscImageChef.Devices/Windows/Extern.cs b/DiscImageChef.Devices/Windows/Extern.cs index e736b78a2..740d635fa 100644 --- a/DiscImageChef.Devices/Windows/Extern.cs +++ b/DiscImageChef.Devices/Windows/Extern.cs @@ -17,9 +17,9 @@ namespace DiscImageChef.Devices.Windows IntPtr templateFile); [DllImport("Kernel32.dll", SetLastError = true, EntryPoint="ioctl", CharSet = CharSet.Auto)] - public static extern bool DeviceIoControlScsi( + internal static extern bool DeviceIoControlScsi( SafeFileHandle hDevice, - uint IoControlCode, + WindowsIoctl IoControlCode, ref ScsiPassThroughDirectAndSenseBuffer InBuffer, uint nInBufferSize, ref ScsiPassThroughDirectAndSenseBuffer OutBuffer, @@ -29,9 +29,9 @@ namespace DiscImageChef.Devices.Windows ); [DllImport("Kernel32.dll", SetLastError = true, EntryPoint="ioctl", CharSet = CharSet.Auto)] - public static extern bool DeviceIoControlAta( + internal static extern bool DeviceIoControlAta( SafeFileHandle hDevice, - uint IoControlCode, + WindowsIoctl IoControlCode, ref AtaPassThroughDirect InBuffer, uint nInBufferSize, ref AtaPassThroughDirect OutBuffer, @@ -41,7 +41,7 @@ namespace DiscImageChef.Devices.Windows ); [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] - public static extern bool CloseHandle(SafeFileHandle hDevice); + internal static extern bool CloseHandle(SafeFileHandle hDevice); } } diff --git a/DiscImageChef.Interop/ChangeLog b/DiscImageChef.Interop/ChangeLog new file mode 100644 index 000000000..e93e6f919 --- /dev/null +++ b/DiscImageChef.Interop/ChangeLog @@ -0,0 +1,8 @@ +2015-10-12 Natalia Portillo + + * DetectOS.cs: + * PlatformID.cs: + * Properties/AssemblyInfo.cs: + * DiscImageChef.Interop.csproj: + Added code to detect OS. + diff --git a/DiscImageChef.Interop/DetectOS.cs b/DiscImageChef.Interop/DetectOS.cs new file mode 100644 index 000000000..2745f222b --- /dev/null +++ b/DiscImageChef.Interop/DetectOS.cs @@ -0,0 +1,188 @@ +// +// Interop.DetectOS.cs +// +// Author: +// Natalia Portillo +// +// Copyright (c) 2015 © Claunia.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Runtime.InteropServices; + +namespace DiscImageChef.Interop +{ + public static class DetectOS + { + /// + /// POSIX uname structure, size from OSX, big enough to handle extra fields + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + struct utsname + { + /// + /// System name + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string sysname; + /// + /// Node name + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string nodename; + /// + /// Release level + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string release; + /// + /// Version level + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string version; + /// + /// Hardware level + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string machine; + } + + [DllImport("libc", SetLastError = true)] + static extern int uname(out utsname name); + + [DllImport("libc", SetLastError = true, EntryPoint = "sysctlbyname", CharSet = CharSet.Ansi)] + static extern int OSX_sysctlbyname(string name, IntPtr oldp, IntPtr oldlenp, IntPtr newp, uint newlen); + + public static Interop.PlatformID GetRealPlatformID() + { + if ((int)Environment.OSVersion.Platform < 4 || + (int)Environment.OSVersion.Platform == 5) + { + return (Interop.PlatformID)((int)Environment.OSVersion.Platform); + } + + utsname unixname; + int error = uname(out unixname); + if (error != 0) + throw new Exception(String.Format("Unhandled exception calling uname: {0}", Marshal.GetLastWin32Error())); + + switch (unixname.sysname) + { + // TODO: Differentiate Linux, Android, Tizen + case "Linux": + { + #if __ANDROID__ + return PlatformID.Android; + #else + return PlatformID.Linux; + #endif + } + case "Darwin": + { + int osx_error; + + IntPtr pLen = Marshal.AllocHGlobal(sizeof(int)); + osx_error = OSX_sysctlbyname("hw.machine", IntPtr.Zero, pLen, IntPtr.Zero, 0); + if (osx_error != 0) + { + Marshal.FreeHGlobal(pLen); + + throw new Exception(String.Format("Unhandled exception calling uname: {0}", Marshal.GetLastWin32Error())); + } + + int length = Marshal.ReadInt32(pLen); + IntPtr pStr = Marshal.AllocHGlobal(length); + osx_error = OSX_sysctlbyname("hw.machine", pStr, pLen, IntPtr.Zero, 0); + if (osx_error != 0) + { + Marshal.FreeHGlobal(pStr); + Marshal.FreeHGlobal(pLen); + + throw new Exception(String.Format("Unhandled exception calling uname: {0}", Marshal.GetLastWin32Error())); + } + + string machine = Marshal.PtrToStringAnsi(pStr); + + Marshal.FreeHGlobal(pStr); + Marshal.FreeHGlobal(pLen); + + if (machine.StartsWith("iPad", StringComparison.Ordinal) || + machine.StartsWith("iPod", StringComparison.Ordinal) || + machine.StartsWith("iPhone", StringComparison.Ordinal)) + return PlatformID.iOS; + + return PlatformID.MacOSX; + } + case "GNU": + return PlatformID.Hurd; + case "FreeBSD": + case "GNU/kFreeBSD": + return PlatformID.FreeBSD; + case "DragonFly": + return PlatformID.DragonFly; + case "Haiku": + return PlatformID.Haiku; + case "HP-UX": + return PlatformID.HPUX; + case "AIX": + return PlatformID.AIX; + case "OS400": + return PlatformID.OS400; + case "IRIX": + case "IRIX64": + return PlatformID.IRIX; + case "Minix": + return PlatformID.Minix; + case "NetBSD": + return PlatformID.NetBSD; + case "NONSTOP_KERNEL": + return PlatformID.NonStop; + case "OpenBSD": + return PlatformID.OpenBSD; + case "QNX": + return PlatformID.QNX; + case "SINIX-Y": + return PlatformID.SINIX; + case "SunOS": + return PlatformID.Solaris; + case "OSF1": + return PlatformID.Tru64; + case "ULTRIX": + return PlatformID.Ultrix; + case "SCO_SV": + return PlatformID.OpenServer; + case "UnixWare": + return PlatformID.UnixWare; + case "Interix": + case "UWIN-W7": + return PlatformID.Win32NT; + default: + { + if (unixname.sysname.StartsWith("CYGWIN_NT", StringComparison.Ordinal) || + unixname.sysname.StartsWith("MINGW32_NT", StringComparison.Ordinal) || + unixname.sysname.StartsWith("MSYS_NT", StringComparison.Ordinal) || + unixname.sysname.StartsWith("UWIN", StringComparison.Ordinal)) + return PlatformID.Win32NT; + + return PlatformID.Unknown; + } + } + } + } +} \ No newline at end of file diff --git a/DiscImageChef.Interop/DiscImageChef.Interop.csproj b/DiscImageChef.Interop/DiscImageChef.Interop.csproj new file mode 100644 index 000000000..4f651a1ab --- /dev/null +++ b/DiscImageChef.Interop/DiscImageChef.Interop.csproj @@ -0,0 +1,41 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {9183F2E0-A879-4F23-9EE3-C6908F1332B2} + Library + DiscImageChef.Interop + DiscImageChef.Interop + v4.5 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + + + + + + + + \ No newline at end of file diff --git a/DiscImageChef.Interop/PlatformID.cs b/DiscImageChef.Interop/PlatformID.cs new file mode 100644 index 000000000..2eccaa14b --- /dev/null +++ b/DiscImageChef.Interop/PlatformID.cs @@ -0,0 +1,177 @@ +// +// Interop.PlatformID.cs +// +// Author: +// Natalia Portillo +// +// Copyright (c) 2015 © Claunia.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +namespace DiscImageChef.Interop +{ + public enum PlatformID + { + /// + /// Win32s + /// + Win32S = 0, + /// + /// Win32 (Windows 9x) + /// + Win32Windows = 1, + /// + /// Windows NT + /// + Win32NT = 2, + /// + /// Windows Mobile + /// + WinCE = 3, + /// + /// UNIX (do not use, too generic) + /// + Unix = 4, + /// + /// Xbox 360 + /// + Xbox = 5, + /// + /// OS X + /// + MacOSX = 6, + /// + /// iOS is not OS X + /// + iOS = 7, + /// + /// Linux + /// + Linux = 8, + /// + /// Sun Solaris + /// + Solaris = 9, + /// + /// NetBSD + /// + NetBSD = 10, + /// + /// OpenBSD + /// + OpenBSD = 11, + /// + /// FreeBSD + /// + FreeBSD = 12, + /// + /// DragonFly BSD + /// + DragonFly = 13, + /// + /// Nintendo Wii + /// + Wii = 14, + /// + /// Nintendo Wii U + /// + WiiU = 15, + /// + /// Sony PlayStation 3 + /// + PlayStation3 = 16, + /// + /// Sony Playstation 4 + /// + PlayStation4 = 17, + /// + /// Google Android + /// + Android = 18, + /// + /// Samsung Tizen + /// + Tizen = 19, + /// + /// Windows Phone + /// + WindowsPhone = 20, + /// + /// GNU/Hurd + /// + Hurd = 21, + /// + /// Haiku + /// + Haiku = 22, + /// + /// HP-UX + /// + HPUX = 23, + /// + /// AIX + /// + AIX = 24, + /// + /// OS/400 + /// + OS400 = 25, + /// + /// IRIX + /// + IRIX = 26, + /// + /// Minix + /// + Minix = 27, + /// + /// NonStop + /// + NonStop = 28, + /// + /// QNX + /// + QNX = 29, + /// + /// SINIX + /// + SINIX = 30, + /// + /// Tru64 UNIX + /// + Tru64 = 31, + /// + /// Ultrix + /// + Ultrix = 32, + /// + /// SCO OpenServer / SCO UNIX + /// + OpenServer = 33, + /// + /// SCO UnixWare + /// + UnixWare = 34, + /// + /// IBM z/OS + /// + zOS = 35, + Unknown = -1 + } +} \ No newline at end of file diff --git a/DiscImageChef.Interop/Properties/AssemblyInfo.cs b/DiscImageChef.Interop/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..1ebad37c9 --- /dev/null +++ b/DiscImageChef.Interop/Properties/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("DiscImageChef.Interop")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Claunia.com")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("© Claunia.com")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/DiscImageChef.sln b/DiscImageChef.sln index 0eaecf823..5f293431e 100644 --- a/DiscImageChef.sln +++ b/DiscImageChef.sln @@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscImageChef.Decoders", "D EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscImageChef.Devices", "DiscImageChef.Devices\DiscImageChef.Devices.csproj", "{57BB2341-AB62-48FD-91B8-46F5A2F9ED51}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscImageChef.Interop", "DiscImageChef.Interop\DiscImageChef.Interop.csproj", "{9183F2E0-A879-4F23-9EE3-C6908F1332B2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 @@ -51,6 +53,10 @@ Global {7A4B05BE-73C9-4F34-87FE-E80CCF1F732D}.Release|x86.Build.0 = Release|x86 {8996EF59-09B9-4920-A3DE-2F8EA2EBBCFF}.Debug|x86.ActiveCfg = Debug|Any CPU {8996EF59-09B9-4920-A3DE-2F8EA2EBBCFF}.Release|x86.ActiveCfg = Release|Any CPU + {9183F2E0-A879-4F23-9EE3-C6908F1332B2}.Debug|x86.ActiveCfg = Debug|Any CPU + {9183F2E0-A879-4F23-9EE3-C6908F1332B2}.Debug|x86.Build.0 = Debug|Any CPU + {9183F2E0-A879-4F23-9EE3-C6908F1332B2}.Release|x86.ActiveCfg = Release|Any CPU + {9183F2E0-A879-4F23-9EE3-C6908F1332B2}.Release|x86.Build.0 = Release|Any CPU {CC48B324-A532-4A45-87A6-6F91F7141E8D}.Debug|x86.ActiveCfg = Debug|Any CPU {CC48B324-A532-4A45-87A6-6F91F7141E8D}.Debug|x86.Build.0 = Debug|Any CPU {CC48B324-A532-4A45-87A6-6F91F7141E8D}.Release|x86.ActiveCfg = Release|Any CPU