00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "config.h"
00013
00014 #include <assert.h>
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020 #include <fcntl.h>
00021 #include <unistd.h>
00022
00023 #include "wine/winbase.h"
00024 #include "wine/windef.h"
00025 #include "wine/winuser.h"
00026 #include "wine/heap.h"
00027 #include "wine/module.h"
00028 #include "wine/debugtools.h"
00029 #include "wine/winerror.h"
00030 #include "loader.h"
00031
00032 #define CP_ACP 0
00033
00034 WORD WINE_LanguageId=0x409;
00035
00036 #define HRSRC_MAP_BLOCKSIZE 16
00037
00038 typedef struct _HRSRC_ELEM
00039 {
00040 HANDLE hRsrc;
00041 WORD type;
00042 } HRSRC_ELEM;
00043
00044 typedef struct _HRSRC_MAP
00045 {
00046 int nAlloc;
00047 int nUsed;
00048 HRSRC_ELEM *elem;
00049 } HRSRC_MAP;
00050
00051 static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type,
00052 LPCSTR name, WORD lang, int unicode)
00053 {
00054 HRSRC hRsrc = 0;
00055 LPWSTR typeStr, nameStr;
00056 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
00057
00058 if(!wm)
00059 return 0;
00060
00061
00062
00063 if ( HIWORD( type ) && (!unicode))
00064 typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type );
00065 else
00066 typeStr = (LPWSTR)type;
00067 if ( HIWORD( name ) && (!unicode))
00068 nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
00069 else
00070 nameStr = (LPWSTR)name;
00071
00072 hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang );
00073
00074 if ( HIWORD( type ) && (!unicode))
00075 HeapFree( GetProcessHeap(), 0, typeStr );
00076 if ( HIWORD( name ) && (!unicode))
00077 HeapFree( GetProcessHeap(), 0, nameStr );
00078
00079 return hRsrc;
00080 }
00081
00082
00083
00084
00085
00086 static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type,
00087 LPCSTR name, WORD lang, int unicode )
00088 {
00089 HRSRC hRsrc;
00090
00091
00092 hRsrc = RES_FindResource2(hModule, type, name, lang, unicode);
00093
00094
00095
00096
00097
00098
00099
00100
00101 return hRsrc;
00102 }
00103
00104
00105
00106
00107 static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc)
00108 {
00109 DWORD size = 0;
00110 HRSRC hRsrc32;
00111
00112
00113
00114
00115
00116 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
00117
00118 if ( !hModule || !hRsrc ) return 0;
00119
00120
00121
00122
00123 if(!HIWORD(hRsrc))
00124 {
00125 printf("16-bit hRsrcs not supported\n");
00126 return 0;
00127 }
00128 size = PE_SizeofResource( hModule, hRsrc );
00129 return size;
00130 }
00131
00132
00133
00134
00135 static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc )
00136 {
00137 HFILE hFile = HFILE_ERROR;
00138
00139 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
00140
00141 if ( !hModule || !hRsrc ) return HFILE_ERROR;
00142
00143
00144 FIXME("32-bit modules not yet supported.\n" );
00145 hFile = HFILE_ERROR;
00146
00147 return hFile;
00148 }
00149
00150
00151
00152
00153 static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc)
00154 {
00155 HGLOBAL hMem = 0;
00156 HRSRC hRsrc32;
00157 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
00158
00159
00160 if ( !hModule || !hRsrc ) return 0;
00161
00162
00163
00164
00165
00166 if(!HIWORD(hRsrc))
00167 {
00168 printf("16-bit hRsrcs not supported\n");
00169 return 0;
00170 }
00171 hMem = PE_LoadResource( wm, hRsrc );
00172
00173 return hMem;
00174 }
00175
00176
00177
00178
00179 static LPVOID RES_LockResource( HGLOBAL handle )
00180 {
00181 LPVOID bits = NULL;
00182
00183 TRACE("(%08x, %s)\n", handle, "PE" );
00184
00185 bits = (LPVOID)handle;
00186
00187 return bits;
00188 }
00189
00190
00191
00192
00193 static WIN_BOOL RES_FreeResource( HGLOBAL handle )
00194 {
00195 HGLOBAL retv = handle;
00196 return (WIN_BOOL)retv;
00197 }
00198
00199
00200
00201
00202 HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
00203 {
00204 return RES_FindResource( hModule, type, name,
00205 WINE_LanguageId, 0);
00206 }
00207 HANDLE WINAPI FindResourceW( HMODULE hModule, LPCWSTR name, LPCWSTR type )
00208 {
00209 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
00210 WINE_LanguageId, 1);
00211 }
00212
00213
00214
00215
00216 HANDLE WINAPI FindResourceExA( HMODULE hModule,
00217 LPCSTR type, LPCSTR name, WORD lang )
00218 {
00219 return RES_FindResource( hModule, type, name,
00220 lang, 0 );
00221 }
00222
00223 HANDLE WINAPI FindResourceExW( HMODULE hModule,
00224 LPCWSTR type, LPCWSTR name, WORD lang )
00225 {
00226 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
00227 lang, 1 );
00228 }
00229
00230
00231
00232
00233
00234
00235 LPVOID WINAPI LockResource( HGLOBAL handle )
00236 {
00237 return RES_LockResource( handle );
00238 }
00239
00240
00241
00242
00243
00244 WIN_BOOL WINAPI FreeResource( HGLOBAL handle )
00245 {
00246 return RES_FreeResource( handle );
00247 }
00248
00249
00250
00251
00252
00253 INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc )
00254 {
00255 return RES_AccessResource( hModule, hRsrc );
00256 }
00257
00258
00259
00260 DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
00261 {
00262 return RES_SizeofResource( hModule, hRsrc );
00263 }
00264
00265
00266 INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
00267 LPWSTR buffer, INT buflen );
00268
00269
00270
00271
00272 INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id,
00273 LPSTR buffer, INT buflen )
00274 {
00275 INT retval;
00276 INT wbuflen;
00277 INT abuflen;
00278 LPWSTR wbuf = NULL;
00279 LPSTR abuf = NULL;
00280
00281 if ( buffer != NULL && buflen > 0 )
00282 *buffer = 0;
00283
00284 wbuflen = LoadStringW(instance,resource_id,NULL,0);
00285 if ( !wbuflen )
00286 return 0;
00287 wbuflen ++;
00288
00289 retval = 0;
00290 wbuf = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, wbuflen * sizeof(WCHAR) );
00291 wbuflen = LoadStringW(instance,resource_id,wbuf,wbuflen);
00292 if ( wbuflen > 0 )
00293 {
00294 abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,NULL,0,NULL,NULL);
00295 if ( abuflen > 0 )
00296 {
00297 if ( buffer == NULL || buflen == 0 )
00298 retval = abuflen;
00299 else
00300 {
00301 abuf = (LPSTR) HeapAlloc( GetProcessHeap(), 0, abuflen * sizeof(CHAR) );
00302 abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,abuf,abuflen,NULL,NULL);
00303 if ( abuflen > 0 )
00304 {
00305 abuflen = min(abuflen,buflen - 1);
00306 memcpy( buffer, abuf, abuflen );
00307 buffer[abuflen] = 0;
00308 retval = abuflen;
00309 }
00310 HeapFree( GetProcessHeap(), 0, abuf );
00311 }
00312 }
00313 }
00314 HeapFree( GetProcessHeap(), 0, wbuf );
00315
00316 return retval;
00317 }
00318
00319
00320
00321
00322 INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
00323 LPWSTR buffer, INT buflen )
00324 {
00325 HGLOBAL hmem;
00326 HRSRC hrsrc;
00327 WCHAR *p;
00328 int string_num;
00329 int i;
00330
00331 if (HIWORD(resource_id)==0xFFFF)
00332 resource_id = (UINT)(-((INT)resource_id));
00333 TRACE("instance = %04x, id = %04x, buffer = %08x, "
00334 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
00335
00336
00337
00338 hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1),
00339 RT_STRINGW );
00340 if (!hrsrc) return 0;
00341 hmem = LoadResource( instance, hrsrc );
00342 if (!hmem) return 0;
00343
00344 p = (WCHAR*) LockResource(hmem);
00345 string_num = resource_id & 0x000f;
00346 for (i = 0; i < string_num; i++)
00347 p += *p + 1;
00348
00349 TRACE("strlen = %d\n", (int)*p );
00350
00351 if (buffer == NULL) return *p;
00352 i = min(buflen - 1, *p);
00353 if (i > 0) {
00354 memcpy(buffer, p + 1, i * sizeof (WCHAR));
00355 buffer[i] = (WCHAR) 0;
00356 } else {
00357 if (buflen > 1) {
00358 buffer[0] = (WCHAR) 0;
00359 return 0;
00360 }
00361 #if 0
00362 WARN("Don't know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
00363 #endif
00364 }
00365
00366 TRACE("String loaded !\n");
00367 return i;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 INT WINAPI LoadMessageA( HMODULE instance, UINT id, WORD lang,
00396 LPSTR buffer, INT buflen )
00397 {
00398 HGLOBAL hmem;
00399 HRSRC hrsrc;
00400 PMESSAGE_RESOURCE_DATA mrd;
00401 PMESSAGE_RESOURCE_BLOCK mrb;
00402 PMESSAGE_RESOURCE_ENTRY mre;
00403 int i,slen;
00404
00405 TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
00406
00407
00408 hrsrc = FindResourceExW(instance,RT_MESSAGELISTW,(LPWSTR)1,lang);
00409 if (!hrsrc) return 0;
00410 hmem = LoadResource( instance, hrsrc );
00411 if (!hmem) return 0;
00412
00413 mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem);
00414 mre = NULL;
00415 mrb = &(mrd->Blocks[0]);
00416 for (i=mrd->NumberOfBlocks;i--;) {
00417 if ((id>=mrb->LowId) && (id<=mrb->HighId)) {
00418 mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries);
00419 id -= mrb->LowId;
00420 break;
00421 }
00422 mrb++;
00423 }
00424 if (!mre)
00425 return 0;
00426 for (i=id;i--;) {
00427 if (!mre->Length)
00428 return 0;
00429 mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+(mre->Length));
00430 }
00431 slen=mre->Length;
00432 TRACE(" - strlen=%d\n",slen);
00433 i = min(buflen - 1, slen);
00434 if (buffer == NULL)
00435 return slen;
00436 if (i>0) {
00437 lstrcpynA(buffer,(char*)mre->Text,i);
00438 buffer[i]=0;
00439 } else {
00440 if (buflen>1) {
00441 buffer[0]=0;
00442 return 0;
00443 }
00444 }
00445 if (buffer)
00446 TRACE("'%s' copied !\n", buffer);
00447 return i;
00448 }
00449
00450
00451
00452
00453
00454
00455 WIN_BOOL WINAPI EnumResourceTypesA( HMODULE hmodule,ENUMRESTYPEPROCA lpfun,
00456 LONG lParam)
00457 {
00458
00459 return PE_EnumResourceTypesA(hmodule,lpfun,lParam);
00460 }
00461
00462
00463
00464
00465 WIN_BOOL WINAPI EnumResourceNamesA( HMODULE hmodule, LPCSTR type,
00466 ENUMRESNAMEPROCA lpfun, LONG lParam )
00467 {
00468
00469 return PE_EnumResourceNamesA(hmodule,type,lpfun,lParam);
00470 }
00471
00472
00473
00474 WIN_BOOL WINAPI EnumResourceLanguagesA( HMODULE hmodule, LPCSTR type,
00475 LPCSTR name, ENUMRESLANGPROCA lpfun,
00476 LONG lParam)
00477 {
00478
00479 return PE_EnumResourceLanguagesA(hmodule,type,name,lpfun,lParam);
00480 }
00481
00482
00483
00484 HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc )
00485 {
00486 return RES_LoadResource( hModule, hRsrc);
00487 }