imagehlp: Add support for the indices array passed to ImageEnumerateCertificates.
[wine/wine-kai.git] / dlls / imagehlp / integrity.c
blob99608b70a72feced5a78c1f00b844bebd8a9324c
1 /*
2 * IMAGEHLP library
4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2003 Mike McCormack
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 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "winreg.h"
28 #include "winternl.h"
29 #include "winnt.h"
30 #include "imagehlp.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
36 * These functions are partially documented at:
37 * http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
40 /***********************************************************************
41 * IMAGEHLP_GetSecurityDirOffset (INTERNAL)
43 * Read a file's PE header, and return the offset and size of the
44 * security directory.
46 static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle,
47 DWORD *pdwOfs, DWORD *pdwSize )
49 IMAGE_DOS_HEADER dos_hdr;
50 IMAGE_NT_HEADERS nt_hdr;
51 DWORD count;
52 BOOL r;
53 IMAGE_DATA_DIRECTORY *sd;
55 TRACE("handle %p\n", handle );
57 /* read the DOS header */
58 count = SetFilePointer( handle, 0, NULL, FILE_BEGIN );
59 if( count == INVALID_SET_FILE_POINTER )
60 return FALSE;
61 count = 0;
62 r = ReadFile( handle, &dos_hdr, sizeof dos_hdr, &count, NULL );
63 if( !r )
64 return FALSE;
65 if( count != sizeof dos_hdr )
66 return FALSE;
68 /* read the PE header */
69 count = SetFilePointer( handle, dos_hdr.e_lfanew, NULL, FILE_BEGIN );
70 if( count == INVALID_SET_FILE_POINTER )
71 return FALSE;
72 count = 0;
73 r = ReadFile( handle, &nt_hdr, sizeof nt_hdr, &count, NULL );
74 if( !r )
75 return FALSE;
76 if( count != sizeof nt_hdr )
77 return FALSE;
79 sd = &nt_hdr.OptionalHeader.
80 DataDirectory[IMAGE_FILE_SECURITY_DIRECTORY];
82 TRACE("size = %x addr = %x\n", sd->Size, sd->VirtualAddress);
83 *pdwSize = sd->Size;
84 *pdwOfs = sd->VirtualAddress;
86 return TRUE;
89 /***********************************************************************
90 * IMAGEHLP_GetCertificateOffset (INTERNAL)
92 * Read a file's PE header, and return the offset and size of the
93 * security directory.
95 static BOOL IMAGEHLP_GetCertificateOffset( HANDLE handle, DWORD num,
96 DWORD *pdwOfs, DWORD *pdwSize )
98 DWORD size, count, offset, len, sd_VirtualAddr;
99 BOOL r;
101 r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
102 if( !r )
103 return FALSE;
105 offset = 0;
106 /* take the n'th certificate */
107 while( 1 )
109 /* read the length of the current certificate */
110 count = SetFilePointer( handle, sd_VirtualAddr + offset,
111 NULL, FILE_BEGIN );
112 if( count == INVALID_SET_FILE_POINTER )
113 return FALSE;
114 r = ReadFile( handle, &len, sizeof len, &count, NULL );
115 if( !r )
116 return FALSE;
117 if( count != sizeof len )
118 return FALSE;
120 /* check the certificate is not too big or too small */
121 if( len < sizeof len )
122 return FALSE;
123 if( len > (size-offset) )
124 return FALSE;
125 if( !num-- )
126 break;
128 /* calculate the offset of the next certificate */
129 offset += len;
130 if( offset >= size )
131 return FALSE;
134 *pdwOfs = sd_VirtualAddr + offset;
135 *pdwSize = len;
137 TRACE("len = %x addr = %x\n", len, sd_VirtualAddr + offset);
139 return TRUE;
143 /***********************************************************************
144 * ImageAddCertificate (IMAGEHLP.@)
147 BOOL WINAPI ImageAddCertificate(
148 HANDLE FileHandle, PWIN_CERTIFICATE Certificate, PDWORD Index)
150 FIXME("(%p, %p, %p): stub\n",
151 FileHandle, Certificate, Index
153 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
154 return FALSE;
157 /***********************************************************************
158 * ImageEnumerateCertificates (IMAGEHLP.@)
160 BOOL WINAPI ImageEnumerateCertificates(
161 HANDLE handle, WORD TypeFilter, PDWORD CertificateCount,
162 PDWORD Indices, DWORD IndexCount)
164 DWORD size, count, offset, sd_VirtualAddr, index;
165 WIN_CERTIFICATE hdr;
166 const size_t cert_hdr_size = sizeof hdr - sizeof hdr.bCertificate;
167 BOOL r;
169 TRACE("%p %hd %p %p %d\n",
170 handle, TypeFilter, CertificateCount, Indices, IndexCount);
172 r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
173 if( !r )
174 return FALSE;
176 offset = 0;
177 index = 0;
178 *CertificateCount = 0;
179 while( offset < size )
181 /* read the length of the current certificate */
182 count = SetFilePointer( handle, sd_VirtualAddr + offset,
183 NULL, FILE_BEGIN );
184 if( count == INVALID_SET_FILE_POINTER )
185 return FALSE;
186 r = ReadFile( handle, &hdr, cert_hdr_size, &count, NULL );
187 if( !r )
188 return FALSE;
189 if( count != cert_hdr_size )
190 return FALSE;
192 TRACE("Size = %08x id = %08hx\n",
193 hdr.dwLength, hdr.wCertificateType );
195 /* check the certificate is not too big or too small */
196 if( hdr.dwLength < cert_hdr_size )
197 return FALSE;
198 if( hdr.dwLength > (size-offset) )
199 return FALSE;
201 if( (TypeFilter == CERT_SECTION_TYPE_ANY) ||
202 (TypeFilter == hdr.wCertificateType) )
204 (*CertificateCount)++;
205 if(Indices && *CertificateCount <= IndexCount)
206 *Indices++ = index;
209 /* next certificate */
210 offset += hdr.dwLength;
211 index++;
214 return TRUE;
217 /***********************************************************************
218 * ImageGetCertificateData (IMAGEHLP.@)
220 * FIXME: not sure that I'm dealing with the Index the right way
222 BOOL WINAPI ImageGetCertificateData(
223 HANDLE handle, DWORD Index,
224 PWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
226 DWORD r, offset, ofs, size, count;
228 TRACE("%p %d %p %p\n", handle, Index, Certificate, RequiredLength);
230 if( !IMAGEHLP_GetCertificateOffset( handle, Index, &ofs, &size ) )
231 return FALSE;
233 if( !Certificate )
235 *RequiredLength = size;
236 return TRUE;
239 if( *RequiredLength < size )
241 *RequiredLength = size;
242 SetLastError( ERROR_INSUFFICIENT_BUFFER );
243 return FALSE;
246 *RequiredLength = size;
248 offset = SetFilePointer( handle, ofs, NULL, FILE_BEGIN );
249 if( offset == INVALID_SET_FILE_POINTER )
250 return FALSE;
252 r = ReadFile( handle, Certificate, size, &count, NULL );
253 if( !r )
254 return FALSE;
255 if( count != size )
256 return FALSE;
258 TRACE("OK\n");
260 return TRUE;
263 /***********************************************************************
264 * ImageGetCertificateHeader (IMAGEHLP.@)
266 BOOL WINAPI ImageGetCertificateHeader(
267 HANDLE handle, DWORD index, PWIN_CERTIFICATE pCert)
269 DWORD r, offset, ofs, size, count;
270 const size_t cert_hdr_size = sizeof *pCert - sizeof pCert->bCertificate;
272 TRACE("%p %d %p\n", handle, index, pCert);
274 if( !IMAGEHLP_GetCertificateOffset( handle, index, &ofs, &size ) )
275 return FALSE;
277 if( size < cert_hdr_size )
278 return FALSE;
280 offset = SetFilePointer( handle, ofs, NULL, FILE_BEGIN );
281 if( offset == INVALID_SET_FILE_POINTER )
282 return FALSE;
284 r = ReadFile( handle, pCert, cert_hdr_size, &count, NULL );
285 if( !r )
286 return FALSE;
287 if( count != cert_hdr_size )
288 return FALSE;
290 TRACE("OK\n");
292 return TRUE;
295 /***********************************************************************
296 * ImageGetDigestStream (IMAGEHLP.@)
298 BOOL WINAPI ImageGetDigestStream(
299 HANDLE FileHandle, DWORD DigestLevel,
300 DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
302 FIXME("(%p, %d, %p, %p): stub\n",
303 FileHandle, DigestLevel, DigestFunction, DigestHandle
305 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
306 return FALSE;
309 /***********************************************************************
310 * ImageRemoveCertificate (IMAGEHLP.@)
312 BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index)
314 FIXME("(%p, %d): stub\n", FileHandle, Index);
315 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
316 return FALSE;