[MSPATCHA] Implement GetFilePatchSignature functions
authorMark Jansen <mark.jansen@reactos.org>
Sun, 2 Dec 2018 18:14:16 +0000 (19:14 +0100)
committerMark Jansen <mark.jansen@reactos.org>
Sat, 15 Dec 2018 15:28:59 +0000 (16:28 +0100)
dll/win32/mspatcha/mspatcha.spec
dll/win32/mspatcha/mspatcha_main.c

index 08231e0..cf3d7d6 100644 (file)
@@ -1,12 +1,12 @@
 1 stdcall ApplyPatchToFileA(str str str long)
 1 stdcall ApplyPatchToFileA(str str str long)
-2 stdcall -stub ApplyPatchToFileByHandles(ptr ptr ptr long)
+2 stdcall ApplyPatchToFileByHandles(ptr ptr ptr long)
 3 stub ApplyPatchToFileByHandlesEx
 4 stub ApplyPatchToFileExA
 5 stub ApplyPatchToFileExW
 6 stdcall ApplyPatchToFileW(wstr wstr wstr long)
 7 stdcall GetFilePatchSignatureA(str long ptr long ptr long ptr long ptr)
 3 stub ApplyPatchToFileByHandlesEx
 4 stub ApplyPatchToFileExA
 5 stub ApplyPatchToFileExW
 6 stdcall ApplyPatchToFileW(wstr wstr wstr long)
 7 stdcall GetFilePatchSignatureA(str long ptr long ptr long ptr long ptr)
-8 stdcall -stub GetFilePatchSignatureByHandle(ptr long ptr long ptr long ptr long ptr)
+8 stdcall GetFilePatchSignatureByHandle(ptr long ptr long ptr long ptr long ptr)
 9 stdcall GetFilePatchSignatureW(wstr long ptr long ptr long ptr long ptr)
 9 stdcall GetFilePatchSignatureW(wstr long ptr long ptr long ptr long ptr)
-10 stdcall -stub TestApplyPatchToFileA(str str long)
-11 stdcall -stub TestApplyPatchToFileByHandles(ptr ptr long)
-12 stdcall -stub TestApplyPatchToFileW(wstr wstr long)
+10 stdcall TestApplyPatchToFileA(str str long)
+11 stdcall TestApplyPatchToFileByHandles(ptr ptr long)
+12 stdcall TestApplyPatchToFileW(wstr wstr long)
index 8dc4403..4ad1988 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
-
-#include <stdarg.h>
-
+#define WIN32_NO_STATUS
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
+#include "ndk/rtlfuncs.h"
 #include "patchapi.h"
 #include "wine/debug.h"
 
 #include "patchapi.h"
 #include "wine/debug.h"
 
