ReactOS  0.4.14-dev-50-g13bb5e2
version.c
Go to the documentation of this file.
1 /*
2  * Implementation of VERSION.DLL
3  *
4  * Copyright 1996,1997 Marcus Meissner
5  * Copyright 1997 David Cuthbert
6  * Copyright 1999 Ulrich Weigand
7  * Copyright 2005 Paul Vriens
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  *
23  */
24 #include "config.h"
25 
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30 
31 #include <sys/types.h>
32 #ifdef HAVE_UNISTD_H
33 # include <unistd.h>
34 #endif
35 
36 #define NONAMELESSUNION
37 #define NONAMELESSSTRUCT
38 #include "windef.h"
39 #include "winbase.h"
40 #include "winver.h"
41 #include "winuser.h"
42 #include "winnls.h"
43 #include "winternl.h"
44 #include "lzexpand.h"
45 #include "wine/unicode.h"
46 #include "winerror.h"
47 #include "wine/debug.h"
48 
49 
51 
52 typedef struct
53 {
54  WORD offset;
55  WORD length;
56  WORD flags;
57  WORD id;
58  WORD handle;
59  WORD usage;
60 } NE_NAMEINFO;
61 
62 typedef struct
63 {
64  WORD type_id;
65  WORD count;
66  DWORD resloader;
67 } NE_TYPEINFO;
68 
69 /**********************************************************************
70  * find_entry_by_id
71  *
72  * Find an entry by id in a resource directory
73  * Copied from loader/pe_resource.c
74  */
76  WORD id, const void *root )
77 {
79  int min, max, pos;
80 
81  entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
82  min = dir->NumberOfNamedEntries;
83  max = min + dir->NumberOfIdEntries - 1;
84  while (min <= max)
85  {
86  pos = (min + max) / 2;
87  if (entry[pos].u.Id == id)
88  return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry[pos].u2.s2.OffsetToDirectory);
89  if (entry[pos].u.Id > id) max = pos - 1;
90  else min = pos + 1;
91  }
92  return NULL;
93 }
94 
95 
96 /**********************************************************************
97  * find_entry_default
98  *
99  * Find a default entry in a resource directory
100  * Copied from loader/pe_resource.c
101  */
103  const void *root )
104 {
106 
107  entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
108  return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry->u2.s2.OffsetToDirectory);
109 }
110 
111 
112 /**********************************************************************
113  * push_language
114  *
115  * push a language onto the list of languages to try
116  */
117 static inline int push_language( WORD *list, int pos, WORD lang )
118 {
119  int i;
120  for (i = 0; i < pos; i++) if (list[i] == lang) return pos;
121  list[pos++] = lang;
122  return pos;
123 }
124 
125 
126 /**********************************************************************
127  * find_entry_language
128  */
130  const void *root, DWORD flags )
131 {
133  WORD list[9];
134  int i, pos = 0;
135 
137  {
138  /* cf. LdrFindResource_U */
140  pos = push_language( list, pos, LANGIDFROMLCID( NtCurrentTeb()->CurrentLocale ) );
148  }
149  else
150  {
151  /* FIXME: resolve LN file here */
153  }
154 
155  for (i = 0; i < pos; i++) if ((ret = find_entry_by_id( dir, list[i], root ))) return ret;
156  return find_entry_default( dir, root );
157 }
158 
159 
160 /***********************************************************************
161  * read_xx_header [internal]
162  */
163 static int read_xx_header( HFILE lzfd )
164 {
165  IMAGE_DOS_HEADER mzh;
166  char magic[3];
167 
168  LZSeek( lzfd, 0, SEEK_SET );
169  if ( sizeof(mzh) != LZRead( lzfd, (LPSTR)&mzh, sizeof(mzh) ) )
170  return 0;
171  if ( mzh.e_magic != IMAGE_DOS_SIGNATURE )
172  {
173  if (!memcmp( &mzh, "\177ELF", 4 )) return 1; /* ELF */
174  if (*(UINT *)&mzh == 0xfeedface || *(UINT *)&mzh == 0xcefaedfe) return 1; /* Mach-O */
175  return 0;
176  }
177 
178  LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
179  if ( 2 != LZRead( lzfd, magic, 2 ) )
180  return 0;
181 
182  LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
183 
184  if ( magic[0] == 'N' && magic[1] == 'E' )
185  return IMAGE_OS2_SIGNATURE;
186  if ( magic[0] == 'P' && magic[1] == 'E' )
187  return IMAGE_NT_SIGNATURE;
188 
189  magic[2] = '\0';
190  WARN("Can't handle %s files.\n", magic );
191  return 0;
192 }
193 
194 /***********************************************************************
195  * find_ne_resource [internal]
196  */
197 static BOOL find_ne_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff )
198 {
199  const WORD typeid = VS_FILE_INFO | 0x8000;
200  const WORD resid = VS_VERSION_INFO | 0x8000;
201  IMAGE_OS2_HEADER nehd;
202  NE_TYPEINFO *typeInfo;
203  NE_NAMEINFO *nameInfo;
204  DWORD nehdoffset;
205  LPBYTE resTab;
206  DWORD resTabSize;
207  int count;
208 
209  /* Read in NE header */
210  nehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
211  if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return FALSE;
212 
213  resTabSize = nehd.ne_restab - nehd.ne_rsrctab;
214  if ( !resTabSize )
215  {
216  TRACE("No resources in NE dll\n" );
217  return FALSE;
218  }
219 
220  /* Read in resource table */
221  resTab = HeapAlloc( GetProcessHeap(), 0, resTabSize );
222  if ( !resTab ) return FALSE;
223 
224  LZSeek( lzfd, nehd.ne_rsrctab + nehdoffset, SEEK_SET );
225  if ( resTabSize != LZRead( lzfd, (char*)resTab, resTabSize ) )
226  {
227  HeapFree( GetProcessHeap(), 0, resTab );
228  return FALSE;
229  }
230 
231  /* Find resource */
232  typeInfo = (NE_TYPEINFO *)(resTab + 2);
233  while (typeInfo->type_id)
234  {
235  if (typeInfo->type_id == typeid) goto found_type;
236  typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
237  typeInfo->count * sizeof(NE_NAMEINFO));
238  }
239  TRACE("No typeid entry found\n" );
240  HeapFree( GetProcessHeap(), 0, resTab );
241  return FALSE;
242 
243  found_type:
244  nameInfo = (NE_NAMEINFO *)(typeInfo + 1);
245 
246  for (count = typeInfo->count; count > 0; count--, nameInfo++)
247  if (nameInfo->id == resid) goto found_name;
248 
249  TRACE("No resid entry found\n" );
250  HeapFree( GetProcessHeap(), 0, resTab );
251  return FALSE;
252 
253  found_name:
254  /* Return resource data */
255  if ( resLen ) *resLen = nameInfo->length << *(WORD *)resTab;
256  if ( resOff ) *resOff = nameInfo->offset << *(WORD *)resTab;
257 
258  HeapFree( GetProcessHeap(), 0, resTab );
259  return TRUE;
260 }
261 
262 /***********************************************************************
263  * find_pe_resource [internal]
264  */
265 static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff, DWORD flags )
266 {
267  union
268  {
269  IMAGE_NT_HEADERS32 nt32;
270  IMAGE_NT_HEADERS64 nt64;
271  } pehd;
272  DWORD pehdoffset;
273  PIMAGE_DATA_DIRECTORY resDataDir;
275  LPBYTE resSection;
276  DWORD section_size, data_size;
277  const void *resDir;
278  const IMAGE_RESOURCE_DIRECTORY *resPtr;
279  const IMAGE_RESOURCE_DATA_ENTRY *resData;
280  int i, len, nSections;
281  BOOL ret = FALSE;
282 
283  /* Read in PE header */
284  pehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
285  len = LZRead( lzfd, (LPSTR)&pehd, sizeof(pehd) );
286  if (len < sizeof(pehd.nt32.FileHeader)) return FALSE;
287  if (len < sizeof(pehd)) memset( (char *)&pehd + len, 0, sizeof(pehd) - len );
288 
289  switch (pehd.nt32.OptionalHeader.Magic)
290  {
292  resDataDir = pehd.nt32.OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
293  break;
295  resDataDir = pehd.nt64.OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
296  break;
297  default:
298  return FALSE;
299  }
300 
301  if ( !resDataDir->Size )
302  {
303  TRACE("No resources in PE dll\n" );
304  return FALSE;
305  }
306 
307  /* Read in section table */
308  nSections = pehd.nt32.FileHeader.NumberOfSections;
310  nSections * sizeof(IMAGE_SECTION_HEADER) );
311  if ( !sections ) return FALSE;
312 
313  len = FIELD_OFFSET( IMAGE_NT_HEADERS32, OptionalHeader ) + pehd.nt32.FileHeader.SizeOfOptionalHeader;
314  LZSeek( lzfd, pehdoffset + len, SEEK_SET );
315 
316  if ( nSections * sizeof(IMAGE_SECTION_HEADER) !=
317  LZRead( lzfd, (LPSTR)sections, nSections * sizeof(IMAGE_SECTION_HEADER) ) )
318  {
320  return FALSE;
321  }
322 
323  /* Find resource section */
324  for ( i = 0; i < nSections; i++ )
325  if ( resDataDir->VirtualAddress >= sections[i].VirtualAddress
326  && resDataDir->VirtualAddress < sections[i].VirtualAddress +
327  sections[i].SizeOfRawData )
328  break;
329 
330  if ( i == nSections )
331  {
333  TRACE("Couldn't find resource section\n" );
334  return FALSE;
335  }
336 
337  /* Read in resource section */
338  data_size = sections[i].SizeOfRawData;
339  section_size = max( data_size, sections[i].Misc.VirtualSize );
340  resSection = HeapAlloc( GetProcessHeap(), 0, section_size );
341  if ( !resSection )
342  {
344  return FALSE;
345  }
346 
347  LZSeek( lzfd, sections[i].PointerToRawData, SEEK_SET );
348  if (data_size != LZRead( lzfd, (char*)resSection, data_size )) goto done;
349  if (data_size < section_size) memset( (char *)resSection + data_size, 0, section_size - data_size );
350 
351  /* Find resource */
352  resDir = resSection + (resDataDir->VirtualAddress - sections[i].VirtualAddress);
353 
354  resPtr = resDir;
355  resPtr = find_entry_by_id( resPtr, VS_FILE_INFO, resDir );
356  if ( !resPtr )
357  {
358  TRACE("No typeid entry found\n" );
359  goto done;
360  }
361  resPtr = find_entry_by_id( resPtr, VS_VERSION_INFO, resDir );
362  if ( !resPtr )
363  {
364  TRACE("No resid entry found\n" );
365  goto done;
366  }
367  resPtr = find_entry_language( resPtr, resDir, flags );
368  if ( !resPtr )
369  {
370  TRACE("No default language entry found\n" );
371  goto done;
372  }
373 
374  /* Find resource data section */
375  resData = (const IMAGE_RESOURCE_DATA_ENTRY*)resPtr;
376  for ( i = 0; i < nSections; i++ )
377  if ( resData->OffsetToData >= sections[i].VirtualAddress
378  && resData->OffsetToData < sections[i].VirtualAddress +
379  sections[i].SizeOfRawData )
380  break;
381 
382  if ( i == nSections )
383  {
384  TRACE("Couldn't find resource data section\n" );
385  goto done;
386  }
387 
388  /* Return resource data */
389  if ( resLen ) *resLen = resData->Size;
390  if ( resOff ) *resOff = resData->OffsetToData - sections[i].VirtualAddress
391  + sections[i].PointerToRawData;
392  ret = TRUE;
393 
394  done:
395  HeapFree( GetProcessHeap(), 0, resSection );
397  return ret;
398 }
399 
400 
401 /***********************************************************************
402  * find_version_resource [internal]
403  */
405 {
406  DWORD magic = read_xx_header( lzfd );
407 
408  switch (magic)
409  {
410  case IMAGE_OS2_SIGNATURE:
411  if (!find_ne_resource( lzfd, reslen, offset )) magic = 0;
412  break;
413  case IMAGE_NT_SIGNATURE:
414  if (!find_pe_resource( lzfd, reslen, offset, flags )) magic = 0;
415  break;
416  }
417  return magic;
418 }
419 
420 /******************************************************************************
421  *
422  * This function will print via standard TRACE, debug info regarding
423  * the file info structure vffi.
424  * 15-Feb-1998 Dimitrie Paun (dimi@cs.toronto.edu)
425  * Added this function to clean up the code.
426  *
427  *****************************************************************************/
428 static void print_vffi_debug(const VS_FIXEDFILEINFO *vffi)
429 {
430  BOOL versioned_printer = FALSE;
431 
432  if((vffi->dwFileType == VFT_DLL) || (vffi->dwFileType == VFT_DRV))
433  {
435  /* this is documented for newer w2k Drivers and up */
436  versioned_printer = TRUE;
437  else if( (vffi->dwFileSubtype == VFT2_DRV_PRINTER) &&
438  (vffi->dwFileVersionMS != vffi->dwProductVersionMS) &&
439  (vffi->dwFileVersionMS > 0) &&
440  (vffi->dwFileVersionMS <= 3) )
441  /* found this on NT 3.51, NT4.0 and old w2k Drivers */
442  versioned_printer = TRUE;
443  }
444 
445  TRACE("structversion=%u.%u, ",
447  if(versioned_printer)
448  {
449  WORD mode = LOWORD(vffi->dwFileVersionMS);
450  WORD ver_rev = HIWORD(vffi->dwFileVersionLS);
451  TRACE("fileversion=%u.%u.%u.%u (%s.major.minor.release), ",
452  (vffi->dwFileVersionMS),
453  HIBYTE(ver_rev), LOBYTE(ver_rev), LOWORD(vffi->dwFileVersionLS),
454  (mode == 3) ? "Usermode" : ((mode <= 2) ? "Kernelmode" : "?") );
455  }
456  else
457  {
458  TRACE("fileversion=%u.%u.%u.%u, ",
461  }
462  TRACE("productversion=%u.%u.%u.%u\n",
465 
466  TRACE("flagmask=0x%x, flags=0x%x %s%s%s%s%s%s\n",
467  vffi->dwFileFlagsMask, vffi->dwFileFlags,
468  (vffi->dwFileFlags & VS_FF_DEBUG) ? "DEBUG," : "",
469  (vffi->dwFileFlags & VS_FF_PRERELEASE) ? "PRERELEASE," : "",
470  (vffi->dwFileFlags & VS_FF_PATCHED) ? "PATCHED," : "",
471  (vffi->dwFileFlags & VS_FF_PRIVATEBUILD) ? "PRIVATEBUILD," : "",
472  (vffi->dwFileFlags & VS_FF_INFOINFERRED) ? "INFOINFERRED," : "",
473  (vffi->dwFileFlags & VS_FF_SPECIALBUILD) ? "SPECIALBUILD," : "");
474 
475  TRACE("(");
476 
477  TRACE("OS=0x%x.0x%x ", HIWORD(vffi->dwFileOS), LOWORD(vffi->dwFileOS));
478 
479  switch (vffi->dwFileOS&0xFFFF0000)
480  {
481  case VOS_DOS:TRACE("DOS,");break;
482  case VOS_OS216:TRACE("OS/2-16,");break;
483  case VOS_OS232:TRACE("OS/2-32,");break;
484  case VOS_NT:TRACE("NT,");break;
485  case VOS_UNKNOWN:
486  default:
487  TRACE("UNKNOWN(0x%x),",vffi->dwFileOS&0xFFFF0000);break;
488  }
489 
490  switch (LOWORD(vffi->dwFileOS))
491  {
492  case VOS__BASE:TRACE("BASE");break;
493  case VOS__WINDOWS16:TRACE("WIN16");break;
494  case VOS__WINDOWS32:TRACE("WIN32");break;
495  case VOS__PM16:TRACE("PM16");break;
496  case VOS__PM32:TRACE("PM32");break;
497  default:
498  TRACE("UNKNOWN(0x%x)",LOWORD(vffi->dwFileOS));break;
499  }
500 
501  TRACE(")\n");
502 
503  switch (vffi->dwFileType)
504  {
505  case VFT_APP:TRACE("filetype=APP");break;
506  case VFT_DLL:
507  TRACE("filetype=DLL");
508  if(vffi->dwFileSubtype != 0)
509  {
510  if(versioned_printer) /* NT3.x/NT4.0 or old w2k Driver */
511  TRACE(",PRINTER");
512  TRACE(" (subtype=0x%x)", vffi->dwFileSubtype);
513  }
514  break;
515  case VFT_DRV:
516  TRACE("filetype=DRV,");
517  switch(vffi->dwFileSubtype)
518  {
519  case VFT2_DRV_PRINTER:TRACE("PRINTER");break;
520  case VFT2_DRV_KEYBOARD:TRACE("KEYBOARD");break;
521  case VFT2_DRV_LANGUAGE:TRACE("LANGUAGE");break;
522  case VFT2_DRV_DISPLAY:TRACE("DISPLAY");break;
523  case VFT2_DRV_MOUSE:TRACE("MOUSE");break;
524  case VFT2_DRV_NETWORK:TRACE("NETWORK");break;
525  case VFT2_DRV_SYSTEM:TRACE("SYSTEM");break;
526  case VFT2_DRV_INSTALLABLE:TRACE("INSTALLABLE");break;
527  case VFT2_DRV_SOUND:TRACE("SOUND");break;
528  case VFT2_DRV_COMM:TRACE("COMM");break;
529  case VFT2_DRV_INPUTMETHOD:TRACE("INPUTMETHOD");break;
530  case VFT2_DRV_VERSIONED_PRINTER:TRACE("VERSIONED_PRINTER");break;
531  case VFT2_UNKNOWN:
532  default:
533  TRACE("UNKNOWN(0x%x)",vffi->dwFileSubtype);break;
534  }
535  break;
536  case VFT_FONT:
537  TRACE("filetype=FONT,");
538  switch (vffi->dwFileSubtype)
539  {
540  case VFT2_FONT_RASTER:TRACE("RASTER");break;
541  case VFT2_FONT_VECTOR:TRACE("VECTOR");break;
542  case VFT2_FONT_TRUETYPE:TRACE("TRUETYPE");break;
543  default:TRACE("UNKNOWN(0x%x)",vffi->dwFileSubtype);break;
544  }
545  break;
546  case VFT_VXD:TRACE("filetype=VXD");break;
547  case VFT_STATIC_LIB:TRACE("filetype=STATIC_LIB");break;
548  case VFT_UNKNOWN:
549  default:
550  TRACE("filetype=Unknown(0x%x)",vffi->dwFileType);break;
551  }
552 
553  TRACE("\n");
554  TRACE("filedate=0x%x.0x%x\n",vffi->dwFileDateMS,vffi->dwFileDateLS);
555 }
556 
557 /***********************************************************************
558  * Version Info Structure
559  */
560 
561 typedef struct
562 {
565  CHAR szKey[1];
566 #if 0 /* variable length structure */
567  /* DWORD aligned */
568  BYTE Value[];
569  /* DWORD aligned */
570  VS_VERSION_INFO_STRUCT16 Children[];
571 #endif
573 
574 typedef struct
575 {
578  WORD wType; /* 1:Text, 0:Binary */
579  WCHAR szKey[1];
580 #if 0 /* variable length structure */
581  /* DWORD aligned */
582  BYTE Value[];
583  /* DWORD aligned */
584  VS_VERSION_INFO_STRUCT32 Children[];
585 #endif
587 
588 #define VersionInfoIs16( ver ) \
589  ( ((const VS_VERSION_INFO_STRUCT16 *)ver)->szKey[0] >= ' ' )
590 
591 #define DWORD_ALIGN( base, ptr ) \
592  ( (LPBYTE)(base) + ((((LPBYTE)(ptr) - (LPBYTE)(base)) + 3) & ~3) )
593 
594 #define VersionInfo16_Value( ver ) \
595  DWORD_ALIGN( (ver), (ver)->szKey + strlen((ver)->szKey) + 1 )
596 #define VersionInfo32_Value( ver ) \
597  DWORD_ALIGN( (ver), (ver)->szKey + strlenW((ver)->szKey) + 1 )
598 
599 #define VersionInfo16_Children( ver ) \
600  (const VS_VERSION_INFO_STRUCT16 *)( VersionInfo16_Value( ver ) + \
601  ( ( (ver)->wValueLength + 3 ) & ~3 ) )
602 #define VersionInfo32_Children( ver ) \
603  (const VS_VERSION_INFO_STRUCT32 *)( VersionInfo32_Value( ver ) + \
604  ( ( (ver)->wValueLength * \
605  ((ver)->wType? 2 : 1) + 3 ) & ~3 ) )
606 
607 #define VersionInfo16_Next( ver ) \
608  (VS_VERSION_INFO_STRUCT16 *)( (LPBYTE)ver + (((ver)->wLength + 3) & ~3) )
609 #define VersionInfo32_Next( ver ) \
610  (VS_VERSION_INFO_STRUCT32 *)( (LPBYTE)ver + (((ver)->wLength + 3) & ~3) )
611 
612 
613 /***********************************************************************
614  * GetFileVersionInfoSizeW [VERSION.@]
615  */
617 {
619 }
620 
621 /***********************************************************************
622  * GetFileVersionInfoSizeA [VERSION.@]
623  */
625 {
627 }
628 
629 /******************************************************************************
630  * GetFileVersionInfoSizeExW [VERSION.@]
631  */
633 {
634  DWORD len, offset, magic = 1;
635  HFILE lzfd;
637  OFSTRUCT ofs;
638 
639  TRACE("(0x%x,%s,%p)\n", flags, debugstr_w(filename), handle );
640 
641  if (handle) *handle = 0;
642 
643  if (!filename)
644  {
646  return 0;
647  }
648  if (!*filename)
649  {
651  return 0;
652  }
654  FIXME("flags 0x%x ignored\n", flags & ~FILE_VER_GET_LOCALISED);
655 
656  if ((lzfd = LZOpenFileW( (LPWSTR)filename, &ofs, OF_READ )) != HFILE_ERROR)
657  {
658  magic = find_version_resource( lzfd, &len, &offset, flags );
659  LZClose( lzfd );
660  }
661 
663  {
664  HRSRC hRsrc = NULL;
665  if (!(flags & FILE_VER_GET_LOCALISED))
666  {
670  }
671  if (!hRsrc)
673  (LPWSTR)VS_FILE_INFO );
674  if (hRsrc)
675  {
677  len = SizeofResource( hModule, hRsrc );
678  }
679  FreeLibrary( hModule );
680  }
681 
682  switch (magic)
683  {
684  case IMAGE_OS2_SIGNATURE:
685  /* We have a 16bit resource.
686  *
687  * XP/W2K/W2K3 uses a buffer which is more than the actual needed space:
688  *
689  * (info->wLength - sizeof(VS_FIXEDFILEINFO)) * 4
690  *
691  * This extra buffer is used for ANSI to Unicode conversions in W-Calls.
692  * info->wLength should be the same as len. Currently it isn't but that
693  * doesn't seem to be a problem (len is bigger than info->wLength).
694  */
695  SetLastError(0);
696  return (len - sizeof(VS_FIXEDFILEINFO)) * 4;
697 
698  case IMAGE_NT_SIGNATURE:
699  /* We have a 32bit resource.
700  *
701  * XP/W2K/W2K3 uses a buffer which is 2 times the actual needed space + 4 bytes "FE2X"
702  * This extra buffer is used for Unicode to ANSI conversions in A-Calls
703  */
704  SetLastError(0);
705  return (len * 2) + 4;
706 
707  default:
708  if (lzfd == HFILE_ERROR)
709  SetLastError(ofs.nErrCode);
710  else if (GetVersion() & 0x80000000) /* Windows 95/98 */
712  else
714  return 0;
715  }
716 }
717 
718 /******************************************************************************
719  * GetFileVersionInfoSizeExA [VERSION.@]
720  */
722 {
724  DWORD retval;
725 
726  TRACE("(0x%x,%s,%p)\n", flags, debugstr_a(filename), handle );
727 
728  if(filename)
730  else
731  filenameW.Buffer = NULL;
732 
733  retval = GetFileVersionInfoSizeExW(flags, filenameW.Buffer, handle);
734 
736 
737  return retval;
738 }
739 
740 /***********************************************************************
741  * GetFileVersionInfoExW [VERSION.@]
742  */
744 {
745  static const char signature[4] = "FE2X";
746  DWORD len, offset, magic = 1;
747  HFILE lzfd;
748  OFSTRUCT ofs;
751 
752  TRACE("(0x%x,%s,%d,size=%d,data=%p)\n",
753  flags, debugstr_w(filename), handle, datasize, data );
754 
755  if (!data)
756  {
758  return FALSE;
759  }
761  FIXME("flags 0x%x ignored\n", flags & ~FILE_VER_GET_LOCALISED);
762 
763  if ((lzfd = LZOpenFileW( (LPWSTR)filename, &ofs, OF_READ )) != HFILE_ERROR)
764  {
765  if ((magic = find_version_resource( lzfd, &len, &offset, flags )) > 1)
766  {
767  LZSeek( lzfd, offset, 0 /* SEEK_SET */ );
768  len = LZRead( lzfd, data, min( len, datasize ) );
769  }
770  LZClose( lzfd );
771  }
772 
774  {
775  HRSRC hRsrc = NULL;
776  if (!(flags & FILE_VER_GET_LOCALISED))
777  {
781  }
782  if (!hRsrc)
784  (LPWSTR)VS_FILE_INFO );
785  if (hRsrc)
786  {
787  HGLOBAL hMem = LoadResource( hModule, hRsrc );
789  len = min( SizeofResource(hModule, hRsrc), datasize );
790  memcpy( data, LockResource( hMem ), len );
791  FreeResource( hMem );
792  }
793  FreeLibrary( hModule );
794  }
795 
796  switch (magic)
797  {
798  case IMAGE_OS2_SIGNATURE:
799  /* We have a 16bit resource. */
800  if (TRACE_ON(ver))
802  SetLastError(0);
803  return TRUE;
804 
805  case IMAGE_NT_SIGNATURE:
806  /* We have a 32bit resource.
807  *
808  * XP/W2K/W2K3 uses a buffer which is 2 times the actual needed space + 4 bytes "FE2X"
809  * This extra buffer is used for Unicode to ANSI conversions in A-Calls
810  */
811  len = vvis->wLength + sizeof(signature);
812  if (datasize >= len) memcpy( (char*)data + vvis->wLength, signature, sizeof(signature) );
813  if (TRACE_ON(ver))
815  SetLastError(0);
816  return TRUE;
817 
818  default:
820  return FALSE;
821  }
822 }
823 
824 /***********************************************************************
825  * GetFileVersionInfoExA [VERSION.@]
826  */
828 {
830  BOOL retval;
831 
832  TRACE("(0x%x,%s,%d,size=%d,data=%p)\n",
833  flags, debugstr_a(filename), handle, datasize, data );
834 
835  if(filename)
837  else
838  filenameW.Buffer = NULL;
839 
840  retval = GetFileVersionInfoExW(flags, filenameW.Buffer, handle, datasize, data);
841 
843 
844  return retval;
845 }
846 
847 /***********************************************************************
848  * GetFileVersionInfoW [VERSION.@]
849  */
851 {
853 }
854 
855 /***********************************************************************
856  * GetFileVersionInfoA [VERSION.@]
857  */
859 {
861 }
862 
863 /***********************************************************************
864  * VersionInfo16_FindChild [internal]
865  */
867  LPCSTR szKey, UINT cbKey )
868 {
870 
871  while ((char *)child < (char *)info + info->wLength )
872  {
873  if (!strncasecmp( child->szKey, szKey, cbKey ) && !child->szKey[cbKey])
874  return child;
875 
876  if (!(child->wLength)) return NULL;
878  }
879 
880  return NULL;
881 }
882 
883 /***********************************************************************
884  * VersionInfo32_FindChild [internal]
885  */
887  LPCWSTR szKey, UINT cbKey )
888 {
890 
891  while ((char *)child < (char *)info + info->wLength )
892  {
893  if (!strncmpiW( child->szKey, szKey, cbKey ) && !child->szKey[cbKey])
894  return child;
895 
896  if (!(child->wLength)) return NULL;
898  }
899 
900  return NULL;
901 }
902 
903 /***********************************************************************
904  * VersionInfo16_QueryValue [internal]
905  *
906  * Gets a value from a 16-bit NE resource
907  */
909  LPVOID *lplpBuffer, UINT *puLen )
910 {
911  while ( *lpSubBlock )
912  {
913  /* Find next path component */
914  LPCSTR lpNextSlash;
915  for ( lpNextSlash = lpSubBlock; *lpNextSlash; lpNextSlash++ )
916  if ( *lpNextSlash == '\\' )
917  break;
918 
919  /* Skip empty components */
920  if ( lpNextSlash == lpSubBlock )
921  {
922  lpSubBlock++;
923  continue;
924  }
925 
926  /* We have a non-empty component: search info for key */
927  info = VersionInfo16_FindChild( info, lpSubBlock, lpNextSlash-lpSubBlock );
928  if ( !info )
929  {
930  if (puLen) *puLen = 0 ;
932  return FALSE;
933  }
934 
935  /* Skip path component */
936  lpSubBlock = lpNextSlash;
937  }
938 
939  /* Return value */
940  *lplpBuffer = VersionInfo16_Value( info );
941  if (puLen)
942  *puLen = info->wValueLength;
943 
944  return TRUE;
945 }
946 
947 /***********************************************************************
948  * VersionInfo32_QueryValue [internal]
949  *
950  * Gets a value from a 32-bit PE resource
951  */
953  LPVOID *lplpBuffer, UINT *puLen, BOOL *pbText )
954 {
955  TRACE("lpSubBlock : (%s)\n", debugstr_w(lpSubBlock));
956 
957  while ( *lpSubBlock )
958  {
959  /* Find next path component */
960  LPCWSTR lpNextSlash;
961  for ( lpNextSlash = lpSubBlock; *lpNextSlash; lpNextSlash++ )
962  if ( *lpNextSlash == '\\' )
963  break;
964 
965  /* Skip empty components */
966  if ( lpNextSlash == lpSubBlock )
967  {
968  lpSubBlock++;
969  continue;
970  }
971 
972  /* We have a non-empty component: search info for key */
973  info = VersionInfo32_FindChild( info, lpSubBlock, lpNextSlash-lpSubBlock );
974  if ( !info )
975  {
976  if (puLen) *puLen = 0 ;
978  return FALSE;
979  }
980 
981  /* Skip path component */
982  lpSubBlock = lpNextSlash;
983  }
984 
985  /* Return value */
986  *lplpBuffer = VersionInfo32_Value( info );
987  if (puLen)
988  *puLen = info->wValueLength;
989  if (pbText)
990  *pbText = info->wType;
991 
992  return TRUE;
993 }
994 
995 /***********************************************************************
996  * VerQueryValueA [VERSION.@]
997  */
999  LPVOID *lplpBuffer, PUINT puLen )
1000 {
1001  static const char rootA[] = "\\";
1002  const VS_VERSION_INFO_STRUCT16 *info = pBlock;
1003 
1004  TRACE("(%p,%s,%p,%p)\n",
1005  pBlock, debugstr_a(lpSubBlock), lplpBuffer, puLen );
1006 
1007  if (!pBlock)
1008  return FALSE;
1009 
1010  if (lpSubBlock == NULL || lpSubBlock[0] == '\0')
1011  lpSubBlock = rootA;
1012 
1013  if ( !VersionInfoIs16( info ) )
1014  {
1015  BOOL ret, isText;
1016  INT len;
1017  LPWSTR lpSubBlockW;
1018  UINT value_len;
1019 
1020  len = MultiByteToWideChar(CP_ACP, 0, lpSubBlock, -1, NULL, 0);
1021  lpSubBlockW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1022 
1023  if (!lpSubBlockW)
1024  return FALSE;
1025 
1026  MultiByteToWideChar(CP_ACP, 0, lpSubBlock, -1, lpSubBlockW, len);
1027 
1028  ret = VersionInfo32_QueryValue(pBlock, lpSubBlockW, lplpBuffer, &value_len, &isText);
1029  if (puLen) *puLen = value_len;
1030 
1031  HeapFree(GetProcessHeap(), 0, lpSubBlockW);
1032 
1033  if (ret && isText)
1034  {
1035  /* Set lpBuffer so it points to the 'empty' area where we store
1036  * the converted strings
1037  */
1038  LPSTR lpBufferA = (LPSTR)pBlock + info->wLength + 4;
1039  DWORD pos = (LPCSTR)*lplpBuffer - (LPCSTR)pBlock;
1040  len = WideCharToMultiByte(CP_ACP, 0, *lplpBuffer, value_len,
1041  lpBufferA + pos, info->wLength - pos, NULL, NULL);
1042  *lplpBuffer = lpBufferA + pos;
1043  if (puLen) *puLen = len;
1044  }
1045  return ret;
1046  }
1047 
1048  return VersionInfo16_QueryValue(info, lpSubBlock, lplpBuffer, puLen);
1049 }
1050 
1051 /***********************************************************************
1052  * VerQueryValueW [VERSION.@]
1053  */
1055  LPVOID *lplpBuffer, PUINT puLen )
1056 {
1057  static const WCHAR rootW[] = { '\\', 0 };
1058  static const WCHAR varfileinfoW[] = { '\\','V','a','r','F','i','l','e','I','n','f','o',
1059  '\\','T','r','a','n','s','l','a','t','i','o','n', 0 };
1060 
1061  const VS_VERSION_INFO_STRUCT32 *info = pBlock;
1062 
1063  TRACE("(%p,%s,%p,%p)\n",
1064  pBlock, debugstr_w(lpSubBlock), lplpBuffer, puLen );
1065 
1066  if (!pBlock)
1067  return FALSE;
1068 
1069  if (!lpSubBlock || !lpSubBlock[0])
1070  lpSubBlock = rootW;
1071 
1072  if ( VersionInfoIs16( info ) )
1073  {
1074  BOOL ret;
1075  int len;
1076  LPSTR lpSubBlockA;
1077 
1078  len = WideCharToMultiByte(CP_ACP, 0, lpSubBlock, -1, NULL, 0, NULL, NULL);
1079  lpSubBlockA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
1080 
1081  if (!lpSubBlockA)
1082  return FALSE;
1083 
1084  WideCharToMultiByte(CP_ACP, 0, lpSubBlock, -1, lpSubBlockA, len, NULL, NULL);
1085 
1086  ret = VersionInfo16_QueryValue(pBlock, lpSubBlockA, lplpBuffer, puLen);
1087 
1088  HeapFree(GetProcessHeap(), 0, lpSubBlockA);
1089 
1090  if (ret && strcmpiW( lpSubBlock, rootW ) && strcmpiW( lpSubBlock, varfileinfoW ))
1091  {
1092  /* Set lpBuffer so it points to the 'empty' area where we store
1093  * the converted strings
1094  */
1095  LPWSTR lpBufferW = (LPWSTR)((LPSTR)pBlock + info->wLength);
1096  DWORD pos = (LPCSTR)*lplpBuffer - (LPCSTR)pBlock;
1097  DWORD max = (info->wLength - sizeof(VS_FIXEDFILEINFO)) * 4 - info->wLength;
1098 
1099  len = MultiByteToWideChar(CP_ACP, 0, *lplpBuffer, -1,
1100  lpBufferW + pos, max/sizeof(WCHAR) - pos );
1101  *lplpBuffer = lpBufferW + pos;
1102  if (puLen) *puLen = len;
1103  }
1104  return ret;
1105  }
1106 
1107  return VersionInfo32_QueryValue(info, lpSubBlock, lplpBuffer, puLen, NULL);
1108 }
1109 
1110 
1111 /******************************************************************************
1112  * testFileExistenceA
1113  *
1114  * Tests whether a given path/file combination exists. If the file does
1115  * not exist, the return value is zero. If it does exist, the return
1116  * value is non-zero.
1117  *
1118  * Revision history
1119  * 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1120  * Original implementation
1121  *
1122  */
1123 static int testFileExistenceA( char const * path, char const * file, BOOL excl )
1124 {
1125  char filename[1024];
1126  int filenamelen;
1128 
1129  fileinfo.cBytes = sizeof(OFSTRUCT);
1130 
1131  if (path)
1132  {
1133  strcpy(filename, path);
1134  filenamelen = strlen(filename);
1135 
1136  /* Add a trailing \ if necessary */
1137  if(filenamelen)
1138  {
1139  if(filename[filenamelen - 1] != '\\')
1140  strcat(filename, "\\");
1141  }
1142  else /* specify the current directory */
1143  strcpy(filename, ".\\");
1144  }
1145  else
1146  filename[0] = 0;
1147 
1148  /* Create the full pathname */
1149  strcat(filename, file);
1150 
1151  return (OpenFile(filename, &fileinfo,
1152  OF_EXIST | (excl ? OF_SHARE_EXCLUSIVE : 0)) != HFILE_ERROR);
1153 }
1154 
1155 /******************************************************************************
1156  * testFileExistenceW
1157  */
1158 static int testFileExistenceW( const WCHAR *path, const WCHAR *file, BOOL excl )
1159 {
1160  char *filename;
1161  DWORD pathlen, filelen;
1162  int ret;
1164 
1165  fileinfo.cBytes = sizeof(OFSTRUCT);
1166 
1167  pathlen = WideCharToMultiByte( CP_ACP, 0, path, -1, NULL, 0, NULL, NULL );
1168  filelen = WideCharToMultiByte( CP_ACP, 0, file, -1, NULL, 0, NULL, NULL );
1169  filename = HeapAlloc( GetProcessHeap(), 0, pathlen+filelen+2 );
1170 
1171  WideCharToMultiByte( CP_ACP, 0, path, -1, filename, pathlen, NULL, NULL );
1172  /* Add a trailing \ if necessary */
1173  if (pathlen > 1)
1174  {
1175  if (filename[pathlen-2] != '\\') strcpy( &filename[pathlen-1], "\\" );
1176  }
1177  else /* specify the current directory */
1178  strcpy(filename, ".\\");
1179 
1180  WideCharToMultiByte( CP_ACP, 0, file, -1, filename+strlen(filename), filelen, NULL, NULL );
1181 
1183  OF_EXIST | (excl ? OF_SHARE_EXCLUSIVE : 0)) != HFILE_ERROR);
1184  HeapFree( GetProcessHeap(), 0, filename );
1185  return ret;
1186 }
1187 
1188 /*****************************************************************************
1189  * VerFindFileA [VERSION.@]
1190  *
1191  * Determines where to install a file based on whether it locates another
1192  * version of the file in the system. The values VerFindFile returns are
1193  * used in a subsequent call to the VerInstallFile function.
1194  *
1195  * Revision history:
1196  * 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1197  * Reimplementation of VerFindFile from original stub.
1198  */
1200  DWORD flags,
1201  LPCSTR lpszFilename,
1202  LPCSTR lpszWinDir,
1203  LPCSTR lpszAppDir,
1204  LPSTR lpszCurDir,
1205  PUINT lpuCurDirLen,
1206  LPSTR lpszDestDir,
1207  PUINT lpuDestDirLen )
1208 {
1209  DWORD retval = 0;
1210  const char *curDir;
1211  const char *destDir;
1212  unsigned int curDirSizeReq;
1213  unsigned int destDirSizeReq;
1214  char winDir[MAX_PATH], systemDir[MAX_PATH];
1215 
1216  /* Print out debugging information */
1217  TRACE("flags = %x filename=%s windir=%s appdir=%s curdirlen=%p(%u) destdirlen=%p(%u)\n",
1218  flags, debugstr_a(lpszFilename), debugstr_a(lpszWinDir), debugstr_a(lpszAppDir),
1219  lpuCurDirLen, lpuCurDirLen ? *lpuCurDirLen : 0,
1220  lpuDestDirLen, lpuDestDirLen ? *lpuDestDirLen : 0 );
1221 
1222  /* Figure out where the file should go; shared files default to the
1223  system directory */
1224 
1225  GetSystemDirectoryA(systemDir, sizeof(systemDir));
1226  curDir = "";
1227 
1228  if(flags & VFFF_ISSHAREDFILE)
1229  {
1230  destDir = systemDir;
1231  /* Were we given a filename? If so, try to find the file. */
1232  if(lpszFilename)
1233  {
1234  if(testFileExistenceA(destDir, lpszFilename, FALSE)) curDir = destDir;
1235  else if(lpszAppDir && testFileExistenceA(lpszAppDir, lpszFilename, FALSE))
1236  curDir = lpszAppDir;
1237 
1238  if(!testFileExistenceA(systemDir, lpszFilename, FALSE))
1239  retval |= VFF_CURNEDEST;
1240  }
1241  }
1242  else /* not a shared file */
1243  {
1244  destDir = lpszAppDir ? lpszAppDir : "";
1245  if(lpszFilename)
1246  {
1247  GetWindowsDirectoryA( winDir, MAX_PATH );
1248  if(testFileExistenceA(destDir, lpszFilename, FALSE)) curDir = destDir;
1249  else if(testFileExistenceA(winDir, lpszFilename, FALSE))
1250  curDir = winDir;
1251  else if(testFileExistenceA(systemDir, lpszFilename, FALSE))
1252  curDir = systemDir;
1253 
1254  if (lpszAppDir && lpszAppDir[0])
1255  {
1256  if(!testFileExistenceA(lpszAppDir, lpszFilename, FALSE))
1257  retval |= VFF_CURNEDEST;
1258  }
1259  else if(testFileExistenceA(NULL, lpszFilename, FALSE))
1260  retval |= VFF_CURNEDEST;
1261  }
1262  }
1263 
1264  /* Check to see if the file exists and is in use by another application */
1265  if (lpszFilename && testFileExistenceA(curDir, lpszFilename, FALSE)) {
1266  if (lpszFilename && !testFileExistenceA(curDir, lpszFilename, TRUE))
1267  retval |= VFF_FILEINUSE;
1268  }
1269 
1270  curDirSizeReq = strlen(curDir) + 1;
1271  destDirSizeReq = strlen(destDir) + 1;
1272 
1273  /* Make sure that the pointers to the size of the buffers are
1274  valid; if not, do NOTHING with that buffer. If that pointer
1275  is valid, then make sure that the buffer pointer is valid, too! */
1276 
1277  if(lpuDestDirLen && lpszDestDir)
1278  {
1279  if (*lpuDestDirLen < destDirSizeReq) retval |= VFF_BUFFTOOSMALL;
1280  lstrcpynA(lpszDestDir, destDir, *lpuDestDirLen);
1281  *lpuDestDirLen = destDirSizeReq;
1282  }
1283  if(lpuCurDirLen && lpszCurDir)
1284  {
1285  if(*lpuCurDirLen < curDirSizeReq) retval |= VFF_BUFFTOOSMALL;
1286  lstrcpynA(lpszCurDir, curDir, *lpuCurDirLen);
1287  *lpuCurDirLen = curDirSizeReq;
1288  }
1289 
1290  TRACE("ret = %u (%s%s%s) curdir=%s destdir=%s\n", retval,
1291  (retval & VFF_CURNEDEST) ? "VFF_CURNEDEST " : "",
1292  (retval & VFF_FILEINUSE) ? "VFF_FILEINUSE " : "",
1293  (retval & VFF_BUFFTOOSMALL) ? "VFF_BUFFTOOSMALL " : "",
1294  debugstr_a(lpszCurDir), debugstr_a(lpszDestDir));
1295 
1296  return retval;
1297 }
1298 
1299 /*****************************************************************************
1300  * VerFindFileW [VERSION.@]
1301  */
1303  LPCWSTR lpszAppDir, LPWSTR lpszCurDir,PUINT lpuCurDirLen,
1304  LPWSTR lpszDestDir,PUINT lpuDestDirLen )
1305 {
1306  static const WCHAR emptyW;
1307  DWORD retval = 0;
1308  const WCHAR *curDir;
1309  const WCHAR *destDir;
1310  unsigned int curDirSizeReq;
1311  unsigned int destDirSizeReq;
1312  WCHAR winDir[MAX_PATH], systemDir[MAX_PATH];
1313 
1314  /* Print out debugging information */
1315  TRACE("flags = %x filename=%s windir=%s appdir=%s curdirlen=%p(%u) destdirlen=%p(%u)\n",
1316  flags, debugstr_w(lpszFilename), debugstr_w(lpszWinDir), debugstr_w(lpszAppDir),
1317  lpuCurDirLen, lpuCurDirLen ? *lpuCurDirLen : 0,
1318  lpuDestDirLen, lpuDestDirLen ? *lpuDestDirLen : 0 );
1319 
1320  /* Figure out where the file should go; shared files default to the
1321  system directory */
1322 
1323  GetSystemDirectoryW(systemDir, ARRAY_SIZE(systemDir));
1324  curDir = &emptyW;
1325 
1326  if(flags & VFFF_ISSHAREDFILE)
1327  {
1328  destDir = systemDir;
1329  /* Were we given a filename? If so, try to find the file. */
1330  if(lpszFilename)
1331  {
1332  if(testFileExistenceW(destDir, lpszFilename, FALSE)) curDir = destDir;
1333  else if(lpszAppDir && testFileExistenceW(lpszAppDir, lpszFilename, FALSE))
1334  {
1335  curDir = lpszAppDir;
1336  retval |= VFF_CURNEDEST;
1337  }
1338  }
1339  }
1340  else /* not a shared file */
1341  {
1342  destDir = lpszAppDir ? lpszAppDir : &emptyW;
1343  if(lpszFilename)
1344  {
1345  GetWindowsDirectoryW( winDir, MAX_PATH );
1346  if(testFileExistenceW(destDir, lpszFilename, FALSE)) curDir = destDir;
1347  else if(testFileExistenceW(winDir, lpszFilename, FALSE))
1348  {
1349  curDir = winDir;
1350  retval |= VFF_CURNEDEST;
1351  }
1352  else if(testFileExistenceW(systemDir, lpszFilename, FALSE))
1353  {
1354  curDir = systemDir;
1355  retval |= VFF_CURNEDEST;
1356  }
1357  }
1358  }
1359 
1360  if (lpszFilename && !testFileExistenceW(curDir, lpszFilename, TRUE))
1361  retval |= VFF_FILEINUSE;
1362 
1363  curDirSizeReq = strlenW(curDir) + 1;
1364  destDirSizeReq = strlenW(destDir) + 1;
1365 
1366  /* Make sure that the pointers to the size of the buffers are
1367  valid; if not, do NOTHING with that buffer. If that pointer
1368  is valid, then make sure that the buffer pointer is valid, too! */
1369 
1370  if(lpuDestDirLen && lpszDestDir)
1371  {
1372  if (*lpuDestDirLen < destDirSizeReq) retval |= VFF_BUFFTOOSMALL;
1373  lstrcpynW(lpszDestDir, destDir, *lpuDestDirLen);
1374  *lpuDestDirLen = destDirSizeReq;
1375  }
1376  if(lpuCurDirLen && lpszCurDir)
1377  {
1378  if(*lpuCurDirLen < curDirSizeReq) retval |= VFF_BUFFTOOSMALL;
1379  lstrcpynW(lpszCurDir, curDir, *lpuCurDirLen);
1380  *lpuCurDirLen = curDirSizeReq;
1381  }
1382 
1383  TRACE("ret = %u (%s%s%s) curdir=%s destdir=%s\n", retval,
1384  (retval & VFF_CURNEDEST) ? "VFF_CURNEDEST " : "",
1385  (retval & VFF_FILEINUSE) ? "VFF_FILEINUSE " : "",
1386  (retval & VFF_BUFFTOOSMALL) ? "VFF_BUFFTOOSMALL " : "",
1387  debugstr_w(lpszCurDir), debugstr_w(lpszDestDir));
1388  return retval;
1389 }
1390 
1391 static LPBYTE
1393  DWORD alloclen;
1394  LPBYTE buf;
1395  DWORD ret;
1396 
1397  alloclen = 1000;
1398  buf=HeapAlloc(GetProcessHeap(), 0, alloclen);
1399  if(buf == NULL) {
1400  WARN("Memory exhausted while fetching version info!\n");
1401  return NULL;
1402  }
1403  while (1) {
1404  ret = GetFileVersionInfoA(fn,0,alloclen,buf);
1405  if (!ret) {
1406  HeapFree(GetProcessHeap(), 0, buf);
1407  return NULL;
1408  }
1409  if (alloclen<*(WORD*)buf) {
1410  alloclen = *(WORD*)buf;
1411  HeapFree(GetProcessHeap(), 0, buf);
1412  buf = HeapAlloc(GetProcessHeap(), 0, alloclen);
1413  if(buf == NULL) {
1414  WARN("Memory exhausted while fetching version info!\n");
1415  return NULL;
1416  }
1417  } else {
1418  *vffi = (VS_FIXEDFILEINFO*)(buf+0x14);
1419  if ((*vffi)->dwSignature == 0x004f0049) /* hack to detect unicode */
1420  *vffi = (VS_FIXEDFILEINFO*)(buf+0x28);
1421  if ((*vffi)->dwSignature != VS_FFI_SIGNATURE)
1422  WARN("Bad VS_FIXEDFILEINFO signature 0x%08x\n",(*vffi)->dwSignature);
1423  return buf;
1424  }
1425  }
1426 }
1427 
1428 static DWORD
1430  switch (error) {
1431  case ERROR_ACCESS_DENIED:
1432  return VIF_ACCESSVIOLATION;
1434  return VIF_SHARINGVIOLATION;
1435  default:
1436  return 0;
1437  }
1438 }
1439 
1440 
1441 /******************************************************************************
1442  * VerInstallFileA [VERSION.@]
1443  */
1445  DWORD flags,LPCSTR srcfilename,LPCSTR destfilename,LPCSTR srcdir,
1446  LPCSTR destdir,LPCSTR curdir,LPSTR tmpfile,PUINT tmpfilelen )
1447 {
1448  LPCSTR pdest;
1449  char destfn[260],tmpfn[260],srcfn[260];
1450  HFILE hfsrc,hfdst;
1451  DWORD attr,xret,tmplast;
1452  LONG ret;
1453  LPBYTE buf1,buf2;
1454  OFSTRUCT ofs;
1455 
1456  TRACE("(%x,%s,%s,%s,%s,%s,%p,%d)\n",
1457  flags,debugstr_a(srcfilename),debugstr_a(destfilename),
1458  debugstr_a(srcdir),debugstr_a(destdir),debugstr_a(curdir),
1459  tmpfile,*tmpfilelen);
1460  xret = 0;
1461  if (!srcdir || !srcfilename) return VIF_CANNOTREADSRC;
1462  sprintf(srcfn,"%s\\%s",srcdir,srcfilename);
1463  if (!destdir || !*destdir) pdest = srcdir;
1464  else pdest = destdir;
1465  sprintf(destfn,"%s\\%s",pdest,destfilename);
1466  hfsrc=LZOpenFileA(srcfn,&ofs,OF_READ);
1467  if (hfsrc < 0)
1468  return VIF_CANNOTREADSRC;
1469  sprintf(tmpfn,"%s\\%s",pdest,destfilename);
1470  tmplast=strlen(pdest)+1;
1471  attr = GetFileAttributesA(tmpfn);
1472  if (attr != INVALID_FILE_ATTRIBUTES) {
1473  if (attr & FILE_ATTRIBUTE_READONLY) {
1474  LZClose(hfsrc);
1475  return VIF_WRITEPROT;
1476  }
1477  /* FIXME: check if file currently in use and return VIF_FILEINUSE */
1478  }
1480  if (flags & VIFF_FORCEINSTALL) {
1481  if (tmpfile[0]) {
1482  sprintf(tmpfn,"%s\\%s",pdest,tmpfile);
1483  tmplast = strlen(pdest)+1;
1484  attr = GetFileAttributesA(tmpfn);
1485  /* if it exists, it has been copied by the call before.
1486  * we jump over the copy part...
1487  */
1488  }
1489  }
1490  if (attr == INVALID_FILE_ATTRIBUTES) {
1491  char *s;
1492 
1493  GetTempFileNameA(pdest,"ver",0,tmpfn); /* should not fail ... */
1494  s=strrchr(tmpfn,'\\');
1495  if (s)
1496  tmplast = s-tmpfn;
1497  else
1498  tmplast = 0;
1499  hfdst = OpenFile(tmpfn,&ofs,OF_CREATE);
1500  if (hfdst == HFILE_ERROR) {
1501  LZClose(hfsrc);
1502  return VIF_CANNOTCREATE; /* | translated dos error */
1503  }
1504  ret = LZCopy(hfsrc,hfdst);
1505  _lclose(hfdst);
1506  if (ret < 0) {
1507  /* translate LZ errors into VIF_xxx */
1508  switch (ret) {
1509  case LZERROR_BADINHANDLE:
1510  case LZERROR_READ:
1511  case LZERROR_BADVALUE:
1512  case LZERROR_UNKNOWNALG:
1513  xret = VIF_CANNOTREADSRC;
1514  break;
1515  case LZERROR_BADOUTHANDLE:
1516  case LZERROR_WRITE:
1517  xret = VIF_OUTOFSPACE;
1518  break;
1519  case LZERROR_GLOBALLOC:
1520  case LZERROR_GLOBLOCK:
1521  xret = VIF_OUTOFMEMORY;
1522  break;
1523  default: /* unknown error, should not happen */
1524  FIXME("Unknown LZCopy error %d, ignoring.\n", ret);
1525  xret = 0;
1526  break;
1527  }
1528  if (xret) {
1529  LZClose(hfsrc);
1530  return xret;
1531  }
1532  }
1533  }
1534  if (!(flags & VIFF_FORCEINSTALL)) {
1535  VS_FIXEDFILEINFO *destvffi,*tmpvffi;
1536  buf1 = _fetch_versioninfo(destfn,&destvffi);
1537  if (buf1) {
1538  buf2 = _fetch_versioninfo(tmpfn,&tmpvffi);
1539  if (buf2) {
1540  char *tbuf1,*tbuf2;
1541  static const CHAR trans_array[] = "\\VarFileInfo\\Translation";
1542  UINT len1,len2;
1543 
1544  len1=len2=40;
1545 
1546  /* compare file versions */
1547  if ((destvffi->dwFileVersionMS > tmpvffi->dwFileVersionMS)||
1548  ((destvffi->dwFileVersionMS==tmpvffi->dwFileVersionMS)&&
1549  (destvffi->dwFileVersionLS > tmpvffi->dwFileVersionLS)
1550  )
1551  )
1552  xret |= VIF_MISMATCH|VIF_SRCOLD;
1553  /* compare filetypes and filesubtypes */
1554  if ((destvffi->dwFileType!=tmpvffi->dwFileType) ||
1555  (destvffi->dwFileSubtype!=tmpvffi->dwFileSubtype)
1556  )
1557  xret |= VIF_MISMATCH|VIF_DIFFTYPE;
1558  if (VerQueryValueA(buf1,trans_array,(LPVOID*)&tbuf1,&len1) &&
1559  VerQueryValueA(buf2,trans_array,(LPVOID*)&tbuf2,&len2)
1560  ) {
1561  /* Do something with tbuf1 and tbuf2
1562  * generates DIFFLANG|MISMATCH
1563  */
1564  }
1565  HeapFree(GetProcessHeap(), 0, buf2);
1566  } else
1567  xret=VIF_MISMATCH|VIF_SRCOLD;
1568  HeapFree(GetProcessHeap(), 0, buf1);
1569  }
1570  }
1571  if (xret) {
1572  if (*tmpfilelen<strlen(tmpfn+tmplast)) {
1573  xret|=VIF_BUFFTOOSMALL;
1574  DeleteFileA(tmpfn);
1575  } else {
1576  strcpy(tmpfile,tmpfn+tmplast);
1577  *tmpfilelen = strlen(tmpfn+tmplast)+1;
1578  xret|=VIF_TEMPFILE;
1579  }
1580  } else {
1582  if (!DeleteFileA(destfn)) {
1584  DeleteFileA(tmpfn);
1585  LZClose(hfsrc);
1586  return xret;
1587  }
1588  if ((!(flags & VIFF_DONTDELETEOLD)) &&
1589  curdir &&
1590  *curdir &&
1591  lstrcmpiA(curdir,pdest)
1592  ) {
1593  char curfn[260];
1594 
1595  sprintf(curfn,"%s\\%s",curdir,destfilename);
1597  /* FIXME: check if in use ... if it is, VIF_CANNOTDELETECUR */
1598  if (!DeleteFileA(curfn))
1600  }
1601  }
1602  if (!MoveFileA(tmpfn,destfn)) {
1604  DeleteFileA(tmpfn);
1605  }
1606  }
1607  LZClose(hfsrc);
1608  return xret;
1609 }
1610 
1611 
1612 /******************************************************************************
1613  * VerInstallFileW [VERSION.@]
1614  */
1616  DWORD flags,LPCWSTR srcfilename,LPCWSTR destfilename,LPCWSTR srcdir,
1617  LPCWSTR destdir,LPCWSTR curdir,LPWSTR tmpfile,PUINT tmpfilelen )
1618 {
1619  LPSTR wsrcf = NULL, wsrcd = NULL, wdestf = NULL, wdestd = NULL, wtmpf = NULL, wcurd = NULL;
1620  DWORD ret = 0;
1621  UINT len;
1622 
1623  if (srcfilename)
1624  {
1625  len = WideCharToMultiByte( CP_ACP, 0, srcfilename, -1, NULL, 0, NULL, NULL );
1626  if ((wsrcf = HeapAlloc( GetProcessHeap(), 0, len )))
1627  WideCharToMultiByte( CP_ACP, 0, srcfilename, -1, wsrcf, len, NULL, NULL );
1628  else
1629  ret = VIF_OUTOFMEMORY;
1630  }
1631  if (srcdir && !ret)
1632  {
1633  len = WideCharToMultiByte( CP_ACP, 0, srcdir, -1, NULL, 0, NULL, NULL );
1634  if ((wsrcd = HeapAlloc( GetProcessHeap(), 0, len )))
1635  WideCharToMultiByte( CP_ACP, 0, srcdir, -1, wsrcd, len, NULL, NULL );
1636  else
1637  ret = VIF_OUTOFMEMORY;
1638  }
1639  if (destfilename && !ret)
1640  {
1641  len = WideCharToMultiByte( CP_ACP, 0, destfilename, -1, NULL, 0, NULL, NULL );
1642  if ((wdestf = HeapAlloc( GetProcessHeap(), 0, len )))
1643  WideCharToMultiByte( CP_ACP, 0, destfilename, -1, wdestf, len, NULL, NULL );
1644  else
1645  ret = VIF_OUTOFMEMORY;
1646  }
1647  if (destdir && !ret)
1648  {
1649  len = WideCharToMultiByte( CP_ACP, 0, destdir, -1, NULL, 0, NULL, NULL );
1650  if ((wdestd = HeapAlloc( GetProcessHeap(), 0, len )))
1651  WideCharToMultiByte( CP_ACP, 0, destdir, -1, wdestd, len, NULL, NULL );
1652  else
1653  ret = VIF_OUTOFMEMORY;
1654  }
1655  if (curdir && !ret)
1656  {
1657  len = WideCharToMultiByte( CP_ACP, 0, curdir, -1, NULL, 0, NULL, NULL );
1658  if ((wcurd = HeapAlloc( GetProcessHeap(), 0, len )))
1659  WideCharToMultiByte( CP_ACP, 0, curdir, -1, wcurd, len, NULL, NULL );
1660  else
1661  ret = VIF_OUTOFMEMORY;
1662  }
1663  if (!ret)
1664  {
1665  len = *tmpfilelen * sizeof(WCHAR);
1666  wtmpf = HeapAlloc( GetProcessHeap(), 0, len );
1667  if (!wtmpf)
1668  ret = VIF_OUTOFMEMORY;
1669  }
1670  if (!ret)
1671  ret = VerInstallFileA(flags,wsrcf,wdestf,wsrcd,wdestd,wcurd,wtmpf,&len);
1672  if (!ret)
1673  *tmpfilelen = MultiByteToWideChar( CP_ACP, 0, wtmpf, -1, tmpfile, *tmpfilelen );
1674  else if (ret & VIF_BUFFTOOSMALL)
1675  *tmpfilelen = len; /* FIXME: not correct */
1676 
1677  HeapFree( GetProcessHeap(), 0, wsrcf );
1678  HeapFree( GetProcessHeap(), 0, wsrcd );
1679  HeapFree( GetProcessHeap(), 0, wdestf );
1680  HeapFree( GetProcessHeap(), 0, wdestd );
1681  HeapFree( GetProcessHeap(), 0, wtmpf );
1682  HeapFree( GetProcessHeap(), 0, wcurd );
1683  return ret;
1684 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
struct _VS_VERSION_INFO_STRUCT32 VS_VERSION_INFO_STRUCT32
#define VOS__PM32
Definition: verrsrc.h:63
#define SEEK_CUR
Definition: util.h:63
#define VIF_CANNOTRENAME
Definition: verrsrc.h:131
GLdouble GLdouble u2
Definition: glext.h:8308
#define max(a, b)
Definition: svc.c:63
static void print_vffi_debug(const VS_FIXEDFILEINFO *vffi)
Definition: version.c:428
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
#define VOS__WINDOWS32
Definition: verrsrc.h:64
WORD offset
Definition: typelib.c:84
#define VFT_FONT
Definition: verrsrc.h:78
#define VIF_TEMPFILE
Definition: verrsrc.h:118
#define VFT_DLL
Definition: verrsrc.h:76
BOOL WINAPI GetFileVersionInfoExW(DWORD flags, LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:743
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define OF_READ
Definition: winbase.h:116
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define VIF_BUFFTOOSMALL
Definition: verrsrc.h:136
#define VIF_DIFFTYPE
Definition: verrsrc.h:123
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
#define VFT2_DRV_MOUSE
Definition: verrsrc.h:89
#define WideCharToMultiByte
Definition: compat.h:101
#define error(str)
Definition: mkdosfs.c:1605
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define LOBYTE(W)
Definition: jmemdos.c:487
DWORD WINAPI VerInstallFileW(DWORD flags, LPCWSTR srcfilename, LPCWSTR destfilename, LPCWSTR srcdir, LPCWSTR destdir, LPCWSTR curdir, LPWSTR tmpfile, PUINT tmpfilelen)
Definition: version.c:1615
DWORD dwFileDateMS
Definition: compat.h:560
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define VIF_OUTOFMEMORY
Definition: verrsrc.h:133
#define LANG_NEUTRAL
Definition: nls.h:22
static const WCHAR rootW[]
Definition: chain.c:69
struct tagVS_FIXEDFILEINFO VS_FIXEDFILEINFO
#define CP_ACP
Definition: compat.h:99
static BOOL VersionInfo16_QueryValue(const VS_VERSION_INFO_STRUCT16 *info, LPCSTR lpSubBlock, LPVOID *lplpBuffer, UINT *puLen)
Definition: version.c:908
GLuint GLuint GLsizei count
Definition: gl.h:1545
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
#define VFFF_ISSHAREDFILE
Definition: verrsrc.h:105
char CHAR
Definition: xmlstorage.h:175
#define WARN(fmt,...)
Definition: debug.h:111
#define VFT2_DRV_LANGUAGE
Definition: verrsrc.h:87
#define SUBLANG_DEFAULT
Definition: nls.h:168
static int push_language(WORD *list, int pos, WORD lang)
Definition: version.c:117
GLintptr offset
Definition: glext.h:5920
#define VS_FF_DEBUG
Definition: verrsrc.h:42
DWORD dwFileVersionLS
Definition: compat.h:552
#define HIBYTE(W)
Definition: jmemdos.c:486
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: ntimage.h:376
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2282
u32_t magic(void)
BOOL WINAPI MoveFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName)
Definition: move.c:1077
#define VIF_OUTOFSPACE
Definition: verrsrc.h:126
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define VFT2_DRV_NETWORK
Definition: verrsrc.h:90
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
#define VS_FFI_SIGNATURE
Definition: verrsrc.h:37
#define VFT_DRV
Definition: verrsrc.h:77
#define VS_FF_PATCHED
Definition: verrsrc.h:44
#define VFT2_UNKNOWN
Definition: verrsrc.h:84
static int testFileExistenceW(const WCHAR *path, const WCHAR *file, BOOL excl)
Definition: version.c:1158
static DWORD _error2vif(DWORD error)
Definition: version.c:1429
WORD LANGID
Definition: typedefs.h:79
#define VOS__PM16
Definition: verrsrc.h:62
#define VIF_CANNOTDELETE
Definition: verrsrc.h:130
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
BOOL WINAPI VerQueryValueA(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:998
#define VersionInfo32_Next(ver)
Definition: version.c:609
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
HFILE WINAPI LZOpenFileW(LPWSTR fn, LPOFSTRUCT ofs, WORD mode)
Definition: lzexpand.c:585
char * LPSTR
Definition: xmlstorage.h:182
#define SUBLANG_NEUTRAL
Definition: nls.h:167
const char * filename
Definition: ioapi.h:135
DWORD WINAPI GetFileVersionInfoSizeExA(DWORD flags, LPCSTR filename, LPDWORD handle)
Definition: version.c:721
int32_t INT
Definition: typedefs.h:56
#define LZERROR_READ
Definition: lzexpand.h:9
static HWND child
Definition: cursoricon.c:298
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
int WINAPI _lclose(HFILE hFile)
Definition: lfile.c:138
DWORD WINAPI GetVersion(VOID)
Definition: version.c:22
#define lstrcpynW
Definition: compat.h:397
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2351
#define VOS_OS232
Definition: verrsrc.h:55
void WINAPI LZClose(HFILE fd)
Definition: lzexpand.c:600
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
static const WCHAR filenameW[]
Definition: amstream.c:41
#define sprintf(buf, format,...)
Definition: sprintf.c:55
struct _OFSTRUCT OFSTRUCT
WORD id
Definition: typelib.c:87
#define VFF_BUFFTOOSMALL
Definition: verrsrc.h:110
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define VFT2_FONT_VECTOR
Definition: verrsrc.h:100
DWORD dwStrucVersion
Definition: compat.h:550
#define HFILE_ERROR
Definition: winbase.h:111
unsigned char * LPBYTE
Definition: typedefs.h:52
#define VIF_SHARINGVIOLATION
Definition: verrsrc.h:128
#define VersionInfoIs16(ver)
Definition: version.c:588
#define VS_FF_PRERELEASE
Definition: verrsrc.h:43
#define VFF_CURNEDEST
Definition: verrsrc.h:108
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
#define VIFF_FORCEINSTALL
Definition: verrsrc.h:114
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:786
struct section sections[2]
Definition: diskspace.c:792
#define debugstr_w
Definition: kernel32.h:32
#define VOS_DOS
Definition: verrsrc.h:53
#define FIXME(fmt,...)
Definition: debug.h:110
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
#define VFT_VXD
Definition: verrsrc.h:79
DWORD dwFileFlagsMask
Definition: compat.h:555
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
#define strncasecmp
Definition: fake.h:10
WORD nErrCode
Definition: winbase.h:1244
DWORD WINAPI VerInstallFileA(DWORD flags, LPCSTR srcfilename, LPCSTR destfilename, LPCSTR srcdir, LPCSTR destdir, LPCSTR curdir, LPSTR tmpfile, PUINT tmpfilelen)
Definition: version.c:1444
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
Definition: pedump.c:457
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
unsigned int dir
Definition: maze.c:112
const char * LPCSTR
Definition: xmlstorage.h:183
#define VersionInfo16_Value(ver)
Definition: version.c:594
#define VersionInfo32_Value(ver)
Definition: version.c:596
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define VersionInfo32_Children(ver)
Definition: version.c:602
#define VOS__WINDOWS16
Definition: verrsrc.h:61
#define VFT2_FONT_RASTER
Definition: verrsrc.h:99
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
static const WCHAR lang[]
Definition: wbemdisp.c:287
_Check_return_ _CRTIMP FILE *__cdecl tmpfile(void)
Definition: file.c:3912
static int testFileExistenceA(char const *path, char const *file, BOOL excl)
Definition: version.c:1123
HFILE WINAPI OpenFile(LPCSTR lpFileName, LPOFSTRUCT lpReOpenBuff, UINT uStyle)
Definition: create.c:368
#define VIF_WRITEPROT
Definition: verrsrc.h:124
#define VFT2_DRV_SOUND
Definition: verrsrc.h:93
DWORD OffsetToData
Definition: pedump.c:459
#define SEEK_SET
Definition: jmemansi.c:26
#define VS_FF_PRIVATEBUILD
Definition: verrsrc.h:45
#define LZERROR_GLOBLOCK
Definition: lzexpand.h:12
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:405
static BOOL VersionInfo32_QueryValue(const VS_VERSION_INFO_STRUCT32 *info, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, UINT *puLen, BOOL *pbText)
Definition: version.c:952
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD dwFileDateLS
Definition: compat.h:561
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define debugstr_a
Definition: kernel32.h:31
#define VersionInfo16_Next(ver)
Definition: version.c:607
#define VFT2_DRV_PRINTER
Definition: verrsrc.h:85
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
HFILE WINAPI LZOpenFileA(LPSTR fn, LPOFSTRUCT ofs, WORD mode)
Definition: lzexpand.c:556
DWORD WINAPI GetFileVersionInfoSizeA(LPCSTR filename, LPDWORD handle)
Definition: version.c:624
DWORD WINAPI GetFileVersionInfoSizeExW(DWORD flags, LPCWSTR filename, LPDWORD handle)
Definition: version.c:632
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
DWORD dwFileSubtype
Definition: compat.h:559
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
LANGID WINAPI GetSystemDefaultLangID(void)
Definition: lang.c:751
static LPBYTE _fetch_versioninfo(LPSTR fn, VS_FIXEDFILEINFO **vffi)
Definition: version.c:1392
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD dwFileVersionMS
Definition: compat.h:551
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
DWORD WINAPI VerFindFileW(DWORD flags, LPCWSTR lpszFilename, LPCWSTR lpszWinDir, LPCWSTR lpszAppDir, LPWSTR lpszCurDir, PUINT lpuCurDirLen, LPWSTR lpszDestDir, PUINT lpuDestDirLen)
Definition: version.c:1302
#define SetLastError(x)
Definition: compat.h:409
Definition: cookie.c:170
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
type_id
#define LANG_ENGLISH
Definition: nls.h:52
BOOL WINAPI GetFileVersionInfoA(LPCSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:858
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
int ret
#define LZERROR_BADVALUE
Definition: lzexpand.h:13
#define VIF_CANNOTREADSRC
Definition: verrsrc.h:134
__u8 attr
Definition: mkdosfs.c:359
DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR filename, LPDWORD handle)
Definition: version.c:616
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
#define IMAGE_OS2_SIGNATURE
Definition: pedump.c:90
#define LANGIDFROMLCID(l)
Definition: nls.h:18
unsigned char BYTE
Definition: mem.h:68
static const IMAGE_RESOURCE_DIRECTORY * find_entry_default(const IMAGE_RESOURCE_DIRECTORY *dir, const void *root)
Definition: version.c:102
#define VFT2_DRV_COMM
Definition: verrsrc.h:94
GLdouble s
Definition: gl.h:2039
#define LZERROR_BADOUTHANDLE
Definition: lzexpand.h:8
Definition: _list.h:228
#define VFT_STATIC_LIB
Definition: verrsrc.h:81
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
LONG WINAPI LZSeek(HFILE fd, LONG off, INT type)
Definition: lzexpand.c:436
INT WINAPI LZRead(HFILE fd, LPSTR vbuf, INT toread)
Definition: lzexpand.c:345
GLenum mode
Definition: glext.h:6217
static int read_xx_header(HFILE lzfd)
Definition: version.c:163
WORD length
Definition: typelib.c:85
#define strcmpiW(s1, s2)
Definition: unicode.h:39
Definition: pedump.c:413
#define ERROR_INVALID_DATA
Definition: winerror.h:116
LONG WINAPI LZCopy(HFILE src, HFILE dest)
Definition: lzexpand.c:472
#define VS_FF_INFOINFERRED
Definition: verrsrc.h:46
DWORD WINAPI VerFindFileA(DWORD flags, LPCSTR lpszFilename, LPCSTR lpszWinDir, LPCSTR lpszAppDir, LPSTR lpszCurDir, PUINT lpuCurDirLen, LPSTR lpszDestDir, PUINT lpuDestDirLen)
Definition: version.c:1199
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:338
#define VIF_ACCESSVIOLATION
Definition: verrsrc.h:127
#define OF_EXIST
Definition: winbase.h:127
#define VFF_FILEINUSE
Definition: verrsrc.h:109
#define VFT2_DRV_VERSIONED_PRINTER
Definition: verrsrc.h:96
WORD count
Definition: typelib.c:95
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
static const WCHAR emptyW[]
Definition: navigate.c:36
#define VIF_MISMATCH
Definition: verrsrc.h:119
static DWORD find_version_resource(HFILE lzfd, DWORD *reslen, DWORD *offset, DWORD flags)
Definition: version.c:404
#define VOS_OS216
Definition: verrsrc.h:54
#define ARRAY_SIZE(a)
Definition: main.h:24
#define VOS_NT
Definition: verrsrc.h:56
#define VIF_CANNOTDELETECUR
Definition: verrsrc.h:132
#define LZERROR_UNKNOWNALG
Definition: lzexpand.h:14
Definition: services.c:325
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2336
#define VFT2_DRV_INSTALLABLE
Definition: verrsrc.h:92
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
#define VFT2_DRV_KEYBOARD
Definition: verrsrc.h:86
#define VS_FILE_INFO
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
DWORD dwProductVersionLS
Definition: compat.h:554
#define VS_VERSION_INFO
WORD type_id
Definition: typelib.c:94
#define FILE_VER_GET_LOCALISED
Definition: verrsrc.h:147
#define lstrcpynA
Definition: compat.h:408
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
#define MultiByteToWideChar
Definition: compat.h:100
#define VIF_SRCOLD
Definition: verrsrc.h:120
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:850
#define VOS__BASE
Definition: verrsrc.h:60
static const LCID english
Definition: wbemdisp.c:32
#define VFT2_DRV_INPUTMETHOD
Definition: verrsrc.h:95
static const VS_VERSION_INFO_STRUCT16 * VersionInfo16_FindChild(const VS_VERSION_INFO_STRUCT16 *info, LPCSTR szKey, UINT cbKey)
Definition: version.c:866
CONST void * LPCVOID
Definition: windef.h:191
#define VFT_UNKNOWN
Definition: verrsrc.h:74
#define VIFF_DONTDELETEOLD
Definition: verrsrc.h:115
#define OF_CREATE
Definition: winbase.h:125
uint32_t * LPDWORD
Definition: typedefs.h:57
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static DWORD LPDWORD reslen
Definition: directory.c:51
#define HIWORD(l)
Definition: typedefs.h:246
GLenum GLuint id
Definition: glext.h:5579
#define MAKELANGID(p, s)
Definition: nls.h:15
LANGID WINAPI GetUserDefaultLangID(void)
Definition: lang.c:734
#define LZERROR_GLOBALLOC
Definition: lzexpand.h:11
#define VS_FF_SPECIALBUILD
Definition: verrsrc.h:47
static const VS_VERSION_INFO_STRUCT32 * VersionInfo32_FindChild(const VS_VERSION_INFO_STRUCT32 *info, LPCWSTR szKey, UINT cbKey)
Definition: version.c:886
#define VFT2_DRV_DISPLAY
Definition: verrsrc.h:88
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IMAGE_DIRECTORY_ENTRY_RESOURCE
Definition: pedump.c:261
#define VFT_APP
Definition: verrsrc.h:75
static const IMAGE_RESOURCE_DIRECTORY * find_entry_by_id(const IMAGE_RESOURCE_DIRECTORY *dir, WORD id, const void *root)
Definition: version.c:75
#define memset(x, y, z)
Definition: compat.h:39
DWORD dwProductVersionMS
Definition: compat.h:553
#define TRACE_ON(x)
Definition: compat.h:65
int HFILE
Definition: windef.h:283
#define ERROR_BAD_PATHNAME
Definition: winerror.h:233
#define LOWORD(l)
Definition: pedump.c:82
static BOOL find_pe_resource(HFILE lzfd, DWORD *resLen, DWORD *resOff, DWORD flags)
Definition: version.c:265
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
WINE_DEFAULT_DEBUG_CHANNEL(ver)
#define HeapFree(x, y, z)
Definition: compat.h:394
#define VersionInfo16_Children(ver)
Definition: version.c:599
BOOL WINAPI GetFileVersionInfoExA(DWORD flags, LPCSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:827
static const IMAGE_RESOURCE_DIRECTORY * find_entry_language(const IMAGE_RESOURCE_DIRECTORY *dir, const void *root, DWORD flags)
Definition: version.c:129
#define LZERROR_BADINHANDLE
Definition: lzexpand.h:7
static BOOL find_ne_resource(HFILE lzfd, DWORD *resLen, DWORD *resOff)
Definition: version.c:197
unsigned int * PUINT
Definition: ndis.h:50
#define ERROR_RESOURCE_DATA_NOT_FOUND
Definition: winerror.h:1119
#define OF_SHARE_EXCLUSIVE
Definition: winbase.h:123
#define ERROR_RESOURCE_TYPE_NOT_FOUND
Definition: winerror.h:1120
#define VFT2_DRV_SYSTEM
Definition: verrsrc.h:91
HMODULE hModule
Definition: animate.c:44
#define VOS_UNKNOWN
Definition: verrsrc.h:52
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1054
#define LZERROR_WRITE
Definition: lzexpand.h:10
#define PRIMARYLANGID(l)
Definition: nls.h:16
DWORD Size
Definition: pedump.c:460
Definition: fci.c:126
#define VFT2_FONT_TRUETYPE
Definition: verrsrc.h:101
#define VIF_CANNOTCREATE
Definition: verrsrc.h:129