Implement imagehlp.ImageGetCertificateData()

Mike McCormack mike at codeweavers.com
Wed Sep 17 12:33:24 CDT 2003


ChangeLog:
* Implement imagehlp.ImageGetCertificateData()
-------------- next part --------------
Index: dlls/imagehlp/integrity.c
===================================================================
RCS file: /home/wine/wine/dlls/imagehlp/integrity.c,v
retrieving revision 1.11
diff -u -r1.11 integrity.c
--- dlls/imagehlp/integrity.c	5 Sep 2003 23:08:37 -0000	1.11
+++ dlls/imagehlp/integrity.c	16 Sep 2003 14:10:56 -0000
@@ -2,6 +2,7 @@
  *	IMAGEHLP library
  *
  *	Copyright 1998	Patrik Stridvall
+ *	Copyright 2003	Mike McCormack
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -23,11 +24,104 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
+#include "winreg.h"
+#include "winternl.h"
+#include "winnt.h"
+#include "ntstatus.h"
 #include "imagehlp.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
 
+/*
+ * These functions are partially documented at:
+ *   http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
+ */
+
+/***********************************************************************
+ * IMAGEHLP_GetSecurityDirOffset (INTERNAL)
+ *
+ * Read a file's PE header, and return the offset and size of the 
+ *  security directory.
+ */
+static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle, DWORD num,
+                                           DWORD *pdwOfs, DWORD *pdwSize )
+{
+    IMAGE_DOS_HEADER dos_hdr;
+    IMAGE_NT_HEADERS nt_hdr;
+    DWORD size, count, offset, len;
+    BOOL r;
+    IMAGE_DATA_DIRECTORY *sd;
+
+    TRACE("handle %p\n", handle );
+
+    /* read the DOS header */
+    count = SetFilePointer( handle, 0, NULL, FILE_BEGIN );
+    if( count == INVALID_SET_FILE_POINTER )
+        return FALSE;
+    count = 0;
+    r = ReadFile( handle, &dos_hdr, sizeof dos_hdr, &count, NULL );
+    if( !r )
+        return FALSE;
+    if( count != sizeof dos_hdr )
+        return FALSE;
+
+    /* read the PE header */
+    count = SetFilePointer( handle, dos_hdr.e_lfanew, NULL, FILE_BEGIN );
+    if( count == INVALID_SET_FILE_POINTER )
+        return FALSE;
+    count = 0;
+    r = ReadFile( handle, &nt_hdr, sizeof nt_hdr, &count, NULL );
+    if( !r )
+        return FALSE;
+    if( count != sizeof nt_hdr )
+        return FALSE;
+
+    sd = &nt_hdr.OptionalHeader.
+                    DataDirectory[IMAGE_FILE_SECURITY_DIRECTORY];
+
+    TRACE("len = %lx addr = %lx\n", sd->Size, sd->VirtualAddress);
+
+    offset = 0;
+    size = sd->Size;
+
+    /* take the n'th certificate */
+    while( 1 )
+    {
+        /* read the length of the current certificate */
+        count = SetFilePointer( handle, sd->VirtualAddress + offset,
+                                 NULL, FILE_BEGIN );
+        if( count == INVALID_SET_FILE_POINTER )
+            return FALSE;
+        r = ReadFile( handle, &len, sizeof len, &count, NULL );
+        if( !r )
+            return FALSE;
+        if( count != sizeof len )
+            return FALSE;
+
+        /* check the certificate is not too big or too small */
+        if( len < sizeof len )
+            return FALSE;
+        if( len > (size-offset) )
+            return FALSE;
+        if( !num-- )
+            break;
+
+        /* calculate the offset of the next certificate */
+        offset += len;
+        if( offset >= size )
+            return FALSE;
+    }
+
+    *pdwOfs = sd->VirtualAddress + offset;
+    *pdwSize = len;
+
+    TRACE("len = %lx addr = %lx\n", len, sd->VirtualAddress + offset);
+
+    return TRUE;
+}
+
+
 /***********************************************************************
  *		ImageAddCertificate (IMAGEHLP.@)
  */
@@ -58,16 +152,48 @@
 
 /***********************************************************************
  *		ImageGetCertificateData (IMAGEHLP.@)
+ *
+ *  FIXME: not sure that I'm dealing with the Index the right way
  */
 BOOL WINAPI ImageGetCertificateData(
-  HANDLE FileHandle, DWORD CertificateIndex,
-  PWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
+                HANDLE handle, DWORD Index,
+                PWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
 {
-  FIXME("(%p, %ld, %p, %p): stub\n",
-    FileHandle, CertificateIndex, Certificate, RequiredLength
-  );
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+    DWORD r, offset, ofs, size, count;
+
+    TRACE("%p %ld %p %p\n", handle, Index, Certificate, RequiredLength);
+
+    if( !IMAGEHLP_GetSecurityDirOffset( handle, Index, &ofs, &size ) )
+        return FALSE;
+
+    if( !Certificate )
+    {
+        *RequiredLength = size;
+        return TRUE;
+    }
+
+    if( *RequiredLength < size )
+    {
+        *RequiredLength = size;
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );
+        return FALSE;
+    }
+
+    *RequiredLength = size;
+
+    offset = SetFilePointer( handle, ofs, NULL, FILE_BEGIN );
+    if( offset == INVALID_SET_FILE_POINTER )
+        return FALSE;
+
+    r = ReadFile( handle, Certificate, size, &count, NULL );
+    if( !r )
+        return FALSE;
+    if( count != size )
+        return FALSE;
+
+    TRACE("OK\n");
+
+    return TRUE;
 }
 
 /***********************************************************************


More information about the wine-patches mailing list