Registry Explorer (console tool) by Nedko Arnaoudov added to the system utilities...
authorEmanuele Aliberti <ea@iol.it>
Wed, 4 Oct 2000 21:04:31 +0000 (21:04 +0000)
committerEmanuele Aliberti <ea@iol.it>
Wed, 4 Oct 2000 21:04:31 +0000 (21:04 +0000)
Also here: http://www.geocities.com/registryexplorer/

svn path=/trunk/; revision=1375

53 files changed:
rosapps/sysutils/makefile
rosapps/sysutils/regexpl/ArgumentParser.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ArgumentParser.h [new file with mode: 0644]
rosapps/sysutils/regexpl/Console.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/Console.h [new file with mode: 0644]
rosapps/sysutils/regexpl/CrtSupplement.c [new file with mode: 0644]
rosapps/sysutils/regexpl/Makefile [new file with mode: 0644]
rosapps/sysutils/regexpl/RegistryExplorer.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/RegistryExplorer.h [new file with mode: 0644]
rosapps/sysutils/regexpl/RegistryKey.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/RegistryKey.h [new file with mode: 0644]
rosapps/sysutils/regexpl/RegistryTree.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/RegistryTree.h [new file with mode: 0644]
rosapps/sysutils/regexpl/SecurityDescriptor.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/SecurityDescriptor.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommand.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommand.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandChangeKey.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandConnect.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandConnect.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDACL.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDACL.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDOKA.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDOKA.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDeleteKey.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDeleteValue.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDir.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandDir.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandExit.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandExit.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandHelp.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandHelp.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandNewKey.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandNewKey.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandOwner.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandOwner.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandSACL.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandSACL.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandSetValue.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandSetValue.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandValue.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandValue.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandVersion.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandVersion.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandsLinkedList.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/ShellCommandsLinkedList.h [new file with mode: 0644]
rosapps/sysutils/regexpl/TextHistory.cpp [new file with mode: 0644]
rosapps/sysutils/regexpl/TextHistory.h [new file with mode: 0644]
rosapps/sysutils/regexpl/ph.h [new file with mode: 0644]
rosapps/sysutils/regexpl/regexpl.rc [new file with mode: 0644]

index df4e6c7..0714e72 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.6 2000/09/11 20:17:02 ea Exp $
+# $Id: makefile,v 1.7 2000/10/04 21:04:30 ea Exp $
 #
 # ReactOS System Utilities
 #
@@ -42,10 +42,12 @@ TARGET=\
        pedump.exe      \
        shutdown.exe    \
        chkdsk.exe      \
-       format.exe
+       format.exe      \
+       regexpl/regexpl$(EXE_POSTFIX)
 
 all: $(TARGET)
 
+
 # By Mark Russinovich
 
 chkdsk.exe: chkdsk.o win32err.o wmain.o chkdsk.coff
@@ -144,6 +146,11 @@ ldd.exe: ldd.o win32err.o ldd.coff
 
 ldd.o: ldd.c
 
+# By Nedko Arnaoudov
+
+regexpl/regexpl$(EXE_POSTFIX):
+       make -C regexpl
+
 #---
 
 CLEAN_FILES = *.o *.exe *.sym
