Implemented DllCanUnloadNow.
[wine/multimedia.git] / dlls / imagehlp / integrity.c
blob49e6bfdf426111b9de3e3b5b5704c972c3d3f39e
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "ntstatus.h"
31 #include "imagehlp.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
37 * These functions are partially documented at:
38 * http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
41 /***********************************************************************
42 * IMAGEHLP_GetSecurityDirOffset (INTERNAL)
44 * Read a file's PE header, and return the offset and size of the
45 * security directory.
47 static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle,
48 DWORD *pdwOfs, DWORD *pdwSize )
50 IMAGE_DOS_HEADER dos_hdr;
51 IMAGE_NT_HEADERS nt_hdr;
52 DWORD count;
53 BOOL r;
54 IMAGE_DATA_DIRECTORY *sd;
56 TRACE("handle %p\n", handle );
58 /* read the DOS header */
59 count = SetFilePointer( handle, 0, NULL, FILE_BEGIN );
60 if( count == INVALID_SET_FILE_POINTER )
61 return FALSE;
62 count = 0;
63 r = ReadFile( handle, &dos_hdr, sizeof dos_hdr, &count, NULL );
64 if( !r )
65 return FALSE;
66 if( count != sizeof dos_hdr )
67 return FALSE;
69 /* read the PE header */
70 count = SetFilePointer( handle, dos_hdr.e_lfanew, NULL, FILE_BEGIN );
71 if( count == INVALID_SET_FILE_POINTER )
72 return FALSE;
73 count = 0;
74 r = ReadFile( handle, &nt_hdr, sizeof nt_hdr, &count, NULL );
75 if( !r )
76 return FALSE;
77 if( count != sizeof nt_hdr )
78 return FALSE;
80 sd = &nt_hdr.OptionalHeader.
81 DataDirectory[IMAGE_FILE_SECURITY_DIRECTORY];
83 TRACE("size = %lx addr = %lx\n", sd->Size, sd->VirtualAddress);
84 *pdwSize = sd->Size;
85 *pdwOfs = sd->VirtualAddress;
87 return TRUE;
90 /***********************************************************************
91 * IMAGEHLP_GetCertificateOffset (INTERNAL)
93 * Read a file's PE header, and return the offset and size of the
94 * security directory.
96 static BOOL IMAGEHLP_GetCertificateOffset( HANDLE handle, DWORD num,
97 DWORD *pdwOfs, DWORD *pdwSize )
99 DWORD size, count, offset, len, sd_VirtualAddr;
100 BOOL r;
102 r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
103 if( !r )
104 return FALSE;
106 offset = 0;
107 /* take the n'th certificate */
108 while( 1 )
110 /* read the length of the current certificate */
111 count = SetFilePointer( handle, sd_VirtualAddr + offset,
112 NULL, FILE_BEGIN );
113 if( count == INVALID_SET_FILE_POINTER )
114 return FALSE;
115 r = ReadFile( handle, &len, sizeof len, &count, NULL );
116 if( !r )
117 return FALSE;
118 if( count != sizeof len )
119 return FALSE;
121 /* check the certificate is not too big or too small */
122 if( len < sizeof len )
123 return FALSE;
124 if( len > (size-offset) )
125 return FALSE;
126 if( !num-- )
127 break;
129 /* calculate the offset of the next certificate */
130 offset += len;
131 if( offset >= size )
132 return FALSE;
135 *pdwOfs = sd_VirtualAddr + offset;
136 *pdwSize = len;
138 TRACE("len = %lx addr = %lx\n", len, sd_VirtualAddr + offset);
140 return TRUE;
144 /***********************************************************************
145 * ImageAddCertificate (IMAGEHLP.@)
148 BOOL WINAPI ImageAddCertificate(
149 HANDLE FileHandle, PWIN_CERTIFICATE Certificate, PDWORD Index)
151 FIXME("(%p, %p, %p): stub\n",
152 FileHandle, Certificate, Index
154 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
155 return FALSE;
158 /***********************************************************************
159 * ImageEnumerateCertificates (IMAGEHLP.@)
161 BOOL WINAPI ImageEnumerateCertificates(
162 HANDLE handle, WORD TypeFilter, PDWORD CertificateCount,
163 PDWORD Indices, DWORD IndexCount)
165 DWORD size, count, offset, sd_VirtualAddr;
166 WIN_CERTIFICATE hdr;
167 const size_t cert_hdr_size = sizeof hdr - sizeof hdr.bCertificate;
168 BOOL r;
170 TRACE("%p %hd %p %p %ld\n",
171 handle, TypeFilter, CertificateCount, Indices, IndexCount);
173 if( Indices )
175 FIXME("Indicies not handled!\n");
176 return FALSE;
179 r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
180 if( !r )
181 return FALSE;
183 offset = 0;
184 *CertificateCount = 0;
185 while( offset < size )
187 /* read the length of the current certificate */
188 count = SetFilePointer( handle, sd_VirtualAddr + offset,
189 NULL, FILE_BEGIN );
190 if( count == INVALID_SET_FILE_POINTER )
191 return FALSE;
192 r = ReadFile( handle, &hdr, cert_hdr_size, &count, NULL );
193 if( !r )
194 return FALSE;
195 if( count != cert_hdr_size )
196 return FALSE;
198 TRACE("Size = %08lx id = %08hx\n",
199 hdr.dwLength, hdr.wCertificateType );
201 /* check the certificate is not too big or too small */
202 if( hdr.dwLength < cert_hdr_size )
203 return FALSE;
204 if( hdr.dwLength > (size-offset) )
205 return FALSE;
207 if( (TypeFilter == CERT_SECTION_TYPE_ANY) ||
208 (TypeFilter == hdr.wCertificateType) )
210 (*CertificateCount)++;
213 /* next certificate */
214 offset += hdr.dwLength;
217 return TRUE;
220 /***********************************************************************
221 * ImageGetCertificateData (IMAGEHLP.@)
223 * FIXME: not sure that I'm dealing with the Index the right way
225 BOOL WINAPI ImageGetCertificateData(
226 HANDLE handle, DWORD Index,
227 PWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
229 DWORD r, offset, ofs, size, count;
231 TRACE("%p %ld %p %p\n", handle, Index, Certificate, RequiredLength);
233 if( !IMAGEHLP_GetCertificateOffset( handle, Index, &ofs, &size ) )
234 return FALSE;
236 if( !Certificate )
238 *RequiredLength = size;
239 return TRUE;
242 if( *RequiredLength < size )
244 *RequiredLength = size;
245 SetLastError( ERROR_INSUFFICIENT_BUFFER );
246 return FALSE;
249 *RequiredLength = size;
251 offset = SetFilePointer( handle, ofs, NULL, FILE_BEGIN );
252 if( offset == INVALID_SET_FILE_POINTER )
253 return FALSE;
255 r = ReadFile( handle, Certificate, size, &count, NULL );
256 if( !r )
257 return FALSE;
258 if( count != size )
259 return FALSE;
261 TRACE("OK\n");
263 return TRUE;
266 /***********************************************************************
267 * ImageGetCertificateHeader (IMAGEHLP.@)
269 BOOL WINAPI ImageGetCertificateHeader(
270 HANDLE handle, DWORD index, PWIN_CERTIFICATE pCert)
272 DWORD r, offset, ofs, size, count;
273 const size_t cert_hdr_size = sizeof *pCert - sizeof pCert->bCertificate;
275 TRACE("%p %ld %p\n", handle, index, pCert);
277 if( !IMAGEHLP_GetCertificateOffset( handle, index, &ofs, &size ) )
278 return FALSE;
280 if( size < cert_hdr_size )
281 return FALSE;
283 offset = SetFilePointer( handle, ofs, NULL, FILE_BEGIN );
284 if( offset == INVALID_SET_FILE_POINTER )
285 return FALSE;
287 r = ReadFile( handle, pCert, cert_hdr_size, &count, NULL );
288 if( !r )
289 return FALSE;
290 if( count != cert_hdr_size )
291 return FALSE;
293 TRACE("OK\n");
295 return TRUE;
298 /***********************************************************************
299 * ImageGetDigestStream (IMAGEHLP.@)
301 BOOL WINAPI ImageGetDigestStream(
302 HANDLE FileHandle, DWORD DigestLevel,
303 DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
305 FIXME("(%p, %ld, %p, %p): stub\n",
306 FileHandle, DigestLevel, DigestFunction, DigestHandle
308 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
309 return FALSE;
312 /***********************************************************************
313 * ImageRemoveCertificate (IMAGEHLP.@)
315 BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index)
317 FIXME("(%p, %ld): stub\n", FileHandle, Index);
318 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
319 return FALSE;