Allow configuration of output devices to use and change standard
[wine] / dlls / imagehlp / integrity.c
1 /*
2  *      IMAGEHLP library
3  *
4  *      Copyright 1998  Patrik Stridvall
5  *      Copyright 2003  Mike McCormack
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include <stdarg.h>
23
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"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
35
36 /*
37  * These functions are partially documented at:
38  *   http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
39  */
40
41 /***********************************************************************
42  * IMAGEHLP_GetSecurityDirOffset (INTERNAL)
43  *
44  * Read a file's PE header, and return the offset and size of the 
45  *  security directory.
46  */
47 static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle, DWORD num,
48                                            DWORD *pdwOfs, DWORD *pdwSize )
49 {
50     IMAGE_DOS_HEADER dos_hdr;
51     IMAGE_NT_HEADERS nt_hdr;
52     DWORD size, count, offset, len;
53     BOOL r;
54     IMAGE_DATA_DIRECTORY *sd;
55
56     TRACE("handle %p\n", handle );
57
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;
68
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;
79
80     sd = &nt_hdr.OptionalHeader.
81                     DataDirectory[IMAGE_FILE_SECURITY_DIRECTORY];
82
83     TRACE("len = %lx addr = %lx\n", sd->Size, sd->VirtualAddress);
84
85     offset = 0;
86     size = sd->Size;
87
88     /* take the n'th certificate */
89     while( 1 )
90     {
91         /* read the length of the current certificate */
92         count = SetFilePointer( handle, sd->VirtualAddress + offset,
93                                  NULL, FILE_BEGIN );
94         if( count == INVALID_SET_FILE_POINTER )
95             return FALSE;
96         r = ReadFile( handle, &len, sizeof len, &count, NULL );
97         if( !r )
98             return FALSE;
99         if( count != sizeof len )
100             return FALSE;
101
102         /* check the certificate is not too big or too small */
103         if( len < sizeof len )
104             return FALSE;
105         if( len > (size-offset) )
106             return FALSE;
107         if( !num-- )
108             break;
109
110         /* calculate the offset of the next certificate */
111         offset += len;
112         if( offset >= size )
113             return FALSE;
114     }
115
116     *pdwOfs = sd->VirtualAddress + offset;
117     *pdwSize = len;
118
119     TRACE("len = %lx addr = %lx\n", len, sd->VirtualAddress + offset);
120
121     return TRUE;
122 }
123
124
125 /***********************************************************************
126  *              ImageAddCertificate (IMAGEHLP.@)
127  */
128
129 BOOL WINAPI ImageAddCertificate(
130   HANDLE FileHandle, PWIN_CERTIFICATE Certificate, PDWORD Index)
131 {
132   FIXME("(%p, %p, %p): stub\n",
133     FileHandle, Certificate, Index
134   );
135   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
136   return FALSE;
137 }
138
139 /***********************************************************************
140  *              ImageEnumerateCertificates (IMAGEHLP.@)
141  */
142 BOOL WINAPI ImageEnumerateCertificates(
143   HANDLE FileHandle, WORD TypeFilter, PDWORD CertificateCount,
144   PDWORD Indices, DWORD IndexCount)
145 {
146   FIXME("(%p, %hd, %p, %p, %ld): stub\n",
147     FileHandle, TypeFilter, CertificateCount, Indices, IndexCount
148   );
149   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
150   return FALSE;
151 }
152
153 /***********************************************************************
154  *              ImageGetCertificateData (IMAGEHLP.@)
155  *
156  *  FIXME: not sure that I'm dealing with the Index the right way
157  */
158 BOOL WINAPI ImageGetCertificateData(
159                 HANDLE handle, DWORD Index,
160                 PWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
161 {
162     DWORD r, offset, ofs, size, count;
163
164     TRACE("%p %ld %p %p\n", handle, Index, Certificate, RequiredLength);
165
166     if( !IMAGEHLP_GetSecurityDirOffset( handle, Index, &ofs, &size ) )
167         return FALSE;
168
169     if( !Certificate )
170     {
171         *RequiredLength = size;
172         return TRUE;
173     }
174
175     if( *RequiredLength < size )
176     {
177         *RequiredLength = size;
178         SetLastError( ERROR_INSUFFICIENT_BUFFER );
179         return FALSE;
180     }
181
182     *RequiredLength = size;
183
184     offset = SetFilePointer( handle, ofs, NULL, FILE_BEGIN );
185     if( offset == INVALID_SET_FILE_POINTER )
186         return FALSE;
187
188     r = ReadFile( handle, Certificate, size, &count, NULL );
189     if( !r )
190         return FALSE;
191     if( count != size )
192         return FALSE;
193
194     TRACE("OK\n");
195
196     return TRUE;
197 }
198
199 /***********************************************************************
200  *              ImageGetCertificateHeader (IMAGEHLP.@)
201  */
202 BOOL WINAPI ImageGetCertificateHeader(
203   HANDLE FileHandle, DWORD CertificateIndex,
204   PWIN_CERTIFICATE Certificateheader)
205 {
206   FIXME("(%p, %ld, %p): stub\n",
207     FileHandle, CertificateIndex, Certificateheader
208   );
209   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
210   return FALSE;
211 }
212
213 /***********************************************************************
214  *              ImageGetDigestStream (IMAGEHLP.@)
215  */
216 BOOL WINAPI ImageGetDigestStream(
217   HANDLE FileHandle, DWORD DigestLevel,
218   DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
219 {
220   FIXME("(%p, %ld, %p, %p): stub\n",
221     FileHandle, DigestLevel, DigestFunction, DigestHandle
222   );
223   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
224   return FALSE;
225 }
226
227 /***********************************************************************
228  *              ImageRemoveCertificate (IMAGEHLP.@)
229  */
230 BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index)
231 {
232   FIXME("(%p, %ld): stub\n", FileHandle, Index);
233   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
234   return FALSE;
235 }