Beispiel #1
0
APR_DECLARE(apr_status_t) apr_shm_create_ex(apr_shm_t **m,
                                            apr_size_t reqsize,
                                            const char *file,
                                            apr_pool_t *pool,
                                            apr_int32_t flags)
{
    static apr_size_t memblock = 0;
    HANDLE hMap, hFile;
    apr_status_t rv;
    apr_size_t size;
    apr_file_t *f;
    void *base;
    void *mapkey;
    DWORD err, sizelo, sizehi;

    reqsize += sizeof(memblock_t);

    if (!memblock)
    {
        SYSTEM_INFO si;
        GetSystemInfo(&si);
        memblock = si.dwAllocationGranularity;
    }   

    /* Compute the granualar multiple of the pagesize */
    size = memblock * (1 + (reqsize - 1) / memblock);
    sizelo = (DWORD)size;
#ifdef _WIN64
    sizehi = (DWORD)(size >> 32);
#else
    sizehi = 0;
#endif

    if (!file) {
        /* Do Anonymous, which must be passed as a duplicated handle */
#ifndef _WIN32_WCE
        hFile = INVALID_HANDLE_VALUE;
#endif
        mapkey = NULL;
    }
    else {
        int global;

        /* Do file backed, which is not an inherited handle 
         * While we could open APR_FOPEN_EXCL, it doesn't seem that Unix
         * ever did.  Ignore that error here, but fail later when
         * we discover we aren't the creator of the file map object.
         */
        rv = apr_file_open(&f, file,
                           APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_BINARY | APR_FOPEN_CREATE,
                           APR_FPROT_UREAD | APR_FPROT_UWRITE, pool);
        if ((rv != APR_SUCCESS)
                || ((rv = apr_os_file_get(&hFile, f)) != APR_SUCCESS)) {
            return rv;
        }
        rv = apr_file_trunc(f, size);

        /* res_name_from_filename turns file into a pseudo-name
         * without slashes or backslashes, and prepends the \global
         * or \local prefix on Win2K and later
         */
        if (flags & APR_SHM_NS_GLOBAL) {
            global = 1;
        }
        else if (flags & APR_SHM_NS_LOCAL) {
            global = 0;
        }
        else {
            global = can_create_global_maps();
        }
        mapkey = res_name_from_filename(file, global, pool);
    }

#if APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE
    {
        hMap = CreateFileMappingW(hFile, NULL, PAGE_READWRITE, 
                                  sizehi, sizelo, mapkey);
    }
#endif
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        hMap = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, 
                                  sizehi, sizelo, mapkey);
    }
