OSDN Git Service

* loadlib.h: New header implementing safe LoadLibrary calls.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / utils / module_info.cc
1 /* module_info.cc
2
3    Copyright 1999,2000,2001,2010 Red Hat, Inc.
4
5    Written by Egor Duda <deo@logos-m.ru>
6
7 This file is part of Cygwin.
8
9 This software is a copyrighted work licensed under the terms of the
10 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
11 details. */
12
13 #include <stdlib.h>
14 #include <windows.h>
15 #include <psapi.h>
16 #include "loadlib.h"
17
18 static int psapi_loaded = 0;
19 static HMODULE psapi_module_handle = NULL;
20
21 typedef BOOL WINAPI (tf_EnumProcessModules) (HANDLE, HMODULE *, DWORD,
22                                              LPDWORD);
23 typedef BOOL WINAPI (tf_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
24                                                DWORD);
25 typedef DWORD WINAPI (tf_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR,
26                                                 DWORD);
27
28 static tf_EnumProcessModules *psapi_EnumProcessModules = NULL;
29 static tf_GetModuleInformation *psapi_GetModuleInformation = NULL;
30 static tf_GetModuleFileNameExA *psapi_GetModuleFileNameExA = NULL;
31
32 /* Returns full name of Dll, which is loaded by hProcess at BaseAddress.
33    Uses psapi.dll. */
34
35 char *
36 psapi_get_module_name (HANDLE hProcess, DWORD BaseAddress)
37 {
38   DWORD len;
39   MODULEINFO mi;
40   unsigned int i;
41   HMODULE dh_buf[1];
42   HMODULE *DllHandle = dh_buf;
43   DWORD cbNeeded;
44   BOOL ok;
45
46   char name_buf[MAX_PATH + 1];
47
48   if (!psapi_loaded ||
49       psapi_EnumProcessModules == NULL ||
50       psapi_GetModuleInformation == NULL ||
51       psapi_GetModuleFileNameExA == NULL)
52     {
53       if (psapi_loaded)
54         goto failed;
55       psapi_loaded = 1;
56       psapi_module_handle = LoadLibrary ("psapi.dll");
57       if (!psapi_module_handle)
58         goto failed;
59       psapi_EnumProcessModules =
60         (tf_EnumProcessModules *) GetProcAddress (psapi_module_handle,
61                                                   "EnumProcessModules");
62       psapi_GetModuleInformation =
63         (tf_GetModuleInformation *) GetProcAddress (psapi_module_handle,
64                                                     "GetModuleInformation");
65       psapi_GetModuleFileNameExA =
66         (tf_GetModuleFileNameExA *) GetProcAddress (psapi_module_handle,
67                                                     "GetModuleFileNameExA");
68       if (psapi_EnumProcessModules == NULL
69           || psapi_GetModuleInformation == NULL
70           || psapi_GetModuleFileNameExA == NULL)
71         goto failed;
72     }
73
74   ok = (*psapi_EnumProcessModules) (hProcess,
75                                     DllHandle, sizeof (HMODULE), &cbNeeded);
76
77   if (!ok || !cbNeeded)
78     goto failed;
79   DllHandle = (HMODULE *) malloc (cbNeeded);
80   if (!DllHandle)
81     goto failed;
82   ok = (*psapi_EnumProcessModules) (hProcess, DllHandle, cbNeeded, &cbNeeded);
83   if (!ok)
84     {
85       free (DllHandle);
86       goto failed;
87     }
88
89   for (i = 0; i < cbNeeded / sizeof (HMODULE); i++)
90     {
91       if (!(*psapi_GetModuleInformation) (hProcess,
92                                           DllHandle[i], &mi, sizeof (mi)))
93         {
94           free (DllHandle);
95           goto failed;
96         }
97
98       len = (*psapi_GetModuleFileNameExA) (hProcess,
99                                            DllHandle[i], name_buf, MAX_PATH);
100       if (len == 0)
101         {
102           free (DllHandle);
103           goto failed;
104         }
105
106       if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
107         {
108           free (DllHandle);
109           return strdup (name_buf);
110         }
111     }
112
113 failed:
114   return NULL;
115 }