00001 /* 00002 * Copyright 2004, 2005 Martin Fuchs 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 */ 00018 00019 00020 // 00021 // Explorer clone 00022 // 00023 // ntobjfs.cpp 00024 // 00025 // Martin Fuchs, 31.01.2004 00026 // 00027 00028 00029 #include <precomp.h> 00030 00031 #include "ntobjfs.h" 00032 //#include "winfs.h" 00033 #include "regfs.h" 00034 00035 00036 #define CONSTRUCT_NTDLLFCT(x) x(TEXT("NTDLL"), #x) 00037 00038 typedef DWORD (__stdcall* NTOBJECTOPENFUNCTIONS)(HANDLE*, DWORD, OpenStruct*); 00039 00040 struct NTDLL { 00041 NTDLL() 00042 : CONSTRUCT_NTDLLFCT(RtlInitAnsiString), 00043 CONSTRUCT_NTDLLFCT(RtlInitUnicodeString), 00044 CONSTRUCT_NTDLLFCT(RtlFreeAnsiString), 00045 CONSTRUCT_NTDLLFCT(RtlFreeUnicodeString), 00046 CONSTRUCT_NTDLLFCT(RtlAnsiStringToUnicodeString), 00047 CONSTRUCT_NTDLLFCT(RtlUnicodeStringToAnsiString), 00048 CONSTRUCT_NTDLLFCT(NtOpenDirectoryObject), 00049 CONSTRUCT_NTDLLFCT(NtQueryDirectoryObject), 00050 CONSTRUCT_NTDLLFCT(NtOpenFile), 00051 CONSTRUCT_NTDLLFCT(NtOpenSymbolicLinkObject), 00052 CONSTRUCT_NTDLLFCT(NtQuerySymbolicLinkObject), 00053 CONSTRUCT_NTDLLFCT(NtQueryObject), 00054 CONSTRUCT_NTDLLFCT(NtOpenMutant), 00055 CONSTRUCT_NTDLLFCT(NtOpenSection), 00056 CONSTRUCT_NTDLLFCT(NtOpenEvent), 00057 CONSTRUCT_NTDLLFCT(NtOpenEventPair), 00058 CONSTRUCT_NTDLLFCT(NtOpenIoCompletion), 00059 CONSTRUCT_NTDLLFCT(NtOpenSemaphore), 00060 CONSTRUCT_NTDLLFCT(NtOpenTimer), 00061 CONSTRUCT_NTDLLFCT(NtOpenKey), 00062 CONSTRUCT_NTDLLFCT(NtClose), 00063 CONSTRUCT_NTDLLFCT(NtOpenProcess), 00064 CONSTRUCT_NTDLLFCT(NtOpenThread) 00065 { 00066 NTOBJECTOPENFUNCTIONS* p = _ObjectOpenFunctions; 00067 00068 *p++ = *NtOpenDirectoryObject; 00069 *p++ = *NtOpenSymbolicLinkObject; 00070 *p++ = *NtOpenMutant; 00071 *p++ = *NtOpenSection; 00072 *p++ = *NtOpenEvent; 00073 *p++ = *NtOpenSemaphore; 00074 *p++ = *NtOpenTimer; 00075 *p++ = *NtOpenKey; 00076 *p++ = *NtOpenEventPair; 00077 *p++ = *NtOpenIoCompletion; 00078 *p++ = 0/*Device Object*/; 00079 *p++ = 0/*NtOpenFile*/; 00080 *p++ = 0/*CONTROLLER_OBJECT*/; 00081 *p++ = 0/*PROFILE_OBJECT*/; 00082 *p++ = 0/*TYPE_OBJECT*/; 00083 *p++ = 0/*DESKTOP_OBJECT*/; 00084 *p++ = 0/*WINDOWSTATION_OBJECT*/; 00085 *p++ = 0/*DRIVER_OBJECT*/; 00086 *p++ = 0/*TOKEN_OBJECT*/; 00087 *p++ = 0/*PROCESS_OBJECT*/; 00088 *p++ = 0/*THREAD_OBJECT*/; 00089 *p++ = 0/*ADAPTER_OBJECT*/; 00090 *p++ = 0/*PORT_OBJECT*/; 00091 } 00092 00093 NTOBJECTOPENFUNCTIONS _ObjectOpenFunctions[23]; 00094 static const LPCWSTR s_ObjectTypes[]; 00095 00096 DynamicFct<void (__stdcall*)(RtlAnsiString*, LPCSTR)> RtlInitAnsiString; 00097 DynamicFct<void (__stdcall*)(RtlUnicodeString*, LPCWSTR)> RtlInitUnicodeString; 00098 DynamicFct<DWORD (__stdcall*)(RtlAnsiString*)> RtlFreeAnsiString; 00099 DynamicFct<DWORD (__stdcall*)(RtlUnicodeString*)> RtlFreeUnicodeString; 00100 DynamicFct<DWORD (__stdcall*)(RtlUnicodeString*, const RtlAnsiString*, BOOL)> RtlAnsiStringToUnicodeString; 00101 DynamicFct<DWORD (__stdcall*)(RtlAnsiString*, const RtlUnicodeString*, BOOL)> RtlUnicodeStringToAnsiString; 00102 00103 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenDirectoryObject; 00104 DynamicFct<DWORD (__stdcall*)(HANDLE, NtObjectInfo*, DWORD size, BOOL, BOOL, void*, void*)> NtQueryDirectoryObject; 00105 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, void*, DWORD*, DWORD, OpenStruct*)> NtOpenFile; 00106 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenSymbolicLinkObject; 00107 DynamicFct<DWORD (__stdcall*)(HANDLE, RtlUnicodeString*, DWORD*)> NtQuerySymbolicLinkObject; 00108 DynamicFct<DWORD (__stdcall*)(HANDLE, DWORD, NtObject*, DWORD size, DWORD* read)> NtQueryObject; 00109 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenMutant; 00110 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenSection; 00111 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenEvent; 00112 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenEventPair; 00113 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenIoCompletion; 00114 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenSemaphore; 00115 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenTimer; 00116 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenKey; 00117 DynamicFct<DWORD (__stdcall*)(HANDLE)> NtClose; 00118 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenProcess; 00119 DynamicFct<DWORD (__stdcall*)(HANDLE*, DWORD, OpenStruct*)> NtOpenThread; 00120 }; 00121 00122 const LPCWSTR NTDLL::s_ObjectTypes[] = { 00123 L"Directory", L"SymbolicLink", 00124 L"Mutant", L"Section", L"Event", L"Semaphore", 00125 L"Timer", L"Key", L"EventPair", L"IoCompletion", 00126 L"Device", L"File", L"Controller", L"Profile", 00127 L"Type", L"Desktop", L"WindowStatiom", L"Driver", 00128 L"Token", L"Process", L"Thread", L"Adapter", L"Port", 00129 0 00130 }; 00131 00132 NTDLL* g_NTDLL = NULL; 00133 00134 00135 struct UnicodeString : public RtlUnicodeString { 00136 UnicodeString(LPCWSTR str) 00137 { 00138 (*g_NTDLL->RtlInitUnicodeString)(this, str); 00139 } 00140 00141 UnicodeString(size_t len, LPWSTR buffer) 00142 { 00143 alloc_len = len; 00144 string_ptr = buffer; 00145 } 00146 00147 operator LPCWSTR() const {return string_ptr;} 00148 }; 00149 00150 00151 static DWORD NtOpenObject(OBJECT_TYPE type, HANDLE* phandle, DWORD access, LPCWSTR path/*, BOOL xflag=FALSE*/) 00152 { 00153 UnicodeString ustr(path); 00154 OpenStruct open_struct = {sizeof(OpenStruct), 0x00, &ustr, 0x40}; 00155 00156 if (type==DIRECTORY_OBJECT || type==SYMBOLICLINK_OBJECT) 00157 access |= FILE_LIST_DIRECTORY; 00158 00159 /* if (xflag) 00160 access |= GENERIC_READ; */ 00161 00162 DWORD ioStatusBlock[2]; // IO_STATUS_BLOCK 00163 00164 if (type>=DIRECTORY_OBJECT && type<=IOCOMPLETITION_OBJECT) 00165 return g_NTDLL->_ObjectOpenFunctions[type](phandle, access|STANDARD_RIGHTS_READ, &open_struct); 00166 else if (type == FILE_OBJECT) 00167 return (*g_NTDLL->NtOpenFile)(phandle, access, &open_struct, ioStatusBlock, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 0/*OpenOptions*/); 00168 else 00169 return ERROR_INVALID_FUNCTION; 00170 } 00171 00172 00173 void NtObjDirectory::read_directory(int scan_flags) 00174 { 00175 CONTEXT("NtObjDirectory::read_directory()"); 00176 00177 if (!g_NTDLL) 00178 g_NTDLL = new NTDLL(); 00179 00180 Entry* first_entry = NULL; 00181 int level = _level + 1; 00182 00183 LPCTSTR path = (LPCTSTR)_path; 00184 00185 TCHAR buffer[MAX_PATH], *p=buffer; 00186 #ifndef UNICODE 00187 WCHAR wbuffer[MAX_PATH], *w=wbuffer; 00188 #endif 00189 00190 do { 00191 *p++ = *path; 00192 #ifndef UNICODE 00193 *w++ = *path; 00194 #endif 00195 } while(*path++); 00196 --p; 00197 #ifndef UNICODE 00198 --w; 00199 #endif 00200 00201 DWORD idx; 00202 HANDLE dir_handle; 00203 00204 #ifdef UNICODE 00205 if (NtOpenObject(_type, &dir_handle, 0, buffer)) 00206 #else 00207 if (NtOpenObject(_type, &dir_handle, 0, wbuffer)) 00208 #endif 00209 return; 00210 00211 #ifdef UNICODE 00212 if (p[-1] != '\\') 00213 *p++ = '\\'; 00214 #else 00215 if (w[-1] != '\\') 00216 *w++ = '\\'; 00217 #endif 00218 00219 NtObjectInfo* info = (NtObjectInfo*)alloca(2048); 00220 00221 if (!(*g_NTDLL->NtQueryDirectoryObject)(dir_handle, info, 2048, TRUE, TRUE, &idx, NULL)) { 00222 WIN32_FIND_DATA w32fd; 00223 Entry* last = NULL; 00224 Entry* entry; 00225 00226 do { 00227 memset(&w32fd, 0, sizeof(WIN32_FIND_DATA)); 00228 00229 #ifdef UNICODE 00230 if (info->name.string_ptr) { 00231 info->name.string_ptr[info->name.string_len / sizeof(WCHAR)] = 0; 00232 } else { 00233 TCHAR empty_string_ptr[] = _T(""); 00234 info->name.string_ptr = empty_string_ptr; 00235 } 00236 if (info->type.string_ptr) { 00237 info->type.string_ptr[info->type.string_len / sizeof(WCHAR)] = 0; 00238 } else { 00239 TCHAR empty_string_ptr[] = _T(""); 00240 info->type.string_ptr = empty_string_ptr; 00241 } 00242 lstrcpynW(p, info->name.string_ptr, COUNTOF(buffer)); 00243 #else 00244 WideCharToMultiByte(CP_ACP, 0, info->name.string_ptr, info->name.string_len, p, COUNTOF(buffer), 0, 0); 00245 #endif 00246 00247 lstrcpyn(w32fd.cFileName, p, sizeof(w32fd.cFileName) / sizeof(0[w32fd.cFileName])); 00248 00249 const LPCWSTR* tname = NTDLL::s_ObjectTypes; 00250 OBJECT_TYPE type = UNKNOWN_OBJECT_TYPE; 00251 00252 for(; *tname; tname++) 00253 if (!wcsncmp(info->type.string_ptr, *tname, 32)) 00254 {type=OBJECT_TYPE(tname-NTDLL::s_ObjectTypes); break;} 00255 00256 if (type == DIRECTORY_OBJECT) { 00257 w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; 00258 00259 entry = new NtObjDirectory(this, buffer); 00260 } 00261 00262 else if (type == SYMBOLICLINK_OBJECT) { 00263 w32fd.dwFileAttributes |= ATTRIBUTE_SYMBOLIC_LINK; 00264 00265 entry = NULL; 00266 00267 #ifndef _NO_WIN_FS 00268 if (*w32fd.cFileName>='A' &&*w32fd.cFileName<='Z' && w32fd.cFileName[1]==':') 00269 if (!_tcsncmp(buffer,TEXT("\\??\\"),4) || // NT4 00270 !_tcsncmp(buffer,TEXT("\\GLOBAL??"),9)) { // XP 00271 w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; 00272 entry = new WinDirectory(this, w32fd.cFileName); 00273 } 00274 #endif 00275 00276 if (!entry) 00277 entry = new NtObjDirectory(this, buffer); 00278 } 00279 00280 else if (type == KEY_OBJECT) { 00281 w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; 00282 00283 entry = new RegistryRoot(this, buffer); 00284 } 00285 else 00286 entry = new NtObjEntry(this, type); 00287 00288 HANDLE handle; 00289 00290 #ifdef UNICODE 00291 lstrcpyW(p, info->name.string_ptr); 00292 if (!NtOpenObject(type, &handle, 0, buffer)) 00293 #else 00294 lstrcpyW(w, info->name.string_ptr); 00295 if (!NtOpenObject(type, &handle, 0, wbuffer)) 00296 #endif 00297 { 00298 NtObject object; 00299 DWORD read; 00300 00301 if (!(*g_NTDLL->NtQueryObject)(handle, 0/*ObjectBasicInformation*/, &object, sizeof(NtObject), &read)) { 00302 memcpy(&w32fd.ftCreationTime, &object.creation_time, sizeof(FILETIME)); 00303 00304 memset(&entry->_bhfi, 0, sizeof(BY_HANDLE_FILE_INFORMATION)); 00305 entry->_bhfi.nNumberOfLinks = object.reference_count - 1; 00306 entry->_bhfi_valid = true; 00307 } 00308 00309 if (type == SYMBOLICLINK_OBJECT) { 00310 WCHAR wbuffer[_MAX_PATH]; 00311 UnicodeString link(_MAX_PATH, wbuffer); 00312 00313 if (!(*g_NTDLL->NtQuerySymbolicLinkObject)(handle, &link, NULL)) { 00314 int len = link.string_len/sizeof(WCHAR); 00315 entry->_content = (LPTSTR) malloc((len+1)*sizeof(TCHAR)); 00316 #ifdef UNICODE 00317 wcsncpy_s(entry->_content, len+1, link, len); 00318 #else 00319 U2nA(link, entry->_content, len); 00320 #endif 00321 entry->_content[len] = '\0'; 00322 } 00323 } 00324 00325 (*g_NTDLL->NtClose)(handle); 00326 } 00327 00328 memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA)); 00329 00330 #ifdef UNICODE 00331 entry->_type_name = _wcsdup(info->type.string_ptr); 00332 #else 00333 char type_name[32]; 00334 WideCharToMultiByte(CP_ACP, 0, info->type.string_ptr, info->type.string_len, type_name, 32, 0, 0); 00335 entry->_type_name = _strdup(type_name); 00336 #endif 00337 00338 if (!first_entry) 00339 first_entry = entry; 00340 00341 if (last) 00342 last->_next = entry; 00343 00344 entry->_level = level; 00345 00346 last = entry; 00347 } while(!(*g_NTDLL->NtQueryDirectoryObject)(dir_handle, info, 2048, TRUE, FALSE, &idx, NULL)); 00348 00349 last->_next = NULL; 00350 } 00351 00352 (*g_NTDLL->NtClose)(dir_handle); 00353 00354 _down = first_entry; 00355 _scanned = true; 00356 } 00357 00358 00359 Entry* NtObjDirectory::find_entry(const void* p) 00360 { 00361 LPCTSTR name = (LPCTSTR)p; 00362 00363 for(Entry*entry=_down; entry; entry=entry->_next) { 00364 LPCTSTR p = name; 00365 LPCTSTR q = entry->_data.cFileName; 00366 00367 do { 00368 if (!*p || *p==TEXT('\\') || *p==TEXT('/')) 00369 return entry; 00370 } while(tolower(*p++) == tolower(*q++)); 00371 00372 p = name; 00373 q = entry->_data.cAlternateFileName; 00374 00375 do { 00376 if (!*p || *p==TEXT('\\') || *p==TEXT('/')) 00377 return entry; 00378 } while(tolower(*p++) == tolower(*q++)); 00379 } 00380 00381 return NULL; 00382 } 00383 00384 00385 // get full path of specified directory entry 00386 bool NtObjEntry::get_path(PTSTR path, size_t path_count) const 00387 { 00388 return get_path_base ( path, path_count, ET_NTOBJS ); 00389 } 00390 00391 BOOL NtObjEntry::launch_entry(HWND hwnd, UINT nCmdShow) 00392 { 00393 return FALSE; 00394 }
ROS Explorer Source Code Documentation
generated on 02.01.2013 by ![]() |