diff --git a/rosapps/sysutils/regexpl/ArgumentParser.cpp b/rosapps/sysutils/regexpl/ArgumentParser.cpp
new file mode 100644 (file)
index 0000000..d28c6a4
--- /dev/null
@@ -0,0 +1,94 @@
+/* $Id: ArgumentParser.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ArgumentParser.cpp: implementation of the CArgumentParser class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ArgumentParser.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CArgumentParser::CArgumentParser()
+{
+       m_pchArgumentList = NULL;
+       m_pchArgumentListEnd = NULL;
+       m_pchArgument = NULL;
+}
+
+CArgumentParser::~CArgumentParser()
+{
+}
+
+void CArgumentParser::SetArgumentList(TCHAR *pchArguments)
+{
+       TCHAR *pch = m_pchArgumentList = pchArguments;
+       m_pchArgumentListEnd = pchArguments + _tcslen(pchArguments);
+
+       BOOL blnLongArg = FALSE;
+       while (*pch)
+       {
+               switch(*pch)
+               {
+               case L'\"':
+                       if (blnLongArg) blnLongArg = FALSE;
+                       else blnLongArg = TRUE;
+                       break;
+               case L' ':
+               case L'\t':
+               case L'\r':
+               case L'\n':
+                       if (!blnLongArg) *pch = 0;
+                       break;
+               }
+               pch++;
+       }
+
+       ResetArgumentIteration();
+}
+
+TCHAR * CArgumentParser::GetNextArgument()
+{
+       ASSERT(m_pchArgumentList);              // call SetArgumentList() before calling this function
+       ASSERT(m_pchArgumentListEnd);   // call SetArgumentList() before calling this function
+       ASSERT(m_pchArgumentListEnd >= m_pchArgumentList);
+
+       // if this is begin of iteration
+       if (!m_pchArgument) m_pchArgument = m_pchArgumentList;
+
+       while(m_pchArgument)
+       {
+               if (m_pchArgument > m_pchArgumentListEnd)
+               {       // if end of arguments list reached
+                       ASSERT(m_pchArgument - 1 == m_pchArgumentListEnd);
+                       break;
+               }
+
+               TCHAR *pchArg = m_pchArgument;
+
+               // Next argument
+               m_pchArgument += _tcslen(m_pchArgument)+1;
+
+               if(*pchArg)
+               {       // if argument is not an empty string
+                       return pchArg;
+               }
+       }
+
+       return NULL;
+}
+
+void CArgumentParser::ResetArgumentIteration()
+{
+       m_pchArgument = NULL;
+}
diff --git a/rosapps/sysutils/regexpl/ArgumentParser.h b/rosapps/sysutils/regexpl/ArgumentParser.h
new file mode 100644 (file)
index 0000000..4495f2f
--- /dev/null
@@ -0,0 +1,40 @@
+// ArgumentParser.h: interface for the CArgumentParser class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(ARGUMENTPARSER_H__D4C1F637_BEBF_11D3_91EE_204C4F4F5020__INCLUDED_)
+#define ARGUMENTPARSER_H__D4C1F637_BEBF_11D3_91EE_204C4F4F5020__INCLUDED_
+
+// Use this class to create parser of command line object
+class CArgumentParser
+{
+public:
+       // Call this function to specify buffer containing the command line to be parsed
+       // Parameters:
+       //      pchArguments - pointer to buffer containing the command line. This buffer is modified by object,
+       //                                      and must not be accessed extrenaly when object is used, unless you interate it
+       //                                      only once and modify only substrings returned by GetNextArgument.
+       //
+       // Remarks:
+       // This object can be reused by setting the buffer multiple times.
+       void SetArgumentList(TCHAR *pchArguments);
+
+       // Call this function to reset argument iteration. You don't need to call this function after call
+       // to set SetArgumentList, because calling SetArgumentList resets iteration with new buffer.
+       void ResetArgumentIteration();
+
+       // Call this function to get next argument from command line.
+       //
+       // Returns:
+       //      Function returns next argument. If this is first call after calling SetArgumentList or
+       //      ResetArgumentIteration, functions returns the first argument (The command itself ?).
+       TCHAR * GetNextArgument();
+       CArgumentParser();
+       virtual ~CArgumentParser();
+private:
+       TCHAR *m_pchArgumentList;               // points to begin of argumet list
+       const TCHAR *m_pchArgumentListEnd;      // points to last 0 in argument list
+       TCHAR *m_pchArgument;
+};
+
+#endif // !defined(ARGUMENTPARSER_H__D4C1F637_BEBF_11D3_91EE_204C4F4F5020__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/Console.cpp b/rosapps/sysutils/regexpl/Console.cpp
new file mode 100644 (file)
index 0000000..c7baa43
--- /dev/null
@@ -0,0 +1,1021 @@
+/* $Id: Console.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// Console.cpp: implementation of the CConsole class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "Console.h"
+/*
+TCHAR * _tcsnchr(const TCHAR *string, TCHAR ch, int count)
+{
+       while (count--)
+       {
+               if (*string == 0) return NULL;
+               if (*string == ch) return const_cast <char *>(string);
+               string++;
+       }
+       return NULL;
+}*/
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CConsole::CConsole()
+{
+       m_hStdIn = INVALID_HANDLE_VALUE;
+       m_hStdOut = INVALID_HANDLE_VALUE;
+       m_blnInsetMode = TRUE;          // Insert
+//     m_blnInsetMode = FALSE;         // Overwrite
+       m_dwInsertModeCursorHeight = 15;
+       m_dwOverwriteModeCursorHeight = 100;
+//     m_Lines = 0;
+       m_pchBuffer = NULL;
+       m_pchBuffer1 = NULL;
+       m_pchBuffer2 = NULL;
+       m_pfReplaceCompletionCallback = NULL;
+       m_blnMoreMode = TRUE;
+}
+
+CConsole::~CConsole()
+{
+       if (m_hStdIn != INVALID_HANDLE_VALUE)
+               VERIFY(CloseHandle(m_hStdIn));
+       if (m_hStdOut != INVALID_HANDLE_VALUE)
+               VERIFY(CloseHandle(m_hStdOut));
+       if (m_pchBuffer)
+               delete m_pchBuffer;
+       if (m_pchBuffer1)
+               delete m_pchBuffer1;
+       if (m_pchBuffer2)
+               delete m_pchBuffer2;
+}
+
+BOOL CConsole::Write(const TCHAR *p, DWORD dwChars)
+{
+       if (m_hStdOut == INVALID_HANDLE_VALUE)
+               return FALSE;
+       if (m_hStdIn == INVALID_HANDLE_VALUE)
+               return FALSE;
+       if (p == NULL)
+       {
+               ASSERT(FALSE);
+               return FALSE;
+       }
+       DWORD dwCharsToWrite = (dwChars)?dwChars:_tcslen(p);
+       DWORD dwCharsWrittenAdd = 0;
+       BOOL ret = TRUE;
+       while (dwCharsToWrite && (!m_blnDisableWrite))
+       {
+               switch(p[dwCharsWrittenAdd])
+               {
+               case _T('\n'):
+                       m_CursorPosition.Y++;
+                       m_CursorPosition.X = 0;
+                       break;
+               case _T('\r'):
+                       break;
+               case _T('\t'):
+                       do
+                       {
+                               if (!Write(_T(" "))) return FALSE;
+                       }
+                       while ((m_CursorPosition.X % 8) && (!m_blnDisableWrite));
+                       dwCharsWrittenAdd++;
+                       dwCharsToWrite--;
+                       continue;
+               default:
+                       {
+                               if (!WriteChar(p[dwCharsWrittenAdd])) return FALSE;
+                               m_CursorPosition.X++;
+                       }
+               }
+               if (m_CursorPosition.X == m_BufferSize.X)
+               {
+                       m_CursorPosition.Y++;
+                       m_CursorPosition.X = 0;
+               }
+               if (m_CursorPosition.Y == m_BufferSize.Y)
+               {
+                       ASSERT(m_CursorPosition.X == 0);
+                       SMALL_RECT Src;
+                       Src.Left = 0;
+                       Src.Right = (SHORT)(m_BufferSize.X-1);
+                       Src.Top = 1;
+                       Src.Bottom = (SHORT)(m_BufferSize.Y-1);
+                       CHAR_INFO ci;
+#ifdef UNICODE
+                       ci.Char.UnicodeChar = L' ';
+#else
+                       ci.Char.AsciiChar = ' ';
+#endif
+                       ci.Attributes = 0;
+                       COORD Dest;
+                       Dest.X = 0;
+                       Dest.Y = 0;
+                       if (!ScrollConsoleScreenBuffer(m_hStdOut,&Src,NULL,Dest,&ci)) return FALSE;
+                       m_CursorPosition.Y--;
+                       m_LinesScrolled++;
+               }
+               if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE;
+               VERIFY(WriteChar(_T(' ')));
+               if ((m_blnMoreMode)&&(m_CursorPosition.X == 0))
+               {
+                       m_Lines++;
+                       if (m_Lines >= m_BufferSize.Y-1)
+                       {
+                               ASSERT(m_Lines == m_BufferSize.Y-1);
+                               m_Lines = 0;
+                               VERIFY(WriteString(_T("-- More --"),m_CursorPosition));
+                               VERIFY(FlushInputBuffer());
+
+                               CONSOLE_CURSOR_INFO cci;
+                               cci.bVisible = FALSE;
+                               cci.dwSize = 10;
+                               VERIFY(SetConsoleCursorInfo(m_hStdOut,&cci));
+
+                               INPUT_RECORD InputRecord;
+                               DWORD dwRecordsReaded;
+                               while ((ret = ReadConsoleInput(m_hStdIn,&InputRecord,1,&dwRecordsReaded)) != FALSE)
+                               {
+                                       ASSERT(dwRecordsReaded == 1);
+                                       if (dwRecordsReaded != 1) break;
+                                       if (InputRecord.EventType != KEY_EVENT) continue;
+                                       if (!InputRecord.Event.KeyEvent.bKeyDown) continue;
+#ifdef UNICODE
+                                       TCHAR ch = InputRecord.Event.KeyEvent.uChar.UnicodeChar;
+#else
+                                       TCHAR ch = InputRecord.Event.KeyEvent.uChar.AsciiChar;
+#endif
+                                       if (ch == VK_CANCEL)
+                                       {
+                                               VERIFY(GenerateConsoleCtrlEvent(CTRL_C_EVENT,0));
+                                               continue;
+                                       }
+                                       if (ch) break;
+                               }
+                               VERIFY(WriteString(_T("          "),m_CursorPosition));
+                               m_CursorPosition.X = 0;
+
+                               cci.bVisible = TRUE;
+                               cci.dwSize = m_blnInsetMode?m_dwInsertModeCursorHeight:m_dwOverwriteModeCursorHeight;
+                               VERIFY(SetConsoleCursorInfo(m_hStdOut,&cci));
+                       }
+               }
+               dwCharsWrittenAdd++;
+               dwCharsToWrite--;
+       }
+       return ret;
+}
+
+BOOL CConsole::SetTitle(TCHAR *p)
+{
+       return SetConsoleTitle(p);
+}
+
+BOOL CConsole::SetTextAttribute(WORD wAttributes)
+{
+       m_wAttributes = wAttributes;
+       return TRUE;
+}
+/*
+BOOL CConsole::SetInputMode(DWORD dwMode)
+{
+       return SetConsoleMode(m_hStdIn,dwMode);
+}
+
+BOOL CConsole::SetOutputMode(DWORD dwMode)
+{
+       return SetConsoleMode(m_hStdOut,dwMode);
+}*/
+
+BOOL CConsole::FlushInputBuffer()
+{
+       if (m_hStdIn == INVALID_HANDLE_VALUE) return FALSE;
+       return FlushConsoleInputBuffer(m_hStdIn);
+}
+
+BOOL CConsole::ReadLine()
+{
+       if (m_hStdIn == INVALID_HANDLE_VALUE) return FALSE;
+       if (m_hStdOut == INVALID_HANDLE_VALUE) return FALSE;
+       if (m_dwBufferSize == 0)
+       {
+               ASSERT(FALSE);
+               return FALSE;
+       }
+       if (m_pchBuffer == NULL)
+       {
+               ASSERT(FALSE);
+               return FALSE;
+       }
+       if (m_pchBuffer1 == NULL)
+       {
+               ASSERT(FALSE);
+               return FALSE;
+       }
+       if (!FlushConsoleInputBuffer(m_hStdIn)) return FALSE;
+
+       COORD FristCharCursorPosition = m_CursorPosition;
+#define X_CURSOR_POSITION_FROM_OFFSET(ofs)     USHORT(((FristCharCursorPosition.X + ofs)%m_BufferSize.X))
+#define Y_CURSOR_POSITION_FROM_OFFSET(ofs)     USHORT((FristCharCursorPosition.Y + (FristCharCursorPosition.X + ofs)/m_BufferSize.X))
+//#define OFFSET_FROM_CURSOR_POSITION(pos)     ((pos.Y-FristCharCursorPosition.Y)*m_BufferSize.X+pos.X-FristCharCursorPosition.X)
+
+       DWORD dwRecordsReaded;
+       DWORD dwCurrentCharOffset = 0;
+       DWORD dwLastCharOffset = 0;
+       BOOL ret;
+
+       BOOL blnCompletionMode = FALSE;
+//     unsigned __int64 nCompletionIndex = 0;
+       unsigned long long nCompletionIndex = 0;
+       DWORD dwCompletionOffset = 0;
+       DWORD dwCompletionStringSize = 0;
+       COORD CompletionPosition = FristCharCursorPosition;
+
+       m_LinesScrolled = 0;
+       BOOL blnOldMoreMode = m_blnMoreMode;
+       m_blnMoreMode = FALSE;
+
+       DWORD dwHistoryIndex = 0;
+
+       INPUT_RECORD InputRecord;
+       while ((ret = ReadConsoleInput(m_hStdIn,&InputRecord,1,&dwRecordsReaded)) != FALSE)
+       {
+               ASSERT(dwRecordsReaded == 1);
+               if (dwRecordsReaded != 1) return FALSE;
+               if (InputRecord.EventType != KEY_EVENT) continue;
+               if (!InputRecord.Event.KeyEvent.bKeyDown) continue;
+#ifdef UNICODE
+               TCHAR ch = InputRecord.Event.KeyEvent.uChar.UnicodeChar;
+#else
+               TCHAR ch = InputRecord.Event.KeyEvent.uChar.AsciiChar;
+#endif
+KeyRepeat:
+               if (m_LinesScrolled)
+               {
+                       if (m_LinesScrolled > FristCharCursorPosition.Y) return FALSE;
+                       FristCharCursorPosition.Y = SHORT(FristCharCursorPosition.Y - m_LinesScrolled);
+                       if (m_LinesScrolled > CompletionPosition.Y) return FALSE;
+                       CompletionPosition.Y = SHORT(CompletionPosition.Y - m_LinesScrolled);
+                       m_LinesScrolled = 0;
+               }
+//             char Buf[1024];
+//             sprintf(Buf,"wVirtualKeyCode = %u\nchar = %u\n\n",InputRecord.Event.KeyEvent.wVirtualKeyCode,ch);
+//             OutputDebugString(Buf);
+               if ((ch == 0x16)&&(InputRecord.Event.KeyEvent.wVirtualKeyCode == 'V'))
+               {
+                       goto Paste;
+               }
+               else if (ch == 0)
+               {
+                       if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_INSERT)
+                       {
+                               if (!(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED))
+                               {
+                                       VERIFY(SetInsertMode(!m_blnInsetMode));
+                               }
+                               else
+                               {
+                                       if (blnCompletionMode) blnCompletionMode = FALSE;
+
+Paste:
+                                       if (!IsClipboardFormatAvailable(
+#ifdef UNICODE
+                                               CF_UNICODETEXT
+#else
+                                               CF_TEXT
+#endif
+                                               )) 
+                                               continue; 
+                                       if (!OpenClipboard(NULL)) 
+                                               continue; 
+                                       const TCHAR *pch = NULL;
+
+                                       HANDLE hglb = GetClipboardData(
+#ifdef UNICODE
+                                               CF_UNICODETEXT
+#else
+                                               CF_TEXT
+#endif
+                                               );
+                                       if (hglb != NULL) 
+                                       { 
+                                               LPTSTR lptstr = (LPTSTR)GlobalLock(hglb);
+                                               if (lptstr != NULL) 
+                                               {
+                                                       _tcsncpy(m_pchBuffer1,lptstr,m_dwBufferSize);
+                                                       m_pchBuffer1[m_dwBufferSize-1] = 0;
+                                                       pch = m_pchBuffer1;
+                                                       GlobalUnlock(hglb); 
+                                               } 
+                                       } 
+                                       CloseClipboard();
+
+                                       if (pch == NULL) continue;
+
+                                       while (*pch)
+                                       {
+                                               if (_istprint(*pch))
+                                               {
+                                                       if (dwLastCharOffset >= m_dwBufferSize-1)
+                                                       {
+                                                               ASSERT(dwLastCharOffset == m_dwBufferSize-1);
+                                                               //                              Beep(1000,100);
+                                                               break;
+                                                       }
+                                                       TCHAR ch1;
+                                                       //if (m_blnInsetMode)
+                                                       ch1 = m_pchBuffer[dwCurrentCharOffset];
+                                                       m_pchBuffer[dwCurrentCharOffset] = *pch;
+                                                       if ((m_blnInsetMode)||(dwCurrentCharOffset == dwLastCharOffset)) dwLastCharOffset++;
+                                                       dwCurrentCharOffset++;
+                                                       if (!Write(pch,1)) return FALSE;
+                                                       if (m_blnInsetMode)
+                                                       {
+                                                               COORD Cursor = m_CursorPosition;
+                                                               DWORD ofs = dwCurrentCharOffset;
+                                                               
+                                                               while(ofs <= dwLastCharOffset)
+                                                               {
+                                                                       ch = m_pchBuffer[ofs];
+                                                                       m_pchBuffer[ofs] = ch1;
+                                                                       ch1 = ch;
+                                                                       ofs++;
+                                                               }
+                                                               
+                                                               if (dwCurrentCharOffset < dwLastCharOffset)
+                                                               {
+                                                                       if (!Write(m_pchBuffer+dwCurrentCharOffset,dwLastCharOffset-dwCurrentCharOffset)) return FALSE;
+                                                                       
+                                                                       if (m_LinesScrolled)
+                                                                       {
+                                                                               if (m_LinesScrolled > FristCharCursorPosition.Y) return FALSE;
+                                                                               Cursor.Y = SHORT(Cursor.Y - m_LinesScrolled);
+                                                                       }
+                                                                       // Update cursor position
+                                                                       m_CursorPosition = Cursor;
+                                                                       if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE;
+                                                               }
+                                                       }
+                                               }
+                                               pch++;
+                                       }
+                               }
+                       }
+                       else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_LEFT)
+                       {
+                               if (blnCompletionMode) blnCompletionMode = FALSE;
+                               if (dwCurrentCharOffset)
+                               {
+                                       if (InputRecord.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
+                                       {
+                                               TCHAR *pchWordBegin = m_pchBuffer+dwCurrentCharOffset-1;
+
+                                               while (pchWordBegin > m_pchBuffer)
+                                               {
+                                                       if (!_istspace(*pchWordBegin)) break;
+                                                       pchWordBegin--;
+                                               }
+
+                                               while (pchWordBegin > m_pchBuffer)
+                                               {
+                                                       if (_istspace(*(pchWordBegin-1))) break;
+                                                       pchWordBegin--;
+                                               }                                                       
+
+                                               ASSERT(pchWordBegin >= m_pchBuffer);
+                                               dwCurrentCharOffset = pchWordBegin - m_pchBuffer;
+
+                                               ASSERT(dwCurrentCharOffset < dwLastCharOffset);
+
+                                               m_CursorPosition.X = X_CURSOR_POSITION_FROM_OFFSET(dwCurrentCharOffset);
+                                               m_CursorPosition.Y = Y_CURSOR_POSITION_FROM_OFFSET(dwCurrentCharOffset);
+                                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                                       }
+                                       else
+                                       {
+                                               dwCurrentCharOffset--;
+                                               if (m_CursorPosition.X)
+                                               {
+                                                       m_CursorPosition.X--;
+                                               }
+                                               else
+                                               {
+                                                       m_CursorPosition.X = SHORT(m_BufferSize.X-1);
+                                                       ASSERT(m_CursorPosition.Y);
+                                                       m_CursorPosition.Y--;
+                                               }
+                                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                                       }
+                               }
+                       }
+                       else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_RIGHT)
+                       {
+                               if (blnCompletionMode) blnCompletionMode = FALSE;
+                               if (dwCurrentCharOffset < dwLastCharOffset)
+                               {
+                                       if (InputRecord.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
+                                       {
+                                               TCHAR *pchWordBegin = m_pchBuffer+dwCurrentCharOffset;
+
+                                               while ((DWORD)(pchWordBegin - m_pchBuffer) < dwLastCharOffset)
+                                               {
+                                                       if (_istspace(*pchWordBegin)) break;
+                                                       pchWordBegin++;
+                                               }
+
+                                               while ((DWORD)(pchWordBegin - m_pchBuffer) < dwLastCharOffset)
+                                               {
+                                                       if (!_istspace(*pchWordBegin)) break;
+                                                       pchWordBegin++;
+                                               }
+
+                                               dwCurrentCharOffset = pchWordBegin - m_pchBuffer;
+                                               ASSERT(dwCurrentCharOffset <= dwLastCharOffset);
+                                               m_CursorPosition.X = X_CURSOR_POSITION_FROM_OFFSET(dwCurrentCharOffset);
+                                               m_CursorPosition.Y = Y_CURSOR_POSITION_FROM_OFFSET(dwCurrentCharOffset);
+                                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                                       }
+                                       else
+                                       {
+                                               dwCurrentCharOffset++;
+                                               m_CursorPosition.X++;
+                                               if (m_CursorPosition.X == m_BufferSize.X)
+                                               {
+                                                       m_CursorPosition.Y++;
+                                                       m_CursorPosition.X = 0;
+                                               }
+                                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                                       }
+                               }
+                       }
+                       else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_HOME)
+                       {
+                               if (blnCompletionMode) blnCompletionMode = FALSE;
+                               dwCurrentCharOffset = 0;
+                               m_CursorPosition = FristCharCursorPosition;
+                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                       }
+                       else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_END)
+                       {
+                               if (blnCompletionMode) blnCompletionMode = FALSE;
+                               dwCurrentCharOffset = dwLastCharOffset;
+                               m_CursorPosition.X = X_CURSOR_POSITION_FROM_OFFSET(dwLastCharOffset);
+                               m_CursorPosition.Y = Y_CURSOR_POSITION_FROM_OFFSET(dwLastCharOffset);
+                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                       }
+                       else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_UP)
+                       {
+                               if (blnCompletionMode) blnCompletionMode = FALSE;
+                               dwHistoryIndex++;
+                               const TCHAR *pchHistoryLine = m_History.GetHistoryLine(dwHistoryIndex-1);
+                               if (pchHistoryLine)
+                               {
+                                       if (dwLastCharOffset)
+                                       {
+                                               _tcsnset(m_pchBuffer,_T(' '),dwLastCharOffset);
+                                               m_CursorPosition = FristCharCursorPosition;
+                                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                                               VERIFY(Write(m_pchBuffer,dwLastCharOffset));
+                                               dwCurrentCharOffset = dwLastCharOffset = 0;
+                                               m_CursorPosition = FristCharCursorPosition;
+                                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                                       }
+                                       dwCurrentCharOffset = dwLastCharOffset = _tcslen(pchHistoryLine);
+                                       if (dwLastCharOffset >= m_dwBufferSize)
+                                       {
+                                               ASSERT(FALSE);
+                                               return FALSE;
+                                       }
+                                       _tcscpy(m_pchBuffer,pchHistoryLine);
+                                       if (!Write(m_pchBuffer)) return FALSE;
+                               }
+                               else
+                               {
+                                       dwHistoryIndex--;
+                               }
+                       }
+                       else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_DOWN)
+                       {
+                               if (blnCompletionMode) blnCompletionMode = FALSE;
+                               if (dwHistoryIndex)
+                               {
+                                       dwHistoryIndex--;
+                                       const TCHAR *pchHistoryLine = m_History.GetHistoryLine(dwHistoryIndex-1);
+                                       if (dwLastCharOffset)
+                                       {
+                                               _tcsnset(m_pchBuffer,_T(' '),dwLastCharOffset);
+                                               m_CursorPosition = FristCharCursorPosition;
+                                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                                               VERIFY(Write(m_pchBuffer,dwLastCharOffset));
+                                               dwCurrentCharOffset = dwLastCharOffset = 0;
+                                               m_CursorPosition = FristCharCursorPosition;
+                                               VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                                       }
+                                       if (pchHistoryLine)
+                                       {
+                                               dwCurrentCharOffset = dwLastCharOffset = _tcslen(pchHistoryLine);
+                                               if (dwLastCharOffset >= m_dwBufferSize)
+                                               {
+                                                       ASSERT(FALSE);
+                                                       return FALSE;
+                                               }
+                                               _tcscpy(m_pchBuffer,pchHistoryLine);
+                                               if (!Write(m_pchBuffer)) return FALSE;
+                                       }
+                               }
+                       }
+                       else if ((InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_DELETE)&&
+                               (dwLastCharOffset))
+                       {
+                               // Move the characters if any...
+                               ASSERT(dwLastCharOffset);
+                               DWORD dwCharOffset = dwCurrentCharOffset;
+                               if (dwCharOffset < dwLastCharOffset)
+                               {
+                                       while(dwCharOffset < dwLastCharOffset)
+                                       {
+                                               m_pchBuffer[dwCharOffset] = m_pchBuffer[dwCharOffset+1];
+                                               dwCharOffset++;
+                                       }
+                                       
+                                       m_pchBuffer[dwLastCharOffset-1] = _T(' ');
+                                       
+                                       // Save cursor position
+                                       COORD Cursor = m_CursorPosition;
+                                       
+                                       if (!Write(m_pchBuffer+dwCurrentCharOffset,dwLastCharOffset-dwCurrentCharOffset)) return FALSE;
+                                       
+                                       dwLastCharOffset--;
+                                       
+                                       // Update cursor position
+                                       m_CursorPosition = Cursor;
+                                       if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE;
+                               }
+
+                       }
+//                     else if ((InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE)&&
+//                             (InputRecord.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)))
+//                     {
+//                                     if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,0)) return FALSE;
+//                     }
+               }
+               else if ((ch == 27) && dwLastCharOffset &&
+                       (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE))
+               {
+                       if (blnCompletionMode) blnCompletionMode = FALSE;
+                       _tcsnset(m_pchBuffer,_T(' '),dwLastCharOffset);
+                       m_CursorPosition = FristCharCursorPosition;
+                       VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+                       VERIFY(Write(m_pchBuffer,dwLastCharOffset));
+                       dwCurrentCharOffset = dwLastCharOffset = 0;
+                       m_CursorPosition = FristCharCursorPosition;
+                       VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition));
+               }
+               else if (ch == _T('\r'))
+               {       // carriage return
+                       if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition = FristCharCursorPosition)) return FALSE;
+                       ASSERT(dwLastCharOffset <= m_dwBufferSize);
+                       m_pchBuffer[dwLastCharOffset] = 0;      // terminate string in buffer
+                       ret = Write(m_pchBuffer);
+                       m_History.AddHistoryLine(m_pchBuffer);
+                       TCHAR *strLF = _T("\n");
+                       ret = Write(strLF);
+                       break;
+               }
+               else if (ch == _T('\b'))
+               {       // backspace
+                       if (blnCompletionMode) blnCompletionMode = FALSE;
+                       if ((dwCurrentCharOffset) && ((m_CursorPosition.X != 0) || (m_CursorPosition.Y != 0)))
+                       {
+                               // Calculate new cursor position
+                               COORD NewCursorPosition;
+                               if (m_CursorPosition.X)
+                               {
+                                       NewCursorPosition.X = SHORT(m_CursorPosition.X-1);
+                                       NewCursorPosition.Y = m_CursorPosition.Y;
+                               }
+                               else
+                               {
+                                       ASSERT(m_BufferSize.X);
+                                       NewCursorPosition.X = SHORT(m_BufferSize.X-1);
+                                       ASSERT(m_CursorPosition.Y);
+                                       NewCursorPosition.Y = SHORT(m_CursorPosition.Y-1);
+                               }
+
+                               // Move the characters if any...
+                               ASSERT(dwLastCharOffset);
+                               DWORD dwCharOffset = dwCurrentCharOffset-1;
+                               while(dwCharOffset < dwLastCharOffset-1)
+                               {
+                                       m_pchBuffer[dwCharOffset] = m_pchBuffer[dwCharOffset+1];
+                                       dwCharOffset++;
+                               }
+
+                               m_pchBuffer[dwLastCharOffset-1] = _T(' ');
+
+                               dwCurrentCharOffset--;
+                               m_CursorPosition = NewCursorPosition;
+                               if (!Write(m_pchBuffer+dwCurrentCharOffset,dwLastCharOffset-dwCurrentCharOffset)) return FALSE;
+
+                               // Update cursor position
+                               m_CursorPosition = NewCursorPosition;
+                               if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE;
+
+                               dwLastCharOffset--;
+                       }
+               }
+               else if (ch == _T('\t'))
+               {
+                       if (!blnCompletionMode)
+                       {
+                               if (InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
+//                                     nCompletionIndex = 0xFFFFFFFFFFFFFFFF;
+                                       nCompletionIndex = (unsigned long long) -1;
+                               else
+                                       nCompletionIndex = 0;
+                               dwCompletionOffset = dwCurrentCharOffset;
+                               BOOL b = FALSE;
+                               while(dwCompletionOffset)
+                               {
+                                       dwCompletionOffset--;
+                                       if (m_pchBuffer[dwCompletionOffset] == _T('\"'))
+                                       {
+                                               b = !b;
+                                       }
+                                       else if (!b && _istspace(m_pchBuffer[dwCompletionOffset]))
+                                       {
+                                               dwCompletionOffset++;
+                                               break;
+                                       }
+                               }
+                               ASSERT(dwCompletionOffset <= dwCurrentCharOffset);
+                               _tcsncpy(m_pchBuffer1,m_pchBuffer,dwCompletionOffset);
+                               m_pchBuffer1[dwCompletionOffset] = 0;
+                               dwCompletionStringSize = dwCurrentCharOffset-dwCompletionOffset;
+                               if (dwCompletionStringSize)
+                                       _tcsncpy(m_pchBuffer2,m_pchBuffer+dwCompletionOffset,dwCompletionStringSize);
+                               m_pchBuffer2[dwCompletionStringSize] = 0;
+                               CompletionPosition.X = X_CURSOR_POSITION_FROM_OFFSET(dwCompletionOffset);
+                               CompletionPosition.Y = Y_CURSOR_POSITION_FROM_OFFSET(dwCompletionOffset);
+//                             Beep(1000,500);
+                       }
+                       else
+                       {
+//                             Beep(1000,50);
+//                             Beep(2000,50);
+//                             Beep(3000,50);
+//                             Beep(4000,50);
+//                             Beep(3000,50);
+//                             Beep(2000,50);
+//                             Beep(1000,50);
+                       }
+                       const TCHAR *pchCompletion = NULL;
+                       BOOL blnForward = !(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED);
+                       if (m_pfReplaceCompletionCallback)
+                               pchCompletion = m_pfReplaceCompletionCallback(nCompletionIndex,
+                               blnCompletionMode?&blnForward:NULL,
+                               m_pchBuffer1,m_pchBuffer2);
+                       if (pchCompletion)
+                       {
+                               // Set cursor position
+                               m_CursorPosition = CompletionPosition;
+                               if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE;
+
+                               // Calculate buffer free space
+                               ASSERT(m_dwBufferSize > dwCompletionOffset);
+                               DWORD dwFree = m_dwBufferSize - dwCompletionOffset - 1;
+
+                               DWORD dwOldCompletionStringSize = dwCompletionStringSize;
+
+                               // Write completion string to buffer
+                               dwCompletionStringSize = _tcslen(pchCompletion);
+
+                               if (dwCompletionStringSize > dwFree)
+                                       dwCompletionStringSize = dwFree;
+                               if (dwCompletionStringSize)
+                               {
+                                       _tcsncpy(m_pchBuffer+dwCompletionOffset,pchCompletion,dwCompletionStringSize);
+//                                     m_pchBuffer[dwCompletionOffset+dwCompletionStringSize] = 0;
+                                       
+                                       // Write completion string to console
+                                       if (!Write(m_pchBuffer+dwCompletionOffset,dwCompletionStringSize)) return FALSE;
+                                       dwCurrentCharOffset = dwLastCharOffset = dwCompletionOffset + dwCompletionStringSize;
+                                       ASSERT(dwLastCharOffset < m_dwBufferSize);
+                               }
+
+                               // Erase rest from previous completion string
+                               if (dwOldCompletionStringSize > dwCompletionStringSize)
+                               {
+                                       _tcsnset(m_pchBuffer+dwCompletionOffset+dwCompletionStringSize,_T(' '),
+                                               dwOldCompletionStringSize - dwCompletionStringSize);
+
+                                       // Save cursor position
+                                       COORD pos = m_CursorPosition;
+
+                                       if (!Write(m_pchBuffer+dwCompletionOffset+dwCompletionStringSize,
+                                               dwOldCompletionStringSize - dwCompletionStringSize))
+                                               return FALSE;
+
+                                       // Set cursor position
+                                       m_CursorPosition = pos;
+                                       if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE;
+                               }
+
+                       }
+                       else
+                       {
+/*                             if (InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
+                               {
+                                        nCompletionIndex++;
+                               }
+                               else
+                               {
+                                       if (nCompletionIndex)
+                                               nCompletionIndex--;
+                               }*/
+                       }
+                       blnCompletionMode = TRUE;
+               }
+               else if (_istprint(ch))
+               {
+                       if (blnCompletionMode) blnCompletionMode = FALSE;
+                       if (dwLastCharOffset >= m_dwBufferSize-1)
+                       {
+                               ASSERT(dwLastCharOffset == m_dwBufferSize-1);
+//                             Beep(1000,100);
+                               continue;
+                       }
+                       TCHAR ch1;
+                       //if (m_blnInsetMode)
+                       ch1 = m_pchBuffer[dwCurrentCharOffset];
+                       m_pchBuffer[dwCurrentCharOffset] = ch;
+                       if ((m_blnInsetMode)||(dwCurrentCharOffset == dwLastCharOffset)) dwLastCharOffset++;
+                       dwCurrentCharOffset++;
+                       if (!Write(&ch,1)) return FALSE;
+                       if (m_blnInsetMode)
+                       {
+                               COORD Cursor = m_CursorPosition;
+                               DWORD ofs = dwCurrentCharOffset;
+
+                               while(ofs <= dwLastCharOffset)
+                               {
+                                       ch = m_pchBuffer[ofs];
+                                       m_pchBuffer[ofs] = ch1;
+                                       ch1 = ch;
+                                       ofs++;
+                               }
+
+                               if (dwCurrentCharOffset < dwLastCharOffset)
+                               {
+                                       if (!Write(m_pchBuffer+dwCurrentCharOffset,dwLastCharOffset-dwCurrentCharOffset)) return FALSE;
+
+                                       if (m_LinesScrolled)
+                                       {
+                                               if (m_LinesScrolled > FristCharCursorPosition.Y) return FALSE;
+                                               Cursor.Y = SHORT(Cursor.Y - m_LinesScrolled);
+                                       }
+                                       // Update cursor position
+                                       m_CursorPosition = Cursor;
+                                       if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE;
+                               }
+                       }
+               }
+               ASSERT(InputRecord.Event.KeyEvent.wRepeatCount);
+               if (!InputRecord.Event.KeyEvent.wRepeatCount) return FALSE;
+               if (--InputRecord.Event.KeyEvent.wRepeatCount) goto KeyRepeat;
+       }
+       m_blnMoreMode = blnOldMoreMode;
+       return TRUE;
+}
+
+BOOL CConsole::GetTextAttribute(WORD& rwAttributes)
+{
+       rwAttributes = m_wAttributes;
+       return TRUE;
+}
+
+// Parameters:
+//             dwBufferSize - size in chars of the input line buffer
+//
+// Rerturns:
+//             NULL - Failed.
+//             pointer to the input buffer
+TCHAR * CConsole::Init(DWORD dwBufferSize, DWORD dwMaxHistoryLines)
+{
+       if (m_hStdIn != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdIn));
+       if (m_hStdOut != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdOut));
+
+       m_hStdIn = GetStdHandle(STD_INPUT_HANDLE);
+       if (m_hStdIn == INVALID_HANDLE_VALUE) goto Abort;
+
+       m_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+       if (m_hStdOut == INVALID_HANDLE_VALUE) goto Abort;
+
+       CONSOLE_SCREEN_BUFFER_INFO info;
+       if (!GetConsoleScreenBufferInfo(m_hStdOut,&info)) goto Abort;
+       m_wAttributes = info.wAttributes;
+       
+       if (!SetConsoleMode(m_hStdIn,0)) goto Abort;
+       if (!SetConsoleMode(m_hStdOut,0)) goto Abort;
+
+       m_CursorPosition = info.dwCursorPosition;
+       m_BufferSize = info.dwSize;
+
+       CONSOLE_CURSOR_INFO cci;
+       cci.bVisible = TRUE;
+       cci.dwSize = m_blnInsetMode?m_dwInsertModeCursorHeight:m_dwOverwriteModeCursorHeight;
+
+       if (!SetConsoleCursorInfo(m_hStdOut,&cci)) goto Abort;
+
+       m_dwBufferSize = dwBufferSize;
+
+       if (m_pchBuffer) delete m_pchBuffer;
+       m_pchBuffer = NULL;
+
+       if (m_pchBuffer1) delete m_pchBuffer1;
+       m_pchBuffer1 = NULL;
+
+       if (m_pchBuffer2) delete m_pchBuffer2;
+       m_pchBuffer2 = NULL;
+
+       m_pchBuffer = new TCHAR [dwBufferSize];
+       if (!m_pchBuffer) goto Abort;
+       m_pchBuffer[dwBufferSize-1] = 0;
+
+       m_pchBuffer1 = new TCHAR [dwBufferSize];
+       if (!m_pchBuffer1) goto Abort;
+       m_pchBuffer1[dwBufferSize-1] = 0;
+
+       m_pchBuffer2 = new TCHAR [dwBufferSize];
+       if (!m_pchBuffer2) goto Abort;
+       m_pchBuffer2[dwBufferSize-1] = 0;
+
+       if (dwMaxHistoryLines)
+       {
+               if (!m_History.Init(dwBufferSize,dwMaxHistoryLines)) goto Abort;
+       }
+
+       return m_pchBuffer;
+
+Abort:
+       if (m_hStdIn != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdIn));
+       m_hStdIn = INVALID_HANDLE_VALUE;
+
+       if (m_hStdOut != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdOut));
+       m_hStdOut = INVALID_HANDLE_VALUE;
+
+       if (m_pchBuffer) delete m_pchBuffer;
+       m_pchBuffer = NULL;
+
+       if (m_pchBuffer1) delete m_pchBuffer1;
+       m_pchBuffer1 = NULL;
+
+       if (m_pchBuffer2) delete m_pchBuffer2;
+       m_pchBuffer2 = NULL;
+
+       m_dwBufferSize = 0;
+
+       return NULL;
+}
+
+BOOL CConsole::WriteChar(TCHAR ch)
+{
+       CHAR_INFO ci;
+       ci.Attributes = m_wAttributes;
+#ifdef UNICODE
+       ci.Char.UnicodeChar = ch;
+#else
+       ci.Char.AsciiChar = ch;
+#endif
+       static COORD BufferSize = {1,1};
+       static COORD BufferCoord = {0,0};
+       SMALL_RECT Dest;
+       Dest.Bottom = Dest.Top = m_CursorPosition.Y;
+       Dest.Left = Dest.Right = m_CursorPosition.X;
+       return WriteConsoleOutput(m_hStdOut,&ci,BufferSize,BufferCoord,&Dest);
+}
+
+void CConsole::BeginScrollingOperation()
+{
+       m_Lines = 0;
+}
+
+BOOL CConsole::WriteString(TCHAR *pchString, COORD Position)
+{
+       CHAR_INFO ciBuffer[256];
+       int nSize = _tcslen(pchString);
+       if ((nSize > 256)||(nSize <= 0))
+       {
+               ASSERT(FALSE);
+               return FALSE;
+       }
+
+       COORD BufferSize;
+       BufferSize.X = (SHORT)nSize;
+       BufferSize.Y = 1;
+       static COORD BufferCoord = {0,0};
+       SMALL_RECT Dest;
+       Dest.Bottom = Dest.Top = Position.Y;
+       Dest.Right = SHORT((Dest.Left = Position.X) + nSize - 1);
+
+       while(nSize--)
+       {
+               ciBuffer[nSize].Attributes = m_wAttributes;
+#ifdef UNICODE
+               ciBuffer[nSize].Char.UnicodeChar = pchString[nSize];
+#else
+               ciBuffer[nSize].Char.AsciiChar = pchString[nSize];
+#endif
+       }
+
+       return WriteConsoleOutput(m_hStdOut,ciBuffer,BufferSize,BufferCoord,&Dest);
+}
+
+BOOL CConsole::SetInsertMode(BOOL blnInsetMode)
+{
+       if (m_hStdOut == INVALID_HANDLE_VALUE) return FALSE;
+
+       CONSOLE_CURSOR_INFO cci;
+       cci.bVisible = TRUE;
+       cci.dwSize = blnInsetMode?m_dwInsertModeCursorHeight:m_dwOverwriteModeCursorHeight;
+
+       BOOL ret = SetConsoleCursorInfo(m_hStdOut,&cci);
+       if (ret) m_blnInsetMode = blnInsetMode;
+       return ret;
+}
+
+
+
+void CConsole::SetReplaceCompletionCallback(ReplaceCompletionCallback pfCallback)
+{
+       m_pfReplaceCompletionCallback = pfCallback;
+}
+
+
+void CConsole::DisableWrite()
+{
+       m_blnDisableWrite = TRUE;
+       INPUT_RECORD InputRecord;
+       DWORD dwRecordsWriten;
+       InputRecord.EventType = KEY_EVENT;
+       InputRecord.Event.KeyEvent.bKeyDown = TRUE;
+#ifdef UNICODE
+       InputRecord.Event.KeyEvent.uChar.UnicodeChar = L' ';
+#else
+       InputRecord.Event.KeyEvent.uChar.AsciiChar = ' ';
+#endif
+       BOOL ret = WriteConsoleInput(m_hStdIn,&InputRecord,1,&dwRecordsWriten);
+       ASSERT(ret);
+}
+
+void CConsole::EnableWrite()
+{
+       m_blnDisableWrite = FALSE;
+}
+
+/*                             DWORD ofs = dwCurrentCharOffset;
+                               DWORD nLines = (FristCharCursorPosition.X + dwLastCharOffset-1)/m_BufferSize.X;
+                               for (DWORD nLine = 0 ; nLine <= nLines ; nLine++)
+                               {
+                                       ASSERT(m_BufferSize.X > pos.X);
+                                       DWORD nChars = m_BufferSize.X - pos.X - 1;
+                                       if (nChars > dwLastCharOffset - ofs) nChars = dwLastCharOffset - ofs;
+                                       if (nChars)
+                                       {       // We have some chars to move in this line
+                                               _tcsncpy(m_pchBuffer1,m_pchBuffer+ofs,nChars);
+                                               m_pchBuffer1[nChars] = 0;
+                                               if (!WriteString(m_pchBuffer1,pos)) return FALSE;
+                                       }
+                                       pos.X = SHORT(pos.X + nChars);
+                                       // if current line is not the last line
+                                       // Move the first char in next line to end of current line
+                                       if (nLine < nLines)
+                                       {
+                                               ofs += nChars;
+                                               m_pchBuffer1[0] = m_pchBuffer[ofs];
+                                               m_pchBuffer1[1] = 0;
+                                               if (!WriteString(m_pchBuffer1,pos)) return FALSE;
+                                               pos.Y++;
+                                               pos.X = 0;
+                                               ofs++;
+                                       }
+                                       else    // Adjust end of read line
+                                       {
+                                               m_pchBuffer1[0] = _T(' ');
+                                               m_pchBuffer1[1] = 0;
+                                               if (!WriteString(m_pchBuffer1,pos)) return FALSE;
+                                       }
+                               }*/
diff --git a/rosapps/sysutils/regexpl/Console.h b/rosapps/sysutils/regexpl/Console.h
new file mode 100644 (file)
index 0000000..05db9cc
--- /dev/null
@@ -0,0 +1,56 @@
+// Console.h: interface for the CConsole class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(CONSOLE_H__FEF419EC_6EB6_11D3_907D_204C4F4F5020__INCLUDED_)
+#define CONSOLE_H__FEF419EC_6EB6_11D3_907D_204C4F4F5020__INCLUDED_
+
+#include "TextHistory.h"
+
+typedef const TCHAR * (*ReplaceCompletionCallback)(unsigned __int64& rnIndex, const BOOL *pblnForward,
+                                                                                                  const TCHAR *pchContext, const TCHAR *pchBegin);
+
+class CConsole  
+{
+public:
+       void EnableWrite();
+       void DisableWrite();
+       void SetReplaceCompletionCallback(ReplaceCompletionCallback pfCallback);
+       BOOL SetInsertMode(BOOL blnInsetMode);
+       void BeginScrollingOperation();
+       TCHAR * Init(DWORD dwBufferSize, DWORD dwMaxHistoryLines = 0);
+       BOOL ReadLine();
+       BOOL FlushInputBuffer();
+//     BOOL SetOutputMode(DWORD dwMode);
+//     BOOL SetInputMode(DWORD dwMode);
+       BOOL SetTextAttribute(WORD wAttributes);
+       BOOL GetTextAttribute(WORD& rwAttributes);
+       BOOL SetTitle(TCHAR *p);
+       BOOL Write(const TCHAR *p, DWORD dwChars = 0);
+       CConsole();
+       virtual ~CConsole();
+private:
+       HANDLE m_hStdOut;
+       HANDLE m_hStdIn;
+       HANDLE m_hStdError;
+       COORD m_CursorPosition;
+       COORD m_BufferSize;
+       WORD m_wAttributes;
+       SHORT m_Lines;
+       BOOL WriteString(TCHAR *pchString, COORD Position);
+       BOOL WriteChar(TCHAR ch);
+       BOOL m_blnInsetMode;    // TRUE - insert, FALSE - overwrite
+       DWORD m_dwInsertModeCursorHeight;
+       DWORD m_dwOverwriteModeCursorHeight;
+       TCHAR *m_pchBuffer;
+       TCHAR *m_pchBuffer1;
+       TCHAR *m_pchBuffer2;
+       DWORD m_dwBufferSize;
+       ReplaceCompletionCallback m_pfReplaceCompletionCallback;
+       SHORT m_LinesScrolled;
+       BOOL m_blnMoreMode;
+       CTextHistory m_History;
+       BOOL m_blnDisableWrite;
+};
+
+#endif // !defined(CONSOLE_H__FEF419EC_6EB6_11D3_907D_204C4F4F5020__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/CrtSupplement.c b/rosapps/sysutils/regexpl/CrtSupplement.c
new file mode 100644 (file)
index 0000000..750080f
--- /dev/null
@@ -0,0 +1,50 @@
+/* $Id: CrtSupplement.c,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * Written by EA because ReactOS hasn't yet _ui64toa()
+ * (it's in msvcrt.dll, and not in crtdll.dll). 
+ */
+
+#include <stdlib.h>
+
+static
+char DigitMap [36] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+char *
+_ui64toa (
+       unsigned __int64        value,
+       char                    * string,
+       int                     radix
+       )
+{
+       int     reminder = 0;
+       char    buffer [17];
+       char    * w = buffer;
+       int     len = 0;
+       int     i = 0;
+
+       /* Check the radix is valid */
+       if ((2 > radix) || (36 < radix))
+       {
+               return string;
+       }
+       /* Convert the int64 to a string */
+       do {
+               reminder = (int) (value % (__int64) radix);
+               *(w ++) = DigitMap [reminder];
+               value /= (__int64) radix;
+               ++ len;
+
+       } while ((__int64) value > 0);
+       /* Reverse the string */
+       while (i < len)
+       {
+               string [i ++] = *(-- w);
+       }
+       string [len] = '\0';
+       
+       return string;
+}
+
+
+
+/* EOF */
diff --git a/rosapps/sysutils/regexpl/Makefile b/rosapps/sysutils/regexpl/Makefile
new file mode 100644 (file)
index 0000000..87b5c07
--- /dev/null
@@ -0,0 +1,96 @@
+#
+#  ReactOS makefile for RegExpl
+#
+
+TARGET_NAME=regexpl
+
+ROS_DIR=../../../reactos
+ROS_INC=$(ROS_DIR)/include
+ROS_LIB=$(ROS_DIR)/lib
+IMPORT_NTDLL=$(ROS_LIB)/ntdll/ntdll.a
+IMPORT_FMIFS=$(ROS_LIB)/fmifs/fmifs.a
+IMPORT_KERNEL32=$(ROS_LIB)/kernel32/kernel32.a
+IMPORT_ADVAPI32=$(ROS_LIB)/advapi32/advapi32.a
+IMPORT_USER32=$(ROS_LIB)/user32/user32.a
+IMPORT_CRTDLL=$(ROS_LIB)/crtdll/crtdll.a
+
+
+all: $(TARGET_NAME)$(EXE_POSTFIX)
+
+OBJECTS = \
+       ArgumentParser.o                \
+       Console.o                       \
+       RegistryExplorer.o              \
+       RegistryKey.o                   \
+       RegistryTree.o                  \
+       SecurityDescriptor.o            \
+       ShellCommand.o                  \
+       ShellCommandChangeKey.o         \
+       ShellCommandConnect.o           \
+       ShellCommandDACL.o              \
+       ShellCommandDOKA.o              \
+       ShellCommandDeleteKey.o         \
+       ShellCommandDeleteValue.o       \
+       ShellCommandDir.o               \
+       ShellCommandExit.o              \
+       ShellCommandHelp.o              \
+       ShellCommandNewKey.o            \
+       ShellCommandOwner.o             \
+       ShellCommandSACL.o              \
+       ShellCommandSetValue.o          \
+       ShellCommandValue.o             \
+       ShellCommandVersion.o           \
+       ShellCommandsLinkedList.o       \
+       CrtSupplement.c                 \
+       TextHistory.o                   \
+       $(TARGET_NAME).coff
+
+CLEAN_FILES = \
+       *.o                             \
+       $(TARGET_NAME)$(EXE_POSTFIX)    \
+       $(TARGET_NAME).sym              \
+       $(TARGET_NAME).coff
+
+
+$(TARGET_NAME)$(EXE_POSTFIX): $(OBJECTS)
+       $(CC) \
+               -Wl,--subsystem,console \
+               -o $(TARGET_NAME)       \
+               $(IMPORT_KERNEL32)      \
+               $(IMPORT_CRTDLL)        \
+               $(IMPORT_USER32)        \
+               $(OBJECTS)
+       $(NM) --numeric-sort $(TARGET_NAME)$(EXE_POSTFIX) > $(TARGET_NAME).sym
+
+
+clean: $(CLEAN_FILES:%=%_clean)
+
+$(CLEAN_FILES:%=%_clean): %_clean:
+       - $(RM) $*
+
+.phony: clean $(CLEAN_FILES:%=%_clean)
+
+
+floppy: $(TARGET:%=$(FLOPPY_DIR)/apps/%)
+
+$(TARGET:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
+ifeq ($(DOSCLI),yes)
+       $(CP) $* $(FLOPPY_DIR)\apps\$*
+else
+       $(CP) $* $(FLOPPY_DIR)/apps/$*
+endif
+
+
+dist: $(TARGET:%=../$(DIST_DIR)/apps/%)
+
+$(TARGET:%=../$(DIST_DIR)/apps/%): ../$(DIST_DIR)/apps/%: %
+ifeq ($(DOSCLI),yes)
+       $(CP) $* ..\$(DIST_DIR)\apps\$*
+else
+       $(CP) $* ../$(DIST_DIR)/apps\$*
+endif
+
+include ../../rules.mak
+
+# EOF
+
diff --git a/rosapps/sysutils/regexpl/RegistryExplorer.cpp b/rosapps/sysutils/regexpl/RegistryExplorer.cpp
new file mode 100644 (file)
index 0000000..96996cf
--- /dev/null
@@ -0,0 +1,510 @@
+/* $Id: RegistryExplorer.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// Registry Explorer.cpp : Defines the entry point for the console application.
+//
+
+#include "ph.h"
+#include "RegistryExplorer.h"
+#include "Console.h"
+#include "RegistryKey.h"
+#include "RegistryTree.h"
+#include "SecurityDescriptor.h"
+#include "ArgumentParser.h"
+#include "ShellCommandsLinkedList.h"
+#include "ShellCommandExit.h"
+#include "ShellCommandVersion.h"
+#include "ShellCommandHelp.h"
+#include "ShellCommandDir.h"
+#include "ShellCommandChangeKey.h"
+#include "ShellCommandValue.h"
+#include "ShellCommandOwner.h"
+#include "ShellCommandDACL.h"
+#include "ShellCommandSACL.h"
+#include "ShellCommandDOKA.h"
+#include "ShellCommandConnect.h"
+#include "ShellCommandNewKey.h"
+#include "ShellCommandDeleteKey.h"
+#include "ShellCommandSetValue.h"
+
+TCHAR pchCurrentKey[PROMPT_BUFFER_SIZE];
+
+CRegistryTree Tree(PROMPT_BUFFER_SIZE+1);
+CConsole Console;
+
+const TCHAR * ppchRootKeys[7] = 
+{
+       _T("HKEY_CLASSES_ROOT"),
+       _T("HKEY_CURRENT_USER"),
+       _T("HKEY_LOCAL_MACHINE"),
+       _T("HKEY_USERS"),
+       _T("HKEY_PERFORMANCE_DATA"),
+       _T("HKEY_CURRENT_CONFIG"),
+       _T("HKEY_DYN_DATA")             //win9x only?
+};
+
+BOOL g_blnCompletionCycle = TRUE;
+
+const TCHAR * CompletionCallback(unsigned __int64 & rnIndex, const BOOL *pblnForward, const TCHAR *pchContext, const TCHAR *pchBegin)
+{
+#define COMPLETION_BUFFER_SIZE 4096
+       static TCHAR pchBuffer[COMPLETION_BUFFER_SIZE];
+       CRegistryKey *pKey = NULL;
+       CRegistryTree *pTree = NULL;
+       unsigned __int64 nTotalKeys = 0;
+       unsigned __int64 nTotalValues = 0;
+       unsigned __int64 nTotalItems = 0;
+       class CompletionMatch
+       {
+       public:
+               CompletionMatch(const TCHAR *pchText, CompletionMatch **pNext)
+               {
+                       BOOL b = _tcschr(pchText,_T(' ')) != NULL;
+                       size_t s = _tcslen(pchText);
+                       m_pchText = new TCHAR [s+(b?3:1)];
+                       if (b)
+                       {
+                               m_pchText[0] = _T('\"');
+                               _tcscpy(m_pchText+1,pchText);
+                               m_pchText[s+1] = _T('\"');
+                               m_pchText[s+2] = 0;
+                       }
+                       else
+                       {
+                               _tcscpy(m_pchText,pchText);
+                       }
+                       if (m_pchText)
+                       {
+                               m_pNext = *pNext;
+                               *pNext = this;
+                       }
+               }
+               ~CompletionMatch()
+               {
+                       if (m_pchText)
+                               delete m_pchText;
+                       if (m_pNext)
+                               delete m_pNext;
+               }
+               const TCHAR *GetText(unsigned __int64 dwReverseIndex)
+               {
+                       if (dwReverseIndex)
+                       {
+                               if (m_pNext)
+                                       return m_pNext->GetText(dwReverseIndex-1);
+                               else
+                                       return NULL;
+                       }
+                       return m_pchText;
+               }
+       private:
+               TCHAR *m_pchText;
+               CompletionMatch *m_pNext;
+       };
+       CompletionMatch *pRootMatch = NULL;
+
+       BOOL blnCompletionOnKeys = TRUE;
+       BOOL blnCompletionOnValues = TRUE;
+
+       while(*pchContext && _istspace(*pchContext))
+       {
+               pchContext++;
+       }
+
+/*     if ((_tcsnicmp(pchContext,DIR_CMD,DIR_CMD_LENGTH) == 0)||
+               (_tcsnicmp(pchContext,CD_CMD,CD_CMD_LENGTH) == 0)||
+               (_tcsnicmp(pchContext,OWNER_CMD,OWNER_CMD_LENGTH) == 0)||
+               (_tcsnicmp(pchContext,DACL_CMD,DACL_CMD_LENGTH) == 0)||
+               (_tcsnicmp(pchContext,SACL_CMD,SACL_CMD_LENGTH) == 0))
+       {
+               blnCompletionOnValues = FALSE;
+       }*/
+//     else if (_tcsnicmp(pchContext,VALUE_CMD,VALUE_CMD_LENGTH) == 0)
+//     {
+//             blnCompletionOnKeys = FALSE;
+//     }
+
+       const TCHAR *pchKey = _tcsrchr(pchBegin,_T('\\'));
+       DWORD nBufferOffset = 0;
+       if (pchKey)
+       {
+               nBufferOffset = pchKey-pchBegin+1;
+               if (nBufferOffset >= COMPLETION_BUFFER_SIZE-1)
+               {
+                       if (pRootMatch) delete pRootMatch;
+                       if (pTree)
+                               delete pTree;
+                       return _T("internal error");
+               }
+               _tcsncpy(pchBuffer,pchBegin,nBufferOffset);
+               pchBuffer[nBufferOffset] = 0;
+               pchBegin = pchKey+1;
+               pTree = new CRegistryTree(Tree);
+               if ((_tcscmp(pTree->GetCurrentPath(),Tree.GetCurrentPath()) != 0)||(!pTree->ChangeCurrentKey(pchBuffer)))
+               {
+                       if (pTree)
+                               delete pTree;
+                       return NULL;
+               }
+               else
+               {
+                       pKey = pTree->GetCurrentKey();
+               }
+       }
+       else
+       {
+               pKey = Tree.GetCurrentKey();
+       }
+
+       if (!pKey)
+       {
+               for(unsigned int i = 0 ; i < sizeof(ppchRootKeys)/sizeof(TCHAR *) ; i++)
+               {
+                       nTotalKeys++;
+                       nTotalItems++;
+                       CompletionMatch *p = new CompletionMatch(ppchRootKeys[i],&pRootMatch);
+                       if (!p || !p->GetText(0))
+                       {
+                               if (pRootMatch) delete pRootMatch;
+                               if (pTree)
+                                       delete pTree;
+                               return _T("Out of memory");
+                       }
+               }
+       }
+       else
+       {
+               CompletionMatch *p;
+               DWORD dwError;
+               if (blnCompletionOnKeys)
+               {
+/*                     if (_tcslen(pchBegin) == 0)
+                       {
+                               p = new CompletionMatch(_T(".."),&pRootMatch);
+                               if (!p || !p->GetText(0))
+                               {
+                                       if (pRootMatch) delete pRootMatch;
+                                       if (pTree)
+                                               delete pTree;
+                                       return _T("Out of memory");
+                               }
+                               nTotalKeys++;
+                               nTotalItems++;
+                       }
+*/                     
+                       pKey->InitSubKeyEnumeration();
+                       TCHAR *pchSubKeyName;
+                       while ((pchSubKeyName = pKey->GetSubKeyName(dwError)) != NULL)
+                       {
+                               if (_tcsnicmp(pchSubKeyName,pchBegin,_tcslen(pchBegin)) == 0)
+                               {
+                                       nTotalKeys++;
+                                       nTotalItems++;
+                                       p = new CompletionMatch(pchSubKeyName,&pRootMatch);
+                                       if (!p || !p->GetText(0))
+                                       {
+                                               if (pRootMatch) delete pRootMatch;
+                                               if (pTree)
+                                                       delete pTree;
+                                               return _T("Out of memory");
+                                       }
+                               }
+                       }
+                       if ((dwError != ERROR_SUCCESS)&&(dwError != ERROR_NO_MORE_ITEMS))
+                       {
+                               if (pRootMatch) delete pRootMatch;
+                               if (pTree)
+                                       delete pTree;
+                               return _T("error");
+                       }
+               }
+               
+               if (blnCompletionOnValues)
+               {
+                       pKey->InitValueEnumeration();
+                       TCHAR *pchValueName;
+                       DWORD dwValueNameLength, dwMaxValueNameLength;
+                       dwError = pKey->GetMaxValueNameLength(dwMaxValueNameLength);
+                       if (dwError != ERROR_SUCCESS)
+                       {
+                               if (pRootMatch) delete pRootMatch;
+                               if (pTree)
+                                       delete pTree;
+                               return _T("error");
+                       }
+                       
+                       dwMaxValueNameLength++;
+                       pchValueName = new TCHAR [dwMaxValueNameLength];
+                       if (!pchValueName)
+                       {
+                               if (pRootMatch) delete pRootMatch;
+                               if (pTree)
+                                       delete pTree;
+                               return _T("Out of memory");
+                       }
+                       for(;;)
+                       {
+                               dwValueNameLength = dwMaxValueNameLength;
+                               //dwValueSize = dwMaxValueSize;
+                               dwError = pKey->GetNextValue(pchValueName,dwValueNameLength,NULL,NULL,NULL);
+                               if (dwError == ERROR_NO_MORE_ITEMS) break;
+                               if (dwError != ERROR_SUCCESS)
+                               {
+                                       if (pRootMatch) delete pRootMatch;
+                                       if (pTree)
+                                               delete pTree;
+                                       return _T("error");
+                               }
+                               
+                               if (((dwValueNameLength == 0) && (_tcslen(pchBegin) == 0))||
+                                       (_tcsnicmp(pchValueName,pchBegin,_tcslen(pchBegin)) == 0))
+                               {
+                                       nTotalValues++;
+                                       nTotalItems++;
+                                       p = new CompletionMatch((dwValueNameLength == 0)?_T("(Default)"):pchValueName,&pRootMatch);
+                                       if (!p || !p->GetText(0))
+                                       {
+                                               if (pRootMatch) delete pRootMatch;
+                                               if (pTree)
+                                                       delete pTree;
+                                               return _T("Out of memory");
+                                       }
+                               }
+                       }       // for
+                       delete [] pchValueName;
+               }
+       }
+       if (rnIndex >= nTotalItems)
+               rnIndex = nTotalItems-1;
+       if (pblnForward)
+       {
+               if (*pblnForward)
+               {
+                       rnIndex++;
+                       if (rnIndex >= nTotalItems)
+                       {
+                               if (g_blnCompletionCycle)
+                                       rnIndex = 0;
+                               else
+                                       rnIndex--;
+                       }
+               }
+               else
+               {
+                       if (rnIndex)
+                               rnIndex--;
+                       else if (g_blnCompletionCycle)
+                               rnIndex = nTotalItems-1;
+               }
+       }
+       
+       const TCHAR *pchName;
+       if (nTotalItems == 0)
+       {
+               if (pRootMatch)
+                       delete pRootMatch;
+               if (pTree)
+                       delete pTree;
+               return NULL;
+       }
+       ASSERT(rnIndex < nTotalItems);
+       pchName = pRootMatch->GetText(nTotalItems-rnIndex-1);
+       if (pchName == NULL)
+       {
+               if (pRootMatch)
+                       delete pRootMatch;
+               if (pTree)
+                       delete pTree;
+               return _T("internal error");
+       }
+       DWORD dwBufferFull = _tcslen(pchName);
+       if (dwBufferFull >= COMPLETION_BUFFER_SIZE-nBufferOffset)
+       {
+               dwBufferFull = COMPLETION_BUFFER_SIZE-1-nBufferOffset;
+       }
+       _tcsncpy(pchBuffer+nBufferOffset,pchName,dwBufferFull);
+       if ((dwBufferFull < COMPLETION_BUFFER_SIZE-1)&&(rnIndex < nTotalKeys))
+               pchBuffer[nBufferOffset+dwBufferFull++] = _T('\\');
+       pchBuffer[nBufferOffset+dwBufferFull] = 0;
+       if (pTree)
+               delete pTree;
+       if (pRootMatch)
+               delete pRootMatch;
+       return pchBuffer;
+}
+
+BOOL blnCommandExecutionInProgress = FALSE;
+
+BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
+{
+       switch(dwCtrlType)
+       {
+       case CTRL_C_EVENT:
+       case CTRL_BREAK_EVENT:
+               if (blnCommandExecutionInProgress)
+               {
+/*                     Beep(1000,100);
+                       Beep(2000,100);
+                       Beep(3000,100);
+                       Beep(4000,100);
+                       Beep(5000,100);
+                       Beep(4000,100);
+                       Beep(3000,100);
+                       Beep(2000,100);
+                       Beep(1000,100);*/
+                       Console.Write(_T("\n"));
+                       Console.DisableWrite();
+               }
+               return TRUE;
+       default:
+               return FALSE;
+       }
+}
+
+//int _tmain(/*int argc, TCHAR* argv[], TCHAR* envp[]*/)
+int main ()
+{
+       CShellCommandsLinkedList CommandsList(Console);
+
+       CShellCommandExit ExitCommand;
+       CommandsList.AddCommand(&ExitCommand);
+
+       CShellCommandVersion VersionCommand;
+       CommandsList.AddCommand(&VersionCommand);
+
+       CShellCommandHelp HelpCommand(CommandsList);
+       CommandsList.AddCommand(&HelpCommand);
+
+       CShellCommandDir DirCommand(Tree);
+       CommandsList.AddCommand(&DirCommand);
+
+       CShellCommandChangeKey ChangeKeyCommand(Tree);
+       CommandsList.AddCommand(&ChangeKeyCommand);
+
+       CShellCommandValue ValueCommand(Tree);
+       CommandsList.AddCommand(&ValueCommand);
+
+       CShellCommandOwner OwnerCommand(Tree);
+       CommandsList.AddCommand(&OwnerCommand);
+
+       CShellCommandDACL DACLCommand(Tree);
+       CommandsList.AddCommand(&DACLCommand);
+
+       CShellCommandSACL SACLCommand(Tree);
+       CommandsList.AddCommand(&SACLCommand);
+
+       CShellCommandDOKA DOKACommand(Tree);
+       CommandsList.AddCommand(&DOKACommand);
+
+       CShellCommandConnect ConnectCommand(Tree);
+       CommandsList.AddCommand(&ConnectCommand);
+
+       CShellCommandNewKey NewKeyCommand(Tree);
+       CommandsList.AddCommand(&NewKeyCommand);
+
+       CShellCommandDeleteKey DeleteKeyCommand(Tree);
+       CommandsList.AddCommand(&DeleteKeyCommand);
+
+       CShellCommandSetValue SetValueCommand(Tree);
+       CommandsList.AddCommand(&SetValueCommand);
+
+       CArgumentParser Parser;
+
+       int nRetCode = 0;
+
+// input buffer size in chars
+#define INPUT_BUFFER_SIZE      1024
+//#define INPUT_BUFFER_SIZE    128
+//#define INPUT_BUFFER_SIZE    10
+
+       TCHAR *pchCommand;
+
+       pchCommand = Console.Init(INPUT_BUFFER_SIZE,10);
+       if (pchCommand == NULL)
+       {
+               _ftprintf(stderr,_T("Cannot initialize console.\n"));
+               goto Abort;
+       }
+
+       Console.SetReplaceCompletionCallback(CompletionCallback);
+
+       WORD wOldConsoleAttribute;
+       if (!Console.GetTextAttribute(wOldConsoleAttribute)) goto Abort;
+
+       Console.SetTitle(_T("Registry Explorer"));
+       Console.SetTextAttribute(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);
+
+       VERIFY(SetConsoleCtrlHandler((PHANDLER_ROUTINE)HandlerRoutine,TRUE));
+
+       if (!Console.Write(HELLO_MSG
+       //(_L(__TIMESTAMP__))
+       )) goto Abort;
+
+       Tree.SetDesiredOpenKeyAccess(KEY_READ);
+
+GetCommand:
+       Console.EnableWrite();
+       Console.Write(_T("["));
+       _tcscpy(pchCurrentKey,Tree.GetCurrentPath());
+       Console.Write(pchCurrentKey);
+       Console.Write(_T("]"));
+       Console.FlushInputBuffer();
+
+       blnCommandExecutionInProgress = FALSE;
+
+       // Set command line color
+//     Console.SetTextAttribute(/*FOREGROUND_BLUE|*/FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);
+       if (!Console.ReadLine()) goto Abort;
+
+       // Set normal color
+//     Console.SetTextAttribute(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);
+
+       Console.BeginScrollingOperation();
+       blnCommandExecutionInProgress = TRUE;
+
+
+       // Parse command line (1st step - convert to multi sz)
+       Parser.SetArgumentList(pchCommand);
+
+       int nCommandReturnValue;
+       switch(CommandsList.Execute(Parser,nCommandReturnValue))
+       {
+       case -1:        // not recognized command
+               {
+                       Parser.ResetArgumentIteration();
+                       TCHAR *pchCommandItself = Parser.GetNextArgument();
+                       size_t cmdlen = _tcslen(pchCommandItself);
+                       if ((!cmdlen)||
+                               (pchCommandItself[cmdlen-1] != _T('\\'))||
+                               (Parser.GetNextArgument())||
+                               (!Tree.ChangeCurrentKey(pchCommandItself)))
+                       {
+                               Console.Write(_T("Unknown command \""));
+                               Console.Write(pchCommandItself);
+                               Console.Write(_T("\"\n"));
+                       }
+               }
+       case -2:        // empty line
+               goto GetCommand;
+       case 0: // exit command
+               nRetCode = 0;
+               Console.SetTextAttribute(wOldConsoleAttribute);
+               goto Exit;
+       default:
+               Console.Write(_T("\n"));
+               goto GetCommand;
+       }
+
+Abort:
+       _ftprintf(stderr,_T("Abnormal program termination.\nPlease report bugs to ") EMAIL _T("\n"));
+       nRetCode = 1;
+Exit:
+       return nRetCode;
+}
diff --git a/rosapps/sysutils/regexpl/RegistryExplorer.h b/rosapps/sysutils/regexpl/RegistryExplorer.h
new file mode 100644 (file)
index 0000000..3d2d4f0
--- /dev/null
@@ -0,0 +1,29 @@
+
+#ifndef _REGISTRY_EXPLORER_H__INCLUDED
+#define _REGISTRY_EXPLORER_H__INCLUDED
+
+#define CURRENT_VERSION                _T("0.10")
+#define EMAIL                          _T("registryexplorer@yahoo.com")
+
+//#define __L(x)      L ## x
+//#define _L(x)      __L(x)
+/*
+#define HELLO_MSG(date)                _T("Registry Explorer for Microsoft Windows NT 4.0\n")\
+                                                       _T("Version ") CURRENT_VERSION _T(" Compiled on ") date _T("\n")\
+                                                       _T("Coded by Nedko Arnaoudov. This product is freeware.\n\n")
+*/
+#define HELLO_MSG                      _T("Registry Explorer version ") CURRENT_VERSION _T(" for ReactOS\n")\
+                                                       _T("Coded by Nedko Arnaoudov. Licence is GNU GPL.\n\n")
+
+#define VER_MSG                                _T("Please report bugs to ") EMAIL _T("\n")
+
+#define GOODBYE_MSG                    _T("\nThank you for using Registry Explorer !!!\n")
+
+#define COMMAND_NA_ON_ROOT     _T(" command is not applicable to root key.\n")
+
+//#define COMMAND_LENGTH(cmd)  (sizeof(DIR_CMD)-sizeof(TCHAR))/sizeof(TCHAR)
+#define COMMAND_LENGTH(cmd)    _tcslen(cmd)
+
+#define PROMPT_BUFFER_SIZE     1024
+
+#endif //#ifndef _REGISTRY_EXPLORER_H__INCLUDED
diff --git a/rosapps/sysutils/regexpl/RegistryKey.cpp b/rosapps/sysutils/regexpl/RegistryKey.cpp
new file mode 100644 (file)
index 0000000..70e3025
--- /dev/null
@@ -0,0 +1,441 @@
+/* $Id: RegistryKey.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// RegistryKey.cpp: implementation of the CRegistryKey class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "RegistryKey.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CRegistryKey::CRegistryKey(const TCHAR *pchKeyName, class CRegistryKey *pParent)
+{
+//     RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+//             &m_dwValueNameBufferSize,&m_dwMaxValueSize,&m_dwSecurityDescriptorSize,&m_ftLastWriteTime);
+//     m_pchValueName = NULL;
+       ASSERT(pParent != NULL);
+       m_pParent = pParent;
+       m_pChild = NULL;
+       m_hKey = NULL;  // Open key with Open() member function
+       ASSERT(pchKeyName != NULL);
+       m_pchKeyName[MAX_PATH] = 0;
+       *m_pszMachineName = 0;
+       if (*pchKeyName == _T('\"'))
+       {
+               _tcsncpy(m_pchKeyName,pchKeyName+1,MAX_PATH);
+               TCHAR *pch = _tcschr(m_pchKeyName,_T('\"'));
+               if (pch)
+               {
+                       *pch = 0;
+               }
+               else
+               {
+                       ASSERT(FALSE);
+               }
+       }
+       else
+       {
+               _tcsncpy(m_pchKeyName,pchKeyName,MAX_PATH);
+       }
+}
+
+CRegistryKey::~CRegistryKey()
+{
+//     if (m_pchValueName) delete [] m_pchValueName;
+       if((m_hKey != HKEY_CLASSES_ROOT)&&(m_hKey != HKEY_CURRENT_USER)&&
+               (m_hKey != HKEY_LOCAL_MACHINE)&&(m_hKey != HKEY_USERS)
+               &&(m_hKey != HKEY_PERFORMANCE_DATA)&&(m_hKey != HKEY_CURRENT_CONFIG)
+               &&(m_hKey != HKEY_DYN_DATA)&&(m_hKey != NULL))
+       {
+               RegCloseKey(m_hKey);
+       }
+}
+
+TCHAR * CRegistryKey::GetKeyName()
+{
+       return m_pchKeyName;
+}
+
+class CRegistryKey * CRegistryKey::GetChild()
+{
+       return m_pChild;
+}
+
+CRegistryKey * CRegistryKey::GetParent()
+{
+       return m_pParent;
+}
+
+CRegistryKey * CRegistryKey::UpOneLevel()
+{
+       CRegistryKey *pParent = m_pParent;
+       ASSERT(m_pChild == NULL);
+       if (pParent)
+       {
+               ASSERT(pParent->m_pChild == this);
+               pParent->m_pChild = NULL;
+       }
+       delete this;
+       return pParent;
+}
+
+void CRegistryKey::InitSubKeyEnumeration()
+{
+       m_dwCurrentSubKeyIndex = 0;
+}
+
+TCHAR * CRegistryKey::GetSubKeyName(DWORD& dwError)
+{
+       static TCHAR m_pchSubName[MAX_PATH+1];
+       dwError = RegEnumKey(m_hKey,m_dwCurrentSubKeyIndex,m_pchSubName,MAX_PATH + 1);
+       m_dwCurrentSubKeyIndex++;
+       switch (dwError)
+       {
+       case ERROR_SUCCESS:
+               return m_pchSubName;
+       case ERROR_NO_MORE_ITEMS:
+               return NULL;
+       default:
+               return NULL;
+       }
+}
+
+void CRegistryKey::UpdateKeyNameCase()
+{
+       m_pParent->InitSubKeyEnumeration();
+       TCHAR *pchSubKeyName;
+       DWORD dwError;
+       while ((pchSubKeyName = m_pParent->GetSubKeyName(dwError)) != NULL)
+       {
+               if (dwError != ERROR_SUCCESS)
+               {
+                       return;
+               }
+               if (_tcsicmp(pchSubKeyName,m_pchKeyName) == 0)
+               {
+                       _tcscpy(m_pchKeyName,pchSubKeyName);
+                       return;
+               }
+       }
+}
+
+void CRegistryKey::InitValueEnumeration()
+{
+       m_dwCurrentValueIndex = 0;
+}
+
+
+// On input dwValueNameSize is size in characters of buffer pointed by pchValueNameBuffer
+// On output dwValueNameSize contains number of characters stored in buffer
+DWORD CRegistryKey::GetNextValue(TCHAR *pchValueNameBuffer,DWORD& dwValueNameSize, 
+                                                        DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize)
+{
+       DWORD dwRet = RegEnumValue(m_hKey,m_dwCurrentValueIndex,pchValueNameBuffer,&dwValueNameSize,NULL,
+               pdwType,lpValueDataBuffer,pdwValueDataSize);
+       m_dwCurrentValueIndex++;
+       return dwRet;
+}
+
+void CRegistryKey::GetLastWriteTime(SYSTEMTIME &st)
+{
+       FILETIME ftLocal,ft;
+       RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+               &ft);
+       FileTimeToLocalFileTime(&ft,&ftLocal);
+       FileTimeToSystemTime(&ftLocal,&st);
+}
+
+TCHAR * CRegistryKey::GetLastWriteTime()
+{
+       SYSTEMTIME st;
+       GetLastWriteTime(st);
+       static TCHAR Buffer[256];
+       _stprintf(Buffer,_T("%d.%d.%d %02d:%02d:%02d"),st.wDay,st.wMonth,st.wYear,st.wHour,st.wMinute,st.wSecond);
+       return Buffer;
+}
+
+// Returns ErrorCode (ERROR_SUCCESS on success)
+// dwMaxValueDataBuferSize receives the length, in bytes, 
+// of the longest data component among the key's values.
+DWORD CRegistryKey::GetMaxValueDataSize(DWORD& dwMaxValueDataBuferSize)
+{
+       return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+               NULL,&dwMaxValueDataBuferSize,NULL,NULL);
+}
+
+// Returns ErrorCode (ERROR_SUCCESS on success)
+// dwMaxValueNameBuferSize receives the length, in characters, 
+// of the key's longest value name.
+// The count returned does not include the terminating null character.
+DWORD CRegistryKey::GetMaxValueNameLength(DWORD& dwMaxValueNameBuferSize)
+{
+       return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+               &dwMaxValueNameBuferSize,NULL,NULL,NULL);
+}
+
+DWORD CRegistryKey::Open(REGSAM samDesired)
+{
+       if (IsPredefined())
+               return ERROR_SUCCESS;
+
+       DWORD dwRet;
+       HKEY hKey = NULL;
+       if (*m_pszMachineName)
+       {
+               ASSERT(ERROR_SUCCESS == 0);
+               dwRet = RegConnectRegistry(m_pszMachineName,m_hKey,&m_hKey);
+       }
+       else
+       {
+               ASSERT((m_hKey != HKEY_CLASSES_ROOT)&&(m_hKey != HKEY_CURRENT_USER)&&
+                       (m_hKey != HKEY_LOCAL_MACHINE)&&(m_hKey != HKEY_USERS)
+                       &&(m_hKey != HKEY_PERFORMANCE_DATA)&&(m_hKey != HKEY_CURRENT_CONFIG)
+                       &&(m_hKey != HKEY_DYN_DATA));
+               if (m_hKey)
+               {
+                       RegCloseKey(m_hKey);
+               }
+               dwRet = RegOpenKeyEx(*m_pParent,m_pchKeyName,0,samDesired,&hKey);
+       }
+       if (dwRet == ERROR_SUCCESS)
+       {
+               m_hKey = hKey;
+               UpdateKeyNameCase();
+       }
+       return dwRet;
+}
+
+CRegistryKey::CRegistryKey(HKEY hKey, LPCTSTR pszMachineName)
+{
+       TCHAR *pchKeyName = NULL;
+       ASSERT((hKey == HKEY_CLASSES_ROOT)||(hKey == HKEY_CURRENT_USER)||
+               (hKey == HKEY_LOCAL_MACHINE)||(hKey == HKEY_USERS)
+               ||(hKey == HKEY_PERFORMANCE_DATA)||(hKey == HKEY_CURRENT_CONFIG)
+               ||(hKey == HKEY_DYN_DATA));
+       if(hKey == HKEY_CLASSES_ROOT)
+       {
+               pchKeyName = _T("HKEY_CLASSES_ROOT");
+       }
+       else if(hKey == HKEY_CURRENT_USER)
+       {
+               pchKeyName = _T("HKEY_CURRENT_USER");
+       }
+       else if (hKey == HKEY_LOCAL_MACHINE)
+       {
+               pchKeyName = _T("HKEY_LOCAL_MACHINE");
+       }
+       else if (hKey == HKEY_USERS)
+       {
+               pchKeyName = _T("HKEY_USERS");
+       }
+       else if (hKey == HKEY_PERFORMANCE_DATA)
+       {
+               pchKeyName = _T("HKEY_PERFORMANCE_DATA");
+       }
+       else if (hKey == HKEY_CURRENT_CONFIG)
+       {
+               pchKeyName = _T("HKEY_CURRENT_CONFIG");
+       }
+       else if (hKey == HKEY_DYN_DATA)
+       {
+               pchKeyName = _T("HKEY_DYN_DATA");
+       }
+       else
+       {
+               ASSERT(FALSE);
+               return;
+       }
+
+       m_hKey = hKey;
+
+       m_pParent = NULL;
+       m_pChild = NULL;
+       ASSERT(pchKeyName != NULL);
+       m_pchKeyName[MAX_PATH] = 0;
+       _tcsncpy(m_pchKeyName,pchKeyName,MAX_PATH);
+       _tcsncpy(m_pszMachineName,pszMachineName?pszMachineName:_T(""),MAX_PATH);
+}
+
+BOOL CRegistryKey::IsPredefined()
+{
+       return ((m_hKey == HKEY_CLASSES_ROOT)||(m_hKey == HKEY_CURRENT_USER)||
+               (m_hKey == HKEY_LOCAL_MACHINE)||(m_hKey == HKEY_USERS)
+               ||(m_hKey == HKEY_PERFORMANCE_DATA)||(m_hKey == HKEY_CURRENT_CONFIG)
+               ||(m_hKey == HKEY_DYN_DATA));
+}
+
+DWORD CRegistryKey::GetDefaultValue(DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize)
+{
+       return RegQueryValueEx(m_hKey,NULL,NULL,pdwType,lpValueDataBuffer,pdwValueDataSize);
+}
+
+void CRegistryKey::LinkParent()
+{
+       m_pParent->m_pChild = this;     // self link
+}
+
+const TCHAR * CRegistryKey::GetValueTypeName(DWORD dwType)
+{
+       switch(dwType)
+       {
+       case REG_NONE:
+               return _T("REG_NONE\t\t");
+       case REG_SZ:
+               return _T("REG_SZ\t\t\t");
+       case REG_EXPAND_SZ:
+               return _T("REG_EXPAND_SZ\t\t");
+       case REG_BINARY:
+               return _T("REG_BINARY\t\t");
+       case REG_DWORD_LITTLE_ENDIAN:
+               return _T("REG_DWORD_LITTLE_ENDIAN\t");
+       case REG_DWORD_BIG_ENDIAN:
+               return _T("REG_DWORD_BIG_ENDIAN\t");
+       case REG_LINK:
+               return _T("REG_LINK\t\t");
+       case REG_MULTI_SZ:
+               return _T("REG_MULTI_SZ\t\t");
+       case REG_RESOURCE_LIST:
+               return _T("REG_RESOURCE_LIST\t");
+       case REG_FULL_RESOURCE_DESCRIPTOR:
+               return _T("REG_FULL_RESOURCE_DESCRIPTOR");
+       case REG_RESOURCE_REQUIREMENTS_LIST:
+               return _T("REG_RESOURCE_REQUIREMENTS_LIST");
+       default:
+               return _T("Unkown Type\t");
+       }
+}
+
+DWORD CRegistryKey::GetValue(TCHAR *pchValueName, DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize)
+{
+       return RegQueryValueEx(m_hKey,pchValueName,NULL,pdwType,lpValueDataBuffer,pdwValueDataSize);
+}
+
+DWORD CRegistryKey::GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor)
+{
+       return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+               NULL,NULL,pdwSecurityDescriptor,NULL);
+}
+
+LONG CRegistryKey::GetSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor)
+{
+       return RegGetKeySecurity(m_hKey,SecurityInformation,pSecurityDescriptor,lpcbSecurityDescriptor);
+}
+
+DWORD CRegistryKey::GetSubKeyCount()
+{
+       DWORD nCount;
+       DWORD nRet = RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,&nCount,NULL,NULL,NULL,
+               NULL,NULL,NULL,NULL);
+       if (nRet)
+               return 0;
+       return nCount;
+}
+
+DWORD CRegistryKey::GetValuesCount()
+{
+       DWORD nCount;
+       if (RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,
+               &nCount,NULL,NULL,NULL,NULL)) return 0;
+       return nCount;
+}
+
+TCHAR * CRegistryKey::GetSubKeyNameByIndex(DWORD dwIndex)
+{
+       DWORD dwError;
+       static TCHAR m_pchSubName[MAX_PATH+1];
+       dwError = RegEnumKey(m_hKey,dwIndex,m_pchSubName,MAX_PATH + 1);
+       switch (dwError)
+       {
+       case ERROR_SUCCESS:
+               return m_pchSubName;
+       case ERROR_NO_MORE_ITEMS:
+               return NULL;
+       default:
+               return NULL;
+       }
+}
+
+DWORD CRegistryKey::Create(REGSAM samDesired, DWORD *pdwDisposition, BOOL blnVolatile)
+{
+       ASSERT((m_hKey != HKEY_CLASSES_ROOT)&&(m_hKey != HKEY_CURRENT_USER)&&
+               (m_hKey != HKEY_LOCAL_MACHINE)&&(m_hKey != HKEY_USERS)
+               &&(m_hKey != HKEY_PERFORMANCE_DATA)&&(m_hKey != HKEY_CURRENT_CONFIG)
+               &&(m_hKey != HKEY_DYN_DATA));
+       if (m_hKey)
+       {
+               RegCloseKey(m_hKey);
+       }
+
+       HKEY hKey;
+
+       DWORD dwRet = RegCreateKeyEx(*m_pParent,m_pchKeyName,0,NULL,
+               blnVolatile?REG_OPTION_VOLATILE:REG_OPTION_NON_VOLATILE,
+               samDesired,
+               NULL,
+               &hKey,
+               pdwDisposition);
+       if (dwRet == ERROR_SUCCESS)
+       {
+               m_hKey = hKey;
+               UpdateKeyNameCase();
+       }
+       return dwRet;
+}
+
+DWORD CRegistryKey::DeleteSubkey(LPCTSTR pszSubKey, BOOL blnRecursive)
+{
+       CRegistryKey *pKey = new CRegistryKey(pszSubKey,this);
+       if (!pKey)
+               return ERROR_NOT_ENOUGH_MEMORY;
+
+       DWORD dwRet = pKey->Open(KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE);
+
+       if (!dwRet)
+               dwRet = pKey->Delete(blnRecursive);
+
+       delete pKey;
+
+       return dwRet;
+}
+
+DWORD CRegistryKey::Delete(BOOL blnRecursive)
+{
+       DWORD dwRet;
+       if (blnRecursive)
+       {
+               // Delete childs
+               while(GetSubKeyCount())
+               {
+                       TCHAR *pchKeyName = GetSubKeyNameByIndex(0);
+                       CRegistryKey *pKey = new CRegistryKey(pchKeyName,this);
+                       if (!pKey)
+                               return ERROR_NOT_ENOUGH_MEMORY;
+
+                       dwRet = pKey->Open(KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE);
+
+                       if (!dwRet)
+                               dwRet = pKey->Delete(blnRecursive);
+
+                       delete pKey;
+               }
+       }
+
+       // Delete yourself
+       return RegDeleteKey(m_pParent->m_hKey,m_pchKeyName);
+}
+
+DWORD CRegistryKey::SetValue(LPCTSTR pszValueName, DWORD dwType, BYTE *lpData, DWORD dwDataSize)
+{
+       return RegSetValueEx(m_hKey,pszValueName,0,dwType,lpData,dwDataSize);
+}
diff --git a/rosapps/sysutils/regexpl/RegistryKey.h b/rosapps/sysutils/regexpl/RegistryKey.h
new file mode 100644 (file)
index 0000000..0530552
--- /dev/null
@@ -0,0 +1,54 @@
+// RegistryKey.h: interface for the CRegistryKey class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(REGISTRYKEY_H__FEF419ED_6EB6_11D3_907D_204C4F4F5020__INCLUDED_)
+#define REGISTRYKEY_H__FEF419ED_6EB6_11D3_907D_204C4F4F5020__INCLUDED_
+
+class CRegistryKey  
+{
+public:
+       DWORD SetValue(LPCTSTR pszValueName, DWORD dwType, BYTE *lpData, DWORD dwDataSize);
+       DWORD Delete(BOOL blnRecursive);
+       DWORD DeleteSubkey(LPCTSTR pszSubKey, BOOL blnRecursive = FALSE);
+       DWORD Create(REGSAM samDesired, DWORD *pdwDisposition = NULL, BOOL blnVolatile = FALSE);
+       TCHAR * GetSubKeyNameByIndex(DWORD dwIndex);
+       DWORD GetValuesCount();
+       DWORD GetSubKeyCount();
+       LONG GetSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor);
+       DWORD GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor);
+       DWORD GetValue(TCHAR *pchValueName, DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize);
+       static const TCHAR * GetValueTypeName(DWORD dwType);
+       void LinkParent();
+       DWORD GetDefaultValue(DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize);
+       BOOL IsPredefined();
+       DWORD Open(REGSAM samDesired);
+       DWORD GetMaxValueNameLength(DWORD& dwMaxValueNameBuferSize);
+       DWORD GetMaxValueDataSize(DWORD& dwMaxValueDataBuferSize);
+       TCHAR * GetLastWriteTime();
+       void GetLastWriteTime(SYSTEMTIME& st);
+       DWORD GetNextValue(TCHAR *pchValueNameBuffer,DWORD& dwValueNameSize, DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize);
+       void InitValueEnumeration();
+       void UpdateKeyNameCase();
+       TCHAR * GetSubKeyName(DWORD& dwError);
+       void InitSubKeyEnumeration();
+       CRegistryKey * UpOneLevel();
+       operator HKEY(){return m_hKey;};
+       CRegistryKey * GetParent();
+       class CRegistryKey * GetChild();
+       TCHAR * GetKeyName();
+       CRegistryKey(const TCHAR *pchKeyName, class CRegistryKey *pParent);
+       CRegistryKey(HKEY hKey, LPCTSTR pszMachineName = NULL);
+       virtual ~CRegistryKey();
+private:
+       DWORD m_dwCurrentSubKeyIndex;
+       DWORD m_dwCurrentValueIndex;
+       HKEY m_hKey;
+       class CRegistryKey *m_pChild;
+       class CRegistryKey *m_pParent;
+       TCHAR m_pchKeyName[MAX_PATH+1];
+//     TCHAR *m_pchValueName;
+       TCHAR m_pszMachineName[MAX_PATH+1];
+};
+
+#endif // !defined(REGISTRYKEY_H__FEF419ED_6EB6_11D3_907D_204C4F4F5020__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/RegistryTree.cpp b/rosapps/sysutils/regexpl/RegistryTree.cpp
new file mode 100644 (file)
index 0000000..9f6a9c8
--- /dev/null
@@ -0,0 +1,434 @@
+/* $Id: RegistryTree.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// RegistryTree.cpp: implementation of the CRegistryTree class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "RegistryTree.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CRegistryTree::CRegistryTree(unsigned int nMaxPathSize)
+{
+       m_pszMachineName = NULL;
+       m_samDesiredOpenKeyAccess = 0;
+       m_pCurrentKey = m_pRoot = NULL;
+       m_ErrorMsg[ERROR_MSG_BUFFER_SIZE] = 0;
+       m_ChangeKeyBuffer = new TCHAR[nMaxPathSize];
+//#ifdef _DEBUG
+       m_nMaxPathSize = nMaxPathSize;
+//#endif
+}
+
+CRegistryTree::CRegistryTree(const CRegistryTree& Tree)
+{
+       m_pszMachineName = NULL;
+       m_samDesiredOpenKeyAccess = Tree.GetDesiredOpenKeyAccess();
+       m_pCurrentKey = m_pRoot = NULL;
+       m_ErrorMsg[ERROR_MSG_BUFFER_SIZE] = 0;
+       m_ChangeKeyBuffer = new TCHAR[m_nMaxPathSize = Tree.m_nMaxPathSize];
+       _tcscpy(m_ChangeKeyBuffer,Tree.GetCurrentPath());
+       ChangeCurrentKey(m_ChangeKeyBuffer);
+}
+
+CRegistryTree::~CRegistryTree()
+{
+       if (m_pszMachineName)
+               delete m_pszMachineName;
+
+       CRegistryKey *pNode;
+       while(m_pRoot)
+       {
+               pNode = m_pRoot;
+               m_pRoot = m_pRoot->GetChild();
+               delete pNode;
+       }
+
+       delete [] m_ChangeKeyBuffer;
+}
+
+const TCHAR * CRegistryTree::GetCurrentPath() const
+{
+       ASSERT(m_nMaxPathSize > 0);
+       unsigned int nBufferSize = m_nMaxPathSize;
+       CRegistryKey *pNode = m_pRoot;
+
+       nBufferSize--;
+       m_ChangeKeyBuffer[nBufferSize] = 0;
+
+       TCHAR *pchCurrentOffset = m_ChangeKeyBuffer;
+
+       if (m_pszMachineName)
+       {
+               size_t m = _tcslen(m_pszMachineName+2);
+               if (m > nBufferSize)
+               {       // No enough space in buffer to store machine name
+                       ASSERT(FALSE);
+               }
+               else
+               {
+                       _tcscpy(pchCurrentOffset,m_pszMachineName+2);
+                       pchCurrentOffset += m;
+                       nBufferSize -= m;
+               }
+       }
+
+       if (2 > nBufferSize)
+       {       // No enough space in buffer to store '\\'
+               ASSERT(FALSE);
+       }
+       else
+       {
+               *pchCurrentOffset = _T('\\');
+               pchCurrentOffset++;
+               nBufferSize--;
+       }
+
+       while(pNode)
+       {
+               TCHAR *pchKeyName = pNode->GetKeyName();
+               unsigned int nKeyNameLength = _tcslen(pchKeyName);
+               if ((nKeyNameLength+1) > nBufferSize)
+               {       // No enough space in buffer to store key name + '\\'
+                       ASSERT(FALSE);
+                       break;
+               }
+               _tcscpy(pchCurrentOffset,pchKeyName);
+               pchCurrentOffset[nKeyNameLength] = '\\';
+               pchCurrentOffset += nKeyNameLength+1;
+               nBufferSize -= nKeyNameLength+1;
+               pNode = pNode->GetChild();
+       }
+       *pchCurrentOffset = 0;
+       return m_ChangeKeyBuffer;
+}
+
+BOOL CRegistryTree::IsCurrentRoot()
+{
+       return m_pRoot == NULL;
+}
+
+// returns TRUE on success and FALSE on fail
+// on fail, extended information can be received  by calling GetLastErrorDescription();
+BOOL CRegistryTree::ChangeCurrentKey(const TCHAR *pchRelativePath)
+{
+       if (*pchRelativePath == _T('\\'))
+       {
+               CRegistryKey *pNode;
+               while(m_pRoot)
+               {
+                       pNode = m_pRoot;
+                       m_pRoot = m_pRoot->GetChild();
+                       delete pNode;
+               }
+               m_pCurrentKey = NULL;
+       }
+       TCHAR *pchSeps = _T("\\");
+
+       ASSERT(_tcslen(pchRelativePath) <= m_nMaxPathSize);
+       _tcscpy(m_ChangeKeyBuffer,pchRelativePath);
+
+       TCHAR *pchNewKey = _tcstok(m_ChangeKeyBuffer,pchSeps);
+
+       if ((!pchNewKey)&&((*pchRelativePath != _T('\\'))||(*(pchRelativePath+1) != 0)))
+       {
+               _tcscpy(m_ErrorMsg,_T("Invalid key name"));
+               return FALSE;
+       };
+       while (pchNewKey)
+       {
+               HKEY hNewKey;
+               if (m_pRoot == NULL)
+               {       // if this is the root key there are limations
+                       if ((_tcsicmp(pchNewKey,_T("HKCR")) == 0)||
+                               (_tcsicmp(pchNewKey,_T("HKEY_CLASSES_ROOT")) == 0))
+                       {
+                               hNewKey = HKEY_CLASSES_ROOT;
+                       }
+                       else if ((_tcsicmp(pchNewKey,_T("HKCU")) == 0)||
+                               (_tcsicmp(pchNewKey,_T("HKEY_CURRENT_USER")) == 0))
+                       {
+                               hNewKey = HKEY_CURRENT_USER;
+                       }
+                       else if ((_tcsicmp(pchNewKey,_T("HKLM")) == 0)||
+                               (_tcsicmp(pchNewKey,_T("HKEY_LOCAL_MACHINE")) == 0))
+                       {
+                               hNewKey = HKEY_LOCAL_MACHINE;
+                       }
+                       else if ((_tcsicmp(pchNewKey,_T("HKU")) == 0)||
+                               (_tcsicmp(pchNewKey,_T("HKEY_USERS")) == 0))
+                       {
+                               hNewKey = HKEY_USERS;
+                       }
+                       else if ((_tcsicmp(pchNewKey,_T("HKPD")) == 0)||
+                               (_tcsicmp(pchNewKey,_T("HKEY_PERFORMANCE_DATA")) == 0))
+                       {
+                               hNewKey = HKEY_PERFORMANCE_DATA;
+                       }
+                       else if ((_tcsicmp(pchNewKey,_T("HKDD")) == 0)||
+                               (_tcsicmp(pchNewKey,_T("HKEY_DYN_DATA")) == 0))
+                       {
+                               hNewKey = HKEY_DYN_DATA;
+                       }
+                       else if ((_tcsicmp(pchNewKey,_T("HKCC")) == 0)||
+                               (_tcsicmp(pchNewKey,_T("HKEY_CURRENT_CONFIG")) == 0))
+                       {
+                               hNewKey = HKEY_CURRENT_CONFIG;
+                       }
+                       else
+                       {
+                               _tcscpy(m_ErrorMsg,_T("Invalid key name."));
+                               return FALSE;
+                       }
+                       // Ok. Key to open is in hNewKey
+
+                       int nErr = ConnectRegistry(hNewKey);
+                       if (nErr)
+                       {
+                               _stprintf(m_ErrorMsg,_T("Cannot connect registry. Error is %d"),nErr);
+                               return FALSE;
+                       }
+               }       // if (m_pRoot == NULL)
+               else
+               {       // current key is not root key
+                       if (_tcsicmp(pchNewKey,_T("..")) == 0)
+                       {
+                               m_pCurrentKey = m_pCurrentKey->UpOneLevel();
+                               if (m_pCurrentKey == NULL)
+                               {
+                                       m_pRoot = NULL;
+                               }
+                       }
+                       else
+                       {       // Normal key name
+                               CRegistryKey *pNewKey = new CRegistryKey(pchNewKey,m_pCurrentKey);
+                               //RegOpenKeyExW(*m_pCurrentKey,pchNewKey,0,KEY_EXECUTE,&hNewKey)
+                               DWORD dwError = pNewKey->Open(m_samDesiredOpenKeyAccess);
+                               if (dwError != ERROR_SUCCESS)
+                               {
+                                       TCHAR *pchPreErrorMsg = _T("Cannot open key : "), *pchCurrentOffset = m_ErrorMsg;
+                                       _tcscpy(pchCurrentOffset,pchPreErrorMsg);
+                                       pchCurrentOffset += _tcslen(pchPreErrorMsg);
+
+                                       _tcscpy(pchCurrentOffset,pchNewKey);
+                                       pchCurrentOffset += _tcslen(pchNewKey);
+
+                                       TCHAR *pchMsg = _T("\nError ");
+                                       _tcscpy(pchCurrentOffset,pchMsg);
+                                       pchCurrentOffset += _tcslen(pchMsg);
+
+                                       TCHAR Buffer[256];
+                                       _tcscpy(pchCurrentOffset,_itot(dwError,Buffer,10));
+                                       pchCurrentOffset += _tcslen(Buffer);
+
+                                       pchMsg = _T("\n");
+                                       _tcscpy(pchCurrentOffset,pchMsg);
+                                       pchCurrentOffset += _tcslen(pchMsg);
+                                       switch(dwError)
+                                       {
+                                       case 5:
+                                               pchMsg = _T("(Access denied)");
+                                               break;
+                                       case 2:
+                                               pchMsg = _T("(The system cannot find the key specified)");
+                                               break;
+                                       }
+
+                                       _tcscpy(pchCurrentOffset,pchMsg);
+                                       pchCurrentOffset += _tcslen(pchMsg);
+
+                                       delete pNewKey;
+
+                                       return FALSE;
+                               }
+                               pNewKey->LinkParent();
+                               m_pCurrentKey = pNewKey;
+                       }
+               }
+               // Get next key name
+               pchNewKey = _tcstok(NULL,pchSeps);
+       }
+       return TRUE;
+}
+
+TCHAR * CRegistryTree::GetLastErrorDescription()
+{
+       return m_ErrorMsg;
+}
+
+CRegistryKey * CRegistryTree::GetCurrentKey()
+{
+       return m_pCurrentKey;
+}
+
+void CRegistryTree::SetDesiredOpenKeyAccess(REGSAM samDesired)
+{
+       m_samDesiredOpenKeyAccess = samDesired;
+}
+
+REGSAM CRegistryTree::GetDesiredOpenKeyAccess() const
+{
+       return m_samDesiredOpenKeyAccess;
+}
+
+int CRegistryTree::ConnectRegistry(HKEY hKey)
+{
+       CRegistryKey *pKey = new CRegistryKey(hKey,m_pszMachineName);
+       int ret = pKey->Open(m_samDesiredOpenKeyAccess);
+
+       if (ret == 0)
+       {
+               CRegistryKey *pNode;
+               while(m_pRoot)
+               {
+                       pNode = m_pRoot;
+                       m_pRoot = m_pRoot->GetChild();
+                       delete pNode;
+               }
+               m_pCurrentKey = NULL;
+               m_pRoot = m_pCurrentKey = pKey;
+       }
+       else
+       {
+               delete pKey;
+       }
+
+       return ret;
+}
+
+void CRegistryTree::SetMachineName(LPCTSTR pszMachineName)
+{
+       if (m_pszMachineName)
+               delete m_pszMachineName;
+
+       if (pszMachineName == NULL)
+       {
+               m_pszMachineName = NULL;
+               return;
+       }
+
+       while ((*pszMachineName)&&(*pszMachineName == _T('\\')))
+               pszMachineName++;
+
+       if (*pszMachineName == 0)
+       {
+               ASSERT(FALSE);
+       }
+
+       m_pszMachineName = new TCHAR[_tcslen(pszMachineName)+3];
+       _tcscpy(m_pszMachineName,_T("\\\\"));
+       _tcscpy(m_pszMachineName+2,pszMachineName);
+       _tcsupr(m_pszMachineName+2);
+}
+
+BOOL CRegistryTree::NewKey(const TCHAR *pchKeyName, BOOL blnVolatile)
+{
+       CRegistryKey *pNewKey = new CRegistryKey(pchKeyName,m_pCurrentKey);
+       DWORD dwDisposition;
+       DWORD dwError = pNewKey->Create(0,&dwDisposition,blnVolatile);
+       switch (dwDisposition)
+       {
+       case REG_OPENED_EXISTING_KEY:
+               _sntprintf(m_ErrorMsg,ERROR_MSG_BUFFER_SIZE,_T("A key \"%s\" already exists."),pchKeyName);
+               delete pNewKey;
+               return FALSE;
+       case REG_CREATED_NEW_KEY:
+               break;
+       default:
+               ASSERT(FALSE);
+       }
+       if (dwError != ERROR_SUCCESS)
+       {
+               TCHAR *pchCurrentOffset = m_ErrorMsg;
+               TCHAR *pchPreErrorMsg = _T("Cannot create key : ");
+               _tcscpy(pchCurrentOffset,pchPreErrorMsg);
+               pchCurrentOffset += _tcslen(pchPreErrorMsg);
+
+               _tcscpy(pchCurrentOffset,pchKeyName);
+               pchCurrentOffset += _tcslen(pchKeyName);
+
+               TCHAR *pchMsg = _T("\nError ");
+               _tcscpy(pchCurrentOffset,pchMsg);
+               pchCurrentOffset += _tcslen(pchMsg);
+
+               TCHAR Buffer[256];
+               _tcscpy(pchCurrentOffset,_itot(dwError,Buffer,10));
+               pchCurrentOffset += _tcslen(Buffer);
+
+               pchMsg = _T("\n");
+               _tcscpy(pchCurrentOffset,pchMsg);
+               pchCurrentOffset += _tcslen(pchMsg);
+               switch(dwError)
+               {
+               case 5:
+                       pchMsg = _T("(Access denied)");
+                       break;
+               case 2:
+                       pchMsg = _T("(The system cannot find the key specified)");
+                       break;
+               }
+
+               _tcscpy(pchCurrentOffset,pchMsg);
+               pchCurrentOffset += _tcslen(pchMsg);
+
+               delete pNewKey;
+
+               return FALSE;
+       }
+
+       delete pNewKey;
+
+       return TRUE;
+}
+
+BOOL CRegistryTree::DeleteKey(const TCHAR *pchKeyName, BOOL blnRecursive)
+{
+       DWORD dwError = m_pCurrentKey->DeleteSubkey(pchKeyName,blnRecursive);
+       if (dwError != ERROR_SUCCESS)
+       {
+               TCHAR *pchPreErrorMsg = _T("Cannot open key : "), *pchCurrentOffset = m_ErrorMsg;
+               _tcscpy(pchCurrentOffset,pchPreErrorMsg);
+               pchCurrentOffset += _tcslen(pchPreErrorMsg);
+
+               _tcscpy(pchCurrentOffset,pchKeyName);
+               pchCurrentOffset += _tcslen(pchKeyName);
+
+               TCHAR *pchMsg = _T("\nError ");
+               _tcscpy(pchCurrentOffset,pchMsg);
+               pchCurrentOffset += _tcslen(pchMsg);
+
+               TCHAR Buffer[256];
+               _tcscpy(pchCurrentOffset,_itot(dwError,Buffer,10));
+               pchCurrentOffset += _tcslen(Buffer);
+
+               pchMsg = _T("\n");
+               _tcscpy(pchCurrentOffset,pchMsg);
+               pchCurrentOffset += _tcslen(pchMsg);
+               switch(dwError)
+               {
+               case 5:
+                       pchMsg = _T("(Access denied)");
+                       break;
+               case 2:
+                       pchMsg = _T("(The system cannot find the key specified)");
+                       break;
+               }
+
+               _tcscpy(pchCurrentOffset,pchMsg);
+               pchCurrentOffset += _tcslen(pchMsg);
+
+               return FALSE;
+       }
+       return TRUE;
+}
diff --git a/rosapps/sysutils/regexpl/RegistryTree.h b/rosapps/sysutils/regexpl/RegistryTree.h
new file mode 100644 (file)
index 0000000..c0a94e9
--- /dev/null
@@ -0,0 +1,43 @@
+// RegistryTree.h: interface for the CRegistryTree class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(REGISTRYTREE_H__239A6461_70F2_11D3_9085_204C4F4F5020__INCLUDED_)
+#define REGISTRYTREE_H__239A6461_70F2_11D3_9085_204C4F4F5020__INCLUDED_
+
+#include "RegistryKey.h"
+
+#define ERROR_MSG_BUFFER_SIZE  1024
+
+class CRegistryTree  
+{
+public:
+       BOOL DeleteKey(const TCHAR *pchKeyName, BOOL blnRecursive = FALSE);
+       BOOL NewKey(const TCHAR *pchKeyName, BOOL blnVolatile = FALSE);
+       void SetMachineName(LPCTSTR pszMachineName);
+       int ConnectRegistry(HKEY hKey);
+       REGSAM GetDesiredOpenKeyAccess() const;
+       void SetDesiredOpenKeyAccess(REGSAM samDesired);
+       CRegistryKey * GetCurrentKey();
+       TCHAR * GetLastErrorDescription();
+       BOOL ChangeCurrentKey(const TCHAR *pchRelativePath);
+       BOOL IsCurrentRoot();
+       const TCHAR * GetCurrentPath() const;
+
+       // Constructor
+       // Parameters:
+       //              nMaxPathSize - size in characters of longest path including terminating NULL char
+       CRegistryTree(unsigned int nMaxPathSize);
+       CRegistryTree(const CRegistryTree& Tree);
+
+       virtual ~CRegistryTree();
+private:
+       unsigned int m_nMaxPathSize;
+       TCHAR *m_ChangeKeyBuffer;
+       CRegistryKey *m_pRoot, *m_pCurrentKey;
+       TCHAR m_ErrorMsg[ERROR_MSG_BUFFER_SIZE+1];
+       REGSAM m_samDesiredOpenKeyAccess;
+       LPTSTR m_pszMachineName;
+};
+
+#endif // !defined(REGISTRYTREE_H__239A6461_70F2_11D3_9085_204C4F4F5020__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/SecurityDescriptor.cpp b/rosapps/sysutils/regexpl/SecurityDescriptor.cpp
new file mode 100644 (file)
index 0000000..e2685ad
--- /dev/null
@@ -0,0 +1,313 @@
+/* $Id: SecurityDescriptor.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// SecurityDescriptor.cpp: implementation of the CSecurityDescriptor class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include <windows.h>
+#include <assert.h>
+#include "SecurityDescriptor.h"
+
+#define ASSERT assert
+
+// *** THIS SHOULD GO IN A MINGW/ROS HEADER - Begin
+#if 1
+
+#define SID_REVISION (1) // Current revision level
+
+//typedef struct _ACE_HEADER {
+//    BYTE  AceType;
+//    BYTE  AceFlags;
+//    WORD   AceSize;
+//} ACE_HEADER;
+typedef ACE_HEADER * PACE_HEADER;
+
+//#define ACCESS_ALLOWED_ACE_TYPE          (0x0)
+//#define ACCESS_DENIED_ACE_TYPE           (0x1)
+//#define SYSTEM_AUDIT_ACE_TYPE            (0x2)
+//#define SYSTEM_ALARM_ACE_TYPE            (0x3)
+
+//#define OBJECT_INHERIT_ACE                (0x1)
+//#define CONTAINER_INHERIT_ACE             (0x2)
+//#define NO_PROPAGATE_INHERIT_ACE          (0x4)
+//#define INHERIT_ONLY_ACE                  (0x8)
+//#define VALID_INHERIT_FLAGS               (0xF)
+
+//#define SUCCESSFUL_ACCESS_ACE_FLAG       (0x40)
+//#define FAILED_ACCESS_ACE_FLAG           (0x80)
+
+typedef struct _SYSTEM_AUDIT_ACE {
+    ACE_HEADER Header;
+    ACCESS_MASK Mask;
+    DWORD SidStart;
+} SYSTEM_AUDIT_ACE;
+
+#endif
+// *** THIS SHOULD GO IN A MINGW/ROS HEADER - End
+
+
+BOOL GetTextualSid(
+    PSID pSid,            // binary Sid
+    LPTSTR TextualSid,    // buffer for Textual representation of Sid
+    LPDWORD lpdwBufferLen // required/provided TextualSid buffersize
+    )
+{
+    PSID_IDENTIFIER_AUTHORITY psia;
+    DWORD dwSubAuthorities;
+    DWORD dwSidRev=SID_REVISION;
+    DWORD dwCounter;
+    DWORD dwSidSize;
+
+    // Validate the binary SID.
+
+    if(!IsValidSid(pSid)) return FALSE;
+
+    // Get the identifier authority value from the SID.
+
+    psia = GetSidIdentifierAuthority(pSid);
+
+    // Get the number of subauthorities in the SID.
+
+    dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
+
+    // Compute the buffer length.
+    // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
+
+    dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
+
+    // Check input buffer length.
+    // If too small, indicate the proper size and set last error.
+
+    if (*lpdwBufferLen < dwSidSize)
+    {
+        *lpdwBufferLen = dwSidSize;
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return FALSE;
+    }
+
+    // Add 'S' prefix and revision number to the string.
+
+    dwSidSize=wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );
+
+    // Add SID identifier authority to the string.
+
+    if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
+    {
+        dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
+                    TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
+                    (USHORT)psia->Value[0],
+                    (USHORT)psia->Value[1],
+                    (USHORT)psia->Value[2],
+                    (USHORT)psia->Value[3],
+                    (USHORT)psia->Value[4],
+                    (USHORT)psia->Value[5]);
+    }
+    else
+    {
+        dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
+                    TEXT("%lu"),
+                    (ULONG)(psia->Value[5]      )   +
+                    (ULONG)(psia->Value[4] <<  8)   +
+                    (ULONG)(psia->Value[3] << 16)   +
+                    (ULONG)(psia->Value[2] << 24)   );
+    }
+
+    // Add SID subauthorities to the string.
+    //
+    for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
+    {
+        dwSidSize+=wsprintf(TextualSid + dwSidSize, TEXT("-%lu"),
+                    *GetSidSubAuthority(pSid, dwCounter) );
+    }
+
+    return TRUE;
+}
+
+const TCHAR * GetSidTypeName(SID_NAME_USE Use)
+{
+       switch(Use)
+       {
+       case SidTypeUser:
+               return _T("User SID");
+       case SidTypeGroup:
+               return _T("Group SID");
+       case SidTypeDomain:
+               return _T("Domain SID");
+       case SidTypeAlias:
+               return _T("Alias SID");
+       case SidTypeWellKnownGroup:
+               return _T("SID for a well-known group");
+       case SidTypeDeletedAccount:
+               return _T("SID for a deleted account");
+       case SidTypeInvalid:
+               return _T("Invalid SID");
+       case SidTypeUnknown:
+               return _T("Unknown SID type");
+       default:
+               return _T("Error. Cannot recognize SID type.");
+       }
+}
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CSecurityDescriptor::CSecurityDescriptor()
+{
+       m_pSecurityDescriptor = NULL;
+       m_pCurrentACEHeader = NULL;
+}
+
+CSecurityDescriptor::~CSecurityDescriptor()
+{
+}
+
+void CSecurityDescriptor::AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor)
+{
+       m_pSecurityDescriptor = pSecurityDescriptor;
+}
+
+DWORD CSecurityDescriptor::BeginDACLInteration()
+{
+       if (!GetSecurityDescriptorDacl(m_pSecurityDescriptor,&m_blnDACLPresent,&m_pDACL,&m_blnDACLDefaulted))
+       {
+               throw GetLastError();
+       }
+       return ERROR_SUCCESS;
+}
+
+BOOL CSecurityDescriptor::DescriptorContainsDACL()
+{
+       return m_blnDACLPresent;
+}
+
+DWORD CSecurityDescriptor::BeginSACLInteration()
+{
+       if (!GetSecurityDescriptorSacl(m_pSecurityDescriptor,&m_blnSACLPresent,&m_pSACL,&m_blnSACLDefaulted))
+               throw GetLastError();
+       return ERROR_SUCCESS;
+}
+
+BOOL CSecurityDescriptor::DescriptorContainsSACL()
+{
+       return m_blnSACLPresent;
+}
+
+BOOL CSecurityDescriptor::HasNULLDACL()
+{
+       ASSERT(m_blnDACLPresent);
+       return (m_pDACL == NULL);
+}
+
+BOOL CSecurityDescriptor::HasValidDACL()
+{
+       ASSERT(m_blnDACLPresent);
+       ASSERT(m_pDACL != NULL);
+       return IsValidAcl(m_pDACL);
+}
+
+BOOL CSecurityDescriptor::HasNULLSACL()
+{
+       ASSERT(m_blnSACLPresent);
+       return (m_pSACL == NULL);
+}
+
+BOOL CSecurityDescriptor::HasValidSACL()
+{
+       ASSERT(m_blnSACLPresent);
+       ASSERT(m_pSACL != NULL);
+       return IsValidAcl(m_pSACL);
+}
+
+DWORD CSecurityDescriptor::GetDACLEntriesCount()
+{
+       ACL_SIZE_INFORMATION SizeInfo;
+       if (!GetAclInformation(m_pDACL,&SizeInfo,sizeof(SizeInfo),AclSizeInformation))
+               throw GetLastError();
+       return SizeInfo.AceCount;
+}
+
+DWORD CSecurityDescriptor::GetSACLEntriesCount()
+{
+       ACL_SIZE_INFORMATION SizeInfo;
+       if (!GetAclInformation(m_pSACL,&SizeInfo,sizeof(SizeInfo),AclSizeInformation))
+               throw GetLastError();
+       return SizeInfo.AceCount;
+}
+
+CSecurityDescriptor::ACEntryType CSecurityDescriptor::GetDACLEntry(DWORD nIndex)
+{
+       void *pACE;
+       if (!GetAce(m_pDACL,nIndex,&pACE)) throw GetLastError();
+       m_pCurrentACEHeader = (PACE_HEADER)pACE;
+       if (m_pCurrentACEHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
+       {
+               return AccessAlowed;
+       }
+       if (m_pCurrentACEHeader->AceType == ACCESS_DENIED_ACE_TYPE)
+       {
+               return AccessDenied;
+       }
+       return Unknown;
+}
+
+CSecurityDescriptor::ACEntryType CSecurityDescriptor::GetSACLEntry(DWORD nIndex, BOOL& blnFailedAccess, BOOL& blnSeccessfulAccess)
+{
+       void *pACE;
+       if (!GetAce(m_pSACL,nIndex,&pACE)) throw GetLastError();
+       m_pCurrentACEHeader = (PACE_HEADER)pACE;
+       if (m_pCurrentACEHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
+       {
+               blnFailedAccess = m_pCurrentACEHeader->AceFlags & FAILED_ACCESS_ACE_FLAG;
+               blnSeccessfulAccess = m_pCurrentACEHeader->AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG;
+               return SystemAudit;
+       }
+       return Unknown;
+}
+
+PSID CSecurityDescriptor::GetCurrentACE_SID()
+{
+       ASSERT(m_pCurrentACEHeader != NULL);
+       switch(m_pCurrentACEHeader->AceType)
+       {
+       case ACCESS_ALLOWED_ACE_TYPE:
+               return ((PSID)&(((ACCESS_ALLOWED_ACE *)m_pCurrentACEHeader)->SidStart));
+       case ACCESS_DENIED_ACE_TYPE:
+               return ((PSID)&(((ACCESS_DENIED_ACE *)m_pCurrentACEHeader)->SidStart));
+       case SYSTEM_AUDIT_ACE_TYPE:
+               return ((PSID)&(((SYSTEM_AUDIT_ACE *)m_pCurrentACEHeader)->SidStart));
+       default:
+               ASSERT(FALSE);  // Do not call this function for unknown ACE types !!!
+               return NULL;
+       }
+}
+
+void CSecurityDescriptor::GetCurrentACE_AccessMask(DWORD& dwMask)
+{
+       ASSERT(m_pCurrentACEHeader != NULL);
+       switch(m_pCurrentACEHeader->AceType)
+       {
+       case ACCESS_ALLOWED_ACE_TYPE:
+               dwMask = (((ACCESS_ALLOWED_ACE *)m_pCurrentACEHeader)->Mask);
+               return;
+       case ACCESS_DENIED_ACE_TYPE:
+               dwMask = (((ACCESS_DENIED_ACE *)m_pCurrentACEHeader)->Mask);
+               return;
+       case SYSTEM_AUDIT_ACE_TYPE:
+               dwMask = (((SYSTEM_AUDIT_ACE *)m_pCurrentACEHeader)->Mask);
+               return;
+       default:
+               ASSERT(FALSE);  // Do not call this function for unknown ACE types !!!
+               return;
+       }
+}
+
+
diff --git a/rosapps/sysutils/regexpl/SecurityDescriptor.h b/rosapps/sysutils/regexpl/SecurityDescriptor.h
new file mode 100644 (file)
index 0000000..898ad89
--- /dev/null
@@ -0,0 +1,54 @@
+// SecurityDescriptor.h: interface for the CSecurityDescriptor class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SECURITYDESCRIPTOR_H__71D0A7E6_8A00_11D3_9103_204C4F4F5020__INCLUDED_)
+#define SECURITYDESCRIPTOR_H__71D0A7E6_8A00_11D3_9103_204C4F4F5020__INCLUDED_
+
+BOOL GetTextualSid(
+    PSID pSid,            // binary Sid
+    LPTSTR TextualSid,    // buffer for Textual representation of Sid
+    LPDWORD lpdwBufferLen // required/provided TextualSid buffersize
+    );
+
+const TCHAR * GetSidTypeName(SID_NAME_USE Use);
+
+class CSecurityDescriptor  
+{
+public:
+       void GetCurrentACE_AccessMask(DWORD& dwMask);
+       PSID GetCurrentACE_SID();
+       enum ACEntryType
+       {
+               Unknown,
+               AccessAlowed,
+               AccessDenied,
+               SystemAudit
+       };
+       ACEntryType GetDACLEntry(DWORD nIndex);
+       ACEntryType GetSACLEntry(DWORD nIndex, BOOL& blnFailedAccess, BOOL& blnSeccessfulAccess);
+       DWORD GetDACLEntriesCount();
+       DWORD GetSACLEntriesCount();
+       BOOL HasValidDACL();
+       BOOL HasNULLDACL();
+       BOOL HasValidSACL();
+       BOOL HasNULLSACL();
+       BOOL DescriptorContainsDACL();
+       BOOL DescriptorContainsSACL();
+       DWORD BeginDACLInteration();
+       DWORD BeginSACLInteration();
+       void AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor);
+       CSecurityDescriptor();
+       virtual ~CSecurityDescriptor();
+private:
+       PSECURITY_DESCRIPTOR m_pSecurityDescriptor;
+       BOOL m_blnDACLPresent;
+       BOOL m_blnDACLDefaulted;
+       PACL m_pDACL;
+       BOOL m_blnSACLPresent;
+       BOOL m_blnSACLDefaulted;
+       PACL m_pSACL;
+       ACE_HEADER *m_pCurrentACEHeader;
+};
+
+#endif // !defined(SECURITYDESCRIPTOR_H__71D0A7E6_8A00_11D3_9103_204C4F4F5020__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommand.cpp b/rosapps/sysutils/regexpl/ShellCommand.cpp
new file mode 100644 (file)
index 0000000..8c95be0
--- /dev/null
@@ -0,0 +1,30 @@
+/* $Id: ShellCommand.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommand.cpp: implementation of the CShellCommand class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommand.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommand::CShellCommand()
+{
+
+}
+
+CShellCommand::~CShellCommand()
+{
+
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommand.h b/rosapps/sysutils/regexpl/ShellCommand.h
new file mode 100644 (file)
index 0000000..6f68b3f
--- /dev/null
@@ -0,0 +1,23 @@
+// ShellCommand.h: interface for the CShellCommand class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMAND_H__D29C1193_5942_11D4_A037_C5AC8D00940F__INCLUDED_)
+#define SHELLCOMMAND_H__D29C1193_5942_11D4_A037_C5AC8D00940F__INCLUDED_
+
+#include "Console.h"
+#include "ArgumentParser.h"
+
+// this class provides common interface to shell commands
+class CShellCommand  
+{
+public:
+       CShellCommand();
+       virtual ~CShellCommand();
+       virtual BOOL Match(const TCHAR *pchCommand) = 0;
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments) = 0;
+       virtual const TCHAR * GetHelpString() = 0;
+       virtual const TCHAR * GetHelpShortDescriptionString() = 0;
+};
+
+#endif // !defined(SHELLCOMMAND_H__D29C1193_5942_11D4_A037_C5AC8D00940F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp b/rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp
new file mode 100644 (file)
index 0000000..076fcd7
--- /dev/null
@@ -0,0 +1,92 @@
+/* $Id: ShellCommandChangeKey.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandChangeKey.cpp: implementation of the CShellCommandChangeKey class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "RegistryExplorer.h"
+#include "ShellCommandChangeKey.h"
+
+#define CD_CMD                         _T("CD")
+#define CD_CMD_LENGTH          COMMAND_LENGTH(CD_CMD)
+#define CD_CMD_SHORT_DESC      CD_CMD _T(" command changes current key.\n")
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandChangeKey::CShellCommandChangeKey(CRegistryTree& rTree):m_rTree(rTree)
+{
+
+}
+
+CShellCommandChangeKey::~CShellCommandChangeKey()
+{
+
+}
+
+BOOL CShellCommandChangeKey::Match(const TCHAR *pchCommand)
+{
+       if (_tcsicmp(pchCommand,CD_CMD) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,CD_CMD _T(".."),CD_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,CD_CMD _T("\\"),CD_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
+               return TRUE;
+       return FALSE;
+}
+
+int CShellCommandChangeKey::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       BOOL blnHelp = FALSE;
+
+       rArguments.ResetArgumentIteration();
+       const TCHAR *pchCommandItself = rArguments.GetNextArgument();
+       const TCHAR *pchPath = rArguments.GetNextArgument();
+
+       if ((_tcsnicmp(pchCommandItself,CD_CMD _T(".."),CD_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
+               (_tcsnicmp(pchCommandItself,CD_CMD _T("\\"),CD_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
+       {
+               if (!pchPath) pchPath = pchCommandItself + CD_CMD_LENGTH;
+               else blnHelp = TRUE;
+       }
+
+       if ((!blnHelp)&&(pchPath != NULL)&&(!rArguments.GetNextArgument()))
+       {
+               ASSERT(_tcslen(pchPath) <= PROMPT_BUFFER_SIZE);
+               if (!m_rTree.ChangeCurrentKey(pchPath))
+               {
+                       rConsole.Write(m_rTree.GetLastErrorDescription());
+                       rConsole.Write(_T("\n"));
+               }
+       }
+       else
+       {
+               rConsole.Write(GetHelpString());
+       }
+
+       return 0;
+}
+
+const TCHAR * CShellCommandChangeKey::GetHelpString()
+{
+       return CD_CMD_SHORT_DESC
+                       _T("Syntax: ") CD_CMD _T(" <KEY>\n\n")
+                       _T("    <KEY> - Relative path of desired key.\n\n")
+                       _T("Without parameters, command displays this help.\n");
+
+}
+
+const TCHAR * CShellCommandChangeKey::GetHelpShortDescriptionString()
+{
+       return CD_CMD_SHORT_DESC;
+}
+
diff --git a/rosapps/sysutils/regexpl/ShellCommandChangeKey.h b/rosapps/sysutils/regexpl/ShellCommandChangeKey.h
new file mode 100644 (file)
index 0000000..e5e4cb1
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandChangeKey.h: interface for the CShellCommandChangeKey class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDCHANGEKEY_H__848A2506_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDCHANGEKEY_H__848A2506_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandChangeKey : public CShellCommand  
+{
+public:
+       CShellCommandChangeKey(CRegistryTree& rTree);
+       virtual ~CShellCommandChangeKey();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDCHANGEKEY_H__848A2506_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandConnect.cpp b/rosapps/sysutils/regexpl/ShellCommandConnect.cpp
new file mode 100644 (file)
index 0000000..7426201
--- /dev/null
@@ -0,0 +1,86 @@
+/* $Id: ShellCommandConnect.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandConnect.cpp: implementation of the CShellCommandConnect class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandConnect.h"
+
+#define CONNECT_CMD                    _T("CONNECT")
+#define CONNECT_CMD_SHORT_DESC CONNECT_CMD _T(" command is used to connect to remote registry.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandConnect::CShellCommandConnect(CRegistryTree& rTree):m_rTree(rTree)
+{
+}
+
+CShellCommandConnect::~CShellCommandConnect()
+{
+}
+
+BOOL CShellCommandConnect::Match(const TCHAR *pchCommand)
+{
+       return _tcsicmp(pchCommand,CONNECT_CMD) == 0;
+}
+
+int CShellCommandConnect::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       const TCHAR *pchArg;
+       const TCHAR *pchMachine = NULL;
+       BOOL blnHelp = FALSE;
+
+       VERIFY(m_rTree.ChangeCurrentKey(_T("\\")));
+
+       while ((pchArg = rArguments.GetNextArgument()) != NULL)
+       {
+               if ((_tcsicmp(pchArg,_T("/?")) == 0)
+                       ||(_tcsicmp(pchArg,_T("-?")) == 0))
+               {
+                       blnHelp = TRUE;
+               }
+//             else if ((_tcsicmp(pchArg,_T("-a")) == 0)||
+//                     (_tcsicmp(pchArg,_T("/a")) == 0))
+//             {
+//             }
+               else
+               {
+                       pchMachine = pchArg;
+               }
+       }
+
+       if (blnHelp)
+               rConsole.Write(GetHelpString());
+
+       m_rTree.SetMachineName(pchMachine);
+       return 0;
+}
+
+const TCHAR * CShellCommandConnect::GetHelpString()
+{
+       return CONNECT_CMD_SHORT_DESC
+//                     _T("Syntax: ") CONNECT_CMD _T(" [Switches] [/?] machine\n\n")
+                       _T("Syntax: ") CONNECT_CMD _T(" /? | MACHINE\n\n")
+                       _T("    /? - This help.\n\n")
+//                     _T("Switches are:\n")
+//                     _T("    -a anonymous login.\n")
+                       _T("    MACHINE is name/ip of the remote machine.\n")
+                       _T("Example:\n")
+                       _T("    ") CONNECT_CMD _T(" BOB");
+}
+
+const TCHAR * CShellCommandConnect::GetHelpShortDescriptionString()
+{
+       return CONNECT_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandConnect.h b/rosapps/sysutils/regexpl/ShellCommandConnect.h
new file mode 100644 (file)
index 0000000..3bada8f
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandConnect.h: interface for the CShellCommandConnect class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDCONNECT_H__848A250C_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDCONNECT_H__848A250C_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandConnect : public CShellCommand  
+{
+public:
+       CShellCommandConnect(CRegistryTree& rTree);
+       virtual ~CShellCommandConnect();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDCONNECT_H__848A250C_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandDACL.cpp b/rosapps/sysutils/regexpl/ShellCommandDACL.cpp
new file mode 100644 (file)
index 0000000..4e006d2
--- /dev/null
@@ -0,0 +1,362 @@
+/* $Id: ShellCommandDACL.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandDACL.cpp: implementation of the CShellCommandDACL class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandDACL.h"
+#include "RegistryExplorer.h"
+#include "SecurityDescriptor.h"
+
+#define DACL_CMD                       _T("DACL")
+#define DACL_CMD_LENGTH                COMMAND_LENGTH(DACL_CMD)
+#define DACL_CMD_SHORT_DESC    DACL_CMD _T(" command is used to view")/*"/edit"*/_T(" key's DACL.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandDACL::CShellCommandDACL(CRegistryTree& rTree):m_rTree(rTree)
+{
+
+}
+
+CShellCommandDACL::~CShellCommandDACL()
+{
+
+}
+
+BOOL CShellCommandDACL::Match(const TCHAR *pchCommand)
+{
+       if (_tcsicmp(pchCommand,DACL_CMD) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,DACL_CMD _T(".."),DACL_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,DACL_CMD _T("/") ,DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,DACL_CMD _T("\\"),DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       return FALSE;
+}
+
+int CShellCommandDACL::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       rArguments.ResetArgumentIteration();
+
+       const TCHAR *pchKey = NULL;
+       BOOL blnDo = TRUE;
+       BOOL blnBadParameter = FALSE;
+       BOOL blnHelp = FALSE;
+       const TCHAR *pchParameter;
+       const TCHAR *pchCommandItself = rArguments.GetNextArgument();
+       DWORD dwError;
+
+       if ((_tcsnicmp(pchCommandItself,DACL_CMD _T(".."),DACL_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
+               (_tcsnicmp(pchCommandItself,DACL_CMD _T("\\"),DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
+       {
+               pchKey = pchCommandItself + DACL_CMD_LENGTH;
+       }
+       else if (_tcsnicmp(pchCommandItself,DACL_CMD _T("/"),DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+       {
+               pchParameter = pchCommandItself + DACL_CMD_LENGTH;
+               goto CheckDACLArgument;
+       }
+
+       while((pchParameter = rArguments.GetNextArgument()) != NULL)
+       {
+CheckDACLArgument:
+               blnBadParameter = FALSE;
+               if ((_tcsicmp(pchParameter,_T("/?")) == 0)
+                       ||(_tcsicmp(pchParameter,_T("-?")) == 0))
+               {
+                       blnHelp = TRUE;
+                       blnDo = pchKey != NULL;
+               }
+               else if (!pchKey)
+               {
+                       pchKey = pchParameter;
+                       blnDo = TRUE;
+               }
+               else
+               {
+                       blnBadParameter = TRUE;
+               }
+               if (blnBadParameter)
+               {
+                       rConsole.Write(_T("Bad parameter: "));
+                       rConsole.Write(pchParameter);
+                       rConsole.Write(_T("\n"));
+               }
+       }
+
+       CRegistryTree *pTree = NULL;
+       CRegistryKey *pKey = NULL;
+       if (pchKey)
+       {
+               pTree = new CRegistryTree(m_rTree);
+               if ((_tcscmp(pTree->GetCurrentPath(),m_rTree.GetCurrentPath()) != 0)||(!pTree->ChangeCurrentKey(pchKey)))
+               {
+                       rConsole.Write(_T("Cannot open key "));
+                       rConsole.Write(pchKey);
+                       rConsole.Write(_T("\n"));
+                       //blnHelp = TRUE;
+                       blnDo = FALSE;
+               }
+               else
+               {
+                       pKey = pTree->GetCurrentKey();
+               }
+       }
+       else
+       {
+               pKey = m_rTree.GetCurrentKey();
+       }
+
+       if (blnHelp)
+       {
+               rConsole.Write(GetHelpString());
+       }
+
+       if (blnDo&&blnHelp) rConsole.Write(_T("\n"));
+
+       if (blnDo)
+       {
+               if (pKey == NULL)
+               {       // root key
+                       rConsole.Write(DACL_CMD COMMAND_NA_ON_ROOT);
+               }
+               else
+               {
+                       DWORD dwSecurityDescriptorLength;
+                       rConsole.Write(_T("Key : "));
+                       rConsole.Write(_T("\\"));
+                       rConsole.Write(pTree?pTree->GetCurrentPath():m_rTree.GetCurrentPath());
+                       rConsole.Write(_T("\n"));
+                       PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
+                       TCHAR *pchName = NULL, *pchDomainName = NULL;
+                       try
+                       {
+                               dwError = pKey->GetSecurityDescriptorLength(&dwSecurityDescriptorLength);
+                               if (dwError != ERROR_SUCCESS) throw dwError;
+                               
+                               pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength];
+                               DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength;
+                               dwError = pKey->GetSecurityDescriptor((SECURITY_INFORMATION)DACL_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1);
+                               if (dwError != ERROR_SUCCESS) throw dwError;
+                               CSecurityDescriptor sd;
+                               sd.AssociateDescriptor(pSecurityDescriptor);
+                               
+                               sd.BeginDACLInteration();
+                               ASSERT(sd.DescriptorContainsDACL());
+                               if (sd.HasNULLDACL())
+                               {
+                                       rConsole.Write(_T("Key has not DACL.\n(This allows all access)\n"));
+                               }
+                               else
+                               {
+                                       if (!sd.HasValidDACL())
+                                       {
+                                               rConsole.Write(_T("Invalid DACL.\n"));
+                                       }
+                                       else
+                                       {
+                                               DWORD nACECount = sd.GetDACLEntriesCount();
+                                               rConsole.Write(_T("DACL has "));
+                                               TCHAR Buffer[256];
+                                               rConsole.Write(_itot(nACECount,Buffer,10));
+                                               rConsole.Write(_T(" ACEs.\n"));
+                                               if (nACECount == 0)
+                                               {
+                                                       rConsole.Write(_T("(This denies all access)\n"));
+                                               }
+                                               else
+                                               {
+                                                       for (DWORD i = 0 ; i < nACECount ; i++)
+                                                       {
+                                                               rConsole.Write(_T("\n"));
+                                                               rConsole.Write(_T("\tACE Index: "));
+                                                               rConsole.Write(_itot(i,Buffer,10));
+                                                               rConsole.Write(_T("\n"));
+                                                               rConsole.Write(_T("\tACE Type: "));
+                                                               switch (sd.GetDACLEntry(i))
+                                                               {
+                                                               case CSecurityDescriptor::AccessAlowed:
+                                                                       rConsole.Write(_T("Access-allowed\n"));
+                                                                       break;
+                                                               case CSecurityDescriptor::AccessDenied:
+                                                                       rConsole.Write(_T("Access-denied\n"));
+                                                                       break;
+                                                               default:
+                                                                       rConsole.Write(_T("Unknown.\nCannot continue dumping of the ACE list.\n"));
+                                                                       goto AbortDumpDACL;
+                                                               }
+                                                               PSID pSID = sd.GetCurrentACE_SID();
+                                                               if ((pSID == NULL)||(!IsValidSid(pSID)))
+                                                               {
+                                                                       rConsole.Write(_T("\tInvalid SID.\n"));
+                                                               }
+                                                               else
+                                                               {
+                                                                       DWORD dwSIDStringSize = 0;
+                                                                       BOOL blnRet = GetTextualSid(pSID,NULL,&dwSIDStringSize);
+                                                                       ASSERT(!blnRet);
+                                                                       ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
+                                                                       TCHAR *pchSID = new TCHAR[dwSIDStringSize];
+                                                                       if(!GetTextualSid(pSID,pchSID,&dwSIDStringSize))
+                                                                       {
+                                                                               dwError = GetLastError();
+                                                                               ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
+                                                                               rConsole.Write(_T("Error "));
+                                                                               TCHAR Buffer[256];
+                                                                               rConsole.Write(_itot(dwError,Buffer,10));
+                                                                               rConsole.Write(_T("\nGetting string representation of SID\n"));
+                                                                       }
+                                                                       else
+                                                                       {
+                                                                               rConsole.Write(_T("\tSID: "));
+                                                                               rConsole.Write(pchSID);
+                                                                               rConsole.Write(_T("\n"));
+                                                                       }
+                                                                       delete pchSID;
+                                                                       DWORD dwNameBufferLength, dwDomainNameBufferLength;
+                                                                       dwNameBufferLength = 1024;
+                                                                       dwDomainNameBufferLength = 1024;
+                                                                       pchName = new TCHAR [dwNameBufferLength];
+                                                                       pchDomainName = new TCHAR [dwDomainNameBufferLength];
+                                                                       DWORD dwNameLength = dwNameBufferLength, dwDomainNameLength = dwDomainNameBufferLength;
+                                                                       SID_NAME_USE Use;
+                                                                       if (!LookupAccountSid(NULL,pSID,pchName,&dwNameLength,pchDomainName,&dwDomainNameLength,&Use))
+                                                                       {
+                                                                               rConsole.Write(_T("Error "));
+                                                                               TCHAR Buffer[256];
+                                                                               rConsole.Write(_itot(GetLastError(),Buffer,10));
+                                                                               rConsole.Write(_T("\n"));
+                                                                       }
+                                                                       else
+                                                                       {
+                                                                               rConsole.Write(_T("\tTrustee Domain: "));
+                                                                               rConsole.Write(pchDomainName);
+                                                                               rConsole.Write(_T("\n"));
+                                                                               rConsole.Write(_T("\tTrustee Name: "));
+                                                                               rConsole.Write(pchName);
+                                                                               rConsole.Write(_T("\n\tSID type: "));
+                                                                               rConsole.Write(GetSidTypeName(Use));
+                                                                               rConsole.Write(_T("\n"));
+                                                                       }
+                                                                       delete [] pchName;
+                                                                       pchName = NULL;
+                                                                       delete [] pchDomainName;
+                                                                       pchDomainName = NULL;
+                                                               }
+                                                               DWORD dwAccessMask;
+                                                               sd.GetCurrentACE_AccessMask(dwAccessMask);
+                                                               wsprintf(Buffer,_T("\tAccess Mask: 0x%08lX\n"),dwAccessMask);
+                                                               rConsole.Write(Buffer);
+                                                               if (dwAccessMask & GENERIC_READ)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tGENERIC_READ\n"));
+                                                               }
+                                                               if (dwAccessMask & GENERIC_WRITE)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tGENERIC_WRITE\n"));
+                                                               }
+                                                               if (dwAccessMask & GENERIC_EXECUTE)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tGENERIC_EXECUTE\n"));
+                                                               }
+                                                               if (dwAccessMask & GENERIC_ALL)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tGENERIC_ALL\n"));
+                                                               }
+                                                               if (dwAccessMask & SYNCHRONIZE)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tSYNCHRONIZE\n"));
+                                                               }
+                                                               if (dwAccessMask & WRITE_OWNER)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tWRITE_OWNER\n"));
+                                                               }
+                                                               if (dwAccessMask & WRITE_DAC)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tWRITE_DAC\n"));
+                                                               }
+                                                               if (dwAccessMask & READ_CONTROL)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tREAD_CONTROL\n"));
+                                                               }
+                                                               if (dwAccessMask & DELETE)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tDELETE\n"));
+                                                               }
+                                                               if (dwAccessMask & KEY_CREATE_LINK)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tKEY_CREATE_LINK\n"));
+                                                               }
+                                                               if (dwAccessMask & KEY_NOTIFY)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tKEY_NOTIFY\n"));
+                                                               }
+                                                               if (dwAccessMask & KEY_ENUMERATE_SUB_KEYS)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tKEY_ENUMERATE_SUB_KEYS\n"));
+                                                               }
+                                                               if (dwAccessMask & KEY_CREATE_SUB_KEY)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tKEY_CREATE_SUB_KEY\n"));
+                                                               }
+                                                               if (dwAccessMask & KEY_SET_VALUE)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tKEY_SET_VALUE\n"));
+                                                               }
+                                                               if (dwAccessMask & KEY_QUERY_VALUE)
+                                                               {
+                                                                       rConsole.Write(_T("\t\tKEY_QUERY_VALUE\n"));
+                                                               }
+                                                       } // for
+                                               } // else (nACECount == 0)
+                                       } // else (!sd.HasValidDACL())
+                               } // else (sd.HasNULLDACL())
+AbortDumpDACL:
+                               delete [] pSecurityDescriptor;
+                       }  // try
+                       catch (DWORD dwError)
+                       {
+                               rConsole.Write(_T("Error "));
+                               TCHAR Buffer[256];
+                               rConsole.Write(_itot(dwError,Buffer,10));
+                               rConsole.Write(_T("\n"));
+                               if (pchName) delete [] pchName;
+                               if (pchDomainName) delete [] pchDomainName;
+                               if (pSecurityDescriptor) delete [] pSecurityDescriptor;
+                       }
+               } // else (pKey == NULL)
+       } // if (blnDo)
+
+       if (pTree)
+               delete pTree;
+
+       return 0;
+}
+
+const TCHAR * CShellCommandDACL::GetHelpString()
+{
+       return DACL_CMD_SHORT_DESC
+                       _T("Syntax: ") DACL_CMD _T(" [<KEY>] [/?]\n\n")
+                       _T("    <KEY> - Optional relative path of desired key.\n")
+                       _T("    /?    - This help.\n\n")
+                       _T("Without parameters, command displays DACL of current key.\n");
+}
+
+const TCHAR * CShellCommandDACL::GetHelpShortDescriptionString()
+{
+       return DACL_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandDACL.h b/rosapps/sysutils/regexpl/ShellCommandDACL.h
new file mode 100644 (file)
index 0000000..40a0476
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandDACL.h: interface for the CShellCommandDACL class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDDACL_H__848A2509_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDDACL_H__848A2509_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandDACL : public CShellCommand  
+{
+public:
+       CShellCommandDACL(CRegistryTree& rTree);
+       virtual ~CShellCommandDACL();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDDACL_H__848A2509_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandDOKA.cpp b/rosapps/sysutils/regexpl/ShellCommandDOKA.cpp
new file mode 100644 (file)
index 0000000..db29f82
--- /dev/null
@@ -0,0 +1,242 @@
+/* $Id: ShellCommandDOKA.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandDOKA.cpp: implementation of the CShellCommandDOKA class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandDOKA.h"
+#include "RegistryExplorer.h"
+#include "SecurityDescriptor.h"
+
+#define DOKA_CMD                       _T("DOKA")
+#define DOKA_CMD_SHORT_DESC    DOKA_CMD _T(" command is used to view/edit Desired Open Key Access.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandDOKA::CShellCommandDOKA(CRegistryTree& rTree):m_rTree(rTree)
+{
+}
+
+CShellCommandDOKA::~CShellCommandDOKA()
+{
+}
+
+BOOL CShellCommandDOKA::Match(const TCHAR *pchCommand)
+{
+       return _tcsicmp(pchCommand,DOKA_CMD) == 0;
+}
+
+int CShellCommandDOKA::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       REGSAM Access = m_rTree.GetDesiredOpenKeyAccess();
+       const TCHAR *pchParameter;
+       BOOL blnBadParameter = FALSE;
+       BOOL blnHelp = FALSE;
+
+       while((pchParameter = rArguments.GetNextArgument()) != NULL)
+       {
+               blnBadParameter = FALSE;
+//                     Console.Write(_T("Processing parameter: \")");
+//                     Console.Write(pchParameter);
+//                     Console.Write(_T("\")\n");
+               if ((_tcsicmp(pchParameter,_T("/?")) == 0)
+                       ||(_tcsicmp(pchParameter,_T("-?")) == 0))
+               {
+                       blnHelp = TRUE;
+               }
+               else if (*pchParameter == _T('-'))
+               {
+                       TCHAR a = *(pchParameter+1);
+                       if (a == 0)
+                       {
+                               Access = 0;
+                       }
+                       else
+                       {
+                               if (*(pchParameter+2) != 0)
+                               {
+                                       blnBadParameter = TRUE;
+                               }
+                               else
+                               {
+                                       switch(a)
+                                       {
+                                       case _T('l'):   // KEY_CREATE_LINK
+                                       case _T('L'):
+                                               Access &= ~KEY_CREATE_LINK;
+                                               break;
+                                       case _T('c'):   // KEY_CREATE_SUB_KEY
+                                       case _T('C'):
+                                               Access &= ~KEY_CREATE_SUB_KEY;
+                                               break;
+                                       case _T('e'):   // KEY_ENUMERATE_SUB_KEYS
+                                       case _T('E'):
+                                               Access &= ~KEY_ENUMERATE_SUB_KEYS;
+                                               break;
+                                       case _T('n'):   // KEY_NOTIFY
+                                       case _T('N'):
+                                               Access &= ~KEY_NOTIFY;
+                                               break;
+                                       case _T('q'):   // KEY_QUERY_VALUE
+                                       case _T('Q'):
+                                               Access &= ~KEY_QUERY_VALUE;
+                                               break;
+                                       case _T('s'):   // KEY_SET_VALUE
+                                       case _T('S'):
+                                               Access &= ~KEY_SET_VALUE;
+                                               break;
+                                       default:
+                                               blnBadParameter = TRUE;
+                                       } // switch
+                               } // else (*(pchParameter+2) != 0)
+                       } // else (a == 0)
+               } // if (*pchParameter == _T('-'))
+               else if (*pchParameter == _T('+'))
+               {
+                       TCHAR a = *(pchParameter+1);
+                       if (a == 0)
+                       {
+                               blnBadParameter = TRUE;
+                       }
+                       else
+                       {
+                               if (*(pchParameter+2) != 0)
+                               {
+                                       blnBadParameter = TRUE;
+                               }
+                               else
+                               {
+                                       switch(a)
+                                       {
+                                       case _T('a'):   // KEY_ALL_ACCESS
+                                       case _T('A'):
+                                               Access |= KEY_ALL_ACCESS;
+                                               break;
+                                       case _T('l'):   // KEY_CREATE_LINK
+                                       case _T('L'):
+                                               Access |= KEY_CREATE_LINK;
+                                               break;
+                                       case _T('c'):   // KEY_CREATE_SUB_KEY
+                                       case _T('C'):
+                                               Access |= KEY_CREATE_SUB_KEY;
+                                               break;
+                                       case _T('e'):   // KEY_ENUMERATE_SUB_KEYS
+                                       case _T('E'):
+                                               Access |= KEY_ENUMERATE_SUB_KEYS;
+                                               break;
+                                       case _T('n'):   // KEY_NOTIFY
+                                       case _T('N'):
+                                               Access |= KEY_NOTIFY;
+                                               break;
+                                       case _T('q'):   // KEY_QUERY_VALUE
+                                       case _T('Q'):
+                                               Access |= KEY_QUERY_VALUE;
+                                               break;
+                                       case _T('s'):   // KEY_SET_VALUE
+                                       case _T('S'):
+                                               Access |= KEY_SET_VALUE;
+                                               break;
+//                                             case _T('X'):   // KEY_EXECUTE
+//                                             case _T('x'):
+//                                                     Access |= KEY_EXECUTE;
+//                                                     break;
+                                       case _T('R'):   // KEY_READ
+                                       case _T('r'):
+                                               Access |= KEY_READ;
+                                               break;
+                                       default:
+                                               blnBadParameter = TRUE;
+                                       } // switch
+                               } // else (*(pchParameter+2) != 0)
+                       } // else (a == 0)
+               } // if (*pchParameter == _T('-'))
+               else
+               {
+                       blnBadParameter = TRUE;
+               }
+
+               if (blnBadParameter)
+               {
+                       rConsole.Write(_T("Bad parameter: "));
+                       rConsole.Write(pchParameter);
+                       rConsole.Write(_T("\n"));
+                       blnHelp = TRUE;
+               }
+       } // while((pchParameter = Parser.GetNextArgument()) != NULL)
+
+       if (blnHelp)
+       {
+               rConsole.Write(GetHelpString());
+       }
+       else
+       {
+               m_rTree.SetDesiredOpenKeyAccess(Access);
+               rConsole.Write(_T("Desired open key access:\n"));
+               REGSAM Access = m_rTree.GetDesiredOpenKeyAccess();
+               if (Access & KEY_CREATE_LINK)
+               {
+                       rConsole.Write(_T("\tKEY_CREATE_LINK - Permission to create a symbolic link.\n"));
+               }
+               if (Access & KEY_CREATE_SUB_KEY)
+               {
+                       rConsole.Write(_T("\tKEY_CREATE_SUB_KEY - Permission to create subkeys.\n"));
+               }
+               if (Access & KEY_ENUMERATE_SUB_KEYS)
+               {
+                       rConsole.Write(_T("\tKEY_ENUMERATE_SUB_KEYS - Permission to enumerate subkeys.\n"));
+               }
+               if (Access & KEY_NOTIFY)
+               {
+                       rConsole.Write(_T("\tKEY_NOTIFY - Permission for change notification.\n"));
+               }
+               if (Access & KEY_QUERY_VALUE)
+               {
+                       rConsole.Write(_T("\tKEY_QUERY_VALUE - Permission to query subkey data.\n"));
+               }
+               if (Access & KEY_SET_VALUE)
+               {
+                       rConsole.Write(_T("\tKEY_SET_VALUE - Permission to set subkey data.\n"));
+               }
+       }
+       return 0;
+}
+
+const TCHAR * CShellCommandDOKA::GetHelpString()
+{
+       return DOKA_CMD_SHORT_DESC
+                       _T("Syntax: ") DOKA_CMD _T(" [Switches] [/?]\n\n")
+                       _T("    /? - This help.\n\n")
+                       _T("Switches are:\n")
+                       _T("    -  - Reset all permisions.\n")
+                       _T("    -l - Reset permission to create a symbolic link.\n")
+                       _T("    -c - Reset permission to create subkeys.\n")
+                       _T("    -e - Reset permission to enumerate subkeys.\n")
+                       _T("    -n - Reset permission for change notification.\n")
+                       _T("    -q - Reset permission to query subkey data.\n")
+                       _T("    -s - Reset permission to set subkey data.\n")
+                       _T("    +a - Set all permisions.\n")
+                       _T("    +l - Set permission to create a symbolic link.\n")
+                       _T("    +c - Set permission to create subkeys.\n")
+                       _T("    +e - Set permission to enumerate subkeys.\n")
+                       _T("    +n - Set permission for change notification.\n")
+                       _T("    +q - Set permission to query subkey data.\n")
+                       _T("    +s - Set permission to set subkey data.\n")
+                       _T("    +r - Equivalent to combination of +q , +e  and +n\n\n")
+                       _T("Without parameters, command displays current Desired Open Key Access.\n");
+}
+
+const TCHAR * CShellCommandDOKA::GetHelpShortDescriptionString()
+{
+       return DOKA_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandDOKA.h b/rosapps/sysutils/regexpl/ShellCommandDOKA.h
new file mode 100644 (file)
index 0000000..874dffd
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandDOKA.h: interface for the CShellCommandDOKA class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDDOKA_H__848A250B_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDDOKA_H__848A250B_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandDOKA : public CShellCommand  
+{
+public:
+       CShellCommandDOKA(CRegistryTree& rTree);
+       virtual ~CShellCommandDOKA();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDDOKA_H__848A250B_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp b/rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp
new file mode 100644 (file)
index 0000000..cecb861
--- /dev/null
@@ -0,0 +1,109 @@
+/* $Id: ShellCommandDeleteKey.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandDeleteKey.cpp: implementation of the CShellCommandDeleteKey class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandDeleteKey.h"
+#include "RegistryExplorer.h"
+
+#define DK_CMD                 _T("DK")
+#define DK_CMD_SHORT_DESC      DK_CMD _T(" command is used to delete key(s).\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandDeleteKey::CShellCommandDeleteKey(CRegistryTree& rTree):m_rTree(rTree)
+{
+}
+
+CShellCommandDeleteKey::~CShellCommandDeleteKey()
+{
+}
+
+BOOL CShellCommandDeleteKey::Match(const TCHAR *pchCommand)
+{
+       return _tcsicmp(pchCommand,DK_CMD) == 0;
+}
+
+int CShellCommandDeleteKey::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       const TCHAR *pchKey = NULL, *pchArg;
+
+       BOOL blnHelp = FALSE;
+       BOOL blnExitAfterHelp = FALSE;
+       BOOL blnRecursive = FALSE;
+       
+       while((pchArg = rArguments.GetNextArgument()) != NULL)
+       {
+               if ((_tcsicmp(pchArg,_T("/?")) == 0)
+                       ||(_tcsicmp(pchArg,_T("-?")) == 0))
+               {
+                       blnHelp = TRUE;
+               }
+               else if ((_tcsicmp(pchArg,_T("/s")) == 0)
+                       ||(_tcsicmp(pchArg,_T("-s")) == 0))
+               {
+                       blnRecursive = TRUE;
+               }
+               else
+               {
+                       if (pchKey)
+                       {
+                               rConsole.Write(_T("Wrong parameter : \""));
+                               rConsole.Write(pchArg);
+                               rConsole.Write(_T("\"\n\n"));
+                               blnHelp = TRUE;
+                       }
+                       else
+                       {
+                               pchKey = pchArg;
+                       }
+               }
+       }
+
+       if ((!blnHelp) && (!pchKey))
+       {
+               rConsole.Write(_T("Key name not specified !\n\n"));
+               blnExitAfterHelp = TRUE;
+       }
+
+       if (blnHelp)
+       {
+               rConsole.Write(GetHelpString());
+               if (blnExitAfterHelp)
+                       return 0;
+               else
+               rConsole.Write(_T("\n"));
+       }
+
+       if (!m_rTree.DeleteKey(pchKey,blnRecursive))
+       {
+               rConsole.Write(_T("Cannot delete key.\n"));
+               rConsole.Write(m_rTree.GetLastErrorDescription());
+       }
+       return 0;
+}
+
+const TCHAR * CShellCommandDeleteKey::GetHelpString()
+{
+       return DK_CMD_SHORT_DESC
+                       _T("Syntax: ") DK_CMD _T(" [/s] [/?] Key_Name\n\n")
+                       _T("    /? - This help.\n\n")
+                       _T("    /s - Delete key and all subkeys.\n");
+}
+
+const TCHAR * CShellCommandDeleteKey::GetHelpShortDescriptionString()
+{
+       return DK_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteKey.h b/rosapps/sysutils/regexpl/ShellCommandDeleteKey.h
new file mode 100644 (file)
index 0000000..283450e
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandDeleteKey.h: interface for the CShellCommandDeleteKey class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDDELETEKEY_H__848A2510_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDDELETEKEY_H__848A2510_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandDeleteKey : public CShellCommand  
+{
+public:
+       CShellCommandDeleteKey(CRegistryTree& rTree);
+       virtual ~CShellCommandDeleteKey();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDDELETEKEY_H__848A2510_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp b/rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp
new file mode 100644 (file)
index 0000000..e997c88
--- /dev/null
@@ -0,0 +1,165 @@
+/* $Id: ShellCommandDeleteValue.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandDeleteValue.cpp: implementation of the CShellCommandDeleteValue class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandDeleteValue.h"
+#include "RegistryExplorer.h"
+
+#define DV_CMD                 _T("DV")
+#define DV_CMD_LENGTH          COMMAND_LENGTH(DV_CMD)
+#define DV_CMD_SHORT_DESC      DV_CMD _T(" command is used to delete value.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandDeleteValue::CShellCommandDeleteValue(CRegistryTree& rTree):m_rTree(rTree)
+{
+}
+
+CShellCommandDeleteValue::~CShellCommandDeleteValue()
+{
+}
+
+BOOL CShellCommandDeleteValue::Match(const TCHAR *pchCommand)
+{
+       return _tcsicmp(pchCommand,DV_CMD) == 0;
+}
+
+int CShellCommandDeleteValue::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       rArguments.ResetArgumentIteration();
+       TCHAR *pchCommandItself = rArguments.GetNextArgument();
+
+       TCHAR *pchParameter;
+       TCHAR *pchValueFull = NULL;
+       BOOL blnHelp = FALSE;
+//     DWORD dwError;
+
+       if ((_tcsnicmp(pchCommandItself,DV_CMD _T(".."),DV_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
+               (_tcsnicmp(pchCommandItself,DV_CMD _T("\\"),DV_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
+       {
+               pchValueFull = pchCommandItself + DV_CMD_LENGTH;
+       }
+       else if (_tcsnicmp(pchCommandItself,DV_CMD _T("/"),DV_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+       {
+               pchParameter = pchCommandItself + DV_CMD_LENGTH;
+               goto CheckValueArgument;
+       }
+
+       while((pchParameter = rArguments.GetNextArgument()) != NULL)
+       {
+CheckValueArgument:
+               if ((_tcsicmp(pchParameter,_T("/?")) == 0)
+                       ||(_tcsicmp(pchParameter,_T("-?")) == 0))
+               {
+                       blnHelp = TRUE;
+                       break;
+               }
+               else if (!pchValueFull)
+               {
+                       pchValueFull = pchParameter;
+               }
+               else
+               {
+                       rConsole.Write(_T("Bad parameter: "));
+                       rConsole.Write(pchParameter);
+                       rConsole.Write(_T("\n"));
+               }
+       }
+       
+       CRegistryTree *pTree = NULL;
+       CRegistryKey *pKey = NULL;
+       TCHAR *pchValueName;
+       TCHAR *pchPath;
+       
+       if (blnHelp)
+       {
+               rConsole.Write(GetHelpString());
+               return 0;
+       }
+
+       if (pchValueFull)
+       {
+               if (_tcscmp(pchValueFull,_T("\\")) == 0)
+                       goto CommandNAonRoot;
+
+               TCHAR *pchSep = _tcsrchr(pchValueFull,_T('\\'));
+               pchValueName = pchSep?(pchSep+1):(pchValueFull);
+               pchPath = pchSep?pchValueFull:NULL;
+                               
+               //if (_tcsrchr(pchValueName,_T('.')))
+               //{
+               //      pchValueName = _T("");
+               //      pchPath = pchValueFull;
+               //}
+               //else
+               if (pchSep)
+                       *pchSep = 0;
+       }
+       else
+       {
+               pchValueName = _T("");
+               pchPath = NULL;
+       }
+               
+       if (pchPath)
+       {
+               pTree = new CRegistryTree(m_rTree);
+               if ((_tcscmp(pTree->GetCurrentPath(),m_rTree.GetCurrentPath()) != 0)
+                       ||(!pTree->ChangeCurrentKey(pchPath)))
+               {
+                       rConsole.Write(_T("Cannot open key "));
+                       rConsole.Write(pchPath);
+                       rConsole.Write(_T("\n"));
+                       goto SkipCommand;
+               }
+               else
+               {
+                       pKey = pTree->GetCurrentKey();
+               }
+       }
+       else
+       {
+               pKey = m_rTree.GetCurrentKey();
+       }
+       
+       if (pKey)
+       {       // not root key ???
+       } // if (pKey)
+       else
+       {
+CommandNAonRoot:
+               rConsole.Write(DV_CMD COMMAND_NA_ON_ROOT);
+       }
+
+SkipCommand:
+       if (pTree)
+               delete pTree;
+       return 0;
+}
+
+const TCHAR * CShellCommandDeleteValue::GetHelpString()
+{
+       return DV_CMD_SHORT_DESC
+                       _T("Syntax: ") DV_CMD _T(" [<PATH>][<VALUE_NAME>] [/?]\n\n")
+                       _T("    <PATH>       - Optional relative path of key which value will be delete.\n")
+                       _T("    <VALUE_NAME> - Name of key's value. Default is key's default value.\n")
+                       _T("    /? - This help.\n\n");
+}
+
+const TCHAR * CShellCommandDeleteValue::GetHelpShortDescriptionString()
+{
+       return DV_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteValue.h b/rosapps/sysutils/regexpl/ShellCommandDeleteValue.h
new file mode 100644 (file)
index 0000000..14d703a
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandDeleteValue.h: interface for the CShellCommandDeleteValue class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDDELETEVALUE_H__15DEA2A5_7B3A_11D4_A081_90F9DC5EBD0F__INCLUDED_)
+#define SHELLCOMMANDDELETEVALUE_H__15DEA2A5_7B3A_11D4_A081_90F9DC5EBD0F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandDeleteValue : public CShellCommand  
+{
+public:
+       CShellCommandDeleteValue(CRegistryTree& rTree);
+       virtual ~CShellCommandDeleteValue();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDDELETEVALUE_H__15DEA2A5_7B3A_11D4_A081_90F9DC5EBD0F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandDir.cpp b/rosapps/sysutils/regexpl/ShellCommandDir.cpp
new file mode 100644 (file)
index 0000000..6cc3541
--- /dev/null
@@ -0,0 +1,245 @@
+/* $Id: ShellCommandDir.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandDir.cpp: implementation of the CShellCommandDir class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "RegistryExplorer.h"
+#include "ShellCommandDir.h"
+#include "RegistryTree.h"
+#include "RegistryKey.h"
+
+// *** THIS SHOULD GO IN A MINGW/ROS HEADER (tchar.h ???) - Begin
+#if 1  // #ifndef _ui64tot ???
+       #ifdef  _UNICODE
+                       #define _ui64tot    _ui64tow
+       #else
+                       #define _ui64tot    _ui64toa
+       #endif
+#endif
+// *** THIS SHOULD GO IN A MINGW/ROS HEADER - End
+
+#define DIR_CMD                                _T("DIR")
+#define DIR_CMD_LENGTH         COMMAND_LENGTH(DIR_CMD)
+#define DIR_CMD_SHORT_DESC     DIR_CMD _T(" command lists keys and values of any key.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandDir::CShellCommandDir(CRegistryTree& rTree):m_rTree(rTree)
+{
+}
+
+CShellCommandDir::~CShellCommandDir()
+{
+}
+
+BOOL CShellCommandDir::Match(const TCHAR *pchCommand)
+{
+       if (_tcsicmp(pchCommand,DIR_CMD) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,DIR_CMD _T(".."),DIR_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,DIR_CMD _T("/"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,DIR_CMD _T("\\"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       return FALSE;
+}
+
+int CShellCommandDir::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       rArguments.ResetArgumentIteration();
+
+       const TCHAR *pchKey = NULL;
+       BOOL blnDo = TRUE,blnBadParameter, blnHelp = FALSE;
+       const TCHAR *pchParameter;
+       const TCHAR *pchCommandItself = rArguments.GetNextArgument();
+
+       if ((_tcsnicmp(pchCommandItself,DIR_CMD _T(".."),DIR_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
+               (_tcsnicmp(pchCommandItself,DIR_CMD _T("\\"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
+       {
+               pchKey = pchCommandItself + DIR_CMD_LENGTH;
+       }
+       else if (_tcsnicmp(pchCommandItself,DIR_CMD _T("/"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+       {
+               pchParameter = pchCommandItself + DIR_CMD_LENGTH;
+               goto CheckDirArgument;
+       }
+
+       while((pchParameter = rArguments.GetNextArgument()) != NULL)
+       {
+CheckDirArgument:
+               blnBadParameter = FALSE;
+               if ((_tcsicmp(pchParameter,_T("/?")) == 0)
+                       ||(_tcsicmp(pchParameter,_T("-?")) == 0))
+               {
+                       blnHelp = TRUE;
+                       blnDo = pchKey != NULL;
+               }
+               else if (!pchKey)
+               {
+                       pchKey = pchParameter;
+                       blnDo = TRUE;
+               }
+               else
+               {
+                       blnBadParameter = TRUE;
+               }
+               if (blnBadParameter)
+               {
+                       rConsole.Write(_T("Bad parameter: "));
+                       rConsole.Write(pchParameter);
+                       rConsole.Write(_T("\n"));
+               }
+       }
+       
+       CRegistryTree *pTree = NULL;
+       CRegistryKey *pKey = NULL;
+       if (pchKey)
+       {
+               pTree = new CRegistryTree(m_rTree);
+               if ((_tcscmp(pTree->GetCurrentPath(),m_rTree.GetCurrentPath()) != 0)||
+                       (!pTree->ChangeCurrentKey(pchKey)))
+               {
+                       rConsole.Write(_T("Cannot open key "));
+                       rConsole.Write(pchKey);
+                       rConsole.Write(_T("\n"));
+                       //blnHelp = TRUE;
+                       blnDo = FALSE;
+               }
+               else
+               {
+                       pKey = pTree->GetCurrentKey();
+               }
+       }
+       else
+       {
+               pKey = m_rTree.GetCurrentKey();
+       }
+       
+       if (blnHelp)
+       {
+               rConsole.Write(GetHelpString());
+       }
+
+       DWORD dwError;
+       
+       if (blnDo)
+       {
+               rConsole.Write(_T("\n Key is "));
+//             rConsole.Write(_T("\\"));
+               rConsole.Write(pTree?pTree->GetCurrentPath():m_rTree.GetCurrentPath());
+               if (pKey)
+               {
+                       rConsole.Write(_T("\n Last modify time is "));
+                       rConsole.Write(pKey->GetLastWriteTime());
+               }
+               rConsole.Write(_T("\n\n"));
+               unsigned __int64 nTotalItems = 0;
+               if (!pKey)
+               {
+                       rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_CLASSES_ROOT\\\n"));
+                       rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_CURRENT_USER\\\n"));
+                       rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_LOCAL_MACHINE\\\n"));
+                       rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_USERS\\\n"));
+                       rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_PERFORMANCE_DATA\\\n"));
+                       rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_CURRENT_CONFIG\\\n"));
+                       rConsole.Write(_T("\t(KEY)\t\t\t\tHKEY_DYN_DATA\\\n"));
+                       nTotalItems = 7;
+               }
+               else
+               {
+                       dwError = ERROR_SUCCESS;
+                       try
+                       {
+                               if (!pKey->IsPredefined())
+                               {
+                                       dwError = pKey->Open(KEY_QUERY_VALUE|KEY_READ);
+                                       if (dwError != ERROR_SUCCESS) throw dwError;
+                               }
+                               
+                               ASSERT(nTotalItems == 0);
+                               rConsole.Write(_T("\t(KEY)\t\t\t\t..\\\n"));    // parent key abstraction
+                               nTotalItems = 1;
+                               
+                               pKey->InitSubKeyEnumeration();
+                               TCHAR *pchSubKeyName;
+                               while ((pchSubKeyName = pKey->GetSubKeyName(dwError)) != NULL)
+                               {
+                                       rConsole.Write(_T("\t(KEY)\t\t\t\t"));
+                                       rConsole.Write(pchSubKeyName);
+                                       rConsole.Write(_T("\\\n"));
+                                       nTotalItems++;
+                               }
+                               if ((dwError != ERROR_SUCCESS)&&(dwError != ERROR_NO_MORE_ITEMS)) throw dwError;
+                               
+                               pKey->InitValueEnumeration();
+                               TCHAR *pchValueName;
+                               DWORD dwValueNameLength, dwMaxValueNameLength;
+                               dwError = pKey->GetMaxValueNameLength(dwMaxValueNameLength);
+                               if (dwError != ERROR_SUCCESS) throw dwError;
+                               dwMaxValueNameLength++;
+                               pchValueName = new TCHAR [dwMaxValueNameLength];
+                               DWORD Type;
+                               for(;;)
+                               {
+                                       dwValueNameLength = dwMaxValueNameLength;
+                                       //dwValueSize = dwMaxValueSize;
+                                       dwError = pKey->GetNextValue(pchValueName,dwValueNameLength,&Type,
+                                               NULL,//pDataBuffer
+                                               NULL//&dwValueSize
+                                               );
+                                       if (dwError == ERROR_NO_MORE_ITEMS) break;
+                                       if (dwError != ERROR_SUCCESS) throw dwError;
+                                       rConsole.Write(_T("\t"));
+                                       rConsole.Write(CRegistryKey::GetValueTypeName(Type));
+                                       rConsole.Write(_T("\t"));
+                                       rConsole.Write((dwValueNameLength == 0)?_T("(Default)"):pchValueName);
+                                       rConsole.Write(_T("\n"));
+                                       nTotalItems++;
+                               }       // for
+                               delete [] pchValueName;
+                       }       // try
+                       catch (DWORD dwError)
+                       {
+                               rConsole.Write(_T("Error "));
+                               TCHAR Buffer[256];
+                               rConsole.Write(_itot(dwError,Buffer,10));
+                               rConsole.Write(_T("\n"));
+                       }
+               }       // else (Tree.IsCurrentRoot())
+               
+               rConsole.Write(_T("\n Total: "));
+               TCHAR Buffer[256];
+               rConsole.Write(_ui64tot(nTotalItems,Buffer,10));
+               rConsole.Write(_T(" item(s) listed.\n"));
+               if (pTree) delete pTree;
+       }       // if (blnDo)
+
+       return 0;
+}
+
+const TCHAR * CShellCommandDir::GetHelpString()
+{
+       return DIR_CMD_SHORT_DESC
+                       _T("Syntax: ") DIR_CMD _T(" [<KEY>] [/?]\n\n")
+                       _T("    <KEY> - Optional relative path to the key on which command will be executed\n")
+                       _T("    /?    - This help.\n\n")
+                       _T("Without parameters, command lists keys and values of current key.\n");
+}
+
+const TCHAR * CShellCommandDir::GetHelpShortDescriptionString()
+{
+       return DIR_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandDir.h b/rosapps/sysutils/regexpl/ShellCommandDir.h
new file mode 100644 (file)
index 0000000..97e51f2
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandDir.h: interface for the CShellCommandDir class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDDIR_H__848A2505_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDDIR_H__848A2505_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandDir : public CShellCommand  
+{
+public:
+       CShellCommandDir(CRegistryTree& rTree);
+       virtual ~CShellCommandDir();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDDIR_H__848A2505_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandExit.cpp b/rosapps/sysutils/regexpl/ShellCommandExit.cpp
new file mode 100644 (file)
index 0000000..080ac79
--- /dev/null
@@ -0,0 +1,55 @@
+/* $Id: ShellCommandExit.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandExit.cpp: implementation of the CShellCommandExit class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandExit.h"
+#include "RegistryExplorer.h"
+
+#define EXIT_CMD                       _T("EXIT")
+#define EXIT_CMD_SHORT_DESC    EXIT_CMD _T(" command termiantes current instance of Registry Explorer.\n")
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandExit::CShellCommandExit()
+{
+
+}
+
+CShellCommandExit::~CShellCommandExit()
+{
+
+}
+
+BOOL CShellCommandExit::Match(const TCHAR *pchCommand)
+{
+       return _tcsicmp(pchCommand,EXIT_CMD) == 0;
+}
+
+int CShellCommandExit::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       rConsole.Write(GOODBYE_MSG);
+       return 0;
+}
+
+const TCHAR * CShellCommandExit::GetHelpString()
+{
+       return EXIT_CMD_SHORT_DESC      _T("Syntax: ") EXIT_CMD _T("\n");
+}
+
+const TCHAR * CShellCommandExit::GetHelpShortDescriptionString()
+{
+       return EXIT_CMD_SHORT_DESC;
+}
+
diff --git a/rosapps/sysutils/regexpl/ShellCommandExit.h b/rosapps/sysutils/regexpl/ShellCommandExit.h
new file mode 100644 (file)
index 0000000..7b44625
--- /dev/null
@@ -0,0 +1,21 @@
+// ShellCommandExit.h: interface for the CShellCommandExit class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDEXIT_H__848A2501_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDEXIT_H__848A2501_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+
+class CShellCommandExit : public CShellCommand  
+{
+public:
+       CShellCommandExit();
+       virtual ~CShellCommandExit();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+};
+
+#endif // !defined(SHELLCOMMANDEXIT_H__848A2501_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandHelp.cpp b/rosapps/sysutils/regexpl/ShellCommandHelp.cpp
new file mode 100644 (file)
index 0000000..818e138
--- /dev/null
@@ -0,0 +1,87 @@
+/* $Id: ShellCommandHelp.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandHelp.cpp: implementation of the CShellCommandHelp class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandHelp.h"
+
+#define HELP_CMD                       _T("HELP")
+#define HELP_CMD_SHORT_DESC    HELP_CMD _T(" command provides help information about Registry Explorer commands.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandHelp::CShellCommandHelp(CShellCommandsLinkedList& rCommandsLinkedList):m_rCommandsLinkedList(rCommandsLinkedList)
+{
+}
+
+CShellCommandHelp::~CShellCommandHelp()
+{
+
+}
+
+BOOL CShellCommandHelp::Match(const TCHAR *pchCommand)
+{
+       return _tcsicmp(pchCommand,HELP_CMD) == 0;
+}
+
+int CShellCommandHelp::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       const TCHAR *pchArg = rArguments.GetNextArgument();
+       CShellCommand *pCommand;
+       if (pchArg == NULL)
+       {
+               POSITION pos = m_rCommandsLinkedList.GetFirstCommandPosition();
+               while(pos)
+               {
+                       pCommand = m_rCommandsLinkedList.GetNextCommand(pos);
+                       rConsole.Write(pCommand->GetHelpShortDescriptionString());
+               }
+       }
+
+       while (pchArg)
+       {
+               pCommand = m_rCommandsLinkedList.Match(pchArg);
+               if ((!pCommand)&&((_tcsicmp(pchArg,_T("/?")) == 0)||(_tcsicmp(pchArg,_T("-?")) == 0)))
+                       pCommand = this;
+
+               if (pCommand)
+               {
+                       rConsole.Write(pCommand->GetHelpString());
+               }
+               else
+               {
+                       rConsole.Write(_T("HELP: Unknown command \""));
+                       rConsole.Write(pchArg);
+                       rConsole.Write(_T("\"\n"));
+               }
+
+               pchArg = rArguments.GetNextArgument();
+       }
+       return 0;
+}
+
+const TCHAR * CShellCommandHelp::GetHelpString()
+{
+       return HELP_CMD_SHORT_DESC
+                       _T("Syntax: ") HELP_CMD _T("[<COMMAND>] [/?]\n")
+                       _T("    COMMAND    - Command for which help will be displayed.\n")
+                       _T("    /?    - This help.\n\n")
+                       _T("Without parameters, command lists available commands.\n");
+}
+
+const TCHAR * CShellCommandHelp::GetHelpShortDescriptionString()
+{
+       return HELP_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandHelp.h b/rosapps/sysutils/regexpl/ShellCommandHelp.h
new file mode 100644 (file)
index 0000000..ee0390f
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandHelp.h: interface for the CShellCommandHelp class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDHELP_H__848A2504_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDHELP_H__848A2504_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "ShellCommandsLinkedList.h"
+
+class CShellCommandHelp : public CShellCommand  
+{
+public:
+       CShellCommandHelp(CShellCommandsLinkedList& rCommandsLinkedList);
+       virtual ~CShellCommandHelp();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CShellCommandsLinkedList& m_rCommandsLinkedList;
+};
+
+#endif // !defined(SHELLCOMMANDHELP_H__848A2504_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandNewKey.cpp b/rosapps/sysutils/regexpl/ShellCommandNewKey.cpp
new file mode 100644 (file)
index 0000000..bf224b5
--- /dev/null
@@ -0,0 +1,116 @@
+/* $Id: ShellCommandNewKey.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandNewKey.cpp: implementation of the CShellCommandNewKey class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandNewKey.h"
+#include "RegistryExplorer.h"
+
+#define NK_CMD                 _T("NK")
+#define NK_CMD_SHORT_DESC      NK_CMD _T(" command is used to create new key.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandNewKey::CShellCommandNewKey(CRegistryTree& rTree):m_rTree(rTree)
+{
+}
+
+CShellCommandNewKey::~CShellCommandNewKey()
+{
+}
+
+BOOL CShellCommandNewKey::Match(const TCHAR *pchCommand)
+{
+       return _tcsicmp(pchCommand,NK_CMD) == 0;
+}
+
+int CShellCommandNewKey::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       const TCHAR *pchNewKey = NULL, *pchArg;
+
+       BOOL blnHelp = FALSE;
+       BOOL blnExitAfterHelp = FALSE;
+       BOOL blnVolatile = FALSE;
+       
+       while((pchArg = rArguments.GetNextArgument()) != NULL)
+       {
+               if ((_tcsicmp(pchArg,_T("/?")) == 0)
+                       ||(_tcsicmp(pchArg,_T("-?")) == 0))
+               {
+                       blnHelp = TRUE;
+               }
+               else if ((_tcsicmp(pchArg,_T("/v")) == 0)
+                       ||(_tcsicmp(pchArg,_T("-v")) == 0))
+               {
+                       blnVolatile = TRUE;
+               }
+               else
+               {
+                       if (pchNewKey)
+                       {
+                               rConsole.Write(_T("Wrong parameter : \""));
+                               rConsole.Write(pchArg);
+                               rConsole.Write(_T("\"\n\n"));
+                               blnHelp = TRUE;
+                       }
+                       else
+                       {
+                               pchNewKey = pchArg;
+                       }
+               }
+       }
+
+       if ((!blnHelp) && (!pchNewKey))
+       {
+               rConsole.Write(_T("Key name not specified !\n\n"));
+               blnExitAfterHelp = TRUE;
+       }
+
+       if (blnHelp)
+       {
+               rConsole.Write(GetHelpString());
+               if (blnExitAfterHelp)
+                       return 0;
+               else
+               rConsole.Write(_T("\n"));
+       }
+
+       if (m_rTree.IsCurrentRoot())
+       {       // root key
+               rConsole.Write(NK_CMD COMMAND_NA_ON_ROOT);
+               return 0;
+       }
+
+       if (!m_rTree.NewKey(pchNewKey,blnVolatile))
+       {
+               rConsole.Write(_T("Cannot create key.\n"));
+               rConsole.Write(m_rTree.GetLastErrorDescription());
+       }
+       return 0;
+}
+
+const TCHAR * CShellCommandNewKey::GetHelpString()
+{
+       return NK_CMD_SHORT_DESC
+                       _T("Syntax: ") NK_CMD _T(" [/v] [/?] Key_Name\n\n")
+                       _T("    /? - This help.\n\n")
+                       _T("    /v - Create volatile key. The information is stored in memory and is not\n")
+                       _T("         preserved when the corresponding registry hive is unloaded.\n");
+}
+
+const TCHAR * CShellCommandNewKey::GetHelpShortDescriptionString()
+{
+       return NK_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandNewKey.h b/rosapps/sysutils/regexpl/ShellCommandNewKey.h
new file mode 100644 (file)
index 0000000..b254ff5
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandNewKey.h: interface for the CShellCommandNewKey class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDNEWKEY_H__848A250F_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDNEWKEY_H__848A250F_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandNewKey : public CShellCommand  
+{
+public:
+       CShellCommandNewKey(CRegistryTree& rTree);
+       virtual ~CShellCommandNewKey();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDNEWKEY_H__848A250F_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandOwner.cpp b/rosapps/sysutils/regexpl/ShellCommandOwner.cpp
new file mode 100644 (file)
index 0000000..5303997
--- /dev/null
@@ -0,0 +1,256 @@
+/* $Id: ShellCommandOwner.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandOwner.cpp: implementation of the CShellCommandOwner class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandOwner.h"
+#include "RegistryExplorer.h"
+#include "SecurityDescriptor.h"
+
+#define OWNER_CMD                      _T("OWNER")
+#define OWNER_CMD_LENGTH       COMMAND_LENGTH(OWNER_CMD)
+#define OWNER_CMD_SHORT_DESC   OWNER_CMD _T(" command is used to view")/*"/change"*/_T(" key's owner.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandOwner::CShellCommandOwner(CRegistryTree& rTree):m_rTree(rTree)
+{
+}
+
+CShellCommandOwner::~CShellCommandOwner()
+{
+}
+
+BOOL CShellCommandOwner::Match(const TCHAR *pchCommand)
+{
+       if (_tcsicmp(pchCommand,OWNER_CMD) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,OWNER_CMD _T(".."),OWNER_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,OWNER_CMD _T("/") ,OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,OWNER_CMD _T("\\"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       return FALSE;
+}
+
+int CShellCommandOwner::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       const TCHAR *pchKey = NULL;
+       BOOL blnDo = TRUE;
+       BOOL blnBadParameter = FALSE;
+       BOOL blnHelp = FALSE;
+       const TCHAR *pchParameter;
+       DWORD dwError;
+
+       rArguments.ResetArgumentIteration();
+       const TCHAR *pchCommandItself = rArguments.GetNextArgument();
+
+       if ((_tcsnicmp(pchCommandItself,OWNER_CMD _T(".."),OWNER_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
+               (_tcsnicmp(pchCommandItself,OWNER_CMD _T("\\"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
+       {
+               pchKey = pchCommandItself + OWNER_CMD_LENGTH;
+       }
+       else if (_tcsnicmp(pchCommandItself,OWNER_CMD _T("/"),OWNER_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+       {
+               pchParameter = pchCommandItself + OWNER_CMD_LENGTH;
+               goto CheckOwnerArgument;
+       }
+
+       while((pchParameter = rArguments.GetNextArgument()) != NULL)
+       {
+CheckOwnerArgument:
+               blnBadParameter = FALSE;
+               if ((_tcsicmp(pchParameter,_T("/?")) == 0)
+                       ||(_tcsicmp(pchParameter,_T("-?")) == 0))
+               {
+                       blnHelp = TRUE;
+                       blnDo = pchKey != NULL;
+               }
+               else if (!pchKey)
+               {
+                       pchKey = pchParameter;
+                       blnDo = TRUE;
+               }
+               else
+               {
+                       blnBadParameter = TRUE;
+               }
+               if (blnBadParameter)
+               {
+                       rConsole.Write(_T("Bad parameter: "));
+                       rConsole.Write(pchParameter);
+                       rConsole.Write(_T("\n"));
+               }
+       }
+
+       CRegistryTree *pTree = NULL;
+       CRegistryKey *pKey = NULL;
+
+       if (pchKey)
+       {
+               pTree = new CRegistryTree(m_rTree);
+               if ((_tcscmp(pTree->GetCurrentPath(),m_rTree.GetCurrentPath()) != 0)||(!pTree->ChangeCurrentKey(pchKey)))
+               {
+                       rConsole.Write(_T("Cannot open key "));
+                       rConsole.Write(pchKey);
+                       rConsole.Write(_T("\n"));
+                       //blnHelp = TRUE;
+                       blnDo = FALSE;
+               }
+               else
+               {
+                       pKey = pTree->GetCurrentKey();
+               }
+       }
+       else
+       {
+               pKey = m_rTree.GetCurrentKey();
+       }
+       
+       if (blnHelp)
+       {
+               rConsole.Write(GetHelpString());
+       }
+
+       if (blnDo&&blnHelp) rConsole.Write(_T("\n"));
+
+       if (blnDo)
+       {
+               if (pKey == NULL)
+               {       // root key
+                       rConsole.Write(OWNER_CMD COMMAND_NA_ON_ROOT);
+               }
+               else
+               {
+                       PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
+                       TCHAR *pchName = NULL, *pchDomainName = NULL;
+                       try
+                       {
+                               DWORD dwSecurityDescriptorLength;
+                               rConsole.Write(_T("Key : "));
+                               rConsole.Write(_T("\\"));
+                               rConsole.Write(pTree?pTree->GetCurrentPath():m_rTree.GetCurrentPath());
+                               rConsole.Write(_T("\n"));
+                               dwError = pKey->GetSecurityDescriptorLength(&dwSecurityDescriptorLength);
+                               if (dwError != ERROR_SUCCESS) throw dwError;
+                               
+                               pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength];
+                               DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength;
+                               dwError = pKey->GetSecurityDescriptor((SECURITY_INFORMATION)OWNER_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1);
+                               if (dwError != ERROR_SUCCESS) throw dwError;
+                               PSID psidOwner;
+                               BOOL blnOwnerDefaulted;
+                               if (!GetSecurityDescriptorOwner(pSecurityDescriptor,&psidOwner,&blnOwnerDefaulted))
+                                       throw GetLastError();
+                               if (psidOwner == NULL)
+                               {
+                                       rConsole.Write(_T("Key has no owner."));
+                               }
+                               else
+                               {
+                                       if (!IsValidSid(psidOwner))
+                                       {
+                                               rConsole.Write(_T("Key has invalid owner SID."));
+                                       }
+                                       else
+                                       {
+                                               rConsole.Write(_T("Key Owner: \n"));
+                                               DWORD dwSIDStringSize = 0;
+                                               BOOL blnRet = GetTextualSid(psidOwner,NULL,&dwSIDStringSize);
+                                               ASSERT(!blnRet);
+                                               ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
+                                               TCHAR *pchSID = new TCHAR[dwSIDStringSize];
+                                               if(!GetTextualSid(psidOwner,pchSID,&dwSIDStringSize))
+                                               {
+                                                       dwError = GetLastError();
+                                                       ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
+                                                       rConsole.Write(_T("Error "));
+                                                       TCHAR Buffer[256];
+                                                       rConsole.Write(_itot(dwError,Buffer,10));
+                                                       rConsole.Write(_T("\nGetting string representation of SID\n"));
+                                               }
+                                               else
+                                               {
+                                                       rConsole.Write(_T("\tSID: "));
+                                                       rConsole.Write(pchSID);
+                                                       rConsole.Write(_T("\n"));
+                                               }
+                                               delete [] pchSID;
+                                               DWORD dwNameBufferLength, dwDomainNameBufferLength;
+                                               dwNameBufferLength = 1024;
+                                               dwDomainNameBufferLength = 1024;
+                                               pchName = new TCHAR [dwNameBufferLength];
+                                               pchDomainName = new TCHAR [dwDomainNameBufferLength];
+                                               DWORD dwNameLength = dwNameBufferLength, dwDomainNameLength = dwDomainNameBufferLength;
+                                               SID_NAME_USE Use;
+                                               if (!LookupAccountSid(NULL,psidOwner,pchName,&dwNameLength,pchDomainName,&dwDomainNameLength,&Use))
+                                                       throw GetLastError();
+                                               else
+                                               {
+                                                       rConsole.Write(_T("\tOwner Domain: "));
+                                                       rConsole.Write(pchDomainName);
+                                                       rConsole.Write(_T("\n"));
+                                                       rConsole.Write(_T("\tOwner Name: "));
+                                                       rConsole.Write(pchName);
+                                                       rConsole.Write(_T("\n\tSID type: "));
+                                                       rConsole.Write(GetSidTypeName(Use));
+                                                       rConsole.Write(_T("\n"));
+                                                       rConsole.Write(_T("\tOwner defaulted: "));
+                                                       rConsole.Write(blnOwnerDefaulted?_T("Yes"):_T("No"));
+                                                       rConsole.Write(_T("\n"));
+                                               }
+                                               delete [] pchName;
+                                               pchName = NULL;
+                                               delete [] pchDomainName;
+                                               pchDomainName = NULL;
+                                               
+                                       }
+                               }
+                               delete [] pSecurityDescriptor;
+                       }
+                       catch (DWORD dwError)
+                       {
+                               rConsole.Write(_T("Error "));
+                               TCHAR Buffer[256];
+                               rConsole.Write(_itot(dwError,Buffer,10));
+                               rConsole.Write(_T("\n"));
+                               if (pchName) delete [] pchName;
+                               if (pchDomainName) delete [] pchDomainName;
+                               if (pSecurityDescriptor) delete [] pSecurityDescriptor;
+                       }
+               } // else (pKey == NULL)
+       } // if (blnDo)
+
+       if (pTree)
+               delete pTree;
+
+       return 0;
+}
+
+const TCHAR * CShellCommandOwner::GetHelpString()
+{
+       return OWNER_CMD_SHORT_DESC
+                       _T("Syntax: ") OWNER_CMD _T(" [<KEY>] [/?]\n\n")
+                       _T("    <KEY> - Optional relative path of desired key.\n")
+                       _T("    /?    - This help.\n\n")
+                       _T("Without parameters, command displays information about owner of current key.\n");
+}
+
+const TCHAR * CShellCommandOwner::GetHelpShortDescriptionString()
+{
+       return OWNER_CMD_SHORT_DESC;
+}
+
diff --git a/rosapps/sysutils/regexpl/ShellCommandOwner.h b/rosapps/sysutils/regexpl/ShellCommandOwner.h
new file mode 100644 (file)
index 0000000..1ac345f
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandOwner.h: interface for the CShellCommandOwner class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDOWNER_H__848A2508_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDOWNER_H__848A2508_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandOwner : public CShellCommand  
+{
+public:
+       CShellCommandOwner(CRegistryTree& rTree);
+       virtual ~CShellCommandOwner();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDOWNER_H__848A2508_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandSACL.cpp b/rosapps/sysutils/regexpl/ShellCommandSACL.cpp
new file mode 100644 (file)
index 0000000..bd80df9
--- /dev/null
@@ -0,0 +1,402 @@
+/* $Id: ShellCommandSACL.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandSACL.cpp: implementation of the CShellCommandSACL class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandSACL.h"
+#include "RegistryExplorer.h"
+#include "SecurityDescriptor.h"
+
+#define SACL_CMD                       _T("SACL")
+#define SACL_CMD_LENGTH                COMMAND_LENGTH(SACL_CMD)
+#define SACL_CMD_SHORT_DESC    SACL_CMD _T(" command is used to view")/*"/edit"*/_T(" key's SACL.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandSACL::CShellCommandSACL(CRegistryTree& rTree):m_rTree(rTree)
+{
+
+}
+
+CShellCommandSACL::~CShellCommandSACL()
+{
+
+}
+
+BOOL CShellCommandSACL::Match(const TCHAR *pchCommand)
+{
+       if (_tcsicmp(pchCommand,SACL_CMD) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,SACL_CMD _T(".."),SACL_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,SACL_CMD _T("/") ,SACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,SACL_CMD _T("\\"),SACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       return FALSE;
+}
+
+int CShellCommandSACL::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       TCHAR err_msg[1024];
+
+       rArguments.ResetArgumentIteration();
+
+       const TCHAR *pchKey = NULL;
+       BOOL blnDo = TRUE;
+       BOOL blnBadParameter = FALSE;
+       BOOL blnHelp = FALSE;
+       const TCHAR *pchParameter;
+       const TCHAR *pchCommandItself = rArguments.GetNextArgument();
+       DWORD dwError;
+
+       if ((_tcsnicmp(pchCommandItself,SACL_CMD _T(".."),SACL_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
+               (_tcsnicmp(pchCommandItself,SACL_CMD _T("\\"),SACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
+       {
+               pchKey = pchCommandItself + SACL_CMD_LENGTH;
+       }
+       else if (_tcsnicmp(pchCommandItself,SACL_CMD _T("/"),SACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+       {
+               pchParameter = pchCommandItself + SACL_CMD_LENGTH;
+               goto CheckSACLArgument;
+       }
+
+       while((pchParameter = rArguments.GetNextArgument()) != NULL)
+       {
+CheckSACLArgument:
+               blnBadParameter = FALSE;
+//                     Console.Write(_T("Processing parameter: \")");
+//                     Console.Write(pchParameter);
+//                     Console.Write(_T("\")\n");
+               if ((_tcsicmp(pchParameter,_T("/?")) == 0)
+                       ||(_tcsicmp(pchParameter,_T("-?")) == 0))
+               {
+                       blnHelp = TRUE;
+                       blnDo = pchKey != NULL;
+               }
+               else if (!pchKey)
+               {
+                       pchKey = pchParameter;
+                       blnDo = TRUE;
+               }
+               else
+               {
+                       blnBadParameter = TRUE;
+               }
+               if (blnBadParameter)
+               {
+                       rConsole.Write(_T("Bad parameter: "));
+                       rConsole.Write(pchParameter);
+                       rConsole.Write(_T("\n"));
+               }
+       }
+
+       CRegistryTree *pTree = NULL;
+       CRegistryKey *pKey = NULL;
+       if (pchKey)
+       {
+               pTree = new CRegistryTree(m_rTree);
+               if ((_tcscmp(pTree->GetCurrentPath(),m_rTree.GetCurrentPath()) != 0)||(!pTree->ChangeCurrentKey(pchKey)))
+               {
+                       rConsole.Write(_T("Cannot open key "));
+                       rConsole.Write(pchKey);
+                       rConsole.Write(_T("\n"));
+                       //blnHelp = TRUE;
+                       blnDo = FALSE;
+               }
+               else
+               {
+                       pKey = pTree->GetCurrentKey();
+               }
+       }
+       else
+       {
+               pKey = m_rTree.GetCurrentKey();
+       }
+
+       if (blnHelp)
+       {
+               rConsole.Write(GetHelpString());
+       }
+
+       if (blnDo&&blnHelp) rConsole.Write(_T("\n"));
+
+       if (blnDo)
+       {
+               try
+               {
+                       if (!pKey)
+                               throw (SACL_CMD COMMAND_NA_ON_ROOT);
+
+                       HANDLE hThreadToken = INVALID_HANDLE_VALUE;
+                       if (!OpenThreadToken(GetCurrentThread(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,FALSE,&hThreadToken))
+                       {       // OpenThreadToken fails
+                               dwError = GetLastError();
+                               if (dwError != ERROR_NO_TOKEN)
+                               {
+                                       _stprintf(err_msg,_T("\nCannot open thread token.\nOpenThreadToken fails with error: %u\n"),dwError);
+                                       throw err_msg;
+                               }
+                               // If the thread does not have an access token, we'll examine the
+                               // access token associated with the process.
+                               if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hThreadToken))
+                               {
+                                       _stprintf(err_msg,_T("\nCannot open process token.\nOpenProcessToken fails with error: %u\n"),GetLastError());
+                                       throw err_msg;
+                               }
+                       }
+                       ASSERT(hThreadToken != INVALID_HANDLE_VALUE);
+                       TOKEN_PRIVILEGES priv;
+                       priv.PrivilegeCount = 1;
+                       priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+                       if (!LookupPrivilegeValue(
+                               NULL,                                                   // lookup privilege on local system
+                               SE_SECURITY_NAME,                               // privilege to lookup 
+                               &(priv.Privileges[0].Luid)))    // receives LUID of privilege
+                       {
+                               _stprintf(err_msg,_T("\nCannot retrieve the locally unique identifier for %s privilege.\nLookupPrivilegeValue error: %u\n"),SE_SECURITY_NAME,GetLastError());
+                               throw err_msg;
+                       }
+                       BOOL blnAdjRet = AdjustTokenPrivileges(
+                               hThreadToken,
+                               FALSE,
+                               &priv,
+                               sizeof(TOKEN_PRIVILEGES),
+                               (PTOKEN_PRIVILEGES)NULL,
+                               (PDWORD)NULL);
+                       dwError = GetLastError();
+                       if (!blnAdjRet)
+                       {
+                               _stprintf(err_msg,_T("\nCannot enable %s privilege.\nAdjustTokenPrivileges fails with error: %u%s\n"),SE_SECURITY_NAME,dwError,(dwError == 5)?_T(" (Access denied)"):_T(""));
+                               throw err_msg;
+                       }
+                       if (dwError != ERROR_SUCCESS)
+                       {
+                               if (dwError == ERROR_NOT_ALL_ASSIGNED)
+                               {
+                                       _stprintf(err_msg,_T("\nCannot enable %s privilege.\nThe token does not have the %s privilege\n"),SE_SECURITY_NAME,SE_SECURITY_NAME);
+                               }
+                               else
+                               {
+                                       _stprintf(err_msg,_T("\nCannot enable %s privilege.\nAdjustTokenPrivileges succeds with error: %u\n"),SE_SECURITY_NAME,dwError);
+                               }
+                               throw err_msg;
+                       }
+                       if (!pKey->IsPredefined())
+                       {
+                               dwError = pKey->Open(m_rTree.GetDesiredOpenKeyAccess()|ACCESS_SYSTEM_SECURITY);
+                               if (dwError != ERROR_SUCCESS)
+                               {
+                                       _stprintf(err_msg,_T("\nCannot reopen current key.\nError %u%s\n"),dwError,(dwError == 5)?_T(" (Access denied)"):_T(""));
+                                       throw err_msg;
+                               }
+                       }
+                       DWORD dwSecurityDescriptorLength;
+                       rConsole.Write(_T("Key : "));
+                       rConsole.Write(_T("\\"));
+                       rConsole.Write(pTree?pTree->GetCurrentPath():m_rTree.GetCurrentPath());
+                       rConsole.Write(_T("\n"));
+                       dwError = pKey->GetSecurityDescriptorLength(&dwSecurityDescriptorLength);
+                       if (dwError != ERROR_SUCCESS)
+                       {
+                               _stprintf(err_msg,_T("\nCannot get security descriptor's length for current key.\nError: %u\n"),dwError);
+                               throw err_msg;
+                       }
+                       PSECURITY_DESCRIPTOR pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength];
+                       DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength;
+                       dwError = pKey->GetSecurityDescriptor((SECURITY_INFORMATION)SACL_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1);
+                       if (dwError != ERROR_SUCCESS)
+                       {
+                               _stprintf(err_msg,_T("\nCannot get security descriptor for current key.\nError: %u%s\n"),dwError,(dwError == 1314)?_T("(A required privilege is not held by the client.)\n"):_T(""));
+                               throw err_msg;
+                       }
+                       CSecurityDescriptor sd;
+                       sd.AssociateDescriptor(pSecurityDescriptor);
+                       sd.BeginSACLInteration();
+                       
+                       if ((!sd.DescriptorContainsSACL())||(sd.HasNULLSACL()))
+                       {
+                               throw _T("Key has not SACL.\n");
+                       }
+                       if (!sd.HasValidSACL())
+                       {
+                               throw _T("Invalid SACL.\n");
+                       }
+                       DWORD nACECount = sd.GetSACLEntriesCount();
+                       rConsole.Write(_T("SACL has "));
+                       TCHAR Buffer[256];
+                       rConsole.Write(_itot(nACECount,Buffer,10));
+                       rConsole.Write(_T(" ACEs.\n"));
+                       ASSERT(sizeof(ACL) == 8);
+                       rConsole.Write(_T("\n"));
+                       for (DWORD i = 0 ; i < nACECount ; i++)
+                       {
+                               rConsole.Write(_T("\n"));
+                               rConsole.Write(_T("\tACE Index: "));
+                               rConsole.Write(_itot(i,Buffer,10));
+                               rConsole.Write(_T("\n"));
+                               rConsole.Write(_T("\tAudit Type: "));
+                               BOOL blnFailed, blnSuccessful;
+                               if (sd.GetSACLEntry(i,blnFailed,blnSuccessful) != CSecurityDescriptor::SystemAudit)
+                               {
+                                       rConsole.Write(_T("Unknown ACE type.\nCannot continue ACE list dump.\n"));
+                                       goto AbortDumpSACL;
+                               }
+                               if (blnFailed) rConsole.Write(_T("Failed access"));
+                               if (blnFailed && blnSuccessful) rConsole.Write(_T(" & "));
+                               if (blnSuccessful) rConsole.Write(_T("Successful access"));
+                               rConsole.Write(_T("\n"));
+                               PSID pSID = sd.GetCurrentACE_SID();
+                               if ((pSID == NULL)||(!IsValidSid(pSID)))
+                               {
+                                       rConsole.Write(_T("\tInvalid SID.\n"));
+                               }
+                               DWORD dwSIDStringSize = 0;
+                               BOOL blnRet = GetTextualSid(pSID,NULL,&dwSIDStringSize);
+                               ASSERT(!blnRet);
+                               ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
+                               TCHAR *pchSID = new TCHAR[dwSIDStringSize];
+                               if(!GetTextualSid(pSID,pchSID,&dwSIDStringSize))
+                               {
+                                       dwError = GetLastError();
+                                       ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
+                                       rConsole.Write(_T("Error "));
+                                       TCHAR Buffer[256];
+                                       rConsole.Write(_itot(dwError,Buffer,10));
+                                       rConsole.Write(_T("\nGetting string representation of SID\n"));
+                               }
+                               else
+                               {
+                                       rConsole.Write(_T("\tSID: "));
+                                       rConsole.Write(pchSID);
+                                       rConsole.Write(_T("\n"));
+                               }
+                               delete [] pchSID;
+                               TCHAR *pchName, *pchDomainName;
+                               DWORD dwNameBufferLength, dwDomainNameBufferLength;
+                               dwNameBufferLength = 1024;
+                               dwDomainNameBufferLength = 1024;
+                               pchName = new TCHAR [dwNameBufferLength];
+                               pchDomainName = new TCHAR [dwDomainNameBufferLength];
+                               DWORD dwNameLength = dwNameBufferLength, dwDomainNameLength = dwDomainNameBufferLength;
+                               SID_NAME_USE Use;
+                               if (!LookupAccountSid(NULL,pSID,pchName,&dwNameLength,pchDomainName,&dwDomainNameLength,&Use))
+                               {
+                                       rConsole.Write(_T("Error "));
+                                       TCHAR Buffer[256];
+                                       rConsole.Write(_itot(GetLastError(),Buffer,10));
+                                       rConsole.Write(_T("\n"));
+                               }
+                               else
+                               {
+                                       rConsole.Write(_T("\tTrustee Domain: "));
+                                       rConsole.Write(pchDomainName);
+                                       rConsole.Write(_T("\n"));
+                                       rConsole.Write(_T("\tTrustee Name: "));
+                                       rConsole.Write(pchName);
+                                       rConsole.Write(_T("\n\tSID type: "));
+                                       rConsole.Write(GetSidTypeName(Use));
+                                       rConsole.Write(_T("\n"));
+                               }
+                               DWORD dwAccessMask;
+                               sd.GetCurrentACE_AccessMask(dwAccessMask);
+                               wsprintf(Buffer,_T("\tAccess Mask: 0x%08lX\n"),dwAccessMask);
+                               rConsole.Write(Buffer);
+                               if (dwAccessMask & GENERIC_READ)
+                               {
+                                       rConsole.Write(_T("\t\tGENERIC_READ\n"));
+                               }
+                               if (dwAccessMask & GENERIC_WRITE)
+                               {
+                                       rConsole.Write(_T("\t\tGENERIC_WRITE\n"));
+                               }
+                               if (dwAccessMask & GENERIC_EXECUTE)
+                               {
+                                       rConsole.Write(_T("\t\tGENERIC_EXECUTE\n"));
+                               }
+                               if (dwAccessMask & GENERIC_ALL)
+                               {
+                                       rConsole.Write(_T("\t\tGENERIC_ALL\n"));
+                               }
+                               if (dwAccessMask & SYNCHRONIZE)
+                               {
+                                       rConsole.Write(_T("\t\tSYNCHRONIZE\n"));
+                               }
+                               if (dwAccessMask & WRITE_OWNER)
+                               {
+                                       rConsole.Write(_T("\t\tWRITE_OWNER\n"));
+                               }
+                               if (dwAccessMask & WRITE_DAC)
+                               {
+                                       rConsole.Write(_T("\t\tWRITE_DAC\n"));
+                               }
+                               if (dwAccessMask & READ_CONTROL)
+                               {
+                                       rConsole.Write(_T("\t\tREAD_CONTROL\n"));
+                               }
+                               if (dwAccessMask & DELETE)
+                               {
+                                       rConsole.Write(_T("\t\tDELETE\n"));
+                               }
+                               if (dwAccessMask & KEY_CREATE_LINK)
+                               {
+                                       rConsole.Write(_T("\t\tKEY_CREATE_LINK\n"));
+                               }
+                               if (dwAccessMask & KEY_NOTIFY)
+                               {
+                                       rConsole.Write(_T("\t\tKEY_NOTIFY\n"));
+                               }
+                               if (dwAccessMask & KEY_ENUMERATE_SUB_KEYS)
+                               {
+                                       rConsole.Write(_T("\t\tKEY_ENUMERATE_SUB_KEYS\n"));
+                               }
+                               if (dwAccessMask & KEY_CREATE_SUB_KEY)
+                               {
+                                       rConsole.Write(_T("\t\tKEY_CREATE_SUB_KEY\n"));
+                               }
+                               if (dwAccessMask & KEY_SET_VALUE)
+                               {
+                                       rConsole.Write(_T("\t\tKEY_SET_VALUE\n"));
+                               }
+                               if (dwAccessMask & KEY_QUERY_VALUE)
+                               {
+                                       rConsole.Write(_T("\t\tKEY_QUERY_VALUE\n"));
+                               }
+                       }       // for
+AbortDumpSACL:
+                       delete pSecurityDescriptor;
+               }
+               catch(TCHAR *pchError)
+               {
+                       rConsole.Write(pchError);
+               }
+       } // if (blnDo)
+
+       return 0;
+}
+
+const TCHAR * CShellCommandSACL::GetHelpString()
+{
+       return SACL_CMD_SHORT_DESC
+                       _T("Syntax: ") SACL_CMD _T(" [<KEY>] [/?]\n\n")
+                       _T("    <KEY> - Optional relative path of desired key.\n")
+                       _T("    /?    - This help.\n\n")
+                       _T("Without parameters, command displays SACL of current key.\n");
+}
+
+const TCHAR * CShellCommandSACL::GetHelpShortDescriptionString()
+{
+       return SACL_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandSACL.h b/rosapps/sysutils/regexpl/ShellCommandSACL.h
new file mode 100644 (file)
index 0000000..ee04f2f
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandSACL.h: interface for the CShellCommandSACL class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDSACL_H__848A250A_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
+#define SHELLCOMMANDSACL_H__848A250A_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandSACL : public CShellCommand  
+{
+public:
+       CShellCommandSACL(CRegistryTree& rTree);
+       virtual ~CShellCommandSACL();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDSACL_H__848A250A_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandSetValue.cpp b/rosapps/sysutils/regexpl/ShellCommandSetValue.cpp
new file mode 100644 (file)
index 0000000..482aa03
--- /dev/null
@@ -0,0 +1,388 @@
+/* $Id: ShellCommandSetValue.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+
+// ShellCommandSetValue.cpp: implementation of the CShellCommandSetValue class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "ShellCommandSetValue.h"
+#include "RegistryExplorer.h"
+#include "RegistryTree.h"
+#include "RegistryKey.h"
+
+#define SET_VALUE_CMD                          _T("SV")
+#define SET_VALUE_CMD_LENGTH           COMMAND_LENGTH(SET_VALUE_CMD)
+#define SET_VALUE_CMD_SHORT_DESC       SET_VALUE_CMD _T(" command is used to set value.\n")
+
+BOOL StringToDWORD(DWORD& rdwOut, const TCHAR *pszIn)
+{
+       const TCHAR *pszDigits;
+       const TCHAR *pszOctalNumbers = _T("01234567");
+       const TCHAR *pszDecimalNumbers = _T("0123456789");
+       const TCHAR *pszHexNumbers = _T("0123456789ABCDEF");
+       const TCHAR *pszNumbers;
+       unsigned int nBase = 0;
+       if (*pszIn == _T('0'))
+       {
+               if ((*(pszIn+1) == _T('x'))||((*(pszIn+1) == _T('X'))))
+               {       // hex
+                       nBase = 16;
+                       pszDigits = pszIn+2;
+                       pszNumbers = pszHexNumbers;
+               }
+               else
+               {       // octal
+                       nBase = 8;
+                       pszDigits = pszIn+1;
+                       pszNumbers = pszOctalNumbers;
+               }
+       }
+       else
+       {       //decimal
+               nBase = 10;
+               pszDigits = pszIn;
+               pszNumbers = pszDecimalNumbers;
+       }
+
+       const TCHAR *pszDigit = pszDigits;
+       pszDigit += _tcslen(pszDigit);
+
+       DWORD nMul = 1;
+       rdwOut = 0;
+       DWORD dwAdd;
+       const TCHAR *pszNumber;
+       while (pszDigit > pszDigits)
+       {
+               pszDigit--;
+               pszNumber = _tcschr(pszNumbers,*pszDigit);
+               if (!pszNumber)
+                       return FALSE;   // wrong char in input string
+
+               dwAdd = (pszNumber-pszNumbers)*nMul;
+
+               if (rdwOut + dwAdd < rdwOut)
+                       return FALSE;   // overflow
+               rdwOut += dwAdd;
+
+               if (nMul * nBase < nMul)
+                       return FALSE;   // overflow
+               nMul *= nBase;
+       };
+
+       return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandSetValue::CShellCommandSetValue(CRegistryTree& rTree):m_rTree(rTree)
+{
+}
+
+CShellCommandSetValue::~CShellCommandSetValue()
+{
+}
+
+BOOL CShellCommandSetValue::Match(const TCHAR *pchCommand)
+{
+       if (_tcsicmp(pchCommand,SET_VALUE_CMD) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,SET_VALUE_CMD _T(".."),SET_VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,SET_VALUE_CMD _T("/"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,SET_VALUE_CMD _T("\\"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       return FALSE;
+}
+
+int CShellCommandSetValue::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       rArguments.ResetArgumentIteration();
+       TCHAR *pchCommandItself = rArguments.GetNextArgument();
+
+       TCHAR *pchParameter;
+       TCHAR *pchValueFull = NULL;
+       TCHAR *pchValueData = NULL;
+       BOOL blnBadParameter = FALSE;
+       BOOL blnHelp = FALSE;
+//     DWORD dwError;
+       DWORD dwValueSize = 0;
+       DWORD dwType = REG_NONE;
+       BYTE *pDataBuffer = NULL;
+
+       if ((_tcsnicmp(pchCommandItself,SET_VALUE_CMD _T(".."),SET_VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
+               (_tcsnicmp(pchCommandItself,SET_VALUE_CMD _T("\\"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
+       {
+               pchValueFull = pchCommandItself + SET_VALUE_CMD_LENGTH;
+       }
+       else if (_tcsnicmp(pchCommandItself,SET_VALUE_CMD _T("/"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+       {
+               pchParameter = pchCommandItself + SET_VALUE_CMD_LENGTH;
+               goto CheckValueArgument;
+       }
+
+       while((pchParameter = rArguments.GetNextArgument()) != NULL)
+       {
+CheckValueArgument:
+               blnBadParameter = FALSE;
+               if (((*pchParameter == _T('/'))||(*pchParameter == _T('-')))
+                       &&(*(pchParameter+1) == _T('?')))
+               {
+                       blnHelp = TRUE;
+               }
+               else if (dwType == REG_NONE)
+               {
+                       if (_tcsicmp(pchParameter,_T("b")) == 0)
+                       {
+                               dwType = REG_BINARY;
+                       }
+                       else if (_tcsicmp(pchParameter,_T("dw")) == 0)
+                       {
+                               dwType = REG_DWORD;
+                       }
+                       else if (_tcsicmp(pchParameter,_T("dwle")) == 0)
+                       {
+                               dwType = REG_DWORD_LITTLE_ENDIAN;
+                       }
+                       else if (_tcsicmp(pchParameter,_T("dwbe")) == 0)
+                       {
+                               dwType = REG_DWORD_BIG_ENDIAN;
+                       }
+                       else if (_tcsicmp(pchParameter,_T("sz")) == 0)
+                       {
+                               dwType = REG_SZ;
+                       }
+                       else if (_tcsicmp(pchParameter,_T("esz")) == 0)
+                       {
+                               dwType = REG_EXPAND_SZ;
+                       }
+                       else
+                       {
+                               blnBadParameter = TRUE;
+                       }
+               }
+               else if (pchValueData == NULL)
+               {
+                       pchValueData = pchParameter;
+               }
+               else if (!pchValueFull)
+               {
+                       pchValueFull = pchParameter;
+               }
+               else
+               {
+                       blnBadParameter = TRUE;
+               }
+               if (blnBadParameter)
+               {
+                       rConsole.Write(_T("Bad parameter: "));
+                       rConsole.Write(pchParameter);
+                       rConsole.Write(_T("\n"));
+               }
+       }
+
+       if (!pchValueData)
+               blnHelp = TRUE;
+       
+       CRegistryTree *pTree = NULL;
+       CRegistryKey *pKey = NULL;
+       TCHAR *pchValueName;
+       TCHAR *pchPath;
+       
+       if (blnHelp)
+       {
+               rConsole.Write(GetHelpString());
+
+               if (pDataBuffer)
+                       delete pDataBuffer;
+
+               return 0;
+       }
+
+       if (pchValueFull)
+       {
+               if (_tcscmp(pchValueFull,_T("\\")) == 0)
+                       goto CommandNAonRoot;
+
+               TCHAR *pchSep = _tcsrchr(pchValueFull,_T('\\'));
+               pchValueName = pchSep?(pchSep+1):(pchValueFull);
+               pchPath = pchSep?pchValueFull:NULL;
+                               
+               //if (_tcsrchr(pchValueName,_T('.')))
+               //{
+               //      pchValueName = _T("");
+               //      pchPath = pchValueFull;
+               //}
+               //else
+               if (pchSep)
+                       *pchSep = 0;
+       }
+       else
+       {
+               pchValueName = _T("");
+               pchPath = NULL;
+       }
+               
+       if (pchPath)
+       {
+               pTree = new CRegistryTree(m_rTree);
+               if ((_tcscmp(pTree->GetCurrentPath(),m_rTree.GetCurrentPath()) != 0)
+                       ||(!pTree->ChangeCurrentKey(pchPath)))
+               {
+                       rConsole.Write(_T("Cannot open key "));
+                       rConsole.Write(pchPath);
+                       rConsole.Write(_T("\n"));
+                       goto SkipCommand;
+               }
+               else
+               {
+                       pKey = pTree->GetCurrentKey();
+               }
+       }
+       else
+       {
+               pKey = m_rTree.GetCurrentKey();
+       }
+       
+       if (pKey)
+       {       // not root key ???
+               switch (dwType)
+               {
+               case REG_BINARY:
+                       {
+                               HANDLE hFile;
+                               DWORD dwBytesReaded;
+                               hFile = CreateFile(pchValueData,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
+                               if (hFile == INVALID_HANDLE_VALUE)
+                               {
+                                       rConsole.Write(_T("Cannot open file "));
+                                       rConsole.Write(pchValueData);
+                                       rConsole.Write(_T("\n"));
+                                       goto SkipCommand;
+                               }
+                               dwValueSize = GetFileSize(hFile,NULL);
+                               if (dwValueSize == -1)  // ok, that's right, we compare signed with unsigned here.
+                                                                               // GetFileSize is documented and declared to return DWORD.
+                                                                               // Error is indicated by checking if return is -1. Design->documentation bug ???
+                               {
+                                       rConsole.Write(_T("Cannot get size of file "));
+                                       rConsole.Write(pchValueData);
+                                       rConsole.Write(_T("\n"));
+                                       VERIFY(CloseHandle(hFile));
+                                       goto SkipCommand;
+                               }
+                               pDataBuffer = new BYTE [dwValueSize];
+                               if (!pDataBuffer)
+                               {
+                                       rConsole.Write(_T("Cannot load file into memory. Out of memory.\n"));
+                                       VERIFY(CloseHandle(hFile));
+                                       goto SkipCommand;
+                               }
+                               if (!ReadFile(hFile,pDataBuffer,dwValueSize,&dwBytesReaded,NULL))
+                               {
+                                       rConsole.Write(_T("Cannot load file into memory. Error reading file.\n"));
+                                       VERIFY(CloseHandle(hFile));
+                                       goto SkipCommand;
+                               }
+
+                               VERIFY(CloseHandle(hFile));
+                               ASSERT(dwBytesReaded == dwValueSize);
+                       }
+                       break;
+               case REG_DWORD_LITTLE_ENDIAN:
+               case REG_DWORD_BIG_ENDIAN:
+                       dwValueSize = 4;
+                       pDataBuffer = (BYTE *) new BYTE [dwValueSize];
+                       if (!StringToDWORD(*(DWORD *)pDataBuffer,pchValueData))
+                       {
+                               rConsole.Write(_T("Cannot convert "));
+                               rConsole.Write(pchValueData);
+                               rConsole.Write(_T(" to DWORD \n"));
+                               goto SkipCommand;
+                       }
+                       if (dwType == REG_DWORD_BIG_ENDIAN)
+                       {
+                               unsigned char nByte;
+                               nByte = *pDataBuffer;
+                               *pDataBuffer = *(pDataBuffer+3);
+                               *(pDataBuffer+3) = nByte;
+                               nByte = *(pDataBuffer+1);
+                               *(pDataBuffer+1) = *(pDataBuffer+2);
+                               *(pDataBuffer+2) = nByte;
+                       }
+                       break;
+               case REG_SZ:
+               case REG_EXPAND_SZ:
+                       dwValueSize = _tcslen(pchValueData)+1;
+                       if (*pchValueData == _T('\"'))
+                       {
+                               dwValueSize -= 2;
+                               *(pchValueData+dwValueSize) = 0;
+                               pchValueData++;
+                       }
+                       dwValueSize *= sizeof(TCHAR);
+                       pDataBuffer = (BYTE *) new BYTE [dwValueSize];
+                       _tcscpy((TCHAR *)pDataBuffer,pchValueData);
+                       break;
+               default:
+                       ASSERT(FALSE);
+               }
+
+               if (pKey->SetValue(pchValueName,dwType,pDataBuffer,dwValueSize) != ERROR_SUCCESS)
+                       rConsole.Write(_T("Cannot set value\n"));
+       } // if (pKey)
+       else
+       {
+CommandNAonRoot:
+               rConsole.Write(SET_VALUE_CMD COMMAND_NA_ON_ROOT);
+       }
+
+SkipCommand:
+       if (pTree)
+               delete pTree;
+
+       if (pDataBuffer)
+               delete pDataBuffer;
+       return 0;
+}
+
+const TCHAR * CShellCommandSetValue::GetHelpString()
+{
+       return SET_VALUE_CMD_SHORT_DESC
+                       _T("Syntax: ") SET_VALUE_CMD _T(" <TYPE> <VALUE> [<PATH>][<VALUE_NAME>] [/?]\n\n")
+                       _T("    <TYPE>       - Type of value to be set. Must be one of following:\n")
+                       _T("                    b    - binary value.\n")
+                       _T("                    dw   - A 32-bit number.\n")
+                       _T("                    dwle - A 32-bit number in little-endian format.\n")
+                       _T("                    dwbe - A 32-bit number in big-endian format.\n")
+                       _T("                    sz   - A null-terminated string.\n")
+                       _T("                    esz  - A null-terminated string that contains unexpanded\n")
+                       _T("                           references to environment variables.\n")
+//                     _T("                    msz  - An array of null-terminated strings,\n")
+//                     _T("                           terminated by two null characters.\n")
+                       _T("    <VALUE>      - The data to be set. According to <TYPE>, <VALUE> means:\n")
+                       _T("                    b    - name of file from which to read binary data.\n")
+                       _T("                    dw   \\\n")
+                       _T("                    dwle - number with syntax: [0 [{ x | X }]] [digits]\n")
+                       _T("                    dwbe /\n")
+                       _T("                    sz   \\\n")
+                       _T("                    esz  - <VALUE> string is interpreted as string\n")
+                       _T("    <PATH>       - Optional relative path of key which value will be processed.\n")
+                       _T("    <VALUE_NAME> - Name of key's value. Default is key's default value.\n")
+                       _T("    /?           - This help.\n");
+}
+
+const TCHAR * CShellCommandSetValue::GetHelpShortDescriptionString()
+{
+       return SET_VALUE_CMD_SHORT_DESC;
+}
diff --git a/rosapps/sysutils/regexpl/ShellCommandSetValue.h b/rosapps/sysutils/regexpl/ShellCommandSetValue.h
new file mode 100644 (file)
index 0000000..d25a7de
--- /dev/null
@@ -0,0 +1,24 @@
+// ShellCommandSetValue.h: interface for the CShellCommandSetValue class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(SHELLCOMMANDSETVALUE_H__32B55193_715E_11D4_A06C_BEFAED86450E__INCLUDED_)
+#define SHELLCOMMANDSETVALUE_H__32B55193_715E_11D4_A06C_BEFAED86450E__INCLUDED_
+
+#include "ShellCommand.h"
+#include "RegistryTree.h"
+
+class CShellCommandSetValue : public CShellCommand  
+{
+public:
+       CShellCommandSetValue(CRegistryTree& rTree);
+       virtual ~CShellCommandSetValue();
+       virtual BOOL Match(const TCHAR *pchCommand);
+       virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments);
+       virtual const TCHAR * GetHelpString();
+       virtual const TCHAR * GetHelpShortDescriptionString();
+private:
+       CRegistryTree& m_rTree;
+};
+
+#endif // !defined(SHELLCOMMANDSETVALUE_H__32B55193_715E_11D4_A06C_BEFAED86450E__INCLUDED_)
diff --git a/rosapps/sysutils/regexpl/ShellCommandValue.cpp b/rosapps/sysutils/regexpl/ShellCommandValue.cpp
new file mode 100644 (file)
index 0000000..f1e01cc
--- /dev/null
@@ -0,0 +1,428 @@
+/* $Id: ShellCommandValue.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $
+ *
+ * regexpl - Console Registry Explorer
+ *
+ * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
+ *
+ * License: GNU GPL
+ *
+ */
+// ShellCommandValue.cpp: implementation of the CShellCommandValue class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "ph.h"
+#include "RegistryExplorer.h"
+#include "ShellCommandValue.h"
+#include "RegistryTree.h"
+#include "RegistryKey.h"
+
+#define VALUE_CMD                              _T("VV")
+#define VALUE_CMD_LENGTH               COMMAND_LENGTH(VALUE_CMD)
+#define VALUE_CMD_SHORT_DESC   VALUE_CMD _T(" command is used to view value.\n")
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CShellCommandValue::CShellCommandValue(CRegistryTree& rTree):m_rTree(rTree)
+{
+}
+
+CShellCommandValue::~CShellCommandValue()
+{
+}
+
+BOOL CShellCommandValue::Match(const TCHAR *pchCommand)
+{
+       if (_tcsicmp(pchCommand,VALUE_CMD) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,VALUE_CMD _T(".."),VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,VALUE_CMD _T("/"),VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       if (_tcsnicmp(pchCommand,VALUE_CMD _T("\\"),VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
+               return TRUE;
+       return FALSE;
+}
+
+int CShellCommandValue::Execute(CConsole &rConsole, CArgumentParser& rArguments)
+{
+       rArguments.ResetArgumentIteration();
+       TCHAR *pchCommandItself = rArguments.GetNextArgument();
+
+       TCHAR *pchParameter;