@@ -9,8 +9,10 @@ import (
9
9
"fmt"
10
10
"io"
11
11
"os"
12
+ "reflect"
12
13
"strings"
13
14
"syscall"
15
+ "unicode/utf16"
14
16
"unsafe"
15
17
16
18
"github.com/shirou/gopsutil/v3/cpu"
@@ -654,7 +656,79 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
654
656
}
655
657
656
658
func (p * Process ) OpenFilesWithContext (ctx context.Context ) ([]OpenFilesStat , error ) {
657
- return nil , common .ErrNotImplementedError
659
+ files := make ([]OpenFilesStat , 0 )
660
+ fileExists := make (map [string ]bool )
661
+
662
+ process , err := windows .OpenProcess (common .ProcessQueryInformation , false , uint32 (p .Pid ))
663
+ if err != nil {
664
+ return nil , err
665
+ }
666
+
667
+ buffer := make ([]byte , 1024 )
668
+ var size uint32
669
+
670
+ st := common .CallWithExpandingBuffer (
671
+ func () common.NtStatus {
672
+ return common .NtQuerySystemInformation (
673
+ common .SystemExtendedHandleInformationClass ,
674
+ & buffer [0 ],
675
+ uint32 (len (buffer )),
676
+ & size ,
677
+ )
678
+ },
679
+ & buffer ,
680
+ & size ,
681
+ )
682
+ if st .IsError () {
683
+ return nil , st .Error ()
684
+ }
685
+
686
+ handlesList := (* common .SystemExtendedHandleInformation )(unsafe .Pointer (& buffer [0 ]))
687
+ handles := make ([]common.SystemExtendedHandleTableEntryInformation , int (handlesList .NumberOfHandles ))
688
+ hdr := (* reflect .SliceHeader )(unsafe .Pointer (& handles ))
689
+ hdr .Data = uintptr (unsafe .Pointer (& handlesList .Handles [0 ]))
690
+
691
+ currentProcess , err := windows .GetCurrentProcess ()
692
+ if err != nil {
693
+ return nil , err
694
+ }
695
+
696
+ for _ , handle := range handles {
697
+ var file uintptr
698
+ if int32 (handle .UniqueProcessId ) != p .Pid {
699
+ continue
700
+ }
701
+ if windows .DuplicateHandle (process , windows .Handle (handle .HandleValue ), currentProcess , (* windows .Handle )(& file ),
702
+ 0 , true , windows .DUPLICATE_SAME_ACCESS ) != nil {
703
+ continue
704
+ }
705
+ fileType , _ := windows .GetFileType (windows .Handle (file ))
706
+ if fileType != windows .FILE_TYPE_DISK {
707
+ continue
708
+ }
709
+
710
+ var buf [syscall .MAX_LONG_PATH ]uint16
711
+ n , err := windows .GetFinalPathNameByHandle (windows .Handle (file ), & buf [0 ], syscall .MAX_LONG_PATH , 0 )
712
+ if err != nil {
713
+ continue
714
+ }
715
+
716
+ fileName := string (utf16 .Decode (buf [:n ]))
717
+ fileInfo , _ := os .Stat (fileName )
718
+ if fileInfo .IsDir () {
719
+ continue
720
+ }
721
+
722
+ if _ , exists := fileExists [fileName ]; ! exists {
723
+ files = append (files , OpenFilesStat {
724
+ Path : fileName ,
725
+ Fd : uint64 (file ),
726
+ })
727
+ fileExists [fileName ] = true
728
+ }
729
+ }
730
+
731
+ return files , nil
658
732
}
659
733
660
734
func (p * Process ) ConnectionsWithContext (ctx context.Context ) ([]net.ConnectionStat , error ) {
0 commit comments