Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

resource.c

00001 /*
00002  * Resources
00003  *
00004  * Copyright 1993 Robert J. Amstadt
00005  * Copyright 1995 Alexandre Julliard
00006  *
00007  * Modified for use with MPlayer, detailed CVS changelog at
00008  * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
00009  * $Id: resource.c 11593 2005-06-28 18:02:01Z courmisch $
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;//english
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     /* 32-bit PE module */
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  *          RES_FindResource
00084  */
00085 
00086 static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type,
00087                                LPCSTR name, WORD lang, int unicode )
00088 {
00089     HRSRC hRsrc;
00090 //    __TRY
00091 //    {
00092         hRsrc = RES_FindResource2(hModule, type, name, lang, unicode);
00093 //    }
00094 //    __EXCEPT(page_fault)
00095 //    {
00096 //      WARN("page fault\n");
00097 //      SetLastError(ERROR_INVALID_PARAMETER);
00098 //      return 0;
00099 //    }
00100 //    __ENDTRY
00101     return hRsrc;
00102 }
00103 
00104 /**********************************************************************
00105  *          RES_SizeofResource
00106  */
00107 static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc)
00108 {
00109     DWORD size = 0;
00110     HRSRC hRsrc32;
00111 
00112 //    HMODULE16 hMod16   = MapHModuleLS( hModule );
00113 //    NE_MODULE *pModule = NE_GetPtr( hMod16 );
00114 //    WINE_MODREF *wm    = pModule && pModule->module32? 
00115 //                         MODULE32_LookupHMODULE( pModule->module32 ) : NULL;
00116     WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
00117 
00118     if ( !hModule || !hRsrc ) return 0;
00119 
00120     /* 32-bit PE module */
00121     /* If we got a 16-bit hRsrc, convert it */
00122 //    hRsrc32  = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
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  *          RES_AccessResource
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     /* 32-bit PE module */
00144     FIXME("32-bit modules not yet supported.\n" );
00145     hFile = HFILE_ERROR;
00146 
00147     return hFile;
00148 }
00149 
00150 /**********************************************************************
00151  *          RES_LoadResource
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     /* 32-bit PE module */
00163 
00164     /* If we got a 16-bit hRsrc, convert it */
00165 //    hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
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  *          RES_LockResource
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  *          RES_FreeResource
00192  */
00193 static WIN_BOOL RES_FreeResource( HGLOBAL handle )
00194 {
00195     HGLOBAL retv = handle;
00196     return (WIN_BOOL)retv;
00197 }
00198 
00199 /**********************************************************************
00200  *          FindResourceA    (KERNEL32.128)
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  *          FindResourceExA  (KERNEL32.129)
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  *          LockResource     (KERNEL32.384)
00234  */
00235 LPVOID WINAPI LockResource( HGLOBAL handle )
00236 {
00237     return RES_LockResource( handle );
00238 }
00239 
00240 
00241 /**********************************************************************
00242  *          FreeResource     (KERNEL32.145)
00243  */
00244 WIN_BOOL WINAPI FreeResource( HGLOBAL handle )
00245 {
00246     return RES_FreeResource( handle );
00247 }
00248 
00249 
00250 /**********************************************************************
00251  *          AccessResource   (KERNEL32.64)
00252  */
00253 INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc )
00254 {
00255     return RES_AccessResource( hModule, hRsrc );
00256 }
00257 /**********************************************************************
00258  *          SizeofResource   (KERNEL32.522)
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  *      LoadStringA     (USER32.375)
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  *      LoadStringW             (USER32.376)
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) /* netscape 3 passes this */
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     /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out 
00337      * 20 - 31. */
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 /* Messages...used by FormatMessage32* (KERNEL32.something)
00371  * 
00372  * They can be specified either directly or using a message ID and
00373  * loading them from the resource.
00374  * 
00375  * The resourcedata has following format:
00376  * start:
00377  * 0: DWORD nrofentries
00378  * nrofentries * subentry:
00379  *      0: DWORD firstentry
00380  *      4: DWORD lastentry
00381  *      8: DWORD offset from start to the stringentries
00382  *
00383  * (lastentry-firstentry) * stringentry:
00384  * 0: WORD len (0 marks end)
00385  * 2: WORD flags
00386  * 4: CHAR[len-4]
00387  *      (stringentry i of a subentry refers to the ID 'firstentry+i')
00388  *
00389  * Yes, ANSI strings in win32 resources. Go figure.
00390  */
00391 
00392 /**********************************************************************
00393  *      LoadMessageA            (internal)
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     /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
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  *      EnumResourceTypesA      (KERNEL32.90)
00454  */
00455 WIN_BOOL WINAPI EnumResourceTypesA( HMODULE hmodule,ENUMRESTYPEPROCA lpfun,
00456                                     LONG lParam)
00457 {
00458         /* FIXME: move WINE_MODREF stuff here */
00459     return PE_EnumResourceTypesA(hmodule,lpfun,lParam);
00460 }
00461 
00462 /**********************************************************************
00463  *      EnumResourceNamesA      (KERNEL32.88)
00464  */
00465 WIN_BOOL WINAPI EnumResourceNamesA( HMODULE hmodule, LPCSTR type,
00466                                     ENUMRESNAMEPROCA lpfun, LONG lParam )
00467 {
00468         /* FIXME: move WINE_MODREF stuff here */
00469     return PE_EnumResourceNamesA(hmodule,type,lpfun,lParam);
00470 }
00471 /**********************************************************************
00472  *      EnumResourceLanguagesA  (KERNEL32.86)
00473  */
00474 WIN_BOOL WINAPI EnumResourceLanguagesA( HMODULE hmodule, LPCSTR type,
00475                                         LPCSTR name, ENUMRESLANGPROCA lpfun,
00476                                         LONG lParam)
00477 {
00478         /* FIXME: move WINE_MODREF stuff here */
00479     return PE_EnumResourceLanguagesA(hmodule,type,name,lpfun,lParam);
00480 }
00481 /**********************************************************************
00482  *          LoadResource     (KERNEL32.370)
00483  */
00484 HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc )
00485 {
00486     return RES_LoadResource( hModule, hRsrc);
00487 }

Generated on Tue Dec 20 10:14:21 2005 for vlc-0.8.4a by  doxygen 1.4.2