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
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.
38 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(mspatcha
);
45 static WCHAR
*strdupAW(const char *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
);
57 /*****************************************************
58 * TestApplyPatchToFileA (MSPATCHA.@)
60 BOOL WINAPI
TestApplyPatchToFileA(LPCSTR patch_file
, LPCSTR old_file
, ULONG apply_flags
)
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
);
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
);
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
,
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
,
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
)
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
)))
121 if (!(new_fileW
= strdupAW(new_file
)))
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
);
128 HeapFree(GetProcessHeap(), 0, patch_fileW
);
129 HeapFree(GetProcessHeap(), 0, old_fileW
);
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
,
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
,
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
,
200 progress_fn
, progress_ctx
,
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, %x, %p, %u, %p, %u, %p, %u, %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
);
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, %x, %p, %u, %p, %u, %p, %u, %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
);
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, %x, %p, %u, %p, %u, %p, %u, %p\n", handle
, flags
, options
,
242 ignore_range_count
, ignore_range
, retain_range_count
, retain_range
, bufsize
, buffer
);
243 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
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, %u, %x, %p, %u, %p, %u, %p, %u, %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
);
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, %u, %x, %p, %u, %u, %u, %p, %u, %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
);