#endif
    err = apr_get_os_error();

    if (file) {
        apr_file_close(f);
    }

    if (hMap && APR_STATUS_IS_EEXIST(err)) {
        CloseHandle(hMap);
        return APR_EEXIST;
    }
    if (!hMap) {
        return err;
    }
    
    base = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE,
                         0, 0, size);
    if (!base) {
        CloseHandle(hMap);
        return apr_get_os_error();
    }
    
    *m = (apr_shm_t *) apr_palloc(pool, sizeof(apr_shm_t));
    (*m)->pool = pool;
    (*m)->hMap = hMap;
    (*m)->memblk = base;
    (*m)->size = size;

    (*m)->usrmem = (char*)base + sizeof(memblock_t);
    (*m)->length = reqsize - sizeof(memblock_t);;
    
    (*m)->memblk->length = (*m)->length;
    (*m)->memblk->size = (*m)->size;
    (*m)->filename = file ? apr_pstrdup(pool, file) : NULL;

    apr_pool_cleanup_register((*m)->pool, *m, 
                              shm_cleanup, apr_pool_cleanup_null);
    return APR_SUCCESS;
}
Beispiel #2
0
/* 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 sffip_cb(PCWSTR buffer, PVOID 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 = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL,
                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hFile == INVALID_HANDLE_VALUE) return FALSE;
            if ((hMap = CreateFileMappingW(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", debugstr_w(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: %08x %08lx\n",
                     debugstr_w(buffer), checksum, (DWORD_PTR)s->id);
                return FALSE;
            }
        }
        else
        {
            WARN("Couldn't read %s\n", debugstr_w(buffer));
            return FALSE;
        }
        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;
            switch (pdb_lookup.kind)
            {
            case PDB_JG:
                if (s->flags & SSRVOPT_GUIDPTR)
                {
                    WARN("Found %s, but wrong PDB version\n", debugstr_w(buffer));
                    return FALSE;
                }
                if (pdb_lookup.u.jg.timestamp != (DWORD_PTR)s->id)
                {
                    WARN("Found %s, but wrong signature: %08x %08lx\n",
                         debugstr_w(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", debugstr_w(buffer));
                    return FALSE;
                }
                if (memcmp(&pdb_lookup.u.ds.guid, (GUID*)s->id, sizeof(GUID)))
                {
                    WARN("Found %s, but wrong GUID: %s %s\n",
                         debugstr_w(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: %08x %08x\n",
                     debugstr_w(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)((WCHAR*)buffer, s->user);
}
Beispiel #3
0
Datei: enum.c Projekt: jaykrell/j
int wmain()
{
    HMODULE Module;
    HANDLE File = { 0 };
    BYTE* MappedFile = { 0 };
    BYTE* MappedFile_End = { 0 };
    HANDLE FileMapping = { 0 };
    ULARGE_INTEGER FileSize;
    DWORD Error = { 0 };
    IMAGE_NT_HEADERS* NtHeaders = { 0 };
    IMAGE_DOS_HEADER* DosHeader = { 0 };
    size_t OffsetToPE = { 0 };
    IMAGE_RESOURCE_DIRECTORY* TopDirectory = { 0 };
    ULONG ResourcesSize = { 0 };

    Module = LoadLibraryW(L".\\notepad.exe");
    if (!EnumResourceTypesW(Module, EnumTypesProc, 0))
    {
        DWORD Error = GetLastError();
        wprintf(L"EnumResourceTypes failed %x\n", Error);
    }
    FreeLibrary(Module);

    File = CreateFileW(L".\\notepad.exe", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (INVALID_HANDLE_VALUE == File)
    {
        Error = GetLastError();
        wprintf(L"CreateFile fails with error: %u", Error);
        goto Exit;
    }

    FileSize.LowPart = GetFileSize(File, &FileSize.HighPart);
    if ((FileSize.LowPart == -1) && ((Error = GetLastError()) != 0))
    {
        wprintf(L"GetFileSize failed with error %u\n", Error);
        goto Exit;
    }
    if (FileSize.HighPart != 0)
    {
        wprintf(L"file too large\n");
        goto Exit;
    }
    if (FileSize.QuadPart <= (sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS)))
    {
        wprintf(L"file too small\n");
        goto Exit;
    }
    
    FileMapping = CreateFileMappingW(File, NULL, PAGE_READONLY, 0, 0, NULL);
    if (FileMapping == NULL)
    {
        Error = GetLastError();
        wprintf(L"CreateFileMapping fails with error: %u", Error);
        goto Exit;
    }

    MappedFile = (BYTE*) MapViewOfFile(FileMapping, FILE_MAP_READ, 0, 0, 0);
    if (MappedFile == NULL)
        goto Exit;

    wprintf(L"MappedFile:%p\n", MappedFile);
    MappedFile_End = (MappedFile + FileSize.QuadPart);
    DosHeader = (IMAGE_DOS_HEADER*) MappedFile;
    if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
    {
        wprintf(L"invalid file");
        goto Exit;
    }

    OffsetToPE = DosHeader->e_lfanew;
    if (OffsetToPE >= FileSize.QuadPart)
    {
        wprintf(L"invalid file");
        goto Exit;
    }
    if ((OffsetToPE + sizeof(IMAGE_NT_HEADERS)) >= FileSize.QuadPart)
    {
        wprintf(L"invalid file");
        goto Exit;
    }
    NtHeaders = (IMAGE_NT_HEADERS*) (MappedFile + OffsetToPE);
    if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
    {
        wprintf(L"invalid file");
        goto Exit;
    }
    if (NtHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
    {
        wprintf(L"invalid file");
        goto Exit;
    }
    if (NtHeaders->OptionalHeader.NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_RESOURCE)
    {
        wprintf(L"no resources");
        goto Exit;
    }
    if (NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress == 0)
    {
        wprintf(L"no resources");
        goto Exit;
    }
    if (NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size == 0)
    {
        wprintf(L"no resources");
        goto Exit;
    }

    TopDirectory = (IMAGE_RESOURCE_DIRECTORY*) ImageDirectoryEntryToData(MappedFile, FALSE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &ResourcesSize);
    if (TopDirectory == NULL)
    {
        wprintf(L"no resources");
        goto Exit;
    }
    DumpResourceDirectory(MappedFile, 0, TopDirectory, TopDirectory);
 
Exit:
    if (MappedFile != NULL)
        UnmapViewOfFile(MappedFile);

    if (FileMapping != NULL)
        CloseHandle(FileMapping);

    if ((File != NULL) && (File != INVALID_HANDLE_VALUE))
        CloseHandle(File);

    return 0;
}
Beispiel #4
0
        mapped_file::mapped_file(const string & fname, unsigned int io_open_mode, unsigned int create_size)
            : file_handle(0), map_handle(0), map_pointer(0)
        {
#ifdef WIN32
            string full_path = io::file::get_full_path(fname);

            // open file handle
            unsigned int win_open_mode = GENERIC_READ;

            if (io_open_mode & io::FILE_OPEN_WRITE)
                win_open_mode |= GENERIC_WRITE;

            if (file::exists(full_path))
            {
                file_handle = CreateFileW(full_path.w_string(), win_open_mode, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

                if (file_handle != INVALID_HANDLE_VALUE)
                    create_size = GetFileSize(file_handle, 0);
            }
            else
            {
                if (create_size == 0)
                    throw internal_exception(__FILE__, __LINE__, L"Must specify size for creating memory-mapped files.");

                file_handle = CreateFileW(full_path.w_string(), win_open_mode, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
                
                if (file_handle != INVALID_HANDLE_VALUE)
                {
                    unsigned char buf = 0;
                    unsigned int written;
                    SetFilePointer(file_handle, create_size-1, 0, FILE_BEGIN);                    
                    WriteFile(file_handle, &buf, 1, (LPDWORD) &written, 0);
                    SetFilePointer(file_handle, 0, 0, FILE_BEGIN);
                }
            }
            
            if (file_handle == INVALID_HANDLE_VALUE)
                throw io_exception(L"Unable to open %ls: %ls", full_path.w_string(), get_windows_error().w_string());

            // create mapping
            string map_name = string::format(L"periapsis_mapped_file_%d", NUM_MAPPED_FILES++);

            if (io_open_mode & io::FILE_OPEN_WRITE)
                win_open_mode = PAGE_READWRITE;
            else
                win_open_mode = PAGE_READONLY;

            map_handle = CreateFileMappingW(file_handle, 0, win_open_mode, 0, create_size, map_name.w_string());

            if (!map_handle)
                throw io_exception(L"Unable to create memory map for %ls: %ls", full_path.w_string(), get_windows_error().w_string());

            // map file
            if (io_open_mode & io::FILE_OPEN_WRITE)
                win_open_mode = FILE_MAP_ALL_ACCESS;
            else
                win_open_mode = FILE_MAP_READ;

            map_pointer = MapViewOfFile(map_handle, win_open_mode, 0, 0, 0);

            if (!map_pointer)
                throw io_exception(L"Unable to create memory map for %ls: %ls", full_path.w_string(), get_windows_error().w_string());

            map_size = create_size;
#else
#error Implement memory-mapped files!
#endif
        } // mapped_file::mapped_file()
Beispiel #5
0
/* 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 = 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;

            timestamp = ~mf->dw1;
            size = ~mf->dw2;
            hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL,
                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hFile == INVALID_HANDLE_VALUE) return FALSE;
            if ((hMap = CreateFileMappingW(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);
                    if (!nth)
                    {
                        UnmapViewOfFile(mapping);
                        CloseHandle(hMap);
                        CloseHandle(hFile);
                        return FALSE;
                    }
                    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_MACHO:
        if (macho_fetch_file_info(NULL, buffer, 0, 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_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 (mf->guid)
            {
                pdb_lookup.kind = PDB_DS;
                pdb_lookup.timestamp = 0;
                pdb_lookup.guid = *mf->guid;
            }
            else
            {
                pdb_lookup.kind = PDB_JG;
                pdb_lookup.timestamp = mf->dw1;
                /* pdb_loopkup.guid = */
            }
            pdb_lookup.age = mf->dw2;

            if (!pdb_fetch_file_info(&pdb_lookup, &matched)) return FALSE;
        }
        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, NULL);
            if (hFile == INVALID_HANDLE_VALUE) return FALSE;
            if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
            {
                if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
                {
                    const IMAGE_SEPARATE_DEBUG_HEADER*  hdr;
                    hdr = 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;
}
Beispiel #6
0
int __cdecl main(int argc, char *argv[])
{

    const   int MAPPINGSIZE = 2048;
    HANDLE  hFileMapping;
    LPVOID  lpMapViewAddress;
    char *p;
    int i;

    /* Initialize the PAL environment.
     */
    if(0 != PAL_Initialize(argc, argv))
    {
        return FAIL;
    }

    hFileMapping = CreateFileMappingW(INVALID_HANDLE_VALUE,
                                      NULL,
                                      PAGE_READWRITE,
                                      0,
                                      MAPPINGSIZE,
                                      NULL);

    if (hFileMapping == NULL) {
        Trace("ERROR:%u: CreateFileMappingW() failed\n", GetLastError());
        Fail("");
    }


    lpMapViewAddress = MapViewOfFile(
                            hFileMapping,
                            FILE_MAP_WRITE, /* access code */
                            0,              /* high order offset */
                            0,              /* low order offset */
                            MAPPINGSIZE);   /* number of bytes for map */

    if(NULL == lpMapViewAddress)
    {
        Trace("ERROR:%u: MapViewOfFile() failed.\n",
              GetLastError());
        CloseHandle(hFileMapping);
        Fail("");
    }

    p = (char *)lpMapViewAddress;
    for (i=0; i<MAPPINGSIZE; ++i) {
        /* Confirm that the memory is zero-initialized */
        if (p[i] != 0) 
        {
            Fail("MapViewOfFile() of pagefile didn't return 0-filled data "
                 "(Offset %d has value 0x%x)\n", i, p[i]);
        }
        /* Confirm that it is writable */
        *(char *)lpMapViewAddress = 0xcc;
    }

    /* Clean-up and Terminate the PAL.
    */
    CloseHandle(hFileMapping);
    UnmapViewOfFile(lpMapViewAddress);
    PAL_Terminate();
    return PASS;
}
Beispiel #7
0
LRESULT WINAPI LresultFromObject( REFIID riid, WPARAM wParam, LPUNKNOWN pAcc )
{
    static const WCHAR atom_fmt[] = {'%','0','8','x',':','%','0','8','x',':','%','0','8','x',0};
    static const LARGE_INTEGER seek_zero = {{0}};

    WCHAR atom_str[sizeof(lresult_atom_prefix)/sizeof(WCHAR)+3*8+3];
    IStream *stream;
    HANDLE mapping;
    STATSTG stat;
    HRESULT hr;
    ATOM atom;
    void *view;

    TRACE("%s %ld %p\n", debugstr_guid(riid), wParam, pAcc);

    if(wParam)
        FIXME("unsupported wParam = %lx\n", wParam);

    if(!pAcc)
        return E_INVALIDARG;

    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
    if(FAILED(hr))
        return hr;

    hr = CoMarshalInterface(stream, riid, pAcc, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
    if(FAILED(hr)) {
        IStream_Release(stream);
        return hr;
    }

    hr = IStream_Seek(stream, seek_zero, STREAM_SEEK_SET, NULL);
    if(FAILED(hr)) {
        IStream_Release(stream);
        return hr;
    }

    hr = IStream_Stat(stream, &stat, STATFLAG_NONAME);
    if(FAILED(hr)) {
        CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return hr;
    }else if(stat.cbSize.u.HighPart) {
        FIXME("stream size to big\n");
        CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return E_NOTIMPL;
    }

    mapping = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
            stat.cbSize.u.HighPart, stat.cbSize.u.LowPart, NULL);
    if(!mapping) {
        CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return hr;
    }

    view = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
    if(!view) {
        CloseHandle(mapping);
        CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return E_FAIL;
    }

    hr = IStream_Read(stream, view, stat.cbSize.u.LowPart, NULL);
    UnmapViewOfFile(view);
    if(FAILED(hr)) {
        CloseHandle(mapping);
        hr = IStream_Seek(stream, seek_zero, STREAM_SEEK_SET, NULL);
        if(SUCCEEDED(hr))
            CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return hr;

    }

    memcpy(atom_str, lresult_atom_prefix, sizeof(lresult_atom_prefix));
    sprintfW(atom_str+sizeof(lresult_atom_prefix)/sizeof(WCHAR),
             atom_fmt, GetCurrentProcessId(), HandleToUlong(mapping), stat.cbSize.u.LowPart);
    atom = GlobalAddAtomW(atom_str);
    if(!atom) {
        CloseHandle(mapping);
        hr = IStream_Seek(stream, seek_zero, STREAM_SEEK_SET, NULL);
        if(SUCCEEDED(hr))
            CoReleaseMarshalData(stream);
        IStream_Release(stream);
        return E_FAIL;
    }

    IStream_Release(stream);
    return atom;
}
Beispiel #8
0
/*
** Create the mutex and shared memory used for locking in the file
** descriptor pFile
*/
static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
  WCHAR *zTok;
  WCHAR *zName = utf8ToUnicode(zFilename);
  BOOL bInit = TRUE;

  /* Initialize the local lockdata */
  ZeroMemory(&pFile->local, sizeof(pFile->local));

  /* Replace the backslashes from the filename and lowercase it
  ** to derive a mutex name. */
  zTok = CharLowerW(zName);
  for (;*zTok;zTok++){
    if (*zTok == '\\') *zTok = '_';
  }

  /* Create/open the named mutex */
  pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
  if (!pFile->hMutex){
    free(zName);
    return FALSE;
  }

  /* Acquire the mutex before continuing */
  winceMutexAcquire(pFile->hMutex);
  
  /* Since the names of named mutexes, semaphores, file mappings etc are 
  ** case-sensitive, take advantage of that by uppercasing the mutex name
  ** and using that as the shared filemapping name.
  */
  CharUpperW(zName);
  pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
                                       PAGE_READWRITE, 0, sizeof(winceLock),
                                       zName);  

  /* Set a flag that indicates we're the first to create the memory so it 
  ** must be zero-initialized */
  if (GetLastError() == ERROR_ALREADY_EXISTS){
    bInit = FALSE;
  }

  free(zName);

  /* If we succeeded in making the shared memory handle, map it. */
  if (pFile->hShared){
    pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, 
             FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
    /* If mapping failed, close the shared memory handle and erase it */
    if (!pFile->shared){
      CloseHandle(pFile->hShared);
      pFile->hShared = NULL;
    }
  }

  /* If shared memory could not be created, then close the mutex and fail */
  if (pFile->hShared == NULL){
    winceMutexRelease(pFile->hMutex);
    CloseHandle(pFile->hMutex);
    pFile->hMutex = NULL;
    return FALSE;
  }
  
  /* Initialize the shared memory if we're supposed to */
  if (bInit) {
    ZeroMemory(pFile->shared, sizeof(winceLock));
  }

  winceMutexRelease(pFile->hMutex);
  return TRUE;
}
Beispiel #9
0
/******************************************************************
 *		pe_map_file
 *
 * Maps an PE file into memory (and checks it's a real PE file)
 */
