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