@@ -20,6 +20,13 @@ import (
20
20
// OSMetadata includes any additional OS-specific information that may be
21
21
// obtained during the retrieval of a given Entry.
22
22
type OSMetadata interface {
23
+ // GetModule returns the entry's module name.
24
+ //
25
+ // It returns ("", nil) if no entry is found. As of 2023-01-27, any returned
26
+ // error is silently discarded by its sole caller in portlist_windows.go and
27
+ // treated equivalently as returning ("", nil), but this may change in the
28
+ // future. An error should only be returned in casees that are worthy of
29
+ // being logged at least.
23
30
GetModule () (string , error )
24
31
}
25
32
@@ -224,7 +231,13 @@ type moduleInfoConstraint interface {
224
231
_MIB_TCPROW_OWNER_MODULE | _MIB_TCP6ROW_OWNER_MODULE
225
232
}
226
233
227
- // moduleInfo may return "", nil indicating a successful call but with empty data
234
+ // moduleInfo implements OSMetadata.GetModule. It calls
235
+ // getOwnerModuleFromTcpEntry or getOwnerModuleFromTcp6Entry.
236
+ //
237
+ // See
238
+ // https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getownermodulefromtcpentry
239
+ //
240
+ // It may return "", nil indicating a successful call but with empty data.
228
241
func moduleInfo [entryType moduleInfoConstraint ](entry * entryType , proc * windows.LazyProc ) (string , error ) {
229
242
var buf []byte
230
243
var desiredLen uint32
@@ -241,28 +254,36 @@ func moduleInfo[entryType moduleInfoConstraint](entry *entryType, proc *windows.
241
254
if err == windows .ERROR_SUCCESS {
242
255
break
243
256
}
257
+ if err == windows .ERROR_NOT_FOUND {
258
+ return "" , nil
259
+ }
244
260
if err != windows .ERROR_INSUFFICIENT_BUFFER {
245
261
return "" , err
246
262
}
247
-
263
+ if desiredLen > 1 << 20 {
264
+ // Sanity check before allocating too much.
265
+ return "" , nil
266
+ }
248
267
buf = make ([]byte , desiredLen )
249
268
addr = unsafe .Pointer (& buf [0 ])
250
269
}
251
-
252
- basicInfo := ( * _TCPIP_OWNER_MODULE_BASIC_INFO )( addr )
253
- // GetOwnerModuleFromTcp*Entry is apparently using nil as an empty result
254
- // under certain circumstances , so we check all the things.
255
- if basicInfo == nil || basicInfo . moduleName == nil {
270
+ if addr == nil {
271
+ // GetOwnerModuleFromTcp*Entry can apparently return ERROR_SUCCESS
272
+ // (NO_ERROR) on the first call without the usual first
273
+ // ERROR_INSUFFICIENT_BUFFER result. Windows said success , so interpret
274
+ // that was sucessfully not having data.
256
275
return "" , nil
257
276
}
258
-
277
+ basicInfo := ( * _TCPIP_OWNER_MODULE_BASIC_INFO )( addr )
259
278
return windows .UTF16PtrToString (basicInfo .moduleName ), nil
260
279
}
261
280
281
+ // GetModule implements OSMetadata.
262
282
func (m * _MIB_TCPROW_OWNER_MODULE ) GetModule () (string , error ) {
263
283
return moduleInfo (m , getOwnerModuleFromTcpEntry )
264
284
}
265
285
286
+ // GetModule implements OSMetadata.
266
287
func (m * _MIB_TCP6ROW_OWNER_MODULE ) GetModule () (string , error ) {
267
288
return moduleInfo (m , getOwnerModuleFromTcp6Entry )
268
289
}
0 commit comments