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
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
45 static BOOL
IMAGEHLP_GetSecurityDirOffset( HANDLE handle
,
46 DWORD
*pdwOfs
, DWORD
*pdwSize
)
48 IMAGE_DOS_HEADER dos_hdr
;
49 IMAGE_NT_HEADERS nt_hdr
;
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
)
61 r
= ReadFile( handle
, &dos_hdr
, sizeof dos_hdr
, &count
, NULL
);
64 if( count
!= sizeof dos_hdr
)
67 /* read the PE header */
68 count
= SetFilePointer( handle
, dos_hdr
.e_lfanew
, NULL
, FILE_BEGIN
);
69 if( count
== INVALID_SET_FILE_POINTER
)
72 r
= ReadFile( handle
, &nt_hdr
, sizeof nt_hdr
, &count
, NULL
);
75 if( count
!= sizeof nt_hdr
)
78 sd
= &nt_hdr
.OptionalHeader
.
79 DataDirectory
[IMAGE_FILE_SECURITY_DIRECTORY
];
81 TRACE("size = %x addr = %x\n", sd
->Size
, sd
->VirtualAddress
);
83 *pdwOfs
= sd
->VirtualAddress
;
88 /***********************************************************************
89 * IMAGEHLP_GetCertificateOffset (INTERNAL)
91 * Read a file's PE header, and return the offset and size of the
94 static BOOL
IMAGEHLP_GetCertificateOffset( HANDLE handle
, DWORD num
,
95 DWORD
*pdwOfs
, DWORD
*pdwSize
)
97 DWORD size
, count
, offset
, len
, sd_VirtualAddr
;
100 r
= IMAGEHLP_GetSecurityDirOffset( handle
, &sd_VirtualAddr
, &size
);
105 /* take the n'th certificate */
108 /* read the length of the current certificate */
109 count
= SetFilePointer( handle
, sd_VirtualAddr
+ offset
,
111 if( count
== INVALID_SET_FILE_POINTER
)
113 r
= ReadFile( handle
, &len
, sizeof len
, &count
, NULL
);
116 if( count
!= sizeof len
)
119 /* check the certificate is not too big or too small */
120 if( len
< sizeof len
)
122 if( len
> (size
-offset
) )
127 /* calculate the offset of the next certificate */
133 *pdwOfs
= sd_VirtualAddr
+ offset
;
136 TRACE("len = %x addr = %x\n", len
, sd_VirtualAddr
+ offset
);
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
);
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
;
165 const size_t cert_hdr_size
= sizeof hdr
- sizeof hdr
.bCertificate
;
168 TRACE("%p %hd %p %p %d\n",
169 handle
, TypeFilter
, CertificateCount
, Indices
, IndexCount
);
171 r
= IMAGEHLP_GetSecurityDirOffset( handle
, &sd_VirtualAddr
, &size
);
177 *CertificateCount
= 0;
178 while( offset
< size
)
180 /* read the length of the current certificate */
181 count
= SetFilePointer( handle
, sd_VirtualAddr
+ offset
,
183 if( count
== INVALID_SET_FILE_POINTER
)
185 r
= ReadFile( handle
, &hdr
, cert_hdr_size
, &count
, NULL
);
188 if( count
!= cert_hdr_size
)
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
)
197 if( hdr
.dwLength
> (size
-offset
) )
200 if( (TypeFilter
== CERT_SECTION_TYPE_ANY
) ||
201 (TypeFilter
== hdr
.wCertificateType
) )
203 (*CertificateCount
)++;
204 if(Indices
&& *CertificateCount
<= IndexCount
)
208 /* next certificate */
209 offset
+= hdr
.dwLength
;
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
);
231 SetLastError( ERROR_INVALID_PARAMETER
);
235 if( !IMAGEHLP_GetCertificateOffset( handle
, Index
, &ofs
, &size
) )
238 if( *RequiredLength
< size
)
240 *RequiredLength
= size
;
241 SetLastError( ERROR_INSUFFICIENT_BUFFER
);
247 SetLastError( ERROR_INVALID_PARAMETER
);
251 *RequiredLength
= size
;
253 offset
= SetFilePointer( handle
, ofs
, NULL
, FILE_BEGIN
);
254 if( offset
== INVALID_SET_FILE_POINTER
)
257 r
= ReadFile( handle
, Certificate
, size
, &count
, NULL
);
264 SetLastError( NO_ERROR
);
269 /***********************************************************************
270 * ImageGetCertificateHeader (IMAGEHLP.@)
272 BOOL WINAPI
ImageGetCertificateHeader(
273 HANDLE handle
, DWORD index
, LPWIN_CERTIFICATE pCert
)
275 DWORD r
, offset
, ofs
, size
, count
;
276 const size_t cert_hdr_size
= sizeof *pCert
- sizeof pCert
->bCertificate
;
278 TRACE("%p %d %p\n", handle
, index
, pCert
);
280 if( !IMAGEHLP_GetCertificateOffset( handle
, index
, &ofs
, &size
) )
283 if( size
< cert_hdr_size
)
286 offset
= SetFilePointer( handle
, ofs
, NULL
, FILE_BEGIN
);
287 if( offset
== INVALID_SET_FILE_POINTER
)
290 r
= ReadFile( handle
, pCert
, cert_hdr_size
, &count
, NULL
);
293 if( count
!= cert_hdr_size
)
301 /***********************************************************************
302 * ImageGetDigestStream (IMAGEHLP.@)
304 BOOL WINAPI
ImageGetDigestStream(
305 HANDLE FileHandle
, DWORD DigestLevel
,
306 DIGEST_FUNCTION DigestFunction
, DIGEST_HANDLE DigestHandle
)
308 FIXME("(%p, %d, %p, %p): stub\n",
309 FileHandle
, DigestLevel
, DigestFunction
, DigestHandle
311 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
315 /***********************************************************************
316 * ImageRemoveCertificate (IMAGEHLP.@)
318 BOOL WINAPI
ImageRemoveCertificate(HANDLE FileHandle
, DWORD Index
)
320 FIXME("(%p, %d): stub\n", FileHandle
, Index
);
321 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);