24
24
#include < pedecoder.h>
25
25
#include < getproductversionnumber.h>
26
26
#include < dbgenginemetrics.h>
27
+ #include < arrayholder.h>
27
28
28
29
#ifndef FEATURE_PAL
29
30
#define PSAPI_VERSION 2
@@ -1052,6 +1053,57 @@ IsCoreClrWithGoodHeader(
1052
1053
return false ;
1053
1054
}
1054
1055
1056
+ static
1057
+ HMODULE*
1058
+ EnumProcessModulesInternal (
1059
+ HANDLE hProcess,
1060
+ DWORD *pCountModules)
1061
+ {
1062
+ *pCountModules = 0 ;
1063
+
1064
+ // Start with 1024 modules
1065
+ DWORD cbNeeded = sizeof (HMODULE) * 1024 ;
1066
+
1067
+ ArrayHolder<HMODULE> modules = new (nothrow) HMODULE[cbNeeded / sizeof (HMODULE)];
1068
+ if (modules == nullptr )
1069
+ {
1070
+ SetLastError (ERROR_OUTOFMEMORY);
1071
+ return nullptr ;
1072
+ }
1073
+
1074
+ if (!EnumProcessModules (hProcess, modules, cbNeeded, &cbNeeded))
1075
+ {
1076
+ return nullptr ;
1077
+ }
1078
+
1079
+ // If 1024 isn't enough, try the modules array size returned (cbNeeded)
1080
+ if (cbNeeded > (sizeof (HMODULE) * 1024 ))
1081
+ {
1082
+ modules = new (nothrow) HMODULE[cbNeeded / sizeof (HMODULE)];
1083
+ if (modules == nullptr )
1084
+ {
1085
+ SetLastError (ERROR_OUTOFMEMORY);
1086
+ return nullptr ;
1087
+ }
1088
+
1089
+ DWORD cbNeeded2;
1090
+ if (!EnumProcessModules (hProcess, modules, cbNeeded, &cbNeeded2))
1091
+ {
1092
+ return nullptr ;
1093
+ }
1094
+
1095
+ // The only way cbNeeded2 could change on the second call is if number of
1096
+ // modules loaded by the process changed in the small window between the
1097
+ // above EnumProcessModules calls. If this actually happens, then give
1098
+ // up on trying to get the whole module list and risk missing the coreclr
1099
+ // module.
1100
+ cbNeeded = min (cbNeeded, cbNeeded2);
1101
+ }
1102
+
1103
+ *pCountModules = cbNeeded / sizeof (HMODULE);
1104
+ return modules.Detach ();
1105
+ }
1106
+
1055
1107
// -----------------------------------------------------------------------------
1056
1108
// Public API.
1057
1109
//
@@ -1089,10 +1141,10 @@ EnumerateCLRs(
1089
1141
if (NULL == hProcess)
1090
1142
return E_FAIL;
1091
1143
1092
- // These shouldn 't be freed
1093
- HMODULE modules[ 1000 ] ;
1094
- DWORD cbNeeded ;
1095
- if (! EnumProcessModules (hProcess, modules, sizeof (modules), &cbNeeded) )
1144
+ // The modules in the array returned don 't need to be closed
1145
+ DWORD countModules ;
1146
+ ArrayHolder<HMODULE> modules = EnumProcessModulesInternal (hProcess, &countModules) ;
1147
+ if (modules == nullptr )
1096
1148
{
1097
1149
return HRESULT_FROM_WIN32 (GetLastError ());
1098
1150
}
@@ -1101,7 +1153,6 @@ EnumerateCLRs(
1101
1153
// count the number of coreclr.dll entries
1102
1154
//
1103
1155
DWORD count = 0 ;
1104
- DWORD countModules = cbNeeded/sizeof (HMODULE);
1105
1156
for (DWORD i = 0 ; i < countModules; i++)
1106
1157
{
1107
1158
if (IsCoreClrWithGoodHeader (hProcess, modules[i]))
@@ -1268,15 +1319,14 @@ GetRemoteModuleBaseAddress(
1268
1319
ThrowHR (E_FAIL);
1269
1320
}
1270
1321
1271
- // These shouldn 't be freed
1272
- HMODULE modules[ 1000 ] ;
1273
- DWORD cbNeeded ;
1274
- if (! EnumProcessModules (hProcess, modules, sizeof (modules), &cbNeeded) )
1322
+ // The modules in the array returned don 't need to be closed
1323
+ DWORD countModules ;
1324
+ ArrayHolder<HMODULE> modules = EnumProcessModulesInternal (hProcess, &countModules) ;
1325
+ if (modules == nullptr )
1275
1326
{
1276
1327
ThrowHR (HRESULT_FROM_WIN32 (GetLastError ()));
1277
1328
}
1278
1329
1279
- DWORD countModules = min (cbNeeded, sizeof (modules)) / sizeof (HMODULE);
1280
1330
for (DWORD i = 0 ; i < countModules; i++)
1281
1331
{
1282
1332
WCHAR modulePath[MAX_LONGPATH];
0 commit comments