ntdll/tests: Adjust test_virtual_unwind() for Win11 results.
[wine.git] / dlls / mspatcha / mspatcha_main.c
blob1f6653da1613e240f71f98b91ce5987ab69ee515
1 /*
2 * PatchAPI
4 * Copyright 2011 David Hedberg for CodeWeavers
5 * Copyright 2019 Conor McCarthy (implementations)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * TODO
22 * - Special processing of 32-bit executables is not supported, so this
23 * version cannot patch 32-bit .exe and .dll files. See pa19.c for details.
24 * - Implement interleaved decoding when PATCH_OPTION_INTERLEAVE_FILES was
25 * used or the old file exceeds the lzxd window size.
26 * - APPLY_OPTION_FAIL_IF_CLOSE is ignored. Normalization of 32-bit PE files
27 * is required for checking this.
28 * - GetFilePatchSignature* and NormalizeFileForPatchSignature require a
29 * solution to the above 32-bit exe problem.
32 #include <stdarg.h>
34 #include "windef.h"
35 #include "winbase.h"
36 #include "winnls.h"
37 #include "patchapi.h"
38 #include "wine/debug.h"
40 #include "pa19.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(mspatcha);
45 static WCHAR *strdupAW(const char *src)
47 WCHAR *dst = NULL;
48 if (src)
50 int len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
51 if ((dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
52 MultiByteToWideChar(CP_ACP, 0, src, -1, dst, len);
54 return dst;
57 /*****************************************************
58 * TestApplyPatchToFileA (MSPATCHA.@)
60 BOOL WINAPI TestApplyPatchToFileA(LPCSTR patch_file, LPCSTR old_file, ULONG apply_flags)
62 BOOL ret;
63 WCHAR *patch_fileW, *old_fileW = NULL;
65 if (!(patch_fileW = strdupAW(patch_file))) return FALSE;
66 if (old_file && !(old_fileW = strdupAW(old_file)))
68 HeapFree(GetProcessHeap(), 0, patch_fileW);
69 return FALSE;
71 ret = apply_patch_to_file(patch_fileW, old_fileW, NULL, apply_flags, NULL, NULL, TRUE);
72 HeapFree(GetProcessHeap(), 0, patch_fileW);
73 HeapFree(GetProcessHeap(), 0, old_fileW);
74 return ret;
77 BOOL WINAPI TestApplyPatchToFileW(LPCWSTR patch_file_name, LPCWSTR old_file_name, ULONG apply_option_flags)
79 return apply_patch_to_file(patch_file_name, old_file_name, NULL, apply_option_flags, NULL, NULL, TRUE);
82 BOOL WINAPI TestApplyPatchToFileByHandles(HANDLE patch_file_hndl, HANDLE old_file_hndl, ULONG apply_option_flags)
84 return apply_patch_to_file_by_handles(patch_file_hndl, old_file_hndl, NULL,
85 apply_option_flags, NULL, NULL, TRUE);
88 BOOL WINAPI TestApplyPatchToFileByBuffers(BYTE *patch_file_buf, ULONG patch_file_size,
89 BYTE *old_file_buf, ULONG old_file_size,
90 ULONG* new_file_size,
91 ULONG apply_option_flags)
93 /* NOTE: windows preserves last error on success for this function, but no apps are known to depend on it */
95 DWORD err = apply_patch_to_file_by_buffers(patch_file_buf, patch_file_size,
96 old_file_buf, old_file_size,
97 NULL, 0, new_file_size, NULL,
98 apply_option_flags,
99 NULL, NULL,
100 TRUE);
102 SetLastError(err);
104 return err == ERROR_SUCCESS;
107 /*****************************************************
108 * ApplyPatchToFileExA (MSPATCHA.@)
110 BOOL WINAPI ApplyPatchToFileExA(LPCSTR patch_file, LPCSTR old_file, LPCSTR new_file, ULONG apply_flags,
111 PPATCH_PROGRESS_CALLBACK progress_fn, PVOID progress_ctx)
113 BOOL ret = FALSE;
114 WCHAR *patch_fileW, *new_fileW, *old_fileW = NULL;
116 if (!(patch_fileW = strdupAW(patch_file))) return FALSE;
118 if (old_file && !(old_fileW = strdupAW(old_file)))
119 goto free_wstrs;
121 if (!(new_fileW = strdupAW(new_file)))
122 goto free_wstrs;
124 ret = apply_patch_to_file(patch_fileW, old_fileW, new_fileW, apply_flags, progress_fn, progress_ctx, FALSE);
126 HeapFree(GetProcessHeap(), 0, new_fileW);
127 free_wstrs:
128 HeapFree(GetProcessHeap(), 0, patch_fileW);
129 HeapFree(GetProcessHeap(), 0, old_fileW);
130 return ret;
133 /*****************************************************
134 * ApplyPatchToFileA (MSPATCHA.@)
136 BOOL WINAPI ApplyPatchToFileA(LPCSTR patch_file, LPCSTR old_file, LPCSTR new_file, ULONG apply_flags)
138 return ApplyPatchToFileExA(patch_file, old_file, new_file, apply_flags, NULL, NULL);
141 /*****************************************************
142 * ApplyPatchToFileW (MSPATCHA.@)
144 BOOL WINAPI ApplyPatchToFileW(LPCWSTR patch_file_name, LPCWSTR old_file_name, LPCWSTR new_file_name,
145 ULONG apply_option_flags)
147 return apply_patch_to_file(patch_file_name, old_file_name, new_file_name, apply_option_flags,
148 NULL, NULL, FALSE);
151 /*****************************************************
152 * ApplyPatchToFileByHandles (MSPATCHA.@)
154 BOOL WINAPI ApplyPatchToFileByHandles(HANDLE patch_file_hndl, HANDLE old_file_hndl, HANDLE new_file_hndl,
155 ULONG apply_option_flags)
157 return apply_patch_to_file_by_handles(patch_file_hndl, old_file_hndl, new_file_hndl,
158 apply_option_flags, NULL, NULL, FALSE);
161 /*****************************************************
162 * ApplyPatchToFileExW (MSPATCHA.@)
164 BOOL WINAPI ApplyPatchToFileExW(LPCWSTR patch_file_name, LPCWSTR old_file_name, LPCWSTR new_file_name,
165 ULONG apply_option_flags,
166 PPATCH_PROGRESS_CALLBACK progress_fn, PVOID progress_ctx)
168 return apply_patch_to_file(patch_file_name, old_file_name, new_file_name, apply_option_flags,
169 progress_fn, progress_ctx, FALSE);
172 /*****************************************************
173 * ApplyPatchToFileByHandlesEx (MSPATCHA.@)
175 BOOL WINAPI ApplyPatchToFileByHandlesEx(HANDLE patch_file_hndl, HANDLE old_file_hndl, HANDLE new_file_hndl,
176 ULONG apply_option_flags,
177 PPATCH_PROGRESS_CALLBACK progress_fn,
178 PVOID progress_ctx)
180 return apply_patch_to_file_by_handles(patch_file_hndl, old_file_hndl, new_file_hndl,
181 apply_option_flags, progress_fn, progress_ctx, FALSE);
184 /*****************************************************
185 * ApplyPatchToFileByBuffers (MSPATCHA.@)
187 BOOL WINAPI ApplyPatchToFileByBuffers(PBYTE patch_file_view, ULONG patch_file_size,
188 PBYTE old_file_view, ULONG old_file_size,
189 PBYTE* new_file_buf, ULONG new_file_buf_size, ULONG* new_file_size,
190 FILETIME* new_file_time,
191 ULONG apply_option_flags,
192 PPATCH_PROGRESS_CALLBACK progress_fn, PVOID progress_ctx)
194 /* NOTE: windows preserves last error on success for this function, but no apps are known to depend on it */
196 DWORD err = apply_patch_to_file_by_buffers(patch_file_view, patch_file_size,
197 old_file_view, old_file_size,
198 new_file_buf, new_file_buf_size, new_file_size, new_file_time,
199 apply_option_flags,
200 progress_fn, progress_ctx,
201 FALSE);
203 SetLastError(err);
205 return err == ERROR_SUCCESS;
208 /*****************************************************
209 * GetFilePatchSignatureA (MSPATCHA.@)
211 BOOL WINAPI GetFilePatchSignatureA(LPCSTR filename, ULONG flags, PVOID data, ULONG ignore_range_count,
212 PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count,
213 PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, LPSTR buffer)
215 FIXME("stub - %s, %lx, %p, %lu, %p, %lu, %p, %lu, %p\n", debugstr_a(filename), flags, data,
216 ignore_range_count, ignore_range, retain_range_count, retain_range, bufsize, buffer);
217 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
218 return FALSE;
221 /*****************************************************
222 * GetFilePatchSignatureW (MSPATCHA.@)
224 BOOL WINAPI GetFilePatchSignatureW(LPCWSTR filename, ULONG flags, PVOID data, ULONG ignore_range_count,
225 PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count,
226 PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, LPWSTR buffer)
228 FIXME("stub - %s, %lx, %p, %lu, %p, %lu, %p, %lu, %p\n", debugstr_w(filename), flags, data,
229 ignore_range_count, ignore_range, retain_range_count, retain_range, bufsize, buffer);
230 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
231 return FALSE;
234 /*****************************************************
235 * GetFilePatchSignatureByHandle (MSPATCHA.@)
237 BOOL WINAPI GetFilePatchSignatureByHandle(HANDLE handle, ULONG flags, PVOID options, ULONG ignore_range_count,
238 PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count,
239 PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, LPSTR buffer)
241 FIXME("stub - %p, %lx, %p, %lu, %p, %lu, %p, %lu, %p\n", handle, flags, options,
242 ignore_range_count, ignore_range, retain_range_count, retain_range, bufsize, buffer);
243 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
244 return FALSE;
247 /*****************************************************
248 * GetFilePatchSignatureByBuffer (MSPATCHA.@)
250 BOOL WINAPI GetFilePatchSignatureByBuffer(PBYTE file_buf, ULONG file_size, ULONG flags, PVOID options,
251 ULONG ignore_range_count, PPATCH_IGNORE_RANGE ignore_range,
252 ULONG retain_range_count, PPATCH_RETAIN_RANGE retain_range,
253 ULONG bufsize, LPSTR buffer)
255 FIXME("stub - %p, %lu, %lx, %p, %lu, %p, %lu, %p, %lu, %p\n", file_buf, file_size, flags, options,
256 ignore_range_count, ignore_range, retain_range_count, retain_range, bufsize, buffer);
257 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
258 return FALSE;
261 /*****************************************************
262 * NormalizeFileForPatchSignature (MSPATCHA.@)
264 INT WINAPI NormalizeFileForPatchSignature(PVOID file_buffer, ULONG file_size, ULONG flags, PATCH_OPTION_DATA *options,
265 ULONG new_coff_base, ULONG new_coff_time, ULONG ignore_range_count, PPATCH_IGNORE_RANGE ignore_range,
266 ULONG retain_range_count, PPATCH_RETAIN_RANGE retain_range)
268 FIXME("stub - %p, %lu, %lx, %p, %lu, %lu, %lu, %p, %lu, %p\n", file_buffer, file_size, flags, options, new_coff_base,
269 new_coff_time, ignore_range_count, ignore_range, retain_range_count, retain_range);
270 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
271 return 0;