public Args(string peFilePath, string pdbFilePathOpt, string outPdbFilePathOpt, PortablePdbConversionOptions options, ImmutableArray <PdbDiagnosticId> suppressedWarnings, bool suppressAllWarnings, bool extract)
            {
                Debug.Assert(options != null);

                PEFilePath          = peFilePath;
                PdbFilePathOpt      = pdbFilePathOpt;
                OutPdbFilePathOpt   = outPdbFilePathOpt;
                Options             = options;
                Extract             = extract;
                SuppressAllWarnings = suppressAllWarnings;
                SuppressedWarnings  = suppressedWarnings;
            }
        // internal for testing
        internal static Args ParseArgs(string[] args)
        {
            string peFile              = null;
            bool   extract             = false;
            bool   sourceLink          = false;
            string inPdb               = null;
            string outPdb              = null;
            bool   suppressAllWarnings = false;
            var    suppressedWarnings  = new List <PdbDiagnosticId>();
            var    srcSvrVariables     = new List <KeyValuePair <string, string> >();

            int i = 0;

            while (i < args.Length)
            {
                var arg = args[i++];

                string ReadValue() => (i < args.Length) ? args[i++] : throw new InvalidDataException(string.Format(Resources.MissingValueForOption, arg));

                switch (arg)
                {
                case "/extract":
                    extract = true;
                    break;

                case "/sourcelink":
                    sourceLink = true;
                    break;

                case "/pdb":
                    inPdb = ReadValue();
                    break;

                case "/out":
                    outPdb = ReadValue();
                    break;

                case "/nowarn":
                    var value = ReadValue();
                    if (value == "*")
                    {
                        suppressAllWarnings = true;
                    }
                    else
                    {
                        suppressedWarnings.AddRange(value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(
                                                        n => (int.TryParse(n, out int id) && id != 0 && ((PdbDiagnosticId)id).IsValid()) ?
                                                        (PdbDiagnosticId)id :
                                                        throw new InvalidDataException(string.Format(Resources.InvalidWarningNumber, n))));
                    }

                    break;

                case "/srcsvrvar":
                case "/srcsvrvariable":
                    srcSvrVariables.Add(ParseSrcSvrVariable(ReadValue()));
                    break;

                default:
                    if (peFile == null)
                    {
                        peFile = arg;
                    }
                    else
                    {
                        throw new InvalidDataException((arg.StartsWith("/", StringComparison.Ordinal) ?
                                                        string.Format(Resources.UnrecognizedOption, arg) :
                                                        Resources.OnlyOneDllExeCanBeSpecified));
                    }
                    break;
                }
            }

            if (peFile == null)
            {
                throw new InvalidDataException(Resources.MissingDllExePath);
            }

            if (!extract && outPdb == null)
            {
                try
                {
                    outPdb = Path.ChangeExtension(peFile, "pdb2");
                }
                catch (Exception e)
                {
                    throw new InvalidDataException(e.Message);
                }
            }

            if (extract && sourceLink)
            {
                throw new InvalidDataException(Resources.CantSpecifyBothExtractAndSourcelinkOptions);
            }

            if (extract && inPdb != null)
            {
                throw new InvalidDataException(Resources.CantSpecifyBothExtractAndPdbOptions);
            }

            if (sourceLink && srcSvrVariables.Count > 0)
            {
                throw new InvalidDataException(Resources.CantSpecifyBothSrcSvrVariableAndSourcelinkOptions);
            }

            PortablePdbConversionOptions options;

            try
            {
                options = new PortablePdbConversionOptions(
                    suppressSourceLinkConversion: sourceLink,
                    srcSvrVariables: srcSvrVariables);
            }
            catch (ArgumentException e)
            {
                throw new InvalidDataException(e.Message);
            }

            return(new Args(peFile, inPdb, outPdb, options, suppressedWarnings.ToImmutableArray(), suppressAllWarnings, extract));
        }
Beispiel #3
0
            public Args(string peFilePath, string pdbFilePathOpt, string outPdbFilePathOpt, PortablePdbConversionOptions options, bool extract, bool verbose)
            {
                Debug.Assert(options != null);

                PEFilePath        = peFilePath;
                PdbFilePathOpt    = pdbFilePathOpt;
                OutPdbFilePathOpt = outPdbFilePathOpt;
                Options           = options;
                Extract           = extract;
                Verbose           = verbose;
            }
