コード例 #1
0
ファイル: path.c プロジェクト: NVIDIA/winex_lgpl
/* checks that buffer (as found by matching the name) matches the info
 * (information is based on file type)
 * returns TRUE when file is found, FALSE to continue searching
 * (NB this is the opposite convention of SymFindFileInPathProc)
 */
static BOOL CALLBACK module_find_cb(PCWSTR buffer, PVOID user)
{
    struct module_find* mf = (struct module_find*)user;
    DWORD               size, checksum, timestamp;
    unsigned            matched = 0;

    /* the matching weights:
     * +1 if a file with same name is found and is a decent file of expected type
     * +1 if first parameter and second parameter match
     */

    /* FIXME: should check that id/two match the file pointed
     * by buffer
     */
    switch (mf->kind)
    {
    case DMT_PE:
        {
            HANDLE  hFile, hMap;
            void*   mapping;
            DWORD   timestamp;

            timestamp = ~mf->dw1;
            size = ~mf->dw2;
            hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL,
                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
            if (hFile == INVALID_HANDLE_VALUE) return FALSE;
            if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0)
            {
                if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
                {
                    IMAGE_NT_HEADERS*   nth = RtlImageNtHeader((HMODULE)mapping);

                    matched++;
                    timestamp = nth->FileHeader.TimeDateStamp;
                    size = nth->OptionalHeader.SizeOfImage;
                    UnmapViewOfFile(mapping);
                }
                CloseHandle(hMap);
            }
            CloseHandle(hFile);
            if (timestamp != mf->dw1)
                WARN("Found %s, but wrong timestamp\n", debugstr_w(buffer));
            if (size != mf->dw2)
                WARN("Found %s, but wrong size\n", debugstr_w(buffer));
            if (timestamp == mf->dw1 && size == mf->dw2) matched++;
        }
        break;
    case DMT_ELF:
        if (elf_fetch_file_info(buffer, 0, &size, &checksum))
        {
            matched++;
            if (checksum == mf->dw1) matched++;
            else
                WARN("Found %s, but wrong checksums: %08x %08x\n",
                     debugstr_w(buffer), checksum, mf->dw1);
        }
        else
        {
            WARN("Couldn't read %s\n", debugstr_w(buffer));
            return FALSE;
        }
        break;
    case DMT_DYLIB:
        FIXME("try to fetch module info to verify this is the correct file\n");
        break;
    case DMT_PDB:
        {
            struct pdb_lookup   pdb_lookup;
            char                fn[MAX_PATH];

            WideCharToMultiByte(CP_ACP, 0, buffer, -1, fn, MAX_PATH, NULL, NULL);
            pdb_lookup.filename = fn;

            if (!pdb_fetch_file_info(&pdb_lookup)) return FALSE;
            matched++;
            switch (pdb_lookup.kind)
            {
            case PDB_JG:
                if (mf->guid)
                {
                    WARN("Found %s, but wrong PDB version\n", debugstr_w(buffer));
                }
                else if (pdb_lookup.u.jg.timestamp == mf->dw1)
                    matched++;
                else
                    WARN("Found %s, but wrong signature: %08x %08x\n",
                         debugstr_w(buffer), pdb_lookup.u.jg.timestamp, mf->dw1);
                break;
            case PDB_DS:
                if (!mf->guid)
                {
                    WARN("Found %s, but wrong PDB version\n", debugstr_w(buffer));
                }
                else if (!memcmp(&pdb_lookup.u.ds.guid, mf->guid, sizeof(GUID)))
                    matched++;
                else
                    WARN("Found %s, but wrong GUID: %s %s\n",
                         debugstr_w(buffer), debugstr_guid(&pdb_lookup.u.ds.guid),
                         debugstr_guid(mf->guid));
                break;
            }
            if (pdb_lookup.age != mf->dw2)
            {
                matched--;
                WARN("Found %s, but wrong age: %08x %08x\n",
                     debugstr_w(buffer), pdb_lookup.age, mf->dw2);
            }
        }
        break;
    case DMT_DBG:
        {
            HANDLE  hFile, hMap;
            void*   mapping;

            timestamp = ~mf->dw1;
            hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL,
                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
            if (hFile == INVALID_HANDLE_VALUE) return FALSE;
            if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0)
            {
                if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
                {
                    const IMAGE_SEPARATE_DEBUG_HEADER*  hdr;
                    hdr = (const IMAGE_SEPARATE_DEBUG_HEADER*)mapping;

                    if (hdr->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
                    {
                        matched++;
                        timestamp = hdr->TimeDateStamp;
                    }
                    UnmapViewOfFile(mapping);
                }
                CloseHandle(hMap);
            }
            CloseHandle(hFile);
            if (timestamp == mf->dw1) matched++;
            else WARN("Found %s, but wrong timestamp\n", debugstr_w(buffer));
        }
        break;
    default:
        FIXME("What the heck??\n");
        return FALSE;
    }
    if (matched > mf->matched)
    {
        strcpyW(mf->filename, buffer);
        mf->matched = matched;
    }
    /* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
     * convention to stop/continue enumeration. sigh.
     */
    return mf->matched == 2;
}
コード例 #2
0
ファイル: path.c プロジェクト: howard5888/wineT
/* checks that buffer (as found by matching the name) matches the info
 * (information is based on file type)
 * returns TRUE when file is found, FALSE to continue searching
 * (NB this is the opposite conventions as for SymFindFileInPathProc)
 */
