ReactOS  0.4.14-dev-49-gfb4591c
res.c
Go to the documentation of this file.
1 /*
2  * Resources
3  *
4  * Copyright 1993 Robert J. Amstadt
5  * Copyright 1995, 2003 Alexandre Julliard
6  * Copyright 2006 Mike McCormack
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include <k32.h>
24 
25 #include <wine/list.h>
26 
27 #define NDEBUG
28 #include <debug.h>
30 
31 /* retrieve the resource name to pass to the ntdll functions */
33 {
34  if (IS_INTRESOURCE(name))
35  {
36  str->Buffer = ULongToPtr(LOWORD(name));
37  return STATUS_SUCCESS;
38  }
39  if (name[0] == '#')
40  {
41  ULONG value;
42  if (RtlCharToInteger( name + 1, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
44  str->Buffer = ULongToPtr(value);
45  return STATUS_SUCCESS;
46  }
49  return STATUS_SUCCESS;
50 }
51 
52 /* retrieve the resource name to pass to the ntdll functions */
54 {
55  if (IS_INTRESOURCE(name))
56  {
57  str->Buffer = ULongToPtr(LOWORD(name));
58  return STATUS_SUCCESS;
59  }
60  if (name[0] == '#')
61  {
62  ULONG value;
66  str->Buffer = ULongToPtr(value);
67  return STATUS_SUCCESS;
68  }
71  return STATUS_SUCCESS;
72 }
73 
74 /* implementation of FindResourceExA */
76 {
81 
82  nameW.Buffer = NULL;
83  typeW.Buffer = NULL;
84 
85  __TRY
86  {
87  if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS) goto done;
88  if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS) goto done;
89  info.Type = (ULONG_PTR)typeW.Buffer;
90  info.Name = (ULONG_PTR)nameW.Buffer;
91  info.Language = lang;
93  done:
95  }
97  {
99  }
100  __ENDTRY
101 
102  if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
103  if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
104  return (HRSRC)entry;
105 }
106 
107 
108 /* implementation of FindResourceExW */
110 {
115 
116  nameW.Buffer = typeW.Buffer = NULL;
117 
118  __TRY
119  {
120  if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS) goto done;
121  if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS) goto done;
122  info.Type = (ULONG_PTR)typeW.Buffer;
123  info.Name = (ULONG_PTR)nameW.Buffer;
124  info.Language = lang;
126  done:
128  }
130  {
132  }
133  __ENDTRY
134 
135  if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
136  if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
137  return (HRSRC)entry;
138 }
139 
140 /**********************************************************************
141  * FindResourceExA (KERNEL32.@)
142  */
144 {
145  TRACE( "%p %s %s %04x\n", hModule, debugstr_a(type), debugstr_a(name), lang );
146 
147  if (!hModule) hModule = GetModuleHandleW(0);
148  return find_resourceA( hModule, type, name, lang );
149 }
150 
151 
152 /**********************************************************************
153  * FindResourceA (KERNEL32.@)
154  */
156 {
158 }
159 
160 
161 /**********************************************************************
162  * FindResourceExW (KERNEL32.@)
163  */
165 {
166  TRACE( "%p %s %s %04x\n", hModule, debugstr_w(type), debugstr_w(name), lang );
167 
168  if (!hModule) hModule = GetModuleHandleW(0);
169  return find_resourceW( hModule, type, name, lang );
170 }
171 
172 
173 /**********************************************************************
174  * FindResourceW (KERNEL32.@)
175  */
177 {
179 }
180 
181 
182 /**********************************************************************
183  * EnumResourceTypesA (KERNEL32.@)
184  */
186 {
187  int i;
188  BOOL ret = FALSE;
189  LPSTR type = NULL;
190  DWORD len = 0, newlen;
192  IMAGE_RESOURCE_DIRECTORY *resdir;
195 
196  TRACE( "%p %p %lx\n", hmod, lpfun, lparam );
197 
198  if (!hmod) hmod = GetModuleHandleA( NULL );
199 
200  if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &resdir )) != STATUS_SUCCESS)
201  {
203  return FALSE;
204  }
205  et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
206  for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
207  {
208  if (et[i].NameIsString)
209  {
210  str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].NameOffset);
211  newlen = WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
212  if (newlen + 1 > len)
213  {
214  len = newlen + 1;
215  HeapFree( GetProcessHeap(), 0, type );
216  if (!(type = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
217  }
218  WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, type, len, NULL, NULL);
219  type[newlen] = 0;
220  ret = lpfun(hmod,type,lparam);
221  }
222  else
223  {
224  ret = lpfun( hmod, UIntToPtr(et[i].Id), lparam );
225  }
226  if (!ret) break;
227  }
228  HeapFree( GetProcessHeap(), 0, type );
229  return ret;
230 }
231 
232 
233 /**********************************************************************
234  * EnumResourceTypesW (KERNEL32.@)
235  */
237 {
238  int i, len = 0;
239  BOOL ret = FALSE;
240  LPWSTR type = NULL;
242  IMAGE_RESOURCE_DIRECTORY *resdir;
245 
246  TRACE( "%p %p %lx\n", hmod, lpfun, lparam );
247 
248  if (!hmod) hmod = GetModuleHandleW( NULL );
249 
250  if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &resdir )) != STATUS_SUCCESS)
251  {
253  return FALSE;
254  }
255  et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
256  for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
257  {
258  if (et[i].NameIsString)
259  {
260  str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)resdir + et[i].NameOffset);
261  if (str->Length + 1 > len)
262  {
263  len = str->Length + 1;
264  HeapFree( GetProcessHeap(), 0, type );
265  if (!(type = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
266  }
267  memcpy(type, str->NameString, str->Length * sizeof (WCHAR));
268  type[str->Length] = 0;
269  ret = lpfun(hmod,type,lparam);
270  }
271  else
272  {
273  ret = lpfun( hmod, UIntToPtr(et[i].Id), lparam );
274  }
275  if (!ret) break;
276  }
277  HeapFree( GetProcessHeap(), 0, type );
278  return ret;
279 }
280 
281 
282 /**********************************************************************
283  * EnumResourceNamesA (KERNEL32.@)
284  */
286 {
287  int i;
288  BOOL ret = FALSE;
289  DWORD len = 0, newlen;
290  LPSTR name = NULL;
294  IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
297 
298  TRACE( "%p %s %p %lx\n", hmod, debugstr_a(type), lpfun, lparam );
299 
300  if (!hmod) hmod = GetModuleHandleA( NULL );
301  typeW.Buffer = NULL;
302  if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
303  goto done;
304  if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
305  goto done;
306  info.Type = (ULONG_PTR)typeW.Buffer;
307  if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
308  goto done;
309 
310  et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
311  __TRY
312  {
313  for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
314  {
315  if (et[i].NameIsString)
316  {
317  str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].NameOffset);
318  newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
319  if (newlen + 1 > len)
320  {
321  len = newlen + 1;
322  HeapFree( GetProcessHeap(), 0, name );
323  if (!(name = HeapAlloc(GetProcessHeap(), 0, len + 1 )))
324  {
325  ret = FALSE;
326  break;
327  }
328  }
329  WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
330  name[newlen] = 0;
331  ret = lpfun(hmod,type,name,lparam);
332  }
333  else
334  {
335  ret = lpfun( hmod, type, UIntToPtr(et[i].Id), lparam );
336  }
337  if (!ret) break;
338  }
339  }
341  {
342  ret = FALSE;
344  }
345  __ENDTRY;
346 
347 done:
348  HeapFree( GetProcessHeap(), 0, name );
349  if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
351  return ret;
352 }
353 
354 
355 /**********************************************************************
356  * EnumResourceNamesW (KERNEL32.@)
357  */
359 {
360  int i, len = 0;
361  BOOL ret = FALSE;
362  LPWSTR name = NULL;
366  IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
369 
370  TRACE( "%p %s %p %lx\n", hmod, debugstr_w(type), lpfun, lparam );
371 
372  if (!hmod) hmod = GetModuleHandleW( NULL );
373  typeW.Buffer = NULL;
374  if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
375  goto done;
376  if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
377  goto done;
378  info.Type = (ULONG_PTR)typeW.Buffer;
379  if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
380  goto done;
381 
382  et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
383  __TRY
384  {
385  for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
386  {
387  if (et[i].NameIsString)
388  {
389  str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].NameOffset);
390  if (str->Length + 1 > len)
391  {
392  len = str->Length + 1;
393  HeapFree( GetProcessHeap(), 0, name );
394  if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
395  {
396  ret = FALSE;
397  break;
398  }
399  }
400  memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
401  name[str->Length] = 0;
402  ret = lpfun(hmod,type,name,lparam);
403  }
404  else
405  {
406  ret = lpfun( hmod, type, UIntToPtr(et[i].Id), lparam );
407  }
408  if (!ret) break;
409  }
410  }
412  {
413  ret = FALSE;
415  }
416  __ENDTRY
417 done:
418  HeapFree( GetProcessHeap(), 0, name );
419  if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
421  return ret;
422 }
423 
424 
425 /**********************************************************************
426  * EnumResourceLanguagesA (KERNEL32.@)
427  */
430 {
431  int i;
432  BOOL ret = FALSE;
436  IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
438 
439  TRACE( "%p %s %s %p %lx\n", hmod, debugstr_a(type), debugstr_a(name), lpfun, lparam );
440 
441  if (!hmod) hmod = GetModuleHandleA( NULL );
442  typeW.Buffer = nameW.Buffer = NULL;
443  if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
444  goto done;
445  if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
446  goto done;
447  if ((status = get_res_nameA( name, &nameW )) != STATUS_SUCCESS)
448  goto done;
449  info.Type = (ULONG_PTR)typeW.Buffer;
450  info.Name = (ULONG_PTR)nameW.Buffer;
451  if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS)
452  goto done;
453 
454  et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
455  __TRY
456  {
457  for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
458  {
459  ret = lpfun( hmod, type, name, et[i].Id, lparam );
460  if (!ret) break;
461  }
462  }
464  {
465  ret = FALSE;
467  }
468  __ENDTRY
469 done:
470  if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
471  if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
473  return ret;
474 }
475 
476 
477 /**********************************************************************
478  * EnumResourceLanguagesW (KERNEL32.@)
479  */
482 {
483  int i;
484  BOOL ret = FALSE;
488  IMAGE_RESOURCE_DIRECTORY *basedir, *resdir;
490 
491  TRACE( "%p %s %s %p %lx\n", hmod, debugstr_w(type), debugstr_w(name), lpfun, lparam );
492 
493  if (!hmod) hmod = GetModuleHandleW( NULL );
494  typeW.Buffer = nameW.Buffer = NULL;
495  if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
496  goto done;
497  if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
498  goto done;
499  if ((status = get_res_nameW( name, &nameW )) != STATUS_SUCCESS)
500  goto done;
501  info.Type = (ULONG_PTR)typeW.Buffer;
502  info.Name = (ULONG_PTR)nameW.Buffer;
503  if ((status = LdrFindResourceDirectory_U( hmod, &info, 2, &resdir )) != STATUS_SUCCESS)
504  goto done;
505 
506  et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
507  __TRY
508  {
509  for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
510  {
511  ret = lpfun( hmod, type, name, et[i].Id, lparam );
512  if (!ret) break;
513  }
514  }
516  {
517  ret = FALSE;
519  }
520  __ENDTRY
521 done:
522  if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
523  if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
525  return ret;
526 }
527 
528 
529 /**********************************************************************
530  * LoadResource (KERNEL32.@)
531  */
533 {
535  void *ret = NULL;
536 
537  TRACE( "%p %p\n", hModule, hRsrc );
538 
539  if (!hRsrc) return 0;
543  return ret;
544 }
545 
546 
547 /**********************************************************************
548  * LockResource (KERNEL32.@)
549  */
551 {
552  return handle;
553 }
554 
555 
556 /**********************************************************************
557  * FreeResource (KERNEL32.@)
558  */
560 {
561  return FALSE;
562 }
563 
564 
565 /**********************************************************************
566  * SizeofResource (KERNEL32.@)
567  */
569 {
570  if (!hRsrc) return 0;
571  return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
572 }
573 
574 /*
575  * Data structure for updating resources.
576  * Type/Name/Language is a keyset for accessing resource data.
577  *
578  * QUEUEDUPDATES (root) ->
579  * list of struct resource_dir_entry (Type) ->
580  * list of struct resource_dir_entry (Name) ->
581  * list of struct resource_data Language + Data
582  */
583 
584 typedef struct
585 {
588  struct list root;
589 } QUEUEDUPDATES;
590 
591 /* this structure is shared for types and names */
593  struct list entry;
595  struct list children;
596 };
597 
598 /* this structure is the leaf */
600  struct list entry;
604  void *lpData;
605 };
606 
608 {
609  if ( a == b )
610  return 0;
611  if (!IS_INTRESOURCE( a ) && !IS_INTRESOURCE( b ) )
612  return lstrcmpW( a, b );
613  /* strings come before ids */
614  if (!IS_INTRESOURCE( a ) && IS_INTRESOURCE( b ))
615  return -1;
616  if (!IS_INTRESOURCE( b ) && IS_INTRESOURCE( a ))
617  return 1;
618  return ( a < b ) ? -1 : 1;
619 }
620 
622 {
623  struct resource_dir_entry *ent;
624 
625  /* match either IDs or strings */
627  if (!resource_strcmp( id, ent->id ))
628  return ent;
629 
630  return NULL;
631 }
632 
634 {
635  struct resource_data *res_data;
636 
637  /* match only languages here */
638  LIST_FOR_EACH_ENTRY( res_data, dir, struct resource_data, entry )
639  if ( lang == res_data->lang )
640  return res_data;
641 
642  return NULL;
643 }
644 
645 static void add_resource_dir_entry( struct list *dir, struct resource_dir_entry *resdir )
646 {
647  struct resource_dir_entry *ent;
648 
650  {
651  if (0>resource_strcmp( ent->id, resdir->id ))
652  continue;
653 
654  list_add_before( &ent->entry, &resdir->entry );
655  return;
656  }
657  list_add_tail( dir, &resdir->entry );
658 }
659 
660 static void add_resource_data_entry( struct list *dir, struct resource_data *resdata )
661 {
662  struct resource_data *ent;
663 
664  LIST_FOR_EACH_ENTRY( ent, dir, struct resource_data, entry )
665  {
666  if (ent->lang < resdata->lang)
667  continue;
668 
669  list_add_before( &ent->entry, &resdata->entry );
670  return;
671  }
672  list_add_tail( dir, &resdata->entry );
673 }
674 
676 {
677  LPWSTR ret;
678  UINT len;
679 
680  if (IS_INTRESOURCE(str))
681  return (LPWSTR) (UINT_PTR) LOWORD(str);
682  len = (lstrlenW( str ) + 1) * sizeof (WCHAR);
683  ret = HeapAlloc( GetProcessHeap(), 0, len );
684  memcpy( ret, str, len );
685  return ret;
686 }
687 
688 static void res_free_str( LPWSTR str )
689 {
690  if (!IS_INTRESOURCE(str))
691  HeapFree( GetProcessHeap(), 0, str );
692 }
693 
695  LANGID Lang, struct resource_data *resdata,
696  BOOL overwrite_existing )
697 {
698  struct resource_dir_entry *restype, *resname;
699  struct resource_data *existing;
700 
701  TRACE("%p %s %s %p %d\n", updates,
702  debugstr_w(Type), debugstr_w(Name), resdata, overwrite_existing );
703 
704  restype = find_resource_dir_entry( &updates->root, Type );
705  if (!restype)
706  {
707  restype = HeapAlloc( GetProcessHeap(), 0, sizeof *restype );
708  restype->id = res_strdupW( Type );
709  list_init( &restype->children );
710  add_resource_dir_entry( &updates->root, restype );
711  }
712 
713  resname = find_resource_dir_entry( &restype->children, Name );
714  if (!resname)
715  {
716  resname = HeapAlloc( GetProcessHeap(), 0, sizeof *resname );
717  resname->id = res_strdupW( Name );
718  list_init( &resname->children );
719  add_resource_dir_entry( &restype->children, resname );
720  }
721 
722  /*
723  * If there's an existing resource entry with matching (Type,Name,Language)
724  * it needs to be removed before adding the new data.
725  */
726  existing = find_resource_data( &resname->children, Lang );
727  if (existing)
728  {
729  if (!overwrite_existing)
730  return FALSE;
731  list_remove( &existing->entry );
732  HeapFree( GetProcessHeap(), 0, existing );
733  }
734 
735  if (resdata)
736  add_resource_data_entry( &resname->children, resdata );
737 
738  return TRUE;
739 }
740 
742  LPVOID lpData, DWORD cbData, BOOL copy_data )
743 {
744  struct resource_data *resdata;
745 
746  if (!lpData || !cbData)
747  return NULL;
748 
749  resdata = HeapAlloc( GetProcessHeap(), 0, sizeof *resdata + (copy_data ? cbData : 0) );
750  if (resdata)
751  {
752  resdata->lang = Language;
753  resdata->codepage = codepage;
754  resdata->cbData = cbData;
755  if (copy_data)
756  {
757  resdata->lpData = &resdata[1];
758  memcpy( resdata->lpData, lpData, cbData );
759  }
760  else
761  resdata->lpData = lpData;
762  }
763 
764  return resdata;
765 }
766 
767 static void free_resource_directory( struct list *head, int level )
768 {
769  struct list *ptr = NULL;
770 
771  while ((ptr = list_head( head )))
772  {
773  list_remove( ptr );
774  if (level)
775  {
776  struct resource_dir_entry *ent;
777 
778  ent = LIST_ENTRY( ptr, struct resource_dir_entry, entry );
779  res_free_str( ent->id );
780  free_resource_directory( &ent->children, level - 1 );
781  HeapFree(GetProcessHeap(), 0, ent);
782  }
783  else
784  {
785  struct resource_data *data;
786 
787  data = LIST_ENTRY( ptr, struct resource_data, entry );
788  HeapFree( GetProcessHeap(), 0, data );
789  }
790  }
791 }
792 
793 static IMAGE_NT_HEADERS *get_nt_header( void *base, DWORD mapping_size )
794 {
797 
798  if (mapping_size<sizeof (*dos))
799  return NULL;
800 
801  dos = base;
803  return NULL;
804 
805  if ((dos->e_lfanew + sizeof (*nt)) > mapping_size)
806  return NULL;
807 
808  nt = (void*) ((BYTE*)base + dos->e_lfanew);
809 
811  return NULL;
812 
813  return nt;
814 }
815 
816 static IMAGE_SECTION_HEADER *get_section_header( void *base, DWORD mapping_size, DWORD *num_sections )
817 {
819  DWORD section_ofs;
820 
821  nt = get_nt_header( base, mapping_size );
822  if (!nt)
823  return NULL;
824 
825  /* check that we don't go over the end of the file accessing the sections */
826  section_ofs = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + nt->FileHeader.SizeOfOptionalHeader;
827  if ((nt->FileHeader.NumberOfSections * sizeof (IMAGE_SECTION_HEADER) + section_ofs) > mapping_size)
828  return NULL;
829 
830  if (num_sections)
831  *num_sections = nt->FileHeader.NumberOfSections;
832 
833  /* from here we have a valid PE exe to update */
834  return (void*) ((BYTE*)nt + section_ofs);
835 }
836 
838 {
839  const IMAGE_NT_HEADERS32 *nt;
840  const IMAGE_NT_HEADERS64 *nt64;
841  const IMAGE_SECTION_HEADER *sec;
842  const IMAGE_DATA_DIRECTORY *dd;
843  BOOL ret = FALSE;
844  HANDLE mapping;
845  DWORD mapping_size, num_sections = 0;
846  void *base = NULL;
847 
848  mapping_size = GetFileSize( file, NULL );
849 
851  if (!mapping)
852  goto done;
853 
854  base = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, mapping_size );
855  if (!base)
856  goto done;
857 
858  nt = (IMAGE_NT_HEADERS32 *)get_nt_header( base, mapping_size );
859  if (!nt)
860  goto done;
861 
862  nt64 = (IMAGE_NT_HEADERS64*)nt;
863  dd = &nt->OptionalHeader.DataDirectory[0];
865  dd = &nt64->OptionalHeader.DataDirectory[0];
866 
867  TRACE("resources: %08x %08x\n",
870 
871  sec = get_section_header( base, mapping_size, &num_sections );
872  if (!sec)
873  goto done;
874 
875  ret = TRUE;
876 
877 done:
878  if (base)
880  if (mapping)
881  CloseHandle( mapping );
882 
883  return ret;
884 }
885 
894 };
895 
896 struct mapping_info {
898  void *base;
901 };
902 
903 static const IMAGE_SECTION_HEADER *section_from_rva( void *base, DWORD mapping_size, DWORD rva )
904 {
905  const IMAGE_SECTION_HEADER *sec;
906  DWORD num_sections = 0;
907  int i;
908 
909  sec = get_section_header( base, mapping_size, &num_sections );
910  if (!sec)
911  return NULL;
912 
913  for (i=num_sections-1; i>=0; i--)
914  {
915  if (sec[i].VirtualAddress <= rva &&
916  rva <= (DWORD)sec[i].VirtualAddress + sec[i].SizeOfRawData)
917  {
918  return &sec[i];
919  }
920  }
921 
922  return NULL;
923 }
924 
925 static void *address_from_rva( void *base, DWORD mapping_size, DWORD rva, DWORD len )
926 {
927  const IMAGE_SECTION_HEADER *sec;
928 
929  sec = section_from_rva( base, mapping_size, rva );
930  if (!sec)
931  return NULL;
932 
933  if (rva + len <= (DWORD)sec->VirtualAddress + sec->SizeOfRawData)
934  return (void*)((LPBYTE) base + (sec->PointerToRawData + rva - sec->VirtualAddress));
935 
936  return NULL;
937 }
938 
940 {
942  LPWSTR s;
943 
944  if (!entry->NameIsString)
945  return UIntToPtr(entry->Id);
946 
947  string = (const IMAGE_RESOURCE_DIR_STRING_U*) (((const char *)root) + entry->NameOffset);
948  s = HeapAlloc(GetProcessHeap(), 0, (string->Length + 1)*sizeof (WCHAR) );
949  memcpy( s, string->NameString, (string->Length + 1)*sizeof (WCHAR) );
950  s[string->Length] = 0;
951 
952  return s;
953 }
954 
955 /* this function is based on the code in winedump's pe.c */
957  void *base, DWORD mapping_size,
959 {
960  const IMAGE_RESOURCE_DIRECTORY *namedir, *langdir;
961  const IMAGE_RESOURCE_DIRECTORY_ENTRY *e1, *e2, *e3;
963  DWORD i, j, k;
964 
965  TRACE("version (%d.%d) %d named %d id entries\n",
966  root->MajorVersion, root->MinorVersion, root->NumberOfNamedEntries, root->NumberOfIdEntries);
967 
968  for (i = 0; i< root->NumberOfNamedEntries + root->NumberOfIdEntries; i++)
969  {
970  LPWSTR Type;
971 
972  e1 = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(root + 1) + i;
973 
974  Type = resource_dup_string( root, e1 );
975 
976  namedir = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + e1->OffsetToDirectory);
977  for (j = 0; j < namedir->NumberOfNamedEntries + namedir->NumberOfIdEntries; j++)
978  {
979  LPWSTR Name;
980 
981  e2 = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(namedir + 1) + j;
982 
983  Name = resource_dup_string( root, e2 );
984 
985  langdir = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + e2->OffsetToDirectory);
986  for (k = 0; k < langdir->NumberOfNamedEntries + langdir->NumberOfIdEntries; k++)
987  {
988  LANGID Lang;
989  void *p;
990  struct resource_data *resdata;
991 
992  e3 = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(langdir + 1) + k;
993 
994  Lang = e3->Id;
995 
996  data = (const IMAGE_RESOURCE_DATA_ENTRY *)((const char *)root + e3->OffsetToData);
997 
998  p = address_from_rva( base, mapping_size, data->OffsetToData, data->Size );
999 
1000  resdata = allocate_resource_data( Lang, data->CodePage, p, data->Size, FALSE );
1001  if (resdata)
1002  {
1003  if (!update_add_resource( updates, Type, Name, Lang, resdata, FALSE ))
1004  HeapFree( GetProcessHeap(), 0, resdata );
1005  }
1006  }
1007  res_free_str( Name );
1008  }
1009  res_free_str( Type );
1010  }
1011 
1012  return TRUE;
1013 }
1014 
1015 static BOOL read_mapped_resources( QUEUEDUPDATES *updates, void *base, DWORD mapping_size )
1016 {
1018  const IMAGE_NT_HEADERS *nt;
1019  const IMAGE_SECTION_HEADER *sec;
1020  DWORD num_sections = 0, i;
1021 
1022  nt = get_nt_header( base, mapping_size );
1023  if (!nt)
1024  return FALSE;
1025 
1026  sec = get_section_header( base, mapping_size, &num_sections );
1027  if (!sec)
1028  return FALSE;
1029 
1030  for (i=0; i<num_sections; i++)
1031  if (!memcmp(sec[i].Name, ".rsrc", 6))
1032  break;
1033 
1034  if (i == num_sections)
1035  return TRUE;
1036 
1037  /* check the resource data is inside the mapping */
1038  if (sec[i].PointerToRawData > mapping_size ||
1039  (sec[i].PointerToRawData + sec[i].SizeOfRawData) > mapping_size)
1040  return TRUE;
1041 
1042  TRACE("found .rsrc at %08x, size %08x\n", sec[i].PointerToRawData, sec[i].SizeOfRawData);
1043 
1044  if (!sec[i].PointerToRawData || sec[i].SizeOfRawData < sizeof(IMAGE_RESOURCE_DIRECTORY))
1045  return TRUE;
1046 
1047  root = (void*) ((BYTE*)base + sec[i].PointerToRawData);
1048  enumerate_mapped_resources( updates, base, mapping_size, root );
1049 
1050  return TRUE;
1051 }
1052 
1054 {
1055  DWORD page_attr, perm;
1056  HANDLE mapping;
1057 
1058  if (mi->read_write)
1059  {
1060  page_attr = PAGE_READWRITE;
1061  perm = FILE_MAP_WRITE | FILE_MAP_READ;
1062  }
1063  else
1064  {
1065  page_attr = PAGE_READONLY;
1066  perm = FILE_MAP_READ;
1067  }
1068 
1069  mapping = CreateFileMappingW( mi->file, NULL, page_attr, 0, 0, NULL );
1070  if (!mapping) return FALSE;
1071 
1072  mi->base = MapViewOfFile( mapping, perm, 0, 0, mi->size );
1073  CloseHandle( mapping );
1074 
1075  return mi->base != NULL;
1076 }
1077 
1079 {
1080  if (mi->base)
1081  UnmapViewOfFile( mi->base );
1082  mi->base = NULL;
1083  return TRUE;
1084 }
1085 
1086 static void destroy_mapping( struct mapping_info *mi )
1087 {
1088  if (!mi)
1089  return;
1091  if (mi->file)
1092  CloseHandle( mi->file );
1093  HeapFree( GetProcessHeap(), 0, mi );
1094 }
1095 
1097 {
1098  struct mapping_info *mi;
1099 
1100  mi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *mi );
1101  if (!mi)
1102  return NULL;
1103 
1104  mi->read_write = rw;
1105 
1106  mi->file = CreateFileW( name, GENERIC_READ | (rw ? GENERIC_WRITE : 0),
1107  0, NULL, OPEN_EXISTING, 0, 0 );
1108 
1109  if (mi->file != INVALID_HANDLE_VALUE)
1110  {
1111  mi->size = GetFileSize( mi->file, NULL );
1112 
1113  if (map_file_into_memory( mi ))
1114  return mi;
1115  }
1116  destroy_mapping( mi );
1117  return NULL;
1118 }
1119 
1120 static BOOL resize_mapping( struct mapping_info *mi, DWORD new_size )
1121 {
1122  if (!unmap_file_from_memory( mi ))
1123  return FALSE;
1124 
1125  /* change the file size */
1126  SetFilePointer( mi->file, new_size, NULL, FILE_BEGIN );
1127  if (!SetEndOfFile( mi->file ))
1128  {
1129  ERR("failed to set file size to %08x\n", new_size );
1130  return FALSE;
1131  }
1132 
1133  mi->size = new_size;
1134 
1135  return map_file_into_memory( mi );
1136 }
1137 
1138 static void get_resource_sizes( QUEUEDUPDATES *updates, struct resource_size_info *si )
1139 {
1140  struct resource_dir_entry *types, *names;
1141  struct resource_data *data;
1142  DWORD num_types = 0, num_names = 0, num_langs = 0, strings_size = 0, data_size = 0;
1143 
1144  memset( si, 0, sizeof *si );
1145 
1146  LIST_FOR_EACH_ENTRY( types, &updates->root, struct resource_dir_entry, entry )
1147  {
1148  num_types++;
1149  if (!IS_INTRESOURCE( types->id ))
1150  strings_size += sizeof (WORD) + lstrlenW( types->id )*sizeof (WCHAR);
1151 
1152  LIST_FOR_EACH_ENTRY( names, &types->children, struct resource_dir_entry, entry )
1153  {
1154  num_names++;
1155 
1156  if (!IS_INTRESOURCE( names->id ))
1157  strings_size += sizeof (WORD) + lstrlenW( names->id )*sizeof (WCHAR);
1158 
1159  LIST_FOR_EACH_ENTRY( data, &names->children, struct resource_data, entry )
1160  {
1161  num_langs++;
1162  data_size += (data->cbData + 3) & ~3;
1163  }
1164  }
1165  }
1166 
1167  /* names are at the end of the types */
1168  si->names_ofs = sizeof (IMAGE_RESOURCE_DIRECTORY) +
1169  num_types * sizeof (IMAGE_RESOURCE_DIRECTORY_ENTRY);
1170 
1171  /* language directories are at the end of the names */
1172  si->langs_ofs = si->names_ofs +
1173  num_types * sizeof (IMAGE_RESOURCE_DIRECTORY) +
1175 
1176  si->data_entry_ofs = si->langs_ofs +
1177  num_names * sizeof (IMAGE_RESOURCE_DIRECTORY) +
1178  num_langs * sizeof (IMAGE_RESOURCE_DIRECTORY_ENTRY);
1179 
1180  si->strings_ofs = si->data_entry_ofs +
1181  num_langs * sizeof (IMAGE_RESOURCE_DATA_ENTRY);
1182 
1183  si->data_ofs = si->strings_ofs + ((strings_size + 3) & ~3);
1184 
1185  si->total_size = si->data_ofs + data_size;
1186 
1187  TRACE("names %08x langs %08x data entries %08x strings %08x data %08x total %08x\n",
1188  si->names_ofs, si->langs_ofs, si->data_entry_ofs,
1189  si->strings_ofs, si->data_ofs, si->total_size);
1190 }
1191 
1192 static void res_write_padding( BYTE *res_base, DWORD size )
1193 {
1194  static const BYTE pad[] = {
1195  'P','A','D','D','I','N','G','X','X','P','A','D','D','I','N','G' };
1196  DWORD i;
1197 
1198  for ( i = 0; i < size / sizeof pad; i++ )
1199  memcpy( &res_base[i*sizeof pad], pad, sizeof pad );
1200  memcpy( &res_base[i*sizeof pad], pad, size%sizeof pad );
1201 }
1202 
1204 {
1205  struct resource_dir_entry *types, *names;
1206  struct resource_data *data;
1208 
1209  TRACE("%p %p %p %08x\n", updates, base, si, rva );
1210 
1211  memset( base, 0, si->total_size );
1212 
1213  /* the root entry always exists */
1215  memset( root, 0, sizeof *root );
1216  root->MajorVersion = 4;
1217  si->types_ofs = sizeof *root;
1218  LIST_FOR_EACH_ENTRY( types, &updates->root, struct resource_dir_entry, entry )
1219  {
1221  IMAGE_RESOURCE_DIRECTORY *namedir;
1222 
1224  memset( e1, 0, sizeof *e1 );
1225  if (!IS_INTRESOURCE( types->id ))
1226  {
1227  WCHAR *strings;
1228  DWORD len;
1229 
1230  root->NumberOfNamedEntries++;
1231  e1->NameIsString = 1;
1232  e1->NameOffset = si->strings_ofs;
1233 
1234  strings = (WCHAR*) &base[si->strings_ofs];
1235  len = lstrlenW( types->id );
1236  strings[0] = len;
1237  memcpy( &strings[1], types->id, len * sizeof (WCHAR) );
1238  si->strings_ofs += (len + 1) * sizeof (WCHAR);
1239  }
1240  else
1241  {
1242  root->NumberOfIdEntries++;
1243  e1->Id = LOWORD( types->id );
1244  }
1245  e1->OffsetToDirectory = si->names_ofs;
1246  e1->DataIsDirectory = TRUE;
1247  si->types_ofs += sizeof (IMAGE_RESOURCE_DIRECTORY_ENTRY);
1248 
1249  namedir = (IMAGE_RESOURCE_DIRECTORY*) &base[si->names_ofs];
1250  memset( namedir, 0, sizeof *namedir );
1251  namedir->MajorVersion = 4;
1252  si->names_ofs += sizeof (IMAGE_RESOURCE_DIRECTORY);
1253 
1254  LIST_FOR_EACH_ENTRY( names, &types->children, struct resource_dir_entry, entry )
1255  {
1257  IMAGE_RESOURCE_DIRECTORY *langdir;
1258 
1260  memset( e2, 0, sizeof *e2 );
1261  if (!IS_INTRESOURCE( names->id ))
1262  {
1263  WCHAR *strings;
1264  DWORD len;
1265 
1266  namedir->NumberOfNamedEntries++;
1267  e2->NameIsString = 1;
1268  e2->NameOffset = si->strings_ofs;
1269 
1270  strings = (WCHAR*) &base[si->strings_ofs];
1271  len = lstrlenW( names->id );
1272  strings[0] = len;
1273  memcpy( &strings[1], names->id, len * sizeof (WCHAR) );
1274  si->strings_ofs += (len + 1) * sizeof (WCHAR);
1275  }
1276  else
1277  {
1278  namedir->NumberOfIdEntries++;
1279  e2->Id = LOWORD( names->id );
1280  }
1281  e2->OffsetToDirectory = si->langs_ofs;
1282  e2->DataIsDirectory = TRUE;
1283  si->names_ofs += sizeof (IMAGE_RESOURCE_DIRECTORY_ENTRY);
1284 
1285  langdir = (IMAGE_RESOURCE_DIRECTORY*) &base[si->langs_ofs];
1286  memset( langdir, 0, sizeof *langdir );
1287  langdir->MajorVersion = 4;
1288  si->langs_ofs += sizeof (IMAGE_RESOURCE_DIRECTORY);
1289 
1290  LIST_FOR_EACH_ENTRY( data, &names->children, struct resource_data, entry )
1291  {
1294  int pad_size;
1295 
1297  memset( e3, 0, sizeof *e3 );
1298  langdir->NumberOfIdEntries++;
1299  e3->Id = LOWORD( data->lang );
1300  e3->OffsetToData = si->data_entry_ofs;
1301 
1302  si->langs_ofs += sizeof (IMAGE_RESOURCE_DIRECTORY_ENTRY);
1303 
1304  /* write out all the data entries */
1306  memset( de, 0, sizeof *de );
1307  de->OffsetToData = si->data_ofs + rva;
1308  de->Size = data->cbData;
1309  de->CodePage = data->codepage;
1310  si->data_entry_ofs += sizeof (IMAGE_RESOURCE_DATA_ENTRY);
1311 
1312  /* write out the resource data */
1313  memcpy( &base[si->data_ofs], data->lpData, data->cbData );
1314  si->data_ofs += data->cbData;
1315 
1316  pad_size = (-si->data_ofs)&3;
1317  res_write_padding( &base[si->data_ofs], pad_size );
1318  si->data_ofs += pad_size;
1319  }
1320  }
1321  }
1322 
1323  return TRUE;
1324 }
1325 
1326 /*
1327  * FIXME:
1328  * Assumes that the resources are in .rsrc
1329  * and .rsrc is the last section in the file.
1330  * Not sure whether updating resources will other cases on Windows.
1331  * If the resources lie in a section containing other data,
1332  * resizing that section could possibly cause trouble.
1333  * If the section with the resources isn't last, the remaining
1334  * sections need to be moved down in the file, and the section header
1335  * would need to be adjusted.
1336  * If we needed to add a section, what would we name it?
1337  * If we needed to add a section and there wasn't space in the file
1338  * header, how would that work?
1339  * Seems that at least some of these cases can't be handled properly.
1340  */
1341 static IMAGE_SECTION_HEADER *get_resource_section( void *base, DWORD mapping_size )
1342 {
1343  IMAGE_SECTION_HEADER *sec;
1345  DWORD i, num_sections = 0;
1346 
1347  nt = get_nt_header( base, mapping_size );
1348  if (!nt)
1349  return NULL;
1350 
1351  sec = get_section_header( base, mapping_size, &num_sections );
1352  if (!sec)
1353  return NULL;
1354 
1355  /* find the resources section */
1356  for (i=0; i<num_sections; i++)
1357  if (!memcmp(sec[i].Name, ".rsrc", 6))
1358  break;
1359 
1360  if (i == num_sections)
1361  return NULL;
1362 
1363  return &sec[i];
1364 }
1365 
1366 static DWORD get_init_data_size( void *base, DWORD mapping_size )
1367 {
1368  DWORD i, sz = 0, num_sections = 0;
1370 
1371  s = get_section_header( base, mapping_size, &num_sections );
1372 
1373  for (i=0; i<num_sections; i++)
1374  if (s[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
1375  sz += s[i].SizeOfRawData;
1376 
1377  TRACE("size = %08x\n", sz);
1378 
1379  return sz;
1380 }
1381 
1383 {
1384  static const WCHAR prefix[] = { 'r','e','s','u',0 };
1385  WCHAR tempdir[MAX_PATH], tempfile[MAX_PATH];
1386  DWORD i, section_size;
1387  BOOL ret = FALSE;
1388  IMAGE_SECTION_HEADER *sec;
1390  IMAGE_NT_HEADERS64 *nt64;
1391  struct resource_size_info res_size;
1392  BYTE *res_base;
1393  struct mapping_info *read_map = NULL, *write_map = NULL;
1394  DWORD PeSectionAlignment, PeFileAlignment, PeSizeOfImage;
1395 
1396  /* copy the exe to a temp file then update the temp file... */
1397  tempdir[0] = 0;
1398  if (!GetTempPathW( MAX_PATH, tempdir ))
1399  return ret;
1400 
1401  if (!GetTempFileNameW( tempdir, prefix, 0, tempfile ))
1402  return ret;
1403 
1404  if (!CopyFileW( updates->pFileName, tempfile, FALSE ))
1405  goto done;
1406 
1407  TRACE("tempfile %s\n", debugstr_w(tempfile));
1408 
1409  if (!updates->bDeleteExistingResources)
1410  {
1411  read_map = create_mapping( updates->pFileName, FALSE );
1412  if (!read_map)
1413  goto done;
1414 
1415  ret = read_mapped_resources( updates, read_map->base, read_map->size );
1416  if (!ret)
1417  {
1418  ERR("failed to read existing resources\n");
1419  goto done;
1420  }
1421  }
1422 
1423  write_map = create_mapping( tempfile, TRUE );
1424  if (!write_map)
1425  goto done;
1426 
1427  nt = (IMAGE_NT_HEADERS32*)get_nt_header( write_map->base, write_map->size );
1428  if (!nt)
1429  goto done;
1430 
1431  nt64 = (IMAGE_NT_HEADERS64*)nt;
1433  PeSectionAlignment = nt64->OptionalHeader.SectionAlignment;
1434  PeFileAlignment = nt64->OptionalHeader.FileAlignment;
1435  PeSizeOfImage = nt64->OptionalHeader.SizeOfImage;
1436  } else {
1437  PeSectionAlignment = nt->OptionalHeader.SectionAlignment;
1438  PeFileAlignment = nt->OptionalHeader.FileAlignment;
1439  PeSizeOfImage = nt->OptionalHeader.SizeOfImage;
1440  }
1441 
1442  if ((LONG)PeSectionAlignment <= 0)
1443  {
1444  ERR("invalid section alignment %08x\n", PeSectionAlignment);
1445  goto done;
1446  }
1447 
1448  if ((LONG)PeFileAlignment <= 0)
1449  {
1450  ERR("invalid file alignment %08x\n", PeFileAlignment);
1451  goto done;
1452  }
1453 
1454  sec = get_resource_section( write_map->base, write_map->size );
1455  if (!sec) /* no section, add one */
1456  {
1457  DWORD num_sections;
1458 
1459  sec = get_section_header( write_map->base, write_map->size, &num_sections );
1460  if (!sec)
1461  goto done;
1462 
1463  sec += num_sections;
1465 
1466  memset( sec, 0, sizeof *sec );
1467  memcpy( sec->Name, ".rsrc", 5 );
1469  sec->VirtualAddress = PeSizeOfImage;
1470  }
1471 
1472  if (!sec->PointerToRawData) /* empty section */
1473  {
1474  sec->PointerToRawData = write_map->size + (-write_map->size) % PeFileAlignment;
1475  sec->SizeOfRawData = 0;
1476  }
1477 
1478  TRACE("before .rsrc at %08x, size %08x\n", sec->PointerToRawData, sec->SizeOfRawData);
1479 
1480  get_resource_sizes( updates, &res_size );
1481 
1482  /* round up the section size */
1483  section_size = res_size.total_size;
1484  section_size += (-section_size) % PeFileAlignment;
1485 
1486  TRACE("requires %08x (%08x) bytes\n", res_size.total_size, section_size );
1487 
1488  /* check if the file size needs to be changed */
1489  if (section_size != sec->SizeOfRawData)
1490  {
1491  DWORD old_size = write_map->size;
1492  DWORD virtual_section_size = res_size.total_size + (-res_size.total_size) % PeSectionAlignment;
1493  int delta = section_size - (sec->SizeOfRawData + (-sec->SizeOfRawData) % PeFileAlignment);
1494  int rva_delta = virtual_section_size -
1495  (sec->Misc.VirtualSize + (-sec->Misc.VirtualSize) % PeSectionAlignment);
1496  /* when new section is added it could end past current mapping size */
1497  BOOL rsrc_is_last = sec->PointerToRawData + sec->SizeOfRawData >= old_size;
1498  /* align .rsrc size when possible */
1499  DWORD mapping_size = rsrc_is_last ? sec->PointerToRawData + section_size : old_size + delta;
1500 
1501  /* postpone file truncation if there are some data to be moved down from file end */
1502  BOOL resize_after = mapping_size < old_size && !rsrc_is_last;
1503 
1504  TRACE("file size %08x -> %08x\n", old_size, mapping_size);
1505 
1506  if (!resize_after)
1507  {
1508  /* unmap the file before changing the file size */
1509  ret = resize_mapping( write_map, mapping_size );
1510 
1511  /* get the pointers again - they might be different after remapping */
1512  nt = (IMAGE_NT_HEADERS32*)get_nt_header( write_map->base, mapping_size );
1513  if (!nt)
1514  {
1515  ERR("couldn't get NT header\n");
1516  goto done;
1517  }
1518  nt64 = (IMAGE_NT_HEADERS64*)nt;
1519 
1520  sec = get_resource_section( write_map->base, mapping_size );
1521  if (!sec)
1522  goto done;
1523  }
1524 
1525  if (!rsrc_is_last) /* not last section, relocate trailing sections */
1526  {
1528  DWORD tail_start = sec->PointerToRawData + sec->SizeOfRawData;
1529  DWORD i, num_sections = 0;
1530 
1531  memmove( (char*)write_map->base + tail_start + delta, (char*)write_map->base + tail_start, old_size - tail_start );
1532 
1533  s = get_section_header( write_map->base, mapping_size, &num_sections );
1534 
1535  for (i=0; i<num_sections; i++)
1536  {
1537  if (s[i].PointerToRawData > sec->PointerToRawData)
1538  {
1539  s[i].PointerToRawData += delta;
1540  s[i].VirtualAddress += rva_delta;
1541  }
1542  }
1543  }
1544 
1545  if (resize_after)
1546  {
1547  ret = resize_mapping( write_map, mapping_size );
1548 
1549  nt = (IMAGE_NT_HEADERS32*)get_nt_header( write_map->base, mapping_size );
1550  if (!nt)
1551  {
1552  ERR("couldn't get NT header\n");
1553  goto done;
1554  }
1555  nt64 = (IMAGE_NT_HEADERS64*)nt;
1556 
1557  sec = get_resource_section( write_map->base, mapping_size );
1558  if (!sec)
1559  goto done;
1560  }
1561 
1562  /* adjust the PE header information */
1563  sec->SizeOfRawData = section_size;
1564  sec->Misc.VirtualSize = virtual_section_size;
1566  nt64->OptionalHeader.SizeOfImage += rva_delta;
1569  nt64->OptionalHeader.SizeOfInitializedData = get_init_data_size( write_map->base, mapping_size );
1570 
1571  for (i=0; i<nt64->OptionalHeader.NumberOfRvaAndSizes; i++)
1573  nt64->OptionalHeader.DataDirectory[i].VirtualAddress += rva_delta;
1574  } else {
1575  nt->OptionalHeader.SizeOfImage += rva_delta;
1578  nt->OptionalHeader.SizeOfInitializedData = get_init_data_size( write_map->base, mapping_size );
1579 
1580  for (i=0; i<nt->OptionalHeader.NumberOfRvaAndSizes; i++)
1583  }
1584  }
1585 
1586  res_base = (LPBYTE) write_map->base + sec->PointerToRawData;
1587 
1588  TRACE("base = %p offset = %08x\n", write_map->base, sec->PointerToRawData);
1589 
1590  ret = write_resources( updates, res_base, &res_size, sec->VirtualAddress );
1591 
1592  res_write_padding( res_base + res_size.total_size, section_size - res_size.total_size );
1593 
1594  TRACE("after .rsrc at %08x, size %08x\n", sec->PointerToRawData, sec->SizeOfRawData);
1595 
1596 done:
1597  destroy_mapping( read_map );
1598  destroy_mapping( write_map );
1599 
1600  if (ret)
1601  ret = CopyFileW( tempfile, updates->pFileName, FALSE );
1602 
1603  DeleteFileW( tempfile );
1604 
1605  return ret;
1606 }
1607 
1608 /***********************************************************************
1609  * BeginUpdateResourceW (KERNEL32.@)
1610  */
1611 HANDLE WINAPI BeginUpdateResourceW( LPCWSTR pFileName, BOOL bDeleteExistingResources )
1612 {
1613  QUEUEDUPDATES *updates = NULL;
1614  HANDLE hUpdate, file, ret = NULL;
1615 
1616  TRACE("%s, %d\n", debugstr_w(pFileName), bDeleteExistingResources);
1617 
1618  hUpdate = GlobalAlloc(GHND, sizeof(QUEUEDUPDATES));
1619  if (!hUpdate)
1620  return ret;
1621 
1622  updates = GlobalLock(hUpdate);
1623  if (updates)
1624  {
1625  list_init( &updates->root );
1626  updates->bDeleteExistingResources = bDeleteExistingResources;
1627  updates->pFileName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(pFileName)+1)*sizeof(WCHAR));
1628  if (updates->pFileName)
1629  {
1630  lstrcpyW(updates->pFileName, pFileName);
1631 
1632  file = CreateFileW( pFileName, GENERIC_READ | GENERIC_WRITE,
1633  0, NULL, OPEN_EXISTING, 0, 0 );
1634 
1635  /* if resources are deleted, only the file's presence is checked */
1636  if (file != INVALID_HANDLE_VALUE &&
1637  (bDeleteExistingResources || check_pe_exe( file, updates )))
1638  ret = hUpdate;
1639  else
1640  HeapFree( GetProcessHeap(), 0, updates->pFileName );
1641 
1642  CloseHandle( file );
1643  }
1644  GlobalUnlock(hUpdate);
1645  }
1646 
1647  if (!ret)
1648  GlobalFree(hUpdate);
1649 
1650  return ret;
1651 }
1652 
1653 
1654 /***********************************************************************
1655  * BeginUpdateResourceA (KERNEL32.@)
1656  */
1657 HANDLE WINAPI BeginUpdateResourceA( LPCSTR pFileName, BOOL bDeleteExistingResources )
1658 {
1659  UNICODE_STRING FileNameW;
1660  HANDLE ret;
1661  RtlCreateUnicodeStringFromAsciiz(&FileNameW, pFileName);
1662  ret = BeginUpdateResourceW(FileNameW.Buffer, bDeleteExistingResources);
1663  RtlFreeUnicodeString(&FileNameW);
1664  return ret;
1665 }
1666 
1667 
1668 /***********************************************************************
1669  * EndUpdateResourceW (KERNEL32.@)
1670  */
1672 {
1673  QUEUEDUPDATES *updates;
1674  BOOL ret;
1675 
1676  TRACE("%p %d\n", hUpdate, fDiscard);
1677 
1678  updates = GlobalLock(hUpdate);
1679  if (!updates)
1680  return FALSE;
1681 
1682  ret = fDiscard || write_raw_resources( updates );
1683 
1684  free_resource_directory( &updates->root, 2 );
1685 
1686  HeapFree( GetProcessHeap(), 0, updates->pFileName );
1687  GlobalUnlock( hUpdate );
1688  GlobalFree( hUpdate );
1689 
1690  return ret;
1691 }
1692 
1693 
1694 /***********************************************************************
1695  * EndUpdateResourceA (KERNEL32.@)
1696  */
1698 {
1699  return EndUpdateResourceW(hUpdate, fDiscard);
1700 }
1701 
1702 
1703 /***********************************************************************
1704  * UpdateResourceW (KERNEL32.@)
1705  */
1707  WORD wLanguage, LPVOID lpData, DWORD cbData)
1708 {
1709  QUEUEDUPDATES *updates;
1710  BOOL ret = FALSE;
1711 
1712  TRACE("%p %s %s %08x %p %d\n", hUpdate,
1713  debugstr_w(lpType), debugstr_w(lpName), wLanguage, lpData, cbData);
1714 
1715  updates = GlobalLock(hUpdate);
1716  if (updates)
1717  {
1718  if (lpData == NULL && cbData == 0) /* remove resource */
1719  {
1720  ret = update_add_resource( updates, lpType, lpName, wLanguage, NULL, TRUE );
1721  }
1722  else
1723  {
1724  struct resource_data *data;
1725  data = allocate_resource_data( wLanguage, 0, lpData, cbData, TRUE );
1726  if (data)
1727  ret = update_add_resource( updates, lpType, lpName, wLanguage, data, TRUE );
1728  }
1729  GlobalUnlock(hUpdate);
1730  }
1731  return ret;
1732 }
1733 
1734 
1735 /***********************************************************************
1736  * UpdateResourceA (KERNEL32.@)
1737  */
1739  WORD wLanguage, LPVOID lpData, DWORD cbData)
1740 {
1741  BOOL ret;
1742  UNICODE_STRING TypeW;
1743  UNICODE_STRING NameW;
1744  if(IS_INTRESOURCE(lpType))
1745  TypeW.Buffer = ULongToPtr(LOWORD(lpType));
1746  else
1747  RtlCreateUnicodeStringFromAsciiz(&TypeW, lpType);
1748  if(IS_INTRESOURCE(lpName))
1749  NameW.Buffer = ULongToPtr(LOWORD(lpName));
1750  else
1752  ret = UpdateResourceW(hUpdate, TypeW.Buffer, NameW.Buffer, wLanguage, lpData, cbData);
1753  if(!IS_INTRESOURCE(lpType)) RtlFreeUnicodeString(&TypeW);
1755  return ret;
1756 }
DWORD codepage
Definition: res.c:602
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
static void get_resource_sizes(QUEUEDUPDATES *updates, struct resource_size_info *si)
Definition: res.c:1138
void * base
Definition: res.c:898
unsigned __int3264 UINT_PTR
Definition: activex.cpp:275
NTSYSAPI NTSTATUS NTAPI RtlCharToInteger(PCSZ String, ULONG Base, PULONG Value)
Definition: unicode.c:261
GLint level
Definition: gl.h:1546
DWORD CodePage
Definition: pedump.c:461
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define CloseHandle
Definition: compat.h:398
static IMAGE_SECTION_HEADER * get_resource_section(void *base, DWORD mapping_size)
Definition: res.c:1341
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
BOOL(CALLBACK * ENUMRESTYPEPROCW)(HMODULE, LPWSTR, LONG_PTR)
Definition: winbase.h:1403
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
BOOL WINAPI UpdateResourceA(HANDLE hUpdate, LPCSTR lpType, LPCSTR lpName, WORD wLanguage, LPVOID lpData, DWORD cbData)
Definition: res.c:1738
Type
Definition: Type.h:6
#define MapViewOfFile
Definition: compat.h:402
#define WideCharToMultiByte
Definition: compat.h:101
static BOOL unmap_file_from_memory(struct mapping_info *mi)
Definition: res.c:1078
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
ULONG NameOffset
Definition: ntimage.h:185
ULONG OffsetToDirectory
Definition: ntimage.h:194
DWORD OffsetToData
Definition: pedump.c:416
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define UIntToPtr(ui)
Definition: basetsd.h:90
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
static BOOL update_add_resource(QUEUEDUPDATES *updates, LPCWSTR Type, LPCWSTR Name, LANGID Lang, struct resource_data *resdata, BOOL overwrite_existing)
Definition: res.c:694
#define LANG_NEUTRAL
Definition: nls.h:22
#define CP_ACP
Definition: compat.h:99
DWORD strings_ofs
Definition: res.c:891
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
struct _root root
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1154
struct _IMAGE_RESOURCE_DATA_ENTRY IMAGE_RESOURCE_DATA_ENTRY
LONG NTSTATUS
Definition: precomp.h:26
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
GLsizei GLenum GLenum * types
Definition: glext.h:7753
BOOL(CALLBACK * ENUMRESNAMEPROCW)(HMODULE, LPCWSTR, LPWSTR, LONG_PTR)
Definition: winbase.h:1401
static void add_resource_data_entry(struct list *dir, struct resource_data *resdata)
Definition: res.c:660
_In_ LPCSTR lpName
Definition: winbase.h:2729
NTSTATUS NTAPI LdrFindResourceDirectory_U(IN PVOID BaseAddress, IN PLDR_RESOURCE_INFO info, IN ULONG level, OUT PIMAGE_RESOURCE_DIRECTORY *addr)
Definition: res.c:257
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
static const WCHAR typeW[]
Definition: name.c:49
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
void * lpData
Definition: res.c:604
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
struct _IMAGE_RESOURCE_DIRECTORY_ENTRY IMAGE_RESOURCE_DIRECTORY_ENTRY
static MONITORINFO mi
Definition: win.c:7331
WORD LANGID
Definition: typedefs.h:79
DWORD total_size
Definition: res.c:893
BOOL WINAPI EnumResourceNamesA(HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG_PTR lparam)
Definition: res.c:285
ULONG NameIsString
Definition: ntimage.h:186
DWORD PointerToRawData
Definition: pedump.c:290
char * LPSTR
Definition: xmlstorage.h:182
#define SUBLANG_NEUTRAL
Definition: nls.h:167
#define lstrlenW
Definition: compat.h:407
struct list children
Definition: res.c:595
IMAGE_NT_HEADERS nt
Definition: module.c:50
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
DWORD Id
DWORD WINAPI DECLSPEC_HOTPATCH SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
Definition: fileinfo.c:204
__WINE_SERVER_LIST_INLINE struct list * list_head(const struct list *list)
Definition: list.h:131
struct _test_info info[]
Definition: SetCursorPos.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOL WINAPI EnumResourceTypesA(HMODULE hmod, ENUMRESTYPEPROCA lpfun, LONG_PTR lparam)
Definition: res.c:185
DWORD size
Definition: res.c:899
BOOL WINAPI EnumResourceTypesW(HMODULE hmod, ENUMRESTYPEPROCW lpfun, LONG_PTR lparam)
Definition: res.c:236
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
struct list entry
Definition: res.c:600
DWORD data_ofs
Definition: res.c:892
BOOL read_write
Definition: res.c:900
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
GLuint GLuint * names
Definition: glext.h:11545
DWORD cbData
Definition: res.c:603
HANDLE WINAPI BeginUpdateResourceW(LPCWSTR pFileName, BOOL bDeleteExistingResources)
Definition: res.c:1611
#define GHND
Definition: winbase.h:294
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
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
unsigned char * LPBYTE
Definition: typedefs.h:52
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2079
static BOOL read_mapped_resources(QUEUEDUPDATES *updates, void *base, DWORD mapping_size)
Definition: res.c:1015
static struct resource_data * allocate_resource_data(WORD Language, DWORD codepage, LPVOID lpData, DWORD cbData, BOOL copy_data)
Definition: res.c:741
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint base
Definition: 3dtext.c:35
long LONG
Definition: pedump.c:60
BOOL WINAPI UpdateResourceW(HANDLE hUpdate, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage, LPVOID lpData, DWORD cbData)
Definition: res.c:1706
static HRSRC find_resourceA(HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang)
Definition: res.c:75
static BOOL map_file_into_memory(struct mapping_info *mi)
Definition: res.c:1053
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
#define GENERIC_WRITE
Definition: nt_native.h:90
#define debugstr_w
Definition: kernel32.h:32
DWORD types_ofs
Definition: res.c:887
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
static PVOID ptr
Definition: dispmode.c:27
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
struct NameRec_ * Name
Definition: cdprocs.h:464
int codepage
Definition: win_iconv.c:156
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
struct list root
Definition: res.c:588
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
HRSRC WINAPI FindResourceExA(HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang)
Definition: res.c:143
Definition: pedump.c:457
HANDLE file
Definition: res.c:897
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
#define FILE_MAP_READ
Definition: compat.h:427
BOOL(CALLBACK * ENUMRESTYPEPROCA)(HMODULE, LPSTR, LONG_PTR)
Definition: winbase.h:1402
BOOL WINAPI EnumResourceLanguagesW(HMODULE hmod, LPCWSTR type, LPCWSTR name, ENUMRESLANGPROCW lpfun, LONG_PTR lparam)
Definition: res.c:480
unsigned int dir
Definition: maze.c:112
const char * LPCSTR
Definition: xmlstorage.h:183
#define __TRY
Definition: compat.h:70
static struct mapping_info * create_mapping(LPCWSTR name, BOOL rw)
Definition: res.c:1096
IMAGE_OPTIONAL_HEADER64 OptionalHeader
Definition: ntimage.h:396
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define OPEN_EXISTING
Definition: compat.h:426
static int num_names
Definition: apinames.c:56
static IMAGE_SECTION_HEADER * get_section_header(void *base, DWORD mapping_size, DWORD *num_sections)
Definition: res.c:816
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 GLint GLint j
Definition: glfuncs.h:250
static const WCHAR nameW[]
Definition: main.c:46
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
static const WCHAR lang[]
Definition: wbemdisp.c:287
BOOL bDeleteExistingResources
Definition: res.c:587
DWORD OffsetToData
Definition: pedump.c:459
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static void pad(Char *s)
Definition: bzip2.c:908
static struct resource_dir_entry * find_resource_dir_entry(struct list *dir, LPCWSTR id)
Definition: res.c:621
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define TRACE(s)
Definition: solgame.cpp:4
#define IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: ntimage.h:231
GLsizeiptr size
Definition: glext.h:5919
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
if(!(yy_init))
Definition: macro.lex.yy.c:714
Definition: cmds.c:130
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define debugstr_a
Definition: kernel32.h:31
static void res_write_padding(BYTE *res_base, DWORD size)
Definition: res.c:1192
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:401
static void destroy_mapping(struct mapping_info *mi)
Definition: res.c:1086
#define FILE_MAP_WRITE
Definition: winbase.h:154
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
const char file[]
Definition: icontest.c:11
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
struct _IMAGE_RESOURCE_DIRECTORY IMAGE_RESOURCE_DIRECTORY
unsigned short WORD
Definition: ntddk_ex.h:93
DEBUG_CHANNEL(resource)
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
static LPWSTR res_strdupW(LPCWSTR str)
Definition: res.c:675
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
#define SetLastError(x)
Definition: compat.h:409
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
BOOL WINAPI EnumResourceLanguagesA(HMODULE hmod, LPCSTR type, LPCSTR name, ENUMRESLANGPROCA lpfun, LONG_PTR lparam)
Definition: res.c:428
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
int rw
USHORT Id
Definition: ntimage.h:189
BOOL WINAPI EnumResourceNamesW(HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG_PTR lparam)
Definition: res.c:358
static void add_resource_dir_entry(struct list *dir, struct resource_dir_entry *resdir)
Definition: res.c:645
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
#define __ENDTRY
Definition: compat.h:72
int ret
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
GLsizei const GLchar *const * strings
Definition: glext.h:7622
IMAGE_DOS_HEADER dos
Definition: module.c:49
BOOL(CALLBACK * ENUMRESNAMEPROCA)(HMODULE, LPCSTR, LPSTR, LONG_PTR)
Definition: winbase.h:1400
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
DWORD langs_ofs
Definition: res.c:889
static struct resource_data * find_resource_data(struct list *dir, LANGID lang)
Definition: res.c:633
static void res_free_str(LPWSTR str)
Definition: res.c:688
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
GLdouble s
Definition: gl.h:2039
Definition: _list.h:228
#define GENERIC_READ
Definition: compat.h:124
LPWSTR id
Definition: res.c:594
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
GLsizei const GLfloat * value
Definition: glext.h:6069
char string[160]
Definition: util.h:11
NTSTATUS NTAPI LdrFindResource_U(PVOID BaseAddress, PLDR_RESOURCE_INFO ResourceInfo, ULONG Level, PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
Definition: res.c:209
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
Definition: pedump.c:413
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define ERR(fmt,...)
Definition: debug.h:109
#define FILE_BEGIN
Definition: winbase.h:112
static LPWSTR resource_dup_string(const IMAGE_RESOURCE_DIRECTORY *root, const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry)
Definition: res.c:939
ULONG DataIsDirectory
Definition: ntimage.h:195
static BOOL write_raw_resources(QUEUEDUPDATES *updates)
Definition: res.c:1382
#define lstrcpyW
Definition: compat.h:406
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
static HRSRC find_resourceW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:109
static void free_resource_directory(struct list *head, int level)
Definition: res.c:767
static int resource_strcmp(LPCWSTR a, LPCWSTR b)
Definition: res.c:607
DWORD names_ofs
Definition: res.c:888
LPWSTR pFileName
Definition: res.c:586
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
LANGID lang
Definition: res.c:601
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
Definition: res.c:592
static BOOL write_resources(QUEUEDUPDATES *updates, LPBYTE base, struct resource_size_info *si, DWORD rva)
Definition: res.c:1203
static void * address_from_rva(void *base, DWORD mapping_size, DWORD rva, DWORD len)
Definition: res.c:925
unsigned int UINT
Definition: ndis.h:50
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
#define PAGE_READONLY
Definition: compat.h:127
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
Definition: list.h:87
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
static BOOL enumerate_mapped_resources(QUEUEDUPDATES *updates, void *base, DWORD mapping_size, const IMAGE_RESOURCE_DIRECTORY *root)
Definition: res.c:956
HANDLE WINAPI BeginUpdateResourceA(LPCSTR pFileName, BOOL bDeleteExistingResources)
Definition: res.c:1657
#define CreateFileW
Definition: compat.h:400
NTSTATUS NTAPI LdrAccessResource(IN PVOID BaseAddress, IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, OUT PVOID *Resource OPTIONAL, OUT PULONG Size OPTIONAL)
Definition: res.c:244
static BOOL check_pe_exe(HANDLE file, QUEUEDUPDATES *updates)
Definition: res.c:837
static BOOL resize_mapping(struct mapping_info *mi, DWORD new_size)
Definition: res.c:1120
Definition: name.c:36
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static DWORD get_init_data_size(void *base, DWORD mapping_size)
Definition: res.c:1366
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:847
#define MAKELANGID(p, s)
Definition: nls.h:15
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ULONG_PTR
Definition: config.h:101
static NTSTATUS get_res_nameW(LPCWSTR name, UNICODE_STRING *str)
Definition: res.c:53
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IMAGE_DIRECTORY_ENTRY_RESOURCE
Definition: pedump.c:261
#define LIST_ENTRY(type)
Definition: queue.h:175
BOOL(CALLBACK * ENUMRESLANGPROCW)(HMODULE, LPCWSTR, LPCWSTR, WORD, LONG_PTR)
Definition: winbase.h:1399
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define UnmapViewOfFile
Definition: compat.h:403
#define memset(x, y, z)
Definition: compat.h:39
union _IMAGE_SECTION_HEADER::@1528 Misc
static SERVICE_STATUS status
Definition: service.c:31
static const IMAGE_SECTION_HEADER * section_from_rva(void *base, DWORD mapping_size, DWORD rva)
Definition: res.c:903
static NTSTATUS get_res_nameA(LPCSTR name, UNICODE_STRING *str)
Definition: res.c:32
int k
Definition: mpi.c:3369
#define LOWORD(l)
Definition: pedump.c:82
struct list entry
Definition: res.c:593
#define HeapFree(x, y, z)
Definition: compat.h:394
BOOL(CALLBACK * ENUMRESLANGPROCA)(HMODULE, LPCSTR, LPCSTR, WORD, LONG_PTR)
Definition: winbase.h:1398
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:71
BOOL WINAPI EndUpdateResourceW(HANDLE hUpdate, BOOL fDiscard)
Definition: res.c:1671
HMODULE hModule
Definition: animate.c:44
#define PAGE_READWRITE
Definition: nt_native.h:1304
static IMAGE_NT_HEADERS * get_nt_header(void *base, DWORD mapping_size)
Definition: res.c:793
DWORD Size
Definition: pedump.c:460
Definition: fci.c:126
BOOL WINAPI EndUpdateResourceA(HANDLE hUpdate, BOOL fDiscard)
Definition: res.c:1697
Definition: ps.c:97
DWORD data_entry_ofs
Definition: res.c:890