Beispiel #4
0
        // internal for testing
        internal static Args ParseArgs(string[] args)
        {
            string peFile          = null;
            bool   extract         = false;
            bool   sourceLink      = false;
            bool   verbose         = false;
            string inPdb           = null;
            string outPdb          = null;
            var    srcSvrVariables = new List <KeyValuePair <string, string> >();

            int i = 0;

            while (i < args.Length)
            {
                var arg = args[i++];

                string ReadValue() => (i < args.Length) ? args[i++] : throw new InvalidDataException(string.Format(Resources.MissingValueForOption, arg));

                switch (arg)
                {
                case "/extract":
                    extract = true;
                    break;

                case "/sourcelink":
                    sourceLink = true;
                    break;

                case "/verbose":
                    verbose = true;
                    break;

                case "/pdb":
                    inPdb = ReadValue();
                    break;

                case "/out":
                    outPdb = ReadValue();
                    break;

                case "/srcsvrvar":
                case "/srcsvrvariable":
                    srcSvrVariables.Add(ParseSrcSvrVariable(ReadValue()));
                    break;

                default:
                    if (peFile == null)
                    {
                        peFile = arg;
                    }
                    else
                    {
                        throw new InvalidDataException((arg.StartsWith("/", StringComparison.Ordinal) ?
                                                        string.Format(Resources.UnrecognizedOption, arg) :
                                                        Resources.OnlyOneDllExeCanBeSpecified));
                    }
                    break;
                }
            }

            if (peFile == null)
            {
                throw new InvalidDataException(Resources.MissingDllExePath);
            }

            if (!extract && outPdb == null)
            {
                try
                {
                    outPdb = Path.ChangeExtension(peFile, "pdb2");
                }
                catch (Exception e)
                {
                    throw new InvalidDataException(e.Message);
                }
            }

            if (extract && sourceLink)
            {
                throw new InvalidDataException(Resources.CantSpecifyBothExtractAndSourcelinkOptions);
            }

            if (extract && inPdb != null)
            {
                throw new InvalidDataException(Resources.CantSpecifyBothExtractAndPdbOptions);
            }

            if (sourceLink && srcSvrVariables.Count > 0)
            {
                throw new InvalidDataException(Resources.CantSpecifyBothSrcSvrVariableAndSourcelinkOptions);
            }

            PortablePdbConversionOptions options;

            try
            {
                options = new PortablePdbConversionOptions(
                    suppressSourceLinkConversion: sourceLink,
                    srcSvrVariables: srcSvrVariables);
            }
            catch (ArgumentException e)
            {
                throw new InvalidDataException(e.Message);
            }

            return(new Args(peFile, inPdb, outPdb, options, extract, verbose));
        }
 /// <summary>
 /// Converts Portable PDB stream to Windows PDB.
 /// </summary>
 /// <param name="peReader">PE reader.</param>
 /// <param name="pdbReader">Portable PDB reader.</param>
 /// <param name="pdbWriter">PDB writer.</param>
 /// <param name="options">Conversion options.</param>
 /// <exception cref="ArgumentNullException"><paramref name="peReader"/>, <paramref name="pdbReader"/>, or <paramref name="pdbWriter"/> is null.</exception>
 /// <exception cref="BadImageFormatException">The format of the PE image or the source PDB image is invalid.</exception>
 /// <exception cref="InvalidDataException">The PDB doesn't match the CodeView Debug Directory record in the PE image.</exception>
 /// <exception cref="IOException">IO error while reading from or writing to a stream.</exception>
 public void ConvertPortableToWindows(PEReader peReader, MetadataReader pdbReader, SymUnmanagedWriter pdbWriter, PortablePdbConversionOptions options = null)
 {
     new PdbConverterPortableToWindows(_diagnosticReporterOpt).Convert(
         peReader ?? throw new ArgumentNullException(nameof(peReader)),
         pdbReader ?? throw new ArgumentNullException(nameof(pdbReader)),
         pdbWriter ?? throw new ArgumentNullException(nameof(pdbWriter)),
         options ?? PortablePdbConversionOptions.Default);
 }
        /// <summary>
        /// Converts Portable PDB to Windows PDB.
        /// </summary>
        /// <param name="peReader">PE reader.</param>
        /// <param name="pdbReader">Portable PDB reader.</param>
        /// <param name="targetPdbStream">Target stream of Windows PDB data. Must be writable.</param>
        /// <param name="options">Conversion options.</param>
        /// <exception cref="ArgumentNullException"><paramref name="peReader"/>, <paramref name="pdbReader"/>, or <paramref name="targetPdbStream"/> is null.</exception>
        /// <exception cref="ArgumentException"><paramref name="targetPdbStream"/> does not support writing.</exception>
        /// <exception cref="BadImageFormatException">The format of the PE image or the source PDB image is invalid.</exception>
        /// <exception cref="InvalidDataException">The PDB doesn't match the CodeView Debug Directory record in the PE image.</exception>
        /// <exception cref="IOException">IO error while reading from or writing to a stream.</exception>
        /// <exception cref="ObjectDisposedException">Stream has been disposed while reading/writing.</exception>
        public void ConvertPortableToWindows(PEReader peReader, MetadataReader pdbReader, Stream targetPdbStream, PortablePdbConversionOptions options = null)
        {
            if (pdbReader == null)
            {
                throw new ArgumentNullException(nameof(pdbReader));
            }

            StreamUtilities.ValidateStream(targetPdbStream, nameof(targetPdbStream), writeRequired: true);

            using (var pdbWriter = SymUnmanagedWriterFactory.CreateWriter(new SymMetadataProvider(peReader.GetMetadataReader())))
            {
                ConvertPortableToWindows(peReader, pdbReader, pdbWriter, options);
                pdbWriter.WriteTo(targetPdbStream);
            }
        }
        /// <summary>
        /// Converts Portable PDB stream to Windows PDB.
        /// </summary>
        /// <param name="peReader">PE reader.</param>
        /// <param name="sourcePdbStream">Source stream of Portable PDB data. Must be readable.</param>
        /// <param name="targetPdbStream">Target stream of Windows PDB data. Must be writable.</param>
        /// <param name="options">Conversion options.</param>
        /// <exception cref="ArgumentNullException"><paramref name="peReader"/>, <paramref name="sourcePdbStream"/>, or <paramref name="targetPdbStream"/> is null.</exception>
        /// <exception cref="ArgumentException"><paramref name="sourcePdbStream"/> does not support reading.</exception>
        /// <exception cref="ArgumentException"><paramref name="targetPdbStream"/> does not support writing.</exception>
        /// <exception cref="BadImageFormatException">The format of the PE image or the source PDB image is invalid.</exception>
        /// <exception cref="InvalidDataException">The PDB doesn't match the CodeView Debug Directory record in the PE image.</exception>
        /// <exception cref="IOException">IO error while reading from or writing to a stream.</exception>
        /// <exception cref="ObjectDisposedException">Stream has been disposed while reading/writing.</exception>
        public void ConvertPortableToWindows(PEReader peReader, Stream sourcePdbStream, Stream targetPdbStream, PortablePdbConversionOptions options = null)
        {
            StreamUtilities.ValidateStream(sourcePdbStream, nameof(sourcePdbStream), readRequired: true);

            using (var pdbReaderProvider = MetadataReaderProvider.FromPortablePdbStream(sourcePdbStream, MetadataStreamOptions.LeaveOpen))
            {
                ConvertPortableToWindows(peReader, pdbReaderProvider.GetMetadataReader(), targetPdbStream, options);
            }
        }
 /// <summary>
 /// Converts Portable PDB stream to Windows PDB.
 /// </summary>
 /// <param name="peStream">PE image stream (.dll or .exe)</param>
 /// <param name="sourcePdbStream">Source stream of Portable PDB data. Must be readable.</param>
 /// <param name="targetPdbStream">Target stream of Windows PDB data. Must be writable.</param>
 /// <param name="options">Conversion options.</param>
 /// <exception cref="ArgumentNullException"><paramref name="peStream"/>, <paramref name="sourcePdbStream"/>, or <paramref name="targetPdbStream"/> is null.</exception>
 /// <exception cref="ArgumentException"><paramref name="peStream"/> does not support read and seek operations.</exception>
 /// <exception cref="ArgumentException"><paramref name="sourcePdbStream"/> does not support reading.</exception>
 /// <exception cref="ArgumentException"><paramref name="targetPdbStream"/> does not support writing.</exception>
 /// <exception cref="BadImageFormatException">The format of the PE image or the source PDB image is invalid.</exception>
 /// <exception cref="InvalidDataException">The PDB doesn't match the CodeView Debug Directory record in the PE image.</exception>
 /// <exception cref="IOException">IO error while reading from or writing to a stream.</exception>
 /// <exception cref="ObjectDisposedException">Stream has been disposed while reading/writing.</exception>
 public void ConvertPortableToWindows(Stream peStream, Stream sourcePdbStream, Stream targetPdbStream, PortablePdbConversionOptions options = null)
 {
     StreamUtilities.ValidateStream(peStream, nameof(peStream), readRequired: true, seekRequired: true);
     using (var peReader = new PEReader(peStream, PEStreamOptions.LeaveOpen))
     {
         ConvertPortableToWindows(peReader, sourcePdbStream, targetPdbStream, options);
     }
 }
Beispiel #9
0
 public Args(string peFilePath, string?pdbFilePath, string?outPdbFilePath, PortablePdbConversionOptions options, ImmutableArray <PdbDiagnosticId> suppressedWarnings, bool suppressAllWarnings, bool extract)
 {
     PEFilePath          = peFilePath;
     PdbFilePath         = pdbFilePath;
     OutPdbFilePath      = outPdbFilePath;
     Options             = options;
     Extract             = extract;
     SuppressAllWarnings = suppressAllWarnings;
     SuppressedWarnings  = suppressedWarnings;
 }