static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
{
    struct sffip*       s = (struct sffip*)user;
    DWORD               size, checksum;

    /* FIXME: should check that id/two/three match the file pointed
     * by buffer
     */
    switch (s->kind)
    {
    case DMT_PE:
        {
            HANDLE  hFile, hMap;
            void*   mapping;
            DWORD   timestamp;

            timestamp = ~(DWORD_PTR)s->id;
            size = ~s->two;
            hFile = CreateFileA(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, 
                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hFile == INVALID_HANDLE_VALUE) return FALSE;
            if ((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
            {
                if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
                {
                    IMAGE_NT_HEADERS*   nth = RtlImageNtHeader(mapping);
                    timestamp = nth->FileHeader.TimeDateStamp;
                    size = nth->OptionalHeader.SizeOfImage;
                    UnmapViewOfFile(mapping);
                }
                CloseHandle(hMap);
            }
            CloseHandle(hFile);
            if (timestamp != (DWORD_PTR)s->id || size != s->two)
            {
                WARN("Found %s, but wrong size or timestamp\n", buffer);
                return FALSE;
            }
        }
        break;
    case DMT_ELF:
        if (elf_fetch_file_info(buffer, 0, &size, &checksum))
        {
            if (checksum != (DWORD_PTR)s->id)
            {
                WARN("Found %s, but wrong checksums: %08lx %08lx\n",
                      buffer, checksum, (DWORD_PTR)s->id);
                return FALSE;
            }
        }
        else
        {
            WARN("Couldn't read %s\n", buffer);
            return FALSE;
        }
        break;
    case DMT_PDB:
        {
            struct pdb_lookup   pdb_lookup;

            pdb_lookup.filename = buffer;

            if (!pdb_fetch_file_info(&pdb_lookup)) return FALSE;
            switch (pdb_lookup.kind)
            {
            case PDB_JG:
                if (s->flags & SSRVOPT_GUIDPTR)
                {
                    WARN("Found %s, but wrong PDB version\n", buffer);
                    return FALSE;
                }
                if (pdb_lookup.u.jg.timestamp != (DWORD_PTR)s->id)
                {
                    WARN("Found %s, but wrong signature: %08lx %08lx\n",
                         buffer, pdb_lookup.u.jg.timestamp, (DWORD_PTR)s->id);
                    return FALSE;
                }
                break;
            case PDB_DS:
                if (!(s->flags & SSRVOPT_GUIDPTR))
                {
                    WARN("Found %s, but wrong PDB version\n", buffer);
                    return FALSE;
                }
                if (memcmp(&pdb_lookup.u.ds.guid, (GUID*)s->id, sizeof(GUID)))
                {
                    WARN("Found %s, but wrong GUID: %s %s\n",
                         buffer, debugstr_guid(&pdb_lookup.u.ds.guid),
                         debugstr_guid((GUID*)s->id));
                    return FALSE;
                }
                break;
            }
            if (pdb_lookup.age != s->two)
            {
                WARN("Found %s, but wrong age: %08lx %08lx\n",
                     buffer, pdb_lookup.age, s->two);
                return FALSE;
            }
        }
        break;
    default:
        FIXME("What the heck??\n");
        return FALSE;
    }
    /* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
     * convention to stop/continue enumeration. sigh.
     */
    return !(s->cb)((char*)buffer, s->user);
}