access.c 7.05 KB
Newer Older
1 2 3 4
/*
 *	IMAGEHLP library
 *
 *	Copyright 1998	Patrik Stridvall
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 20
 */

21
#include <stdarg.h>
22
#include <string.h>
23
#include "windef.h"
24 25
#include "winbase.h"
#include "winnt.h"
26
#include "winternl.h"
27
#include "winerror.h"
28
#include "wine/debug.h"
29 30
#include "imagehlp.h"

31
WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
32

33 34 35
/***********************************************************************
 *           Data
 */
36
static LIST_ENTRY image_list = { &image_list, &image_list };
37

38

39
/***********************************************************************
40
 *		GetImageConfigInformation (IMAGEHLP.@)
41
 */
42 43 44
BOOL WINAPI GetImageConfigInformation(
  PLOADED_IMAGE LoadedImage,
  PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
45
{
46
  FIXME("(%p, %p): stub\n",
47 48 49 50 51 52 53
    LoadedImage, ImageConfigInformation
  );
  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  return FALSE;
}

/***********************************************************************
54
 *		GetImageUnusedHeaderBytes (IMAGEHLP.@)
55
 */
56 57
DWORD WINAPI GetImageUnusedHeaderBytes(
  PLOADED_IMAGE LoadedImage,
58 59
  LPDWORD SizeUnusedHeaderBytes)
{
60
  FIXME("(%p, %p): stub\n",
61 62 63 64 65 66 67
    LoadedImage, SizeUnusedHeaderBytes
  );
  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  return 0;
}

/***********************************************************************
68
 *		ImageLoad (IMAGEHLP.@)
69
 */
70
PLOADED_IMAGE WINAPI ImageLoad(PCSTR dll_name, PCSTR dll_path)
71
{
72 73 74 75
    LOADED_IMAGE *image;

    TRACE("(%s, %s)\n", dll_name, dll_path);

76
    image = HeapAlloc(GetProcessHeap(), 0, sizeof(*image));
77 78 79 80
    if (!image) return NULL;

    if (!MapAndLoad(dll_name, dll_path, image, TRUE, TRUE))
    {
81
        HeapFree(GetProcessHeap(), 0, image);
82 83 84 85 86 87 88 89 90
        return NULL;
    }

    image->Links.Flink = image_list.Flink;
    image->Links.Blink = &image_list;
    image_list.Flink->Blink = &image->Links;
    image_list.Flink = &image->Links;

    return image;
91 92 93
}

/***********************************************************************
94
 *		ImageUnload (IMAGEHLP.@)
95
 */
96
BOOL WINAPI ImageUnload(PLOADED_IMAGE loaded_image)
97
{
98 99
    LIST_ENTRY *entry, *mark;
    PLOADED_IMAGE image;
100

101 102 103 104 105
    TRACE("(%p)\n", loaded_image);

    /* FIXME: do we really need to check this? */
    mark = &image_list;
    for (entry = mark->Flink; entry != mark; entry = entry->Flink)
106
    {
107 108 109
        image = CONTAINING_RECORD(entry, LOADED_IMAGE, Links);
        if (image == loaded_image)
            break;
110 111
    }

112
    if (entry == mark)
113
    {
114 115 116
        /* Not found */
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
117 118
    }

119 120
    entry->Blink->Flink = entry->Flink;
    entry->Flink->Blink = entry->Blink;
121

122
    UnMapAndLoad(loaded_image);
123
    HeapFree(GetProcessHeap(), 0, loaded_image);
124

125
    return TRUE;
126 127 128
}

/***********************************************************************
129
 *		MapAndLoad (IMAGEHLP.@)
130
 */
131
BOOL WINAPI MapAndLoad(PCSTR pszImageName, PCSTR pszDllPath, PLOADED_IMAGE pLoadedImage,
132
                       BOOL bDotDll, BOOL bReadOnly)
133
{
134 135 136 137 138
    CHAR szFileName[MAX_PATH];
    HANDLE hFile = INVALID_HANDLE_VALUE;
    HANDLE hFileMapping = NULL;
    PVOID mapping = NULL;
    PIMAGE_NT_HEADERS pNtHeader = NULL;
139

140 141
    TRACE("(%s, %s, %p, %d, %d)\n",
          pszImageName, pszDllPath, pLoadedImage, bDotDll, bReadOnly);
142

143 144
    if (!SearchPathA(pszDllPath, pszImageName, bDotDll ? ".DLL" : ".EXE",
                     sizeof(szFileName), szFileName, NULL))
145
    {
146 147
        SetLastError(ERROR_FILE_NOT_FOUND);
        goto Error;
148 149
    }

150 151 152
    hFile = CreateFileA(szFileName,
                        GENERIC_READ | (bReadOnly ? 0 : GENERIC_WRITE),
                        FILE_SHARE_READ,
153 154
                        NULL, OPEN_EXISTING, 0, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
155
    {
156 157
        WARN("CreateFile: Error = %d\n", GetLastError());
        goto Error;
158 159
    }

160 161 162
    hFileMapping = CreateFileMappingA(hFile, NULL, 
                                      (bReadOnly ? PAGE_READONLY : PAGE_READWRITE) | SEC_COMMIT,
                                      0, 0, NULL);
163
    if (!hFileMapping)
164
    {
165 166
        WARN("CreateFileMapping: Error = %d\n", GetLastError());
        goto Error;
167 168
    }

169
    mapping = MapViewOfFile(hFileMapping, bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, 0, 0);
170 171 172 173 174 175
    CloseHandle(hFileMapping);
    if (!mapping)
    {
        WARN("MapViewOfFile: Error = %d\n", GetLastError());
        goto Error;
    }
176

177 178 179 180 181 182
    if (!(pNtHeader = RtlImageNtHeader(mapping)))
    {
        WARN("Not an NT header\n");
        UnmapViewOfFile(mapping);
        goto Error;
    }
183

184 185 186 187 188 189 190 191 192 193
    pLoadedImage->ModuleName       = HeapAlloc(GetProcessHeap(), 0,
                                               strlen(szFileName) + 1);
    if (pLoadedImage->ModuleName) strcpy(pLoadedImage->ModuleName, szFileName);
    pLoadedImage->hFile            = hFile;
    pLoadedImage->MappedAddress    = mapping;
    pLoadedImage->FileHeader       = pNtHeader;
    pLoadedImage->Sections         = (PIMAGE_SECTION_HEADER)
        ((LPBYTE) &pNtHeader->OptionalHeader +
         pNtHeader->FileHeader.SizeOfOptionalHeader);
    pLoadedImage->NumberOfSections = pNtHeader->FileHeader.NumberOfSections;
194
    pLoadedImage->SizeOfImage      = GetFileSize(hFile, NULL);
195 196
    pLoadedImage->Characteristics  = pNtHeader->FileHeader.Characteristics;
    pLoadedImage->LastRvaSection   = pLoadedImage->Sections;
197

198 199
    pLoadedImage->fSystemImage     = FALSE; /* FIXME */
    pLoadedImage->fDOSImage        = FALSE; /* FIXME */
200

201 202
    pLoadedImage->Links.Flink      = &pLoadedImage->Links;
    pLoadedImage->Links.Blink      = &pLoadedImage->Links;
203

204
    return TRUE;
205 206

Error:
207 208
    if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
    return FALSE;
209 210 211
}

/***********************************************************************
212
 *		SetImageConfigInformation (IMAGEHLP.@)
213
 */
214 215 216
BOOL WINAPI SetImageConfigInformation(
  PLOADED_IMAGE LoadedImage,
  PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
217
{
218
  FIXME("(%p, %p): stub\n",
219 220 221 222 223 224 225
    LoadedImage, ImageConfigInformation
  );
  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  return FALSE;
}

/***********************************************************************
226
 *		UnMapAndLoad (IMAGEHLP.@)
227
 */
228
BOOL WINAPI UnMapAndLoad(PLOADED_IMAGE pLoadedImage)
229
{
230 231 232 233 234
    HeapFree(GetProcessHeap(), 0, pLoadedImage->ModuleName);
    /* FIXME: MSDN states that a new checksum is computed and stored into the file */
    if (pLoadedImage->MappedAddress) UnmapViewOfFile(pLoadedImage->MappedAddress);
    if (pLoadedImage->hFile != INVALID_HANDLE_VALUE) CloseHandle(pLoadedImage->hFile);
    return TRUE;
235
}