Ignore:
Timestamp:
Aug 19, 1999, 12:25:27 PM (26 years ago)
Author:
sandervl
Message:

PE loader resource fixes + ConvertNameId bugfix

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/winimgres.cpp

    r532 r571  
    1 /* $Id: winimgres.cpp,v 1.7 1999-08-17 17:04:52 sandervl Exp $ */
     1/* $Id: winimgres.cpp,v 1.8 1999-08-19 10:25:27 sandervl Exp $ */
    22
    33/*
     
    3131
    3232//******************************************************************************
    33 //TODO: use OS/2 unicode stuff
    34 //******************************************************************************
    35 char *extremelyuglyUnicodeToAscii(int length, WCHAR *NameString)
    36 {
    37 static char asciistring[256];
    38 int i;
    39 
    40   if(length >= 255) length = 255;
    41   for(i=0;i<length;i++) {
    42     asciistring[i] = NameString[i] & 0xFF;
    43   }
    44   asciistring[length] = 0;
    45   return(asciistring);
    46 }
    47 //******************************************************************************
    48 //******************************************************************************
    49 
    50 //******************************************************************************
    5133//Assuming names are case insensitive
    5234//PE spec says names & ids are sorted; keep on searching just to be sure
     
    5941 Win32Resource                  *res;
    6042 ULONG  nodeData[3];
    61  ULONG  nrres;
    62  BOOL  fFound = FALSE, fNumId;
     43 BOOL  fFound = FALSE, fNumType;
    6344 char  *winres = NULL;
    6445 int    i, stringid = -1, j;
     
    7556  nodeData[2] = 0xFFFFFFFF;
    7657
    77   nrres = pResDir->NumberOfIdEntries + pResDir->NumberOfNamedEntries;
    78   fNumId = TRUE;    //assume numeric
    79   if(((ULONG)type >> 16) != 0) {//string id?
     58  fNumType = TRUE;    //assume numeric
     59  if(HIWORD(type) != 0) {//string id?
    8060    for(i=0;i<MAX_RES;i++) {
    81         if(stricmp((char *)type, ResTypes[i]) == 0)
    82             break;
     61         if(stricmp((char *)type, ResTypes[i]) == 0)
     62                break;
    8363    }
    8464    if(i == MAX_RES) {//custom resource type
    85         nrres  = pResDir->NumberOfNamedEntries;
    86         fNumId = FALSE;
    87     }
    88     else    type   = i;
     65         fNumType = FALSE;
     66    }
     67    else type   = i;
    8968  }
    9069
     
    9271  //upper 12 bits of resource id passed by user determines block (res id)
    9372  //lower 4 bits are an index into the string table
    94   if(fNumId) {
     73  if(fNumType) {
    9574    if(type == NTRT_STRING) {
    9675        stringid = id & 0xF;
     
    10584  }
    10685
    107   for(i=0;i<nrres;i++) {
     86  for (i=0; i<pResDir->NumberOfNamedEntries+pResDir->NumberOfIdEntries; i++) {
    10887    /* locate directory or each resource type */
    109     prdType = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)pResDir + (ULONG)prde->u2.OffsetToData);
    110 
    111     if(i < prdType->NumberOfNamedEntries) {//name or id entry?
     88    prdType = (PIMAGE_RESOURCE_DIRECTORY)((int)pResDir + (int)prde->u2.OffsetToData);
     89
     90    if(i < pResDir->NumberOfNamedEntries)
     91    {//name or id entry?
    11292        //SvL: 30-10-'97, high bit is set, so clear to get real offset
    11393        prde->u1.Name &= ~0x80000000;
    114         char *resname = extremelyuglyUnicodeToAscii(*(WCHAR *)((ULONG)pResDir + (ULONG)prde->u1.Name), (WCHAR *)((ULONG)pResDir + (ULONG)prde->u1.Name + sizeof(WCHAR)));  // first word = string length
    115         if(!fNumId) {
    116             if(stricmp(resname, (char *)type) == 0) {
     94        char *typename = UnicodeToAsciiStringN((WCHAR *)((ULONG)pResDir + (ULONG)prde->u1.Name + sizeof(WCHAR)), *(WCHAR *)((ULONG)pResDir + (ULONG)prde->u1.Name));  // first word = string length
     95
     96        if(!fNumType) {
     97            if(stricmp(typename, (char *)type) == 0) {
    11798                fFound = TRUE;
    11899            }
     
    120101        else {
    121102            for(j=0;j<MAX_RES;j++) {
    122                 if(stricmp((char *)type, ResTypes[j]) == 0)
     103                if(stricmp(typename, ResTypes[j]) == 0)
    123104                    break;
    124105            }
     
    127108            }
    128109        }
     110        FreeAsciiString(typename);
    129111    }
    130112    else {
     
    135117    if(fFound) {
    136118        if((ULONG)prdType & 0x80000000) {//subdirectory?
    137             pData = ProcessResSubDir(prdType, &nodeData[0]);
     119            pData = ProcessResSubDir(prdType, &nodeData[0], 2);
    138120        }
    139121        else {
     
    169151}
    170152//******************************************************************************
     153//level: 2 ids
     154//       3 languages
    171155//******************************************************************************
    172156PIMAGE_RESOURCE_DATA_ENTRY
    173157    Win32Image::ProcessResSubDir(PIMAGE_RESOURCE_DIRECTORY prdType,
    174                      ULONG *nodeData)
     158                                 ULONG *nodeData, int level)
    175159{
    176160 PIMAGE_RESOURCE_DIRECTORY       prdType2;
     
    184168
    185169  if(*nodeData == 0xFFFFFFFF) {//shouldn't happen!
    186     dprintf(("ProcessResSubDir: *nodeData == 0xFFFFFFFF!\n"));
    187     return(NULL);
     170        dprintf(("ProcessResSubDir: *nodeData == 0xFFFFFFFF!\n"));
     171        return(NULL);
    188172  }
    189173  prdType = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)prdType & ~0x80000000);
    190174  prde    = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)prdType + sizeof(IMAGE_RESOURCE_DIRECTORY));
    191175
    192   fNumId  = (*nodeData >> 16) == 0;
    193 
    194   if(fNumId) {//numeric or string id?
    195     nrres = pResDir->NumberOfIdEntries;
    196     prde += pResDir->NumberOfNamedEntries;  //skip name entries
    197   }
    198   else  nrres = pResDir->NumberOfNamedEntries;
     176  if(level == 3 && *nodeData == LANG_GETFIRST) {
     177        nrres  = prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;
     178        fNumId = (prdType->NumberOfNamedEntries != 0);
     179  }
     180  else {
     181        fNumId = HIWORD(*nodeData) == 0;
     182
     183        if(fNumId) {//numeric or string id?
     184                nrres = prdType->NumberOfIdEntries;
     185                prde += prdType->NumberOfNamedEntries;  //skip name entries
     186        }
     187        else    nrres = prdType->NumberOfNamedEntries;
     188  }
    199189
    200190  for(i=0;i<nrres;i++) {
    201     /* locate directory or each resource type */
    202     prdType2 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)pResDir + (ULONG)prde->u2.OffsetToData);
    203 
    204     if(!fNumId) {//name or id entry?
    205         if(prde->u1.s.NameIsString) //unicode directory string /*PLF Sat  97-06-21 22:30:35*/
    206                prde->u1.Name &= ~0x80000000;
    207            pstring = (PIMAGE_RESOURCE_DIR_STRING_U)((ULONG)pResDir + (ULONG)prde->u1.Name);
    208          resname = extremelyuglyUnicodeToAscii(pstring->Length, pstring->NameString);
    209          if(stricmp(resname, (char *)*nodeData) == 0) {
    210                   fFound = TRUE;
    211          }
    212       }
    213       else {
    214          if(*nodeData == prde->u1.Id)
    215                   fFound = TRUE;
    216       }
    217       if(*nodeData == LANG_GETFIRST)
    218          fFound = TRUE;
    219 
    220    if(fFound) {
    221          if((ULONG)prdType2 & 0x80000000) {//subdirectory?
    222                ProcessResSubDir(prdType2, nodeData+1);
    223            }
    224            else {
    225              pData = (PIMAGE_RESOURCE_DATA_ENTRY)prdType2;
    226                if(pData->Size) {//winamp17 winzip archive has resource with size 0
    227                  return(pData);
    228                }
    229              else    return(NULL);
    230          }
    231       }
    232       prde++;
     191        /* locate directory or each resource type */
     192        prdType2 = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)pResDir + (ULONG)prde->u2.OffsetToData);
     193
     194        if(!fNumId) {//name or id entry?
     195                if(prde->u1.s.NameIsString) //unicode directory string /*PLF Sat  97-06-21 22:30:35*/
     196                        prde->u1.Name &= ~0x80000000;
     197
     198                pstring = (PIMAGE_RESOURCE_DIR_STRING_U)((ULONG)pResDir + (ULONG)prde->u1.Name);
     199                resname = UnicodeToAsciiStringN(pstring->NameString, pstring->Length);
     200                if(stricmp(resname, (char *)*nodeData) == 0) {
     201                        fFound = TRUE;
     202                }
     203                FreeAsciiString(resname);
     204        }
     205        else {
     206                if(*nodeData == prde->u1.Id)
     207                        fFound = TRUE;
     208        }
     209        if(*nodeData == LANG_GETFIRST)
     210                fFound = TRUE;
     211
     212        if(fFound) {
     213                if((ULONG)prdType2 & 0x80000000) {//subdirectory?
     214                        ProcessResSubDir(prdType2, nodeData+1, 3);
     215                }
     216                else {
     217                        pData = (PIMAGE_RESOURCE_DATA_ENTRY)prdType2;
     218                        if(pData->Size) {//winamp17 winzip archive has resource with size 0
     219                                return(pData);
     220                        }
     221                        else    return(NULL);
     222                }
     223        }
     224        prde++;
    233225  }
    234226  return(NULL);
     
    289281    if((int)lpszName >> 16 != 0) {//convert string name identifier to numeric id
    290282        dprintf(("FindResource %s\n", lpszName));
    291       if(lpszName[0] == '#') {// #344
    292             lpszName = (LPCSTR)atoi(&lpszName[1]);
    293       }
    294       else  lpszName = (LPCSTR)ConvertNameId(hinstance, (char *)lpszName);
     283        if(lpszName[0] == '#') {// #344
     284                lpszName = (LPCSTR)atoi(&lpszName[1]);
     285        }
     286        else    lpszName = (LPCSTR)ConvertNameId(hinstance, (char *)lpszName);
    295287    }
    296288    else dprintf(("FindResource %d\n", (int)lpszName));
     
    299291    if(hres)
    300292    {
    301       res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
     293        res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
    302294    }
    303295
    304296    if(hres == NULL && (int)lpszName >> 16 == 0 && (int)szType == NTRT_STRING) {
    305       hres = O32_FindResource(hinstance, (LPCSTR)(((int)lpszName - 1)*16), (LPCSTR)NTRT_RCDATA);
    306       if(hres)
    307       {
    308          res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
    309       }
    310       else    dprintf(("FindResourceA can't find string %d\n", (int)lpszName));
     297        hres = O32_FindResource(hinstance, (LPCSTR)(((int)lpszName - 1)*16), (LPCSTR)NTRT_RCDATA);
     298        if(hres)
     299        {
     300                res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
     301        }
     302        else    dprintf(("FindResourceA can't find string %d\n", (int)lpszName));
    311303    }
    312304    dprintf(("FindResourceA returned %X (%X)\n", hres, GetLastError()));
     
    325317
    326318    if(fNativePEImage == TRUE) {//load resources directly from res section
    327     if((int)lpszType >> 16 != 0) {
    328         char *resname = UnicodeToAsciiString(lpszType);
    329     }
    330     else    astring1 = (char *)lpszType;
    331 
    332     if((int)lpszName >> 16 != 0) {
    333         astring2 = UnicodeToAsciiString(lpszName);
    334     }
    335     else    astring2 = (char *)lpszName;
    336 
    337     hres = (HRSRC) getPEResource((ULONG)astring1, (ULONG)astring1);
    338     if(astring1) FreeAsciiString(astring1);
    339     if(astring2) FreeAsciiString(astring2);
    340 
    341     return(hres);
     319        if((int)lpszType >> 16 != 0) {
     320                char *resname = UnicodeToAsciiString(lpszType);
     321        }
     322        else    astring1 = (char *)lpszType;
     323
     324        if((int)lpszName >> 16 != 0) {
     325                astring2 = UnicodeToAsciiString(lpszName);
     326        }
     327        else    astring2 = (char *)lpszName;
     328
     329        hres = (HRSRC) getPEResource((ULONG)astring1, (ULONG)astring1);
     330        if(astring1) FreeAsciiString(astring1);
     331        if(astring2) FreeAsciiString(astring2);
     332
     333        return(hres);
    342334    }
    343335    //else converted win32 exe/dll
     
    384376
    385377    if((int)lpszName >> 16 != 0) {//convert string name identifier to numeric id
    386       astring1 = UnicodeToAsciiString(lpszName);
     378        astring1 = UnicodeToAsciiString(lpszName);
    387379        dprintf(("FindResourceW %X %s\n", hinstance, astring1));
    388       if(astring1[0] == '#') {// #344
    389             lpszName = (LPWSTR)atoi(&astring1[1]);
    390       }
    391       else  lpszName = (LPWSTR)ConvertNameId(hinstance, (char *)astring1);
     380        if(astring1[0] == '#') {// #344
     381                lpszName = (LPWSTR)atoi(&astring1[1]);
     382        }
     383        else    lpszName = (LPWSTR)ConvertNameId(hinstance, (char *)astring1);
    392384    }
    393385    else dprintf(("FindResourceW %X %d\n", hinstance, (int)lpszName));
     
    396388    if(hres)
    397389    {
    398       res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
     390        res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
    399391    }
    400392
    401393    if(hres == NULL && (int)lpszName >> 16 == 0 && (int)szType == NTRT_STRING) {
    402       hres = O32_FindResource(hinstance, (LPCSTR)(((ULONG)lpszName - 1)*16), (LPCSTR)NTRT_RCDATA);
    403       if(hres)
    404       {
    405         res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
    406       }
    407       else    dprintf(("FindResourceW can't find string %d\n", (int)lpszName));
     394        hres = O32_FindResource(hinstance, (LPCSTR)(((ULONG)lpszName - 1)*16), (LPCSTR)NTRT_RCDATA);
     395        if(hres)
     396        {
     397                res = new Win32Resource(this, hres, (ULONG)lpszName, (ULONG)szType);
     398        }
     399        else    dprintf(("FindResourceW can't find string %d\n", (int)lpszName));
    408400    }
    409401    if(astring1)    FreeAsciiString(astring1);
Note: See TracChangeset for help on using the changeset viewer.