Exemple #1
0
            // Marshal operations

            private IntPtr MarshalPOD(PatchOptionData managed)
            {
                if (null == managed)
                {
                    throw new ArgumentNullException("managed");
                }

                IntPtr native = this.CreateMainStruct(managed.oldFileSymbolPathArray.Length);

                Marshal.WriteInt32(native, patchOptionDataSize); // SizeOfThisStruct
                WriteUInt32(native, symbolOptionFlagsOffset, (uint)managed.symbolOptionFlags);
                Marshal.WriteIntPtr(native, newFileSymbolPathOffset, PatchAPIMarshaler.OptionalAnsiString(managed.newFileSymbolPath));
                Marshal.WriteIntPtr(native, oldFileSymbolPathArrayOffset, PatchAPIMarshaler.CreateArrayOfStringA(managed.oldFileSymbolPathArray));
                WriteUInt32(native, extendedOptionFlagsOffset, managed.extendedOptionFlags);

                // GetFunctionPointerForDelegate() throws an ArgumentNullException if the delegate is null.
                if (null == managed.symLoadCallback)
                {
                    Marshal.WriteIntPtr(native, symLoadCallbackOffset, IntPtr.Zero);
                }
                else
                {
                    Marshal.WriteIntPtr(native, symLoadCallbackOffset, Marshal.GetFunctionPointerForDelegate(managed.symLoadCallback));
                }

                Marshal.WriteIntPtr(native, symLoadContextOffset, managed.symLoadContext);
                Marshal.WriteIntPtr(native, interleaveMapArrayOffset, PatchAPIMarshaler.CreateInterleaveMap(managed.interleaveMapArray));
                WriteUInt32(native, maxLzxWindowSizeOffset, managed.maxLzxWindowSize);
                return(native);
            }
Exemple #2
0
 internal static extern bool CreatePatchFileExW(
     uint oldFileCount,          // maximum 255
     [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PatchAPIMarshaler), MarshalCookie = "PATCH_OLD_FILE_INFO_W")]
     PatchOldFileInfoW[] oldFileInfoArray,
     string newFileName,         // input file  (required)
     string patchFileName,       // output file (required)
     uint optionFlags,
     [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PatchAPIMarshaler), MarshalCookie = "PATCH_OPTION_DATA")]
     PatchOptionData optionData,
     [MarshalAs(UnmanagedType.FunctionPtr)]
     PatchProgressCallback progressCallback,
     IntPtr context
     );
