shell/unixfs.cpp
shell/winfs.cpp
shell/ntobjfs.cpp
+ shell/regfs.cpp
shell/startup.c
taskbar/desktopbar.cpp
taskbar/quicklaunch.cpp
unixfs.o \
shellfs.o \
ntobjfs.o \
+ regfs.o \
mainframe.o \
filechild.o \
pane.o \
unixfs.o \
shellfs.o \
ntobjfs.o \
+ regfs.o \
mainframe.o \
filechild.o \
pane.o \
shell/pane.cpp \
shell/shellbrowser.cpp \
shell/ntobjfs.cpp \
+ shell/regfs.cpp \
taskbar/desktopbar.cpp \
taskbar/taskbar.cpp \
taskbar/startmenu.cpp \
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
+31.01.2004 m. fuchs included Registry as virtual file system
# End Source File
# Begin Source File
+SOURCE=.\shell\regfs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\shell\regfs.h
+# End Source File
+# Begin Source File
+
SOURCE=.\shell\shellbrowser.cpp
# End Source File
# Begin Source File
#define ID_DRIVE_SHELL_NS 0x9001
#define ID_DRIVE_UNIX_FS 0x9002
#define ID_DRIVE_NTOBJ_NS 0x9003
-#define ID_DRIVE_FIRST 0x9004
+#define ID_DRIVE_REGISTRY 0x9004
+#define ID_DRIVE_FIRST 0x9005
#define ID_ABOUT_WINDOWS 40002
#define ID_ABOUT_EXPLORER 40003
#define ID_DESKTOPBAR_SETTINGS 40005
} while(next);
}
}
+
+
+const void* Directory::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;
+}
ET_UNIX,
#endif
ET_SHELL,
- ET_NTOBJS
+ ET_NTOBJS,
+ ET_REGISTRY
};
enum SORT_ORDER {
Directory() : _path(NULL) {}
virtual ~Directory() {}
+ // default implementation like that of Windows file systems
+ virtual const void* get_next_path_component(const void*);
+
void* _path;
};
#include "../explorer.h"
#include "../globals.h"
#include "ntobjfs.h"
+#include "regfs.h"
#include "../explorer_intres.h"
}
+RegistryChildWndInfo::RegistryChildWndInfo(LPCTSTR path)
+ : FileChildWndInfo(path)
+{
+ _etype = ET_REGISTRY;
+}
+
+
FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
: ChildWindow(hwnd)
{
_root._entry = new NtObjDirectory(_root._path);
entry = _root._entry->read_tree(info._path, SORT_NAME/*_sortOrder*/);
}
+ else if (info._etype == ET_REGISTRY)
+ {
+ _root._drive_type = DRIVE_UNKNOWN;
+
+ _tsplitpath(info._path, drv, NULL, NULL, NULL);
+ lstrcat(drv, TEXT("\\"));
+ lstrcpy(_root._volname, TEXT("Registry"));
+ lstrcpy(_root._fs, TEXT("Registry"));
+ lstrcpy(_root._path, drv);
+ _root._entry = new RegistryRoot();
+ entry = _root._entry->read_tree(info._path, SORT_NAME/*_sortOrder*/);
+ }
else //if (info._etype == ET_WINDOWS)
{
_root._drive_type = GetDriveType(info._path);
NtObjChildWndInfo(LPCTSTR path);
};
+ /// information structure for creation of FileChildWindow for the Registry
+struct RegistryChildWndInfo : public FileChildWndInfo
+{
+ RegistryChildWndInfo(LPCTSTR path);
+};
+
/// MDI child window displaying file lists
struct FileChildWindow : public ChildWindow
++drivebarBtn.iString;
}
+ // insert Registry button
+ SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("Registry\0"));
+
+ drivebarBtn.idCommand = ID_DRIVE_REGISTRY;
+ SendMessage(_hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
+ ++drivebarBtn.iString;
+
// register windows drive root strings
SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)_drives);
TCHAR path[MAX_PATH];
FileChildWindow* child;
- if (activate_fs_window(TEXT("unixfs")))
+ if (activate_child_window(TEXT("unixfs")))
break;
getcwd(path, MAX_PATH);
case ID_DRIVE_SHELL_NS: {
TCHAR path[MAX_PATH];
- if (activate_fs_window(TEXT("Shell")))
+ if (activate_child_window(TEXT("Shell")))
break;
GetCurrentDirectory(MAX_PATH, path);
break;}
case ID_DRIVE_NTOBJ_NS: {
- if (activate_fs_window(TEXT("NTOBJ")))
+ if (activate_child_window(TEXT("NTOBJ")))
break;
#ifndef _NO_MDI
#endif
break;}
+ case ID_DRIVE_REGISTRY: {
+ if (activate_child_window(TEXT("Registry")))
+ break;
+
+#ifndef _NO_MDI
+ FileChildWindow::create(_hmdiclient, RegistryChildWndInfo(TEXT("\\")));
+#else
+ ///@todo SDI implementation
+#endif
+ break;}
+
case ID_DRIVE_DESKTOP: {
TCHAR path[MAX_PATH];
- if (activate_fs_window(TEXT("Desktop")))
+ if (activate_child_window(TEXT("Desktop")))
break;
GetCurrentDirectory(MAX_PATH, path);
return false;
}
-bool MainFrame::activate_fs_window(LPCTSTR filesys)
+bool MainFrame::activate_child_window(LPCTSTR filesys)
{
HWND child_wnd;
void toggle_child(HWND hwnd, UINT cmd, HWND hchild);
bool activate_drive_window(LPCTSTR path);
- bool activate_fs_window(LPCTSTR filesys);
+ bool activate_child_window(LPCTSTR filesys);
void resize_frame_rect(PRECT prect);
void resize_frame(int cx, int cy);
#include "entries.h"
#include "ntobjfs.h"
+#include "regfs.h"
#define CONSTRUCT_NTDLLFCT(x) x(TEXT("NTDLL"), #x)
if (!(*g_NTDLL->NtQueryDirectoryObject)(dir_handle, info, 0x800, TRUE, TRUE, &idx1, &idx2)) {
WIN32_FIND_DATA w32fd;
Entry* last = NULL;
- NtObjEntry* entry;
+ Entry* entry;
do {
memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
else if (type == KEY_OBJECT) {
w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
- entry = new NtObjDirectory(this, buffer);
-
-#if 0 ///@todo mount registry hives
- *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
+ entry = new RegistryRoot(this, buffer);
}
else
entry = new NtObjEntry(this, type);
- entry->_bhfi_valid = false;
-
HANDLE handle;
#ifdef UNICODE
}
-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;
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('\\');
+ path[0] = TEXT('\\');
}
entry = entry->_up;
}
virtual void read_directory(int scan_flags=SCAN_ALL);
- virtual const void* get_next_path_component(const void*);
virtual Entry* find_entry(const void*);
};
--- /dev/null
+/*
+ * 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 "regfs.h"
+
+
+void RegDirectory::read_directory(int scan_flags)
+{
+ CONTEXT("RegDirectory::read_directory()");
+
+ Entry* first_entry = NULL;
+ int level = _level + 1;
+
+ TCHAR buffer[MAX_PATH];
+
+ _tcscpy(buffer, (LPCTSTR)_path);
+ LPTSTR p = buffer + _tcslen(buffer);
+
+ HKEY hKey;
+
+ if (!RegOpenKeyEx(_hKeyRoot, *buffer=='\\'?buffer+1:buffer, 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hKey)) {
+ if (p[-1] != '\\')
+ *p++ = '\\';
+
+ TCHAR name[MAX_PATH], class_name[MAX_PATH];
+ WIN32_FIND_DATA w32fd;
+ Entry* last = NULL;
+ RegEntry* entry;
+
+ for(int idx=0; ; ++idx) {
+ memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
+
+ DWORD name_len = MAX_PATH;
+ DWORD class_len = MAX_PATH;
+
+ if (RegEnumKeyEx(hKey, idx, name, &name_len, 0, class_name, &class_len, &w32fd.ftLastWriteTime))
+ break;
+
+ w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+
+ _tcscpy(p, name);
+ ///@todo class_name -> _entry->_class_name
+
+ lstrcpy(w32fd.cFileName, p);
+
+ entry = new RegDirectory(this, buffer, _hKeyRoot);
+
+ 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;
+ }
+
+ DWORD type;
+ for(int idx=0; ; ++idx) {
+ DWORD name_len = MAX_PATH;
+
+ if (RegEnumValue(hKey, idx, name, &name_len, 0, &type, NULL, NULL))
+ break;
+
+ memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
+
+ _tcscpy(p, name);
+ ///@todo type -> _entry->_class_name
+
+ lstrcpy(w32fd.cFileName, p);
+
+ entry = new RegEntry(this);
+
+ 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;
+ }
+
+ if (last)
+ last->_next = NULL;
+
+ RegCloseKey(hKey);
+ }
+
+ _down = first_entry;
+ _scanned = true;
+}
+
+
+Entry* RegDirectory::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 registry entry
+bool RegEntry::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_REGISTRY) {
+ 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;
+
+ 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;
+}
+
+BOOL RegEntry::launch_entry(HWND hwnd, UINT nCmdShow)
+{
+ return FALSE;
+}
+
+
+RegDirectory::RegDirectory(Entry* parent, LPCTSTR path, HKEY hKeyRoot)
+ : RegEntry(parent),
+ _hKeyRoot(hKeyRoot)
+{
+ _path = _tcsdup(path);
+
+ memset(&_data, 0, sizeof(WIN32_FIND_DATA));
+ _data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+}
+
+
+void RegistryRoot::read_directory(int scan_flags)
+{
+ Entry *entry, *last;
+ int level = _level + 1;
+
+ _data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+
+ entry = new RegDirectory(this, TEXT("\\"), HKEY_CURRENT_USER);
+ _tcscpy(entry->_data.cFileName, TEXT("HKEY_CURRENT_USER"));
+ entry->_level = level;
+
+ _down = entry;
+ last = entry;
+
+ entry = new RegDirectory(this, TEXT("\\"), HKEY_LOCAL_MACHINE);
+ _tcscpy(entry->_data.cFileName, TEXT("HKEY_LOCAL_MACHINE"));
+ entry->_level = level;
+
+ last->_next = entry;
+ last = entry;
+
+ entry = new RegDirectory(this, TEXT("\\"), HKEY_CLASSES_ROOT);
+ _tcscpy(entry->_data.cFileName, TEXT("HKEY_CLASSES_ROOT"));
+ entry->_level = level;
+
+ last->_next = entry;
+ last = entry;
+
+ entry = new RegDirectory(this, TEXT("\\"), HKEY_USERS);
+ _tcscpy(entry->_data.cFileName, TEXT("HKEY_USERS"));
+ entry->_level = level;
+
+ last->_next = entry;
+ last = entry;
+/*
+ entry = new RegDirectory(this, TEXT("\\"), HKEY_PERFORMANCE_DATA);
+ _tcscpy(entry->_data.cFileName, TEXT("HKEY_PERFORMANCE_DATA"));
+ entry->_level = level;
+
+ last->_next = entry;
+ last = entry;
+*/
+ entry = new RegDirectory(this, TEXT("\\"), HKEY_CURRENT_CONFIG);
+ _tcscpy(entry->_data.cFileName, TEXT("HKEY_CURRENT_CONFIG"));
+ entry->_level = level;
+
+ last->_next = entry;
+ last = entry;
+/*
+ entry = new RegDirectory(this, TEXT("\\"), HKEY_DYN_DATA);
+ _tcscpy(entry->_data.cFileName, TEXT("HKEY_DYN_DATA"));
+ entry->_level = level;
+
+ last->_next = entry;
+ last = entry;
+*/
+ last->_next = NULL;
+}
--- /dev/null
+/*
+ * 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
+ //
+ // regfs.h
+ //
+ // Martin Fuchs, 31.01.2004
+ //
+
+
+ /// Registry entry
+struct RegEntry : public Entry
+{
+ RegEntry(Entry* parent) : Entry(parent, ET_REGISTRY) {}
+
+protected:
+ RegEntry() : Entry(ET_REGISTRY) {}
+
+ virtual bool get_path(PTSTR path) const;
+ virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow);
+};
+
+
+ /// Registry key entry
+struct RegDirectory : public RegEntry, public Directory
+{
+ RegDirectory(Entry* parent, LPCTSTR path, HKEY hKeyRoot);
+
+ ~RegDirectory()
+ {
+ free(_path);
+ _path = NULL;
+ }
+
+ virtual void read_directory(int scan_flags=SCAN_ALL);
+ virtual Entry* find_entry(const void*);
+
+protected:
+ HKEY _hKeyRoot;
+};
+
+
+ /// Registry key entry
+struct RegistryRoot : public RegEntry, public Directory
+{
+ RegistryRoot()
+ {
+ }
+
+ RegistryRoot(Entry* parent, LPCTSTR path)
+ : RegEntry(parent)
+ {
+ _path = _tcsdup(path);
+ }
+
+ ~RegistryRoot()
+ {
+ free(_path);
+ _path = NULL;
+ }
+
+ virtual void read_directory(int scan_flags=SCAN_ALL);
+};
stream_entry->_expanded = false;
stream_entry->_scanned = false;
stream_entry->_level = entry->_level + 1;
- stream_entry->_bhfi_valid = false;
*pnext = stream_entry;
pnext = &stream_entry->_next;
entry->_expanded = false;
entry->_scanned = false;
entry->_level = level;
- entry->_bhfi_valid = false;
if (scan_flags & SCAN_DO_ACCESS) {
HANDLE hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
}
-const void* WinDirectory::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* WinDirectory::find_entry(const void* p)
{
LPCTSTR name = (LPCTSTR)p;
}
virtual void read_directory(int scan_flags=SCAN_ALL);
- virtual const void* get_next_path_component(const void*);
virtual Entry* find_entry(const void*);
};