static BOOL pe_map_file(HANDLE file, struct image_file_map* fmap, enum module_type mt)
{
    void*       mapping;

    fmap->modtype = mt;
    fmap->u.pe.hMap = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
    if (fmap->u.pe.hMap == 0) return FALSE;
    fmap->u.pe.full_count = 0;
    fmap->u.pe.full_map = NULL;
    if (!(mapping = pe_map_full(fmap, NULL))) goto error;

    switch (mt)
    {
    case DMT_PE:
        {
            IMAGE_NT_HEADERS*       nthdr;
            IMAGE_SECTION_HEADER*   section;
            unsigned                i;

            if (!(nthdr = RtlImageNtHeader(mapping))) goto error;
            memcpy(&fmap->u.pe.ntheader, nthdr, sizeof(fmap->u.pe.ntheader));
            switch (nthdr->OptionalHeader.Magic)
            {
            case 0x10b: fmap->addr_size = 32; break;
            case 0x20b: fmap->addr_size = 64; break;
            default: return FALSE;
            }
            section = (IMAGE_SECTION_HEADER*)
                ((char*)&nthdr->OptionalHeader + nthdr->FileHeader.SizeOfOptionalHeader);
            fmap->u.pe.sect = HeapAlloc(GetProcessHeap(), 0,
                                        nthdr->FileHeader.NumberOfSections * sizeof(fmap->u.pe.sect[0]));
            if (!fmap->u.pe.sect) goto error;
            for (i = 0; i < nthdr->FileHeader.NumberOfSections; i++)
            {
                memcpy(&fmap->u.pe.sect[i].shdr, section + i, sizeof(IMAGE_SECTION_HEADER));
                fmap->u.pe.sect[i].mapped = IMAGE_NO_MAP;
            }
            if (nthdr->FileHeader.PointerToSymbolTable && nthdr->FileHeader.NumberOfSymbols)
            {
                LARGE_INTEGER li;

                if (GetFileSizeEx(file, &li) && pe_is_valid_pointer_table(nthdr, mapping, li.QuadPart))
                {
                    /* FIXME ugly: should rather map the relevant content instead of copying it */
                    const char* src = (const char*)mapping +
                        nthdr->FileHeader.PointerToSymbolTable +
                        nthdr->FileHeader.NumberOfSymbols * sizeof(IMAGE_SYMBOL);
                    char* dst;
                    DWORD sz = *(DWORD*)src;

                    if ((dst = HeapAlloc(GetProcessHeap(), 0, sz)))
                        memcpy(dst, src, sz);
                    fmap->u.pe.strtable = dst;
                }
                else
                {
                    WARN("Bad coff table... wipping out\n");
                    /* we have bad information here, wipe it out */
                    fmap->u.pe.ntheader.FileHeader.PointerToSymbolTable = 0;
                    fmap->u.pe.ntheader.FileHeader.NumberOfSymbols = 0;
                    fmap->u.pe.strtable = NULL;
                }
            }
            else fmap->u.pe.strtable = NULL;
        }
        break;
    default: assert(0); goto error;
    }
    pe_unmap_full(fmap);

    return TRUE;
error:
    pe_unmap_full(fmap);
    CloseHandle(fmap->u.pe.hMap);
    return FALSE;
}
bool InitializeProfAPISharedObj()
{
    gCAProfAPISharedMapFile = OpenFileMappingW(FILE_MAP_ALL_ACCESS,          // read/write access
                                               FALSE,                      // do not inherit the name
                                               CPU_PROF_SHARED_OBJ);   // name of mapping object

    if (!gCAProfAPISharedMapFile)
    {
        SECURITY_ATTRIBUTES secAttr;
        char secDesc[ SECURITY_DESCRIPTOR_MIN_LENGTH ];
        secAttr.nLength = sizeof(secAttr);
        secAttr.bInheritHandle = FALSE;
        secAttr.lpSecurityDescriptor = &secDesc;

        bool bHasSD = false;
        OSVERSIONINFO osVersionInfo;
        osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

        if (GetVersionEx(&osVersionInfo))
        {
            if (osVersionInfo.dwMajorVersion >= 6)
            {
                // Vista, Longhorn or later;
                bHasSD = true;
            }
        }

        if (bHasSD)
        {
            PSECURITY_DESCRIPTOR pSD;
            PACL pSacl = nullptr;                  // not allocated
            BOOL fSaclPresent = FALSE;
            BOOL fSaclDefaulted = FALSE;

            ConvertStringSecurityDescriptorToSecurityDescriptorW(L"S:(ML;;NW;;;LW)",  // this means "low integrity"
                                                                 SDDL_REVISION_1,
                                                                 &pSD,
                                                                 nullptr);

            GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl,
                                      &fSaclDefaulted);

            SetSecurityDescriptorSacl(secAttr.lpSecurityDescriptor, TRUE,
                                      pSacl, FALSE);
        }

        InitializeSecurityDescriptor(secAttr.lpSecurityDescriptor,
                                     SECURITY_DESCRIPTOR_REVISION);
        SetSecurityDescriptorDacl(secAttr.lpSecurityDescriptor, TRUE, 0,
                                  FALSE);

        gCAProfAPISharedMapFile =
            CreateFileMappingW(INVALID_HANDLE_VALUE,
                               &secAttr,           // default security
                               PAGE_READWRITE,         // read/write access
                               0,              // max. object size
                               CPU_PROF_SHARED_MEM_SIZE,           // buffer size
                               CPU_PROF_SHARED_OBJ);   // name of mapping object
    }

    if (gCAProfAPISharedMapFile)
    {
        return true;
    }
    else
    {
        return false;
    }
}
Beispiel #11
0
CShareMemory::CShareMemory(LPCWSTR name,DWORD size,BOOL shareWrite):memfile(INVALID_HANDLE_VALUE)
{
	filesize=size;

	DWORD dwRes;
	PSID pEveryoneSID = nullptr,pOwnerSID=nullptr;
	PACL pACL = nullptr;
	SECURITY_DESCRIPTOR SD;
	SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
		SECURITY_WORLD_SID_AUTHORITY;
	SID_IDENTIFIER_AUTHORITY SIDAuthOwner =
		SECURITY_CREATOR_SID_AUTHORITY;
	SECURITY_ATTRIBUTES sa;
	EXPLICIT_ACCESS *acclist=nullptr;

	__try
	{
		if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
			SECURITY_WORLD_RID,
			0, 0, 0, 0, 0, 0, 0,
			&pEveryoneSID))
		{
			ATLTRACE("AllocateAndInitializeSid Error %u\n", GetLastError());
			__leave;
		}

		int eacount=0;
		if(shareWrite)
		{
			eacount=1;
			acclist=(EXPLICIT_ACCESS *)calloc(eacount,sizeof(EXPLICIT_ACCESS));
			if(acclist==nullptr) __leave;

			acclist[0].grfAccessPermissions = GENERIC_WRITE|GENERIC_READ;
			acclist[0].grfAccessMode = SET_ACCESS;
			acclist[0].grfInheritance= NO_INHERITANCE;
			acclist[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
			acclist[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			acclist[0].Trustee.ptstrName  = (LPTSTR) pEveryoneSID;
		}
		else
		{
			eacount=2;
			acclist=(EXPLICIT_ACCESS *)calloc(eacount,sizeof(EXPLICIT_ACCESS));
			if(acclist==nullptr) __leave;

			if(!AllocateAndInitializeSid(&SIDAuthOwner, 1,
				SECURITY_CREATOR_OWNER_RID,
				0, 0, 0, 0, 0, 0, 0,
				&pOwnerSID))
			{
				ATLTRACE("AllocateAndInitializeSid Error %u\n", GetLastError());
				__leave;
			}

			acclist[0].grfAccessPermissions = GENERIC_READ;
			acclist[0].grfAccessMode = SET_ACCESS;
			acclist[0].grfInheritance= NO_INHERITANCE;
			acclist[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
			acclist[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			acclist[0].Trustee.ptstrName  = (LPTSTR) pEveryoneSID;

			acclist[1].grfAccessPermissions = GENERIC_READ|GENERIC_WRITE;
			acclist[1].grfAccessMode = SET_ACCESS;
			acclist[1].grfInheritance= NO_INHERITANCE;
			acclist[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
			acclist[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			acclist[1].Trustee.ptstrName  = (LPTSTR) pOwnerSID;
		}

		dwRes = SetEntriesInAcl(eacount, acclist, nullptr, &pACL);
		if (ERROR_SUCCESS != dwRes) 
		{
			ATLTRACE("SetEntriesInAcl Error %u\n", GetLastError());
			__leave;
		}

		// Initialize a security descriptor.

		if (!InitializeSecurityDescriptor(&SD,
			SECURITY_DESCRIPTOR_REVISION)) 
		{  
			ATLTRACE("InitializeSecurityDescriptor Error %u\n",
				GetLastError());
			__leave;
		} 

		// Add the ACL to the security descriptor. 
		if (!SetSecurityDescriptorDacl(&SD, 
			TRUE,     // bDaclPresent flag   
			pACL, 
			FALSE))   // not a default DACL 
		{  
			ATLTRACE("SetSecurityDescriptorDacl Error %u\n",
				GetLastError());
			__leave;
		} 

		// Initialize a security attributes structure.
		sa.nLength = sizeof (SECURITY_ATTRIBUTES);
		sa.lpSecurityDescriptor = &SD;
		sa.bInheritHandle = FALSE;

		memfile=CreateFileMappingW(INVALID_HANDLE_VALUE,&sa,PAGE_READWRITE,0,filesize,name);
		if(memfile==INVALID_HANDLE_VALUE) __leave;
		if(GetLastError()==ERROR_ALREADY_EXISTS)
			ATLTRACE("file map exit\n");
		p=MapViewOfFileEx(memfile,FILE_MAP_READ|FILE_MAP_WRITE,0,0,filesize,nullptr);
	}
	__finally
	{
		if (pEveryoneSID) 
			FreeSid(pEveryoneSID);
		if (pOwnerSID)
			FreeSid(pOwnerSID);
		if (pACL) 
			LocalFree(pACL);
		if(acclist)
			free(acclist);
	}
}
Beispiel #12
0
int main(int argc, char *argv[])
{
	HANDLE map;

	bool srvr = true;
	if (argc > 1 && !strcmp(argv[1], "client")) {
		srvr = false;

	}




	HANDLE ev;
	/* create event */
	if (srvr) {
		ev = CreateEventW(NULL, false, false, SHM_EVENT);
	} else {
		ev = OpenEventW(EVENT_ALL_ACCESS, false, SHM_EVENT);
	}
	if (ev == NULL) {
		printf("can't create/open event");
		exit(1);
	}
	

	HANDLE mutex;
	if (srvr) {
		mutex = CreateMutex(NULL, false, SHM_MUTEX);
	} else {
		mutex = OpenMutex(SYNCHRONIZE, false, SHM_MUTEX);
	}
	if (mutex == NULL) {
		printf("mutex error\n");
		exit(1);
	} 


	/* Shared memory */
	if (srvr) {
		map = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, SHM_NAME);
	} else {
		map = OpenFileMappingW(FILE_MAP_ALL_ACCESS, false, SHM_NAME);
	}
	if (map == NULL) {
		fprintf(stderr, "Can't get file mapping: %lu\n", GetLastError());
		exit(1);
	}
	void *mem;
	mem = MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if (!mem) {
		fprintf(stderr, "MapViewOfFile() failed with %lu\n", GetLastError());
		exit(2);
	}
	CloseHandle(map);

	struct my_mem *mm;
	mm = (struct my_mem *)mem;	

	if (srvr == false) {
		/* writer */
		printf("client\n");
		mm->total = 4096;
		while(1) {
			int x = getchar();

			WaitForSingleObject(mutex, INFINITE);
			printf("idx(%d) < total(%d)\n", mm->idx, mm->total);
			if (mm->idx < mm->total) {
				mm->arr[mm->idx] = x;
				mm->idx++;
			}
		
			SetEvent(ev);
			ReleaseMutex(mutex);
			/* end of file */
			if (x < 0)
				break;			
		}
	} else {
		/* reader */
		while(1) {
			WaitForSingleObject(ev, INFINITE);
			WaitForSingleObject(mutex, INFINITE);

			int i;
			bool stop = false;
			for (i=0; i<mm->idx; i++) {
				if (mm->arr[i] < 0)
					stop = true;
				printf("%c", mm->arr[i]);
			}
			mm->idx = 0;
			ReleaseMutex(mutex);
			if (stop)
				break;
		}
	}
	
	UnmapViewOfFile(mem);
	CloseHandle(ev);
	CloseHandle(mutex);




	system("pause");
	return 0;
}
Beispiel #13
0
/***********************************************************************
 *		ImageGetDigestStream (IMAGEHLP.@)
 *
 * Gets a stream of bytes from a PE file over which a hash might be computed to
 * verify that the image has not changed.  Useful for creating a certificate to
 * be added to the file with ImageAddCertificate.
 *
 * PARAMS
 *  FileHandle     [In] File for which to return a stream.
 *  DigestLevel    [In] Flags to control which portions of the file to return.
 *                      0 is allowed, as is any combination of:
 *                       CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO: reports the entire
 *                        import section rather than selected portions of it.
 *                       CERT_PE_IMAGE_DIGEST_DEBUG_INFO: reports the debug section.
 *                       CERT_PE_IMAGE_DIGEST_RESOURCES: reports the resources
                          section.
 *  DigestFunction [In] Callback function.
 *  DigestHandle   [In] Handle passed as first parameter to DigestFunction.
 *
 * RETURNS
 *  TRUE if successful.
 *  FALSE if unsuccessful.  GetLastError returns more about the error.
 *
 * NOTES
 *  Only supports 32-bit PE files, not tested with any other format.
 *  Reports data in the following order:
 *  1. The file headers are reported first
 *  2. Any code sections are reported next.
 *  3. The data (".data" and ".rdata") sections are reported next.
 *  4. The import section is reported next.
 *  5. If CERT_PE_IMAGE_DIGEST_DEBUG_INFO is set in DigestLevel, the debug section is
 *     reported next.
 *  6. If CERT_PE_IMAGE_DIGEST_RESOURCES is set in DigestLevel, the resources section
 *     is reported next.
 *
 * BUGS
 *  CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO must be specified, returns an error if not.
 */
BOOL WINAPI ImageGetDigestStream(
  HANDLE FileHandle, DWORD DigestLevel,
  DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
{
    DWORD error = 0;
    BOOL ret = FALSE;
    DWORD offset, size, num_sections, fileSize;
    HANDLE hMap = INVALID_HANDLE_VALUE;
    BYTE *map = NULL;
    IMAGE_DOS_HEADER *dos_hdr;
    IMAGE_NT_HEADERS *nt_hdr;
    IMAGE_SECTION_HEADER *section_headers;

    TRACE("(%p, %d, %p, %p)\n", FileHandle, DigestLevel, DigestFunction,
        DigestHandle);

    /* Get the file size */
    if( !FileHandle )
        goto invalid_parameter;
    fileSize = GetFileSize( FileHandle, NULL );
    if(fileSize == INVALID_FILE_SIZE )
        goto invalid_parameter;

    /* map file */
    hMap = CreateFileMappingW( FileHandle, NULL, PAGE_READONLY, 0, 0, NULL );
    if( hMap == INVALID_HANDLE_VALUE )
        goto invalid_parameter;
    map = MapViewOfFile( hMap, FILE_MAP_COPY, 0, 0, 0 );
    if( !map )
        goto invalid_parameter;

    /* Read the file header */
    if( fileSize < sizeof(IMAGE_DOS_HEADER) )
        goto invalid_parameter;
    dos_hdr = (IMAGE_DOS_HEADER *)map;

    if( dos_hdr->e_magic != IMAGE_DOS_SIGNATURE )
        goto invalid_parameter;
    offset = dos_hdr->e_lfanew;
    if( !offset || offset > fileSize )
        goto invalid_parameter;
    ret = DigestFunction( DigestHandle, map, offset );
    if( !ret )
        goto end;

    /* Read the NT header */
    if( offset + sizeof(IMAGE_NT_HEADERS) > fileSize )
        goto invalid_parameter;
    nt_hdr = (IMAGE_NT_HEADERS *)(map + offset);
    if( nt_hdr->Signature != IMAGE_NT_SIGNATURE )
        goto invalid_parameter;
    /* It's clear why the checksum is cleared, but why only these size headers?
     */
    nt_hdr->OptionalHeader.SizeOfInitializedData = 0;
    nt_hdr->OptionalHeader.SizeOfImage = 0;
    nt_hdr->OptionalHeader.CheckSum = 0;
    size = sizeof(nt_hdr->Signature) + sizeof(nt_hdr->FileHeader) +
        nt_hdr->FileHeader.SizeOfOptionalHeader;
    ret = DigestFunction( DigestHandle, map + offset, size );
    if( !ret )
        goto end;

    /* Read the section headers */
    offset += size;
    num_sections = nt_hdr->FileHeader.NumberOfSections;
    size = num_sections * sizeof(IMAGE_SECTION_HEADER);
    if( offset + size > fileSize )
        goto invalid_parameter;
    ret = DigestFunction( DigestHandle, map + offset, size );
    if( !ret )
        goto end;

    section_headers = (IMAGE_SECTION_HEADER *)(map + offset);
    IMAGEHLP_ReportCodeSections( section_headers, num_sections,
        map, fileSize, DigestFunction, DigestHandle );
    IMAGEHLP_ReportSection( section_headers, num_sections, ".data",
        map, fileSize, DigestFunction, DigestHandle );
    IMAGEHLP_ReportSection( section_headers, num_sections, ".rdata",
        map, fileSize, DigestFunction, DigestHandle );
    IMAGEHLP_ReportImportSection( section_headers, num_sections,
        map, fileSize, DigestLevel, DigestFunction, DigestHandle );
    if( DigestLevel & CERT_PE_IMAGE_DIGEST_DEBUG_INFO )
        IMAGEHLP_ReportSection( section_headers, num_sections, ".debug",
            map, fileSize, DigestFunction, DigestHandle );
    if( DigestLevel & CERT_PE_IMAGE_DIGEST_RESOURCES )
        IMAGEHLP_ReportSection( section_headers, num_sections, ".rsrc",
            map, fileSize, DigestFunction, DigestHandle );

end:
    if( map )
        UnmapViewOfFile( map );
    if( hMap != INVALID_HANDLE_VALUE )
        CloseHandle( hMap );
    if( error )
        SetLastError(error);
    return ret;

invalid_parameter:
    error = ERROR_INVALID_PARAMETER;
    goto end;
}
Beispiel #14
0
/***********************************************************************
 * IMAGEHLP_RecalculateChecksum (INTERNAL)
 *
 * Update the NT header checksum for the specified file.
 */
static BOOL IMAGEHLP_RecalculateChecksum(HANDLE handle)
{
    DWORD FileLength, count, HeaderSum, pe_offset, nt_hdr_size;
    IMAGE_NT_HEADERS32 nt_hdr32;
    IMAGE_NT_HEADERS64 nt_hdr64;
    LPVOID BaseAddress;
    HANDLE hMapping;
    DWORD *CheckSum;
    void *nt_hdr;
    int ret;
    BOOL r;

    TRACE("handle %p\n", handle);

    ret = IMAGEHLP_GetNTHeaders(handle, &pe_offset, &nt_hdr32, &nt_hdr64);

    if (ret == HDR_NT32)
    {
        CheckSum = &nt_hdr32.OptionalHeader.CheckSum;

        nt_hdr = &nt_hdr32;
        nt_hdr_size = sizeof(IMAGE_NT_HEADERS32);
    }
    else if (ret == HDR_NT64)
    {
        CheckSum = &nt_hdr64.OptionalHeader.CheckSum;

        nt_hdr = &nt_hdr64;
        nt_hdr_size = sizeof(IMAGE_NT_HEADERS64);
    }
    else
        return FALSE;

    hMapping = CreateFileMappingW(handle, NULL, PAGE_READONLY, 0, 0, NULL);

    if (!hMapping)
        return FALSE;

    BaseAddress = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

    if (!BaseAddress)
    {
        CloseHandle(hMapping);
        return FALSE;
    }

    FileLength = GetFileSize(handle, NULL);

    *CheckSum = 0;
    CheckSumMappedFile(BaseAddress, FileLength, &HeaderSum, CheckSum);

    UnmapViewOfFile(BaseAddress);
    CloseHandle(hMapping);

    if (*CheckSum)
    {
        /* write the header back again */
        count = SetFilePointer(handle, pe_offset, NULL, FILE_BEGIN);

        if (count == INVALID_SET_FILE_POINTER)
            return FALSE;

        count = 0;

        r = WriteFile(handle, nt_hdr, nt_hdr_size, &count, NULL);

        if (!r)
            return FALSE;

        if (count != nt_hdr_size)
            return FALSE;

        return TRUE;
    }

    return FALSE;
}
Beispiel #15
0
static apr_status_t shm_attach_internal(apr_shm_t **m,
                                        const char *file,
                                        apr_pool_t *pool,
                                        int global)
{
    HANDLE hMap;
    void *mapkey;
    void *base;

    /* res_name_from_filename turns file into a pseudo-name
     * without slashes or backslashes, and prepends the \global
     * or local prefix on Win2K and later
     */
    mapkey = res_name_from_filename(file, global, pool);

#if APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE
    {
#ifndef _WIN32_WCE
        hMap = OpenFileMappingW(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapkey);
#else
        /* The WCE 3.0 lacks OpenFileMapping. So we emulate one with
         * opening the existing shmem and reading its size from the header 
         */
        hMap = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, 
                                  PAGE_READWRITE, 0, sizeof(apr_shm_t), mapkey);
#endif
    }
#endif
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        hMap = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapkey);
    }
#endif

    if (!hMap) {
        return apr_get_os_error();
    }
    
    base = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
    if (!base) {
        CloseHandle(hMap);
        return apr_get_os_error();
    }
    
    *m = (apr_shm_t *) apr_palloc(pool, sizeof(apr_shm_t));
    (*m)->pool = pool;
    (*m)->memblk = base;
    /* Real (*m)->mem->size could be recovered with VirtualQuery */
    (*m)->size = (*m)->memblk->size;
#if _WIN32_WCE
    /* Reopen with real size  */
    UnmapViewOfFile(base);
    CloseHandle(hMap);

    hMap = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, 
                              PAGE_READWRITE, 0, (*m)->size, mapkey);
    if (!hMap) {
        return apr_get_os_error();
    }
    base = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
    if (!base) {
        CloseHandle(hMap);
        return apr_get_os_error();
    }    
#endif
    (*m)->hMap = hMap;
    (*m)->length = (*m)->memblk->length;
    (*m)->usrmem = (char*)base + sizeof(memblock_t);
    (*m)->filename = NULL;

    apr_pool_cleanup_register((*m)->pool, *m, 
                              shm_cleanup, apr_pool_cleanup_null);
    return APR_SUCCESS;
}
Beispiel #16
0
HMODULE CustomLoadLibrary(const PWCHAR wszFullDllName, const PWCHAR wszBaseDllName, ULONG_PTR pDllBase)
{
    // File handles
    HANDLE hFile = INVALID_HANDLE_VALUE;
    HANDLE hMap = NULL;
    PCHAR pFile = NULL;

    // PE headers
    PIMAGE_DOS_HEADER pDosHeader;
    PIMAGE_NT_HEADERS pNtHeader;
    PIMAGE_SECTION_HEADER pSectionHeader;

    // Library 
    PCHAR pLibraryAddr = NULL;
    DWORD dwIdx;

    // Relocation
    PIMAGE_DATA_DIRECTORY pDataDir;
    PIMAGE_BASE_RELOCATION pBaseReloc;
    ULONG_PTR pReloc;
    DWORD dwNumRelocs;
    ULONG_PTR pInitialImageBase;
    PIMAGE_RELOC pImageReloc;

    // Import
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
    PCHAR szDllName;
    SIZE_T stDllName;
    PWSTR wszDllName = NULL;
    PWCHAR wsRedir = NULL;
    PWSTR wszRedirName = NULL;
    SIZE_T stRedirName;
    SIZE_T stSize;

    HMODULE hModule;
    PIMAGE_THUNK_DATA pThunkData;
    FARPROC* pIatEntry;

	// clr.dll hotpatches itself at runtime for performance reasons, so skip it
	if (wcscmp(L"clr.dll", wszBaseDllName) == 0)
		goto cleanup;

	dprintf("[REFRESH] Opening file: %S", wszFullDllName);

    // ----
    // Step 1: Map the file into memory
    // ----

	hFile = CreateFileW(wszFullDllName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        goto cleanup;

    hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (hMap == NULL)
        goto cleanup;

    pFile = (PCHAR)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
    if (pFile == NULL)
        goto cleanup;

    // ----
    // Step 2: Parse the file headers and load it into memory
    // ----
    pDosHeader = (PIMAGE_DOS_HEADER)pFile;
    pNtHeader = (PIMAGE_NT_HEADERS)(pFile + pDosHeader->e_lfanew);

    // allocate memory to copy DLL into
    dprintf("[REFRESH] Allocating memory for library");
    pLibraryAddr = (PCHAR)VirtualAlloc(NULL, pNtHeader->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    // copy header
    dprintf("[REFRESH] Copying PE header into memory");
    memcpy(pLibraryAddr, pFile, pNtHeader->OptionalHeader.SizeOfHeaders);

    // copy sections
    dprintf("[REFRESH] Copying PE sections into memory");
    pSectionHeader = (PIMAGE_SECTION_HEADER)(pFile + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
    for (dwIdx = 0; dwIdx < pNtHeader->FileHeader.NumberOfSections; dwIdx++)
    {
        memcpy(pLibraryAddr + pSectionHeader[dwIdx].VirtualAddress,
               pFile + pSectionHeader[dwIdx].PointerToRawData,
               pSectionHeader[dwIdx].SizeOfRawData);
    }

    // update our pointers to the loaded image
    pDosHeader = (PIMAGE_DOS_HEADER)pLibraryAddr;
    pNtHeader = (PIMAGE_NT_HEADERS)(pLibraryAddr + pDosHeader->e_lfanew);

    // ----
    // Step 3: Calculate relocations
    // ----
    dprintf("[REFRESH] Calculating file relocations");

    pDataDir = &pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
    pInitialImageBase = pNtHeader->OptionalHeader.ImageBase;
    // set the ImageBase to the already loaded module's base
    pNtHeader->OptionalHeader.ImageBase = pDllBase;

    // check if their are any relocations present
    if (pDataDir->Size)
    {
        // calculate the address of the first IMAGE_BASE_RELOCATION entry
        pBaseReloc = (PIMAGE_BASE_RELOCATION)(pLibraryAddr + pDataDir->VirtualAddress);

        // iterate through each relocation entry
        while ((PCHAR)pBaseReloc < (pLibraryAddr + pDataDir->VirtualAddress + pDataDir->Size) && pBaseReloc->SizeOfBlock)
        {
            // the VA for this relocation block
            pReloc = (ULONG_PTR)(pLibraryAddr + pBaseReloc->VirtualAddress);

            // number of entries in this relocation block
            dwNumRelocs = (pBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(IMAGE_RELOC);

            // first entry in the current relocation block
            pImageReloc = (PIMAGE_RELOC)((PCHAR)pBaseReloc + sizeof(IMAGE_BASE_RELOCATION));

            // iterate through each entry in the relocation block
            while (dwNumRelocs--)
            {
                // perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required.
                // we subtract the initial ImageBase and add in the original dll base
                if (pImageReloc->type == IMAGE_REL_BASED_DIR64)
                {
                    *(ULONG_PTR *)(pReloc + pImageReloc->offset) -= pInitialImageBase;
                    *(ULONG_PTR *)(pReloc + pImageReloc->offset) += pDllBase;
                }
                else if (pImageReloc->type == IMAGE_REL_BASED_HIGHLOW)
                {
                    *(DWORD *)(pReloc + pImageReloc->offset) -= (DWORD)pInitialImageBase;
                    *(DWORD *)(pReloc + pImageReloc->offset) += (DWORD)pDllBase;
                }
                else if (pImageReloc->type == IMAGE_REL_BASED_HIGH)
                {
                    *(WORD *)(pReloc + pImageReloc->offset) -= HIWORD(pInitialImageBase);
                    *(WORD *)(pReloc + pImageReloc->offset) += HIWORD(pDllBase);
                }
                else if (pImageReloc->type == IMAGE_REL_BASED_LOW)
                {
                    *(WORD *)(pReloc + pImageReloc->offset) -= LOWORD(pInitialImageBase);
                    *(WORD *)(pReloc + pImageReloc->offset) += LOWORD(pDllBase);
                }
                
                // get the next entry in the current relocation block
                pImageReloc = (PIMAGE_RELOC)((PCHAR)pImageReloc + sizeof(IMAGE_RELOC));
            }

            // get the next entry in the relocation directory
            pBaseReloc = (PIMAGE_BASE_RELOCATION)((PCHAR)pBaseReloc + pBaseReloc->SizeOfBlock);
        }
    }

    // ----
    // Step 4: Update import table
    // ----
    dprintf("[REFRESH] Resolving Import Address Table (IAT) ");

    pDataDir = &pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
    if (pDataDir->Size)
    {
        pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pLibraryAddr + pDataDir->VirtualAddress);

        while (pImportDesc->Characteristics)
        {
            hModule = NULL;
            wszDllName = NULL;
            szDllName = (PCHAR)(pLibraryAddr + pImportDesc->Name);
            stDllName = strnlen(szDllName, MAX_PATH);
            wszDllName = (PWSTR)calloc(stDllName + 1, sizeof(WCHAR));

            if (wszDllName == NULL)
                goto next_import;

            mbstowcs_s(&stSize, wszDllName, stDllName + 1, szDllName, stDllName);

			dprintf("[REFRESH] Loading library: %S", wszDllName);

			// If the DLL starts with api- or ext-, resolve the redirected name and load it
            if (_wcsnicmp(wszDllName, L"api-", 4) == 0 || _wcsnicmp(wszDllName, L"ext-", 4) == 0)
            {
                // wsRedir is not null terminated
                wsRedir = GetRedirectedName(wszBaseDllName, wszDllName, &stRedirName);
                if (wsRedir)
                {
                    // Free the original wszDllName and allocate a new buffer for the redirected dll name
                    free(wszDllName);
                    wszDllName = (PWSTR)calloc(stRedirName + 1, sizeof(WCHAR));
                    if (wszDllName == NULL)
                        goto next_import;

                    memcpy(wszDllName, wsRedir, stRedirName * sizeof(WCHAR));
                    dprintf("[REFRESH] Redirected library: %S", wszDllName);
                }
            }

            // Load the module
            hModule = CustomGetModuleHandleW(wszDllName);

            // Ignore libraries that fail to load
            if (hModule == NULL)
                goto next_import;

            if (pImportDesc->OriginalFirstThunk)
                pThunkData = (PIMAGE_THUNK_DATA)(pLibraryAddr + pImportDesc->OriginalFirstThunk);
            else
                pThunkData = (PIMAGE_THUNK_DATA)(pLibraryAddr + pImportDesc->FirstThunk);

            pIatEntry = (FARPROC*)(pLibraryAddr + pImportDesc->FirstThunk);

            // loop through each thunk and resolve the import
            for(; DEREF(pThunkData); pThunkData++, pIatEntry++)
            {
                if (IMAGE_SNAP_BY_ORDINAL(pThunkData->u1.Ordinal))
                    *pIatEntry = CustomGetProcAddressEx(hModule, (PCHAR)IMAGE_ORDINAL(pThunkData->u1.Ordinal), wszDllName);
                else
                    *pIatEntry = CustomGetProcAddressEx(hModule, ((PIMAGE_IMPORT_BY_NAME)(pLibraryAddr + DEREF(pThunkData)))->Name, wszDllName);
            }

next_import:
            if (wszDllName != NULL)
            {
                free(wszDllName);
                wszDllName = NULL;
            }
            pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((PCHAR)pImportDesc + sizeof(IMAGE_IMPORT_DESCRIPTOR));

        }
    }

cleanup:
    if (pFile != NULL)
        UnmapViewOfFile(pFile);
    if (hMap != NULL)
        CloseHandle(hMap);
    if (hFile != INVALID_HANDLE_VALUE)
        CloseHandle(hFile);

    return (HMODULE) pLibraryAddr;
}
Beispiel #17
0
/*************************************************************************
 *	ICO_ExtractIconExW		[internal]
 *
 * NOTES
 *  nIcons = 0: returns number of Icons in file
 *
 * returns
 *  invalid file: -1
 *  failure:0;
 *  success: number of icons in file (nIcons = 0) or nr of icons retrieved
 */
static UINT ICO_ExtractIconExW(
	LPCWSTR lpszExeFileName,
	HICON * RetPtr,
	INT nIconIndex,
	UINT nIcons,
	UINT cxDesired,
	UINT cyDesired,
	UINT *pIconId,
	UINT flags)
{
	UINT		ret = 0;
	UINT		cx1, cx2, cy1, cy2;
	LPBYTE		pData;
	DWORD		sig;
	HANDLE		hFile;
	UINT16		iconDirCount = 0, iconCount = 0;
	LPBYTE		peimage;
	HANDLE		fmapping;
	DWORD		fsizeh,fsizel;
        WCHAR		szExePath[MAX_PATH];
        DWORD		dwSearchReturn;

	TRACE("%s, %d, %d %p 0x%08x\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons, pIconId, flags);

        dwSearchReturn = SearchPathW(NULL, lpszExeFileName, NULL, sizeof(szExePath) / sizeof(szExePath[0]), szExePath, NULL);
        if ((dwSearchReturn == 0) || (dwSearchReturn > sizeof(szExePath) / sizeof(szExePath[0])))
        {
            WARN("File %s not found or path too long\n", debugstr_w(lpszExeFileName));
            return -1;
        }

	hFile = CreateFileW(szExePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
	if (hFile == INVALID_HANDLE_VALUE) return ret;
	fsizel = GetFileSize(hFile,&fsizeh);

	/* Map the file */
	fmapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
	CloseHandle(hFile);
	if (!fmapping)
	{
	  WARN("CreateFileMapping error %ld\n", GetLastError() );
	  return 0xFFFFFFFF;
	}

	if (!(peimage = MapViewOfFile(fmapping, FILE_MAP_READ, 0, 0, 0)))
	{
	  WARN("MapViewOfFile error %ld\n", GetLastError() );
	  CloseHandle(fmapping);
	  return 0xFFFFFFFF;
	}
	CloseHandle(fmapping);

	cx1 = LOWORD(cxDesired);
	cx2 = HIWORD(cxDesired);
	cy1 = LOWORD(cyDesired);
	cy2 = HIWORD(cyDesired);

	if (pIconId) /* Invalidate first icon identifier */
		*pIconId = 0xFFFFFFFF;

	if (!pIconId) /* if no icon identifier array present use the icon handle array as intermediate storage */
	  pIconId = (UINT*)RetPtr;

	sig = USER32_GetResourceTable(peimage, fsizel, &pData);

#ifdef WINE
/* ico file or NE exe/dll*/
	if (sig==IMAGE_OS2_SIGNATURE || sig==1) /* .ICO file */
	{
	  BYTE		*pCIDir = 0;
	  NE_TYPEINFO	*pTInfo = (NE_TYPEINFO*)(pData + 2);
	  NE_NAMEINFO	*pIconStorage = NULL;
	  NE_NAMEINFO	*pIconDir = NULL;
	  LPicoICONDIR	lpiID = NULL;
	  ULONG		uSize = 0;

          TRACE("-- OS2/icon Signature (0x%08x)\n", sig);

	  if (pData == (BYTE*)-1)
	  {
	    pCIDir = ICO_GetIconDirectory(peimage, &lpiID, &uSize);	/* check for .ICO file */
	    if (pCIDir)
	    {
	      iconDirCount = 1; iconCount = lpiID->idCount;
              TRACE("-- icon found %p 0x%08x 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);
	    }
	  }
	  else while (pTInfo->type_id && !(pIconStorage && pIconDir))
	  {
	    if (pTInfo->type_id == NE_RSCTYPE_GROUP_ICON)	/* find icon directory and icon repository */
	    {
	      iconDirCount = pTInfo->count;
	      pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
	      TRACE("\tfound directory - %i icon families\n", iconDirCount);
	    }
	    if (pTInfo->type_id == NE_RSCTYPE_ICON)
	    {
	      iconCount = pTInfo->count;
	      pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
	      TRACE("\ttotal icons - %i\n", iconCount);
	    }
	    pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
	  }

	  if ((pIconStorage && pIconDir) || lpiID)	  /* load resources and create icons */
	  {
	    if (nIcons == 0)
	    {
	      ret = iconDirCount;
              if (lpiID)	/* *.ico file, deallocate heap pointer*/
	        HeapFree(GetProcessHeap(), 0, pCIDir);
	    }
	    else if (nIconIndex < iconDirCount)
	    {
	      UINT16   i, icon;
	      if (nIcons > iconDirCount - nIconIndex)
	        nIcons = iconDirCount - nIconIndex;

	      for (i = 0; i < nIcons; i++)
	      {
	        /* .ICO files have only one icon directory */
	        if (lpiID == NULL)	/* not *.ico */
	          pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex, *(WORD*)pData, &uSize);
	        pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx1, cy1, flags);
                if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE,  cx2, cy2, flags);
	      }
              if (lpiID)	/* *.ico file, deallocate heap pointer*/
	        HeapFree(GetProcessHeap(), 0, pCIDir);

	      for (icon = 0; icon < nIcons; icon++)
	      {
	        pCIDir = NULL;
	        if (lpiID)
	          pCIDir = ICO_LoadIcon(peimage, lpiID->idEntries + (int)pIconId[icon], &uSize);
	        else
	          for (i = 0; i < iconCount; i++)
	            if (pIconStorage[i].id == ((int)pIconId[icon] | 0x8000) )
	              pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize);

	        if (pCIDir)
                {
	          RetPtr[icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
                                                                 cx1, cy1, flags);
                  if (cx2 && cy2)
                      RetPtr[++icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
                                                                       cx2, cy2, flags);
                }
	        else
	          RetPtr[icon] = 0;
	      }
	      ret = icon;	/* return number of retrieved icons */
	    }
	  }
	}
#else
    if (sig == 1 || sig == 2) /* .ICO or .CUR file */
    {
        TRACE("-- icon Signature (0x%08x)\n", sig);

        if (pData == (BYTE*)-1)
        {
            INT cx[2] = {cx1, cx2}, cy[2] = {cy1, cy2};
            INT index;

            for(index = 0; index < 2; index++)
            {
                DWORD dataOffset;
                LPBYTE imageData;
                POINT hotSpot;
                LPICONIMAGE entry;

                dataOffset = get_best_icon_file_offset(peimage, fsizel, cx[index], cy[index], sig == 1, flags, sig == 1 ? NULL : &hotSpot);

                if (dataOffset)
                {
                    HICON icon;
                    WORD *cursorData = NULL;

                    imageData = peimage + dataOffset;
                    entry = (LPICONIMAGE)(imageData);

                    if(sig == 2)
                    {
                        /* we need to prepend the bitmap data with hot spots for CreateIconFromResourceEx */
                        cursorData = HeapAlloc(GetProcessHeap(), 0, entry->icHeader.biSizeImage + 2 * sizeof(WORD));

                        if(!cursorData)
                            continue;

                        cursorData[0] = hotSpot.x;
                        cursorData[1] = hotSpot.y;

                        memcpy(cursorData + 2, imageData, entry->icHeader.biSizeImage);

                        imageData = (LPBYTE)cursorData;
                    }

                    icon = CreateIconFromResourceEx(imageData, entry->icHeader.biSizeImage, sig == 1, 0x00030000, cx[index], cy[index], flags);

                    if (icon)
                    {
                        RetPtr[index] = icon;
                        iconCount = 1;
                    }

                    if(cursorData != NULL)
                        HeapFree(GetProcessHeap(), 0, cursorData);
                }
            }

        }
        ret = iconCount;	/* return number of retrieved icons */
    }
#endif
/* end ico file */

/* exe/dll */
	else if( sig == IMAGE_NT_SIGNATURE )
	{
        BYTE *idata, *igdata;
        const IMAGE_RESOURCE_DIRECTORY *rootresdir, *iconresdir, *icongroupresdir;
        const IMAGE_RESOURCE_DATA_ENTRY *idataent, *igdataent;
        const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
        ULONG size;
        UINT i;

        rootresdir = RtlImageDirectoryEntryToData((HMODULE)peimage, FALSE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size);
        if (!rootresdir)
        {
            WARN("haven't found section for resource directory.\n");
            goto end;
        }

	  /* search for the group icon directory */
	  if (!(icongroupresdir = find_entry_by_id(rootresdir, LOWORD(RT_GROUP_ICON), rootresdir)))
	  {
	    WARN("No Icongroupresourcedirectory!\n");
	    goto end;		/* failure */
	  }
	  iconDirCount = icongroupresdir->NumberOfNamedEntries + icongroupresdir->NumberOfIdEntries;

	  /* only number of icons requested */
	  if( !pIconId )
	  {
	    ret = iconDirCount;
	    goto end;		/* success */
	  }

	  if( nIconIndex < 0 )
	  {
	    /* search resource id */
	    int n = 0;
	    int iId = abs(nIconIndex);
	    const IMAGE_RESOURCE_DIRECTORY_ENTRY* xprdeTmp = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1);

	    while(n<iconDirCount && xprdeTmp)
	    {
              if(xprdeTmp->Id ==  iId)
              {
                  nIconIndex = n;
                  break;
              }
              n++;
              xprdeTmp++;
	    }
	    if (nIconIndex < 0)
	    {
	      WARN("resource id %d not found\n", iId);
	      goto end;		/* failure */
	    }
	  }
	  else
	  {
	    /* check nIconIndex to be in range */
	    if (nIconIndex >= iconDirCount)
	    {
	      WARN("nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount);
	      goto end;		/* failure */
	    }
	  }

	  /* assure we don't get too much */
	  if( nIcons > iconDirCount - nIconIndex )
	    nIcons = iconDirCount - nIconIndex;

	  /* starting from specified index */
	  xresent = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1) + nIconIndex;

	  for (i=0; i < nIcons; i++,xresent++)
	  {
	    const IMAGE_RESOURCE_DIRECTORY *resdir;

	    /* go down this resource entry, name */
            resdir = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)rootresdir + xresent->OffsetToDirectory);

	    /* default language (0) */
	    resdir = find_entry_default(resdir,rootresdir);
	    igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)resdir;

	    /* lookup address in mapped image for virtual address */
        igdata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, igdataent->OffsetToData, NULL);
        if (!igdata)
	    {
	      FIXME("no matching real address for icongroup!\n");
	      goto end;	/* failure */
	    }
	    pIconId[i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx1, cy1, flags);
            if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags);
	  }

	  if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICON),rootresdir)))
	  {
	    WARN("No Iconresourcedirectory!\n");
	    goto end;		/* failure */
	  }

	  for (i=0; i<nIcons; i++)
	  {
	    const IMAGE_RESOURCE_DIRECTORY *xresdir;
	    xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir);
            if( !xresdir )
            {
              WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
	      RetPtr[i]=0;
	      continue;
            }
	    xresdir = find_entry_default(xresdir, rootresdir);
	    idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir;

        idata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, idataent->OffsetToData, NULL);
        if (!idata)
	    {
	      WARN("no matching real address found for icondata!\n");
	      RetPtr[i]=0;
	      continue;
	    }
	    RetPtr[i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx1, cy1, flags);
            if (cx2 && cy2)
                RetPtr[++i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx2, cy2, flags);
	  }
	  ret = i;	/* return number of retrieved icons */
	}			/* if(sig == IMAGE_NT_SIGNATURE) */

