4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
11 #include <sys/types.h>
27 /***********************************************************************
30 * Find the type and resource id from their names.
31 * Return value is MAKELONG( typeId, resId ), or 0 if not found.
33 static DWORD
NE_FindNameTableId( HMODULE hModule
, SEGPTR typeId
, SEGPTR resId
)
36 NE_TYPEINFO
*pTypeInfo
;
37 NE_NAMEINFO
*pNameInfo
;
43 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
44 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
45 for (; pTypeInfo
->type_id
!= 0;
46 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
47 pTypeInfo
->count
* sizeof(NE_NAMEINFO
)))
49 if (pTypeInfo
->type_id
!= 0x800f) continue;
50 pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
51 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
53 dprintf_resource( stddeb
, "NameTable entry: type=%04x id=%04x\n",
54 pTypeInfo
->type_id
, pNameInfo
->id
);
55 handle
= LoadResource( hModule
,
56 (HANDLE
)((int)pNameInfo
- (int)pModule
) );
57 for(p
= (WORD
*)LockResource(handle
); p
&& *p
; p
= (WORD
*)((char*)p
+*p
))
59 dprintf_resource( stddeb
," type=%04x '%s' id=%04x '%s'\n",
60 p
[1], (char *)(p
+3), p
[2],
61 (char *)(p
+3)+strlen((char *)(p
+3))+1 );
62 /* Check for correct type */
66 if (!HIWORD(typeId
)) continue;
67 if (lstrcmpi32A( (char *)PTR_SEG_TO_LIN(typeId
),
68 (char *)(p
+ 3) )) continue;
70 else if (HIWORD(typeId
) || ((typeId
& ~0x8000)!= p
[1]))
73 /* Now check for the id */
77 if (!HIWORD(resId
)) continue;
78 if (lstrcmpi32A( (char *)PTR_SEG_TO_LIN(resId
),
79 (char*)(p
+3)+strlen((char*)(p
+3))+1 )) continue;
82 else if (HIWORD(resId
) || ((resId
& ~0x8000) != p
[2]))
85 /* If we get here, we've found the entry */
87 dprintf_resource( stddeb
, " Found!\n" );
88 ret
= MAKELONG( p
[1], p
[2] );
91 FreeResource( handle
);
99 /***********************************************************************
100 * NE_FindResourceFromType
102 * Find a resource once the type info structure has been found.
104 static HRSRC
NE_FindResourceFromType( NE_MODULE
*pModule
,
105 NE_TYPEINFO
*pTypeInfo
, SEGPTR resId
)
109 NE_NAMEINFO
*pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
111 if (HIWORD(resId
) != 0) /* Named resource */
113 char *str
= (char *)PTR_SEG_TO_LIN( resId
);
114 BYTE len
= strlen( str
);
115 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
117 if (pNameInfo
->id
& 0x8000) continue;
118 p
= (BYTE
*)pModule
+ pModule
->res_table
+ pNameInfo
->id
;
119 if ((*p
== len
) && !lstrncmpi32A( p
+1, str
, len
))
120 return (HRSRC
)((int)pNameInfo
- (int)pModule
);
123 else /* Numeric resource id */
125 WORD id
= LOWORD(resId
) | 0x8000;
126 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
127 if (pNameInfo
->id
== id
)
128 return (HRSRC
)((int)pNameInfo
- (int)pModule
);
134 /***********************************************************************
137 HRSRC
NE_FindResource( HMODULE hModule
, SEGPTR typeId
, SEGPTR resId
)
139 NE_TYPEINFO
*pTypeInfo
;
142 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
143 if (!pModule
|| !pModule
->res_table
) return 0;
144 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
146 if (HIWORD(typeId
) || HIWORD(resId
))
148 /* Search the names in the nametable */
149 DWORD id
= NE_FindNameTableId( hModule
, typeId
, resId
);
157 if (HIWORD(typeId
) != 0) /* Named type */
159 char *str
= (char *)PTR_SEG_TO_LIN( typeId
);
160 BYTE len
= strlen( str
);
161 while (pTypeInfo
->type_id
)
163 if (!(pTypeInfo
->type_id
& 0x8000))
165 BYTE
*p
= (BYTE
*)pModule
+pModule
->res_table
+pTypeInfo
->type_id
;
166 if ((*p
== len
) && !lstrncmpi32A( p
+1, str
, len
))
168 dprintf_resource( stddeb
, " Found type '%s'\n", str
);
169 hRsrc
= NE_FindResourceFromType(pModule
, pTypeInfo
, resId
);
172 dprintf_resource( stddeb
, " Found id %08lx\n", resId
);
175 dprintf_resource( stddeb
, " Not found, going on\n" );
178 dprintf_resource( stddeb
, " Skipping type %04x\n",
179 pTypeInfo
->type_id
);
180 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
181 pTypeInfo
->count
* sizeof(NE_NAMEINFO
));
184 else /* Numeric type id */
186 WORD id
= LOWORD(typeId
) | 0x8000;
187 while (pTypeInfo
->type_id
)
189 if (pTypeInfo
->type_id
== id
)
191 dprintf_resource( stddeb
, " Found type %04x\n", id
);
192 hRsrc
= NE_FindResourceFromType( pModule
, pTypeInfo
, resId
);
195 dprintf_resource( stddeb
, " Found id %08lx\n", resId
);
198 dprintf_resource( stddeb
, " Not found, going on\n" );
200 dprintf_resource( stddeb
, " Skipping type %04x\n",
201 pTypeInfo
->type_id
);
202 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
203 pTypeInfo
->count
* sizeof(NE_NAMEINFO
));
211 /***********************************************************************
214 HGLOBAL
NE_AllocResource( HMODULE hModule
, HRSRC hRsrc
, DWORD size
)
216 NE_NAMEINFO
*pNameInfo
=NULL
;
219 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
220 if (!pModule
|| !pModule
->res_table
) return 0;
221 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
223 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
225 if (size
< (DWORD
)pNameInfo
->length
<< sizeShift
)
226 size
= (DWORD
)pNameInfo
->length
<< sizeShift
;
227 return GLOBAL_Alloc( GMEM_FIXED
, size
, hModule
, FALSE
, FALSE
, FALSE
);
231 /***********************************************************************
234 int NE_AccessResource( HMODULE hModule
, HRSRC hRsrc
)
236 NE_NAMEINFO
*pNameInfo
=NULL
;
239 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
240 if (!pModule
|| !pModule
->res_table
) return -1;
242 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
245 if ((fd
= _lopen( NE_MODULE_NAME(pModule
), OF_READ
)) != -1)
247 WORD sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
248 _llseek( fd
, (int)pNameInfo
->offset
<< sizeShift
, SEEK_SET
);
254 /***********************************************************************
257 DWORD
NE_SizeofResource( HMODULE hModule
, HRSRC hRsrc
)
259 NE_NAMEINFO
*pNameInfo
=NULL
;
262 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
263 if (!pModule
|| !pModule
->res_table
) return 0;
264 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
266 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
268 return (DWORD
)pNameInfo
->length
<< sizeShift
;
272 /***********************************************************************
275 HGLOBAL
NE_LoadResource( HMODULE hModule
, HRSRC hRsrc
)
277 NE_NAMEINFO
*pNameInfo
=NULL
;
281 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
282 if (!pModule
|| !pModule
->res_table
) return 0;
284 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
286 if (pNameInfo
->handle
)
289 dprintf_resource( stddeb
, " Already loaded, new count=%d\n",
291 return pNameInfo
->handle
;
293 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
294 dprintf_resource( stddeb
, " Loading, pos=%d, len=%d\n",
295 (int)pNameInfo
->offset
<< sizeShift
,
296 (int)pNameInfo
->length
<< sizeShift
);
297 if ((fd
= MODULE_OpenFile( hModule
)) == -1) return 0;
298 pNameInfo
->handle
= NE_AllocResource( hModule
, hRsrc
, 0 );
299 pNameInfo
->usage
= 1;
300 lseek( fd
, (int)pNameInfo
->offset
<< sizeShift
, SEEK_SET
);
301 read( fd
, GlobalLock16( pNameInfo
->handle
),
302 (int)pNameInfo
->length
<< sizeShift
);
303 return pNameInfo
->handle
;
307 /***********************************************************************
310 SEGPTR
NE_LockResource( HMODULE hModule
, HGLOBAL handle
)
312 /* May need to reload the resource if discarded */
314 return (SEGPTR
)WIN16_GlobalLock16( handle
);
318 /***********************************************************************
321 BOOL
NE_FreeResource( HMODULE hModule
, HGLOBAL handle
)
323 NE_TYPEINFO
*pTypeInfo
;
324 NE_NAMEINFO
*pNameInfo
;
327 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
328 if (!pModule
|| !pModule
->res_table
) return handle
;
329 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
330 while (pTypeInfo
->type_id
)
332 pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
333 for (count
= pTypeInfo
->count
; count
> 0; count
--)
335 if (pNameInfo
->handle
== handle
)
337 if (pNameInfo
->usage
> 0) pNameInfo
->usage
--;
338 if (pNameInfo
->usage
== 0)
340 GlobalFree16( pNameInfo
->handle
);
341 pNameInfo
->handle
= 0;
347 pTypeInfo
= (NE_TYPEINFO
*)pNameInfo
;
349 fprintf( stderr
, "FreeResource: %04x %04x not found!\n", hModule
, handle
);