OSDN Git Service

c0e7079cc3335a3df623740943ef370b0ef6dbdb
[pf3gnuchains/pf3gnuchains4x.git] / winsup / utils / module_info.cc
1 /* module_info.cc
2
3    Copyright 1999,2000,2001 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
17 static int psapi_loaded = 0;
18 static HMODULE psapi_module_handle = NULL;
19
20 typedef BOOL WINAPI (tf_EnumProcessModules) (HANDLE, HMODULE *, DWORD,
21                                              LPDWORD);
22 typedef BOOL WINAPI (tf_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
23                                                DWORD);
24 typedef DWORD WINAPI (tf_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR,
25                                                 DWORD);
26
27 static tf_EnumProcessModules *psapi_EnumProcessModules = NULL;
28 static tf_GetModuleInformation *psapi_GetModuleInformation = NULL;
29 static tf_GetModuleFileNameExA *psapi_GetModuleFileNameExA = NULL;
30
31 /* Returns full name of Dll, which is loaded by hProcess at BaseAddress.
32    Uses psapi.dll. */
33
34 char *
35 psapi_get_module_name (HANDLE hProcess, DWORD BaseAddress)
36 {
37   DWORD len;
38   MODULEINFO mi;
39   unsigned int i;
40   HMODULE dh_buf[1];
41   HMODULE *DllHandle = dh_buf;
42   DWORD cbNeeded;
43   BOOL ok;
44
45   char name_buf[MAX_PATH + 1];
46
47   if (!psapi_loaded ||
48       psapi_EnumProcessModules == NULL ||
49       psapi_GetModuleInformation == NULL ||
50       psapi_GetModuleFileNameExA == NULL)
51     {
52       if (psapi_loaded)
53         goto failed;
54       psapi_loaded = 1;
55       psapi_module_handle = LoadLibrary ("psapi.dll");
56       if (!psapi_module_handle)
57         goto failed;
58       psapi_EnumProcessModules =
59         (tf_EnumProcessModules *) GetProcAddress (psapi_module_handle,
60                                                   "EnumProcessModules");
61       psapi_GetModuleInformation =
62         (tf_GetModuleInformation *) GetProcAddress (psapi_module_handle,
63                                                     "GetModuleInformation");
64       psapi_GetModuleFileNameExA =
65         (tf_GetModuleFileNameExA *) GetProcAddress (psapi_module_handle,
66                                                     "GetModuleFileNameExA");
67       if (psapi_EnumProcessModules == NULL
68           || psapi_GetModuleInformation == NULL
69           || psapi_GetModuleFileNameExA == NULL)
70         goto failed;
71     }
72
73   ok = (*psapi_EnumProcessModules) (hProcess,
74                                     DllHandle, sizeof (HMODULE), &cbNeeded);
75
76   if (!ok || !cbNeeded)
77     goto failed;
78   DllHandle = (HMODULE *) malloc (cbNeeded);
79   if (!DllHandle)
80     goto failed;
81   ok = (*psapi_EnumProcessModules) (hProcess, DllHandle, cbNeeded, &cbNeeded);
82   if (!ok)
83     {
84       free (DllHandle);
85       goto failed;
86     }
87
88   for (i = 0; i < cbNeeded / sizeof (HMODULE); i++)
89     {
90       if (!(*psapi_GetModuleInformation) (hProcess,
91                                           DllHandle[i], &mi, sizeof (mi)))
92         {
93           free (DllHandle);
94           goto failed;
95         }
96
97       len = (*psapi_GetModuleFileNameExA) (hProcess,
98                                            DllHandle[i], name_buf, MAX_PATH);
99       if (len == 0)
100         {
101           free (DllHandle);
102           goto failed;
103         }
104
105       if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
106         {
107           free (DllHandle);
108           return strdup (name_buf);
109         }
110     }
111
112 failed:
113   return NULL;
114 }