diff --git a/src/Drivers/Common.items b/src/Drivers/Common.items index b5b0cb84ca..727cc9a88d 100644 --- a/src/Drivers/Common.items +++ b/src/Drivers/Common.items @@ -82,6 +82,7 @@ by the PreBuild.targets file. + diff --git a/src/Drivers/reko.config b/src/Drivers/reko.config index 200d962fdf..e9111618f4 100644 --- a/src/Drivers/reko.config +++ b/src/Drivers/reko.config @@ -78,6 +78,7 @@ + @@ -444,6 +445,11 @@ Type="Reko.Environments.Ps3.Ps3Platform,Reko.Environments.Ps3"> + + + diff --git a/src/Environments/MacOS/Classic/AppleDoubleLoader.cs b/src/Environments/MacOS/Classic/AppleDoubleLoader.cs index c8ef553dc8..a08a7e03a9 100644 --- a/src/Environments/MacOS/Classic/AppleDoubleLoader.cs +++ b/src/Environments/MacOS/Classic/AppleDoubleLoader.cs @@ -55,7 +55,7 @@ public override Program LoadProgram(Address? addrLoad) { addrLoad ??= PreferredBaseAddress; var cfgSvc = Services.RequireService(); - var rdr = new Core.Memory.BeImageReader(RawImage); + var rdr = new BeImageReader(RawImage); var hdr = rdr.ReadStruct
(); var things = new Entry[hdr.cEntries]; for (int i = 0; i < things.Length; ++i) diff --git a/src/Environments/PalmOS/PRC/Code0Resource.cs b/src/Environments/PalmOS/PRC/Code0Resource.cs new file mode 100644 index 0000000000..3a86519fd5 --- /dev/null +++ b/src/Environments/PalmOS/PRC/Code0Resource.cs @@ -0,0 +1,32 @@ +#region License +/* + * Copyright (C) 1999-2023 John Källén. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Reko.Environments.PalmOS.PRC +{ + public class Code0Resource + { + } +} diff --git a/src/Environments/PalmOS/PRC/PrcHeader.cs b/src/Environments/PalmOS/PRC/PrcHeader.cs new file mode 100644 index 0000000000..a2066f3e12 --- /dev/null +++ b/src/Environments/PalmOS/PRC/PrcHeader.cs @@ -0,0 +1,46 @@ +#region License +/* + * Copyright (C) 1999-2023 John Källén. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Reko.Environments.PalmOS.PRC +{ + public class PrcHeader + { + public string? name; + public ushort flags; + public ushort version; + public uint create_time; + public uint mod_time; + public uint backup_time; + public uint mod_num; + public uint app_info; + public uint sort_info; + public uint type; + public uint id; + public uint unique_id_seed; + public uint next_record_list; + public ushort num_records; + } +} diff --git a/src/Environments/PalmOS/PRC/PrcLoader.cs b/src/Environments/PalmOS/PRC/PrcLoader.cs new file mode 100644 index 0000000000..92140a0e70 --- /dev/null +++ b/src/Environments/PalmOS/PRC/PrcLoader.cs @@ -0,0 +1,180 @@ +#region License +/* + * Copyright (C) 1999-2023 John Källén. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#endregion + +using Reko.Core; +using Reko.Core.Configuration; +using Reko.Core.Loading; +using Reko.Core.Memory; +using Reko.Core.Services; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Reko.Environments.PalmOS.PRC +{ + /// + /// Loads PalmOS PRC files. + /// + + public class PrcLoader : ProgramImageLoader + { + // https://web.mit.edu/tytso/www/pilot/prc-format.html + + public PrcLoader(IServiceProvider services, ImageLocation imageLocation, byte[] imgRaw) + : base(services, imageLocation, imgRaw) + { + } + + public override Address PreferredBaseAddress + { + get { return Address.Ptr32(0x00100000); } + set { throw new NotImplementedException(); } + } + + + public override Program LoadProgram(Address? addrLoad) + { + addrLoad ??= PreferredBaseAddress; + var rdr = new BeImageReader(base.RawImage); + var cfgSvc = Services.RequireService(); + + var header = LoadHeader(rdr); + if (header is null) + throw new BadImageFormatException(); + var rsrcHeaders = LoadResourceHeaders(rdr, header.num_records); + if (rsrcHeaders is null) + throw new BadImageFormatException(); + var segments = LoadResources(rdr, rsrcHeaders, addrLoad); + if (segments is null) + throw new BadImageFormatException(); + + var arch = cfgSvc.GetArchitecture("m68k")!; + var platform = new PalmOSPlatform(Services, arch, "palmOS"); + var program = new Program(segments, arch, platform); + return program; + } + + private PrcHeader? LoadHeader(BeImageReader rdr) + { + var header = new PrcHeader(); + var abName = rdr.ReadBytes(0x20); + if (abName.Length != 0x20) + return null; + int i = Array.IndexOf(abName, 0); + if (i < 0) + header.name = Encoding.ASCII.GetString(abName); + else + header.name = Encoding.ASCII.GetString(abName, 0, i); + + if (!rdr.TryReadBeUInt16(out header.flags)) + return null; + if (!rdr.TryReadBeUInt16(out header.version)) + return null; + if (!rdr.TryReadBeUInt32(out header.create_time)) + return null; + if (!rdr.TryReadBeUInt32(out header.mod_time)) + return null; + if (!rdr.TryReadBeUInt32(out header.backup_time)) + return null; + + if (!rdr.TryReadBeUInt32(out header.mod_num)) + return null; + if (!rdr.TryReadBeUInt32(out header.app_info)) + return null; + if (!rdr.TryReadBeUInt32(out header.sort_info)) + return null; + if (!rdr.TryReadBeUInt32(out header.type)) + return null; + + if (!rdr.TryReadBeUInt32(out header.id)) + return null; + if (!rdr.TryReadBeUInt32(out header.unique_id_seed)) + return null; + if (!rdr.TryReadBeUInt32(out header.next_record_list)) + return null; + if (!rdr.TryReadBeUInt16(out header.num_records)) + return null; + + return header; + } + + private List? LoadResourceHeaders(BeImageReader rdr, uint cRecords) + { + var headers = new List(); + for (uint i = 0; i < cRecords; ++i) + { + var rhdr = new ResourceHeader(); + var abName = rdr.ReadBytes(4); + if (abName.Length != 4) + return null; + rhdr.name = Encoding.ASCII.GetString(abName); + if (!rdr.TryReadBeUInt16(out rhdr.id)) + return null; + if (!rdr.TryReadBeUInt32(out rhdr.offset)) + return null; + headers.Add(rhdr); + } + return headers; + } + + private SegmentMap LoadResources(BeImageReader rdr, List rsrcHeaders, Address addrBase) + { + var segments = new List(); + var addr = addrBase; + for (int i = 0; i < rsrcHeaders.Count - 1; ++i) + { + var hdr = rsrcHeaders[i]; + var length = rsrcHeaders[i+1].offset - hdr.offset; + rdr.Offset = hdr.offset; + var bytes = rdr.ReadBytes(length); + var mem = new ByteMemoryArea(addr, bytes); + string? name = hdr.name; + if (name is null) + name = $"#{hdr.id}"; + else + name = $"{name}#{hdr.id}"; + var accessMode = AccessMode.Read; + if (hdr.name == "code") + { + if (hdr.id == 0) + { + LoadCode0Resource(); + } + else + { + accessMode = AccessMode.ReadExecute; + } + } + var seg = new ImageSegment(name, mem, accessMode); + segments.Add(seg); + addr += length; //$TODO: align to even paragraph boundary? + } + return new SegmentMap(segments.ToArray()); + } + + private void LoadCode0Resource() + { + //$TODO: according to the doc page, the code0 resource sometimes + // is patterend after MacOS, with a jump table above the "a5 line", + // and sometimes follows a different convention. Needs more investigation, + // and access to different binaries build by different toolchains. + } + } +} diff --git a/src/Environments/PalmOS/PRC/ResourceHeader.cs b/src/Environments/PalmOS/PRC/ResourceHeader.cs new file mode 100644 index 0000000000..6e10933b8a --- /dev/null +++ b/src/Environments/PalmOS/PRC/ResourceHeader.cs @@ -0,0 +1,35 @@ +#region License +/* + * Copyright (C) 1999-2023 John Källén. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Reko.Environments.PalmOS.PRC +{ + public class ResourceHeader + { + public string? name; + public ushort id; + public uint offset; + } +} diff --git a/src/Environments/PalmOS/PalmOS.csproj b/src/Environments/PalmOS/PalmOS.csproj new file mode 100644 index 0000000000..496f8aaeaa --- /dev/null +++ b/src/Environments/PalmOS/PalmOS.csproj @@ -0,0 +1,16 @@ + + + + net6.0 + Library + Reko.Environments.PalmOS + Reko.Environments.PalmOS + enable + false + Debug;Release + + + + + + diff --git a/src/Environments/PalmOS/PalmOSPlatform.cs b/src/Environments/PalmOS/PalmOSPlatform.cs new file mode 100644 index 0000000000..5e4a872b6e --- /dev/null +++ b/src/Environments/PalmOS/PalmOSPlatform.cs @@ -0,0 +1,55 @@ +#region License +/* + * Copyright (C) 1999-2023 John Källén. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#endregion + +using Reko.Core; +using Reko.Core.Hll.C; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Reko.Environments.PalmOS +{ + public class PalmOSPlatform : Platform + { + public PalmOSPlatform(IServiceProvider services, IProcessorArchitecture arch, string platformId) + : base(services, arch, platformId) + { + } + + public override string DefaultCallingConvention => throw new NotImplementedException(); + + public override SystemService? FindService(int vector, ProcessorState? state, SegmentMap? segmentMap) + { + throw new NotImplementedException(); + } + + public override int GetBitSizeFromCBasicType(CBasicType cb) + { + throw new NotImplementedException(); + } + + public override ExternalProcedure? LookupProcedureByName(string? moduleName, string procName) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Environments/PalmOS/Properties/AssemblyInfo.cs b/src/Environments/PalmOS/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..97ac618ab9 --- /dev/null +++ b/src/Environments/PalmOS/Properties/AssemblyInfo.cs @@ -0,0 +1,46 @@ +#region License +/* + * Copyright (C) 1999-2023 John Källén. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#endregion + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Reko Decompiler PalmOS support")] +[assembly: AssemblyDescription("Reko Decompiler support for the Palm operating system.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany(Reko.AssemblyMetadata.Company)] +[assembly: AssemblyProduct(Reko.AssemblyMetadata.Product)] +[assembly: AssemblyCopyright(Reko.AssemblyMetadata.Copyright)] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("D9CD39FF-C948-4440-8652-901528D3DB08")] + +[assembly: AssemblyVersion(Reko.AssemblyMetadata.AssemblyVersion)] +[assembly: AssemblyFileVersion(Reko.AssemblyMetadata.AssemblyFileVersion)] diff --git a/src/Installers/NuGetPackage/NuGetPackage.template b/src/Installers/NuGetPackage/NuGetPackage.template index 0c6ab7c4e4..d81cfa7081 100644 --- a/src/Installers/NuGetPackage/NuGetPackage.template +++ b/src/Installers/NuGetPackage/NuGetPackage.template @@ -2,7 +2,7 @@ Reko.Decompiler.Runtime - 0.11.4 + 0.11.5 Reko Decompiler Runtime Reko Decompiler contributors John Källén diff --git a/src/Installers/NuGetPackage/reko-files.xml b/src/Installers/NuGetPackage/reko-files.xml index 3870221538..c40b0a3db2 100644 --- a/src/Installers/NuGetPackage/reko-files.xml +++ b/src/Installers/NuGetPackage/reko-files.xml @@ -91,6 +91,8 @@ $SolutionDir$/Environments/OpenVMS/$TargetDir$/Reko.Environments.OpenVMS.dll $SolutionDir$/Environments/OS2/ $SolutionDir$/Environments/OS2/$TargetDir$/Reko.Environments.OS2.dll + $SolutionDir$/Environments/PalmOS/ + $SolutionDir$/Environments/PalmOS/$TargetDir$/Reko.Environments.PalmOS.dll $SolutionDir$/Environments/Pdp10Env/$TargetDir$/Reko.Environments.Pdp10Env.dll $SolutionDir$/Environments/Ps3/$TargetDir$/Reko.Environments.Ps3.dll $SolutionDir$/Environments/RT11/ @@ -222,6 +224,7 @@ + diff --git a/src/Reko-decompiler.sln b/src/Reko-decompiler.sln index b4c83e6a7f..627ffe792d 100644 --- a/src/Reko-decompiler.sln +++ b/src/Reko-decompiler.sln @@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Arm", "Arch\Arm\Arm.csproj" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avr", "Arch\Avr\Avr.csproj", "{5E75D702-3032-41FE-8D09-86428555A8ED}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{2B025555-2C2C-42FE-B5B4-238E7F1E0AB5}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blackfin", "Arch\Blackfin\Blackfin.csproj", "{0BCCEFDD-63A8-47F2-9A39-8CE7B5F9CFAB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cil", "Arch\Cil\Cil.csproj", "{F6F2225D-B778-4FD2-9BA9-A8E2B58ACCCC}" @@ -530,7 +532,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fujitsu", "Arch\Fujitsu\Fuj EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenVMS", "Environments\OpenVMS\OpenVMS.csproj", "{C44138B0-6F67-48E8-B793-03BC2156A14B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{2B025555-2C2C-42FE-B5B4-238E7F1E0AB5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PalmOS", "Environments\PalmOS\PalmOS.csproj", "{AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -4751,6 +4753,38 @@ Global {2B025555-2C2C-42FE-B5B4-238E7F1E0AB5}.UnixRelease|x64.Build.0 = Release|Any CPU {2B025555-2C2C-42FE-B5B4-238E7F1E0AB5}.UnixRelease|x86.ActiveCfg = Release|Any CPU {2B025555-2C2C-42FE-B5B4-238E7F1E0AB5}.UnixRelease|x86.Build.0 = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Debug|ARM64.Build.0 = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Debug|x64.Build.0 = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Debug|x86.ActiveCfg = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Debug|x86.Build.0 = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Release|Any CPU.Build.0 = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Release|ARM64.ActiveCfg = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Release|ARM64.Build.0 = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Release|x64.ActiveCfg = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Release|x64.Build.0 = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Release|x86.ActiveCfg = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.Release|x86.Build.0 = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixDebug|Any CPU.ActiveCfg = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixDebug|Any CPU.Build.0 = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixDebug|ARM64.ActiveCfg = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixDebug|ARM64.Build.0 = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixDebug|x64.ActiveCfg = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixDebug|x64.Build.0 = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixDebug|x86.ActiveCfg = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixDebug|x86.Build.0 = Debug|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixRelease|Any CPU.ActiveCfg = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixRelease|Any CPU.Build.0 = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixRelease|ARM64.ActiveCfg = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixRelease|ARM64.Build.0 = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixRelease|x64.ActiveCfg = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixRelease|x64.Build.0 = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixRelease|x86.ActiveCfg = Release|Any CPU + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93}.UnixRelease|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -4887,6 +4921,7 @@ Global {5D970ABA-822D-4A35-8354-C82DA425EF6A} = {18994109-C4D5-49F9-86E0-3B5B1046C08E} {C44138B0-6F67-48E8-B793-03BC2156A14B} = {E6A2E818-3AB9-47FC-9266-4E72ECBB13F4} {2B025555-2C2C-42FE-B5B4-238E7F1E0AB5} = {3F38B136-C309-4B62-8496-931723F16706} + {AC7E183E-2FB1-4E93-ADEB-31B318D3DC93} = {E6A2E818-3AB9-47FC-9266-4E72ECBB13F4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8B012B36-B0A2-4412-A22A-023C9B7C2EDD}