Exemple #3
0
        /// <summary>
        /// Create a binary delta file.
        /// </summary>
        /// <param name="deltaFile">Name of the delta file to create.</param>
        /// <param name="targetFile">Name of updated file.</param>
        /// <param name="targetSymbolPath">Optional paths to updated file's symbols.</param>
        /// <param name="targetRetainOffsets">Optional offsets to the delta retain sections in the updated file.</param>
        /// <param name="basisFiles">Optional array of target files.</param>
        /// <param name="basisSymbolPaths">Optional array of target files' symbol paths (must match basisFiles array).</param>
        /// <param name="basisIgnoreLengths">Optional array of target files' delta ignore section lengths (must match basisFiles array)(each entry must match basisIgnoreOffsets entries).</param>
        /// <param name="basisIgnoreOffsets">Optional array of target files' delta ignore section offsets (must match basisFiles array)(each entry must match basisIgnoreLengths entries).</param>
        /// <param name="basisRetainLengths">Optional array of target files' delta protect section lengths (must match basisFiles array)(each entry must match basisRetainOffsets and targetRetainOffsets entries).</param>
        /// <param name="basisRetainOffsets">Optional array of target files' delta protect section offsets (must match basisFiles array)(each entry must match basisRetainLengths and targetRetainOffsets entries).</param>
        /// <param name="apiPatchingSymbolFlags">ApiPatchingSymbolFlags value.</param>
        /// <param name="optimizePatchSizeForLargeFiles">OptimizePatchSizeForLargeFiles value.</param>
        /// <param name="retainRangesIgnored">Flag to indicate retain ranges were ignored due to mismatch.</param>
        /// <returns>true if delta file was created, false if whole file should be used instead.</returns>
        static public bool CreateDelta(
            string deltaFile,
            string targetFile,
            string targetSymbolPath,
            string targetRetainOffsets,
            string[] basisFiles,
            string[] basisSymbolPaths,
            string[] basisIgnoreLengths,
            string[] basisIgnoreOffsets,
            string[] basisRetainLengths,
            string[] basisRetainOffsets,
            PatchSymbolFlagsType apiPatchingSymbolFlags,
            bool optimizePatchSizeForLargeFiles,
            out bool retainRangesIgnored
            )
        {
            retainRangesIgnored = false;
            if (0 != (apiPatchingSymbolFlags & ~(PatchSymbolFlagsType.PATCH_SYMBOL_NO_IMAGEHLP | PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES | PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO)))
            {
                throw new ArgumentOutOfRangeException("apiPatchingSymbolFlags");
            }

            if (null == deltaFile || 0 == deltaFile.Length)
            {
                throw new ArgumentNullException("deltaFile");
            }

            if (null == targetFile || 0 == targetFile.Length)
            {
                throw new ArgumentNullException("targetFile");
            }

            if (null == basisFiles || 0 == basisFiles.Length)
            {
                return(false);
            }
            uint countOldFiles = (uint)basisFiles.Length;

            if (null != basisSymbolPaths)
            {
                if (0 != basisSymbolPaths.Length)
                {
                    if ((uint)basisSymbolPaths.Length != countOldFiles)
                    {
                        throw new ArgumentOutOfRangeException("basisSymbolPaths");
                    }
                }
            }
            // a null basisSymbolPaths is allowed.

            if (null != basisIgnoreLengths)
            {
                if (0 != basisIgnoreLengths.Length)
                {
                    if ((uint)basisIgnoreLengths.Length != countOldFiles)
                    {
                        throw new ArgumentOutOfRangeException("basisIgnoreLengths");
                    }
                }
            }
            else
            {
                basisIgnoreLengths = new string[countOldFiles];
            }

            if (null != basisIgnoreOffsets)
            {
                if (0 != basisIgnoreOffsets.Length)
                {
                    if ((uint)basisIgnoreOffsets.Length != countOldFiles)
                    {
                        throw new ArgumentOutOfRangeException("basisIgnoreOffsets");
                    }
                }
            }
            else
            {
                basisIgnoreOffsets = new string[countOldFiles];
            }

            if (null != basisRetainLengths)
            {
                if (0 != basisRetainLengths.Length)
                {
                    if ((uint)basisRetainLengths.Length != countOldFiles)
                    {
                        throw new ArgumentOutOfRangeException("basisRetainLengths");
                    }
                }
            }
            else
            {
                basisRetainLengths = new string[countOldFiles];
            }

            if (null != basisRetainOffsets)
            {
                if (0 != basisRetainOffsets.Length)
                {
                    if ((uint)basisRetainOffsets.Length != countOldFiles)
                    {
                        throw new ArgumentOutOfRangeException("basisRetainOffsets");
                    }
                }
            }
            else
            {
                basisRetainOffsets = new string[countOldFiles];
            }

            PatchOptionData pod = new PatchOptionData();

            pod.symbolOptionFlags      = apiPatchingSymbolFlags;
            pod.newFileSymbolPath      = targetSymbolPath;
            pod.oldFileSymbolPathArray = basisSymbolPaths;
            pod.extendedOptionFlags    = 0;
            PatchOldFileInfoW[] oldFileInfoArray     = new PatchOldFileInfoW[countOldFiles];
            string[]            newRetainOffsetArray = ((null == targetRetainOffsets) ? new string[0] : targetRetainOffsets.Split(','));
            for (uint i = 0; i < countOldFiles; ++i)
            {
                PatchOldFileInfoW ofi = new PatchOldFileInfoW();
                ofi.oldFileName = basisFiles[i];
                string[] ignoreLengthArray = ((null == basisIgnoreLengths[i]) ? new string[0] : basisIgnoreLengths[i].Split(','));
                string[] ignoreOffsetArray = ((null == basisIgnoreOffsets[i]) ? new string[0] : basisIgnoreOffsets[i].Split(','));
                string[] retainLengthArray = ((null == basisRetainLengths[i]) ? new string[0] : basisRetainLengths[i].Split(','));
                string[] retainOffsetArray = ((null == basisRetainOffsets[i]) ? new string[0] : basisRetainOffsets[i].Split(','));
                // Validate inputs
                if (ignoreLengthArray.Length != ignoreOffsetArray.Length)
                {
                    throw new ArgumentOutOfRangeException("basisIgnoreLengths");
                }

                if (retainLengthArray.Length != retainOffsetArray.Length)
                {
                    throw new ArgumentOutOfRangeException("basisRetainLengths");
                }

                if (newRetainOffsetArray.Length != retainOffsetArray.Length)
                {
                    // remove all retain range information
                    retainRangesIgnored = true;
                    for (uint j = 0; j < countOldFiles; ++j)
                    {
                        basisRetainLengths[j] = null;
                        basisRetainOffsets[j] = null;
                    }
                    retainLengthArray    = new string[0];
                    retainOffsetArray    = new string[0];
                    newRetainOffsetArray = new string[0];
                    for (uint j = 0; j < oldFileInfoArray.Length; ++j)
                    {
                        oldFileInfoArray[j].retainRange = null;
                    }
                }

                // Populate IgnoreRange structure
                PatchIgnoreRange[] ignoreArray = null;
                if (0 != ignoreLengthArray.Length)
                {
                    ignoreArray = new PatchIgnoreRange[ignoreLengthArray.Length];
                    for (int j = 0; j < ignoreLengthArray.Length; ++j)
                    {
                        PatchIgnoreRange ignoreRange = new PatchIgnoreRange();
                        ignoreRange.offsetInOldFile = ParseHexOrDecimal(ignoreOffsetArray[j]);
                        ignoreRange.lengthInBytes   = ParseHexOrDecimal(ignoreLengthArray[j]);
                        ignoreArray[j] = ignoreRange;
                    }
                    ofi.ignoreRange = ignoreArray;
                }

                PatchRetainRange[] retainArray = null;
                if (0 != newRetainOffsetArray.Length)
                {
                    retainArray = new PatchRetainRange[retainLengthArray.Length];
                    for (int j = 0; j < newRetainOffsetArray.Length; ++j)
                    {
                        PatchRetainRange retainRange = new PatchRetainRange();
                        retainRange.offsetInOldFile = ParseHexOrDecimal(retainOffsetArray[j]);
                        retainRange.lengthInBytes   = ParseHexOrDecimal(retainLengthArray[j]);
                        retainRange.offsetInNewFile = ParseHexOrDecimal(newRetainOffsetArray[j]);
                        retainArray[j] = retainRange;
                    }
                    ofi.retainRange = retainArray;
                }
                oldFileInfoArray[i] = ofi;
            }

            if (CreatePatchFileExW(
                    countOldFiles,
                    oldFileInfoArray,
                    targetFile,
                    deltaFile,
                    PatchOptionFlags(optimizePatchSizeForLargeFiles),
                    pod,
                    null,
                    IntPtr.Zero))
            {
                return(true);
            }

            // determine if this is an error or a need to use whole file.
            int err = Marshal.GetLastWin32Error();

            switch (err)
            {
            case unchecked ((int)ERROR_PATCH_BIGGER_THAN_COMPRESSED):
                break;

            // too late to exclude this file -- should have been caught before
            case unchecked ((int)ERROR_PATCH_SAME_FILE):
            default:
                throw new System.ComponentModel.Win32Exception(err);
            }
            return(false);
        }