blob: e4d3e853c51ef34dfbdd56c041da8fb5e31dccc9 [file] [log] [blame]
Alexandre Julliard234bc241994-12-10 13:02:28 +00001/*
Alexandre Julliard594997c1995-04-30 10:05:20 +00002 * Resources
3 *
4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Alexandre Julliard594997c1995-04-30 10:05:20 +000020 */
21
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000022#include <assert.h>
Alexandre Julliard401710d1993-09-04 10:09:32 +000023#include <stdlib.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000024#include <string.h>
Alexandre Julliardf0b23541993-09-29 12:21:49 +000025#include <sys/types.h>
26#include <sys/stat.h>
27#include <fcntl.h>
28#include <unistd.h>
Ulrich Weigand05112821999-03-10 14:02:06 +000029#include "windef.h"
Alexandre Julliard58d5a0a2000-07-29 21:58:17 +000030#include "winbase.h"
Marcus Meissner04c3e1d1999-02-19 10:37:02 +000031#include "wine/winbase16.h"
Richard Cohenc775e1e2000-04-16 20:27:51 +000032#include "wine/exception.h"
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000033#include "heap.h"
Ulrich Weigand05112821999-03-10 14:02:06 +000034#include "cursoricon.h"
Alexandre Julliard594997c1995-04-30 10:05:20 +000035#include "module.h"
Ulrich Weigand80a69b61998-11-25 17:58:51 +000036#include "file.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000037#include "wine/debug.h"
Alexandre Julliard54c27111998-03-29 19:44:57 +000038#include "winerror.h"
Joshua Thielena49bb261999-07-04 12:55:10 +000039#include "winnls.h"
Peter Hunnisett73ab6492002-02-25 20:10:35 +000040#include "msvcrt/excpt.h"
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000041
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000042WINE_DEFAULT_DEBUG_CHANNEL(resource);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000043
Ulrich Weigand80a69b61998-11-25 17:58:51 +000044#define HRSRC_MAP_BLOCKSIZE 16
45
46typedef struct _HRSRC_ELEM
47{
Alexandre Julliarda3960291999-02-26 11:11:13 +000048 HANDLE hRsrc;
Ulrich Weigand80a69b61998-11-25 17:58:51 +000049 WORD type;
50} HRSRC_ELEM;
51
52typedef struct _HRSRC_MAP
53{
54 int nAlloc;
55 int nUsed;
56 HRSRC_ELEM *elem;
57} HRSRC_MAP;
58
59/**********************************************************************
60 * MapHRsrc32To16
61 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000062static HRSRC16 MapHRsrc32To16( NE_MODULE *pModule, HANDLE hRsrc32, WORD type )
Ulrich Weigand80a69b61998-11-25 17:58:51 +000063{
64 HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap;
65 HRSRC_ELEM *newElem;
66 int i;
67
68 /* On first call, initialize HRSRC map */
69 if ( !map )
70 {
Vincent Béron9a624912002-05-31 23:06:46 +000071 if ( !(map = (HRSRC_MAP *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
Ulrich Weigand80a69b61998-11-25 17:58:51 +000072 sizeof(HRSRC_MAP) ) ) )
73 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +000074 ERR("Cannot allocate HRSRC map\n" );
Ulrich Weigand80a69b61998-11-25 17:58:51 +000075 return 0;
76 }
77 pModule->hRsrcMap = (LPVOID)map;
78 }
79
80 /* Check whether HRSRC32 already in map */
81 for ( i = 0; i < map->nUsed; i++ )
82 if ( map->elem[i].hRsrc == hRsrc32 )
83 return (HRSRC16)(i + 1);
84
85 /* If no space left, grow table */
86 if ( map->nUsed == map->nAlloc )
87 {
Vincent Béron9a624912002-05-31 23:06:46 +000088 if ( !(newElem = (HRSRC_ELEM *)HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
89 map->elem,
90 (map->nAlloc + HRSRC_MAP_BLOCKSIZE)
Ulrich Weigand80a69b61998-11-25 17:58:51 +000091 * sizeof(HRSRC_ELEM) ) ))
92 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +000093 ERR("Cannot grow HRSRC map\n" );
Ulrich Weigand80a69b61998-11-25 17:58:51 +000094 return 0;
95 }
96 map->elem = newElem;
97 map->nAlloc += HRSRC_MAP_BLOCKSIZE;
98 }
99
100 /* Add HRSRC32 to table */
101 map->elem[map->nUsed].hRsrc = hRsrc32;
102 map->elem[map->nUsed].type = type;
103 map->nUsed++;
104
105 return (HRSRC16)map->nUsed;
106}
107
108/**********************************************************************
109 * MapHRsrc16To32
110 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000111static HANDLE MapHRsrc16To32( NE_MODULE *pModule, HRSRC16 hRsrc16 )
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000112{
113 HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap;
114 if ( !map || !hRsrc16 || (int)hRsrc16 > map->nUsed ) return 0;
115
116 return map->elem[(int)hRsrc16-1].hRsrc;
117}
118
119/**********************************************************************
120 * MapHRsrc16ToType
121 */
122static WORD MapHRsrc16ToType( NE_MODULE *pModule, HRSRC16 hRsrc16 )
123{
124 HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap;
125 if ( !map || !hRsrc16 || (int)hRsrc16 > map->nUsed ) return 0;
126
127 return map->elem[(int)hRsrc16-1].type;
128}
129
Ulrich Weigand05112821999-03-10 14:02:06 +0000130
Richard Cohenc775e1e2000-04-16 20:27:51 +0000131/* filter for page-fault exceptions */
132static WINE_EXCEPTION_FILTER(page_fault)
133{
134 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
135 return EXCEPTION_EXECUTE_HANDLER;
136 return EXCEPTION_CONTINUE_SEARCH;
137}
138
139static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type,
Vincent Béron9a624912002-05-31 23:06:46 +0000140 LPCSTR name, WORD lang,
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000141 BOOL bUnicode, BOOL bRet16 )
Richard Cohenc775e1e2000-04-16 20:27:51 +0000142{
143 HRSRC hRsrc = 0;
Vincent Béron9a624912002-05-31 23:06:46 +0000144
Alexandre Julliard32936f02000-08-07 23:50:00 +0000145 TRACE("(%08x, %08x%s, %08x%s, %04x, %s, %s)\n",
Richard Cohenc775e1e2000-04-16 20:27:51 +0000146 hModule,
Richard Cohenc775e1e2000-04-16 20:27:51 +0000147 (UINT)type, HIWORD(type)? (bUnicode? debugstr_w((LPWSTR)type) : debugstr_a(type)) : "",
148 (UINT)name, HIWORD(name)? (bUnicode? debugstr_w((LPWSTR)name) : debugstr_a(name)) : "",
149 lang,
150 bUnicode? "W" : "A",
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000151 bRet16? "NE" : "PE" );
Alexandre Julliard32936f02000-08-07 23:50:00 +0000152
153 if (!HIWORD(hModule))
Richard Cohenc775e1e2000-04-16 20:27:51 +0000154 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000155 HMODULE16 hMod16 = MapHModuleLS( hModule );
156 NE_MODULE *pModule = NE_GetPtr( hMod16 );
157 if (!pModule) return 0;
158 if (!pModule->module32)
159 {
Richard Cohenc775e1e2000-04-16 20:27:51 +0000160 /* 16-bit NE module */
161 LPSTR typeStr, nameStr;
Vincent Béron9a624912002-05-31 23:06:46 +0000162
Richard Cohenc775e1e2000-04-16 20:27:51 +0000163 if ( HIWORD( type ) && bUnicode )
164 typeStr = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)type );
165 else
166 typeStr = (LPSTR)type;
167 if ( HIWORD( name ) && bUnicode )
168 nameStr = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)name );
169 else
170 nameStr = (LPSTR)name;
Vincent Béron9a624912002-05-31 23:06:46 +0000171
Richard Cohenc775e1e2000-04-16 20:27:51 +0000172 hRsrc = NE_FindResource( pModule, nameStr, typeStr );
Vincent Béron9a624912002-05-31 23:06:46 +0000173
174 if ( HIWORD( type ) && bUnicode )
Richard Cohenc775e1e2000-04-16 20:27:51 +0000175 HeapFree( GetProcessHeap(), 0, typeStr );
Vincent Béron9a624912002-05-31 23:06:46 +0000176 if ( HIWORD( name ) && bUnicode )
Richard Cohenc775e1e2000-04-16 20:27:51 +0000177 HeapFree( GetProcessHeap(), 0, nameStr );
Vincent Béron9a624912002-05-31 23:06:46 +0000178
Richard Cohenc775e1e2000-04-16 20:27:51 +0000179 /* If we need to return 32-bit HRSRC, no conversion is necessary,
180 we simply use the 16-bit HRSRC as 32-bit HRSRC */
Alexandre Julliard32936f02000-08-07 23:50:00 +0000181 }
182 else
183 {
184 /* 32-bit PE module */
185 hRsrc = RES_FindResource2( pModule->module32, type, name, lang, bUnicode, FALSE );
186 /* If we need to return 16-bit HRSRC, perform conversion */
187 if ( bRet16 )
Vincent Béron9a624912002-05-31 23:06:46 +0000188 hRsrc = MapHRsrc32To16( pModule, hRsrc,
Alexandre Julliard32936f02000-08-07 23:50:00 +0000189 HIWORD( type )? 0 : LOWORD( type ) );
190 }
191 }
192 else
193 {
194 /* 32-bit PE module */
195 LPWSTR typeStr, nameStr;
Vincent Béron9a624912002-05-31 23:06:46 +0000196
Alexandre Julliard32936f02000-08-07 23:50:00 +0000197 if ( HIWORD( type ) && !bUnicode )
198 typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type );
199 else
200 typeStr = (LPWSTR)type;
201 if ( HIWORD( name ) && !bUnicode )
202 nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
203 else
204 nameStr = (LPWSTR)name;
205
Dmitry Timoshkov05c88fa2000-08-11 12:50:56 +0000206 /* Here is the real difference between FindResouce and FindResourceEx */
207 if(lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) ||
208 lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) ||
209 lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT) ||
210 lang == MAKELANGID(LANG_NEUTRAL, 3)) /* FIXME: real name? */
211 hRsrc = PE_FindResourceW( hModule, nameStr, typeStr );
212 else
213 hRsrc = PE_FindResourceExW( hModule, nameStr, typeStr, lang );
Vincent Béron9a624912002-05-31 23:06:46 +0000214
215 if ( HIWORD( type ) && !bUnicode )
Alexandre Julliard32936f02000-08-07 23:50:00 +0000216 HeapFree( GetProcessHeap(), 0, typeStr );
Vincent Béron9a624912002-05-31 23:06:46 +0000217 if ( HIWORD( name ) && !bUnicode )
Alexandre Julliard32936f02000-08-07 23:50:00 +0000218 HeapFree( GetProcessHeap(), 0, nameStr );
Richard Cohenc775e1e2000-04-16 20:27:51 +0000219 }
220 return hRsrc;
221}
222
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000223/**********************************************************************
Ulrich Weigand05112821999-03-10 14:02:06 +0000224 * RES_FindResource
225 */
Richard Cohenc775e1e2000-04-16 20:27:51 +0000226
Ulrich Weigand05112821999-03-10 14:02:06 +0000227static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type,
Vincent Béron9a624912002-05-31 23:06:46 +0000228 LPCSTR name, WORD lang,
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000229 BOOL bUnicode, BOOL bRet16 )
Ulrich Weigand05112821999-03-10 14:02:06 +0000230{
Richard Cohenc775e1e2000-04-16 20:27:51 +0000231 HRSRC hRsrc;
232 __TRY
Ulrich Weigand05112821999-03-10 14:02:06 +0000233 {
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000234 hRsrc = RES_FindResource2(hModule, type, name, lang, bUnicode, bRet16);
Ulrich Weigand05112821999-03-10 14:02:06 +0000235 }
Richard Cohenc775e1e2000-04-16 20:27:51 +0000236 __EXCEPT(page_fault)
Ulrich Weigand05112821999-03-10 14:02:06 +0000237 {
Richard Cohenc775e1e2000-04-16 20:27:51 +0000238 WARN("page fault\n");
239 SetLastError(ERROR_INVALID_PARAMETER);
240 return 0;
Ulrich Weigand05112821999-03-10 14:02:06 +0000241 }
Richard Cohenc775e1e2000-04-16 20:27:51 +0000242 __ENDTRY
Ulrich Weigand05112821999-03-10 14:02:06 +0000243 return hRsrc;
244}
245
246/**********************************************************************
247 * RES_SizeofResource
248 */
249static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 )
250{
Alexandre Julliard32936f02000-08-07 23:50:00 +0000251 if (!hRsrc) return 0;
Ulrich Weigand05112821999-03-10 14:02:06 +0000252
Alexandre Julliard32936f02000-08-07 23:50:00 +0000253 TRACE("(%08x, %08x, %s)\n", hModule, hRsrc, bRet16? "NE" : "PE" );
Ulrich Weigand05112821999-03-10 14:02:06 +0000254
Alexandre Julliard32936f02000-08-07 23:50:00 +0000255 if (!HIWORD(hModule))
Ulrich Weigand05112821999-03-10 14:02:06 +0000256 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000257 HMODULE16 hMod16 = MapHModuleLS( hModule );
258 NE_MODULE *pModule = NE_GetPtr( hMod16 );
259 if (!pModule) return 0;
260
261 if (!pModule->module32) /* 16-bit NE module */
262 {
263 /* If we got a 32-bit hRsrc, we don't need to convert it */
264 return NE_SizeofResource( pModule, hRsrc );
265 }
Ulrich Weigand05112821999-03-10 14:02:06 +0000266
267 /* If we got a 16-bit hRsrc, convert it */
Alexandre Julliard32936f02000-08-07 23:50:00 +0000268 if (!HIWORD(hRsrc)) hRsrc = MapHRsrc16To32( pModule, hRsrc );
Ulrich Weigand05112821999-03-10 14:02:06 +0000269 }
270
Alexandre Julliard32936f02000-08-07 23:50:00 +0000271 /* 32-bit PE module */
272 return PE_SizeofResource( hRsrc );
Ulrich Weigand05112821999-03-10 14:02:06 +0000273}
274
275/**********************************************************************
276 * RES_LoadResource
277 */
278static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 )
279{
280 HGLOBAL hMem = 0;
281
Alexandre Julliard32936f02000-08-07 23:50:00 +0000282 TRACE("(%08x, %08x, %s)\n", hModule, hRsrc, bRet16? "NE" : "PE" );
Ulrich Weigand05112821999-03-10 14:02:06 +0000283
Alexandre Julliard32936f02000-08-07 23:50:00 +0000284 if (!hRsrc) return 0;
Ulrich Weigand05112821999-03-10 14:02:06 +0000285
Alexandre Julliard32936f02000-08-07 23:50:00 +0000286 if (!HIWORD(hModule))
Ulrich Weigand05112821999-03-10 14:02:06 +0000287 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000288 HMODULE16 hMod16 = MapHModuleLS( hModule );
289 NE_MODULE *pModule = NE_GetPtr( hMod16 );
290 if (!pModule) return 0;
291 if (!pModule->module32)
Ulrich Weigand05112821999-03-10 14:02:06 +0000292 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000293 /* 16-bit NE module */
Ulrich Weigand05112821999-03-10 14:02:06 +0000294
Alexandre Julliard32936f02000-08-07 23:50:00 +0000295 /* If we got a 32-bit hRsrc, we don't need to convert it */
296 hMem = NE_LoadResource( pModule, hRsrc );
297
298 /* If we are to return a 32-bit resource, we should probably
299 convert it but we don't for now. FIXME !!! */
300 return hMem;
301 }
302 else
303 {
304 /* If we got a 16-bit hRsrc, convert it */
305 HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
306
307 hMem = PE_LoadResource( pModule->module32, hRsrc32 );
308
309 /* If we need to return a 16-bit resource, convert it */
310 if ( bRet16 )
311 {
312 WORD type = MapHRsrc16ToType( pModule, hRsrc );
313 DWORD size = SizeofResource( hModule, hRsrc );
314 LPVOID bits = LockResource( hMem );
315
316 hMem = NE_LoadPEResource( pModule, type, bits, size );
317 }
Ulrich Weigand05112821999-03-10 14:02:06 +0000318 }
319 }
320 else
321 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000322 /* 32-bit PE module */
323 hMem = PE_LoadResource( hModule, hRsrc );
Ulrich Weigand05112821999-03-10 14:02:06 +0000324 }
325
326 return hMem;
327}
328
329/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000330 * FindResource (KERNEL.60)
331 * FindResource16 (KERNEL32.@)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000332 */
Alexandre Julliardac7efef2000-11-27 21:54:01 +0000333HRSRC16 WINAPI FindResource16( HMODULE16 hModule, LPCSTR name, LPCSTR type )
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000334{
Alexandre Julliardac7efef2000-11-27 21:54:01 +0000335 return RES_FindResource( hModule, type, name,
Dmitry Timoshkov05c88fa2000-08-11 12:50:56 +0000336 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, TRUE );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000337}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000338
Alexandre Julliard594997c1995-04-30 10:05:20 +0000339/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000340 * FindResourceA (KERNEL32.@)
Alexandre Julliard594997c1995-04-30 10:05:20 +0000341 */
François Gouget55146db2000-12-24 20:33:01 +0000342HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000343{
Vincent Béron9a624912002-05-31 23:06:46 +0000344 return RES_FindResource( hModule, type, name,
Dmitry Timoshkov05c88fa2000-08-11 12:50:56 +0000345 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, FALSE );
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000346}
347
348/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000349 * FindResourceExA (KERNEL32.@)
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000350 */
Vincent Béron9a624912002-05-31 23:06:46 +0000351HRSRC WINAPI FindResourceExA( HMODULE hModule,
Ulrich Weigand05112821999-03-10 14:02:06 +0000352 LPCSTR type, LPCSTR name, WORD lang )
Ulrich Weigand7df1fbb1998-11-01 18:01:53 +0000353{
Vincent Béron9a624912002-05-31 23:06:46 +0000354 return RES_FindResource( hModule, type, name,
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000355 lang, FALSE, FALSE );
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000356}
357
Ulrich Weigand05112821999-03-10 14:02:06 +0000358/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000359 * FindResourceExW (KERNEL32.@)
Ulrich Weigand05112821999-03-10 14:02:06 +0000360 */
Vincent Béron9a624912002-05-31 23:06:46 +0000361HRSRC WINAPI FindResourceExW( HMODULE hModule,
Ulrich Weigand05112821999-03-10 14:02:06 +0000362 LPCWSTR type, LPCWSTR name, WORD lang )
363{
Vincent Béron9a624912002-05-31 23:06:46 +0000364 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000365 lang, TRUE, FALSE );
Ulrich Weigand05112821999-03-10 14:02:06 +0000366}
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000367
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000368/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000369 * FindResourceW (KERNEL32.@)
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000370 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000371HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000372{
Vincent Béron9a624912002-05-31 23:06:46 +0000373 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
Dmitry Timoshkov05c88fa2000-08-11 12:50:56 +0000374 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), TRUE, FALSE );
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000375}
376
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000377/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000378 * LoadResource (KERNEL.61)
379 * LoadResource16 (KERNEL32.@)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000380 */
381HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc )
382{
Ulrich Weigand05112821999-03-10 14:02:06 +0000383 return RES_LoadResource( hModule, hRsrc, TRUE );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000384}
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000385
386/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000387 * LoadResource (KERNEL32.@)
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000388 */
Ulrich Weigand05112821999-03-10 14:02:06 +0000389HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000390{
Ulrich Weigand05112821999-03-10 14:02:06 +0000391 return RES_LoadResource( hModule, hRsrc, FALSE );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000392}
393
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000394/**********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000395 * LockResource (KERNEL.62)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000396 */
397SEGPTR WINAPI WIN16_LockResource16( HGLOBAL16 handle )
398{
Alexandre Julliard32936f02000-08-07 23:50:00 +0000399 TRACE("(%04x)\n", handle );
400 /* May need to reload the resource if discarded */
Alexandre Julliard58017232000-12-22 01:09:26 +0000401 return K32WOWGlobalLock16( handle );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000402}
Patrik Stridvall697bf652000-12-02 23:44:59 +0000403
404/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000405 * LockResource16 (KERNEL32.@)
Patrik Stridvall697bf652000-12-02 23:44:59 +0000406 */
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000407LPVOID WINAPI LockResource16( HGLOBAL16 handle )
408{
Alexandre Julliard982a2232000-12-13 20:20:09 +0000409 return MapSL( WIN16_LockResource16(handle) );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000410}
Alexandre Julliard594997c1995-04-30 10:05:20 +0000411
Alexandre Julliardaca05781994-10-17 18:12:41 +0000412/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000413 * LockResource (KERNEL32.@)
Alexandre Julliardaca05781994-10-17 18:12:41 +0000414 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000415LPVOID WINAPI LockResource( HGLOBAL handle )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000416{
Alexandre Julliard32936f02000-08-07 23:50:00 +0000417 TRACE("(%08x)\n", handle );
418
419 if (HIWORD( handle )) /* 32-bit memory handle */
420 return (LPVOID)handle;
421
422 /* 16-bit memory handle */
423 return LockResource16( handle );
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000424}
425
Patrik Stridvall57e57842002-02-02 18:42:11 +0000426typedef WORD (WINAPI *pDestroyIcon32Proc)( HGLOBAL16 handle, UINT16 flags );
Alexandre Julliard8eeed942001-12-17 21:40:56 +0000427
428
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000429/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000430 * FreeResource (KERNEL.63)
431 * FreeResource16 (KERNEL32.@)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000432 */
433BOOL16 WINAPI FreeResource16( HGLOBAL16 handle )
434{
Alexandre Julliard32936f02000-08-07 23:50:00 +0000435 HGLOBAL retv = handle;
436 NE_MODULE *pModule = NE_GetPtr( FarGetOwner16( handle ) );
437
438 TRACE("(%04x)\n", handle );
439
440 /* Try NE resource first */
441 retv = NE_FreeResource( pModule, handle );
442
443 /* If this failed, call USER.DestroyIcon32; this will check
444 whether it is a shared cursor/icon; if not it will call
445 GlobalFree16() */
446 if ( retv )
447 {
Alexandre Julliard8eeed942001-12-17 21:40:56 +0000448 pDestroyIcon32Proc proc;
449 HMODULE user = GetModuleHandleA( "user32.dll" );
450
451 if (user && (proc = (pDestroyIcon32Proc)GetProcAddress( user, "DestroyIcon32" )))
452 retv = proc( handle, CID_RESOURCE );
Alexandre Julliard32936f02000-08-07 23:50:00 +0000453 else
454 retv = GlobalFree16( handle );
455 }
456 return (BOOL)retv;
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000457}
458
459/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000460 * FreeResource (KERNEL32.@)
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000461 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000462BOOL WINAPI FreeResource( HGLOBAL handle )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000463{
Alexandre Julliard32936f02000-08-07 23:50:00 +0000464 if (HIWORD(handle)) return 0; /* 32-bit memory handle: nothing to do */
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000465
Alexandre Julliard32936f02000-08-07 23:50:00 +0000466 return FreeResource16( handle );
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000467}
468
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000469/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000470 * SizeofResource (KERNEL.65)
471 * SizeofResource16 (KERNEL32.@)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000472 */
473DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc )
474{
Ulrich Weigand05112821999-03-10 14:02:06 +0000475 return RES_SizeofResource( hModule, hRsrc, TRUE );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000476}
477
478/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000479 * SizeofResource (KERNEL32.@)
Alexandre Julliard594997c1995-04-30 10:05:20 +0000480 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000481DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000482{
Ulrich Weigand05112821999-03-10 14:02:06 +0000483 return RES_SizeofResource( hModule, hRsrc, FALSE );
Alexandre Julliarda2f2e011995-06-06 16:40:35 +0000484}