-# $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
#
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
ldd.o: ldd.c
+# By Nedko Arnaoudov
+
+regexpl/regexpl$(EXE_POSTFIX):
+ make -C regexpl
+
#---
CLEAN_FILES = *.o *.exe *.sym
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+ }
+ }*/
--- /dev/null
+// 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_)
--- /dev/null
+/* $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 */
--- /dev/null
+#
+# 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
+
--- /dev/null
+/* $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;
+}
--- /dev/null
+
+#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
--- /dev/null
+/* $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);
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+ }
+}
+
+
--- /dev/null
+// 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_)
--- /dev/null
+/* $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()
+{
+
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
+
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
+
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
+
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;
+}
--- /dev/null
+// 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_)
--- /dev/null
+/* $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;