ReactOS 0.4.15-dev-7788-g1ad9096
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{
35 {
36 str->Buffer = ULongToPtr(LOWORD(name));
37 return STATUS_SUCCESS;
38 }
39 if (name[0] == '#')
40 {
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{
56 {
57 str->Buffer = ULongToPtr(LOWORD(name));
58 return STATUS_SUCCESS;
59 }
60 if (name[0] == '#')
61 {
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 }
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 }
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
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
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;
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;
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 }
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;
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;
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 }
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;
305 goto done;
306 info.Type = (ULONG_PTR)typeW.Buffer;
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;
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
347done:
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;
377 goto done;
378 info.Type = (ULONG_PTR)typeW.Buffer;
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;
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 }
417done:
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;
446 goto done;
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 }
469done:
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;
498 goto done;
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 }
521done:
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
584typedef struct
585{
588 struct list root;
590
591/* this structure is shared for types and names */
593 struct list entry;
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
645static 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
660static void add_resource_data_entry( struct list *dir, struct resource_data *resdata )
661{
662 struct resource_data *ent;
663
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
688static 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
767static 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 );
781 HeapFree(GetProcessHeap(), 0, ent);
782 }
783 else
784 {
785 struct resource_data *data;
786
787 data = LIST_ENTRY( ptr, struct resource_data, entry );
789 }
790 }
791}
792
793static 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
816static 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;
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;
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
877done:
878 if (base)
880 if (mapping)
882
883 return ret;
884}
885
894};
895
898 void *base;
901};
902
903static 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
925static 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
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
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
1015static 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;
1057
1058 if (mi->read_write)
1059 {
1060 page_attr = PAGE_READWRITE;
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 );
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
1086static 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
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 }
1117 return NULL;
1118}
1119
1120static 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
1138static 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
1147 {
1148 num_types++;
1149 if (!IS_INTRESOURCE( types->id ))
1150 strings_size += sizeof (WORD) + lstrlenW( types->id )*sizeof (WCHAR);
1151
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 +
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
1192static 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;
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;
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
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;
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
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;
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 */
1342{
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
1366static 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;
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
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
1596done:
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 */
1611HANDLE 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
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 */
1657HANDLE 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);
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 Id
@ lparam
Definition: SystemMenu.c:31
Type
Definition: Type.h:7
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
struct outqueuenode * head
Definition: adnsresfilter.c:66
static int num_names
Definition: apinames.c:56
struct NameRec_ * Name
Definition: cdprocs.h:460
unsigned int dir
Definition: maze.c:112
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR nameW[]
Definition: main.c:46
#define DEBUG_CHANNEL(args)
Definition: rdesktop.h:159
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define UIntToPtr(ui)
Definition: basetsd.h:90
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define ERR(fmt,...)
Definition: debug.h:110
struct _root root
Definition: list.h:37
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HMODULE hModule
Definition: animate.c:44
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define FILE_BEGIN
Definition: compat.h:761
#define UnmapViewOfFile
Definition: compat.h:746
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define __TRY
Definition: compat.h:80
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
#define __ENDTRY
Definition: compat.h:82
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MapViewOfFile
Definition: compat.h:745
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
static void res_write_padding(BYTE *res_base, DWORD size)
Definition: res.c:1192
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
BOOL WINAPI EnumResourceTypesW(HMODULE hmod, ENUMRESTYPEPROCW lpfun, LONG_PTR lparam)
Definition: res.c:236
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
BOOL WINAPI UpdateResourceW(HANDLE hUpdate, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage, LPVOID lpData, DWORD cbData)
Definition: res.c:1706
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
static LPWSTR res_strdupW(LPCWSTR str)
Definition: res.c:675
static BOOL enumerate_mapped_resources(QUEUEDUPDATES *updates, void *base, DWORD mapping_size, const IMAGE_RESOURCE_DIRECTORY *root)
Definition: res.c:956
static LPWSTR resource_dup_string(const IMAGE_RESOURCE_DIRECTORY *root, const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry)
Definition: res.c:939
static NTSTATUS get_res_nameW(LPCWSTR name, UNICODE_STRING *str)
Definition: res.c:53
static struct mapping_info * create_mapping(LPCWSTR name, BOOL rw)
Definition: res.c:1096
static BOOL map_file_into_memory(struct mapping_info *mi)
Definition: res.c:1053
BOOL WINAPI UpdateResourceA(HANDLE hUpdate, LPCSTR lpType, LPCSTR lpName, WORD wLanguage, LPVOID lpData, DWORD cbData)
Definition: res.c:1738
HANDLE WINAPI BeginUpdateResourceA(LPCSTR pFileName, BOOL bDeleteExistingResources)
Definition: res.c:1657
BOOL WINAPI EndUpdateResourceW(HANDLE hUpdate, BOOL fDiscard)
Definition: res.c:1671
static BOOL write_raw_resources(QUEUEDUPDATES *updates)
Definition: res.c:1382
static void get_resource_sizes(QUEUEDUPDATES *updates, struct resource_size_info *si)
Definition: res.c:1138
static BOOL write_resources(QUEUEDUPDATES *updates, LPBYTE base, struct resource_size_info *si, DWORD rva)
Definition: res.c:1203
static BOOL unmap_file_from_memory(struct mapping_info *mi)
Definition: res.c:1078
static BOOL read_mapped_resources(QUEUEDUPDATES *updates, void *base, DWORD mapping_size)
Definition: res.c:1015
BOOL WINAPI EnumResourceTypesA(HMODULE hmod, ENUMRESTYPEPROCA lpfun, LONG_PTR lparam)
Definition: res.c:185
static void free_resource_directory(struct list *head, int level)
Definition: res.c:767
static BOOL update_add_resource(QUEUEDUPDATES *updates, LPCWSTR Type, LPCWSTR Name, LANGID Lang, struct resource_data *resdata, BOOL overwrite_existing)
Definition: res.c:694
static HRSRC find_resourceA(HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang)
Definition: res.c:75
BOOL WINAPI EnumResourceLanguagesA(HMODULE hmod, LPCSTR type, LPCSTR name, ENUMRESLANGPROCA lpfun, LONG_PTR lparam)
Definition: res.c:428
static void destroy_mapping(struct mapping_info *mi)
Definition: res.c:1086
static int resource_strcmp(LPCWSTR a, LPCWSTR b)
Definition: res.c:607
static void add_resource_data_entry(struct list *dir, struct resource_data *resdata)
Definition: res.c:660
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
static DWORD get_init_data_size(void *base, DWORD mapping_size)
Definition: res.c:1366
static struct resource_data * allocate_resource_data(WORD Language, DWORD codepage, LPVOID lpData, DWORD cbData, BOOL copy_data)
Definition: res.c:741
BOOL WINAPI EnumResourceNamesA(HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG_PTR lparam)
Definition: res.c:285
static IMAGE_NT_HEADERS * get_nt_header(void *base, DWORD mapping_size)
Definition: res.c:793
static NTSTATUS get_res_nameA(LPCSTR name, UNICODE_STRING *str)
Definition: res.c:32
static BOOL resize_mapping(struct mapping_info *mi, DWORD new_size)
Definition: res.c:1120
static HRSRC find_resourceW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:109
static BOOL check_pe_exe(HANDLE file, QUEUEDUPDATES *updates)
Definition: res.c:837
static const IMAGE_SECTION_HEADER * section_from_rva(void *base, DWORD mapping_size, DWORD rva)
Definition: res.c:903
static struct resource_data * find_resource_data(struct list *dir, LANGID lang)
Definition: res.c:633
static IMAGE_SECTION_HEADER * get_resource_section(void *base, DWORD mapping_size)
Definition: res.c:1341
static struct resource_dir_entry * find_resource_dir_entry(struct list *dir, LPCWSTR id)
Definition: res.c:621
static void res_free_str(LPWSTR str)
Definition: res.c:688
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
static void * address_from_rva(void *base, DWORD mapping_size, DWORD rva, DWORD len)
Definition: res.c:925
BOOL WINAPI EnumResourceNamesW(HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG_PTR lparam)
Definition: res.c:358
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
HANDLE WINAPI BeginUpdateResourceW(LPCWSTR pFileName, BOOL bDeleteExistingResources)
Definition: res.c:1611
BOOL WINAPI EndUpdateResourceA(HANDLE hUpdate, BOOL fDiscard)
Definition: res.c:1697
HRSRC WINAPI FindResourceExA(HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang)
Definition: res.c:143
BOOL WINAPI EnumResourceLanguagesW(HMODULE hmod, LPCWSTR type, LPCWSTR name, ENUMRESLANGPROCW lpfun, LONG_PTR lparam)
Definition: res.c:480
static IMAGE_SECTION_HEADER * get_section_header(void *base, DWORD mapping_size, DWORD *num_sections)
Definition: res.c:816
static void add_resource_dir_entry(struct list *dir, struct resource_dir_entry *resdir)
Definition: res.c:645
static const WCHAR typeW[]
Definition: name.c:51
#define ULONG_PTR
Definition: config.h:101
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLuint GLuint * names
Definition: glext.h:11545
GLsizei const GLchar *const * strings
Definition: glext.h:7622
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
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
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
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
NTSTATUS NTAPI LdrAccessResource(_In_ PVOID BaseAddress, _In_ PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, _Out_opt_ PVOID *Resource, _Out_opt_ PULONG Size)
NTSTATUS NTAPI LdrFindResource_U(_In_ PVOID BaseAddress, _In_ PLDR_RESOURCE_INFO ResourceInfo, _In_ ULONG Level, _Out_ PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
NTSTATUS NTAPI LdrFindResourceDirectory_U(_In_ PVOID BaseAddress, _In_ PLDR_RESOURCE_INFO ResourceInfo, _In_ ULONG Level, _Out_ PIMAGE_RESOURCE_DIRECTORY *ResourceDirectory)
USHORT LANGID
Definition: mui.h:9
if(dx< 0)
Definition: linetemp.h:194
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
char string[160]
Definition: util.h:11
static PVOID ptr
Definition: dispmode.c:27
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
IMAGE_NT_HEADERS nt
Definition: module.c:50
IMAGE_DOS_HEADER dos
Definition: module.c:49
int k
Definition: mpi.c:3369
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
#define PAGE_READWRITE
Definition: nt_native.h:1304
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSYSAPI NTSTATUS NTAPI RtlCharToInteger(PCSZ String, ULONG Base, PULONG Value)
Definition: unicode.c:261
#define IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: ntimage.h:231
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define LOWORD(l)
Definition: pedump.c:82
struct _IMAGE_RESOURCE_DIRECTORY_ENTRY IMAGE_RESOURCE_DIRECTORY_ENTRY
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
long LONG
Definition: pedump.c:60
struct _IMAGE_RESOURCE_DIRECTORY IMAGE_RESOURCE_DIRECTORY
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
struct _IMAGE_RESOURCE_DATA_ENTRY IMAGE_RESOURCE_DATA_ENTRY
#define IMAGE_DIRECTORY_ENTRY_RESOURCE
Definition: pedump.c:261
#define rw
Definition: rosglue.h:38
const WCHAR * str
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_NEUTRAL
Definition: nls.h:167
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
Definition: list.h:87
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR pFileName
Definition: res.c:586
BOOL bDeleteExistingResources
Definition: res.c:587
struct list root
Definition: res.c:588
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
IMAGE_OPTIONAL_HEADER64 OptionalHeader
Definition: ntimage.h:396
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
Definition: pedump.c:458
DWORD CodePage
Definition: pedump.c:461
DWORD OffsetToData
Definition: pedump.c:459
DWORD Size
Definition: pedump.c:460
Definition: pedump.c:414
DWORD OffsetToData
Definition: pedump.c:416
ULONG OffsetToDirectory
Definition: ntimage.h:194
ULONG DataIsDirectory
Definition: ntimage.h:195
ULONG NameOffset
Definition: ntimage.h:185
ULONG NameIsString
Definition: ntimage.h:186
USHORT Id
Definition: ntimage.h:189
DWORD PointerToRawData
Definition: pedump.c:290
union _IMAGE_SECTION_HEADER::@1555 Misc
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
Definition: fci.c:127
Definition: list.h:15
BOOL read_write
Definition: res.c:900
DWORD size
Definition: res.c:899
void * base
Definition: res.c:898
HANDLE file
Definition: res.c:897
Definition: name.c:39
DWORD codepage
Definition: res.c:602
struct list entry
Definition: res.c:600
LANGID lang
Definition: res.c:601
void * lpData
Definition: res.c:604
DWORD cbData
Definition: res.c:603
Definition: res.c:592
struct list children
Definition: res.c:595
struct list entry
Definition: res.c:593
LPWSTR id
Definition: res.c:594
DWORD data_ofs
Definition: res.c:892
DWORD data_entry_ofs
Definition: res.c:890
DWORD total_size
Definition: res.c:893
DWORD names_ofs
Definition: res.c:888
DWORD strings_ofs
Definition: res.c:891
DWORD langs_ofs
Definition: res.c:889
DWORD types_ofs
Definition: res.c:887
Definition: ps.c:97
Definition: cmds.c:130
#define LIST_ENTRY(type)
Definition: queue.h:175
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: pdh_main.c:94
static const WCHAR lang[]
Definition: wbemdisp.c:287
int ret
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
static MONITORINFO mi
Definition: win.c:7338
int codepage
Definition: win_iconv.c:156
BOOL(CALLBACK * ENUMRESNAMEPROCW)(HMODULE, LPCWSTR, LPWSTR, LONG_PTR)
Definition: winbase.h:1448
BOOL(CALLBACK * ENUMRESLANGPROCA)(HMODULE, LPCSTR, LPCSTR, WORD, LONG_PTR)
Definition: winbase.h:1445
#define FILE_MAP_WRITE
Definition: winbase.h:154
BOOL(CALLBACK * ENUMRESTYPEPROCA)(HMODULE, LPSTR, LONG_PTR)
Definition: winbase.h:1449
_In_ LPCSTR lpName
Definition: winbase.h:2789
BOOL(CALLBACK * ENUMRESNAMEPROCA)(HMODULE, LPCSTR, LPSTR, LONG_PTR)
Definition: winbase.h:1447
#define GHND
Definition: winbase.h:297
BOOL(CALLBACK * ENUMRESLANGPROCW)(HMODULE, LPCWSTR, LPCWSTR, WORD, LONG_PTR)
Definition: winbase.h:1446
BOOL(CALLBACK * ENUMRESTYPEPROCW)(HMODULE, LPWSTR, LONG_PTR)
Definition: winbase.h:1450
#define WINAPI
Definition: msvc.h:6
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193