Release 0.9.45.
[wine.git] / dlls / imagehlp / integrity.c
blobdf6de0fe366b1c7dc686cdc61384884525b1efd1
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 "winternl.h"
28 #include "winnt.h"
29 #include "imagehlp.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
35 * These functions are partially documented at:
36 * http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
39 /***********************************************************************
40 * IMAGEHLP_GetSecurityDirOffset (INTERNAL)
42 * Read a file's PE header, and return the offset and size of the
43 * security directory.
45 static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle,
46 DWORD *pdwOfs, DWORD *pdwSize )
48 IMAGE_DOS_HEADER dos_hdr;
49 IMAGE_NT_HEADERS nt_hdr;
50 DWORD count;
51 BOOL r;
52 IMAGE_DATA_DIRECTORY *sd;
54 TRACE("handle %p\n", handle );
56 /* read the DOS header */
57 count = SetFilePointer( handle, 0, NULL, FILE_BEGIN );
58 if( count == INVALID_SET_FILE_POINTER )
59 return FALSE;
60 count = 0;
61 r = ReadFile( handle, &dos_hdr, sizeof dos_hdr, &count, NULL );
62 if( !r )
63 return FALSE;
64 if( count != sizeof dos_hdr )
65 return FALSE;
67 /* read the PE header */
68 count = SetFilePointer( handle, dos_hdr.e_lfanew, NULL, FILE_BEGIN );
69 if( count == INVALID_SET_FILE_POINTER )
70 return FALSE;
71 count = 0;
72 r = ReadFile( handle, &nt_hdr, sizeof nt_hdr, &count, NULL );
73 if( !r )
74 return FALSE;
75 if( count != sizeof nt_hdr )
76 return FALSE;
78 sd = &nt_hdr.OptionalHeader.
79 DataDirectory[IMAGE_FILE_SECURITY_DIRECTORY];
81 TRACE("size = %x addr = %x\n", sd->Size, sd->VirtualAddress);
82 *pdwSize = sd->Size;
83 *pdwOfs = sd->VirtualAddress;
85 return TRUE;
88 /***********************************************************************
89 * IMAGEHLP_GetCertificateOffset (INTERNAL)
91 * Read a file's PE header, and return the offset and size of the
92 * security directory.
94 static BOOL IMAGEHLP_GetCertificateOffset( HANDLE handle, DWORD num,
95 DWORD *pdwOfs, DWORD *pdwSize )
97 DWORD size, count, offset, len, sd_VirtualAddr;
98 BOOL r;
100 r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
101 if( !r )
102 return FALSE;
104 offset = 0;
105 /* take the n'th certificate */
106 while( 1 )
108 /* read the length of the current certificate */
109 count = SetFilePointer( handle, sd_VirtualAddr + offset,
110 NULL, FILE_BEGIN );
111 if( count == INVALID_SET_FILE_POINTER )
112 return FALSE;
113 r = ReadFile( handle, &len, sizeof len, &count, NULL );
114 if( !r )
115 return FALSE;
116 if( count != sizeof len )
117 return FALSE;
119 /* check the certificate is not too big or too small */
120 if( len < sizeof len )
121 return FALSE;
122 if( len > (size-offset) )
123 return FALSE;
124 if( !num-- )
125 break;
127 /* calculate the offset of the next certificate */
128 offset += len;
129 if( offset >= size )
130 return FALSE;
133 *pdwOfs = sd_VirtualAddr + offset;
134 *pdwSize = len;
136 TRACE("len = %x addr = %x\n", len, sd_VirtualAddr + offset);
138 return TRUE;
142 /***********************************************************************
143 * ImageAddCertificate (IMAGEHLP.@)
146 BOOL WINAPI ImageAddCertificate(
147 HANDLE FileHandle, LPWIN_CERTIFICATE Certificate, PDWORD Index)
149 FIXME("(%p, %p, %p): stub\n",
150 FileHandle, Certificate, Index
152 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
153 return FALSE;
156 /***********************************************************************
157 * ImageEnumerateCertificates (IMAGEHLP.@)
159 BOOL WINAPI ImageEnumerateCertificates(
160 HANDLE handle, WORD TypeFilter, PDWORD CertificateCount,
161 PDWORD Indices, DWORD IndexCount)
163 DWORD size, count, offset, sd_VirtualAddr, index;
164 WIN_CERTIFICATE hdr;
165 const size_t cert_hdr_size = sizeof hdr - sizeof hdr.bCertificate;
166 BOOL r;
168 TRACE("%p %hd %p %p %d\n",
169 handle, TypeFilter, CertificateCount, Indices, IndexCount);
171 r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
172 if( !r )
173 return FALSE;
175 offset = 0;
176 index = 0;
177 *CertificateCount = 0;
178 while( offset < size )
180 /* read the length of the current certificate */
181 count = SetFilePointer( handle, sd_VirtualAddr + offset,
182 NULL, FILE_BEGIN );
183 if( count == INVALID_SET_FILE_POINTER )
184 return FALSE;
185 r = ReadFile( handle, &hdr, cert_hdr_size, &count, NULL );
186 if( !r )
187 return FALSE;
188 if( count != cert_hdr_size )
189 return FALSE;
191 TRACE("Size = %08x id = %08hx\n",
192 hdr.dwLength, hdr.wCertificateType );
194 /* check the certificate is not too big or too small */
195 if( hdr.dwLength < cert_hdr_size )
196 return FALSE;
197 if( hdr.dwLength > (size-offset) )
198 return FALSE;
200 if( (TypeFilter == CERT_SECTION_TYPE_ANY) ||
201 (TypeFilter == hdr.wCertificateType) )
203 (*CertificateCount)++;
204 if(Indices && *CertificateCount <= IndexCount)
205 *Indices++ = index;
208 /* next certificate */
209 offset += hdr.dwLength;
210 index++;
213 return TRUE;
216 /***********************************************************************
217 * ImageGetCertificateData (IMAGEHLP.@)
219 * FIXME: not sure that I'm dealing with the Index the right way
221 BOOL WINAPI ImageGetCertificateData(
222 HANDLE handle, DWORD Index,
223 LPWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
225 DWORD r, offset, ofs, size, count;
227 TRACE("%p %d %p %p\n", handle, Index, Certificate, RequiredLength);
229 if( !IMAGEHLP_GetCertificateOffset( handle, Index, &ofs, &size ) )
230 return FALSE;
232 if( !Certificate )
234 *RequiredLength = size;
235 return TRUE;
238 if( *RequiredLength < size )
240 *RequiredLength = size;
241 SetLastError( ERROR_INSUFFICIENT_BUFFER );
242 return FALSE;
245 *RequiredLength = size;
247 offset = SetFilePointer( handle, ofs, NULL, FILE_BEGIN );
248 if( offset == INVALID_SET_FILE_POINTER )
249 return FALSE;
251 r = ReadFile( handle, Certificate, size, &count, NULL );
252 if( !r )
253 return FALSE;
254 if( count != size )
255 return FALSE;
257 TRACE("OK\n");
259 return TRUE;
262 /***********************************************************************
263 * ImageGetCertificateHeader (IMAGEHLP.@)
265 BOOL WINAPI ImageGetCertificateHeader(
266 HANDLE handle, DWORD index, LPWIN_CERTIFICATE pCert)
268 DWORD r, offset, ofs, size, count;
269 const size_t cert_hdr_size = sizeof *pCert - sizeof pCert->bCertificate;
271 TRACE("%p %d %p\n", handle, index, pCert);
273 if( !IMAGEHLP_GetCertificateOffset( handle, index, &ofs, &size ) )
274 return FALSE;
276 if( size < cert_hdr_size )
277 return FALSE;
279 offset = SetFilePointer( handle, ofs, NULL, FILE_BEGIN );
280 if( offset == INVALID_SET_FILE_POINTER )
281 return FALSE;
283 r = ReadFile( handle, pCert, cert_hdr_size, &count, NULL );
284 if( !r )
285 return FALSE;
286 if( count != cert_hdr_size )
287 return FALSE;
289 TRACE("OK\n");
291 return TRUE;
294 /***********************************************************************
295 * ImageGetDigestStream (IMAGEHLP.@)
297 BOOL WINAPI ImageGetDigestStream(
298 HANDLE FileHandle, DWORD DigestLevel,
299 DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
301 FIXME("(%p, %d, %p, %p): stub\n",
302 FileHandle, DigestLevel, DigestFunction, DigestHandle
304 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
305 return FALSE;
308 /***********************************************************************
309 * ImageRemoveCertificate (IMAGEHLP.@)
311 BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index)
313 FIXME("(%p, %d): stub\n", FileHandle, Index);
314 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
315 return FALSE;