private static extern bool asar_patch_ex(ref Rawpatchparams parameters);
/// <summary> /// Applies a patch. /// </summary> /// <param name="patchLocation">The patch location.</param> /// <param name="romData">The rom data. It must not be headered.</param> /// <param name="includePaths">lists additional include paths</param> /// <param name="shouldReset">specifies whether asar should clear out all defines, labels, /// etc from the last inserted file. Setting it to False will make Asar act like the // currently patched file was directly appended to the previous one.</param> /// <param name="additionalDefines">specifies extra defines to give to the patch</param> /// <param name="stdIncludeFile">path to a file that specifes additional include paths</param> /// <param name="stdDefineFile">path to a file that specifes additional defines</param> /// <returns>True if no errors.</returns> public static bool patch(string patchLocation, ref byte[] romData, string[] includePaths = null, bool shouldReset = true, Dictionary <string, string> additionalDefines = null, string stdIncludeFile = null, string stdDefineFile = null) { if (includePaths == null) { includePaths = new string[0]; } if (additionalDefines == null) { additionalDefines = new Dictionary <string, string>(); } var includes = new byte *[includePaths.Length]; var defines = new Rawasardefine[additionalDefines.Count]; try{ for (int i = 0; i < includePaths.Length; i++) { includes[i] = (byte *)Marshal.StringToCoTaskMemAnsi(includePaths[i]); } var keys = additionalDefines.Keys.ToArray(); for (int i = 0; i < additionalDefines.Count; i++) { var name = keys[i]; var value = additionalDefines[name]; defines[i].name = Marshal.StringToCoTaskMemAnsi(name); defines[i].contents = Marshal.StringToCoTaskMemAnsi(value); } int newsize = maxromsize(); int length = romData.Length; if (length < newsize) { Array.Resize(ref romData, newsize); } bool success; fixed(byte *ptr = romData) fixed(byte **includepaths = includes) fixed(Rawasardefine * additional_defines = defines) { var param = new Rawpatchparams { patchloc = patchLocation, romdata = ptr, buflen = newsize, romlen = &length, should_reset = shouldReset, includepaths = includepaths, numincludepaths = includes.Length, additional_defines = additional_defines, additional_define_count = defines.Length, stddefinesfile = stdDefineFile, stdincludesfile = stdIncludeFile }; param.structsize = Marshal.SizeOf(param); success = asar_patch_ex(ref param); } if (length < newsize) { Array.Resize(ref romData, length); } return(success); } finally { for (int i = 0; i < includes.Length; i++) { Marshal.FreeCoTaskMem((IntPtr)includes[i]); } foreach (var define in defines) { Marshal.FreeCoTaskMem(define.name); Marshal.FreeCoTaskMem(define.contents); } } }