diff --git a/rosapps/sysutils/makefile b/rosapps/sysutils/makefile index df4e6c71b96..0714e727dad 100644 --- a/rosapps/sysutils/makefile +++ b/rosapps/sysutils/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.6 2000/09/11 20:17:02 ea Exp $ +# $Id: makefile,v 1.7 2000/10/04 21:04:30 ea Exp $ # # ReactOS System Utilities # @@ -42,10 +42,12 @@ TARGET=\ pedump.exe \ shutdown.exe \ chkdsk.exe \ - format.exe + format.exe \ + regexpl/regexpl$(EXE_POSTFIX) all: $(TARGET) + # By Mark Russinovich chkdsk.exe: chkdsk.o win32err.o wmain.o chkdsk.coff @@ -144,6 +146,11 @@ ldd.exe: ldd.o win32err.o ldd.coff ldd.o: ldd.c +# By Nedko Arnaoudov + +regexpl/regexpl$(EXE_POSTFIX): + make -C regexpl + #--- CLEAN_FILES = *.o *.exe *.sym diff --git a/rosapps/sysutils/regexpl/ArgumentParser.cpp b/rosapps/sysutils/regexpl/ArgumentParser.cpp new file mode 100644 index 00000000000..d28c6a4fcd3 --- /dev/null +++ b/rosapps/sysutils/regexpl/ArgumentParser.cpp @@ -0,0 +1,94 @@ +/* $Id: ArgumentParser.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// ArgumentParser.cpp: implementation of the CArgumentParser class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "ArgumentParser.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CArgumentParser::CArgumentParser() +{ + m_pchArgumentList = NULL; + m_pchArgumentListEnd = NULL; + m_pchArgument = NULL; +} + +CArgumentParser::~CArgumentParser() +{ +} + +void CArgumentParser::SetArgumentList(TCHAR *pchArguments) +{ + TCHAR *pch = m_pchArgumentList = pchArguments; + m_pchArgumentListEnd = pchArguments + _tcslen(pchArguments); + + BOOL blnLongArg = FALSE; + while (*pch) + { + switch(*pch) + { + case L'\"': + if (blnLongArg) blnLongArg = FALSE; + else blnLongArg = TRUE; + break; + case L' ': + case L'\t': + case L'\r': + case L'\n': + if (!blnLongArg) *pch = 0; + break; + } + pch++; + } + + ResetArgumentIteration(); +} + +TCHAR * CArgumentParser::GetNextArgument() +{ + ASSERT(m_pchArgumentList); // call SetArgumentList() before calling this function + ASSERT(m_pchArgumentListEnd); // call SetArgumentList() before calling this function + ASSERT(m_pchArgumentListEnd >= m_pchArgumentList); + + // if this is begin of iteration + if (!m_pchArgument) m_pchArgument = m_pchArgumentList; + + while(m_pchArgument) + { + if (m_pchArgument > m_pchArgumentListEnd) + { // if end of arguments list reached + ASSERT(m_pchArgument - 1 == m_pchArgumentListEnd); + break; + } + + TCHAR *pchArg = m_pchArgument; + + // Next argument + m_pchArgument += _tcslen(m_pchArgument)+1; + + if(*pchArg) + { // if argument is not an empty string + return pchArg; + } + } + + return NULL; +} + +void CArgumentParser::ResetArgumentIteration() +{ + m_pchArgument = NULL; +} diff --git a/rosapps/sysutils/regexpl/ArgumentParser.h b/rosapps/sysutils/regexpl/ArgumentParser.h new file mode 100644 index 00000000000..4495f2f8402 --- /dev/null +++ b/rosapps/sysutils/regexpl/ArgumentParser.h @@ -0,0 +1,40 @@ +// ArgumentParser.h: interface for the CArgumentParser class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(ARGUMENTPARSER_H__D4C1F637_BEBF_11D3_91EE_204C4F4F5020__INCLUDED_) +#define ARGUMENTPARSER_H__D4C1F637_BEBF_11D3_91EE_204C4F4F5020__INCLUDED_ + +// Use this class to create parser of command line object +class CArgumentParser +{ +public: + // Call this function to specify buffer containing the command line to be parsed + // Parameters: + // pchArguments - pointer to buffer containing the command line. This buffer is modified by object, + // and must not be accessed extrenaly when object is used, unless you interate it + // only once and modify only substrings returned by GetNextArgument. + // + // Remarks: + // This object can be reused by setting the buffer multiple times. + void SetArgumentList(TCHAR *pchArguments); + + // Call this function to reset argument iteration. You don't need to call this function after call + // to set SetArgumentList, because calling SetArgumentList resets iteration with new buffer. + void ResetArgumentIteration(); + + // Call this function to get next argument from command line. + // + // Returns: + // Function returns next argument. If this is first call after calling SetArgumentList or + // ResetArgumentIteration, functions returns the first argument (The command itself ?). + TCHAR * GetNextArgument(); + CArgumentParser(); + virtual ~CArgumentParser(); +private: + TCHAR *m_pchArgumentList; // points to begin of argumet list + const TCHAR *m_pchArgumentListEnd; // points to last 0 in argument list + TCHAR *m_pchArgument; +}; + +#endif // !defined(ARGUMENTPARSER_H__D4C1F637_BEBF_11D3_91EE_204C4F4F5020__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/Console.cpp b/rosapps/sysutils/regexpl/Console.cpp new file mode 100644 index 00000000000..c7baa43a012 --- /dev/null +++ b/rosapps/sysutils/regexpl/Console.cpp @@ -0,0 +1,1021 @@ +/* $Id: Console.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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 (string); + string++; + } + return NULL; +}*/ + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CConsole::CConsole() +{ + m_hStdIn = INVALID_HANDLE_VALUE; + m_hStdOut = INVALID_HANDLE_VALUE; + m_blnInsetMode = TRUE; // Insert +// m_blnInsetMode = FALSE; // Overwrite + m_dwInsertModeCursorHeight = 15; + m_dwOverwriteModeCursorHeight = 100; +// m_Lines = 0; + m_pchBuffer = NULL; + m_pchBuffer1 = NULL; + m_pchBuffer2 = NULL; + m_pfReplaceCompletionCallback = NULL; + m_blnMoreMode = TRUE; +} + +CConsole::~CConsole() +{ + if (m_hStdIn != INVALID_HANDLE_VALUE) + VERIFY(CloseHandle(m_hStdIn)); + if (m_hStdOut != INVALID_HANDLE_VALUE) + VERIFY(CloseHandle(m_hStdOut)); + if (m_pchBuffer) + delete m_pchBuffer; + if (m_pchBuffer1) + delete m_pchBuffer1; + if (m_pchBuffer2) + delete m_pchBuffer2; +} + +BOOL CConsole::Write(const TCHAR *p, DWORD dwChars) +{ + if (m_hStdOut == INVALID_HANDLE_VALUE) + return FALSE; + if (m_hStdIn == INVALID_HANDLE_VALUE) + return FALSE; + if (p == NULL) + { + ASSERT(FALSE); + return FALSE; + } + DWORD dwCharsToWrite = (dwChars)?dwChars:_tcslen(p); + DWORD dwCharsWrittenAdd = 0; + BOOL ret = TRUE; + while (dwCharsToWrite && (!m_blnDisableWrite)) + { + switch(p[dwCharsWrittenAdd]) + { + case _T('\n'): + m_CursorPosition.Y++; + m_CursorPosition.X = 0; + break; + case _T('\r'): + break; + case _T('\t'): + do + { + if (!Write(_T(" "))) return FALSE; + } + while ((m_CursorPosition.X % 8) && (!m_blnDisableWrite)); + dwCharsWrittenAdd++; + dwCharsToWrite--; + continue; + default: + { + if (!WriteChar(p[dwCharsWrittenAdd])) return FALSE; + m_CursorPosition.X++; + } + } + if (m_CursorPosition.X == m_BufferSize.X) + { + m_CursorPosition.Y++; + m_CursorPosition.X = 0; + } + if (m_CursorPosition.Y == m_BufferSize.Y) + { + ASSERT(m_CursorPosition.X == 0); + SMALL_RECT Src; + Src.Left = 0; + Src.Right = (SHORT)(m_BufferSize.X-1); + Src.Top = 1; + Src.Bottom = (SHORT)(m_BufferSize.Y-1); + CHAR_INFO ci; +#ifdef UNICODE + ci.Char.UnicodeChar = L' '; +#else + ci.Char.AsciiChar = ' '; +#endif + ci.Attributes = 0; + COORD Dest; + Dest.X = 0; + Dest.Y = 0; + if (!ScrollConsoleScreenBuffer(m_hStdOut,&Src,NULL,Dest,&ci)) return FALSE; + m_CursorPosition.Y--; + m_LinesScrolled++; + } + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE; + VERIFY(WriteChar(_T(' '))); + if ((m_blnMoreMode)&&(m_CursorPosition.X == 0)) + { + m_Lines++; + if (m_Lines >= m_BufferSize.Y-1) + { + ASSERT(m_Lines == m_BufferSize.Y-1); + m_Lines = 0; + VERIFY(WriteString(_T("-- More --"),m_CursorPosition)); + VERIFY(FlushInputBuffer()); + + CONSOLE_CURSOR_INFO cci; + cci.bVisible = FALSE; + cci.dwSize = 10; + VERIFY(SetConsoleCursorInfo(m_hStdOut,&cci)); + + INPUT_RECORD InputRecord; + DWORD dwRecordsReaded; + while ((ret = ReadConsoleInput(m_hStdIn,&InputRecord,1,&dwRecordsReaded)) != FALSE) + { + ASSERT(dwRecordsReaded == 1); + if (dwRecordsReaded != 1) break; + if (InputRecord.EventType != KEY_EVENT) continue; + if (!InputRecord.Event.KeyEvent.bKeyDown) continue; +#ifdef UNICODE + TCHAR ch = InputRecord.Event.KeyEvent.uChar.UnicodeChar; +#else + TCHAR ch = InputRecord.Event.KeyEvent.uChar.AsciiChar; +#endif + if (ch == VK_CANCEL) + { + VERIFY(GenerateConsoleCtrlEvent(CTRL_C_EVENT,0)); + continue; + } + if (ch) break; + } + VERIFY(WriteString(_T(" "),m_CursorPosition)); + m_CursorPosition.X = 0; + + cci.bVisible = TRUE; + cci.dwSize = m_blnInsetMode?m_dwInsertModeCursorHeight:m_dwOverwriteModeCursorHeight; + VERIFY(SetConsoleCursorInfo(m_hStdOut,&cci)); + } + } + dwCharsWrittenAdd++; + dwCharsToWrite--; + } + return ret; +} + +BOOL CConsole::SetTitle(TCHAR *p) +{ + return SetConsoleTitle(p); +} + +BOOL CConsole::SetTextAttribute(WORD wAttributes) +{ + m_wAttributes = wAttributes; + return TRUE; +} +/* +BOOL CConsole::SetInputMode(DWORD dwMode) +{ + return SetConsoleMode(m_hStdIn,dwMode); +} + +BOOL CConsole::SetOutputMode(DWORD dwMode) +{ + return SetConsoleMode(m_hStdOut,dwMode); +}*/ + +BOOL CConsole::FlushInputBuffer() +{ + if (m_hStdIn == INVALID_HANDLE_VALUE) return FALSE; + return FlushConsoleInputBuffer(m_hStdIn); +} + +BOOL CConsole::ReadLine() +{ + if (m_hStdIn == INVALID_HANDLE_VALUE) return FALSE; + if (m_hStdOut == INVALID_HANDLE_VALUE) return FALSE; + if (m_dwBufferSize == 0) + { + ASSERT(FALSE); + return FALSE; + } + if (m_pchBuffer == NULL) + { + ASSERT(FALSE); + return FALSE; + } + if (m_pchBuffer1 == NULL) + { + ASSERT(FALSE); + return FALSE; + } + if (!FlushConsoleInputBuffer(m_hStdIn)) return FALSE; + + COORD FristCharCursorPosition = m_CursorPosition; +#define X_CURSOR_POSITION_FROM_OFFSET(ofs) USHORT(((FristCharCursorPosition.X + ofs)%m_BufferSize.X)) +#define Y_CURSOR_POSITION_FROM_OFFSET(ofs) USHORT((FristCharCursorPosition.Y + (FristCharCursorPosition.X + ofs)/m_BufferSize.X)) +//#define OFFSET_FROM_CURSOR_POSITION(pos) ((pos.Y-FristCharCursorPosition.Y)*m_BufferSize.X+pos.X-FristCharCursorPosition.X) + + DWORD dwRecordsReaded; + DWORD dwCurrentCharOffset = 0; + DWORD dwLastCharOffset = 0; + BOOL ret; + + BOOL blnCompletionMode = FALSE; +// unsigned __int64 nCompletionIndex = 0; + unsigned long long nCompletionIndex = 0; + DWORD dwCompletionOffset = 0; + DWORD dwCompletionStringSize = 0; + COORD CompletionPosition = FristCharCursorPosition; + + m_LinesScrolled = 0; + BOOL blnOldMoreMode = m_blnMoreMode; + m_blnMoreMode = FALSE; + + DWORD dwHistoryIndex = 0; + + INPUT_RECORD InputRecord; + while ((ret = ReadConsoleInput(m_hStdIn,&InputRecord,1,&dwRecordsReaded)) != FALSE) + { + ASSERT(dwRecordsReaded == 1); + if (dwRecordsReaded != 1) return FALSE; + if (InputRecord.EventType != KEY_EVENT) continue; + if (!InputRecord.Event.KeyEvent.bKeyDown) continue; +#ifdef UNICODE + TCHAR ch = InputRecord.Event.KeyEvent.uChar.UnicodeChar; +#else + TCHAR ch = InputRecord.Event.KeyEvent.uChar.AsciiChar; +#endif +KeyRepeat: + if (m_LinesScrolled) + { + if (m_LinesScrolled > FristCharCursorPosition.Y) return FALSE; + FristCharCursorPosition.Y = SHORT(FristCharCursorPosition.Y - m_LinesScrolled); + if (m_LinesScrolled > CompletionPosition.Y) return FALSE; + CompletionPosition.Y = SHORT(CompletionPosition.Y - m_LinesScrolled); + m_LinesScrolled = 0; + } +// char Buf[1024]; +// sprintf(Buf,"wVirtualKeyCode = %u\nchar = %u\n\n",InputRecord.Event.KeyEvent.wVirtualKeyCode,ch); +// OutputDebugString(Buf); + if ((ch == 0x16)&&(InputRecord.Event.KeyEvent.wVirtualKeyCode == 'V')) + { + goto Paste; + } + else if (ch == 0) + { + if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_INSERT) + { + if (!(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)) + { + VERIFY(SetInsertMode(!m_blnInsetMode)); + } + else + { + if (blnCompletionMode) blnCompletionMode = FALSE; + +Paste: + if (!IsClipboardFormatAvailable( +#ifdef UNICODE + CF_UNICODETEXT +#else + CF_TEXT +#endif + )) + continue; + if (!OpenClipboard(NULL)) + continue; + + const TCHAR *pch = NULL; + + HANDLE hglb = GetClipboardData( +#ifdef UNICODE + CF_UNICODETEXT +#else + CF_TEXT +#endif + ); + if (hglb != NULL) + { + LPTSTR lptstr = (LPTSTR)GlobalLock(hglb); + if (lptstr != NULL) + { + _tcsncpy(m_pchBuffer1,lptstr,m_dwBufferSize); + m_pchBuffer1[m_dwBufferSize-1] = 0; + pch = m_pchBuffer1; + GlobalUnlock(hglb); + } + } + CloseClipboard(); + + if (pch == NULL) continue; + + while (*pch) + { + if (_istprint(*pch)) + { + if (dwLastCharOffset >= m_dwBufferSize-1) + { + ASSERT(dwLastCharOffset == m_dwBufferSize-1); + // Beep(1000,100); + break; + } + TCHAR ch1; + //if (m_blnInsetMode) + ch1 = m_pchBuffer[dwCurrentCharOffset]; + m_pchBuffer[dwCurrentCharOffset] = *pch; + if ((m_blnInsetMode)||(dwCurrentCharOffset == dwLastCharOffset)) dwLastCharOffset++; + dwCurrentCharOffset++; + if (!Write(pch,1)) return FALSE; + if (m_blnInsetMode) + { + COORD Cursor = m_CursorPosition; + DWORD ofs = dwCurrentCharOffset; + + while(ofs <= dwLastCharOffset) + { + ch = m_pchBuffer[ofs]; + m_pchBuffer[ofs] = ch1; + ch1 = ch; + ofs++; + } + + if (dwCurrentCharOffset < dwLastCharOffset) + { + if (!Write(m_pchBuffer+dwCurrentCharOffset,dwLastCharOffset-dwCurrentCharOffset)) return FALSE; + + if (m_LinesScrolled) + { + if (m_LinesScrolled > FristCharCursorPosition.Y) return FALSE; + Cursor.Y = SHORT(Cursor.Y - m_LinesScrolled); + } + // Update cursor position + m_CursorPosition = Cursor; + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE; + } + } + } + pch++; + } + } + } + else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_LEFT) + { + if (blnCompletionMode) blnCompletionMode = FALSE; + if (dwCurrentCharOffset) + { + if (InputRecord.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + { + TCHAR *pchWordBegin = m_pchBuffer+dwCurrentCharOffset-1; + + while (pchWordBegin > m_pchBuffer) + { + if (!_istspace(*pchWordBegin)) break; + pchWordBegin--; + } + + while (pchWordBegin > m_pchBuffer) + { + if (_istspace(*(pchWordBegin-1))) break; + pchWordBegin--; + } + + ASSERT(pchWordBegin >= m_pchBuffer); + dwCurrentCharOffset = pchWordBegin - m_pchBuffer; + + ASSERT(dwCurrentCharOffset < dwLastCharOffset); + + m_CursorPosition.X = X_CURSOR_POSITION_FROM_OFFSET(dwCurrentCharOffset); + m_CursorPosition.Y = Y_CURSOR_POSITION_FROM_OFFSET(dwCurrentCharOffset); + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + } + else + { + dwCurrentCharOffset--; + if (m_CursorPosition.X) + { + m_CursorPosition.X--; + } + else + { + m_CursorPosition.X = SHORT(m_BufferSize.X-1); + ASSERT(m_CursorPosition.Y); + m_CursorPosition.Y--; + } + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + } + } + } + else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_RIGHT) + { + if (blnCompletionMode) blnCompletionMode = FALSE; + if (dwCurrentCharOffset < dwLastCharOffset) + { + if (InputRecord.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + { + TCHAR *pchWordBegin = m_pchBuffer+dwCurrentCharOffset; + + while ((DWORD)(pchWordBegin - m_pchBuffer) < dwLastCharOffset) + { + if (_istspace(*pchWordBegin)) break; + pchWordBegin++; + } + + while ((DWORD)(pchWordBegin - m_pchBuffer) < dwLastCharOffset) + { + if (!_istspace(*pchWordBegin)) break; + pchWordBegin++; + } + + dwCurrentCharOffset = pchWordBegin - m_pchBuffer; + ASSERT(dwCurrentCharOffset <= dwLastCharOffset); + m_CursorPosition.X = X_CURSOR_POSITION_FROM_OFFSET(dwCurrentCharOffset); + m_CursorPosition.Y = Y_CURSOR_POSITION_FROM_OFFSET(dwCurrentCharOffset); + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + } + else + { + dwCurrentCharOffset++; + m_CursorPosition.X++; + if (m_CursorPosition.X == m_BufferSize.X) + { + m_CursorPosition.Y++; + m_CursorPosition.X = 0; + } + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + } + } + } + else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_HOME) + { + if (blnCompletionMode) blnCompletionMode = FALSE; + dwCurrentCharOffset = 0; + m_CursorPosition = FristCharCursorPosition; + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + } + else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_END) + { + if (blnCompletionMode) blnCompletionMode = FALSE; + dwCurrentCharOffset = dwLastCharOffset; + m_CursorPosition.X = X_CURSOR_POSITION_FROM_OFFSET(dwLastCharOffset); + m_CursorPosition.Y = Y_CURSOR_POSITION_FROM_OFFSET(dwLastCharOffset); + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + } + else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_UP) + { + if (blnCompletionMode) blnCompletionMode = FALSE; + dwHistoryIndex++; + const TCHAR *pchHistoryLine = m_History.GetHistoryLine(dwHistoryIndex-1); + if (pchHistoryLine) + { + if (dwLastCharOffset) + { + _tcsnset(m_pchBuffer,_T(' '),dwLastCharOffset); + m_CursorPosition = FristCharCursorPosition; + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + VERIFY(Write(m_pchBuffer,dwLastCharOffset)); + dwCurrentCharOffset = dwLastCharOffset = 0; + m_CursorPosition = FristCharCursorPosition; + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + } + dwCurrentCharOffset = dwLastCharOffset = _tcslen(pchHistoryLine); + if (dwLastCharOffset >= m_dwBufferSize) + { + ASSERT(FALSE); + return FALSE; + } + _tcscpy(m_pchBuffer,pchHistoryLine); + if (!Write(m_pchBuffer)) return FALSE; + } + else + { + dwHistoryIndex--; + } + } + else if (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_DOWN) + { + if (blnCompletionMode) blnCompletionMode = FALSE; + if (dwHistoryIndex) + { + dwHistoryIndex--; + const TCHAR *pchHistoryLine = m_History.GetHistoryLine(dwHistoryIndex-1); + if (dwLastCharOffset) + { + _tcsnset(m_pchBuffer,_T(' '),dwLastCharOffset); + m_CursorPosition = FristCharCursorPosition; + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + VERIFY(Write(m_pchBuffer,dwLastCharOffset)); + dwCurrentCharOffset = dwLastCharOffset = 0; + m_CursorPosition = FristCharCursorPosition; + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + } + if (pchHistoryLine) + { + dwCurrentCharOffset = dwLastCharOffset = _tcslen(pchHistoryLine); + if (dwLastCharOffset >= m_dwBufferSize) + { + ASSERT(FALSE); + return FALSE; + } + _tcscpy(m_pchBuffer,pchHistoryLine); + if (!Write(m_pchBuffer)) return FALSE; + } + } + } + else if ((InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_DELETE)&& + (dwLastCharOffset)) + { + // Move the characters if any... + ASSERT(dwLastCharOffset); + DWORD dwCharOffset = dwCurrentCharOffset; + if (dwCharOffset < dwLastCharOffset) + { + while(dwCharOffset < dwLastCharOffset) + { + m_pchBuffer[dwCharOffset] = m_pchBuffer[dwCharOffset+1]; + dwCharOffset++; + } + + m_pchBuffer[dwLastCharOffset-1] = _T(' '); + + // Save cursor position + COORD Cursor = m_CursorPosition; + + if (!Write(m_pchBuffer+dwCurrentCharOffset,dwLastCharOffset-dwCurrentCharOffset)) return FALSE; + + dwLastCharOffset--; + + // Update cursor position + m_CursorPosition = Cursor; + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE; + } + + } +// else if ((InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE)&& +// (InputRecord.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))) +// { +// if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,0)) return FALSE; +// } + } + else if ((ch == 27) && dwLastCharOffset && + (InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) + { + if (blnCompletionMode) blnCompletionMode = FALSE; + _tcsnset(m_pchBuffer,_T(' '),dwLastCharOffset); + m_CursorPosition = FristCharCursorPosition; + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + VERIFY(Write(m_pchBuffer,dwLastCharOffset)); + dwCurrentCharOffset = dwLastCharOffset = 0; + m_CursorPosition = FristCharCursorPosition; + VERIFY(SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)); + } + else if (ch == _T('\r')) + { // carriage return + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition = FristCharCursorPosition)) return FALSE; + ASSERT(dwLastCharOffset <= m_dwBufferSize); + m_pchBuffer[dwLastCharOffset] = 0; // terminate string in buffer + ret = Write(m_pchBuffer); + m_History.AddHistoryLine(m_pchBuffer); + TCHAR *strLF = _T("\n"); + ret = Write(strLF); + break; + } + else if (ch == _T('\b')) + { // backspace + if (blnCompletionMode) blnCompletionMode = FALSE; + if ((dwCurrentCharOffset) && ((m_CursorPosition.X != 0) || (m_CursorPosition.Y != 0))) + { + // Calculate new cursor position + COORD NewCursorPosition; + if (m_CursorPosition.X) + { + NewCursorPosition.X = SHORT(m_CursorPosition.X-1); + NewCursorPosition.Y = m_CursorPosition.Y; + } + else + { + ASSERT(m_BufferSize.X); + NewCursorPosition.X = SHORT(m_BufferSize.X-1); + ASSERT(m_CursorPosition.Y); + NewCursorPosition.Y = SHORT(m_CursorPosition.Y-1); + } + + // Move the characters if any... + ASSERT(dwLastCharOffset); + DWORD dwCharOffset = dwCurrentCharOffset-1; + while(dwCharOffset < dwLastCharOffset-1) + { + m_pchBuffer[dwCharOffset] = m_pchBuffer[dwCharOffset+1]; + dwCharOffset++; + } + + m_pchBuffer[dwLastCharOffset-1] = _T(' '); + + dwCurrentCharOffset--; + m_CursorPosition = NewCursorPosition; + if (!Write(m_pchBuffer+dwCurrentCharOffset,dwLastCharOffset-dwCurrentCharOffset)) return FALSE; + + // Update cursor position + m_CursorPosition = NewCursorPosition; + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE; + + dwLastCharOffset--; + } + } + else if (ch == _T('\t')) + { + if (!blnCompletionMode) + { + if (InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) +// nCompletionIndex = 0xFFFFFFFFFFFFFFFF; + nCompletionIndex = (unsigned long long) -1; + else + nCompletionIndex = 0; + dwCompletionOffset = dwCurrentCharOffset; + BOOL b = FALSE; + while(dwCompletionOffset) + { + dwCompletionOffset--; + if (m_pchBuffer[dwCompletionOffset] == _T('\"')) + { + b = !b; + } + else if (!b && _istspace(m_pchBuffer[dwCompletionOffset])) + { + dwCompletionOffset++; + break; + } + } + ASSERT(dwCompletionOffset <= dwCurrentCharOffset); + _tcsncpy(m_pchBuffer1,m_pchBuffer,dwCompletionOffset); + m_pchBuffer1[dwCompletionOffset] = 0; + dwCompletionStringSize = dwCurrentCharOffset-dwCompletionOffset; + if (dwCompletionStringSize) + _tcsncpy(m_pchBuffer2,m_pchBuffer+dwCompletionOffset,dwCompletionStringSize); + m_pchBuffer2[dwCompletionStringSize] = 0; + CompletionPosition.X = X_CURSOR_POSITION_FROM_OFFSET(dwCompletionOffset); + CompletionPosition.Y = Y_CURSOR_POSITION_FROM_OFFSET(dwCompletionOffset); +// Beep(1000,500); + } + else + { +// Beep(1000,50); +// Beep(2000,50); +// Beep(3000,50); +// Beep(4000,50); +// Beep(3000,50); +// Beep(2000,50); +// Beep(1000,50); + } + const TCHAR *pchCompletion = NULL; + BOOL blnForward = !(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED); + if (m_pfReplaceCompletionCallback) + pchCompletion = m_pfReplaceCompletionCallback(nCompletionIndex, + blnCompletionMode?&blnForward:NULL, + m_pchBuffer1,m_pchBuffer2); + if (pchCompletion) + { + // Set cursor position + m_CursorPosition = CompletionPosition; + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE; + + // Calculate buffer free space + ASSERT(m_dwBufferSize > dwCompletionOffset); + DWORD dwFree = m_dwBufferSize - dwCompletionOffset - 1; + + DWORD dwOldCompletionStringSize = dwCompletionStringSize; + + // Write completion string to buffer + dwCompletionStringSize = _tcslen(pchCompletion); + + if (dwCompletionStringSize > dwFree) + dwCompletionStringSize = dwFree; + if (dwCompletionStringSize) + { + _tcsncpy(m_pchBuffer+dwCompletionOffset,pchCompletion,dwCompletionStringSize); +// m_pchBuffer[dwCompletionOffset+dwCompletionStringSize] = 0; + + // Write completion string to console + if (!Write(m_pchBuffer+dwCompletionOffset,dwCompletionStringSize)) return FALSE; + dwCurrentCharOffset = dwLastCharOffset = dwCompletionOffset + dwCompletionStringSize; + ASSERT(dwLastCharOffset < m_dwBufferSize); + } + + // Erase rest from previous completion string + if (dwOldCompletionStringSize > dwCompletionStringSize) + { + _tcsnset(m_pchBuffer+dwCompletionOffset+dwCompletionStringSize,_T(' '), + dwOldCompletionStringSize - dwCompletionStringSize); + + // Save cursor position + COORD pos = m_CursorPosition; + + if (!Write(m_pchBuffer+dwCompletionOffset+dwCompletionStringSize, + dwOldCompletionStringSize - dwCompletionStringSize)) + return FALSE; + + // Set cursor position + m_CursorPosition = pos; + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE; + } + + } + else + { +/* if (InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) + { + nCompletionIndex++; + } + else + { + if (nCompletionIndex) + nCompletionIndex--; + }*/ + } + blnCompletionMode = TRUE; + } + else if (_istprint(ch)) + { + if (blnCompletionMode) blnCompletionMode = FALSE; + if (dwLastCharOffset >= m_dwBufferSize-1) + { + ASSERT(dwLastCharOffset == m_dwBufferSize-1); +// Beep(1000,100); + continue; + } + TCHAR ch1; + //if (m_blnInsetMode) + ch1 = m_pchBuffer[dwCurrentCharOffset]; + m_pchBuffer[dwCurrentCharOffset] = ch; + if ((m_blnInsetMode)||(dwCurrentCharOffset == dwLastCharOffset)) dwLastCharOffset++; + dwCurrentCharOffset++; + if (!Write(&ch,1)) return FALSE; + if (m_blnInsetMode) + { + COORD Cursor = m_CursorPosition; + DWORD ofs = dwCurrentCharOffset; + + while(ofs <= dwLastCharOffset) + { + ch = m_pchBuffer[ofs]; + m_pchBuffer[ofs] = ch1; + ch1 = ch; + ofs++; + } + + if (dwCurrentCharOffset < dwLastCharOffset) + { + if (!Write(m_pchBuffer+dwCurrentCharOffset,dwLastCharOffset-dwCurrentCharOffset)) return FALSE; + + if (m_LinesScrolled) + { + if (m_LinesScrolled > FristCharCursorPosition.Y) return FALSE; + Cursor.Y = SHORT(Cursor.Y - m_LinesScrolled); + } + // Update cursor position + m_CursorPosition = Cursor; + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE; + } + } + } + ASSERT(InputRecord.Event.KeyEvent.wRepeatCount); + if (!InputRecord.Event.KeyEvent.wRepeatCount) return FALSE; + if (--InputRecord.Event.KeyEvent.wRepeatCount) goto KeyRepeat; + } + m_blnMoreMode = blnOldMoreMode; + return TRUE; +} + +BOOL CConsole::GetTextAttribute(WORD& rwAttributes) +{ + rwAttributes = m_wAttributes; + return TRUE; +} + +// Parameters: +// dwBufferSize - size in chars of the input line buffer +// +// Rerturns: +// NULL - Failed. +// pointer to the input buffer +TCHAR * CConsole::Init(DWORD dwBufferSize, DWORD dwMaxHistoryLines) +{ + if (m_hStdIn != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdIn)); + if (m_hStdOut != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdOut)); + + m_hStdIn = GetStdHandle(STD_INPUT_HANDLE); + if (m_hStdIn == INVALID_HANDLE_VALUE) goto Abort; + + m_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (m_hStdOut == INVALID_HANDLE_VALUE) goto Abort; + + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(m_hStdOut,&info)) goto Abort; + m_wAttributes = info.wAttributes; + + if (!SetConsoleMode(m_hStdIn,0)) goto Abort; + if (!SetConsoleMode(m_hStdOut,0)) goto Abort; + + m_CursorPosition = info.dwCursorPosition; + m_BufferSize = info.dwSize; + + CONSOLE_CURSOR_INFO cci; + cci.bVisible = TRUE; + cci.dwSize = m_blnInsetMode?m_dwInsertModeCursorHeight:m_dwOverwriteModeCursorHeight; + + if (!SetConsoleCursorInfo(m_hStdOut,&cci)) goto Abort; + + m_dwBufferSize = dwBufferSize; + + if (m_pchBuffer) delete m_pchBuffer; + m_pchBuffer = NULL; + + if (m_pchBuffer1) delete m_pchBuffer1; + m_pchBuffer1 = NULL; + + if (m_pchBuffer2) delete m_pchBuffer2; + m_pchBuffer2 = NULL; + + m_pchBuffer = new TCHAR [dwBufferSize]; + if (!m_pchBuffer) goto Abort; + m_pchBuffer[dwBufferSize-1] = 0; + + m_pchBuffer1 = new TCHAR [dwBufferSize]; + if (!m_pchBuffer1) goto Abort; + m_pchBuffer1[dwBufferSize-1] = 0; + + m_pchBuffer2 = new TCHAR [dwBufferSize]; + if (!m_pchBuffer2) goto Abort; + m_pchBuffer2[dwBufferSize-1] = 0; + + if (dwMaxHistoryLines) + { + if (!m_History.Init(dwBufferSize,dwMaxHistoryLines)) goto Abort; + } + + return m_pchBuffer; + +Abort: + if (m_hStdIn != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdIn)); + m_hStdIn = INVALID_HANDLE_VALUE; + + if (m_hStdOut != INVALID_HANDLE_VALUE) VERIFY(CloseHandle(m_hStdOut)); + m_hStdOut = INVALID_HANDLE_VALUE; + + if (m_pchBuffer) delete m_pchBuffer; + m_pchBuffer = NULL; + + if (m_pchBuffer1) delete m_pchBuffer1; + m_pchBuffer1 = NULL; + + if (m_pchBuffer2) delete m_pchBuffer2; + m_pchBuffer2 = NULL; + + m_dwBufferSize = 0; + + return NULL; +} + +BOOL CConsole::WriteChar(TCHAR ch) +{ + CHAR_INFO ci; + ci.Attributes = m_wAttributes; +#ifdef UNICODE + ci.Char.UnicodeChar = ch; +#else + ci.Char.AsciiChar = ch; +#endif + static COORD BufferSize = {1,1}; + static COORD BufferCoord = {0,0}; + SMALL_RECT Dest; + Dest.Bottom = Dest.Top = m_CursorPosition.Y; + Dest.Left = Dest.Right = m_CursorPosition.X; + return WriteConsoleOutput(m_hStdOut,&ci,BufferSize,BufferCoord,&Dest); +} + +void CConsole::BeginScrollingOperation() +{ + m_Lines = 0; +} + +BOOL CConsole::WriteString(TCHAR *pchString, COORD Position) +{ + CHAR_INFO ciBuffer[256]; + int nSize = _tcslen(pchString); + if ((nSize > 256)||(nSize <= 0)) + { + ASSERT(FALSE); + return FALSE; + } + + COORD BufferSize; + BufferSize.X = (SHORT)nSize; + BufferSize.Y = 1; + static COORD BufferCoord = {0,0}; + SMALL_RECT Dest; + Dest.Bottom = Dest.Top = Position.Y; + Dest.Right = SHORT((Dest.Left = Position.X) + nSize - 1); + + while(nSize--) + { + ciBuffer[nSize].Attributes = m_wAttributes; +#ifdef UNICODE + ciBuffer[nSize].Char.UnicodeChar = pchString[nSize]; +#else + ciBuffer[nSize].Char.AsciiChar = pchString[nSize]; +#endif + } + + return WriteConsoleOutput(m_hStdOut,ciBuffer,BufferSize,BufferCoord,&Dest); +} + +BOOL CConsole::SetInsertMode(BOOL blnInsetMode) +{ + if (m_hStdOut == INVALID_HANDLE_VALUE) return FALSE; + + CONSOLE_CURSOR_INFO cci; + cci.bVisible = TRUE; + cci.dwSize = blnInsetMode?m_dwInsertModeCursorHeight:m_dwOverwriteModeCursorHeight; + + BOOL ret = SetConsoleCursorInfo(m_hStdOut,&cci); + if (ret) m_blnInsetMode = blnInsetMode; + return ret; +} + + + +void CConsole::SetReplaceCompletionCallback(ReplaceCompletionCallback pfCallback) +{ + m_pfReplaceCompletionCallback = pfCallback; +} + + +void CConsole::DisableWrite() +{ + m_blnDisableWrite = TRUE; + INPUT_RECORD InputRecord; + DWORD dwRecordsWriten; + InputRecord.EventType = KEY_EVENT; + InputRecord.Event.KeyEvent.bKeyDown = TRUE; +#ifdef UNICODE + InputRecord.Event.KeyEvent.uChar.UnicodeChar = L' '; +#else + InputRecord.Event.KeyEvent.uChar.AsciiChar = ' '; +#endif + BOOL ret = WriteConsoleInput(m_hStdIn,&InputRecord,1,&dwRecordsWriten); + ASSERT(ret); +} + +void CConsole::EnableWrite() +{ + m_blnDisableWrite = FALSE; +} + +/* DWORD ofs = dwCurrentCharOffset; + DWORD nLines = (FristCharCursorPosition.X + dwLastCharOffset-1)/m_BufferSize.X; + for (DWORD nLine = 0 ; nLine <= nLines ; nLine++) + { + ASSERT(m_BufferSize.X > pos.X); + DWORD nChars = m_BufferSize.X - pos.X - 1; + if (nChars > dwLastCharOffset - ofs) nChars = dwLastCharOffset - ofs; + if (nChars) + { // We have some chars to move in this line + _tcsncpy(m_pchBuffer1,m_pchBuffer+ofs,nChars); + m_pchBuffer1[nChars] = 0; + if (!WriteString(m_pchBuffer1,pos)) return FALSE; + } + pos.X = SHORT(pos.X + nChars); + // if current line is not the last line + // Move the first char in next line to end of current line + if (nLine < nLines) + { + ofs += nChars; + m_pchBuffer1[0] = m_pchBuffer[ofs]; + m_pchBuffer1[1] = 0; + if (!WriteString(m_pchBuffer1,pos)) return FALSE; + pos.Y++; + pos.X = 0; + ofs++; + } + else // Adjust end of read line + { + m_pchBuffer1[0] = _T(' '); + m_pchBuffer1[1] = 0; + if (!WriteString(m_pchBuffer1,pos)) return FALSE; + } + }*/ diff --git a/rosapps/sysutils/regexpl/Console.h b/rosapps/sysutils/regexpl/Console.h new file mode 100644 index 00000000000..05db9ccb5e1 --- /dev/null +++ b/rosapps/sysutils/regexpl/Console.h @@ -0,0 +1,56 @@ +// Console.h: interface for the CConsole class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(CONSOLE_H__FEF419EC_6EB6_11D3_907D_204C4F4F5020__INCLUDED_) +#define CONSOLE_H__FEF419EC_6EB6_11D3_907D_204C4F4F5020__INCLUDED_ + +#include "TextHistory.h" + +typedef const TCHAR * (*ReplaceCompletionCallback)(unsigned __int64& rnIndex, const BOOL *pblnForward, + const TCHAR *pchContext, const TCHAR *pchBegin); + +class CConsole +{ +public: + void EnableWrite(); + void DisableWrite(); + void SetReplaceCompletionCallback(ReplaceCompletionCallback pfCallback); + BOOL SetInsertMode(BOOL blnInsetMode); + void BeginScrollingOperation(); + TCHAR * Init(DWORD dwBufferSize, DWORD dwMaxHistoryLines = 0); + BOOL ReadLine(); + BOOL FlushInputBuffer(); +// BOOL SetOutputMode(DWORD dwMode); +// BOOL SetInputMode(DWORD dwMode); + BOOL SetTextAttribute(WORD wAttributes); + BOOL GetTextAttribute(WORD& rwAttributes); + BOOL SetTitle(TCHAR *p); + BOOL Write(const TCHAR *p, DWORD dwChars = 0); + CConsole(); + virtual ~CConsole(); +private: + HANDLE m_hStdOut; + HANDLE m_hStdIn; + HANDLE m_hStdError; + COORD m_CursorPosition; + COORD m_BufferSize; + WORD m_wAttributes; + SHORT m_Lines; + BOOL WriteString(TCHAR *pchString, COORD Position); + BOOL WriteChar(TCHAR ch); + BOOL m_blnInsetMode; // TRUE - insert, FALSE - overwrite + DWORD m_dwInsertModeCursorHeight; + DWORD m_dwOverwriteModeCursorHeight; + TCHAR *m_pchBuffer; + TCHAR *m_pchBuffer1; + TCHAR *m_pchBuffer2; + DWORD m_dwBufferSize; + ReplaceCompletionCallback m_pfReplaceCompletionCallback; + SHORT m_LinesScrolled; + BOOL m_blnMoreMode; + CTextHistory m_History; + BOOL m_blnDisableWrite; +}; + +#endif // !defined(CONSOLE_H__FEF419EC_6EB6_11D3_907D_204C4F4F5020__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/CrtSupplement.c b/rosapps/sysutils/regexpl/CrtSupplement.c new file mode 100644 index 00000000000..750080fea4c --- /dev/null +++ b/rosapps/sysutils/regexpl/CrtSupplement.c @@ -0,0 +1,50 @@ +/* $Id: CrtSupplement.c,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * Written by EA because ReactOS hasn't yet _ui64toa() + * (it's in msvcrt.dll, and not in crtdll.dll). + */ + +#include + +static +char DigitMap [36] = "0123456789abcdefghijklmnopqrstuvwxyz"; + +char * +_ui64toa ( + unsigned __int64 value, + char * string, + int radix + ) +{ + int reminder = 0; + char buffer [17]; + char * w = buffer; + int len = 0; + int i = 0; + + /* Check the radix is valid */ + if ((2 > radix) || (36 < radix)) + { + return string; + } + /* Convert the int64 to a string */ + do { + reminder = (int) (value % (__int64) radix); + *(w ++) = DigitMap [reminder]; + value /= (__int64) radix; + ++ len; + + } while ((__int64) value > 0); + /* Reverse the string */ + while (i < len) + { + string [i ++] = *(-- w); + } + string [len] = '\0'; + + return string; +} + + + +/* EOF */ diff --git a/rosapps/sysutils/regexpl/Makefile b/rosapps/sysutils/regexpl/Makefile new file mode 100644 index 00000000000..87b5c0725f6 --- /dev/null +++ b/rosapps/sysutils/regexpl/Makefile @@ -0,0 +1,96 @@ +# +# ReactOS makefile for RegExpl +# + +TARGET_NAME=regexpl + +ROS_DIR=../../../reactos +ROS_INC=$(ROS_DIR)/include +ROS_LIB=$(ROS_DIR)/lib +IMPORT_NTDLL=$(ROS_LIB)/ntdll/ntdll.a +IMPORT_FMIFS=$(ROS_LIB)/fmifs/fmifs.a +IMPORT_KERNEL32=$(ROS_LIB)/kernel32/kernel32.a +IMPORT_ADVAPI32=$(ROS_LIB)/advapi32/advapi32.a +IMPORT_USER32=$(ROS_LIB)/user32/user32.a +IMPORT_CRTDLL=$(ROS_LIB)/crtdll/crtdll.a + + +all: $(TARGET_NAME)$(EXE_POSTFIX) + +OBJECTS = \ + ArgumentParser.o \ + Console.o \ + RegistryExplorer.o \ + RegistryKey.o \ + RegistryTree.o \ + SecurityDescriptor.o \ + ShellCommand.o \ + ShellCommandChangeKey.o \ + ShellCommandConnect.o \ + ShellCommandDACL.o \ + ShellCommandDOKA.o \ + ShellCommandDeleteKey.o \ + ShellCommandDeleteValue.o \ + ShellCommandDir.o \ + ShellCommandExit.o \ + ShellCommandHelp.o \ + ShellCommandNewKey.o \ + ShellCommandOwner.o \ + ShellCommandSACL.o \ + ShellCommandSetValue.o \ + ShellCommandValue.o \ + ShellCommandVersion.o \ + ShellCommandsLinkedList.o \ + CrtSupplement.c \ + TextHistory.o \ + $(TARGET_NAME).coff + +CLEAN_FILES = \ + *.o \ + $(TARGET_NAME)$(EXE_POSTFIX) \ + $(TARGET_NAME).sym \ + $(TARGET_NAME).coff + + +$(TARGET_NAME)$(EXE_POSTFIX): $(OBJECTS) + $(CC) \ + -Wl,--subsystem,console \ + -o $(TARGET_NAME) \ + $(IMPORT_KERNEL32) \ + $(IMPORT_CRTDLL) \ + $(IMPORT_USER32) \ + $(OBJECTS) + $(NM) --numeric-sort $(TARGET_NAME)$(EXE_POSTFIX) > $(TARGET_NAME).sym + + +clean: $(CLEAN_FILES:%=%_clean) + +$(CLEAN_FILES:%=%_clean): %_clean: + - $(RM) $* + +.phony: clean $(CLEAN_FILES:%=%_clean) + + +floppy: $(TARGET:%=$(FLOPPY_DIR)/apps/%) + +$(TARGET:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: % +ifeq ($(DOSCLI),yes) + $(CP) $* $(FLOPPY_DIR)\apps\$* +else + $(CP) $* $(FLOPPY_DIR)/apps/$* +endif + + +dist: $(TARGET:%=../$(DIST_DIR)/apps/%) + +$(TARGET:%=../$(DIST_DIR)/apps/%): ../$(DIST_DIR)/apps/%: % +ifeq ($(DOSCLI),yes) + $(CP) $* ..\$(DIST_DIR)\apps\$* +else + $(CP) $* ../$(DIST_DIR)/apps\$* +endif + +include ../../rules.mak + +# EOF + diff --git a/rosapps/sysutils/regexpl/RegistryExplorer.cpp b/rosapps/sysutils/regexpl/RegistryExplorer.cpp new file mode 100644 index 00000000000..96996cf4434 --- /dev/null +++ b/rosapps/sysutils/regexpl/RegistryExplorer.cpp @@ -0,0 +1,510 @@ +/* $Id: RegistryExplorer.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// Registry Explorer.cpp : Defines the entry point for the console application. +// + +#include "ph.h" +#include "RegistryExplorer.h" +#include "Console.h" +#include "RegistryKey.h" +#include "RegistryTree.h" +#include "SecurityDescriptor.h" +#include "ArgumentParser.h" +#include "ShellCommandsLinkedList.h" +#include "ShellCommandExit.h" +#include "ShellCommandVersion.h" +#include "ShellCommandHelp.h" +#include "ShellCommandDir.h" +#include "ShellCommandChangeKey.h" +#include "ShellCommandValue.h" +#include "ShellCommandOwner.h" +#include "ShellCommandDACL.h" +#include "ShellCommandSACL.h" +#include "ShellCommandDOKA.h" +#include "ShellCommandConnect.h" +#include "ShellCommandNewKey.h" +#include "ShellCommandDeleteKey.h" +#include "ShellCommandSetValue.h" + +TCHAR pchCurrentKey[PROMPT_BUFFER_SIZE]; + +CRegistryTree Tree(PROMPT_BUFFER_SIZE+1); +CConsole Console; + +const TCHAR * ppchRootKeys[7] = +{ + _T("HKEY_CLASSES_ROOT"), + _T("HKEY_CURRENT_USER"), + _T("HKEY_LOCAL_MACHINE"), + _T("HKEY_USERS"), + _T("HKEY_PERFORMANCE_DATA"), + _T("HKEY_CURRENT_CONFIG"), + _T("HKEY_DYN_DATA") //win9x only? +}; + +BOOL g_blnCompletionCycle = TRUE; + +const TCHAR * CompletionCallback(unsigned __int64 & rnIndex, const BOOL *pblnForward, const TCHAR *pchContext, const TCHAR *pchBegin) +{ +#define COMPLETION_BUFFER_SIZE 4096 + static TCHAR pchBuffer[COMPLETION_BUFFER_SIZE]; + CRegistryKey *pKey = NULL; + CRegistryTree *pTree = NULL; + unsigned __int64 nTotalKeys = 0; + unsigned __int64 nTotalValues = 0; + unsigned __int64 nTotalItems = 0; + class CompletionMatch + { + public: + CompletionMatch(const TCHAR *pchText, CompletionMatch **pNext) + { + BOOL b = _tcschr(pchText,_T(' ')) != NULL; + size_t s = _tcslen(pchText); + m_pchText = new TCHAR [s+(b?3:1)]; + if (b) + { + m_pchText[0] = _T('\"'); + _tcscpy(m_pchText+1,pchText); + m_pchText[s+1] = _T('\"'); + m_pchText[s+2] = 0; + } + else + { + _tcscpy(m_pchText,pchText); + } + if (m_pchText) + { + m_pNext = *pNext; + *pNext = this; + } + } + ~CompletionMatch() + { + if (m_pchText) + delete m_pchText; + if (m_pNext) + delete m_pNext; + } + const TCHAR *GetText(unsigned __int64 dwReverseIndex) + { + if (dwReverseIndex) + { + if (m_pNext) + return m_pNext->GetText(dwReverseIndex-1); + else + return NULL; + } + return m_pchText; + } + private: + TCHAR *m_pchText; + CompletionMatch *m_pNext; + }; + CompletionMatch *pRootMatch = NULL; + + BOOL blnCompletionOnKeys = TRUE; + BOOL blnCompletionOnValues = TRUE; + + while(*pchContext && _istspace(*pchContext)) + { + pchContext++; + } + +/* if ((_tcsnicmp(pchContext,DIR_CMD,DIR_CMD_LENGTH) == 0)|| + (_tcsnicmp(pchContext,CD_CMD,CD_CMD_LENGTH) == 0)|| + (_tcsnicmp(pchContext,OWNER_CMD,OWNER_CMD_LENGTH) == 0)|| + (_tcsnicmp(pchContext,DACL_CMD,DACL_CMD_LENGTH) == 0)|| + (_tcsnicmp(pchContext,SACL_CMD,SACL_CMD_LENGTH) == 0)) + { + blnCompletionOnValues = FALSE; + }*/ +// else if (_tcsnicmp(pchContext,VALUE_CMD,VALUE_CMD_LENGTH) == 0) +// { +// blnCompletionOnKeys = FALSE; +// } + + const TCHAR *pchKey = _tcsrchr(pchBegin,_T('\\')); + DWORD nBufferOffset = 0; + if (pchKey) + { + nBufferOffset = pchKey-pchBegin+1; + if (nBufferOffset >= COMPLETION_BUFFER_SIZE-1) + { + if (pRootMatch) delete pRootMatch; + if (pTree) + delete pTree; + return _T("internal error"); + } + _tcsncpy(pchBuffer,pchBegin,nBufferOffset); + pchBuffer[nBufferOffset] = 0; + pchBegin = pchKey+1; + pTree = new CRegistryTree(Tree); + if ((_tcscmp(pTree->GetCurrentPath(),Tree.GetCurrentPath()) != 0)||(!pTree->ChangeCurrentKey(pchBuffer))) + { + if (pTree) + delete pTree; + return NULL; + } + else + { + pKey = pTree->GetCurrentKey(); + } + } + else + { + pKey = Tree.GetCurrentKey(); + } + + if (!pKey) + { + for(unsigned int i = 0 ; i < sizeof(ppchRootKeys)/sizeof(TCHAR *) ; i++) + { + nTotalKeys++; + nTotalItems++; + CompletionMatch *p = new CompletionMatch(ppchRootKeys[i],&pRootMatch); + if (!p || !p->GetText(0)) + { + if (pRootMatch) delete pRootMatch; + if (pTree) + delete pTree; + return _T("Out of memory"); + } + } + } + else + { + CompletionMatch *p; + DWORD dwError; + if (blnCompletionOnKeys) + { +/* if (_tcslen(pchBegin) == 0) + { + p = new CompletionMatch(_T(".."),&pRootMatch); + if (!p || !p->GetText(0)) + { + if (pRootMatch) delete pRootMatch; + if (pTree) + delete pTree; + return _T("Out of memory"); + } + nTotalKeys++; + nTotalItems++; + } +*/ + pKey->InitSubKeyEnumeration(); + TCHAR *pchSubKeyName; + while ((pchSubKeyName = pKey->GetSubKeyName(dwError)) != NULL) + { + if (_tcsnicmp(pchSubKeyName,pchBegin,_tcslen(pchBegin)) == 0) + { + nTotalKeys++; + nTotalItems++; + p = new CompletionMatch(pchSubKeyName,&pRootMatch); + if (!p || !p->GetText(0)) + { + if (pRootMatch) delete pRootMatch; + if (pTree) + delete pTree; + return _T("Out of memory"); + } + } + } + if ((dwError != ERROR_SUCCESS)&&(dwError != ERROR_NO_MORE_ITEMS)) + { + if (pRootMatch) delete pRootMatch; + if (pTree) + delete pTree; + return _T("error"); + } + } + + if (blnCompletionOnValues) + { + pKey->InitValueEnumeration(); + TCHAR *pchValueName; + DWORD dwValueNameLength, dwMaxValueNameLength; + dwError = pKey->GetMaxValueNameLength(dwMaxValueNameLength); + if (dwError != ERROR_SUCCESS) + { + if (pRootMatch) delete pRootMatch; + if (pTree) + delete pTree; + return _T("error"); + } + + dwMaxValueNameLength++; + pchValueName = new TCHAR [dwMaxValueNameLength]; + if (!pchValueName) + { + if (pRootMatch) delete pRootMatch; + if (pTree) + delete pTree; + return _T("Out of memory"); + } + for(;;) + { + dwValueNameLength = dwMaxValueNameLength; + //dwValueSize = dwMaxValueSize; + dwError = pKey->GetNextValue(pchValueName,dwValueNameLength,NULL,NULL,NULL); + if (dwError == ERROR_NO_MORE_ITEMS) break; + if (dwError != ERROR_SUCCESS) + { + if (pRootMatch) delete pRootMatch; + if (pTree) + delete pTree; + return _T("error"); + } + + if (((dwValueNameLength == 0) && (_tcslen(pchBegin) == 0))|| + (_tcsnicmp(pchValueName,pchBegin,_tcslen(pchBegin)) == 0)) + { + nTotalValues++; + nTotalItems++; + p = new CompletionMatch((dwValueNameLength == 0)?_T("(Default)"):pchValueName,&pRootMatch); + if (!p || !p->GetText(0)) + { + if (pRootMatch) delete pRootMatch; + if (pTree) + delete pTree; + return _T("Out of memory"); + } + } + } // for + delete [] pchValueName; + } + } + if (rnIndex >= nTotalItems) + rnIndex = nTotalItems-1; + if (pblnForward) + { + if (*pblnForward) + { + rnIndex++; + if (rnIndex >= nTotalItems) + { + if (g_blnCompletionCycle) + rnIndex = 0; + else + rnIndex--; + } + } + else + { + if (rnIndex) + rnIndex--; + else if (g_blnCompletionCycle) + rnIndex = nTotalItems-1; + } + } + + const TCHAR *pchName; + if (nTotalItems == 0) + { + if (pRootMatch) + delete pRootMatch; + if (pTree) + delete pTree; + return NULL; + } + ASSERT(rnIndex < nTotalItems); + pchName = pRootMatch->GetText(nTotalItems-rnIndex-1); + if (pchName == NULL) + { + if (pRootMatch) + delete pRootMatch; + if (pTree) + delete pTree; + return _T("internal error"); + } + DWORD dwBufferFull = _tcslen(pchName); + if (dwBufferFull >= COMPLETION_BUFFER_SIZE-nBufferOffset) + { + dwBufferFull = COMPLETION_BUFFER_SIZE-1-nBufferOffset; + } + _tcsncpy(pchBuffer+nBufferOffset,pchName,dwBufferFull); + if ((dwBufferFull < COMPLETION_BUFFER_SIZE-1)&&(rnIndex < nTotalKeys)) + pchBuffer[nBufferOffset+dwBufferFull++] = _T('\\'); + pchBuffer[nBufferOffset+dwBufferFull] = 0; + if (pTree) + delete pTree; + if (pRootMatch) + delete pRootMatch; + return pchBuffer; +} + +BOOL blnCommandExecutionInProgress = FALSE; + +BOOL WINAPI HandlerRoutine(DWORD dwCtrlType) +{ + switch(dwCtrlType) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + if (blnCommandExecutionInProgress) + { +/* Beep(1000,100); + Beep(2000,100); + Beep(3000,100); + Beep(4000,100); + Beep(5000,100); + Beep(4000,100); + Beep(3000,100); + Beep(2000,100); + Beep(1000,100);*/ + Console.Write(_T("\n")); + Console.DisableWrite(); + } + return TRUE; + default: + return FALSE; + } +} + +//int _tmain(/*int argc, TCHAR* argv[], TCHAR* envp[]*/) +int main () +{ + CShellCommandsLinkedList CommandsList(Console); + + CShellCommandExit ExitCommand; + CommandsList.AddCommand(&ExitCommand); + + CShellCommandVersion VersionCommand; + CommandsList.AddCommand(&VersionCommand); + + CShellCommandHelp HelpCommand(CommandsList); + CommandsList.AddCommand(&HelpCommand); + + CShellCommandDir DirCommand(Tree); + CommandsList.AddCommand(&DirCommand); + + CShellCommandChangeKey ChangeKeyCommand(Tree); + CommandsList.AddCommand(&ChangeKeyCommand); + + CShellCommandValue ValueCommand(Tree); + CommandsList.AddCommand(&ValueCommand); + + CShellCommandOwner OwnerCommand(Tree); + CommandsList.AddCommand(&OwnerCommand); + + CShellCommandDACL DACLCommand(Tree); + CommandsList.AddCommand(&DACLCommand); + + CShellCommandSACL SACLCommand(Tree); + CommandsList.AddCommand(&SACLCommand); + + CShellCommandDOKA DOKACommand(Tree); + CommandsList.AddCommand(&DOKACommand); + + CShellCommandConnect ConnectCommand(Tree); + CommandsList.AddCommand(&ConnectCommand); + + CShellCommandNewKey NewKeyCommand(Tree); + CommandsList.AddCommand(&NewKeyCommand); + + CShellCommandDeleteKey DeleteKeyCommand(Tree); + CommandsList.AddCommand(&DeleteKeyCommand); + + CShellCommandSetValue SetValueCommand(Tree); + CommandsList.AddCommand(&SetValueCommand); + + CArgumentParser Parser; + + int nRetCode = 0; + +// input buffer size in chars +#define INPUT_BUFFER_SIZE 1024 +//#define INPUT_BUFFER_SIZE 128 +//#define INPUT_BUFFER_SIZE 10 + + TCHAR *pchCommand; + + pchCommand = Console.Init(INPUT_BUFFER_SIZE,10); + if (pchCommand == NULL) + { + _ftprintf(stderr,_T("Cannot initialize console.\n")); + goto Abort; + } + + Console.SetReplaceCompletionCallback(CompletionCallback); + + WORD wOldConsoleAttribute; + if (!Console.GetTextAttribute(wOldConsoleAttribute)) goto Abort; + + Console.SetTitle(_T("Registry Explorer")); + Console.SetTextAttribute(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY); + + VERIFY(SetConsoleCtrlHandler((PHANDLER_ROUTINE)HandlerRoutine,TRUE)); + + if (!Console.Write(HELLO_MSG + //(_L(__TIMESTAMP__)) + )) goto Abort; + + Tree.SetDesiredOpenKeyAccess(KEY_READ); + +GetCommand: + Console.EnableWrite(); + Console.Write(_T("[")); + _tcscpy(pchCurrentKey,Tree.GetCurrentPath()); + Console.Write(pchCurrentKey); + Console.Write(_T("]")); + Console.FlushInputBuffer(); + + blnCommandExecutionInProgress = FALSE; + + // Set command line color +// Console.SetTextAttribute(/*FOREGROUND_BLUE|*/FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY); + if (!Console.ReadLine()) goto Abort; + + // Set normal color +// Console.SetTextAttribute(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY); + + Console.BeginScrollingOperation(); + blnCommandExecutionInProgress = TRUE; + + + // Parse command line (1st step - convert to multi sz) + Parser.SetArgumentList(pchCommand); + + int nCommandReturnValue; + switch(CommandsList.Execute(Parser,nCommandReturnValue)) + { + case -1: // not recognized command + { + Parser.ResetArgumentIteration(); + TCHAR *pchCommandItself = Parser.GetNextArgument(); + size_t cmdlen = _tcslen(pchCommandItself); + if ((!cmdlen)|| + (pchCommandItself[cmdlen-1] != _T('\\'))|| + (Parser.GetNextArgument())|| + (!Tree.ChangeCurrentKey(pchCommandItself))) + { + Console.Write(_T("Unknown command \"")); + Console.Write(pchCommandItself); + Console.Write(_T("\"\n")); + } + } + case -2: // empty line + goto GetCommand; + case 0: // exit command + nRetCode = 0; + Console.SetTextAttribute(wOldConsoleAttribute); + goto Exit; + default: + Console.Write(_T("\n")); + goto GetCommand; + } + +Abort: + _ftprintf(stderr,_T("Abnormal program termination.\nPlease report bugs to ") EMAIL _T("\n")); + nRetCode = 1; +Exit: + return nRetCode; +} diff --git a/rosapps/sysutils/regexpl/RegistryExplorer.h b/rosapps/sysutils/regexpl/RegistryExplorer.h new file mode 100644 index 00000000000..3d2d4f0f98d --- /dev/null +++ b/rosapps/sysutils/regexpl/RegistryExplorer.h @@ -0,0 +1,29 @@ + +#ifndef _REGISTRY_EXPLORER_H__INCLUDED +#define _REGISTRY_EXPLORER_H__INCLUDED + +#define CURRENT_VERSION _T("0.10") +#define EMAIL _T("registryexplorer@yahoo.com") + +//#define __L(x) L ## x +//#define _L(x) __L(x) +/* +#define HELLO_MSG(date) _T("Registry Explorer for Microsoft Windows NT 4.0\n")\ + _T("Version ") CURRENT_VERSION _T(" Compiled on ") date _T("\n")\ + _T("Coded by Nedko Arnaoudov. This product is freeware.\n\n") +*/ +#define HELLO_MSG _T("Registry Explorer version ") CURRENT_VERSION _T(" for ReactOS\n")\ + _T("Coded by Nedko Arnaoudov. Licence is GNU GPL.\n\n") + +#define VER_MSG _T("Please report bugs to ") EMAIL _T("\n") + +#define GOODBYE_MSG _T("\nThank you for using Registry Explorer !!!\n") + +#define COMMAND_NA_ON_ROOT _T(" command is not applicable to root key.\n") + +//#define COMMAND_LENGTH(cmd) (sizeof(DIR_CMD)-sizeof(TCHAR))/sizeof(TCHAR) +#define COMMAND_LENGTH(cmd) _tcslen(cmd) + +#define PROMPT_BUFFER_SIZE 1024 + +#endif //#ifndef _REGISTRY_EXPLORER_H__INCLUDED diff --git a/rosapps/sysutils/regexpl/RegistryKey.cpp b/rosapps/sysutils/regexpl/RegistryKey.cpp new file mode 100644 index 00000000000..70e30254add --- /dev/null +++ b/rosapps/sysutils/regexpl/RegistryKey.cpp @@ -0,0 +1,441 @@ +/* $Id: RegistryKey.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// RegistryKey.cpp: implementation of the CRegistryKey class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "RegistryKey.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CRegistryKey::CRegistryKey(const TCHAR *pchKeyName, class CRegistryKey *pParent) +{ +// RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +// &m_dwValueNameBufferSize,&m_dwMaxValueSize,&m_dwSecurityDescriptorSize,&m_ftLastWriteTime); +// m_pchValueName = NULL; + ASSERT(pParent != NULL); + m_pParent = pParent; + m_pChild = NULL; + m_hKey = NULL; // Open key with Open() member function + ASSERT(pchKeyName != NULL); + m_pchKeyName[MAX_PATH] = 0; + *m_pszMachineName = 0; + if (*pchKeyName == _T('\"')) + { + _tcsncpy(m_pchKeyName,pchKeyName+1,MAX_PATH); + TCHAR *pch = _tcschr(m_pchKeyName,_T('\"')); + if (pch) + { + *pch = 0; + } + else + { + ASSERT(FALSE); + } + } + else + { + _tcsncpy(m_pchKeyName,pchKeyName,MAX_PATH); + } +} + +CRegistryKey::~CRegistryKey() +{ +// if (m_pchValueName) delete [] m_pchValueName; + if((m_hKey != HKEY_CLASSES_ROOT)&&(m_hKey != HKEY_CURRENT_USER)&& + (m_hKey != HKEY_LOCAL_MACHINE)&&(m_hKey != HKEY_USERS) + &&(m_hKey != HKEY_PERFORMANCE_DATA)&&(m_hKey != HKEY_CURRENT_CONFIG) + &&(m_hKey != HKEY_DYN_DATA)&&(m_hKey != NULL)) + { + RegCloseKey(m_hKey); + } +} + +TCHAR * CRegistryKey::GetKeyName() +{ + return m_pchKeyName; +} + +class CRegistryKey * CRegistryKey::GetChild() +{ + return m_pChild; +} + +CRegistryKey * CRegistryKey::GetParent() +{ + return m_pParent; +} + +CRegistryKey * CRegistryKey::UpOneLevel() +{ + CRegistryKey *pParent = m_pParent; + ASSERT(m_pChild == NULL); + if (pParent) + { + ASSERT(pParent->m_pChild == this); + pParent->m_pChild = NULL; + } + delete this; + return pParent; +} + +void CRegistryKey::InitSubKeyEnumeration() +{ + m_dwCurrentSubKeyIndex = 0; +} + +TCHAR * CRegistryKey::GetSubKeyName(DWORD& dwError) +{ + static TCHAR m_pchSubName[MAX_PATH+1]; + dwError = RegEnumKey(m_hKey,m_dwCurrentSubKeyIndex,m_pchSubName,MAX_PATH + 1); + m_dwCurrentSubKeyIndex++; + switch (dwError) + { + case ERROR_SUCCESS: + return m_pchSubName; + case ERROR_NO_MORE_ITEMS: + return NULL; + default: + return NULL; + } +} + +void CRegistryKey::UpdateKeyNameCase() +{ + m_pParent->InitSubKeyEnumeration(); + TCHAR *pchSubKeyName; + DWORD dwError; + while ((pchSubKeyName = m_pParent->GetSubKeyName(dwError)) != NULL) + { + if (dwError != ERROR_SUCCESS) + { + return; + } + if (_tcsicmp(pchSubKeyName,m_pchKeyName) == 0) + { + _tcscpy(m_pchKeyName,pchSubKeyName); + return; + } + } +} + +void CRegistryKey::InitValueEnumeration() +{ + m_dwCurrentValueIndex = 0; +} + + +// On input dwValueNameSize is size in characters of buffer pointed by pchValueNameBuffer +// On output dwValueNameSize contains number of characters stored in buffer +DWORD CRegistryKey::GetNextValue(TCHAR *pchValueNameBuffer,DWORD& dwValueNameSize, + DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize) +{ + DWORD dwRet = RegEnumValue(m_hKey,m_dwCurrentValueIndex,pchValueNameBuffer,&dwValueNameSize,NULL, + pdwType,lpValueDataBuffer,pdwValueDataSize); + m_dwCurrentValueIndex++; + return dwRet; +} + +void CRegistryKey::GetLastWriteTime(SYSTEMTIME &st) +{ + FILETIME ftLocal,ft; + RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + &ft); + FileTimeToLocalFileTime(&ft,&ftLocal); + FileTimeToSystemTime(&ftLocal,&st); +} + +TCHAR * CRegistryKey::GetLastWriteTime() +{ + SYSTEMTIME st; + GetLastWriteTime(st); + static TCHAR Buffer[256]; + _stprintf(Buffer,_T("%d.%d.%d %02d:%02d:%02d"),st.wDay,st.wMonth,st.wYear,st.wHour,st.wMinute,st.wSecond); + return Buffer; +} + +// Returns ErrorCode (ERROR_SUCCESS on success) +// dwMaxValueDataBuferSize receives the length, in bytes, +// of the longest data component among the key's values. +DWORD CRegistryKey::GetMaxValueDataSize(DWORD& dwMaxValueDataBuferSize) +{ + return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,&dwMaxValueDataBuferSize,NULL,NULL); +} + +// Returns ErrorCode (ERROR_SUCCESS on success) +// dwMaxValueNameBuferSize receives the length, in characters, +// of the key's longest value name. +// The count returned does not include the terminating null character. +DWORD CRegistryKey::GetMaxValueNameLength(DWORD& dwMaxValueNameBuferSize) +{ + return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + &dwMaxValueNameBuferSize,NULL,NULL,NULL); +} + +DWORD CRegistryKey::Open(REGSAM samDesired) +{ + if (IsPredefined()) + return ERROR_SUCCESS; + + DWORD dwRet; + HKEY hKey = NULL; + if (*m_pszMachineName) + { + ASSERT(ERROR_SUCCESS == 0); + dwRet = RegConnectRegistry(m_pszMachineName,m_hKey,&m_hKey); + } + else + { + ASSERT((m_hKey != HKEY_CLASSES_ROOT)&&(m_hKey != HKEY_CURRENT_USER)&& + (m_hKey != HKEY_LOCAL_MACHINE)&&(m_hKey != HKEY_USERS) + &&(m_hKey != HKEY_PERFORMANCE_DATA)&&(m_hKey != HKEY_CURRENT_CONFIG) + &&(m_hKey != HKEY_DYN_DATA)); + if (m_hKey) + { + RegCloseKey(m_hKey); + } + dwRet = RegOpenKeyEx(*m_pParent,m_pchKeyName,0,samDesired,&hKey); + } + if (dwRet == ERROR_SUCCESS) + { + m_hKey = hKey; + UpdateKeyNameCase(); + } + return dwRet; +} + +CRegistryKey::CRegistryKey(HKEY hKey, LPCTSTR pszMachineName) +{ + TCHAR *pchKeyName = NULL; + ASSERT((hKey == HKEY_CLASSES_ROOT)||(hKey == HKEY_CURRENT_USER)|| + (hKey == HKEY_LOCAL_MACHINE)||(hKey == HKEY_USERS) + ||(hKey == HKEY_PERFORMANCE_DATA)||(hKey == HKEY_CURRENT_CONFIG) + ||(hKey == HKEY_DYN_DATA)); + if(hKey == HKEY_CLASSES_ROOT) + { + pchKeyName = _T("HKEY_CLASSES_ROOT"); + } + else if(hKey == HKEY_CURRENT_USER) + { + pchKeyName = _T("HKEY_CURRENT_USER"); + } + else if (hKey == HKEY_LOCAL_MACHINE) + { + pchKeyName = _T("HKEY_LOCAL_MACHINE"); + } + else if (hKey == HKEY_USERS) + { + pchKeyName = _T("HKEY_USERS"); + } + else if (hKey == HKEY_PERFORMANCE_DATA) + { + pchKeyName = _T("HKEY_PERFORMANCE_DATA"); + } + else if (hKey == HKEY_CURRENT_CONFIG) + { + pchKeyName = _T("HKEY_CURRENT_CONFIG"); + } + else if (hKey == HKEY_DYN_DATA) + { + pchKeyName = _T("HKEY_DYN_DATA"); + } + else + { + ASSERT(FALSE); + return; + } + + m_hKey = hKey; + + m_pParent = NULL; + m_pChild = NULL; + ASSERT(pchKeyName != NULL); + m_pchKeyName[MAX_PATH] = 0; + _tcsncpy(m_pchKeyName,pchKeyName,MAX_PATH); + _tcsncpy(m_pszMachineName,pszMachineName?pszMachineName:_T(""),MAX_PATH); +} + +BOOL CRegistryKey::IsPredefined() +{ + return ((m_hKey == HKEY_CLASSES_ROOT)||(m_hKey == HKEY_CURRENT_USER)|| + (m_hKey == HKEY_LOCAL_MACHINE)||(m_hKey == HKEY_USERS) + ||(m_hKey == HKEY_PERFORMANCE_DATA)||(m_hKey == HKEY_CURRENT_CONFIG) + ||(m_hKey == HKEY_DYN_DATA)); +} + +DWORD CRegistryKey::GetDefaultValue(DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize) +{ + return RegQueryValueEx(m_hKey,NULL,NULL,pdwType,lpValueDataBuffer,pdwValueDataSize); +} + +void CRegistryKey::LinkParent() +{ + m_pParent->m_pChild = this; // self link +} + +const TCHAR * CRegistryKey::GetValueTypeName(DWORD dwType) +{ + switch(dwType) + { + case REG_NONE: + return _T("REG_NONE\t\t"); + case REG_SZ: + return _T("REG_SZ\t\t\t"); + case REG_EXPAND_SZ: + return _T("REG_EXPAND_SZ\t\t"); + case REG_BINARY: + return _T("REG_BINARY\t\t"); + case REG_DWORD_LITTLE_ENDIAN: + return _T("REG_DWORD_LITTLE_ENDIAN\t"); + case REG_DWORD_BIG_ENDIAN: + return _T("REG_DWORD_BIG_ENDIAN\t"); + case REG_LINK: + return _T("REG_LINK\t\t"); + case REG_MULTI_SZ: + return _T("REG_MULTI_SZ\t\t"); + case REG_RESOURCE_LIST: + return _T("REG_RESOURCE_LIST\t"); + case REG_FULL_RESOURCE_DESCRIPTOR: + return _T("REG_FULL_RESOURCE_DESCRIPTOR"); + case REG_RESOURCE_REQUIREMENTS_LIST: + return _T("REG_RESOURCE_REQUIREMENTS_LIST"); + default: + return _T("Unkown Type\t"); + } +} + +DWORD CRegistryKey::GetValue(TCHAR *pchValueName, DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize) +{ + return RegQueryValueEx(m_hKey,pchValueName,NULL,pdwType,lpValueDataBuffer,pdwValueDataSize); +} + +DWORD CRegistryKey::GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor) +{ + return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,pdwSecurityDescriptor,NULL); +} + +LONG CRegistryKey::GetSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor) +{ + return RegGetKeySecurity(m_hKey,SecurityInformation,pSecurityDescriptor,lpcbSecurityDescriptor); +} + +DWORD CRegistryKey::GetSubKeyCount() +{ + DWORD nCount; + DWORD nRet = RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,&nCount,NULL,NULL,NULL, + NULL,NULL,NULL,NULL); + if (nRet) + return 0; + return nCount; +} + +DWORD CRegistryKey::GetValuesCount() +{ + DWORD nCount; + if (RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL, + &nCount,NULL,NULL,NULL,NULL)) return 0; + return nCount; +} + +TCHAR * CRegistryKey::GetSubKeyNameByIndex(DWORD dwIndex) +{ + DWORD dwError; + static TCHAR m_pchSubName[MAX_PATH+1]; + dwError = RegEnumKey(m_hKey,dwIndex,m_pchSubName,MAX_PATH + 1); + switch (dwError) + { + case ERROR_SUCCESS: + return m_pchSubName; + case ERROR_NO_MORE_ITEMS: + return NULL; + default: + return NULL; + } +} + +DWORD CRegistryKey::Create(REGSAM samDesired, DWORD *pdwDisposition, BOOL blnVolatile) +{ + ASSERT((m_hKey != HKEY_CLASSES_ROOT)&&(m_hKey != HKEY_CURRENT_USER)&& + (m_hKey != HKEY_LOCAL_MACHINE)&&(m_hKey != HKEY_USERS) + &&(m_hKey != HKEY_PERFORMANCE_DATA)&&(m_hKey != HKEY_CURRENT_CONFIG) + &&(m_hKey != HKEY_DYN_DATA)); + if (m_hKey) + { + RegCloseKey(m_hKey); + } + + HKEY hKey; + + DWORD dwRet = RegCreateKeyEx(*m_pParent,m_pchKeyName,0,NULL, + blnVolatile?REG_OPTION_VOLATILE:REG_OPTION_NON_VOLATILE, + samDesired, + NULL, + &hKey, + pdwDisposition); + if (dwRet == ERROR_SUCCESS) + { + m_hKey = hKey; + UpdateKeyNameCase(); + } + return dwRet; +} + +DWORD CRegistryKey::DeleteSubkey(LPCTSTR pszSubKey, BOOL blnRecursive) +{ + CRegistryKey *pKey = new CRegistryKey(pszSubKey,this); + if (!pKey) + return ERROR_NOT_ENOUGH_MEMORY; + + DWORD dwRet = pKey->Open(KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE); + + if (!dwRet) + dwRet = pKey->Delete(blnRecursive); + + delete pKey; + + return dwRet; +} + +DWORD CRegistryKey::Delete(BOOL blnRecursive) +{ + DWORD dwRet; + if (blnRecursive) + { + // Delete childs + while(GetSubKeyCount()) + { + TCHAR *pchKeyName = GetSubKeyNameByIndex(0); + CRegistryKey *pKey = new CRegistryKey(pchKeyName,this); + if (!pKey) + return ERROR_NOT_ENOUGH_MEMORY; + + dwRet = pKey->Open(KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE); + + if (!dwRet) + dwRet = pKey->Delete(blnRecursive); + + delete pKey; + } + } + + // Delete yourself + return RegDeleteKey(m_pParent->m_hKey,m_pchKeyName); +} + +DWORD CRegistryKey::SetValue(LPCTSTR pszValueName, DWORD dwType, BYTE *lpData, DWORD dwDataSize) +{ + return RegSetValueEx(m_hKey,pszValueName,0,dwType,lpData,dwDataSize); +} diff --git a/rosapps/sysutils/regexpl/RegistryKey.h b/rosapps/sysutils/regexpl/RegistryKey.h new file mode 100644 index 00000000000..0530552d60d --- /dev/null +++ b/rosapps/sysutils/regexpl/RegistryKey.h @@ -0,0 +1,54 @@ +// RegistryKey.h: interface for the CRegistryKey class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(REGISTRYKEY_H__FEF419ED_6EB6_11D3_907D_204C4F4F5020__INCLUDED_) +#define REGISTRYKEY_H__FEF419ED_6EB6_11D3_907D_204C4F4F5020__INCLUDED_ + +class CRegistryKey +{ +public: + DWORD SetValue(LPCTSTR pszValueName, DWORD dwType, BYTE *lpData, DWORD dwDataSize); + DWORD Delete(BOOL blnRecursive); + DWORD DeleteSubkey(LPCTSTR pszSubKey, BOOL blnRecursive = FALSE); + DWORD Create(REGSAM samDesired, DWORD *pdwDisposition = NULL, BOOL blnVolatile = FALSE); + TCHAR * GetSubKeyNameByIndex(DWORD dwIndex); + DWORD GetValuesCount(); + DWORD GetSubKeyCount(); + LONG GetSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor); + DWORD GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor); + DWORD GetValue(TCHAR *pchValueName, DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize); + static const TCHAR * GetValueTypeName(DWORD dwType); + void LinkParent(); + DWORD GetDefaultValue(DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize); + BOOL IsPredefined(); + DWORD Open(REGSAM samDesired); + DWORD GetMaxValueNameLength(DWORD& dwMaxValueNameBuferSize); + DWORD GetMaxValueDataSize(DWORD& dwMaxValueDataBuferSize); + TCHAR * GetLastWriteTime(); + void GetLastWriteTime(SYSTEMTIME& st); + DWORD GetNextValue(TCHAR *pchValueNameBuffer,DWORD& dwValueNameSize, DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize); + void InitValueEnumeration(); + void UpdateKeyNameCase(); + TCHAR * GetSubKeyName(DWORD& dwError); + void InitSubKeyEnumeration(); + CRegistryKey * UpOneLevel(); + operator HKEY(){return m_hKey;}; + CRegistryKey * GetParent(); + class CRegistryKey * GetChild(); + TCHAR * GetKeyName(); + CRegistryKey(const TCHAR *pchKeyName, class CRegistryKey *pParent); + CRegistryKey(HKEY hKey, LPCTSTR pszMachineName = NULL); + virtual ~CRegistryKey(); +private: + DWORD m_dwCurrentSubKeyIndex; + DWORD m_dwCurrentValueIndex; + HKEY m_hKey; + class CRegistryKey *m_pChild; + class CRegistryKey *m_pParent; + TCHAR m_pchKeyName[MAX_PATH+1]; +// TCHAR *m_pchValueName; + TCHAR m_pszMachineName[MAX_PATH+1]; +}; + +#endif // !defined(REGISTRYKEY_H__FEF419ED_6EB6_11D3_907D_204C4F4F5020__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/RegistryTree.cpp b/rosapps/sysutils/regexpl/RegistryTree.cpp new file mode 100644 index 00000000000..9f6a9c85c7a --- /dev/null +++ b/rosapps/sysutils/regexpl/RegistryTree.cpp @@ -0,0 +1,434 @@ +/* $Id: RegistryTree.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// RegistryTree.cpp: implementation of the CRegistryTree class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "RegistryTree.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CRegistryTree::CRegistryTree(unsigned int nMaxPathSize) +{ + m_pszMachineName = NULL; + m_samDesiredOpenKeyAccess = 0; + m_pCurrentKey = m_pRoot = NULL; + m_ErrorMsg[ERROR_MSG_BUFFER_SIZE] = 0; + m_ChangeKeyBuffer = new TCHAR[nMaxPathSize]; +//#ifdef _DEBUG + m_nMaxPathSize = nMaxPathSize; +//#endif +} + +CRegistryTree::CRegistryTree(const CRegistryTree& Tree) +{ + m_pszMachineName = NULL; + m_samDesiredOpenKeyAccess = Tree.GetDesiredOpenKeyAccess(); + m_pCurrentKey = m_pRoot = NULL; + m_ErrorMsg[ERROR_MSG_BUFFER_SIZE] = 0; + m_ChangeKeyBuffer = new TCHAR[m_nMaxPathSize = Tree.m_nMaxPathSize]; + _tcscpy(m_ChangeKeyBuffer,Tree.GetCurrentPath()); + ChangeCurrentKey(m_ChangeKeyBuffer); +} + +CRegistryTree::~CRegistryTree() +{ + if (m_pszMachineName) + delete m_pszMachineName; + + CRegistryKey *pNode; + while(m_pRoot) + { + pNode = m_pRoot; + m_pRoot = m_pRoot->GetChild(); + delete pNode; + } + + delete [] m_ChangeKeyBuffer; +} + +const TCHAR * CRegistryTree::GetCurrentPath() const +{ + ASSERT(m_nMaxPathSize > 0); + unsigned int nBufferSize = m_nMaxPathSize; + CRegistryKey *pNode = m_pRoot; + + nBufferSize--; + m_ChangeKeyBuffer[nBufferSize] = 0; + + TCHAR *pchCurrentOffset = m_ChangeKeyBuffer; + + if (m_pszMachineName) + { + size_t m = _tcslen(m_pszMachineName+2); + if (m > nBufferSize) + { // No enough space in buffer to store machine name + ASSERT(FALSE); + } + else + { + _tcscpy(pchCurrentOffset,m_pszMachineName+2); + pchCurrentOffset += m; + nBufferSize -= m; + } + } + + if (2 > nBufferSize) + { // No enough space in buffer to store '\\' + ASSERT(FALSE); + } + else + { + *pchCurrentOffset = _T('\\'); + pchCurrentOffset++; + nBufferSize--; + } + + while(pNode) + { + TCHAR *pchKeyName = pNode->GetKeyName(); + unsigned int nKeyNameLength = _tcslen(pchKeyName); + if ((nKeyNameLength+1) > nBufferSize) + { // No enough space in buffer to store key name + '\\' + ASSERT(FALSE); + break; + } + _tcscpy(pchCurrentOffset,pchKeyName); + pchCurrentOffset[nKeyNameLength] = '\\'; + pchCurrentOffset += nKeyNameLength+1; + nBufferSize -= nKeyNameLength+1; + pNode = pNode->GetChild(); + } + *pchCurrentOffset = 0; + return m_ChangeKeyBuffer; +} + +BOOL CRegistryTree::IsCurrentRoot() +{ + return m_pRoot == NULL; +} + +// returns TRUE on success and FALSE on fail +// on fail, extended information can be received by calling GetLastErrorDescription(); +BOOL CRegistryTree::ChangeCurrentKey(const TCHAR *pchRelativePath) +{ + if (*pchRelativePath == _T('\\')) + { + CRegistryKey *pNode; + while(m_pRoot) + { + pNode = m_pRoot; + m_pRoot = m_pRoot->GetChild(); + delete pNode; + } + m_pCurrentKey = NULL; + } + TCHAR *pchSeps = _T("\\"); + + ASSERT(_tcslen(pchRelativePath) <= m_nMaxPathSize); + _tcscpy(m_ChangeKeyBuffer,pchRelativePath); + + TCHAR *pchNewKey = _tcstok(m_ChangeKeyBuffer,pchSeps); + + if ((!pchNewKey)&&((*pchRelativePath != _T('\\'))||(*(pchRelativePath+1) != 0))) + { + _tcscpy(m_ErrorMsg,_T("Invalid key name")); + return FALSE; + }; + while (pchNewKey) + { + HKEY hNewKey; + if (m_pRoot == NULL) + { // if this is the root key there are limations + if ((_tcsicmp(pchNewKey,_T("HKCR")) == 0)|| + (_tcsicmp(pchNewKey,_T("HKEY_CLASSES_ROOT")) == 0)) + { + hNewKey = HKEY_CLASSES_ROOT; + } + else if ((_tcsicmp(pchNewKey,_T("HKCU")) == 0)|| + (_tcsicmp(pchNewKey,_T("HKEY_CURRENT_USER")) == 0)) + { + hNewKey = HKEY_CURRENT_USER; + } + else if ((_tcsicmp(pchNewKey,_T("HKLM")) == 0)|| + (_tcsicmp(pchNewKey,_T("HKEY_LOCAL_MACHINE")) == 0)) + { + hNewKey = HKEY_LOCAL_MACHINE; + } + else if ((_tcsicmp(pchNewKey,_T("HKU")) == 0)|| + (_tcsicmp(pchNewKey,_T("HKEY_USERS")) == 0)) + { + hNewKey = HKEY_USERS; + } + else if ((_tcsicmp(pchNewKey,_T("HKPD")) == 0)|| + (_tcsicmp(pchNewKey,_T("HKEY_PERFORMANCE_DATA")) == 0)) + { + hNewKey = HKEY_PERFORMANCE_DATA; + } + else if ((_tcsicmp(pchNewKey,_T("HKDD")) == 0)|| + (_tcsicmp(pchNewKey,_T("HKEY_DYN_DATA")) == 0)) + { + hNewKey = HKEY_DYN_DATA; + } + else if ((_tcsicmp(pchNewKey,_T("HKCC")) == 0)|| + (_tcsicmp(pchNewKey,_T("HKEY_CURRENT_CONFIG")) == 0)) + { + hNewKey = HKEY_CURRENT_CONFIG; + } + else + { + _tcscpy(m_ErrorMsg,_T("Invalid key name.")); + return FALSE; + } + // Ok. Key to open is in hNewKey + + int nErr = ConnectRegistry(hNewKey); + if (nErr) + { + _stprintf(m_ErrorMsg,_T("Cannot connect registry. Error is %d"),nErr); + return FALSE; + } + } // if (m_pRoot == NULL) + else + { // current key is not root key + if (_tcsicmp(pchNewKey,_T("..")) == 0) + { + m_pCurrentKey = m_pCurrentKey->UpOneLevel(); + if (m_pCurrentKey == NULL) + { + m_pRoot = NULL; + } + } + else + { // Normal key name + CRegistryKey *pNewKey = new CRegistryKey(pchNewKey,m_pCurrentKey); + //RegOpenKeyExW(*m_pCurrentKey,pchNewKey,0,KEY_EXECUTE,&hNewKey) + DWORD dwError = pNewKey->Open(m_samDesiredOpenKeyAccess); + if (dwError != ERROR_SUCCESS) + { + TCHAR *pchPreErrorMsg = _T("Cannot open key : "), *pchCurrentOffset = m_ErrorMsg; + _tcscpy(pchCurrentOffset,pchPreErrorMsg); + pchCurrentOffset += _tcslen(pchPreErrorMsg); + + _tcscpy(pchCurrentOffset,pchNewKey); + pchCurrentOffset += _tcslen(pchNewKey); + + TCHAR *pchMsg = _T("\nError "); + _tcscpy(pchCurrentOffset,pchMsg); + pchCurrentOffset += _tcslen(pchMsg); + + TCHAR Buffer[256]; + _tcscpy(pchCurrentOffset,_itot(dwError,Buffer,10)); + pchCurrentOffset += _tcslen(Buffer); + + pchMsg = _T("\n"); + _tcscpy(pchCurrentOffset,pchMsg); + pchCurrentOffset += _tcslen(pchMsg); + switch(dwError) + { + case 5: + pchMsg = _T("(Access denied)"); + break; + case 2: + pchMsg = _T("(The system cannot find the key specified)"); + break; + } + + _tcscpy(pchCurrentOffset,pchMsg); + pchCurrentOffset += _tcslen(pchMsg); + + delete pNewKey; + + return FALSE; + } + pNewKey->LinkParent(); + m_pCurrentKey = pNewKey; + } + } + // Get next key name + pchNewKey = _tcstok(NULL,pchSeps); + } + return TRUE; +} + +TCHAR * CRegistryTree::GetLastErrorDescription() +{ + return m_ErrorMsg; +} + +CRegistryKey * CRegistryTree::GetCurrentKey() +{ + return m_pCurrentKey; +} + +void CRegistryTree::SetDesiredOpenKeyAccess(REGSAM samDesired) +{ + m_samDesiredOpenKeyAccess = samDesired; +} + +REGSAM CRegistryTree::GetDesiredOpenKeyAccess() const +{ + return m_samDesiredOpenKeyAccess; +} + +int CRegistryTree::ConnectRegistry(HKEY hKey) +{ + CRegistryKey *pKey = new CRegistryKey(hKey,m_pszMachineName); + int ret = pKey->Open(m_samDesiredOpenKeyAccess); + + if (ret == 0) + { + CRegistryKey *pNode; + while(m_pRoot) + { + pNode = m_pRoot; + m_pRoot = m_pRoot->GetChild(); + delete pNode; + } + m_pCurrentKey = NULL; + m_pRoot = m_pCurrentKey = pKey; + } + else + { + delete pKey; + } + + return ret; +} + +void CRegistryTree::SetMachineName(LPCTSTR pszMachineName) +{ + if (m_pszMachineName) + delete m_pszMachineName; + + if (pszMachineName == NULL) + { + m_pszMachineName = NULL; + return; + } + + while ((*pszMachineName)&&(*pszMachineName == _T('\\'))) + pszMachineName++; + + if (*pszMachineName == 0) + { + ASSERT(FALSE); + } + + m_pszMachineName = new TCHAR[_tcslen(pszMachineName)+3]; + _tcscpy(m_pszMachineName,_T("\\\\")); + _tcscpy(m_pszMachineName+2,pszMachineName); + _tcsupr(m_pszMachineName+2); +} + +BOOL CRegistryTree::NewKey(const TCHAR *pchKeyName, BOOL blnVolatile) +{ + CRegistryKey *pNewKey = new CRegistryKey(pchKeyName,m_pCurrentKey); + DWORD dwDisposition; + DWORD dwError = pNewKey->Create(0,&dwDisposition,blnVolatile); + switch (dwDisposition) + { + case REG_OPENED_EXISTING_KEY: + _sntprintf(m_ErrorMsg,ERROR_MSG_BUFFER_SIZE,_T("A key \"%s\" already exists."),pchKeyName); + delete pNewKey; + return FALSE; + case REG_CREATED_NEW_KEY: + break; + default: + ASSERT(FALSE); + } + if (dwError != ERROR_SUCCESS) + { + TCHAR *pchCurrentOffset = m_ErrorMsg; + TCHAR *pchPreErrorMsg = _T("Cannot create key : "); + _tcscpy(pchCurrentOffset,pchPreErrorMsg); + pchCurrentOffset += _tcslen(pchPreErrorMsg); + + _tcscpy(pchCurrentOffset,pchKeyName); + pchCurrentOffset += _tcslen(pchKeyName); + + TCHAR *pchMsg = _T("\nError "); + _tcscpy(pchCurrentOffset,pchMsg); + pchCurrentOffset += _tcslen(pchMsg); + + TCHAR Buffer[256]; + _tcscpy(pchCurrentOffset,_itot(dwError,Buffer,10)); + pchCurrentOffset += _tcslen(Buffer); + + pchMsg = _T("\n"); + _tcscpy(pchCurrentOffset,pchMsg); + pchCurrentOffset += _tcslen(pchMsg); + switch(dwError) + { + case 5: + pchMsg = _T("(Access denied)"); + break; + case 2: + pchMsg = _T("(The system cannot find the key specified)"); + break; + } + + _tcscpy(pchCurrentOffset,pchMsg); + pchCurrentOffset += _tcslen(pchMsg); + + delete pNewKey; + + return FALSE; + } + + delete pNewKey; + + return TRUE; +} + +BOOL CRegistryTree::DeleteKey(const TCHAR *pchKeyName, BOOL blnRecursive) +{ + DWORD dwError = m_pCurrentKey->DeleteSubkey(pchKeyName,blnRecursive); + if (dwError != ERROR_SUCCESS) + { + TCHAR *pchPreErrorMsg = _T("Cannot open key : "), *pchCurrentOffset = m_ErrorMsg; + _tcscpy(pchCurrentOffset,pchPreErrorMsg); + pchCurrentOffset += _tcslen(pchPreErrorMsg); + + _tcscpy(pchCurrentOffset,pchKeyName); + pchCurrentOffset += _tcslen(pchKeyName); + + TCHAR *pchMsg = _T("\nError "); + _tcscpy(pchCurrentOffset,pchMsg); + pchCurrentOffset += _tcslen(pchMsg); + + TCHAR Buffer[256]; + _tcscpy(pchCurrentOffset,_itot(dwError,Buffer,10)); + pchCurrentOffset += _tcslen(Buffer); + + pchMsg = _T("\n"); + _tcscpy(pchCurrentOffset,pchMsg); + pchCurrentOffset += _tcslen(pchMsg); + switch(dwError) + { + case 5: + pchMsg = _T("(Access denied)"); + break; + case 2: + pchMsg = _T("(The system cannot find the key specified)"); + break; + } + + _tcscpy(pchCurrentOffset,pchMsg); + pchCurrentOffset += _tcslen(pchMsg); + + return FALSE; + } + return TRUE; +} diff --git a/rosapps/sysutils/regexpl/RegistryTree.h b/rosapps/sysutils/regexpl/RegistryTree.h new file mode 100644 index 00000000000..c0a94e9c05b --- /dev/null +++ b/rosapps/sysutils/regexpl/RegistryTree.h @@ -0,0 +1,43 @@ +// RegistryTree.h: interface for the CRegistryTree class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(REGISTRYTREE_H__239A6461_70F2_11D3_9085_204C4F4F5020__INCLUDED_) +#define REGISTRYTREE_H__239A6461_70F2_11D3_9085_204C4F4F5020__INCLUDED_ + +#include "RegistryKey.h" + +#define ERROR_MSG_BUFFER_SIZE 1024 + +class CRegistryTree +{ +public: + BOOL DeleteKey(const TCHAR *pchKeyName, BOOL blnRecursive = FALSE); + BOOL NewKey(const TCHAR *pchKeyName, BOOL blnVolatile = FALSE); + void SetMachineName(LPCTSTR pszMachineName); + int ConnectRegistry(HKEY hKey); + REGSAM GetDesiredOpenKeyAccess() const; + void SetDesiredOpenKeyAccess(REGSAM samDesired); + CRegistryKey * GetCurrentKey(); + TCHAR * GetLastErrorDescription(); + BOOL ChangeCurrentKey(const TCHAR *pchRelativePath); + BOOL IsCurrentRoot(); + const TCHAR * GetCurrentPath() const; + + // Constructor + // Parameters: + // nMaxPathSize - size in characters of longest path including terminating NULL char + CRegistryTree(unsigned int nMaxPathSize); + CRegistryTree(const CRegistryTree& Tree); + + virtual ~CRegistryTree(); +private: + unsigned int m_nMaxPathSize; + TCHAR *m_ChangeKeyBuffer; + CRegistryKey *m_pRoot, *m_pCurrentKey; + TCHAR m_ErrorMsg[ERROR_MSG_BUFFER_SIZE+1]; + REGSAM m_samDesiredOpenKeyAccess; + LPTSTR m_pszMachineName; +}; + +#endif // !defined(REGISTRYTREE_H__239A6461_70F2_11D3_9085_204C4F4F5020__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/SecurityDescriptor.cpp b/rosapps/sysutils/regexpl/SecurityDescriptor.cpp new file mode 100644 index 00000000000..e2685ad1a94 --- /dev/null +++ b/rosapps/sysutils/regexpl/SecurityDescriptor.cpp @@ -0,0 +1,313 @@ +/* $Id: SecurityDescriptor.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// SecurityDescriptor.cpp: implementation of the CSecurityDescriptor class. +// +////////////////////////////////////////////////////////////////////// + +#include +#include +#include "SecurityDescriptor.h" + +#define ASSERT assert + +// *** THIS SHOULD GO IN A MINGW/ROS HEADER - Begin +#if 1 + +#define SID_REVISION (1) // Current revision level + +//typedef struct _ACE_HEADER { +// BYTE AceType; +// BYTE AceFlags; +// WORD AceSize; +//} ACE_HEADER; +typedef ACE_HEADER * PACE_HEADER; + +//#define ACCESS_ALLOWED_ACE_TYPE (0x0) +//#define ACCESS_DENIED_ACE_TYPE (0x1) +//#define SYSTEM_AUDIT_ACE_TYPE (0x2) +//#define SYSTEM_ALARM_ACE_TYPE (0x3) + +//#define OBJECT_INHERIT_ACE (0x1) +//#define CONTAINER_INHERIT_ACE (0x2) +//#define NO_PROPAGATE_INHERIT_ACE (0x4) +//#define INHERIT_ONLY_ACE (0x8) +//#define VALID_INHERIT_FLAGS (0xF) + +//#define SUCCESSFUL_ACCESS_ACE_FLAG (0x40) +//#define FAILED_ACCESS_ACE_FLAG (0x80) + +typedef struct _SYSTEM_AUDIT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; +} SYSTEM_AUDIT_ACE; + +#endif +// *** THIS SHOULD GO IN A MINGW/ROS HEADER - End + + +BOOL GetTextualSid( + PSID pSid, // binary Sid + LPTSTR TextualSid, // buffer for Textual representation of Sid + LPDWORD lpdwBufferLen // required/provided TextualSid buffersize + ) +{ + PSID_IDENTIFIER_AUTHORITY psia; + DWORD dwSubAuthorities; + DWORD dwSidRev=SID_REVISION; + DWORD dwCounter; + DWORD dwSidSize; + + // Validate the binary SID. + + if(!IsValidSid(pSid)) return FALSE; + + // Get the identifier authority value from the SID. + + psia = GetSidIdentifierAuthority(pSid); + + // Get the number of subauthorities in the SID. + + dwSubAuthorities = *GetSidSubAuthorityCount(pSid); + + // Compute the buffer length. + // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL + + dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR); + + // Check input buffer length. + // If too small, indicate the proper size and set last error. + + if (*lpdwBufferLen < dwSidSize) + { + *lpdwBufferLen = dwSidSize; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + // Add 'S' prefix and revision number to the string. + + dwSidSize=wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev ); + + // Add SID identifier authority to the string. + + if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) + { + dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid), + TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"), + (USHORT)psia->Value[0], + (USHORT)psia->Value[1], + (USHORT)psia->Value[2], + (USHORT)psia->Value[3], + (USHORT)psia->Value[4], + (USHORT)psia->Value[5]); + } + else + { + dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid), + TEXT("%lu"), + (ULONG)(psia->Value[5] ) + + (ULONG)(psia->Value[4] << 8) + + (ULONG)(psia->Value[3] << 16) + + (ULONG)(psia->Value[2] << 24) ); + } + + // Add SID subauthorities to the string. + // + for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++) + { + dwSidSize+=wsprintf(TextualSid + dwSidSize, TEXT("-%lu"), + *GetSidSubAuthority(pSid, dwCounter) ); + } + + return TRUE; +} + +const TCHAR * GetSidTypeName(SID_NAME_USE Use) +{ + switch(Use) + { + case SidTypeUser: + return _T("User SID"); + case SidTypeGroup: + return _T("Group SID"); + case SidTypeDomain: + return _T("Domain SID"); + case SidTypeAlias: + return _T("Alias SID"); + case SidTypeWellKnownGroup: + return _T("SID for a well-known group"); + case SidTypeDeletedAccount: + return _T("SID for a deleted account"); + case SidTypeInvalid: + return _T("Invalid SID"); + case SidTypeUnknown: + return _T("Unknown SID type"); + default: + return _T("Error. Cannot recognize SID type."); + } +} + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CSecurityDescriptor::CSecurityDescriptor() +{ + m_pSecurityDescriptor = NULL; + m_pCurrentACEHeader = NULL; +} + +CSecurityDescriptor::~CSecurityDescriptor() +{ +} + +void CSecurityDescriptor::AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor) +{ + m_pSecurityDescriptor = pSecurityDescriptor; +} + +DWORD CSecurityDescriptor::BeginDACLInteration() +{ + if (!GetSecurityDescriptorDacl(m_pSecurityDescriptor,&m_blnDACLPresent,&m_pDACL,&m_blnDACLDefaulted)) + { + throw GetLastError(); + } + return ERROR_SUCCESS; +} + +BOOL CSecurityDescriptor::DescriptorContainsDACL() +{ + return m_blnDACLPresent; +} + +DWORD CSecurityDescriptor::BeginSACLInteration() +{ + if (!GetSecurityDescriptorSacl(m_pSecurityDescriptor,&m_blnSACLPresent,&m_pSACL,&m_blnSACLDefaulted)) + throw GetLastError(); + return ERROR_SUCCESS; +} + +BOOL CSecurityDescriptor::DescriptorContainsSACL() +{ + return m_blnSACLPresent; +} + +BOOL CSecurityDescriptor::HasNULLDACL() +{ + ASSERT(m_blnDACLPresent); + return (m_pDACL == NULL); +} + +BOOL CSecurityDescriptor::HasValidDACL() +{ + ASSERT(m_blnDACLPresent); + ASSERT(m_pDACL != NULL); + return IsValidAcl(m_pDACL); +} + +BOOL CSecurityDescriptor::HasNULLSACL() +{ + ASSERT(m_blnSACLPresent); + return (m_pSACL == NULL); +} + +BOOL CSecurityDescriptor::HasValidSACL() +{ + ASSERT(m_blnSACLPresent); + ASSERT(m_pSACL != NULL); + return IsValidAcl(m_pSACL); +} + +DWORD CSecurityDescriptor::GetDACLEntriesCount() +{ + ACL_SIZE_INFORMATION SizeInfo; + if (!GetAclInformation(m_pDACL,&SizeInfo,sizeof(SizeInfo),AclSizeInformation)) + throw GetLastError(); + return SizeInfo.AceCount; +} + +DWORD CSecurityDescriptor::GetSACLEntriesCount() +{ + ACL_SIZE_INFORMATION SizeInfo; + if (!GetAclInformation(m_pSACL,&SizeInfo,sizeof(SizeInfo),AclSizeInformation)) + throw GetLastError(); + return SizeInfo.AceCount; +} + +CSecurityDescriptor::ACEntryType CSecurityDescriptor::GetDACLEntry(DWORD nIndex) +{ + void *pACE; + if (!GetAce(m_pDACL,nIndex,&pACE)) throw GetLastError(); + m_pCurrentACEHeader = (PACE_HEADER)pACE; + if (m_pCurrentACEHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) + { + return AccessAlowed; + } + if (m_pCurrentACEHeader->AceType == ACCESS_DENIED_ACE_TYPE) + { + return AccessDenied; + } + return Unknown; +} + +CSecurityDescriptor::ACEntryType CSecurityDescriptor::GetSACLEntry(DWORD nIndex, BOOL& blnFailedAccess, BOOL& blnSeccessfulAccess) +{ + void *pACE; + if (!GetAce(m_pSACL,nIndex,&pACE)) throw GetLastError(); + m_pCurrentACEHeader = (PACE_HEADER)pACE; + if (m_pCurrentACEHeader->AceType == SYSTEM_AUDIT_ACE_TYPE) + { + blnFailedAccess = m_pCurrentACEHeader->AceFlags & FAILED_ACCESS_ACE_FLAG; + blnSeccessfulAccess = m_pCurrentACEHeader->AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG; + return SystemAudit; + } + return Unknown; +} + +PSID CSecurityDescriptor::GetCurrentACE_SID() +{ + ASSERT(m_pCurrentACEHeader != NULL); + switch(m_pCurrentACEHeader->AceType) + { + case ACCESS_ALLOWED_ACE_TYPE: + return ((PSID)&(((ACCESS_ALLOWED_ACE *)m_pCurrentACEHeader)->SidStart)); + case ACCESS_DENIED_ACE_TYPE: + return ((PSID)&(((ACCESS_DENIED_ACE *)m_pCurrentACEHeader)->SidStart)); + case SYSTEM_AUDIT_ACE_TYPE: + return ((PSID)&(((SYSTEM_AUDIT_ACE *)m_pCurrentACEHeader)->SidStart)); + default: + ASSERT(FALSE); // Do not call this function for unknown ACE types !!! + return NULL; + } +} + +void CSecurityDescriptor::GetCurrentACE_AccessMask(DWORD& dwMask) +{ + ASSERT(m_pCurrentACEHeader != NULL); + switch(m_pCurrentACEHeader->AceType) + { + case ACCESS_ALLOWED_ACE_TYPE: + dwMask = (((ACCESS_ALLOWED_ACE *)m_pCurrentACEHeader)->Mask); + return; + case ACCESS_DENIED_ACE_TYPE: + dwMask = (((ACCESS_DENIED_ACE *)m_pCurrentACEHeader)->Mask); + return; + case SYSTEM_AUDIT_ACE_TYPE: + dwMask = (((SYSTEM_AUDIT_ACE *)m_pCurrentACEHeader)->Mask); + return; + default: + ASSERT(FALSE); // Do not call this function for unknown ACE types !!! + return; + } +} + + diff --git a/rosapps/sysutils/regexpl/SecurityDescriptor.h b/rosapps/sysutils/regexpl/SecurityDescriptor.h new file mode 100644 index 00000000000..898ad899a18 --- /dev/null +++ b/rosapps/sysutils/regexpl/SecurityDescriptor.h @@ -0,0 +1,54 @@ +// SecurityDescriptor.h: interface for the CSecurityDescriptor class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SECURITYDESCRIPTOR_H__71D0A7E6_8A00_11D3_9103_204C4F4F5020__INCLUDED_) +#define SECURITYDESCRIPTOR_H__71D0A7E6_8A00_11D3_9103_204C4F4F5020__INCLUDED_ + +BOOL GetTextualSid( + PSID pSid, // binary Sid + LPTSTR TextualSid, // buffer for Textual representation of Sid + LPDWORD lpdwBufferLen // required/provided TextualSid buffersize + ); + +const TCHAR * GetSidTypeName(SID_NAME_USE Use); + +class CSecurityDescriptor +{ +public: + void GetCurrentACE_AccessMask(DWORD& dwMask); + PSID GetCurrentACE_SID(); + enum ACEntryType + { + Unknown, + AccessAlowed, + AccessDenied, + SystemAudit + }; + ACEntryType GetDACLEntry(DWORD nIndex); + ACEntryType GetSACLEntry(DWORD nIndex, BOOL& blnFailedAccess, BOOL& blnSeccessfulAccess); + DWORD GetDACLEntriesCount(); + DWORD GetSACLEntriesCount(); + BOOL HasValidDACL(); + BOOL HasNULLDACL(); + BOOL HasValidSACL(); + BOOL HasNULLSACL(); + BOOL DescriptorContainsDACL(); + BOOL DescriptorContainsSACL(); + DWORD BeginDACLInteration(); + DWORD BeginSACLInteration(); + void AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor); + CSecurityDescriptor(); + virtual ~CSecurityDescriptor(); +private: + PSECURITY_DESCRIPTOR m_pSecurityDescriptor; + BOOL m_blnDACLPresent; + BOOL m_blnDACLDefaulted; + PACL m_pDACL; + BOOL m_blnSACLPresent; + BOOL m_blnSACLDefaulted; + PACL m_pSACL; + ACE_HEADER *m_pCurrentACEHeader; +}; + +#endif // !defined(SECURITYDESCRIPTOR_H__71D0A7E6_8A00_11D3_9103_204C4F4F5020__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommand.cpp b/rosapps/sysutils/regexpl/ShellCommand.cpp new file mode 100644 index 00000000000..8c95be0c722 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommand.cpp @@ -0,0 +1,30 @@ +/* $Id: ShellCommand.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// ShellCommand.cpp: implementation of the CShellCommand class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "ShellCommand.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CShellCommand::CShellCommand() +{ + +} + +CShellCommand::~CShellCommand() +{ + +} diff --git a/rosapps/sysutils/regexpl/ShellCommand.h b/rosapps/sysutils/regexpl/ShellCommand.h new file mode 100644 index 00000000000..6f68b3f4a97 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommand.h @@ -0,0 +1,23 @@ +// ShellCommand.h: interface for the CShellCommand class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMAND_H__D29C1193_5942_11D4_A037_C5AC8D00940F__INCLUDED_) +#define SHELLCOMMAND_H__D29C1193_5942_11D4_A037_C5AC8D00940F__INCLUDED_ + +#include "Console.h" +#include "ArgumentParser.h" + +// this class provides common interface to shell commands +class CShellCommand +{ +public: + CShellCommand(); + virtual ~CShellCommand(); + virtual BOOL Match(const TCHAR *pchCommand) = 0; + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments) = 0; + virtual const TCHAR * GetHelpString() = 0; + virtual const TCHAR * GetHelpShortDescriptionString() = 0; +}; + +#endif // !defined(SHELLCOMMAND_H__D29C1193_5942_11D4_A037_C5AC8D00940F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp b/rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp new file mode 100644 index 00000000000..076fcd7b127 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp @@ -0,0 +1,92 @@ +/* $Id: ShellCommandChangeKey.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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(" \n\n") + _T(" - Relative path of desired key.\n\n") + _T("Without parameters, command displays this help.\n"); + +} + +const TCHAR * CShellCommandChangeKey::GetHelpShortDescriptionString() +{ + return CD_CMD_SHORT_DESC; +} + diff --git a/rosapps/sysutils/regexpl/ShellCommandChangeKey.h b/rosapps/sysutils/regexpl/ShellCommandChangeKey.h new file mode 100644 index 00000000000..e5e4cb19321 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandChangeKey.h @@ -0,0 +1,24 @@ +// ShellCommandChangeKey.h: interface for the CShellCommandChangeKey class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDCHANGEKEY_H__848A2506_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDCHANGEKEY_H__848A2506_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandChangeKey : public CShellCommand +{ +public: + CShellCommandChangeKey(CRegistryTree& rTree); + virtual ~CShellCommandChangeKey(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDCHANGEKEY_H__848A2506_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandConnect.cpp b/rosapps/sysutils/regexpl/ShellCommandConnect.cpp new file mode 100644 index 00000000000..74262012dd8 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandConnect.cpp @@ -0,0 +1,86 @@ +/* $Id: ShellCommandConnect.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// ShellCommandConnect.cpp: implementation of the CShellCommandConnect class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "ShellCommandConnect.h" + +#define CONNECT_CMD _T("CONNECT") +#define CONNECT_CMD_SHORT_DESC CONNECT_CMD _T(" command is used to connect to remote registry.\n") + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CShellCommandConnect::CShellCommandConnect(CRegistryTree& rTree):m_rTree(rTree) +{ +} + +CShellCommandConnect::~CShellCommandConnect() +{ +} + +BOOL CShellCommandConnect::Match(const TCHAR *pchCommand) +{ + return _tcsicmp(pchCommand,CONNECT_CMD) == 0; +} + +int CShellCommandConnect::Execute(CConsole &rConsole, CArgumentParser& rArguments) +{ + const TCHAR *pchArg; + const TCHAR *pchMachine = NULL; + BOOL blnHelp = FALSE; + + VERIFY(m_rTree.ChangeCurrentKey(_T("\\"))); + + while ((pchArg = rArguments.GetNextArgument()) != NULL) + { + if ((_tcsicmp(pchArg,_T("/?")) == 0) + ||(_tcsicmp(pchArg,_T("-?")) == 0)) + { + blnHelp = TRUE; + } +// else if ((_tcsicmp(pchArg,_T("-a")) == 0)|| +// (_tcsicmp(pchArg,_T("/a")) == 0)) +// { +// } + else + { + pchMachine = pchArg; + } + } + + if (blnHelp) + rConsole.Write(GetHelpString()); + + m_rTree.SetMachineName(pchMachine); + return 0; +} + +const TCHAR * CShellCommandConnect::GetHelpString() +{ + return CONNECT_CMD_SHORT_DESC +// _T("Syntax: ") CONNECT_CMD _T(" [Switches] [/?] machine\n\n") + _T("Syntax: ") CONNECT_CMD _T(" /? | MACHINE\n\n") + _T(" /? - This help.\n\n") +// _T("Switches are:\n") +// _T(" -a anonymous login.\n") + _T(" MACHINE is name/ip of the remote machine.\n") + _T("Example:\n") + _T(" ") CONNECT_CMD _T(" BOB"); +} + +const TCHAR * CShellCommandConnect::GetHelpShortDescriptionString() +{ + return CONNECT_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandConnect.h b/rosapps/sysutils/regexpl/ShellCommandConnect.h new file mode 100644 index 00000000000..3bada8ff4b9 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandConnect.h @@ -0,0 +1,24 @@ +// ShellCommandConnect.h: interface for the CShellCommandConnect class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDCONNECT_H__848A250C_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDCONNECT_H__848A250C_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandConnect : public CShellCommand +{ +public: + CShellCommandConnect(CRegistryTree& rTree); + virtual ~CShellCommandConnect(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDCONNECT_H__848A250C_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandDACL.cpp b/rosapps/sysutils/regexpl/ShellCommandDACL.cpp new file mode 100644 index 00000000000..4e006d23cf4 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDACL.cpp @@ -0,0 +1,362 @@ +/* $Id: ShellCommandDACL.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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(" [] [/?]\n\n") + _T(" - Optional relative path of desired key.\n") + _T(" /? - This help.\n\n") + _T("Without parameters, command displays DACL of current key.\n"); +} + +const TCHAR * CShellCommandDACL::GetHelpShortDescriptionString() +{ + return DACL_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandDACL.h b/rosapps/sysutils/regexpl/ShellCommandDACL.h new file mode 100644 index 00000000000..40a0476d5e9 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDACL.h @@ -0,0 +1,24 @@ +// ShellCommandDACL.h: interface for the CShellCommandDACL class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDDACL_H__848A2509_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDDACL_H__848A2509_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandDACL : public CShellCommand +{ +public: + CShellCommandDACL(CRegistryTree& rTree); + virtual ~CShellCommandDACL(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDDACL_H__848A2509_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandDOKA.cpp b/rosapps/sysutils/regexpl/ShellCommandDOKA.cpp new file mode 100644 index 00000000000..db29f82f7d7 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDOKA.cpp @@ -0,0 +1,242 @@ +/* $Id: ShellCommandDOKA.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// ShellCommandDOKA.cpp: implementation of the CShellCommandDOKA class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "ShellCommandDOKA.h" +#include "RegistryExplorer.h" +#include "SecurityDescriptor.h" + +#define DOKA_CMD _T("DOKA") +#define DOKA_CMD_SHORT_DESC DOKA_CMD _T(" command is used to view/edit Desired Open Key Access.\n") + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CShellCommandDOKA::CShellCommandDOKA(CRegistryTree& rTree):m_rTree(rTree) +{ +} + +CShellCommandDOKA::~CShellCommandDOKA() +{ +} + +BOOL CShellCommandDOKA::Match(const TCHAR *pchCommand) +{ + return _tcsicmp(pchCommand,DOKA_CMD) == 0; +} + +int CShellCommandDOKA::Execute(CConsole &rConsole, CArgumentParser& rArguments) +{ + REGSAM Access = m_rTree.GetDesiredOpenKeyAccess(); + const TCHAR *pchParameter; + BOOL blnBadParameter = FALSE; + BOOL blnHelp = FALSE; + + while((pchParameter = rArguments.GetNextArgument()) != NULL) + { + blnBadParameter = FALSE; +// Console.Write(_T("Processing parameter: \")"); +// Console.Write(pchParameter); +// Console.Write(_T("\")\n"); + if ((_tcsicmp(pchParameter,_T("/?")) == 0) + ||(_tcsicmp(pchParameter,_T("-?")) == 0)) + { + blnHelp = TRUE; + } + else if (*pchParameter == _T('-')) + { + TCHAR a = *(pchParameter+1); + if (a == 0) + { + Access = 0; + } + else + { + if (*(pchParameter+2) != 0) + { + blnBadParameter = TRUE; + } + else + { + switch(a) + { + case _T('l'): // KEY_CREATE_LINK + case _T('L'): + Access &= ~KEY_CREATE_LINK; + break; + case _T('c'): // KEY_CREATE_SUB_KEY + case _T('C'): + Access &= ~KEY_CREATE_SUB_KEY; + break; + case _T('e'): // KEY_ENUMERATE_SUB_KEYS + case _T('E'): + Access &= ~KEY_ENUMERATE_SUB_KEYS; + break; + case _T('n'): // KEY_NOTIFY + case _T('N'): + Access &= ~KEY_NOTIFY; + break; + case _T('q'): // KEY_QUERY_VALUE + case _T('Q'): + Access &= ~KEY_QUERY_VALUE; + break; + case _T('s'): // KEY_SET_VALUE + case _T('S'): + Access &= ~KEY_SET_VALUE; + break; + default: + blnBadParameter = TRUE; + } // switch + } // else (*(pchParameter+2) != 0) + } // else (a == 0) + } // if (*pchParameter == _T('-')) + else if (*pchParameter == _T('+')) + { + TCHAR a = *(pchParameter+1); + if (a == 0) + { + blnBadParameter = TRUE; + } + else + { + if (*(pchParameter+2) != 0) + { + blnBadParameter = TRUE; + } + else + { + switch(a) + { + case _T('a'): // KEY_ALL_ACCESS + case _T('A'): + Access |= KEY_ALL_ACCESS; + break; + case _T('l'): // KEY_CREATE_LINK + case _T('L'): + Access |= KEY_CREATE_LINK; + break; + case _T('c'): // KEY_CREATE_SUB_KEY + case _T('C'): + Access |= KEY_CREATE_SUB_KEY; + break; + case _T('e'): // KEY_ENUMERATE_SUB_KEYS + case _T('E'): + Access |= KEY_ENUMERATE_SUB_KEYS; + break; + case _T('n'): // KEY_NOTIFY + case _T('N'): + Access |= KEY_NOTIFY; + break; + case _T('q'): // KEY_QUERY_VALUE + case _T('Q'): + Access |= KEY_QUERY_VALUE; + break; + case _T('s'): // KEY_SET_VALUE + case _T('S'): + Access |= KEY_SET_VALUE; + break; +// case _T('X'): // KEY_EXECUTE +// case _T('x'): +// Access |= KEY_EXECUTE; +// break; + case _T('R'): // KEY_READ + case _T('r'): + Access |= KEY_READ; + break; + default: + blnBadParameter = TRUE; + } // switch + } // else (*(pchParameter+2) != 0) + } // else (a == 0) + } // if (*pchParameter == _T('-')) + else + { + blnBadParameter = TRUE; + } + + if (blnBadParameter) + { + rConsole.Write(_T("Bad parameter: ")); + rConsole.Write(pchParameter); + rConsole.Write(_T("\n")); + blnHelp = TRUE; + } + } // while((pchParameter = Parser.GetNextArgument()) != NULL) + + if (blnHelp) + { + rConsole.Write(GetHelpString()); + } + else + { + m_rTree.SetDesiredOpenKeyAccess(Access); + rConsole.Write(_T("Desired open key access:\n")); + REGSAM Access = m_rTree.GetDesiredOpenKeyAccess(); + if (Access & KEY_CREATE_LINK) + { + rConsole.Write(_T("\tKEY_CREATE_LINK - Permission to create a symbolic link.\n")); + } + if (Access & KEY_CREATE_SUB_KEY) + { + rConsole.Write(_T("\tKEY_CREATE_SUB_KEY - Permission to create subkeys.\n")); + } + if (Access & KEY_ENUMERATE_SUB_KEYS) + { + rConsole.Write(_T("\tKEY_ENUMERATE_SUB_KEYS - Permission to enumerate subkeys.\n")); + } + if (Access & KEY_NOTIFY) + { + rConsole.Write(_T("\tKEY_NOTIFY - Permission for change notification.\n")); + } + if (Access & KEY_QUERY_VALUE) + { + rConsole.Write(_T("\tKEY_QUERY_VALUE - Permission to query subkey data.\n")); + } + if (Access & KEY_SET_VALUE) + { + rConsole.Write(_T("\tKEY_SET_VALUE - Permission to set subkey data.\n")); + } + } + return 0; +} + +const TCHAR * CShellCommandDOKA::GetHelpString() +{ + return DOKA_CMD_SHORT_DESC + _T("Syntax: ") DOKA_CMD _T(" [Switches] [/?]\n\n") + _T(" /? - This help.\n\n") + _T("Switches are:\n") + _T(" - - Reset all permisions.\n") + _T(" -l - Reset permission to create a symbolic link.\n") + _T(" -c - Reset permission to create subkeys.\n") + _T(" -e - Reset permission to enumerate subkeys.\n") + _T(" -n - Reset permission for change notification.\n") + _T(" -q - Reset permission to query subkey data.\n") + _T(" -s - Reset permission to set subkey data.\n") + _T(" +a - Set all permisions.\n") + _T(" +l - Set permission to create a symbolic link.\n") + _T(" +c - Set permission to create subkeys.\n") + _T(" +e - Set permission to enumerate subkeys.\n") + _T(" +n - Set permission for change notification.\n") + _T(" +q - Set permission to query subkey data.\n") + _T(" +s - Set permission to set subkey data.\n") + _T(" +r - Equivalent to combination of +q , +e and +n\n\n") + _T("Without parameters, command displays current Desired Open Key Access.\n"); +} + +const TCHAR * CShellCommandDOKA::GetHelpShortDescriptionString() +{ + return DOKA_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandDOKA.h b/rosapps/sysutils/regexpl/ShellCommandDOKA.h new file mode 100644 index 00000000000..874dffdd7fd --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDOKA.h @@ -0,0 +1,24 @@ +// ShellCommandDOKA.h: interface for the CShellCommandDOKA class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDDOKA_H__848A250B_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDDOKA_H__848A250B_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandDOKA : public CShellCommand +{ +public: + CShellCommandDOKA(CRegistryTree& rTree); + virtual ~CShellCommandDOKA(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDDOKA_H__848A250B_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp b/rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp new file mode 100644 index 00000000000..cecb86168e3 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp @@ -0,0 +1,109 @@ +/* $Id: ShellCommandDeleteKey.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// ShellCommandDeleteKey.cpp: implementation of the CShellCommandDeleteKey class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "ShellCommandDeleteKey.h" +#include "RegistryExplorer.h" + +#define DK_CMD _T("DK") +#define DK_CMD_SHORT_DESC DK_CMD _T(" command is used to delete key(s).\n") + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CShellCommandDeleteKey::CShellCommandDeleteKey(CRegistryTree& rTree):m_rTree(rTree) +{ +} + +CShellCommandDeleteKey::~CShellCommandDeleteKey() +{ +} + +BOOL CShellCommandDeleteKey::Match(const TCHAR *pchCommand) +{ + return _tcsicmp(pchCommand,DK_CMD) == 0; +} + +int CShellCommandDeleteKey::Execute(CConsole &rConsole, CArgumentParser& rArguments) +{ + const TCHAR *pchKey = NULL, *pchArg; + + BOOL blnHelp = FALSE; + BOOL blnExitAfterHelp = FALSE; + BOOL blnRecursive = FALSE; + + while((pchArg = rArguments.GetNextArgument()) != NULL) + { + if ((_tcsicmp(pchArg,_T("/?")) == 0) + ||(_tcsicmp(pchArg,_T("-?")) == 0)) + { + blnHelp = TRUE; + } + else if ((_tcsicmp(pchArg,_T("/s")) == 0) + ||(_tcsicmp(pchArg,_T("-s")) == 0)) + { + blnRecursive = TRUE; + } + else + { + if (pchKey) + { + rConsole.Write(_T("Wrong parameter : \"")); + rConsole.Write(pchArg); + rConsole.Write(_T("\"\n\n")); + blnHelp = TRUE; + } + else + { + pchKey = pchArg; + } + } + } + + if ((!blnHelp) && (!pchKey)) + { + rConsole.Write(_T("Key name not specified !\n\n")); + blnExitAfterHelp = TRUE; + } + + if (blnHelp) + { + rConsole.Write(GetHelpString()); + if (blnExitAfterHelp) + return 0; + else + rConsole.Write(_T("\n")); + } + + if (!m_rTree.DeleteKey(pchKey,blnRecursive)) + { + rConsole.Write(_T("Cannot delete key.\n")); + rConsole.Write(m_rTree.GetLastErrorDescription()); + } + return 0; +} + +const TCHAR * CShellCommandDeleteKey::GetHelpString() +{ + return DK_CMD_SHORT_DESC + _T("Syntax: ") DK_CMD _T(" [/s] [/?] Key_Name\n\n") + _T(" /? - This help.\n\n") + _T(" /s - Delete key and all subkeys.\n"); +} + +const TCHAR * CShellCommandDeleteKey::GetHelpShortDescriptionString() +{ + return DK_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteKey.h b/rosapps/sysutils/regexpl/ShellCommandDeleteKey.h new file mode 100644 index 00000000000..283450e58d7 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDeleteKey.h @@ -0,0 +1,24 @@ +// ShellCommandDeleteKey.h: interface for the CShellCommandDeleteKey class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDDELETEKEY_H__848A2510_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDDELETEKEY_H__848A2510_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandDeleteKey : public CShellCommand +{ +public: + CShellCommandDeleteKey(CRegistryTree& rTree); + virtual ~CShellCommandDeleteKey(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDDELETEKEY_H__848A2510_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp b/rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp new file mode 100644 index 00000000000..e997c88754c --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp @@ -0,0 +1,165 @@ +/* $Id: ShellCommandDeleteValue.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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(" [][] [/?]\n\n") + _T(" - Optional relative path of key which value will be delete.\n") + _T(" - Name of key's value. Default is key's default value.\n") + _T(" /? - This help.\n\n"); +} + +const TCHAR * CShellCommandDeleteValue::GetHelpShortDescriptionString() +{ + return DV_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteValue.h b/rosapps/sysutils/regexpl/ShellCommandDeleteValue.h new file mode 100644 index 00000000000..14d703ad198 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDeleteValue.h @@ -0,0 +1,24 @@ +// ShellCommandDeleteValue.h: interface for the CShellCommandDeleteValue class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDDELETEVALUE_H__15DEA2A5_7B3A_11D4_A081_90F9DC5EBD0F__INCLUDED_) +#define SHELLCOMMANDDELETEVALUE_H__15DEA2A5_7B3A_11D4_A081_90F9DC5EBD0F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandDeleteValue : public CShellCommand +{ +public: + CShellCommandDeleteValue(CRegistryTree& rTree); + virtual ~CShellCommandDeleteValue(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDDELETEVALUE_H__15DEA2A5_7B3A_11D4_A081_90F9DC5EBD0F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandDir.cpp b/rosapps/sysutils/regexpl/ShellCommandDir.cpp new file mode 100644 index 00000000000..6cc3541f0ba --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDir.cpp @@ -0,0 +1,245 @@ +/* $Id: ShellCommandDir.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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(" [] [/?]\n\n") + _T(" - Optional relative path to the key on which command will be executed\n") + _T(" /? - This help.\n\n") + _T("Without parameters, command lists keys and values of current key.\n"); +} + +const TCHAR * CShellCommandDir::GetHelpShortDescriptionString() +{ + return DIR_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandDir.h b/rosapps/sysutils/regexpl/ShellCommandDir.h new file mode 100644 index 00000000000..97e51f239c7 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandDir.h @@ -0,0 +1,24 @@ +// ShellCommandDir.h: interface for the CShellCommandDir class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDDIR_H__848A2505_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDDIR_H__848A2505_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandDir : public CShellCommand +{ +public: + CShellCommandDir(CRegistryTree& rTree); + virtual ~CShellCommandDir(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDDIR_H__848A2505_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandExit.cpp b/rosapps/sysutils/regexpl/ShellCommandExit.cpp new file mode 100644 index 00000000000..080ac79e745 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandExit.cpp @@ -0,0 +1,55 @@ +/* $Id: ShellCommandExit.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// ShellCommandExit.cpp: implementation of the CShellCommandExit class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "ShellCommandExit.h" +#include "RegistryExplorer.h" + +#define EXIT_CMD _T("EXIT") +#define EXIT_CMD_SHORT_DESC EXIT_CMD _T(" command termiantes current instance of Registry Explorer.\n") +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CShellCommandExit::CShellCommandExit() +{ + +} + +CShellCommandExit::~CShellCommandExit() +{ + +} + +BOOL CShellCommandExit::Match(const TCHAR *pchCommand) +{ + return _tcsicmp(pchCommand,EXIT_CMD) == 0; +} + +int CShellCommandExit::Execute(CConsole &rConsole, CArgumentParser& rArguments) +{ + rConsole.Write(GOODBYE_MSG); + return 0; +} + +const TCHAR * CShellCommandExit::GetHelpString() +{ + return EXIT_CMD_SHORT_DESC _T("Syntax: ") EXIT_CMD _T("\n"); +} + +const TCHAR * CShellCommandExit::GetHelpShortDescriptionString() +{ + return EXIT_CMD_SHORT_DESC; +} + diff --git a/rosapps/sysutils/regexpl/ShellCommandExit.h b/rosapps/sysutils/regexpl/ShellCommandExit.h new file mode 100644 index 00000000000..7b446259167 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandExit.h @@ -0,0 +1,21 @@ +// ShellCommandExit.h: interface for the CShellCommandExit class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDEXIT_H__848A2501_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDEXIT_H__848A2501_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" + +class CShellCommandExit : public CShellCommand +{ +public: + CShellCommandExit(); + virtual ~CShellCommandExit(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +}; + +#endif // !defined(SHELLCOMMANDEXIT_H__848A2501_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandHelp.cpp b/rosapps/sysutils/regexpl/ShellCommandHelp.cpp new file mode 100644 index 00000000000..818e1389b56 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandHelp.cpp @@ -0,0 +1,87 @@ +/* $Id: ShellCommandHelp.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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("[] [/?]\n") + _T(" COMMAND - Command for which help will be displayed.\n") + _T(" /? - This help.\n\n") + _T("Without parameters, command lists available commands.\n"); +} + +const TCHAR * CShellCommandHelp::GetHelpShortDescriptionString() +{ + return HELP_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandHelp.h b/rosapps/sysutils/regexpl/ShellCommandHelp.h new file mode 100644 index 00000000000..ee0390fdc16 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandHelp.h @@ -0,0 +1,24 @@ +// ShellCommandHelp.h: interface for the CShellCommandHelp class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDHELP_H__848A2504_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDHELP_H__848A2504_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "ShellCommandsLinkedList.h" + +class CShellCommandHelp : public CShellCommand +{ +public: + CShellCommandHelp(CShellCommandsLinkedList& rCommandsLinkedList); + virtual ~CShellCommandHelp(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CShellCommandsLinkedList& m_rCommandsLinkedList; +}; + +#endif // !defined(SHELLCOMMANDHELP_H__848A2504_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandNewKey.cpp b/rosapps/sysutils/regexpl/ShellCommandNewKey.cpp new file mode 100644 index 00000000000..bf224b5f99a --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandNewKey.cpp @@ -0,0 +1,116 @@ +/* $Id: ShellCommandNewKey.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// ShellCommandNewKey.cpp: implementation of the CShellCommandNewKey class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "ShellCommandNewKey.h" +#include "RegistryExplorer.h" + +#define NK_CMD _T("NK") +#define NK_CMD_SHORT_DESC NK_CMD _T(" command is used to create new key.\n") + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CShellCommandNewKey::CShellCommandNewKey(CRegistryTree& rTree):m_rTree(rTree) +{ +} + +CShellCommandNewKey::~CShellCommandNewKey() +{ +} + +BOOL CShellCommandNewKey::Match(const TCHAR *pchCommand) +{ + return _tcsicmp(pchCommand,NK_CMD) == 0; +} + +int CShellCommandNewKey::Execute(CConsole &rConsole, CArgumentParser& rArguments) +{ + const TCHAR *pchNewKey = NULL, *pchArg; + + BOOL blnHelp = FALSE; + BOOL blnExitAfterHelp = FALSE; + BOOL blnVolatile = FALSE; + + while((pchArg = rArguments.GetNextArgument()) != NULL) + { + if ((_tcsicmp(pchArg,_T("/?")) == 0) + ||(_tcsicmp(pchArg,_T("-?")) == 0)) + { + blnHelp = TRUE; + } + else if ((_tcsicmp(pchArg,_T("/v")) == 0) + ||(_tcsicmp(pchArg,_T("-v")) == 0)) + { + blnVolatile = TRUE; + } + else + { + if (pchNewKey) + { + rConsole.Write(_T("Wrong parameter : \"")); + rConsole.Write(pchArg); + rConsole.Write(_T("\"\n\n")); + blnHelp = TRUE; + } + else + { + pchNewKey = pchArg; + } + } + } + + if ((!blnHelp) && (!pchNewKey)) + { + rConsole.Write(_T("Key name not specified !\n\n")); + blnExitAfterHelp = TRUE; + } + + if (blnHelp) + { + rConsole.Write(GetHelpString()); + if (blnExitAfterHelp) + return 0; + else + rConsole.Write(_T("\n")); + } + + if (m_rTree.IsCurrentRoot()) + { // root key + rConsole.Write(NK_CMD COMMAND_NA_ON_ROOT); + return 0; + } + + if (!m_rTree.NewKey(pchNewKey,blnVolatile)) + { + rConsole.Write(_T("Cannot create key.\n")); + rConsole.Write(m_rTree.GetLastErrorDescription()); + } + return 0; +} + +const TCHAR * CShellCommandNewKey::GetHelpString() +{ + return NK_CMD_SHORT_DESC + _T("Syntax: ") NK_CMD _T(" [/v] [/?] Key_Name\n\n") + _T(" /? - This help.\n\n") + _T(" /v - Create volatile key. The information is stored in memory and is not\n") + _T(" preserved when the corresponding registry hive is unloaded.\n"); +} + +const TCHAR * CShellCommandNewKey::GetHelpShortDescriptionString() +{ + return NK_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandNewKey.h b/rosapps/sysutils/regexpl/ShellCommandNewKey.h new file mode 100644 index 00000000000..b254ff5e356 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandNewKey.h @@ -0,0 +1,24 @@ +// ShellCommandNewKey.h: interface for the CShellCommandNewKey class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDNEWKEY_H__848A250F_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDNEWKEY_H__848A250F_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandNewKey : public CShellCommand +{ +public: + CShellCommandNewKey(CRegistryTree& rTree); + virtual ~CShellCommandNewKey(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDNEWKEY_H__848A250F_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandOwner.cpp b/rosapps/sysutils/regexpl/ShellCommandOwner.cpp new file mode 100644 index 00000000000..53039977b0e --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandOwner.cpp @@ -0,0 +1,256 @@ +/* $Id: ShellCommandOwner.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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(" [] [/?]\n\n") + _T(" - Optional relative path of desired key.\n") + _T(" /? - This help.\n\n") + _T("Without parameters, command displays information about owner of current key.\n"); +} + +const TCHAR * CShellCommandOwner::GetHelpShortDescriptionString() +{ + return OWNER_CMD_SHORT_DESC; +} + diff --git a/rosapps/sysutils/regexpl/ShellCommandOwner.h b/rosapps/sysutils/regexpl/ShellCommandOwner.h new file mode 100644 index 00000000000..1ac345fd5e9 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandOwner.h @@ -0,0 +1,24 @@ +// ShellCommandOwner.h: interface for the CShellCommandOwner class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDOWNER_H__848A2508_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDOWNER_H__848A2508_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandOwner : public CShellCommand +{ +public: + CShellCommandOwner(CRegistryTree& rTree); + virtual ~CShellCommandOwner(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDOWNER_H__848A2508_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandSACL.cpp b/rosapps/sysutils/regexpl/ShellCommandSACL.cpp new file mode 100644 index 00000000000..bd80df9735e --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandSACL.cpp @@ -0,0 +1,402 @@ +/* $Id: ShellCommandSACL.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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(" [] [/?]\n\n") + _T(" - Optional relative path of desired key.\n") + _T(" /? - This help.\n\n") + _T("Without parameters, command displays SACL of current key.\n"); +} + +const TCHAR * CShellCommandSACL::GetHelpShortDescriptionString() +{ + return SACL_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandSACL.h b/rosapps/sysutils/regexpl/ShellCommandSACL.h new file mode 100644 index 00000000000..ee04f2fe272 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandSACL.h @@ -0,0 +1,24 @@ +// ShellCommandSACL.h: interface for the CShellCommandSACL class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDSACL_H__848A250A_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDSACL_H__848A250A_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandSACL : public CShellCommand +{ +public: + CShellCommandSACL(CRegistryTree& rTree); + virtual ~CShellCommandSACL(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDSACL_H__848A250A_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandSetValue.cpp b/rosapps/sysutils/regexpl/ShellCommandSetValue.cpp new file mode 100644 index 00000000000..482aa0389fe --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandSetValue.cpp @@ -0,0 +1,388 @@ +/* $Id: ShellCommandSetValue.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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(" [][] [/?]\n\n") + _T(" - 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(" - The data to be set. According to , 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 - string is interpreted as string\n") + _T(" - Optional relative path of key which value will be processed.\n") + _T(" - Name of key's value. Default is key's default value.\n") + _T(" /? - This help.\n"); +} + +const TCHAR * CShellCommandSetValue::GetHelpShortDescriptionString() +{ + return SET_VALUE_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandSetValue.h b/rosapps/sysutils/regexpl/ShellCommandSetValue.h new file mode 100644 index 00000000000..d25a7deb8b6 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandSetValue.h @@ -0,0 +1,24 @@ +// ShellCommandSetValue.h: interface for the CShellCommandSetValue class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDSETVALUE_H__32B55193_715E_11D4_A06C_BEFAED86450E__INCLUDED_) +#define SHELLCOMMANDSETVALUE_H__32B55193_715E_11D4_A06C_BEFAED86450E__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandSetValue : public CShellCommand +{ +public: + CShellCommandSetValue(CRegistryTree& rTree); + virtual ~CShellCommandSetValue(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +private: + CRegistryTree& m_rTree; +}; + +#endif // !defined(SHELLCOMMANDSETVALUE_H__32B55193_715E_11D4_A06C_BEFAED86450E__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandValue.cpp b/rosapps/sysutils/regexpl/ShellCommandValue.cpp new file mode 100644 index 00000000000..f1e01cc2c7e --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandValue.cpp @@ -0,0 +1,428 @@ +/* $Id: ShellCommandValue.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * 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; + TCHAR *pchValueFull = NULL; + BOOL blnUnicodeDump = FALSE; + BOOL blnBadParameter = FALSE; + BOOL blnHelp = FALSE; + DWORD dwError; + DWORD dwValueSize; + DWORD dwType = REG_NONE; + BYTE *pDataBuffer = NULL; + TCHAR *pchFilename = NULL; + + if ((_tcsnicmp(pchCommandItself,VALUE_CMD _T(".."),VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0)|| + (_tcsnicmp(pchCommandItself,VALUE_CMD _T("\\"),VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)) + { + pchValueFull = pchCommandItself + VALUE_CMD_LENGTH; + } + else if (_tcsnicmp(pchCommandItself,VALUE_CMD _T("/"),VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) + { + pchParameter = pchCommandItself + VALUE_CMD_LENGTH; + goto CheckValueArgument; + } + + while((pchParameter = rArguments.GetNextArgument()) != NULL) + { +CheckValueArgument: + blnBadParameter = FALSE; + if ((_tcsicmp(pchParameter,_T("/?")) == 0) + ||(_tcsicmp(pchParameter,_T("-?")) == 0)) + { + blnHelp = TRUE; + break; + } + else if (_tcsicmp(pchParameter,_T("/u")) == 0) + { + blnUnicodeDump = TRUE; + } + else if ((*pchParameter == _T('/'))&&(*(pchParameter+1) == _T('f'))) + { + pchFilename = pchParameter+2; + } + else if (!pchValueFull) + { + pchValueFull = pchParameter; + } + else + { + blnBadParameter = TRUE; + } + if (blnBadParameter) + { + 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()); + + if (pDataBuffer) + delete pDataBuffer; + + return 0; + } + + if (pchValueFull) + { + if (_tcscmp(pchValueFull,_T("\\")) == 0) + goto ValueCommandNAonRoot; + + 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 SkipValueCommand; + } + else + { + pKey = pTree->GetCurrentKey(); + } + } + else + { + pKey = m_rTree.GetCurrentKey(); + } + + if (pKey) + { // not root key ??? + rConsole.Write(_T("Value name : \"")); + rConsole.Write(_T("\\")); + rConsole.Write(pTree?pTree->GetCurrentPath():m_rTree.GetCurrentPath()); + rConsole.Write(*pchValueName?pchValueName:_T("\"(Default)\"")); + rConsole.Write(_T("\"\n")); + size_t l = _tcslen(pchValueName); + if (l&& + (*pchValueName == _T('\"'))&& + (pchValueName[l-1] == _T('\"'))) + { + pchValueName[l-1] = 0; + pchValueName++; + } + dwError = pKey->GetValue(pchValueName,NULL,NULL,&dwValueSize); + if (dwError == ERROR_SUCCESS) + { + pDataBuffer = new BYTE [dwValueSize]; + pKey->GetValue(pchValueName,&dwType,pDataBuffer,&dwValueSize); + rConsole.Write(_T("Value type : ")); + rConsole.Write(CRegistryKey::GetValueTypeName(dwType)); + rConsole.Write(_T("\nValue data : ")); + switch(dwType) + { + case REG_DWORD_LITTLE_ENDIAN: + { + TCHAR Buffer[11]; + unsigned int n = *pDataBuffer; + _stprintf(Buffer,_T("0x%08X\n"),n); + rConsole.Write(Buffer); + } + break; + case REG_DWORD_BIG_ENDIAN: + { + TCHAR Buffer[3]; + rConsole.Write(_T("0x")); + for (unsigned int i = 0 ; i < dwValueSize ; i++) + { + _stprintf(Buffer,_T("%02X"),*(pDataBuffer+i)); + rConsole.Write(Buffer); + } + } + rConsole.Write(_T("\n")); + break; + case REG_LINK: + break; + case REG_MULTI_SZ: + { + TCHAR *pchCurrentString = (TCHAR *)pDataBuffer; + rConsole.Write(_T("\n")); + while(*pchCurrentString) + { + rConsole.Write(_T("\"")); + rConsole.Write(pchCurrentString); + rConsole.Write(_T("\"\n")); + pchCurrentString += _tcslen(pchCurrentString)+1; + } + } + break; + case REG_RESOURCE_LIST: + break; + case REG_SZ: + case REG_EXPAND_SZ: + rConsole.Write(_T("\"")); + rConsole.Write((TCHAR *)pDataBuffer); + rConsole.Write(_T("\"\n")); + break; + case REG_BINARY: + default: + { + TCHAR Buffer[256]; + DWORD i; + for (i = 0 ; i < dwValueSize ; i++) + { + if (i%16 == 0) + { // ok this is begining of line + rConsole.Write(_T("\n")); + // print offset + _stprintf(Buffer,_T("0x%08X "),i); + rConsole.Write(Buffer); + } + else if (i%8 == 0) + { // this is the additional space between 7th and 8th byte in current line + rConsole.Write(_T(" ")); + } + + // print current byte + unsigned int n = *(pDataBuffer+i); + _stprintf(Buffer,_T("%02X "),n); + rConsole.Write(Buffer); + + if (i && (i%16 == 15)) + { // if this is the last byte in line + // Dump text representation + for (DWORD j = i-15; j <= i; j += blnUnicodeDump?2:1)\ + { + if ((j%8 == 0)&&(j%16 != 0)) + { // this is the additional space between 7th and 8th byte in current line + rConsole.Write(_T(" ")); + } + ASSERT(i-j < 16); + // write current char representation + if (blnUnicodeDump) + { + ASSERT(j%2 == 0); + wchar_t ch = *(TCHAR *)(pDataBuffer+j); + _stprintf(Buffer, +#ifdef _UNICODE + _T("%c"), +#else + _T("%C"), +#endif + iswprint(ch)?ch:L'.'); + } + else + { + unsigned char ch = *(pDataBuffer+j); + _stprintf(Buffer, +#ifdef _UNICODE + _T("%C"), +#else + _T("%c"), +#endif + isprint(ch)?ch:'.'); + } + rConsole.Write(Buffer); + } // for + } // if + } // for + + // print text representation of last line if it is not full (it have less than 16 bytes) + // k is pseudo offset + for (DWORD k = i; k%16 != 0; k++) + { + if (k%8 == 0) + { // this is the additional space between 7th and 8th byte in current line + rConsole.Write(_T(" ")); + } + _tcscpy(Buffer,_T(" ")); // the replacement of two digit of current byte + spacing + rConsole.Write(Buffer); + if (k && (k%16 == 15)) + { // if this is the last byte in line + ASSERT((k-15)%16 == 0); // k-15 must point at begin of last line + for (DWORD j = k-15; j < i; j += j += blnUnicodeDump?2:1) + { + if (blnUnicodeDump&&(j+1 >= i)) + { // ok, buffer size is odd number, so we don't display last byte. + ASSERT(j+1 == i); + break; + } + if ((j%8 == 0)&&(j%16 != 0)) + { // this is the additional space between 7th and 8th byte in current line + rConsole.Write(_T(" ")); + } + + // write current char representation + if (blnUnicodeDump) + { + ASSERT(j%2 == 0); + wchar_t ch = *(TCHAR *)(pDataBuffer+j); + _stprintf(Buffer, +#ifdef _UNICODE + _T("%c"), +#else + _T("%C"), +#endif + iswprint(ch)?ch:L'.'); + } + else + { + unsigned char ch = *(pDataBuffer+j); + _stprintf(Buffer, +#ifdef _UNICODE + _T("%C"), +#else + _T("%c"), +#endif + isprint(ch)?ch:'.'); + } + rConsole.Write(Buffer); + } // for + } // if + } // for + } // default: + rConsole.Write(_T("\n")); + } // switch + rConsole.Write(_T("\n")); + + if (pchFilename) + { + rConsole.Write(_T("Exporting value data to ")); + rConsole.Write(pchFilename); + rConsole.Write(_T(" ...\n")); + + HANDLE hFile = CreateFile(pchFilename,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + rConsole.Write(_T("Cannot create new file ")); + rConsole.Write(pchFilename); + rConsole.Write(_T("\n")); + goto SkipValueCommand; + } + + DWORD dwBytesWritten; + if (!WriteFile(hFile,pDataBuffer,dwValueSize,&dwBytesWritten,NULL)) + { + rConsole.Write(_T("Error writting file.\n")); + VERIFY(CloseHandle(hFile)); + goto SkipValueCommand; + } + + ASSERT(dwBytesWritten == dwValueSize); + VERIFY(CloseHandle(hFile)); + } + } + else + { + rConsole.Write(_T("Error ")); + TCHAR Buffer[256]; + rConsole.Write(_itot(dwError,Buffer,10)); + rConsole.Write(_T("\n")); + if (dwError == 2) + { + rConsole.Write(_T("(System Cannot find the value specified)\n")); + } + } + } // if (pKey) + else + { +ValueCommandNAonRoot: + rConsole.Write(VALUE_CMD COMMAND_NA_ON_ROOT); + } + +SkipValueCommand: + if (pTree) + delete pTree; + + if (pDataBuffer) + delete pDataBuffer; + return 0; +} + +const TCHAR * CShellCommandValue::GetHelpString() +{ + return VALUE_CMD_SHORT_DESC + _T("Syntax: ") VALUE_CMD _T(" [][] [/u] [/?]\n\n") + _T(" - Optional relative path of key which value will be processed.\n") + _T(" - Name of key's value. Default is key's default value.\n") + _T(" /u - On binary dump view as Unicode.\n") + _T(" /fFILE - Export value data to FILE.\n") + _T(" /? - This help.\n\n") + _T("Without parameters, command displays default value of current key.\n"); +} + +const TCHAR * CShellCommandValue::GetHelpShortDescriptionString() +{ + return VALUE_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandValue.h b/rosapps/sysutils/regexpl/ShellCommandValue.h new file mode 100644 index 00000000000..fea43a6c689 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandValue.h @@ -0,0 +1,24 @@ +// ShellCommandValue.h: interface for the CShellCommandValue class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDVALUE_H__848A2507_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) +#define SHELLCOMMANDVALUE_H__848A2507_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_ + +#include "ShellCommand.h" +#include "RegistryTree.h" + +class CShellCommandValue : public CShellCommand +{ +public: + CShellCommandValue(CRegistryTree& rTree); + virtual ~CShellCommandValue(); + 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(SHELLCOMMANDVALUE_H__848A2507_5A0F_11D4_A039_FC2CE602E70F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandVersion.cpp b/rosapps/sysutils/regexpl/ShellCommandVersion.cpp new file mode 100644 index 00000000000..5f16a255aa9 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandVersion.cpp @@ -0,0 +1,54 @@ +/* $Id: ShellCommandVersion.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// ShellCommandVersion.cpp: implementation of the CShellCommandVersion class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "ShellCommandVersion.h" +#include "RegistryExplorer.h" + +#define VER_CMD _T("VER") +#define VER_CMD_SHORT_DESC VER_CMD _T(" command displays information about this program.\n") + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CShellCommandVersion::CShellCommandVersion() +{ +} + +CShellCommandVersion::~CShellCommandVersion() +{ +} + +BOOL CShellCommandVersion::Match(const TCHAR *pchCommand) +{ + return _tcsicmp(pchCommand,VER_CMD) == 0; +} + +int CShellCommandVersion::Execute(CConsole &rConsole, CArgumentParser& rArguments) +{ + rConsole.Write(HELLO_MSG); + rConsole.Write(VER_MSG); + return 0; +} + +const TCHAR * CShellCommandVersion::GetHelpString() +{ + return VER_CMD_SHORT_DESC _T("Syntax: ") VER_CMD _T("\n"); +} + +const TCHAR * CShellCommandVersion::GetHelpShortDescriptionString() +{ + return VER_CMD_SHORT_DESC; +} diff --git a/rosapps/sysutils/regexpl/ShellCommandVersion.h b/rosapps/sysutils/regexpl/ShellCommandVersion.h new file mode 100644 index 00000000000..20b87ccd292 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandVersion.h @@ -0,0 +1,21 @@ +// ShellCommandVersion.h: interface for the CShellCommandVersion class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDVERSION_H__D29C1196_5942_11D4_A037_C5AC8D00940F__INCLUDED_) +#define SHELLCOMMANDVERSION_H__D29C1196_5942_11D4_A037_C5AC8D00940F__INCLUDED_ + +#include "ShellCommand.h" + +class CShellCommandVersion : public CShellCommand +{ +public: + CShellCommandVersion(); + virtual ~CShellCommandVersion(); + virtual BOOL Match(const TCHAR *pchCommand); + virtual int Execute(CConsole &rConsole, CArgumentParser& rArguments); + virtual const TCHAR * GetHelpString(); + virtual const TCHAR * GetHelpShortDescriptionString(); +}; + +#endif // !defined(SHELLCOMMANDVERSION_H__D29C1196_5942_11D4_A037_C5AC8D00940F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ShellCommandsLinkedList.cpp b/rosapps/sysutils/regexpl/ShellCommandsLinkedList.cpp new file mode 100644 index 00000000000..204e33aec66 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandsLinkedList.cpp @@ -0,0 +1,108 @@ +/* $Id: ShellCommandsLinkedList.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// ShellCommandsLinkedList.cpp: implementation of the CShellCommandsLinkedList class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "ShellCommandsLinkedList.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CShellCommandsLinkedList::CShellCommandsLinkedList(CConsole& rConsole):m_rConsole(rConsole) +{ + m_pRoot = NULL; +} + +CShellCommandsLinkedList::~CShellCommandsLinkedList() +{ +} + +void CShellCommandsLinkedList::AddCommand(CShellCommand *pCommand) +{ + // Create new node + SNode *pNewNode = new SNode; + if (pNewNode == NULL) + return; + + pNewNode->m_pData = pCommand; + + // add new node to the end + if (m_pRoot) + { + SNode *pLastNode = m_pRoot; + + while (pLastNode->m_pNext) + pLastNode = pLastNode->m_pNext; + + pLastNode->m_pNext = pNewNode; + } + else + { + m_pRoot = pNewNode; + } +} + +int CShellCommandsLinkedList::Execute(CArgumentParser& rArgumentParser, int& nReturnValue) +{ + rArgumentParser.ResetArgumentIteration(); + + const TCHAR *pchCommand = rArgumentParser.GetNextArgument(); + + if (pchCommand == NULL) // empty command line + return -2; + + int i = -1; + + SNode *pNode = m_pRoot; + + while(pNode) + { + i++; + if (pNode->m_pData->Match(pchCommand)) + { + nReturnValue = pNode->m_pData->Execute(m_rConsole,rArgumentParser); + return i; + } + pNode = pNode->m_pNext; + } + + return -1; +} + +CShellCommand * CShellCommandsLinkedList::Match(const TCHAR * pchCommand) +{ + SNode *pNode = m_pRoot; + + while(pNode) + { + if (pNode->m_pData->Match(pchCommand)) + return pNode->m_pData; + pNode = pNode->m_pNext; + } + + return NULL; +} + +POSITION CShellCommandsLinkedList::GetFirstCommandPosition() +{ + return (POSITION)m_pRoot; +} + +CShellCommand * CShellCommandsLinkedList::GetNextCommand(POSITION& rPos) +{ + CShellCommand * pCommand = ((SNode *)rPos)->m_pData; + rPos = (POSITION)(((SNode *)rPos)->m_pNext); + return pCommand; +} + diff --git a/rosapps/sysutils/regexpl/ShellCommandsLinkedList.h b/rosapps/sysutils/regexpl/ShellCommandsLinkedList.h new file mode 100644 index 00000000000..ef87c9c4a57 --- /dev/null +++ b/rosapps/sysutils/regexpl/ShellCommandsLinkedList.h @@ -0,0 +1,33 @@ +// ShellCommandsLinkedList.h: interface for the CShellCommandsLinkedList class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(SHELLCOMMANDSLINKEDLIST_H__D29C1198_5942_11D4_A037_C5AC8D00940F__INCLUDED_) +#define SHELLCOMMANDSLINKEDLIST_H__D29C1198_5942_11D4_A037_C5AC8D00940F__INCLUDED_ + +#include "ShellCommand.h" +#include "Console.h" + +#define POSITION int * + +class CShellCommandsLinkedList +{ +public: + CShellCommandsLinkedList(CConsole& rConsole); + virtual ~CShellCommandsLinkedList(); + void AddCommand(CShellCommand *pCommand); + int Execute(CArgumentParser& rArgumentParser, int& nReturnValue); + CShellCommand * Match(const TCHAR * pchCommand); + POSITION GetFirstCommandPosition(); + CShellCommand * GetNextCommand(POSITION& rPos); +private: + struct SNode + { + SNode() {m_pNext = NULL;}; + CShellCommand *m_pData; + SNode *m_pNext; + } *m_pRoot; + CConsole &m_rConsole; +}; + +#endif // !defined(SHELLCOMMANDSLINKEDLIST_H__D29C1198_5942_11D4_A037_C5AC8D00940F__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/TextHistory.cpp b/rosapps/sysutils/regexpl/TextHistory.cpp new file mode 100644 index 00000000000..58a055e6a4c --- /dev/null +++ b/rosapps/sysutils/regexpl/TextHistory.cpp @@ -0,0 +1,81 @@ +/* $Id: TextHistory.cpp,v 1.1 2000/10/04 21:04:31 ea Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (c) 1999-2000 Nedko Arnaoudov + * + * License: GNU GPL + * + */ + +// TextHistory.cpp: implementation of the CTextHistory class. +// +////////////////////////////////////////////////////////////////////// + +#include "ph.h" +#include "TextHistory.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CTextHistory::CTextHistory() +{ + m_pHistoryBuffer = NULL; + m_dwMaxHistoryLines = 0; +} + +CTextHistory::~CTextHistory() +{ + if (m_pHistoryBuffer) delete m_pHistoryBuffer; +} + +BOOL CTextHistory::Init(DWORD dwMaxHistoryLineSize, DWORD dwMaxHistoryLines) +{ + if (!dwMaxHistoryLines) + { + ASSERT(FALSE); + return FALSE; + } + if (m_pHistoryBuffer) delete m_pHistoryBuffer; + m_dwFirstHistoryIndex = 0; + m_dwLastHistoryIndex = 0; + m_dwHisoryFull = 0; + m_dwMaxHistoryLines = dwMaxHistoryLines; + m_dwMaxHistoryLineSize = dwMaxHistoryLineSize; + m_pHistoryBuffer = new TCHAR [m_dwMaxHistoryLines*dwMaxHistoryLineSize]; + if (!m_pHistoryBuffer) return FALSE; + return TRUE; +} + +void CTextHistory::AddHistoryLine(const TCHAR *pchLine) +{ + if (!m_pHistoryBuffer) return; + if (_tcslen(pchLine) == 0) return; + if (_tcslen(pchLine) >= m_dwMaxHistoryLineSize) + { + ASSERT(FALSE); + return; + } + if (m_dwHisoryFull == m_dwMaxHistoryLines) // if buffer is full, replace last + { + ASSERT(m_dwFirstHistoryIndex == m_dwLastHistoryIndex); + m_dwLastHistoryIndex = (m_dwLastHistoryIndex+1)%m_dwMaxHistoryLines; + } + ASSERT(m_dwFirstHistoryIndex < m_dwMaxHistoryLines); + _tcscpy(m_pHistoryBuffer+m_dwFirstHistoryIndex*m_dwMaxHistoryLineSize,pchLine); + m_dwFirstHistoryIndex = (m_dwFirstHistoryIndex+1)%m_dwMaxHistoryLines; + ASSERT(m_dwHisoryFull <= m_dwMaxHistoryLines); + if (m_dwHisoryFull < m_dwMaxHistoryLines) m_dwHisoryFull++; +} + +const TCHAR * CTextHistory::GetHistoryLine(DWORD dwIndex) +{ + if (!m_pHistoryBuffer) return NULL; + ASSERT(m_dwHisoryFull <= m_dwMaxHistoryLines); + if (dwIndex >= m_dwHisoryFull) return NULL; + dwIndex = m_dwHisoryFull - dwIndex - 1; + dwIndex = (dwIndex+m_dwLastHistoryIndex) % m_dwMaxHistoryLines; + ASSERT(dwIndex < m_dwMaxHistoryLines); + return m_pHistoryBuffer+dwIndex*m_dwMaxHistoryLineSize; +} diff --git a/rosapps/sysutils/regexpl/TextHistory.h b/rosapps/sysutils/regexpl/TextHistory.h new file mode 100644 index 00000000000..ad7ddf43c2a --- /dev/null +++ b/rosapps/sysutils/regexpl/TextHistory.h @@ -0,0 +1,25 @@ +// TextHistory.h: interface for the CTextHistory class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(TEXTHISTORY_H__AD9C6555_1D97_11D4_9F58_204C4F4F5020__INCLUDED_) +#define TEXTHISTORY_H__AD9C6555_1D97_11D4_9F58_204C4F4F5020__INCLUDED_ + +class CTextHistory +{ +public: + CTextHistory(); + virtual ~CTextHistory(); + BOOL Init(DWORD dwMaxHistoryLineSize, DWORD dwMaxHistoryLines); + const TCHAR * GetHistoryLine(DWORD dwIndex); + void AddHistoryLine(const TCHAR *pchLine); +private: + TCHAR *m_pHistoryBuffer; + DWORD m_dwMaxHistoryLines; + DWORD m_dwMaxHistoryLineSize; + DWORD m_dwFirstHistoryIndex; + DWORD m_dwLastHistoryIndex; + DWORD m_dwHisoryFull; +}; + +#endif // !defined(TEXTHISTORY_H__AD9C6555_1D97_11D4_9F58_204C4F4F5020__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/ph.h b/rosapps/sysutils/regexpl/ph.h new file mode 100644 index 00000000000..f53c648fd23 --- /dev/null +++ b/rosapps/sysutils/regexpl/ph.h @@ -0,0 +1,32 @@ +// ph.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// it is used to generate precompiled header file, if supported. + +#if !defined(PH_H__FEF419E3_6EB6_11D3_907D_204C4F4F5020__INCLUDED_) +#define PH_H__FEF419E3_6EB6_11D3_907D_204C4F4F5020__INCLUDED_ + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +// comment next two lines to compile ANSI version +//#define UNICODE +//#define _UNICODE + +#include + +#include +#include +#include +#include +#define ASSERT assert +#ifdef _DEBUG +#define VERIFY ASSERT +#else +#define VERIFY(e) (e) +#endif +#include +#include +#include +#include + +#endif // !defined(PH_H__FEF419E3_6EB6_11D3_907D_204C4F4F5020__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/regexpl.rc b/rosapps/sysutils/regexpl/regexpl.rc new file mode 100644 index 00000000000..afab1628f3e --- /dev/null +++ b/rosapps/sysutils/regexpl/regexpl.rc @@ -0,0 +1,38 @@ +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "ReactOS Console Registry Explorer\0" + VALUE "FileVersion", RES_STR_FILE_VERSION + VALUE "InternalName", "regexpl\0" + VALUE "LegalCopyright", "2000 (c) Nedko Arnaoudov\0" + VALUE "OriginalFilename", "regexpl.exe\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END +