end:
	UnmapViewOfFile(peimage);	/* success */
	return ret;
}
Beispiel #18
0
/*************************************************************************
 *	ICO_ExtractIconExW		[internal]
 *
 * NOTES
 *  nIcons = 0: returns number of Icons in file
 *
 * returns
 *  invalid file: -1
 *  failure:0;
 *  success: number of icons in file (nIcons = 0) or nr of icons retrieved
 */
static UINT ICO_ExtractIconExW(
	LPCWSTR lpszExeFileName,
	HICON * RetPtr,
	INT nIconIndex,
	UINT nIcons,
	UINT cxDesired,
	UINT cyDesired,
	UINT *pIconId,
	UINT flags)
{
	UINT		ret = 0;
	UINT		cx1, cx2, cy1, cy2;
	LPBYTE		pData;
	DWORD		sig;
	HANDLE		hFile;
	UINT16		iconDirCount = 0; //,iconCount = 0;
	LPBYTE		peimage;
	HANDLE		fmapping;
	DWORD		fsizeh,fsizel;
        WCHAR		szExePath[MAX_PATH];
        DWORD		dwSearchReturn;

	TRACE("%s, %d, %d %p 0x%08x\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons, pIconId, flags);

        dwSearchReturn = SearchPathW(NULL, lpszExeFileName, NULL, sizeof(szExePath) / sizeof(szExePath[0]), szExePath, NULL);
        if ((dwSearchReturn == 0) || (dwSearchReturn > sizeof(szExePath) / sizeof(szExePath[0])))
        {
            WARN("File %s not found or path too long\n", debugstr_w(lpszExeFileName));
            return -1;
        }

	hFile = CreateFileW(szExePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
	if (hFile == INVALID_HANDLE_VALUE) return ret;
	fsizel = GetFileSize(hFile,&fsizeh);

	/* Map the file */
	fmapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
	CloseHandle(hFile);
	if (!fmapping)
	{
	  WARN("CreateFileMapping error %ld\n", GetLastError() );
	  return 0xFFFFFFFF;
	}

	if (!(peimage = MapViewOfFile(fmapping, FILE_MAP_READ, 0, 0, 0)))
	{
	  WARN("MapViewOfFile error %ld\n", GetLastError() );
	  CloseHandle(fmapping);
	  return 0xFFFFFFFF;
	}
	CloseHandle(fmapping);

	cx1 = LOWORD(cxDesired);
	cx2 = HIWORD(cxDesired);
	cy1 = LOWORD(cyDesired);
	cy2 = HIWORD(cyDesired);

	if (pIconId) /* Invalidate first icon identifier */
		*pIconId = 0xFFFFFFFF;

	if (!pIconId) /* if no icon identifier array present use the icon handle array as intermediate storage */
	  pIconId = (UINT*)RetPtr;

	sig = USER32_GetResourceTable(peimage, fsizel, &pData);

/* ico file or NE exe/dll*/
#if 0
	if (sig==IMAGE_OS2_SIGNATURE || sig==1) /* .ICO file */
	{
	  BYTE		*pCIDir = 0;
	  NE_TYPEINFO	*pTInfo = (NE_TYPEINFO*)(pData + 2);
	  NE_NAMEINFO	*pIconStorage = NULL;
	  NE_NAMEINFO	*pIconDir = NULL;
	  LPicoICONDIR	lpiID = NULL;

	  TRACE("-- OS2/icon Signature (0x%08lx)\n", sig);

	  if (pData == (BYTE*)-1)
	  {
	    pCIDir = ICO_GetIconDirectory(peimage, &lpiID, &uSize);	/* check for .ICO file */
	    if (pCIDir)
	    {
	      iconDirCount = 1; iconCount = lpiID->idCount;
	      TRACE("-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);
	    }
	  }
	  else while (pTInfo->type_id && !(pIconStorage && pIconDir))
	  {
	    if (pTInfo->type_id == NE_RSCTYPE_GROUP_ICON)	/* find icon directory and icon repository */
	    {
	      iconDirCount = pTInfo->count;
	      pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
	      TRACE("\tfound directory - %i icon families\n", iconDirCount);
	    }
	    if (pTInfo->type_id == NE_RSCTYPE_ICON)
	    {
	      iconCount = pTInfo->count;
	      pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
	      TRACE("\ttotal icons - %i\n", iconCount);
	    }
	    pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
	  }

	  if ((pIconStorage && pIconDir) || lpiID)	  /* load resources and create icons */
	  {
	    if (nIcons == 0)
	    {
	      ret = iconDirCount;
	      if (lpiID && pCIDir)	/* *.ico file, deallocate heap pointer*/
	        HeapFree(GetProcessHeap(), 0, pCIDir);
	    }
	    else if (nIconIndex < iconDirCount)
	    {
	      UINT16   i, icon;
	      if (nIcons > iconDirCount - nIconIndex)
	        nIcons = iconDirCount - nIconIndex;

	      for (i = 0; i < nIcons; i++)
	      {
	        /* .ICO files have only one icon directory */
	        if (lpiID == NULL)	/* not *.ico */
	          pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex, *(WORD*)pData, &uSize);
	        pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, (i & 1) ? cx2 : cx1, (i & 1) ? cy2 : cy1, flags);
	      }
	      if (lpiID && pCIDir)	/* *.ico file, deallocate heap pointer*/
	        HeapFree(GetProcessHeap(), 0, pCIDir);

	      for (icon = 0; icon < nIcons; icon++)
	      {
	        pCIDir = NULL;
	        if (lpiID)
	          pCIDir = ICO_LoadIcon(peimage, lpiID->idEntries + (int)pIconId[icon], &uSize);
	        else
	          for (i = 0; i < iconCount; i++)
	            if (pIconStorage[i].id == ((int)pIconId[icon] | 0x8000) )
	              pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize);

	        if (pCIDir)
	          RetPtr[icon] = (HICON)CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
	                                                         (icon & 1) ? cx2 : cx1, (icon & 1) ? cy2 : cy1, flags);
	        else
	          RetPtr[icon] = 0;
	      }
	      ret = icon;	/* return number of retrieved icons */
	    }
	  }
	}
