Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1 | #ifndef WINELIB |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 2 | /* |
Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 3 | * (c) 1994 Erik Bos <erik@xs4all.nl> |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 4 | * |
| 5 | * based on Eric Youndale's pe-test and: |
| 6 | * |
| 7 | * ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP |
| 8 | */ |
| 9 | |
| 10 | #include <stdio.h> |
| 11 | #include <stdlib.h> |
| 12 | #include <string.h> |
| 13 | #include <sys/types.h> |
| 14 | #include <sys/stat.h> |
| 15 | #include <fcntl.h> |
| 16 | #include <unistd.h> |
| 17 | #include "windows.h" |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 18 | #include "ldt.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 19 | #include "neexe.h" |
| 20 | #include "peexe.h" |
| 21 | #include "dlls.h" |
Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 22 | #include "pe_image.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 23 | #include "resource.h" |
Alexandre Julliard | 3a405ba | 1994-10-30 16:25:19 +0000 | [diff] [blame] | 24 | #include "stddebug.h" |
| 25 | /* #define DEBUG_RESOURCE */ |
Alexandre Julliard | 3a405ba | 1994-10-30 16:25:19 +0000 | [diff] [blame] | 26 | #include "debug.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 27 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 28 | #if 0 |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 29 | |
| 30 | static int |
| 31 | find_lang(char *root, struct PE_Resource_Directory *resource, RESOURCE *r) |
| 32 | { |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 33 | struct PE_Directory_Entry *type_dir; |
| 34 | struct PE_Resource_Leaf_Entry *leaf; |
| 35 | |
| 36 | type_dir = (struct PE_Directory_Entry *)(resource + 1); |
| 37 | type_dir += resource->NumberOfNamedEntries; |
| 38 | |
| 39 | /* grab the 1st resource available */ |
| 40 | leaf = (struct PE_Resource_Leaf_Entry *) (root + type_dir->OffsetToData); |
Alexandre Julliard | 3a405ba | 1994-10-30 16:25:19 +0000 | [diff] [blame] | 41 | dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n", (int) type_dir->Name); |
| 42 | dprintf_resource(stddeb, "\t\taddress %ld, size %ld, language id %ld\n", leaf->OffsetToData, leaf->Size, leaf->CodePage); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 43 | r->offset = leaf->OffsetToData - r->wpnt->pe->resource_offset; |
| 44 | r->size = leaf->Size; |
| 45 | printf("\t\toffset %d, size %d\n", r->offset, r->size); |
| 46 | return 1; |
| 47 | |
| 48 | /* for(i=0; i< resource->NumberOfIdEntries; i++) { |
| 49 | leaf = (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)); |
Alexandre Julliard | 3a405ba | 1994-10-30 16:25:19 +0000 | [diff] [blame] | 50 | dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n", |
| 51 | (int) type_dir->Name); |
| 52 | dprintf_resource(stddeb, "\t\t%x %x %x\n", leaf->OffsetToData, |
| 53 | leaf->Size, leaf->CodePage); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 54 | type_dir++; |
| 55 | } */ |
| 56 | } |
| 57 | |
| 58 | static int |
| 59 | find_resource(char *root, struct PE_Resource_Directory *resource, |
| 60 | LPSTR resource_name, RESOURCE *r) |
| 61 | { |
| 62 | int i; |
| 63 | char res_name[256]; |
| 64 | struct PE_Directory_Entry *type_dir; |
| 65 | struct PE_Directory_Name_String_U *name; |
| 66 | |
| 67 | type_dir = (struct PE_Directory_Entry *)(resource + 1); |
| 68 | |
| 69 | if (HIWORD((DWORD)resource_name)) { |
| 70 | for(i=0; i< resource->NumberOfNamedEntries; i++) { |
| 71 | name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING)); |
| 72 | memset(res_name, 0, sizeof(res_name)); |
| 73 | my_wcstombs(res_name, name->NameString, name->Length); |
Alexandre Julliard | 3a405ba | 1994-10-30 16:25:19 +0000 | [diff] [blame] | 74 | dprintf_resource(stddeb, "\tPE_findresource: name %s\n", res_name); |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 75 | if (lstrcmpi(res_name, resource_name) == 0) |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 76 | return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r); |
| 77 | type_dir++; |
| 78 | } |
| 79 | } else { |
| 80 | type_dir += resource->NumberOfNamedEntries; |
| 81 | for(i=0; i< resource->NumberOfIdEntries; i++) { |
Alexandre Julliard | 3a405ba | 1994-10-30 16:25:19 +0000 | [diff] [blame] | 82 | dprintf_resource(stddeb, "\tPE_findresource: name %8x\n", (int) type_dir->Name); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 83 | if (type_dir->Name == ((int) resource_name & 0xff)) |
| 84 | return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r); |
| 85 | type_dir++; |
| 86 | } |
| 87 | } |
| 88 | return 0; |
| 89 | } |
| 90 | |
| 91 | static int |
| 92 | find_type(struct PE_Resource_Directory *resource, LPSTR resource_name, |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 93 | LPSTR type_name) |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 94 | { |
| 95 | int i; |
| 96 | char *root, res_name[256]; |
| 97 | struct PE_Directory_Entry *type_dir; |
| 98 | struct PE_Directory_Name_String_U *name; |
| 99 | |
| 100 | root = (char *) resource; |
| 101 | type_dir = (struct PE_Directory_Entry *)(resource + 1); |
| 102 | |
| 103 | if (HIWORD((DWORD)type_name)) { |
| 104 | for(i=0; i< resource->NumberOfNamedEntries; i++) { |
| 105 | name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING)); |
| 106 | memset(res_name, 0, sizeof(res_name)); |
| 107 | my_wcstombs(res_name, name->NameString, name->Length); |
Alexandre Julliard | 3a405ba | 1994-10-30 16:25:19 +0000 | [diff] [blame] | 108 | dprintf_resource(stddeb, "PE_findtype: type %s\n", |
| 109 | res_name); |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 110 | if (lstrcmpi(res_name, type_name) == 0) |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 111 | return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r); |
| 112 | type_dir++; |
| 113 | } |
| 114 | } else { |
| 115 | type_dir += resource->NumberOfNamedEntries; |
| 116 | for(i=0; i< resource->NumberOfIdEntries; i++) { |
Alexandre Julliard | 3a405ba | 1994-10-30 16:25:19 +0000 | [diff] [blame] | 117 | dprintf_resource(stddeb, "PE_findtype: type %8x\n", (int) type_dir->Name); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 118 | if (type_dir->Name == ((int) type_name & 0xff)) |
| 119 | return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r); |
| 120 | type_dir++; |
| 121 | } |
| 122 | } |
| 123 | return 0; |
| 124 | } |
| 125 | |
| 126 | /********************************************************************** |
| 127 | * PE_FindResource [KERNEL.60] |
| 128 | */ |
| 129 | int |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 130 | PE_FindResource(HANDLE instance, SEGPTR resource_name, SEGPTR type_name, |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 131 | RESOURCE *r) |
| 132 | { |
Alexandre Julliard | 3a405ba | 1994-10-30 16:25:19 +0000 | [diff] [blame] | 133 | dprintf_resource(stddeb, "PE_FindResource hInst=%04X typename=%08X resname=%08X\n", |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 134 | instance, (int) type_name, (int) resource_name); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 135 | if (HIWORD(resource_name)) |
| 136 | { |
| 137 | char *resource_name_ptr = PTR_SEG_TO_LIN( resource_name ); |
| 138 | if (resource_name_ptr[0] == '#') |
| 139 | resource_name = (SEGPTR) atoi(resource_name_ptr + 1); |
| 140 | else |
| 141 | resource_name = (SEGPTR)resource_name_ptr; |
| 142 | } |
| 143 | if (HIWORD(type_name)) |
| 144 | { |
| 145 | char *type_name_ptr = PTR_SEG_TO_LIN( type_name ); |
| 146 | if (type_name_ptr[0] == '#') |
| 147 | type_name = (SEGPTR) atoi(type_name_ptr + 1); |
| 148 | else |
| 149 | type_name = (SEGPTR) type_name_ptr; |
| 150 | } |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 151 | return find_type(r->wpnt->pe->pe_resource, resource_name, type_name); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 152 | } |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 153 | #endif |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 154 | |
| 155 | #endif /* WINELIB */ |