diff --git a/reactos/subsys/system/explorer/Jamfile b/reactos/subsys/system/explorer/Jamfile index 474dbe13d3a..96593ab6ee6 100644 --- a/reactos/subsys/system/explorer/Jamfile +++ b/reactos/subsys/system/explorer/Jamfile @@ -21,6 +21,7 @@ exe explorer : shell/shellfs.cpp shell/unixfs.cpp shell/winfs.cpp + shell/ntobjfs.cpp shell/startup.c taskbar/desktopbar.cpp taskbar/quicklaunch.cpp diff --git a/reactos/subsys/system/explorer/Makefile b/reactos/subsys/system/explorer/Makefile index 49eb2de1996..8291b8ef17e 100644 --- a/reactos/subsys/system/explorer/Makefile +++ b/reactos/subsys/system/explorer/Makefile @@ -80,6 +80,7 @@ OBJECTS = \ winfs.o \ unixfs.o \ shellfs.o \ + ntobjfs.o \ mainframe.o \ filechild.o \ pane.o \ diff --git a/reactos/subsys/system/explorer/Makefile.MinGW b/reactos/subsys/system/explorer/Makefile.MinGW index be537ca952a..9391b78a0ed 100644 --- a/reactos/subsys/system/explorer/Makefile.MinGW +++ b/reactos/subsys/system/explorer/Makefile.MinGW @@ -54,6 +54,7 @@ OBJECTS = \ winfs.o \ unixfs.o \ shellfs.o \ + ntobjfs.o \ mainframe.o \ filechild.o \ pane.o \ diff --git a/reactos/subsys/system/explorer/Makefile.Wine b/reactos/subsys/system/explorer/Makefile.Wine index f08b7660225..4f3340131b0 100644 --- a/reactos/subsys/system/explorer/Makefile.Wine +++ b/reactos/subsys/system/explorer/Makefile.Wine @@ -29,6 +29,7 @@ CPP_SRCS = \ shell/filechild.cpp \ shell/pane.cpp \ shell/shellbrowser.cpp \ + shell/ntobjfs.cpp \ taskbar/desktopbar.cpp \ taskbar/taskbar.cpp \ taskbar/startmenu.cpp \ diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index ff1d9520927..32b45446ab3 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -57,4 +57,4 @@ If you search for more information, look into the CVS repository. 11.01.2004 m. fuchs keyboard navigation in start menu 14.01.2004 m. fuchs automatically adjusted size of notification area and quicklaunch bar in desktop bar 18.01.2004 m. fuchs explorer/desktop settings property sheet - +31.01.2004 m. fuchs included NT Object namespace as virtual file system diff --git a/reactos/subsys/system/explorer/explorer.dsp b/reactos/subsys/system/explorer/explorer.dsp index 931a358c70d..a95d315f265 100644 --- a/reactos/subsys/system/explorer/explorer.dsp +++ b/reactos/subsys/system/explorer/explorer.dsp @@ -744,6 +744,14 @@ SOURCE=.\shell\mainframe.h # End Source File # Begin Source File +SOURCE=.\shell\ntobjfs.cpp +# End Source File +# Begin Source File + +SOURCE=.\shell\ntobjfs.h +# End Source File +# Begin Source File + SOURCE=.\shell\pane.cpp # End Source File # Begin Source File diff --git a/reactos/subsys/system/explorer/explorer_intres.h b/reactos/subsys/system/explorer/explorer_intres.h index b4bb3d34b7a..3d870f5ce67 100644 --- a/reactos/subsys/system/explorer/explorer_intres.h +++ b/reactos/subsys/system/explorer/explorer_intres.h @@ -118,7 +118,8 @@ #define ID_DRIVE_DESKTOP 0x9000 #define ID_DRIVE_SHELL_NS 0x9001 #define ID_DRIVE_UNIX_FS 0x9002 -#define ID_DRIVE_FIRST 0x9003 +#define ID_DRIVE_NTOBJ_NS 0x9003 +#define ID_DRIVE_FIRST 0x9004 #define ID_ABOUT_WINDOWS 40002 #define ID_ABOUT_EXPLORER 40003 #define ID_DESKTOPBAR_SETTINGS 40005 diff --git a/reactos/subsys/system/explorer/shell/entries.h b/reactos/subsys/system/explorer/shell/entries.h index fab8fb51668..a5b2d601f23 100644 --- a/reactos/subsys/system/explorer/shell/entries.h +++ b/reactos/subsys/system/explorer/shell/entries.h @@ -31,7 +31,8 @@ enum ENTRY_TYPE { #ifdef __WINE__ ET_UNIX, #endif - ET_SHELL + ET_SHELL, + ET_NTOBJS }; enum SORT_ORDER { diff --git a/reactos/subsys/system/explorer/shell/filechild.cpp b/reactos/subsys/system/explorer/shell/filechild.cpp index 153d9d3761b..33e914f1e64 100644 --- a/reactos/subsys/system/explorer/shell/filechild.cpp +++ b/reactos/subsys/system/explorer/shell/filechild.cpp @@ -30,6 +30,7 @@ #include "../explorer.h" #include "../globals.h" +#include "ntobjfs.h" #include "../explorer_intres.h" @@ -63,7 +64,13 @@ ShellChildWndInfo::ShellChildWndInfo(LPCTSTR path, const ShellPath& root_shell_p _root_shell_path(root_shell_path) { _etype = ET_SHELL; - _path = path; +} + + +NtObjChildWndInfo::NtObjChildWndInfo(LPCTSTR path) + : FileChildWndInfo(path) +{ + _etype = ET_NTOBJS; } @@ -104,7 +111,20 @@ FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info) } else #endif - {// if (info._etype == ET_WINDOWS) + if (info._etype == ET_NTOBJS) + { + _root._drive_type = DRIVE_UNKNOWN; + + _tsplitpath(info._path, drv, NULL, NULL, NULL); + lstrcat(drv, TEXT("\\")); + lstrcpy(_root._volname, TEXT("NT Object Namespace")); + lstrcpy(_root._fs, TEXT("NTOBJ")); + lstrcpy(_root._path, drv); + _root._entry = new NtObjDirectory(_root._path); + entry = _root._entry->read_tree(info._path, SORT_NAME/*_sortOrder*/); + } + else //if (info._etype == ET_WINDOWS) + { _root._drive_type = GetDriveType(info._path); _tsplitpath(info._path, drv, NULL, NULL, NULL); diff --git a/reactos/subsys/system/explorer/shell/filechild.h b/reactos/subsys/system/explorer/shell/filechild.h index e49f270f1ac..a719a42c6d5 100644 --- a/reactos/subsys/system/explorer/shell/filechild.h +++ b/reactos/subsys/system/explorer/shell/filechild.h @@ -47,6 +47,12 @@ struct ShellChildWndInfo : public FileChildWndInfo ShellPath _root_shell_path; }; + /// information structure for creation of FileChildWindow for NT object namespace +struct NtObjChildWndInfo : public FileChildWndInfo +{ + NtObjChildWndInfo(LPCTSTR path); +}; + /// MDI child window displaying file lists struct FileChildWindow : public ChildWindow diff --git a/reactos/subsys/system/explorer/shell/mainframe.cpp b/reactos/subsys/system/explorer/shell/mainframe.cpp index 4d5783bfa1c..8c3a64f9e1f 100644 --- a/reactos/subsys/system/explorer/shell/mainframe.cpp +++ b/reactos/subsys/system/explorer/shell/mainframe.cpp @@ -114,6 +114,16 @@ MainFrame::MainFrame(HWND hwnd) SendMessage(_hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn); ++drivebarBtn.iString; +#define W_VER_NT 0 + if ((HIWORD(GetVersion())>>14) == W_VER_NT) { + // insert NT object namespace button + SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("NT Obj\0")); + + drivebarBtn.idCommand = ID_DRIVE_NTOBJ_NS; + SendMessage(_hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn); + ++drivebarBtn.iString; + } + // register windows drive root strings SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)_drives); @@ -512,6 +522,14 @@ int MainFrame::Command(int id, int code) #endif break;} + case ID_DRIVE_NTOBJ_NS: { +#ifndef _NO_MDI + FileChildWindow::create(_hmdiclient, NtObjChildWndInfo(TEXT("\\"))); +#else + ///@todo SDI implementation +#endif + break;} + case ID_DRIVE_DESKTOP: { TCHAR path[MAX_PATH]; diff --git a/reactos/subsys/system/explorer/shell/ntobjfs.cpp b/reactos/subsys/system/explorer/shell/ntobjfs.cpp new file mode 100644 index 00000000000..0b55e939068 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/ntobjfs.cpp @@ -0,0 +1,513 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // ntobjfs.cpp + // + // Martin Fuchs, 31.01.2004 + // + + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" + +#include "entries.h" +#include "ntobjfs.h" + + +#define CONSTRUCT_NTDLLFCT(x) x(TEXT("NTDLL"), #x) + +typedef DWORD (__stdcall* NTOBJECTOPENFUNCTIONS)(HANDLE*, DWORD, OpenStruct*); + +struct NTDLL { + NTDLL() + : CONSTRUCT_NTDLLFCT(RtlInitAnsiString), + CONSTRUCT_NTDLLFCT(RtlInitUnicodeString), + CONSTRUCT_NTDLLFCT(RtlFreeAnsiString), + CONSTRUCT_NTDLLFCT(RtlFreeUnicodeString), + CONSTRUCT_NTDLLFCT(RtlAnsiStringToUnicodeString), + CONSTRUCT_NTDLLFCT(RtlUnicodeStringToAnsiString), + CONSTRUCT_NTDLLFCT(NtOpenDirectoryObject), + CONSTRUCT_NTDLLFCT(NtQueryDirectoryObject), + CONSTRUCT_NTDLLFCT(NtOpenFile), + CONSTRUCT_NTDLLFCT(NtOpenSymbolicLinkObject), + CONSTRUCT_NTDLLFCT(NtQuerySymbolicLinkObject), + CONSTRUCT_NTDLLFCT(NtQueryObject), + CONSTRUCT_NTDLLFCT(NtOpenMutant), + CONSTRUCT_NTDLLFCT(NtOpenSection), + CONSTRUCT_NTDLLFCT(NtOpenEvent), + CONSTRUCT_NTDLLFCT(NtOpenEventPair), + CONSTRUCT_NTDLLFCT(NtOpenIoCompletion), + CONSTRUCT_NTDLLFCT(NtOpenSemaphore), + CONSTRUCT_NTDLLFCT(NtOpenTimer), + CONSTRUCT_NTDLLFCT(NtOpenKey), + CONSTRUCT_NTDLLFCT(NtClose), + CONSTRUCT_NTDLLFCT(NtOpenProcess), + CONSTRUCT_NTDLLFCT(NtOpenThread) + { + NTOBJECTOPENFUNCTIONS* p = _ObjectOpenFunctions; + + *p++ = *NtOpenDirectoryObject; + *p++ = *NtOpenSymbolicLinkObject; + *p++ = *NtOpenMutant; + *p++ = *NtOpenSection; + *p++ = *NtOpenEvent; + *p++ = *NtOpenSemaphore; + *p++ = *NtOpenTimer; + *p++ = *NtOpenKey; + *p++ = *NtOpenEventPair; + *p++ = *NtOpenIoCompletion; + *p++ = 0/*Device Object*/; + *p++ = 0/*NtOpenFile*/; + *p++ = 0/*CONTROLLER_OBJECT*/; + *p++ = 0/*PROFILE_OBJECT*/; + *p++ = 0/*TYPE_OBJECT*/; + *p++ = 0/*DESKTOP_OBJECT*/; + *p++ = 0/*WINDOWSTATION_OBJECT*/; + *p++ = 0/*DRIVER_OBJECT*/; + *p++ = 0/*TOKEN_OBJECT*/; + *p++ = 0/*PROCESS_OBJECT*/; + *p++ = 0/*THREAD_OBJECT*/; + *p++ = 0/*ADAPTER_OBJECT*/; + *p++ = 0/*PORT_OBJECT*/; + } + + NTOBJECTOPENFUNCTIONS _ObjectOpenFunctions[23]; + static const LPCWSTR s_ObjectTypes[]; + + DynamicFct RtlInitAnsiString; + DynamicFct RtlInitUnicodeString; + DynamicFct RtlFreeAnsiString; + DynamicFct RtlFreeUnicodeString; + DynamicFct RtlAnsiStringToUnicodeString; + DynamicFct RtlUnicodeStringToAnsiString; + + DynamicFct NtOpenDirectoryObject; + DynamicFct NtQueryDirectoryObject; + DynamicFct NtOpenFile; + DynamicFct NtOpenSymbolicLinkObject; + DynamicFct NtQuerySymbolicLinkObject; + DynamicFct NtQueryObject; + DynamicFct NtOpenMutant; + DynamicFct NtOpenSection; + DynamicFct NtOpenEvent; + DynamicFct NtOpenEventPair; + DynamicFct NtOpenIoCompletion; + DynamicFct NtOpenSemaphore; + DynamicFct NtOpenTimer; + DynamicFct NtOpenKey; + DynamicFct NtClose; + DynamicFct NtOpenProcess; + DynamicFct NtOpenThread; +}; + +const LPCWSTR NTDLL::s_ObjectTypes[] = { + L"Directory", L"SymbolicLink", + L"Mutant", L"Section", L"Event", L"Semaphore", + L"Timer", L"Key", L"EventPair", L"IoCompletion", + L"Device", L"File", L"Controller", L"Profile", + L"Type", L"Desktop", L"WindowStatiom", L"Driver", + L"Token", L"Process", L"Thread", L"Adapter", L"Port", + 0 +}; + +NTDLL* g_NTDLL = NULL; + + +struct UnicodeString : public RtlUnicodeString { + UnicodeString(LPCWSTR str) + { + (*g_NTDLL->RtlInitUnicodeString)(this, str); + } + + UnicodeString(size_t len, LPWSTR buffer) + { + alloc_len = len; + string_ptr = buffer; + } + + operator LPCWSTR() const {return string_ptr;} +}; + + +static DWORD NtOpenObject(OBJECT_TYPE type, HANDLE* phandle, DWORD flags, LPCWSTR path/*, BOOL xflag=FALSE*/) +{ + UnicodeString ustr(path); + OpenStruct open_struct = {sizeof(OpenStruct), 0x00, &ustr, 0x40}; + + if (type==SYMBOLICLINK_OBJECT || type==DIRECTORY_OBJECT) + flags |= 1; //@@ ENUMERATE + + /* if (xflag) + flags |= 0x80000000; */ + + DWORD retx; + + if (type>=DIRECTORY_OBJECT && type<=IOCOMPLETITION_OBJECT) + return g_NTDLL->_ObjectOpenFunctions[type](phandle, flags|0x20000, &open_struct); + else if (type == FILE_OBJECT) + return (*g_NTDLL->NtOpenFile)(phandle, flags, &open_struct, &retx, 7, 0); + else + return ERROR_INVALID_FUNCTION; +} + + +void NtObjDirectory::read_directory(int scan_flags) +{ + CONTEXT("NtObjDirectory::read_directory()"); + + if (!g_NTDLL) + g_NTDLL = new NTDLL(); + + Entry* first_entry = NULL; + int level = _level + 1; + + LPCTSTR path = (LPCTSTR)_path; + + TCHAR buffer[MAX_PATH], *p=buffer; +#ifndef UNICODE + WCHAR wbuffer[MAX_PATH], *w=wbuffer; +#endif + + do { + *p++ = *path; +#ifndef UNICODE + *w++ = *path; +#endif + } while(*path++); + --p; +#ifndef UNICODE + --w; +#endif + + DWORD idx1, idx2; + HANDLE dir_handle; + +#ifdef UNICODE + if (NtOpenObject(_type, &dir_handle, 0, buffer)) +#else + if (NtOpenObject(_type, &dir_handle, 0, wbuffer)) +#endif + return; + +#ifdef UNICODE + if (p[-1] != '\\') + *p++ = '\\'; +#else + if (w[-1] != '\\') + *w++ = '\\'; +#endif + + if (_type == DIRECTORY_OBJECT) { + NtObjectInfo* info = (NtObjectInfo*)alloca(0x800); + + if (!(*g_NTDLL->NtQueryDirectoryObject)(dir_handle, info, 0x800, TRUE, TRUE, &idx1, &idx2)) { + WIN32_FIND_DATA w32fd; + Entry* last = NULL; + NtObjEntry* entry; + + do { + memset(&w32fd, 0, sizeof(WIN32_FIND_DATA)); + +#ifdef UNICODE + wcscpyn(p, info->name.string_ptr, _MAX_PATH); + //@@wcscpyn(_class, info->type.string_ptr, 32); +#else + WideCharToMultiByte(CP_ACP, 0, info->name.string_ptr, info->name.string_len, p, MAX_PATH, 0, 0); + //@@U2T(info->type.string_ptr, _class, 32); +#endif + + lstrcpy(w32fd.cFileName, p); + + const LPCWSTR* tname = NTDLL::s_ObjectTypes; + OBJECT_TYPE type = UNKNOWN_OBJECT_TYPE; + + for(; *tname; tname++) + if (!wcsncmp(info->type.string_ptr, *tname, 32)) + {type=OBJECT_TYPE(tname-NTDLL::s_ObjectTypes); break;} + + if (type == DIRECTORY_OBJECT) { + w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; + + entry = new NtObjDirectory(this, buffer); + } + + else if (type == SYMBOLICLINK_OBJECT) { + w32fd.dwFileAttributes |= ATTRIBUTE_SYMBOLIC_LINK; + + //@@_toscan |= INF_DESCRIPTION; + + entry = new NtObjDirectory(this, buffer); + + if (*w32fd.cFileName>='A' &&*w32fd.cFileName<='Z' && w32fd.cFileName[1]==':') { + if (!_tcsncmp(buffer,TEXT("\\??\\"),4) || !_tcsncmp(buffer,TEXT("\\GLOBAL??\\"),10)) { + + ///@todo mount drive at this entry + + } + } + } + + else if (type == KEY_OBJECT) { +#if 0 ///@todo mount registry hives + TLVEntry *entry, **pnext = pchild(); + TLVController* tlvctrlr = system()->tlvctrlr(); + + *pnext = entry = new RegRootEntry(tlvctrlr, HKEY_CURRENT_USER); + *entry->pparent() = this; + + pnext = entry->pnext(); + *pnext = entry = new RegRootEntry(tlvctrlr, HKEY_LOCAL_MACHINE); + *entry->pparent() = this; + + pnext = entry->pnext(); + *pnext = entry = new RegRootEntry(tlvctrlr, HKEY_CLASSES_ROOT); + *entry->pparent() = this; + + pnext = entry->pnext(); + *pnext = entry = new RegRootEntry(tlvctrlr, HKEY_USERS); + *entry->pparent() = this; + /* + pnext = entry->pnext(); + *pnext = entry = new RegRootEntry(tlvctrlr, HKEY_PERFORMANCE_DATA); + *entry->pparent() = this; + */ + pnext = entry->pnext(); + *pnext = entry = new RegRootEntry(tlvctrlr, HKEY_CURRENT_CONFIG); + *entry->pparent() = this; + /* + pnext = entry->pnext(); + *pnext = entry = new RegRootEntry(tlvctrlr, HKEY_DYN_DATA); + *entry->pparent() = this; + */ +#endif + } + else + entry = new NtObjEntry(this, type); + + entry->_bhfi_valid = false; + + HANDLE handle; + +#ifdef UNICODE + lstrcpyW(p, info->name.string_ptr); + if (!NtOpenObject(_type, &handle, 0, buffer)) +#else + lstrcpyW(w, info->name.string_ptr); + if (!NtOpenObject(_type, &handle, 0, wbuffer)) +#endif + { + NtObject object; + DWORD read; + + if (!(*g_NTDLL->NtQueryObject)(handle, 0, &object, sizeof(NtObject), &read)) { + memcpy(&w32fd.ftCreationTime, &object.creation_time, sizeof(FILETIME)); + + memset(&entry->_bhfi, 0, sizeof(BY_HANDLE_FILE_INFORMATION)); + entry->_bhfi.nNumberOfLinks = object.reference_count - 1; + entry->_bhfi_valid = true; + } + + (*g_NTDLL->NtClose)(handle); + } + + memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA)); + + if (!first_entry) + first_entry = entry; + + if (last) + last->_next = entry; + + entry->_down = NULL; + entry->_expanded = false; + entry->_scanned = false; + entry->_level = level; + + last = entry; + } while(!(*g_NTDLL->NtQueryDirectoryObject)(dir_handle, info, 0x800, TRUE, FALSE, &idx1, &idx2)); + + last->_next = NULL; + } + } else { +/*@@ + assert(_type==SYMBOLICLINK_OBJECT); + + try { + wcscpy(wcpcpy(buffer, UNC(_name)), L"\\"); + + if (GetFileAttributesW(buffer) != 0xFFFFFFFF) { +#ifdef UNICODE + TLVEntry* entry = new FileSysEntry(system()->tlvctrlr(), buffer); +#else + TLVEntry* entry = new FileSysEntry(system()->tlvctrlr(), String(buffer)); +#endif + + *entry->pparent() = this; + *pchild() = entry; + + expand(); + } else + _toscan |= INF_REFRESH_SCAN_CHILD; + } catch(Exception& e) { + if (display_errors) + HandleException(e); + } +*/ + } + +/*@@ + if (_toscan & INF_DESCRIPTION) { + _toscan &= ~INF_DESCRIPTION; + + if (_type == SYMBOLICLINK_OBJECT) { + DWORD len; + WCHAR wbuffer[_MAX_PATH]; + UnicodeString link(_MAX_PATH, wbuffer); + + if (!NtQuerySymbolicLinkObject(dir_handle, &link, &len)) { +#ifdef UNICODE + wcscpy(_description, link); +#else + U2T(link, _description, -1); +#endif + _inf |= INF_DESCRIPTION; + } + } + } +*/ + + (*g_NTDLL->NtClose)(dir_handle); + + _down = first_entry; + _scanned = true; +} + + +const void* NtObjDirectory::get_next_path_component(const void* p) +{ + LPCTSTR s = (LPCTSTR) p; + + while(*s && *s!=TEXT('\\') && *s!=TEXT('/')) + ++s; + + while(*s==TEXT('\\') || *s==TEXT('/')) + ++s; + + if (!*s) + return NULL; + + return s; +} + + +Entry* NtObjDirectory::find_entry(const void* p) +{ + LPCTSTR name = (LPCTSTR)p; + + for(Entry*entry=_down; entry; entry=entry->_next) { + LPCTSTR p = name; + LPCTSTR q = entry->_data.cFileName; + + do { + if (!*p || *p==TEXT('\\') || *p==TEXT('/')) + return entry; + } while(tolower(*p++) == tolower(*q++)); + + p = name; + q = entry->_data.cAlternateFileName; + + do { + if (!*p || *p==TEXT('\\') || *p==TEXT('/')) + return entry; + } while(tolower(*p++) == tolower(*q++)); + } + + return NULL; +} + + + // get full path of specified directory entry +bool NtObjEntry::get_path(PTSTR path) const +{ + int level = 0; + int len = 0; + int l = 0; + LPCTSTR name = NULL; + TCHAR buffer[MAX_PATH]; + + const Entry* entry; + for(entry=this; entry; level++) { + l = 0; + + if (entry->_etype == ET_NTOBJS) { + name = entry->_data.cFileName; + + for(LPCTSTR s=name; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++) + ++l; + + if (!entry->_up) + break; + } else { + if (entry->get_path(buffer)) { + l = _tcslen(buffer); + name = buffer; + + /* special handling of drive names */ + if (l>0 && buffer[l-1]=='\\' && path[0]=='\\') + --l; + + memmove(path+l, path, len*sizeof(TCHAR)); + memcpy(path, name, l*sizeof(TCHAR)); + len += l; + } + + entry = NULL; + break; + } + + if (l > 0) { + memmove(path+l+1, path, len*sizeof(TCHAR)); + memcpy(path+1, name, l*sizeof(TCHAR)); + len += l+1; + + if (entry->_up && !(entry->_up->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) // a NTFS stream? + path[0] = TEXT(':'); + else + path[0] = TEXT('\\'); + } + + entry = entry->_up; + } + + if (entry) { + memmove(path+l, path, len*sizeof(TCHAR)); + memcpy(path, name, l*sizeof(TCHAR)); + len += l; + } + + if (!level) + path[len++] = TEXT('\\'); + + path[len] = TEXT('\0'); + + return true; +} diff --git a/reactos/subsys/system/explorer/shell/ntobjfs.h b/reactos/subsys/system/explorer/shell/ntobjfs.h new file mode 100644 index 00000000000..176b25a9d69 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/ntobjfs.h @@ -0,0 +1,128 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // ntobjfs.h + // + // Martin Fuchs, 31.01.2004 + // + + +enum OBJECT_TYPE { + DIRECTORY_OBJECT, SYMBOLICLINK_OBJECT, + MUTANT_OBJECT, SECTION_OBJECT, EVENT_OBJECT, SEMAPHORE_OBJECT, + TIMER_OBJECT, KEY_OBJECT, EVENTPAIR_OBJECT, IOCOMPLETITION_OBJECT, + DEVICE_OBJECT, FILE_OBJECT, CONTROLLER_OBJECT, PROFILE_OBJECT, + TYPE_OBJECT, DESKTOP_OBJECT, WINDOWSTATION_OBJECT, DRIVER_OBJECT, + TOKEN_OBJECT, PROCESS_OBJECT, THREAD_OBJECT, ADAPTER_OBJECT, PORT_OBJECT, + + UNKNOWN_OBJECT_TYPE=-1 +}; + +struct RtlAnsiString { + WORD string_len; + WORD alloc_len; + LPSTR string_ptr; +}; + +struct RtlUnicodeString { + WORD string_len; + WORD alloc_len; + LPWSTR string_ptr; +}; + +struct NtObjectInfo { + RtlUnicodeString name; + RtlUnicodeString type; + BYTE padding[16]; +}; + +struct OpenStruct { + DWORD size; + DWORD _1; + RtlUnicodeString* string; + DWORD _3; + DWORD _4; + DWORD _5; +}; + +struct NtObject { + DWORD _0; + DWORD _1; + DWORD handle_count; + DWORD reference_count; + DWORD _4; + DWORD _5; + DWORD _6; + DWORD _7; + DWORD _8; + DWORD _9; + DWORD _A; + DWORD _B; + FILETIME creation_time; +}; + + +#ifndef ATTRIBUTE_SYMBOLIC_LINK +#define ATTRIBUTE_SYMBOLIC_LINK 0x40000000 +#define ATTRIBUTE_EXECUTABLE 0x80000000 +#endif + + + /// NtObj file system file-entry +struct NtObjEntry : public Entry +{ + NtObjEntry(Entry* parent, OBJECT_TYPE type) : Entry(parent, ET_NTOBJS), _type(type) {} + + OBJECT_TYPE _type; + +protected: + NtObjEntry(OBJECT_TYPE type) : Entry(ET_NTOBJS), _type(type) {} + + virtual bool get_path(PTSTR path) const; +}; + + + /// NtObj file system directory-entry +struct NtObjDirectory : public NtObjEntry, public Directory +{ + NtObjDirectory(LPCTSTR root_path) + : NtObjEntry(DIRECTORY_OBJECT) + { + _path = _tcsdup(root_path); + } + + NtObjDirectory(Entry* parent, LPCTSTR path) + : NtObjEntry(parent, DIRECTORY_OBJECT) + { + _path = _tcsdup(path); + } + + ~NtObjDirectory() + { + free(_path); + _path = NULL; + } + + virtual void read_directory(int scan_flags=SCAN_ALL); + virtual const void* get_next_path_component(const void*); + virtual Entry* find_entry(const void*); +}; diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.h b/reactos/subsys/system/explorer/shell/shellbrowser.h index e939900fe4c..5cfe04cd81c 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.h +++ b/reactos/subsys/system/explorer/shell/shellbrowser.h @@ -41,7 +41,7 @@ struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl { #ifndef _NO_MDI ChildWindow* child = ChildWindow::create(hmdiclient, info._pos.rcNormalPosition, - WINDOW_CREATOR_INFO(ShellBrowserChild,ShellChildWndInfo), CLASSNAME_CHILDWND, NULL, &info); + WINDOW_CREATOR_INFO(ShellBrowserChild,ShellChildWndInfo), CLASSNAME_CHILDWND, NULL, &info); #else ///@todo SDI implementation #endif