2 * Copyright 2004, 2005 Martin Fuchs
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 // Martin Fuchs, 31.01.2004
36 #define CONSTRUCT_NTDLLFCT(x) x(TEXT("NTDLL"), #x)
38 typedef DWORD (__stdcall
* NTOBJECTOPENFUNCTIONS
)(HANDLE
*, DWORD
, OpenStruct
*);
42 : CONSTRUCT_NTDLLFCT(RtlInitAnsiString
),
43 CONSTRUCT_NTDLLFCT(RtlInitUnicodeString
),
44 CONSTRUCT_NTDLLFCT(RtlFreeAnsiString
),
45 CONSTRUCT_NTDLLFCT(RtlFreeUnicodeString
),
46 CONSTRUCT_NTDLLFCT(RtlAnsiStringToUnicodeString
),
47 CONSTRUCT_NTDLLFCT(RtlUnicodeStringToAnsiString
),
48 CONSTRUCT_NTDLLFCT(NtOpenDirectoryObject
),
49 CONSTRUCT_NTDLLFCT(NtQueryDirectoryObject
),
50 CONSTRUCT_NTDLLFCT(NtOpenFile
),
51 CONSTRUCT_NTDLLFCT(NtOpenSymbolicLinkObject
),
52 CONSTRUCT_NTDLLFCT(NtQuerySymbolicLinkObject
),
53 CONSTRUCT_NTDLLFCT(NtQueryObject
),
54 CONSTRUCT_NTDLLFCT(NtOpenMutant
),
55 CONSTRUCT_NTDLLFCT(NtOpenSection
),
56 CONSTRUCT_NTDLLFCT(NtOpenEvent
),
57 CONSTRUCT_NTDLLFCT(NtOpenEventPair
),
58 CONSTRUCT_NTDLLFCT(NtOpenIoCompletion
),
59 CONSTRUCT_NTDLLFCT(NtOpenSemaphore
),
60 CONSTRUCT_NTDLLFCT(NtOpenTimer
),
61 CONSTRUCT_NTDLLFCT(NtOpenKey
),
62 CONSTRUCT_NTDLLFCT(NtClose
),
63 CONSTRUCT_NTDLLFCT(NtOpenProcess
),
64 CONSTRUCT_NTDLLFCT(NtOpenThread
)
66 NTOBJECTOPENFUNCTIONS
* p
= _ObjectOpenFunctions
;
68 *p
++ = *NtOpenDirectoryObject
;
69 *p
++ = *NtOpenSymbolicLinkObject
;
71 *p
++ = *NtOpenSection
;
73 *p
++ = *NtOpenSemaphore
;
76 *p
++ = *NtOpenEventPair
;
77 *p
++ = *NtOpenIoCompletion
;
78 *p
++ = 0/*Device Object*/;
79 *p
++ = 0/*NtOpenFile*/;
80 *p
++ = 0/*CONTROLLER_OBJECT*/;
81 *p
++ = 0/*PROFILE_OBJECT*/;
82 *p
++ = 0/*TYPE_OBJECT*/;
83 *p
++ = 0/*DESKTOP_OBJECT*/;
84 *p
++ = 0/*WINDOWSTATION_OBJECT*/;
85 *p
++ = 0/*DRIVER_OBJECT*/;
86 *p
++ = 0/*TOKEN_OBJECT*/;
87 *p
++ = 0/*PROCESS_OBJECT*/;
88 *p
++ = 0/*THREAD_OBJECT*/;
89 *p
++ = 0/*ADAPTER_OBJECT*/;
90 *p
++ = 0/*PORT_OBJECT*/;
93 NTOBJECTOPENFUNCTIONS _ObjectOpenFunctions
[23];
94 static const LPCWSTR s_ObjectTypes
[];
96 DynamicFct
<void (__stdcall
*)(RtlAnsiString
*, LPCSTR
)> RtlInitAnsiString
;
97 DynamicFct
<void (__stdcall
*)(RtlUnicodeString
*, LPCWSTR
)> RtlInitUnicodeString
;
98 DynamicFct
<DWORD (__stdcall
*)(RtlAnsiString
*)> RtlFreeAnsiString
;
99 DynamicFct
<DWORD (__stdcall
*)(RtlUnicodeString
*)> RtlFreeUnicodeString
;
100 DynamicFct
<DWORD (__stdcall
*)(RtlUnicodeString
*, const RtlAnsiString
*, BOOL
)> RtlAnsiStringToUnicodeString
;
101 DynamicFct
<DWORD (__stdcall
*)(RtlAnsiString
*, const RtlUnicodeString
*, BOOL
)> RtlUnicodeStringToAnsiString
;
103 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenDirectoryObject
;
104 DynamicFct
<DWORD (__stdcall
*)(HANDLE
, NtObjectInfo
*, DWORD size
, BOOL
, BOOL
, void*, void*)> NtQueryDirectoryObject
;
105 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, void*, DWORD
*, DWORD
, OpenStruct
*)> NtOpenFile
;
106 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenSymbolicLinkObject
;
107 DynamicFct
<DWORD (__stdcall
*)(HANDLE
, RtlUnicodeString
*, DWORD
*)> NtQuerySymbolicLinkObject
;
108 DynamicFct
<DWORD (__stdcall
*)(HANDLE
, DWORD
, NtObject
*, DWORD size
, DWORD
* read
)> NtQueryObject
;
109 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenMutant
;
110 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenSection
;
111 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenEvent
;
112 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenEventPair
;
113 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenIoCompletion
;
114 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenSemaphore
;
115 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenTimer
;
116 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenKey
;
117 DynamicFct
<DWORD (__stdcall
*)(HANDLE
)> NtClose
;
118 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenProcess
;
119 DynamicFct
<DWORD (__stdcall
*)(HANDLE
*, DWORD
, OpenStruct
*)> NtOpenThread
;
122 const LPCWSTR
NTDLL::s_ObjectTypes
[] = {
123 L
"Directory", L
"SymbolicLink",
124 L
"Mutant", L
"Section", L
"Event", L
"Semaphore",
125 L
"Timer", L
"Key", L
"EventPair", L
"IoCompletion",
126 L
"Device", L
"File", L
"Controller", L
"Profile",
127 L
"Type", L
"Desktop", L
"WindowStatiom", L
"Driver",
128 L
"Token", L
"Process", L
"Thread", L
"Adapter", L
"Port",
132 NTDLL
* g_NTDLL
= NULL
;
135 struct UnicodeString
: public RtlUnicodeString
{
136 UnicodeString(LPCWSTR str
)
138 (*g_NTDLL
->RtlInitUnicodeString
)(this, str
);
141 UnicodeString(size_t len
, LPWSTR buffer
)
147 operator LPCWSTR() const {return string_ptr
;}
151 static DWORD
NtOpenObject(OBJECT_TYPE type
, HANDLE
* phandle
, DWORD access
, LPCWSTR path
/*, BOOL xflag=FALSE*/)
153 UnicodeString
ustr(path
);
154 OpenStruct open_struct
= {sizeof(OpenStruct
), 0x00, &ustr
, 0x40};
156 if (type
==DIRECTORY_OBJECT
|| type
==SYMBOLICLINK_OBJECT
)
157 access
|= FILE_LIST_DIRECTORY
;
160 access |= GENERIC_READ; */
162 DWORD ioStatusBlock
[2]; // IO_STATUS_BLOCK
164 if (type
>=DIRECTORY_OBJECT
&& type
<=IOCOMPLETITION_OBJECT
)
165 return g_NTDLL
->_ObjectOpenFunctions
[type
](phandle
, access
|STANDARD_RIGHTS_READ
, &open_struct
);
166 else if (type
== FILE_OBJECT
)
167 return (*g_NTDLL
->NtOpenFile
)(phandle
, access
, &open_struct
, ioStatusBlock
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, 0/*OpenOptions*/);
169 return ERROR_INVALID_FUNCTION
;
173 void NtObjDirectory::read_directory(int scan_flags
)
175 CONTEXT("NtObjDirectory::read_directory()");
178 g_NTDLL
= new NTDLL();
180 Entry
* first_entry
= NULL
;
181 int level
= _level
+ 1;
183 LPCTSTR path
= (LPCTSTR
)_path
;
185 TCHAR buffer
[MAX_PATH
], *p
=buffer
;
187 WCHAR wbuffer
[MAX_PATH
], *w
=wbuffer
;
205 if (NtOpenObject(_type
, &dir_handle
, 0, buffer
))
207 if (NtOpenObject(_type
, &dir_handle
, 0, wbuffer
))
219 NtObjectInfo
* info
= (NtObjectInfo
*)alloca(2048);
221 if (!(*g_NTDLL
->NtQueryDirectoryObject
)(dir_handle
, info
, 2048, TRUE
, TRUE
, &idx
, NULL
)) {
222 WIN32_FIND_DATA w32fd
;
227 memset(&w32fd
, 0, sizeof(WIN32_FIND_DATA
));
230 if (info
->name
.string_ptr
) {
231 info
->name
.string_ptr
[info
->name
.string_len
/ sizeof(WCHAR
)] = 0;
233 TCHAR empty_string_ptr
[] = _T("");
234 info
->name
.string_ptr
= empty_string_ptr
;
236 if (info
->type
.string_ptr
) {
237 info
->type
.string_ptr
[info
->type
.string_len
/ sizeof(WCHAR
)] = 0;
239 TCHAR empty_string_ptr
[] = _T("");
240 info
->type
.string_ptr
= empty_string_ptr
;
242 lstrcpynW(p
, info
->name
.string_ptr
, COUNTOF(buffer
));
244 WideCharToMultiByte(CP_ACP
, 0, info
->name
.string_ptr
, info
->name
.string_len
, p
, COUNTOF(buffer
), 0, 0);
247 lstrcpyn(w32fd
.cFileName
, p
, sizeof(w32fd
.cFileName
) / sizeof(0[w32fd
.cFileName
]));
249 const LPCWSTR
* tname
= NTDLL::s_ObjectTypes
;
250 OBJECT_TYPE type
= UNKNOWN_OBJECT_TYPE
;
252 for(; *tname
; tname
++)
253 if (!wcsncmp(info
->type
.string_ptr
, *tname
, 32))
254 {type
=OBJECT_TYPE(tname
-NTDLL::s_ObjectTypes
); break;}
256 if (type
== DIRECTORY_OBJECT
) {
257 w32fd
.dwFileAttributes
|= FILE_ATTRIBUTE_DIRECTORY
;
259 entry
= new NtObjDirectory(this, buffer
);
262 else if (type
== SYMBOLICLINK_OBJECT
) {
263 w32fd
.dwFileAttributes
|= ATTRIBUTE_SYMBOLIC_LINK
;
268 if (*w32fd
.cFileName
>='A' &&*w32fd
.cFileName
<='Z' && w32fd
.cFileName
[1]==':')
269 if (!_tcsncmp(buffer
,TEXT("\\??\\"),4) || // NT4
270 !_tcsncmp(buffer
,TEXT("\\GLOBAL??"),9)) { // XP
271 w32fd
.dwFileAttributes
|= FILE_ATTRIBUTE_DIRECTORY
;
272 entry
= new WinDirectory(this, w32fd
.cFileName
);
277 entry
= new NtObjDirectory(this, buffer
);
280 else if (type
== KEY_OBJECT
) {
281 w32fd
.dwFileAttributes
|= FILE_ATTRIBUTE_DIRECTORY
;
283 entry
= new RegistryRoot(this, buffer
);
286 entry
= new NtObjEntry(this, type
);
291 lstrcpyW(p
, info
->name
.string_ptr
);
292 if (!NtOpenObject(type
, &handle
, 0, buffer
))
294 lstrcpyW(w
, info
->name
.string_ptr
);
295 if (!NtOpenObject(type
, &handle
, 0, wbuffer
))
301 if (!(*g_NTDLL
->NtQueryObject
)(handle
, 0/*ObjectBasicInformation*/, &object
, sizeof(NtObject
), &read
)) {
302 memcpy(&w32fd
.ftCreationTime
, &object
.creation_time
, sizeof(FILETIME
));
304 memset(&entry
->_bhfi
, 0, sizeof(BY_HANDLE_FILE_INFORMATION
));
305 entry
->_bhfi
.nNumberOfLinks
= object
.reference_count
- 1;
306 entry
->_bhfi_valid
= true;
309 if (type
== SYMBOLICLINK_OBJECT
) {
310 WCHAR wbuffer
[_MAX_PATH
];
311 UnicodeString
link(_MAX_PATH
, wbuffer
);
313 if (!(*g_NTDLL
->NtQuerySymbolicLinkObject
)(handle
, &link
, NULL
)) {
314 int len
= link
.string_len
/sizeof(WCHAR
);
315 entry
->_content
= (LPTSTR
) malloc((len
+1)*sizeof(TCHAR
));
317 wcsncpy_s(entry
->_content
, len
+1, link
, len
);
319 U2nA(link
, entry
->_content
, len
);
321 entry
->_content
[len
] = '\0';
325 (*g_NTDLL
->NtClose
)(handle
);
328 memcpy(&entry
->_data
, &w32fd
, sizeof(WIN32_FIND_DATA
));
331 entry
->_type_name
= _wcsdup(info
->type
.string_ptr
);
334 WideCharToMultiByte(CP_ACP
, 0, info
->type
.string_ptr
, info
->type
.string_len
, type_name
, 32, 0, 0);
335 entry
->_type_name
= _strdup(type_name
);
344 entry
->_level
= level
;
347 } while(!(*g_NTDLL
->NtQueryDirectoryObject
)(dir_handle
, info
, 2048, TRUE
, FALSE
, &idx
, NULL
));
352 (*g_NTDLL
->NtClose
)(dir_handle
);
359 Entry
* NtObjDirectory::find_entry(const void* p
)
361 LPCTSTR name
= (LPCTSTR
)p
;
363 for(Entry
*entry
=_down
; entry
; entry
=entry
->_next
) {
365 LPCTSTR q
= entry
->_data
.cFileName
;
368 if (!*p
|| *p
==TEXT('\\') || *p
==TEXT('/'))
370 } while(tolower(*p
++) == tolower(*q
++));
373 q
= entry
->_data
.cAlternateFileName
;
376 if (!*p
|| *p
==TEXT('\\') || *p
==TEXT('/'))
378 } while(tolower(*p
++) == tolower(*q
++));
385 // get full path of specified directory entry
386 bool NtObjEntry::get_path(PTSTR path
, size_t path_count
) const
388 return get_path_base ( path
, path_count
, ET_NTOBJS
);
391 BOOL
NtObjEntry::launch_entry(HWND hwnd
, UINT nCmdShow
)