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