Ignore:
Timestamp:
Nov 29, 1999, 1:05:03 AM (26 years ago)
Author:
bird
Message:

Implemented EnumResourceNamesA/W.

File:
1 edited

Legend:

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

    r1613 r1872  
    1 /* $Id: winimgres.cpp,v 1.26 1999-11-05 12:54:50 sandervl Exp $ */
     1/* $Id: winimgres.cpp,v 1.27 1999-11-29 00:04:07 bird Exp $ */
    22
    33/*
     
    2222#include <misc.h>
    2323#include <winimagebase.h>
    24 #include <winimagepe2lx.h>
    25 #include <winimagepeldr.h>
    26 #include <winimagelx.h>
    2724#include <winres.h>
    2825#include <unicode.h>
     
    270267        return 0;
    271268    }
    272     //pResourceSectionStart contains the virtual address of the imagebase in the PE header
    273     //for the resource section (images loaded by the pe.exe)
     269    //ulRVAResourceSection contains the relative virtual address (relative to the start of the image)
     270    //for the resource section (images loaded by the pe.exe and pe2lx/win32k)
    274271    //For LX images, this is 0 as OffsetToData contains a relative offset
    275     char *resdata = (char *)((char *)pResDir + pData->OffsetToData - pResourceSectionStart);
     272    char *resdata = (char *)((char *)pResDir + pData->OffsetToData - ulRVAResourceSection);
    276273    res = new Win32Resource(this, id, type, pData->Size, resdata);
    277274
     
    385382        return 0;
    386383    }
    387     char *resdata = (char *)((char *)pResDir + pData->OffsetToData - pResourceSectionStart);
     384    char *resdata = (char *)((char *)pResDir + pData->OffsetToData - ulRVAResourceSection);
    388385    memcpy(verstruct, resdata, min(bufLength, pData->Size));
    389386    return TRUE;
    390387}
    391 //******************************************************************************
    392 //******************************************************************************
     388
     389
     390/**
     391 * The EnumResourceNames function searches a module for each
     392 * resource of the specified type and passes the name of each
     393 * resource it locates to an application-defined callback function
     394 *
     395 * @returns   If the function succeeds, the return value is nonzero.
     396 *            If the function fails, the return value is zero
     397 * @param     hmod          The specified module handle.
     398 * @param     lpszType      pointer to resource type
     399 * @param     lpEnumFunc    pointer to callback function
     400 * @param     lParam        application-defined parameter
     401 * @sketch    IF not resources in module THEN return fail.
     402 *            Validate parameters.
     403 *            Get the subdirectory for the specified type.
     404 *            IF found THEN
     405 *            BEGIN
     406 *                Find the number of directory entries.
     407 *                Find directory entries.
     408 *                LOOP thru all entries while the callback function returns true
     409 *                BEGIN
     410 *                    Name = pointer to ASCII name string or Id.
     411 *                    call callback function.
     412 *                END
     413 *            END
     414 *            ELSE
     415 *                fail.
     416 *            return
     417 * @status    completely implemented and tested.
     418 * @author    knut st. osmundsen
     419 * @remark    The EnumResourceNames function continues to enumerate resource
     420 *            names until the callback function returns FALSE or all resource
     421 *            names have been enumerated
     422 */
     423BOOL Win32ImageBase::enumResourceNamesA(HMODULE hmod,
     424                                        LPCTSTR  lpszType,
     425                                        ENUMRESNAMEPROCA lpEnumFunc,
     426                                        LONG lParam)
     427{
     428    BOOL                            fRet;
     429    PIMAGE_RESOURCE_DIRECTORY       pResDirOurType;
     430    PIMAGE_RESOURCE_DIRECTORY_ENTRY paResDirEntries;
     431
     432    if (pResDir == NULL)
     433    {
     434        /* SetLastError(?);? */
     435        return FALSE;
     436    }
     437
     438    /* validate parameters - FIXME... Exception handler??? */
     439    if ((unsigned)lpszType >= 0xc0000000) //....
     440    {
     441        SetLastError(ERROR_INVALID_PARAMETER);
     442        return FALSE;
     443    }
     444
     445    if ((unsigned)lpEnumFunc < 0x10000 || (unsigned)lpEnumFunc >= 0xc0000000)
     446    {
     447        SetLastError(ERROR_NOACCESS);
     448        return FALSE;
     449    }
     450
     451    //reminder:
     452    //1st level -> types
     453    //2nd level -> names
     454    //3rd level -> language
     455
     456    pResDirOurType = getResSubDirA(pResDir, lpszType);
     457    if (pResDirOurType != NULL)
     458    {
     459        char     *pszASCII = NULL;
     460        unsigned  cch = 0;
     461        unsigned  cResEntries;
     462        unsigned  i;
     463
     464        fRet = TRUE;
     465        cResEntries = pResDirOurType->NumberOfNamedEntries + pResDirOurType->NumberOfIdEntries;
     466        paResDirEntries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((unsigned)pResDirOurType + sizeof(*pResDirOurType));
     467        for (i = 0; i < cResEntries && fRet; i++)
     468        {
     469            LPSTR lpszName;
     470
     471            if (paResDirEntries[i].u1.s.NameIsString)
     472            {
     473                PIMAGE_RESOURCE_DIR_STRING_U pResDirString =
     474                    (PIMAGE_RESOURCE_DIR_STRING_U)(paResDirEntries[i].u1.s.NameOffset + (unsigned)pResDir);
     475
     476                /* ASCII buffer allocation/adjustment? */
     477                if (cch <= pResDirString->Length)
     478                {
     479                    void *pszTmp;
     480                    cch = max(pResDirString->Length + 1, 32);
     481                    pszTmp = pszASCII != NULL ? realloc(pszASCII, cch) : malloc(cch);
     482                    if (pszTmp == NULL)
     483                    {
     484                        fRet = FALSE;
     485                        break;
     486                    }
     487                    pszASCII = (char*)pszTmp;
     488                }
     489                UnicodeToAsciiN(pResDirString->NameString, pszASCII, pResDirString->Length);
     490                lpszName = pszASCII;
     491            }
     492            else
     493                lpszName = (LPSTR)paResDirEntries[i].u1.Id;
     494
     495            fRet = lpEnumFunc(hmod, lpszType, lpszName, lParam);
     496        }
     497
     498        if (pszASCII != NULL)
     499            free(pszASCII);
     500    }
     501    else
     502    {
     503        SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
     504        fRet = FALSE;
     505    }
     506
     507    return fRet > 0 ? TRUE : FALSE;
     508}
     509
     510
     511/**
     512 * The EnumResourceNames function searches a module for each
     513 * resource of the specified type and passes the name of each
     514 * resource it locates to an application-defined callback function
     515 *
     516 * @returns   If the function succeeds, the return value is nonzero.
     517 *            If the function fails, the return value is zero
     518 * @param     hmod          The specified module handle.
     519 * @param     lpszType      pointer to resource type
     520 * @param     lpEnumFunc    pointer to callback function
     521 * @param     lParam        application-defined parameter
     522 * @sketch    IF not resources in module THEN return fail.
     523 *            Validate parameters.
     524 *            Get the subdirectory for the specified type.
     525 *            IF found THEN
     526 *            BEGIN
     527 *                Find the number of directory entries.
     528 *                Find directory entries.
     529 *                LOOP thru all entries while the callback function returns true
     530 *                BEGIN
     531 *                    Name = pointer to ASCII name string or Id.
     532 *                    call callback function.
     533 *                END
     534 *            END
     535 *            ELSE
     536 *                fail.
     537 *            return
     538 * @status    completely implemented and tested.
     539 * @author    knut st. osmundsen
     540 * @remark    The EnumResourceNames function continues to enumerate resource
     541 *            names until the callback function returns FALSE or all resource
     542 *            names have been enumerated
     543 */
     544BOOL Win32ImageBase::enumResourceNamesW(HMODULE hmod,
     545                                        LPCWSTR  lpszType,
     546                                        ENUMRESNAMEPROCW lpEnumFunc,
     547                                        LONG lParam)
     548{
     549    BOOL                            fRet;
     550    PIMAGE_RESOURCE_DIRECTORY       pResDirOurType;
     551    PIMAGE_RESOURCE_DIRECTORY_ENTRY paResDirEntries;
     552
     553    if (pResDir == NULL)
     554    {
     555        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
     556        return FALSE;
     557    }
     558
     559    /* validate parameters - FIXME... Exception handler??? */
     560    if ((unsigned)lpszType >= 0xc0000000) //....
     561    {
     562        SetLastError(ERROR_INVALID_PARAMETER);
     563        return FALSE;
     564    }
     565
     566    if ((unsigned)lpEnumFunc < 0x10000 || (unsigned)lpEnumFunc >= 0xc0000000)
     567    {
     568        SetLastError(ERROR_NOACCESS);
     569        return FALSE;
     570    }
     571
     572
     573    //reminder:
     574    //1st level -> types
     575    //2nd level -> names
     576    //3rd level -> language
     577
     578    pResDirOurType = getResSubDirW(pResDir, lpszType);
     579    if (pResDirOurType != NULL)
     580    {
     581        unsigned  cResEntries;
     582        unsigned  i;
     583
     584        fRet = TRUE;
     585        cResEntries = pResDirOurType->NumberOfNamedEntries + pResDirOurType->NumberOfIdEntries;
     586        paResDirEntries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((unsigned)pResDirOurType + sizeof(*pResDirOurType));
     587        for (i = 0; i < cResEntries && fRet; i++)
     588        {
     589            LPWSTR lpszName;
     590
     591            if (paResDirEntries[i].u1.s.NameIsString)
     592                lpszName = (LPWSTR)(paResDirEntries[i].u1.s.NameOffset + (unsigned)pResDir + 2);
     593            else
     594                lpszName = (LPWSTR)paResDirEntries[i].u1.Id;
     595
     596            fRet = lpEnumFunc(hmod, lpszType, lpszName, lParam);
     597        }
     598    }
     599    else
     600    {
     601        SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
     602        fRet = FALSE;
     603    }
     604
     605    return fRet > 0;
     606}
     607
     608
     609
     610/**
     611 * This function finds a resource (sub)directory within a given resource directory.
     612 * @returns   Pointer to resource directory. NULL if not found or not a directory.
     613 * @param     pResDirToSearch  Pointer to resource directory to search. (any level)
     614 * @param     lpszName         Resource ID string.
     615 * @sketch
     616 * @status    completely implemented
     617 * @author    knut st. osmundsen
     618 */
     619PIMAGE_RESOURCE_DIRECTORY Win32ImageBase::getResSubDirW(PIMAGE_RESOURCE_DIRECTORY pResDirToSearch, LPCWSTR lpszName)
     620{
     621    PIMAGE_RESOURCE_DIRECTORY_ENTRY paResDirEntries;
     622    int     i;
     623    int     idName = -1;
     624
     625    /* lpszName */
     626    if (HIWORD(lpszName) != 0)
     627    {
     628        if (lpszName[0] == '#')
     629        {
     630            char szBuf[10];
     631            lstrcpynWtoA(szBuf, (WCHAR*)(lpszName + 1), sizeof(szBuf));
     632            idName = atoi(szBuf);
     633        }
     634    }
     635    else
     636        idName = (int)lpszName;
     637
     638    paResDirEntries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((unsigned)pResDirToSearch + sizeof(*pResDirToSearch));
     639    if (idName != -1)
     640    {   /* idName */
     641        paResDirEntries += pResDirToSearch->NumberOfNamedEntries;
     642
     643        for (i = 0; i < pResDirToSearch->NumberOfIdEntries; i++)
     644            if (paResDirEntries[i].u1.Id == (WORD)idName)
     645                return paResDirEntries[i].u2.s.DataIsDirectory ?
     646                    (PIMAGE_RESOURCE_DIRECTORY) (paResDirEntries[i].u2.s.OffsetToDirectory + (unsigned)pResDir /*?*/
     647                                                 /*- ulRVAResourceSection*/)
     648                    : NULL;
     649    }
     650    else
     651    {   /* string name */
     652        int cusName = lstrlenW(lpszName);
     653
     654        for (i = 0; i < pResDirToSearch->NumberOfNamedEntries; i++)
     655        {
     656            PIMAGE_RESOURCE_DIR_STRING_U pResDirStr =
     657                (PIMAGE_RESOURCE_DIR_STRING_U)(paResDirEntries[i].u1.s.NameOffset + (unsigned)pResDir /*?*/);
     658
     659            if (pResDirStr->Length == cusName
     660                && UniStrncmp(pResDirStr->NameString, lpszName, cusName) == 0)
     661            {
     662                return paResDirEntries[i].u2.s.DataIsDirectory ?
     663                    (PIMAGE_RESOURCE_DIRECTORY) (paResDirEntries[i].u2.s.OffsetToDirectory + (unsigned)pResDir
     664                                                 /*- ulRVAResourceSection*/)
     665                    : NULL;
     666            }
     667        }
     668    }
     669
     670    return NULL;
     671}
     672
     673/**
     674 * This function finds a resource (sub)directory within a given resource directory.
     675 * @returns   Pointer to resource directory. NULL if not found or not a directory.
     676 * @param     pResDirToSearch  Pointer to resource directory to search. (any level)
     677 * @param     lpszName         Resource ID string.
     678 * @sketch
     679 * @status    completely implemented
     680 * @author    knut st. osmundsen
     681 */
     682PIMAGE_RESOURCE_DIRECTORY Win32ImageBase::getResSubDirA(PIMAGE_RESOURCE_DIRECTORY pResDirToSearch, LPCTSTR lpszName)
     683{
     684    PIMAGE_RESOURCE_DIRECTORY   pResDirRet;
     685    LPCWSTR                     lpszwName;
     686
     687    /* lpszName */
     688    if (HIWORD(lpszName) != 0)
     689    {
     690        lpszwName = AsciiToUnicodeString((char*)lpszName);
     691        if (lpszwName == NULL)
     692            return NULL;
     693    }
     694    else
     695        lpszwName = (LPWSTR)lpszName;
     696
     697    pResDirRet = getResSubDirW(pResDirToSearch, lpszwName);
     698
     699    if (HIWORD(lpszwName) != 0)
     700        free((void*)lpszwName);
     701
     702    return pResDirRet;
     703}
     704
Note: See TracChangeset for help on using the changeset viewer.