...
1
2
3 package winobjdir
4
5 import (
6 "path/filepath"
7 "syscall"
8 "unsafe"
9
10 "github.com/Microsoft/hcsshim/internal/winapi"
11 )
12
13 const bufferSize = 1024
14
15
16
17 func EnumerateNTObjectDirectory(ntObjDirPath string) ([]string, error) {
18 var (
19 handle uintptr
20 oa winapi.ObjectAttributes
21
22 context uint32
23 returnLength uint32
24 buffer [bufferSize]byte
25 result []string
26 )
27
28 path := filepath.Clean(ntObjDirPath)
29 fsNtPath := filepath.FromSlash(path)
30
31 pathUnicode, err := winapi.NewUnicodeString(fsNtPath)
32 if err != nil {
33 return nil, err
34 }
35
36 oa.Length = unsafe.Sizeof(oa)
37 oa.ObjectName = pathUnicode
38
39
40 status := winapi.NtOpenDirectoryObject(
41 &handle,
42 winapi.FILE_LIST_DIRECTORY,
43 &oa,
44 )
45
46 if !winapi.NTSuccess(status) {
47 return nil, winapi.RtlNtStatusToDosError(status)
48 }
49
50 defer syscall.Close(syscall.Handle(handle))
51
52 for {
53
54
55
56 status = winapi.NtQueryDirectoryObject(
57 handle,
58 &buffer[0],
59 bufferSize,
60 false,
61 false,
62 &context,
63 &returnLength,
64 )
65
66 if !winapi.NTSuccess(status) && status != winapi.STATUS_MORE_ENTRIES {
67 if status == winapi.STATUS_NO_MORE_ENTRIES {
68 break
69 }
70 return nil, winapi.RtlNtStatusToDosError(status)
71 }
72 dirInfo := (*winapi.ObjectDirectoryInformation)(unsafe.Pointer(&buffer[0]))
73 index := 1
74 for {
75 if dirInfo == nil || dirInfo.Name.Length == 0 {
76 break
77 }
78 result = append(result, dirInfo.Name.String())
79 size := unsafe.Sizeof(winapi.ObjectDirectoryInformation{}) * uintptr(index)
80 dirInfo = (*winapi.ObjectDirectoryInformation)(unsafe.Pointer(&buffer[size]))
81 index++
82 }
83 }
84
85 return result, nil
86 }
87
View as plain text