/* end ico file */

/* exe/dll */
	else if( sig == IMAGE_NT_SIGNATURE )
#endif
	if( sig == IMAGE_NT_SIGNATURE )
	{
	  LPBYTE		idata,igdata;
	  PIMAGE_DOS_HEADER	dheader;
	  PIMAGE_NT_HEADERS	pe_header;
	  PIMAGE_SECTION_HEADER	pe_sections;
	  const IMAGE_RESOURCE_DIRECTORY *rootresdir,*iconresdir,*icongroupresdir;
	  const IMAGE_RESOURCE_DATA_ENTRY *idataent,*igdataent;
	  const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
	  UINT	i, j;

	  dheader = (PIMAGE_DOS_HEADER)peimage;
	  pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew);	  /* it is a pe header, USER32_GetResourceTable checked that */
	  pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER)
	                                        + pe_header->FileHeader.SizeOfOptionalHeader);
	  rootresdir = NULL;

	  /* search for the root resource directory */
	  for (i=0;i<pe_header->FileHeader.NumberOfSections;i++)
	  {
	    if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
	      continue;
	    if (fsizel < pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData) {
              FIXME("File %s too short (section is at %ld bytes, real size is %ld)\n",
		      debugstr_w(lpszExeFileName),
		      pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData,
		      fsizel
	      );
	      goto end;
	    }
	    /* FIXME: doesn't work when the resources are not in a separate section */
	    if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress)
	    {
	      rootresdir = (PIMAGE_RESOURCE_DIRECTORY)(peimage+pe_sections[i].PointerToRawData);
	      break;
	    }
	  }

	  if (!rootresdir)
	  {
	    WARN("haven't found section for resource directory.\n");
	    goto end;		/* failure */
	  }

	  /* search for the group icon directory */
	  if (!(icongroupresdir = find_entry_by_id(rootresdir, LOWORD(RT_GROUP_ICON), rootresdir)))
	  {
	    WARN("No Icongroupresourcedirectory!\n");
	    goto end;		/* failure */
	  }
	  iconDirCount = icongroupresdir->NumberOfNamedEntries + icongroupresdir->NumberOfIdEntries;

	  /* only number of icons requested */
	  if( !pIconId )
	  {
	    ret = iconDirCount;
	    goto end;		/* success */
	  }

	  if( nIconIndex < 0 )
	  {
	    /* search resource id */
	    int n = 0;
	    int iId = abs(nIconIndex);
	    const IMAGE_RESOURCE_DIRECTORY_ENTRY* xprdeTmp = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1);

	    while(n<iconDirCount && xprdeTmp)
	    {
              if(xprdeTmp->Id ==  iId)
              {
                  nIconIndex = n;
                  break;
              }
              n++;
              xprdeTmp++;
	    }
	    if (nIconIndex < 0)
	    {
	      WARN("resource id %d not found\n", iId);
	      goto end;		/* failure */
	    }
	  }
	  else
	  {
	    /* check nIconIndex to be in range */
	    if (nIconIndex >= iconDirCount)
	    {
	      WARN("nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount);
	      goto end;		/* failure */
	    }
	  }

	  /* assure we don't get too much */
	  if( nIcons > iconDirCount - nIconIndex )
	    nIcons = iconDirCount - nIconIndex;

	  /* starting from specified index */
	  xresent = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1) + nIconIndex;

	  for (i=0; i < nIcons; i++,xresent++)
	  {
	    const IMAGE_RESOURCE_DIRECTORY *resdir;

	    /* go down this resource entry, name */
	    resdir = (const IMAGE_RESOURCE_DIRECTORY*)((const char *)rootresdir+(xresent->OffsetToDirectory));

	    /* default language (0) */
	    resdir = find_entry_default(resdir,rootresdir);
	    igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)resdir;

	    /* lookup address in mapped image for virtual address */
	    igdata = NULL;

	    for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
	    {
	      if (igdataent->OffsetToData < pe_sections[j].VirtualAddress)
	        continue;
	      if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
	        continue;

	      if (igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData+igdataent->Size > fsizel) {
	        FIXME("overflow in PE lookup (%s has len %ld, have offset %ld), short file?\n", debugstr_w(lpszExeFileName), fsizel,
	        	   igdataent->OffsetToData - pe_sections[j].VirtualAddress + pe_sections[j].PointerToRawData + igdataent->Size);
	        goto end; /* failure */
	      }
	      igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
	    }

	    if (!igdata)
	    {
	      FIXME("no matching real address for icongroup!\n");
	      goto end;	/* failure */
	    }
	    pIconId[i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx1, cy1, flags);
	        if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags);
	  }

	  if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICON),rootresdir)))
	  {
	    WARN("No Iconresourcedirectory!\n");
	    goto end;		/* failure */
	  }

	  for (i=0; i<nIcons; i++)
	  {
	    const IMAGE_RESOURCE_DIRECTORY *xresdir;
	    xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir);
	    if (!xresdir)
	    {
	      WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
	      RetPtr[i]=0;
	      continue;
	    }
	    xresdir = find_entry_default(xresdir, rootresdir);
	    if (!xresdir)
	    {
	      WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
	      RetPtr[i]=0;
	      continue;
	    }
	    idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir;
	    idata = NULL;

	    /* map virtual to address in image */
	    for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
	    {
	      if (idataent->OffsetToData < pe_sections[j].VirtualAddress)
	        continue;
	      if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
	        continue;
	      idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
	    }
	    if (!idata)
	    {
	      WARN("no matching real address found for icondata!\n");
	      RetPtr[i]=0;
	      continue;
	    }
	    RetPtr[i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx1, cy1, flags);
            if (cx2 && cy2)
                RetPtr[++i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx2, cy2, flags);
	  }
	  ret = i;	/* return number of retrieved icons */
	}			/* if(sig == IMAGE_NT_SIGNATURE) */

end:
	UnmapViewOfFile(peimage);	/* success */
	return ret;
}