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
);
44 /*****************************************************
45 * DllMain (MSPATCHA.@)
47 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
49 TRACE("(0x%p, %d, %p)\n", hinstDLL
, fdwReason
, lpvReserved
);
53 case DLL_WINE_PREATTACH
:
54 return FALSE
; /* prefer native version */
55 case DLL_PROCESS_ATTACH
:
56 DisableThreadLibraryCalls(hinstDLL
);
63 static WCHAR
*strdupAW(const char *src
)
68 int len
= MultiByteToWideChar(CP_ACP
, 0, src
, -1, NULL
, 0);
69 if ((dst
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
))))
70 MultiByteToWideChar(CP_ACP
, 0, src
, -1, dst
, len
);
75 /*****************************************************
76 * TestApplyPatchToFileA (MSPATCHA.@)
78 BOOL WINAPI
TestApplyPatchToFileA(LPCSTR patch_file
, LPCSTR old_file
, ULONG apply_flags
)
81 WCHAR
*patch_fileW
, *old_fileW
= NULL
;
83 if (!(patch_fileW
= strdupAW(patch_file
))) return FALSE
;
84 if (old_file
&& !(old_fileW
= strdupAW(old_file
)))
86 HeapFree(GetProcessHeap(), 0, patch_fileW
);
89 ret
= apply_patch_to_file(patch_fileW
, old_fileW
, NULL
, apply_flags
, NULL
, NULL
, TRUE
);
90 HeapFree(GetProcessHeap(), 0, patch_fileW
);
91 HeapFree(GetProcessHeap(), 0, old_fileW
);
95 BOOL WINAPI
TestApplyPatchToFileW(LPCWSTR patch_file_name
, LPCWSTR old_file_name
, ULONG apply_option_flags
)
97 return apply_patch_to_file(patch_file_name
, old_file_name
, NULL
, apply_option_flags
, NULL
, NULL
, TRUE
);
100 BOOL WINAPI
TestApplyPatchToFileByHandles(HANDLE patch_file_hndl
, HANDLE old_file_hndl
, ULONG apply_option_flags
)
102 return apply_patch_to_file_by_handles(patch_file_hndl
, old_file_hndl
, NULL
,
103 apply_option_flags
, NULL
, NULL
, TRUE
);
106 BOOL WINAPI
TestApplyPatchToFileByBuffers(BYTE
*patch_file_buf
, ULONG patch_file_size
,
107 BYTE
*old_file_buf
, ULONG old_file_size
,
108 ULONG
* new_file_size
,
109 ULONG apply_option_flags
)
111 /* NOTE: windows preserves last error on success for this function, but no apps are known to depend on it */
113 DWORD err
= apply_patch_to_file_by_buffers(patch_file_buf
, patch_file_size
,
114 old_file_buf
, old_file_size
,
115 NULL
, 0, new_file_size
, NULL
,
122 return err
== ERROR_SUCCESS
;
125 /*****************************************************
126 * ApplyPatchToFileExA (MSPATCHA.@)
128 BOOL WINAPI
ApplyPatchToFileExA(LPCSTR patch_file
, LPCSTR old_file
, LPCSTR new_file
, ULONG apply_flags
,
129 PPATCH_PROGRESS_CALLBACK progress_fn
, PVOID progress_ctx
)
132 WCHAR
*patch_fileW
, *new_fileW
, *old_fileW
= NULL
;
134 if (!(patch_fileW
= strdupAW(patch_file
))) return FALSE
;
136 if (old_file
&& !(old_fileW
= strdupAW(old_file
)))
139 if (!(new_fileW
= strdupAW(new_file
)))
142 ret
= apply_patch_to_file(patch_fileW
, old_fileW
, new_fileW
, apply_flags
, progress_fn
, progress_ctx
, FALSE
);
144 HeapFree(GetProcessHeap(), 0, new_fileW
);
146 HeapFree(GetProcessHeap(), 0, patch_fileW
);
147 HeapFree(GetProcessHeap(), 0, old_fileW
);
151 /*****************************************************
152 * ApplyPatchToFileA (MSPATCHA.@)
154 BOOL WINAPI
ApplyPatchToFileA(LPCSTR patch_file
, LPCSTR old_file
, LPCSTR new_file
, ULONG apply_flags
)
156 return ApplyPatchToFileExA(patch_file
, old_file
, new_file
, apply_flags
, NULL
, NULL
);
159 /*****************************************************
160 * ApplyPatchToFileW (MSPATCHA.@)
162 BOOL WINAPI
ApplyPatchToFileW(LPCWSTR patch_file_name
, LPCWSTR old_file_name
, LPCWSTR new_file_name
,
163 ULONG apply_option_flags
)
165 return apply_patch_to_file(patch_file_name
, old_file_name
, new_file_name
, apply_option_flags
,
169 /*****************************************************
170 * ApplyPatchToFileByHandles (MSPATCHA.@)
172 BOOL WINAPI
ApplyPatchToFileByHandles(HANDLE patch_file_hndl
, HANDLE old_file_hndl
, HANDLE new_file_hndl
,
173 ULONG apply_option_flags
)
175 return apply_patch_to_file_by_handles(patch_file_hndl
, old_file_hndl
, new_file_hndl
,
176 apply_option_flags
, NULL
, NULL
, FALSE
);
179 /*****************************************************
180 * ApplyPatchToFileExW (MSPATCHA.@)
182 BOOL WINAPI
ApplyPatchToFileExW(LPCWSTR patch_file_name
, LPCWSTR old_file_name
, LPCWSTR new_file_name
,
183 ULONG apply_option_flags
,
184 PPATCH_PROGRESS_CALLBACK progress_fn
, PVOID progress_ctx
)
186 return apply_patch_to_file(patch_file_name
, old_file_name
, new_file_name
, apply_option_flags
,
187 progress_fn
, progress_ctx
, FALSE
);
190 /*****************************************************
191 * ApplyPatchToFileByHandlesEx (MSPATCHA.@)
193 BOOL WINAPI
ApplyPatchToFileByHandlesEx(HANDLE patch_file_hndl
, HANDLE old_file_hndl
, HANDLE new_file_hndl
,
194 ULONG apply_option_flags
,
195 PPATCH_PROGRESS_CALLBACK progress_fn
,
198 return apply_patch_to_file_by_handles(patch_file_hndl
, old_file_hndl
, new_file_hndl
,
199 apply_option_flags
, progress_fn
, progress_ctx
, FALSE
);
202 /*****************************************************
203 * ApplyPatchToFileByBuffers (MSPATCHA.@)
205 BOOL WINAPI
ApplyPatchToFileByBuffers(PBYTE patch_file_view
, ULONG patch_file_size
,
206 PBYTE old_file_view
, ULONG old_file_size
,
207 PBYTE
* new_file_buf
, ULONG new_file_buf_size
, ULONG
* new_file_size
,
208 FILETIME
* new_file_time
,
209 ULONG apply_option_flags
,
210 PPATCH_PROGRESS_CALLBACK progress_fn
, PVOID progress_ctx
)
212 /* NOTE: windows preserves last error on success for this function, but no apps are known to depend on it */
214 DWORD err
= apply_patch_to_file_by_buffers(patch_file_view
, patch_file_size
,
215 old_file_view
, old_file_size
,
216 new_file_buf
, new_file_buf_size
, new_file_size
, new_file_time
,
218 progress_fn
, progress_ctx
,
223 return err
== ERROR_SUCCESS
;
226 /*****************************************************
227 * GetFilePatchSignatureA (MSPATCHA.@)
229 BOOL WINAPI
GetFilePatchSignatureA(LPCSTR filename
, ULONG flags
, PVOID data
, ULONG ignore_range_count
,
230 PPATCH_IGNORE_RANGE ignore_range
, ULONG retain_range_count
,
231 PPATCH_RETAIN_RANGE retain_range
, ULONG bufsize
, LPSTR buffer
)
233 FIXME("stub - %s, %x, %p, %u, %p, %u, %p, %u, %p\n", debugstr_a(filename
), flags
, data
,
234 ignore_range_count
, ignore_range
, retain_range_count
, retain_range
, bufsize
, buffer
);
235 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
239 /*****************************************************
240 * GetFilePatchSignatureW (MSPATCHA.@)
242 BOOL WINAPI
GetFilePatchSignatureW(LPCWSTR filename
, ULONG flags
, PVOID data
, ULONG ignore_range_count
,
243 PPATCH_IGNORE_RANGE ignore_range
, ULONG retain_range_count
,
244 PPATCH_RETAIN_RANGE retain_range
, ULONG bufsize
, LPWSTR buffer
)
246 FIXME("stub - %s, %x, %p, %u, %p, %u, %p, %u, %p\n", debugstr_w(filename
), flags
, data
,
247 ignore_range_count
, ignore_range
, retain_range_count
, retain_range
, bufsize
, buffer
);
248 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
252 /*****************************************************
253 * GetFilePatchSignatureByHandle (MSPATCHA.@)
255 BOOL WINAPI
GetFilePatchSignatureByHandle(HANDLE handle
, ULONG flags
, PVOID options
, ULONG ignore_range_count
,
256 PPATCH_IGNORE_RANGE ignore_range
, ULONG retain_range_count
,
257 PPATCH_RETAIN_RANGE retain_range
, ULONG bufsize
, LPSTR buffer
)
259 FIXME("stub - %p, %x, %p, %u, %p, %u, %p, %u, %p\n", handle
, flags
, options
,
260 ignore_range_count
, ignore_range
, retain_range_count
, retain_range
, bufsize
, buffer
);
261 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
265 /*****************************************************
266 * GetFilePatchSignatureByBuffer (MSPATCHA.@)
268 BOOL WINAPI
GetFilePatchSignatureByBuffer(PBYTE file_buf
, ULONG file_size
, ULONG flags
, PVOID options
,
269 ULONG ignore_range_count
, PPATCH_IGNORE_RANGE ignore_range
,
270 ULONG retain_range_count
, PPATCH_RETAIN_RANGE retain_range
,
271 ULONG bufsize
, LPSTR buffer
)
273 FIXME("stub - %p, %u, %x, %p, %u, %p, %u, %p, %u, %p\n", file_buf
, file_size
, flags
, options
,
274 ignore_range_count
, ignore_range
, retain_range_count
, retain_range
, bufsize
, buffer
);
275 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
279 /*****************************************************
280 * NormalizeFileForPatchSignature (MSPATCHA.@)
282 INT WINAPI
NormalizeFileForPatchSignature(PVOID file_buffer
, ULONG file_size
, ULONG flags
, PATCH_OPTION_DATA
*options
,
283 ULONG new_coff_base
, ULONG new_coff_time
, ULONG ignore_range_count
, PPATCH_IGNORE_RANGE ignore_range
,
284 ULONG retain_range_count
, PPATCH_RETAIN_RANGE retain_range
)
286 FIXME("stub - %p, %u, %x, %p, %u, %u, %u, %p, %u, %p\n", file_buffer
, file_size
, flags
, options
, new_coff_base
,
287 new_coff_time
, ignore_range_count
, ignore_range
, retain_range_count
, retain_range
);
288 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);