+static const char szHexString[] = "0123456789abcdef";
+#define SIGNATURE_MIN_SIZE          9
+
 WINE_DEFAULT_DEBUG_CHANNEL(mspatcha);
 
 /*****************************************************
 WINE_DEFAULT_DEBUG_CHANNEL(mspatcha);
 
 /*****************************************************
@@ -49,57 +50,79 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     return TRUE;
 }
 
     return TRUE;
 }
 
-static inline WCHAR *strdupAW( const char *src )
-{
-    WCHAR *dst = NULL;
-    if (src)
-    {
-        int len = MultiByteToWideChar( CP_ACP, 0, src, -1, NULL, 0 );
-        if ((dst = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
-            MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len );
-    }
-    return dst;
-}
-
 /*****************************************************
  *    ApplyPatchToFileA (MSPATCHA.1)
  */
 BOOL WINAPI ApplyPatchToFileA(LPCSTR patch_file, LPCSTR old_file, LPCSTR new_file, ULONG apply_flags)
 {
 /*****************************************************
  *    ApplyPatchToFileA (MSPATCHA.1)
  */
 BOOL WINAPI ApplyPatchToFileA(LPCSTR patch_file, LPCSTR old_file, LPCSTR new_file, ULONG apply_flags)
 {
-    BOOL ret;
-    WCHAR *patch_fileW, *new_fileW, *old_fileW = NULL;
+    BOOL ret = FALSE;
+    HANDLE hPatch, hOld, hNew;
 
 
-    if (!(patch_fileW = strdupAW( patch_file ))) return FALSE;
-    if (old_file && !(old_fileW = strdupAW( old_file )))
+    hPatch = CreateFileA(patch_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                         OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+    if (hPatch != INVALID_HANDLE_VALUE)
     {
     {
-        HeapFree( GetProcessHeap(), 0, patch_fileW );
-        return FALSE;
+        hOld = CreateFileA(old_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                           OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+        if (hOld != INVALID_HANDLE_VALUE)
+        {
+            hNew = CreateFileA(new_file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,
+                               CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+            if (hNew != INVALID_HANDLE_VALUE)
+            {
+                ret = ApplyPatchToFileByHandles(hPatch, hOld, hNew, apply_flags);
+                CloseHandle(hNew);
+            }
+            CloseHandle(hOld);
+        }
+        CloseHandle(hPatch);
     }
     }
-    if (!(new_fileW = strdupAW( new_file )))
-    {
-        HeapFree( GetProcessHeap(), 0, patch_fileW );
-        HeapFree( GetProcessHeap(), 0, old_fileW );
-        return FALSE;
-    }
-    ret = ApplyPatchToFileW( patch_fileW, old_fileW, new_fileW, apply_flags );
-    HeapFree( GetProcessHeap(), 0, patch_fileW );
-    HeapFree( GetProcessHeap(), 0, old_fileW );
-    HeapFree( GetProcessHeap(), 0, new_fileW );
+
     return ret;
 }
 
 /*****************************************************
     return ret;
 }
 
 /*****************************************************
- *    ApplyPatchToFileW (MSPATCHA.6)
+ *    ApplyPatchToFileByHandles (MSPATCHA.2)
  */
  */
-BOOL WINAPI ApplyPatchToFileW(LPCWSTR patch_file, LPCWSTR old_file, LPCWSTR new_file, ULONG apply_flags)
+BOOL WINAPI ApplyPatchToFileByHandles(HANDLE patch_file, HANDLE old_file, HANDLE new_file, ULONG apply_flags)
 {
 {
-    FIXME("stub - %s, %s, %s, %08x\n", debugstr_w(patch_file), debugstr_w(old_file),
-          debugstr_w(new_file), apply_flags);
+    FIXME("stub - %p, %p, %p, %08x\n", patch_file, old_file, new_file, apply_flags);
 
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
 
 
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
 
+/*****************************************************
+ *    ApplyPatchToFileW (MSPATCHA.6)
+ */
+BOOL WINAPI ApplyPatchToFileW(LPCWSTR patch_file, LPCWSTR old_file, LPCWSTR new_file, ULONG apply_flags)
+{
+    BOOL ret = FALSE;
+    HANDLE hPatch, hOld, hNew;
+
+    hPatch = CreateFileW(patch_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                         OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+    if (hPatch != INVALID_HANDLE_VALUE)
+    {
+        hOld = CreateFileW(old_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                           OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+        if (hOld != INVALID_HANDLE_VALUE)
+        {
+            hNew = CreateFileW(new_file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,
+                               CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+            if (hNew != INVALID_HANDLE_VALUE)
+            {
+                ret = ApplyPatchToFileByHandles(hPatch, hOld, hNew, apply_flags);
+                CloseHandle(hNew);
+            }
+            CloseHandle(hOld);
+        }
+        CloseHandle(hPatch);
+    }
+
+    return ret;
+}
+
 /*****************************************************
  *    GetFilePatchSignatureA (MSPATCHA.7)
  */
 /*****************************************************
  *    GetFilePatchSignatureA (MSPATCHA.7)
  */
@@ -107,10 +130,71 @@ BOOL WINAPI GetFilePatchSignatureA(LPCSTR filename, ULONG flags, PVOID data, ULO
                                    PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count,
                                    PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, PVOID buffer)
 {
                                    PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count,
                                    PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, PVOID buffer)
 {
-    FIXME("stub - %s, %x, %p, %u, %p, %u, %p, %u, %p\n", debugstr_a(filename), flags, data,
-          ignore_range_count, ignore_range, retain_range_count, retain_range, bufsize, buffer);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    BOOL ret = FALSE;
+    HANDLE hFile;
+
+    hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                        OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+    if (hFile != INVALID_HANDLE_VALUE)
+    {
+        ret = GetFilePatchSignatureByHandle(hFile, flags, data, ignore_range_count, ignore_range,
+                                            retain_range_count, retain_range, bufsize, buffer);
+        CloseHandle(hFile);
+    }
+
+    return ret;
+}
+
+/*****************************************************
+ *    GetFilePatchSignatureA (MSPATCHA.7)
+ */
+BOOL WINAPI GetFilePatchSignatureByHandle(HANDLE hFile, ULONG flags, PVOID data, ULONG ignore_range_count,
+                                   PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count,
+                                   PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, PVOID buffer)
+{
+    BOOL ret = FALSE;
+    HANDLE hMap;
+    DWORD dwSize, ulCrc;
+    PVOID pView;
+
+    if (flags)
+        FIXME("Unhandled flags 0x%x\n", flags);
+    if (ignore_range_count)
+        FIXME("Unhandled ignore_range_count %u\n", ignore_range_count);
+    if (retain_range_count)
+        FIXME("Unhandled ignore_range_count %u\n", retain_range_count);
+
+    dwSize = GetFileSize(hFile, NULL);
+    hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+    if (hMap != INVALID_HANDLE_VALUE)
+    {
+        pView = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
+        CloseHandle(hMap);
+
+        if (dwSize >= 2 && *(PWORD)pView == IMAGE_DOS_SIGNATURE)
+        {
+            FIXME("Potentially unimplemented case, normalized signature\n");
+        }
+
+        ulCrc = RtlComputeCrc32(0, pView, dwSize);
+        if (bufsize >= SIGNATURE_MIN_SIZE)
+        {
+            char *pBuffer = buffer;
+            pBuffer[8] = '\0';
+            for (dwSize = 0; dwSize < 8; ++dwSize)
+            {
+                pBuffer[7 - dwSize] = szHexString[ulCrc & 0xf];
+                ulCrc >>= 4;
+            }
+            ret = TRUE;
+        }
+        UnmapViewOfFile(pView);
+
+        if (bufsize < SIGNATURE_MIN_SIZE)
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+    }
+
+    return ret;
 }
 
 /*****************************************************
 }
 
 /*****************************************************
@@ -120,8 +204,86 @@ BOOL WINAPI GetFilePatchSignatureW(LPCWSTR filename, ULONG flags, PVOID data, UL
                                    PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count,
                                    PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, PVOID buffer)
 {
                                    PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count,
                                    PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, PVOID buffer)
 {
-    FIXME("stub - %s, %x, %p, %u, %p, %u, %p, %u, %p\n", debugstr_w(filename), flags, data,
-          ignore_range_count, ignore_range, retain_range_count, retain_range, bufsize, buffer);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    CHAR LocalBuf[SIGNATURE_MIN_SIZE];
+    BOOL ret = FALSE;
+    HANDLE hFile;
+
+    hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                        OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+    if (hFile != INVALID_HANDLE_VALUE)
+    {
+        ret = GetFilePatchSignatureByHandle(hFile, flags, data, ignore_range_count, ignore_range,
+                                            retain_range_count, retain_range, sizeof(LocalBuf), LocalBuf);
+        CloseHandle(hFile);
+
+        if (bufsize < (SIGNATURE_MIN_SIZE * sizeof(WCHAR)))
+        {
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
+        if (ret)
+        {
+            MultiByteToWideChar(CP_ACP, 0, LocalBuf, -1, buffer, bufsize / sizeof(WCHAR));
+        }
+    }
+
+    return ret;
+}
+
+/*****************************************************
+ *    TestApplyPatchToFileA (MSPATCHA.10)
+ */
+BOOL WINAPI TestApplyPatchToFileA(LPCSTR patch_file, LPCSTR old_file, ULONG apply_flags)
+{
+    BOOL ret = FALSE;
+    HANDLE hPatch, hOld;
+
+    hPatch = CreateFileA(patch_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                         OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+    if (hPatch != INVALID_HANDLE_VALUE)
+    {
+        hOld = CreateFileA(old_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                           OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+        if (hOld != INVALID_HANDLE_VALUE)
+        {
+            ret = TestApplyPatchToFileByHandles(hPatch, hOld, apply_flags);
+            CloseHandle(hOld);
+        }
+        CloseHandle(hPatch);
+    }
+
+    return ret;
+}
+
+/*****************************************************
+ *    TestApplyPatchToFileByHandles (MSPATCHA.11)
+ */
+BOOL WINAPI TestApplyPatchToFileByHandles(HANDLE patch_file, HANDLE old_file, ULONG apply_flags)
+{
+    return ApplyPatchToFileByHandles(patch_file, old_file, INVALID_HANDLE_VALUE, apply_flags | APPLY_OPTION_TEST_ONLY);
+}
+
+/*****************************************************
+ *    TestApplyPatchToFileW (MSPATCHA.12)
+ */
+BOOL WINAPI TestApplyPatchToFileW(LPCWSTR patch_file, LPCWSTR old_file, ULONG apply_flags)
+{
+    BOOL ret = FALSE;
+    HANDLE hPatch, hOld;
+
+    hPatch = CreateFileW(patch_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                         OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+    if (hPatch != INVALID_HANDLE_VALUE)
+    {
+        hOld = CreateFileW(old_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                           OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
+        if (hOld != INVALID_HANDLE_VALUE)
+        {
+            ret = TestApplyPatchToFileByHandles(hPatch, hOld, apply_flags);
+            CloseHandle(hOld);
+        }
+        CloseHandle(hPatch);
+    }
+
+    return ret;
 }
 }