1 static char RCSId[] = "$Id: ne_resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
18 /* #define DEBUG_RESOURCE */
20 static int ResourceFd = -1;
21 static HANDLE ResourceInst = 0;
22 static struct w_files *ResourceFileInfo;
24 /**********************************************************************
27 void RSC_LoadNameTable(void)
29 struct resource_typeinfo_s typeinfo;
30 struct resource_nameinfo_s nameinfo;
31 unsigned short size_shift;
43 * Move to beginning of resource table.
45 rtoff = (ResourceFileInfo->mz_header->ne_offset +
46 ResourceFileInfo->ne->ne_header->resource_tab_offset);
47 lseek(ResourceFd, rtoff, SEEK_SET);
52 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
57 size_shift = CONV_SHORT(size_shift);
62 typeinfo.type_id = 0xffff;
63 while (typeinfo.type_id != 0)
65 if (!load_typeinfo (ResourceFd, &typeinfo))
68 if (typeinfo.type_id == 0)
70 if (typeinfo.type_id == 0x800f)
72 for (i = 0; i < typeinfo.count; i++)
74 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
80 saved_pos = lseek(ResourceFd, 0, SEEK_CUR);
81 lseek(ResourceFd, (long) nameinfo.offset << size_shift,
83 read(ResourceFd, &len, sizeof(len));
86 new = (RESNAMTAB *) GlobalQuickAlloc(sizeof(*new));
90 read(ResourceFd, &new->type_ord, 2);
91 read(ResourceFd, &new->id_ord, 2);
92 read(ResourceFd, read_buf, len - 6);
94 p = read_buf + strlen(read_buf) + 1;
95 strncpy(new->id, p, MAX_NAME_LENGTH);
96 new->id[MAX_NAME_LENGTH - 1] = '\0';
98 read(ResourceFd, &len, sizeof(len));
101 lseek(ResourceFd, saved_pos, SEEK_SET);
107 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
110 ResourceFileInfo->ne->resnamtab = top;
113 /**********************************************************************
117 OpenResourceFile(HANDLE instance)
122 if (ResourceInst == instance)
125 w = GetFileInfo(instance);
128 ResourceFileInfo = w;
129 res_file = w->filename;
134 ResourceInst = instance;
135 ResourceFd = open (res_file, O_RDONLY);
138 if (w->ne->resnamtab == (RESNAMTAB *) -1)
145 #ifdef DEBUG_RESOURCE
146 printf("OpenResourceFile(%04X) // file='%s' hFile=%04X !\n",
147 instance, w->filename, ResourceFd);
152 int load_typeinfo (int fd, struct resource_typeinfo_s *typeinfo)
154 return read (fd, typeinfo, sizeof (*typeinfo)) == sizeof (*typeinfo);
157 int type_match(int type_id1, int type_id2, int fd, off_t off)
166 if ((type_id1 & 0xffff0000) == 0) {
167 if ((type_id2 & 0x8000) == 0)
169 return (type_id1 & 0x000f) == (type_id2 & 0x000f);
171 if ((type_id2 & 0x8000) != 0)
173 #ifdef DEBUG_RESOURCE
174 printf("type_compare: type_id2=%04X !\n", type_id2);
176 old_pos = lseek(fd, 0, SEEK_CUR);
177 lseek(fd, off + type_id2, SEEK_SET);
179 nbytes = CONV_CHAR_TO_LONG (c);
180 #ifdef DEBUG_RESOURCE
181 printf("type_compare: namesize=%d\n", nbytes);
183 read(fd, name, nbytes);
184 lseek(fd, old_pos, SEEK_SET);
186 #ifdef DEBUG_RESOURCE
187 printf("type_compare: name=`%s'\n", name);
189 return strcasecmp((char *) type_id1, name) == 0;
192 /**********************************************************************
193 * FindResourceByNumber
196 FindResourceByNumber(struct resource_nameinfo_s *result_p,
197 int type_id, int resource_id)
199 struct resource_typeinfo_s typeinfo;
200 struct resource_nameinfo_s nameinfo;
201 unsigned short size_shift;
206 * Move to beginning of resource table.
208 rtoff = (ResourceFileInfo->mz_header->ne_offset +
209 ResourceFileInfo->ne->ne_header->resource_tab_offset);
210 lseek(ResourceFd, rtoff, SEEK_SET);
215 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
218 printf("FindResourceByNumber (%d) bad block size !\n",(int) resource_id);
221 size_shift = CONV_SHORT(size_shift);
226 if (!load_typeinfo (ResourceFd, &typeinfo)){
227 printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id);
230 #ifdef DEBUG_RESOURCE
231 printf("FindResourceByNumber type=%X count=%d ?=%d searched=%08X\n",
232 typeinfo.type_id, typeinfo.count, typeinfo.reserved, type_id);
234 if (typeinfo.type_id == 0) break;
235 if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff)) {
237 for (i = 0; i < typeinfo.count; i++) {
239 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
242 if (!load_nameinfo (ResourceFd, &nameinfo))
245 printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id);
248 #ifdef DEBUG_RESOURCE
249 printf("FindResource: search type=%X id=%X // type=%X id=%X\n",
250 type_id, resource_id, typeinfo.type_id, nameinfo.id);
252 if (nameinfo.id == resource_id) {
253 memcpy(result_p, &nameinfo, sizeof(nameinfo));
259 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
265 /**********************************************************************
269 FindResourceByName(struct resource_nameinfo_s *result_p,
270 int type_id, char *resource_name)
272 struct resource_typeinfo_s typeinfo;
273 struct resource_nameinfo_s nameinfo;
274 unsigned short size_shift;
275 off_t old_pos, new_pos;
276 unsigned char nbytes;
282 * Check for loaded name table.
284 if (ResourceFileInfo->ne->resnamtab != NULL)
288 for (e = ResourceFileInfo->ne->resnamtab; e != NULL; e = e->next)
290 if (e->type_ord == (type_id & 0x000f) &&
291 strcasecmp(e->id, resource_name) == 0)
293 return FindResourceByNumber(result_p, type_id, e->id_ord);
301 * Move to beginning of resource table.
303 rtoff = (ResourceFileInfo->mz_header->ne_offset +
304 ResourceFileInfo->ne->ne_header->resource_tab_offset);
305 lseek(ResourceFd, rtoff, SEEK_SET);
310 if (read(ResourceFd, &size_shift, sizeof(size_shift)) !=
313 printf("FindResourceByName (%s) bad block size !\n", resource_name);
316 size_shift = CONV_SHORT (size_shift);
323 if (!load_typeinfo (ResourceFd, &typeinfo))
325 printf("FindResourceByName (%s) bad typeinfo size !\n", resource_name);
328 #ifdef DEBUG_RESOURCE
329 printf("FindResourceByName typeinfo.type_id=%X count=%d type_id=%X\n",
330 typeinfo.type_id, typeinfo.count, type_id);
332 if (typeinfo.type_id == 0) break;
333 if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff))
335 for (i = 0; i < typeinfo.count; i++)
338 if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) !=
341 if (!load_nameinfo (ResourceFd, &nameinfo))
344 printf("FindResourceByName (%s) bad nameinfo size !\n", resource_name);
348 if ((nameinfo.id & 0x8000) != 0) continue;
350 #ifdef DEBUG_RESOURCE
351 printf("FindResourceByName // nameinfo.id=%04X !\n", nameinfo.id);
353 old_pos = lseek(ResourceFd, 0, SEEK_CUR);
354 new_pos = rtoff + nameinfo.id;
355 lseek(ResourceFd, new_pos, SEEK_SET);
356 read(ResourceFd, &nbytes, 1);
357 #ifdef DEBUG_RESOURCE
358 printf("FindResourceByName // namesize=%d !\n", nbytes);
360 nbytes = CONV_CHAR_TO_LONG (nbytes);
361 read(ResourceFd, name, nbytes);
362 lseek(ResourceFd, old_pos, SEEK_SET);
364 #ifdef DEBUG_RESOURCE
365 printf("FindResourceByName type_id=%X (%d of %d) name='%s' resource_name='%s'\n",
366 typeinfo.type_id, i + 1, typeinfo.count,
367 name, resource_name);
369 if (strcasecmp(name, resource_name) == 0)
371 memcpy(result_p, &nameinfo, sizeof(nameinfo));
377 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
384 /**********************************************************************
385 * GetRsrcCount [internal]
387 int GetRsrcCount(HINSTANCE hInst, int type_id)
389 struct resource_typeinfo_s typeinfo;
390 struct resource_nameinfo_s nameinfo;
391 unsigned short size_shift;
394 if (hInst == 0) return 0;
395 #ifdef DEBUG_RESOURCE
396 printf("GetRsrcCount hInst=%04X typename=%08X\n", hInst, type_id);
398 if (OpenResourceFile(hInst) < 0) return 0;
401 * Move to beginning of resource table.
403 rtoff = (ResourceFileInfo->mz_header->ne_offset +
404 ResourceFileInfo->ne->ne_header->resource_tab_offset);
405 lseek(ResourceFd, rtoff, SEEK_SET);
409 if (read(ResourceFd, &size_shift, sizeof(size_shift)) != sizeof(size_shift)) {
410 printf("GetRsrcCount // bad block size !\n");
413 size_shift = CONV_SHORT (size_shift);
415 if (!load_typeinfo (ResourceFd, &typeinfo)) {
416 printf("GetRsrcCount // bad typeinfo size !\n");
419 #ifdef DEBUG_RESOURCE
420 printf("GetRsrcCount // typeinfo.type_id=%X count=%d type_id=%X\n",
421 typeinfo.type_id, typeinfo.count, type_id);
423 if (typeinfo.type_id == 0) break;
424 if (type_match(type_id, typeinfo.type_id, ResourceFd, rtoff)) {
425 return typeinfo.count;
428 lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
434 /**********************************************************************
435 * NE_FindResource [KERNEL.60]
438 NE_FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name,
443 #ifdef DEBUG_RESOURCE
444 printf("NE_FindResource hInst=%04X typename=%08X resname=%08X\n",
445 instance, type_name, resource_name);
449 ResourceFileInfo = r->wpnt;
451 /* nametable loaded ? */
452 if (r->wpnt->ne->resnamtab == NULL)
455 if (((int) type_name & 0xffff0000) == 0)
457 type = (int) type_name;
459 else if (type_name[0] == '\0')
463 else if (type_name[0] == '#')
465 type = atoi(type_name + 1);
469 type = (int) type_name;
471 if (((int) resource_name & 0xffff0000) == 0)
473 r->size_shift = FindResourceByNumber(&r->nameinfo, type,
474 (int) resource_name | 0x8000);
476 else if (resource_name[0] == '\0')
478 r->size_shift = FindResourceByNumber(&r->nameinfo, type, -1);
480 else if (resource_name[0] == '#')
482 r->size_shift = FindResourceByNumber(&r->nameinfo, type,
483 atoi(resource_name + 1));
487 r->size_shift = FindResourceByName(&r->nameinfo, type, resource_name);
490 if (r->size_shift == -1)
492 printf("NE_FindResource hInst=%04X typename=%08X resname=%08X not found!\n",
493 instance, (int) type_name, (int) resource_name);
496 r->size = r->nameinfo.length << r->size_shift;
497 r->offset = r->nameinfo.offset << r->size_shift;