3 * Copyright 1993 Robert J. Amstadt
4 * Copyright 1995 Alexandre Julliard
10 #include <sys/types.h>
25 typedef struct resource_typeinfo_s NE_TYPEINFO
;
26 typedef struct resource_nameinfo_s NE_NAMEINFO
;
29 /***********************************************************************
32 * Find the type and resource id from their names.
33 * Return value is MAKELONG( typeId, resId ), or 0 if not found.
35 static DWORD
NE_FindNameTableId( HMODULE hModule
, SEGPTR typeId
, SEGPTR resId
)
38 NE_TYPEINFO
*pTypeInfo
;
39 NE_NAMEINFO
*pNameInfo
;
45 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
46 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
47 for (; pTypeInfo
->type_id
!= 0;
48 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
49 pTypeInfo
->count
* sizeof(NE_NAMEINFO
)))
51 if (pTypeInfo
->type_id
!= 0x800f) continue;
52 pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
53 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
55 dprintf_resource( stddeb
, "NameTable entry: type=%04x id=%04x\n",
56 pTypeInfo
->type_id
, pNameInfo
->id
);
57 handle
= LoadResource( hModule
, (int)pNameInfo
- (int)pModule
);
58 for(p
= (WORD
*)LockResource(handle
); *p
; p
= (WORD
*)((char*)p
+*p
))
60 dprintf_resource( stddeb
," type=%04x '%s' id=%04x '%s'\n",
61 p
[1], (char *)(p
+3), p
[2],
62 (char *)(p
+3)+strlen((char *)(p
+3))+1 );
63 /* Check for correct type */
67 if (!HIWORD(typeId
)) continue;
68 if (strcasecmp( (char *)PTR_SEG_TO_LIN(typeId
),
69 (char *)(p
+ 3) )) continue;
71 else if (HIWORD(typeId
) || ((typeId
& ~0x8000)!= p
[1]))
74 /* Now check for the id */
78 if (!HIWORD(resId
)) continue;
79 if (strcasecmp( (char *)PTR_SEG_TO_LIN(resId
),
80 (char*)(p
+3)+strlen((char*)(p
+3))+1 )) continue;
83 else if (HIWORD(resId
) || ((resId
& ~0x8000) != p
[2]))
86 /* If we get here, we've found the entry */
88 dprintf_resource( stddeb
, " Found!\n" );
89 ret
= MAKELONG( p
[1], p
[2] );
92 FreeResource( handle
);
100 /***********************************************************************
101 * NE_FindResourceFromType
103 * Find a resource once the type info structure has been found.
105 static HRSRC
NE_FindResourceFromType( NE_MODULE
*pModule
,
106 NE_TYPEINFO
*pTypeInfo
, SEGPTR resId
)
110 NE_NAMEINFO
*pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
112 if (HIWORD(resId
) != 0) /* Named resource */
114 char *str
= (char *)PTR_SEG_TO_LIN( resId
);
115 BYTE len
= strlen( str
);
116 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
118 if (pNameInfo
->id
& 0x8000) continue;
119 p
= (BYTE
*)pModule
+ pModule
->res_table
+ pNameInfo
->id
;
120 if ((*p
== len
) && !strncasecmp( p
+1, str
, len
))
121 return (int)pNameInfo
- (int)pModule
;
124 else /* Numeric resource id */
126 WORD id
= LOWORD(resId
) | 0x8000;
127 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
128 if (pNameInfo
->id
== id
) return (int)pNameInfo
- (int)pModule
;
134 /***********************************************************************
137 HRSRC
NE_FindResource( HMODULE hModule
, SEGPTR typeId
, SEGPTR resId
)
140 NE_TYPEINFO
*pTypeInfo
;
143 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
144 if (!pModule
|| !pModule
->res_table
) return 0;
145 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
147 if (HIWORD(typeId
) || HIWORD(resId
))
149 /* Search the names in the nametable */
150 DWORD id
= NE_FindNameTableId( hModule
, typeId
, resId
);
158 if (HIWORD(typeId
) != 0) /* Named type */
160 char *str
= (char *)PTR_SEG_TO_LIN( typeId
);
161 BYTE len
= strlen( str
);
162 while (pTypeInfo
->type_id
)
164 if (!(pTypeInfo
->type_id
& 0x8000))
166 BYTE
*p
= (BYTE
*)pModule
+pModule
->res_table
+pTypeInfo
->type_id
;
167 if ((*p
== len
) && !strncasecmp( p
+1, str
, len
))
169 dprintf_resource( stddeb
, " Found type '%s'\n", str
);
170 hRsrc
= NE_FindResourceFromType(pModule
, pTypeInfo
, resId
);
173 dprintf_resource( stddeb
, " Found id %08lx\n", resId
);
176 dprintf_resource( stddeb
, " Not found, going on\n" );
179 dprintf_resource( stddeb
, " Skipping type %04x\n",
180 pTypeInfo
->type_id
);
181 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
182 pTypeInfo
->count
* sizeof(NE_NAMEINFO
));
185 else /* Numeric type id */
187 WORD id
= LOWORD(typeId
) | 0x8000;
188 while (pTypeInfo
->type_id
)
190 if (pTypeInfo
->type_id
== id
)
192 dprintf_resource( stddeb
, " Found type %04x\n", id
);
193 hRsrc
= NE_FindResourceFromType( pModule
, pTypeInfo
, resId
);
196 dprintf_resource( stddeb
, " Found id %08lx\n", resId
);
199 dprintf_resource( stddeb
, " Not found, going on\n" );
201 dprintf_resource( stddeb
, " Skipping type %04x\n",
202 pTypeInfo
->type_id
);
203 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
204 pTypeInfo
->count
* sizeof(NE_NAMEINFO
));
207 fprintf( stderr
, "FindResource('%*.*s',%08lx,%08lx): Not found.\n",
208 *((BYTE
*)pModule
+ pModule
->name_table
),
209 *((BYTE
*)pModule
+ pModule
->name_table
),
210 (char *)pModule
+ pModule
->name_table
+ 1, typeId
, resId
);
216 /***********************************************************************
219 HGLOBAL
NE_AllocResource( HMODULE hModule
, HRSRC hRsrc
, DWORD size
)
222 NE_NAMEINFO
*pNameInfo
;
225 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
226 if (!pModule
|| !pModule
->res_table
) return 0;
227 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
228 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
229 if (size
< (DWORD
)pNameInfo
->length
<< sizeShift
)
230 size
= (DWORD
)pNameInfo
->length
<< sizeShift
;
231 return GLOBAL_Alloc( GMEM_FIXED
, size
, hModule
, FALSE
, FALSE
, FALSE
);
235 /***********************************************************************
238 int NE_AccessResource( HMODULE hModule
, HRSRC hRsrc
)
241 NE_NAMEINFO
*pNameInfo
;
246 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
247 if (!pModule
|| !pModule
->res_table
) return 0;
248 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
250 name
= ((LOADEDFILEINFO
*)((char*)pModule
+ pModule
->fileinfo
))->filename
;
251 fd
= open( DOS_GetUnixFileName(name
), O_RDONLY
);
252 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
253 lseek( fd
, (int)pNameInfo
->offset
<< sizeShift
, SEEK_SET
);
258 /***********************************************************************
261 DWORD
NE_SizeofResource( HMODULE hModule
, HRSRC hRsrc
)
264 NE_NAMEINFO
*pNameInfo
;
267 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
268 if (!pModule
|| !pModule
->res_table
) return 0;
269 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
270 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
271 return (DWORD
)pNameInfo
->length
<< sizeShift
;
275 /***********************************************************************
278 HGLOBAL
NE_LoadResource( HMODULE hModule
, HRSRC hRsrc
)
281 NE_NAMEINFO
*pNameInfo
;
285 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
286 if (!pModule
|| !pModule
->res_table
) return 0;
287 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
288 if (pNameInfo
->handle
)
291 dprintf_resource( stddeb
, " Already loaded, new count=%d\n",
293 return pNameInfo
->handle
;
295 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
296 dprintf_resource( stddeb
, " Loading, pos=%d, len=%d\n",
297 (int)pNameInfo
->offset
<< sizeShift
,
298 (int)pNameInfo
->length
<< sizeShift
);
299 if ((fd
= MODULE_OpenFile( hModule
)) == -1) return 0;
300 pNameInfo
->handle
= NE_AllocResource( hModule
, hRsrc
, 0 );
301 pNameInfo
->usage
= 1;
302 lseek( fd
, (int)pNameInfo
->offset
<< sizeShift
, SEEK_SET
);
303 read( fd
, GlobalLock( pNameInfo
->handle
),
304 (int)pNameInfo
->length
<< sizeShift
);
305 return pNameInfo
->handle
;
309 /***********************************************************************
312 SEGPTR
NE_LockResource( HMODULE hModule
, HGLOBAL handle
)
314 /* May need to reload the resource if discarded */
316 return WIN16_GlobalLock( handle
);
320 /***********************************************************************
323 BOOL
NE_FreeResource( HMODULE hModule
, HGLOBAL handle
)
326 NE_TYPEINFO
*pTypeInfo
;
327 NE_NAMEINFO
*pNameInfo
;
330 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
331 if (!pModule
|| !pModule
->res_table
) return FALSE
;
332 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
333 while (pTypeInfo
->type_id
)
335 pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
336 for (count
= pTypeInfo
->count
; count
> 0; count
--)
338 if (pNameInfo
->handle
== handle
)
340 if (pNameInfo
->usage
> 0) pNameInfo
->usage
--;
341 if (pNameInfo
->usage
== 0)
343 GlobalFree( pNameInfo
->handle
);
344 pNameInfo
->handle
= 0;
350 pTypeInfo
= (NE_TYPEINFO
*)pNameInfo
;
352 fprintf( stderr
, "FreeResource: %04x %04x not found!\n", hModule
, handle
);