ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ntobjfs.cpp
Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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 }

Generated on Sun May 27 2012 04:18:33 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.