From 1688a8d7c5b2ce532df122c30236965b4bb8ed53 Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Wed, 10 Jan 2001 01:25:29 +0000 Subject: [PATCH] no message svn path=/trunk/; revision=1500 --- rosapps/sysutils/regexpl/ArgumentParser.cpp | 51 +- rosapps/sysutils/regexpl/Completion.cpp | 505 ++++++++++ rosapps/sysutils/regexpl/Completion.h | 17 + rosapps/sysutils/regexpl/Console.cpp | 121 ++- rosapps/sysutils/regexpl/Console.h | 5 +- rosapps/sysutils/regexpl/Makefile | 5 +- rosapps/sysutils/regexpl/Pattern.cpp | 55 ++ rosapps/sysutils/regexpl/Pattern.h | 12 + rosapps/sysutils/regexpl/RegistryExplorer.cpp | 322 +------ rosapps/sysutils/regexpl/RegistryExplorer.h | 6 +- rosapps/sysutils/regexpl/RegistryKey.cpp | 780 ++++++++------- rosapps/sysutils/regexpl/RegistryKey.h | 276 +++++- rosapps/sysutils/regexpl/RegistryTree.cpp | 911 +++++++++++------- rosapps/sysutils/regexpl/RegistryTree.h | 113 ++- .../sysutils/regexpl/SecurityDescriptor.cpp | 8 +- rosapps/sysutils/regexpl/SecurityDescriptor.h | 1 + .../regexpl/ShellCommandChangeKey.cpp | 6 +- .../sysutils/regexpl/ShellCommandConnect.cpp | 9 +- rosapps/sysutils/regexpl/ShellCommandDACL.cpp | 491 +++++----- .../regexpl/ShellCommandDeleteKey.cpp | 66 +- .../regexpl/ShellCommandDeleteValue.cpp | 118 +-- rosapps/sysutils/regexpl/ShellCommandDir.cpp | 251 +++-- rosapps/sysutils/regexpl/ShellCommandHelp.cpp | 4 +- .../sysutils/regexpl/ShellCommandNewKey.cpp | 86 +- .../sysutils/regexpl/ShellCommandOwner.cpp | 244 +++-- rosapps/sysutils/regexpl/ShellCommandSACL.cpp | 693 ++++++------- .../sysutils/regexpl/ShellCommandSetValue.cpp | 315 +++--- .../sysutils/regexpl/ShellCommandValue.cpp | 484 +++++----- rosapps/sysutils/regexpl/ph.h | 9 + 29 files changed, 3494 insertions(+), 2470 deletions(-) create mode 100644 rosapps/sysutils/regexpl/Completion.cpp create mode 100644 rosapps/sysutils/regexpl/Completion.h create mode 100644 rosapps/sysutils/regexpl/Pattern.cpp create mode 100644 rosapps/sysutils/regexpl/Pattern.h diff --git a/rosapps/sysutils/regexpl/ArgumentParser.cpp b/rosapps/sysutils/regexpl/ArgumentParser.cpp index d857c1bac86..95a024ad740 100644 --- a/rosapps/sysutils/regexpl/ArgumentParser.cpp +++ b/rosapps/sysutils/regexpl/ArgumentParser.cpp @@ -1,4 +1,4 @@ -/* $Id: ArgumentParser.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ArgumentParser.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -44,29 +44,29 @@ 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 *pch = m_pchArgumentList = pchArguments; +m_pchArgumentListEnd = pchArguments + _tcslen(pchArguments); + + BOOL blnLongArg = FALSE; + while (*pch) + { + switch(*pch) + { + case _T('\"'): + blnLongArg = !blnLongArg; + break; + case _T(' '): + case _T('\t'): + case _T('\r'): + case _T('\n'): + if (!blnLongArg) + *pch = 0; + break; + } + pch++; + } + + ResetArgumentIteration(); } TCHAR * CArgumentParser::GetNextArgument() @@ -76,7 +76,8 @@ TCHAR * CArgumentParser::GetNextArgument() ASSERT(m_pchArgumentListEnd >= m_pchArgumentList); // if this is begin of iteration - if (!m_pchArgument) m_pchArgument = m_pchArgumentList; + if (!m_pchArgument) + m_pchArgument = m_pchArgumentList; while(m_pchArgument) { diff --git a/rosapps/sysutils/regexpl/Completion.cpp b/rosapps/sysutils/regexpl/Completion.cpp new file mode 100644 index 00000000000..2d389618dd6 --- /dev/null +++ b/rosapps/sysutils/regexpl/Completion.cpp @@ -0,0 +1,505 @@ +/* $Id: Completion.cpp,v 1.1 2001/01/10 01:25:29 narnaoud Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (C) 2000 Nedko Arnaoudov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +// Completion.cpp : Defines the completion related functions. +#include "ph.h" +#include "RegistryKey.h" +#include "RegistryTree.h" + +#define COMPLETION_BUFFER_SIZE 4096 + +extern CRegistryTree Tree; + +BOOL g_blnCompletionCycle = TRUE; + +class CCompletionMatch +{ +public: + CCompletionMatch() + { + m_pNext = m_pPrev = NULL; + m_pszText = NULL; + }; + + BOOL Init(const TCHAR *pszText) + { + // find the offset to "unique" part + const TCHAR *pszUnique = _tcsrchr(pszText,_T('\\')); + pszUnique = pszUnique?(pszUnique+1):pszText; + BOOL b = _tcschr(pszUnique,_T(' ')) != NULL; // has it spaces in it ??? + size_t s = _tcslen(pszText); + + if (m_pszText) + delete m_pszText; + + m_pszText = new TCHAR [s+(b?3:1)]; // if we have spaces in unique part, we need 2 addtional chars for " + + if (!m_pszText) + return FALSE; + + ASSERT(pszText <= pszUnique); + s = pszUnique - pszText; // calculate offset of the unique part + if (s) + _tcsncpy(m_pszText,pszText,s); + + if (b) + m_pszText[s++] = _T('\"'); + + _tcscpy(m_pszText+s,pszUnique); + + if (b) + _tcscat(m_pszText,_T("\"")); + + return TRUE; + } + + ~CCompletionMatch() + { + if (m_pszText) + delete m_pszText; + } + +private: + TCHAR *m_pszText; + BOOL m_blnIsKey; + CCompletionMatch *m_pNext; + CCompletionMatch *m_pPrev; + friend class CCompletionList; +}; + +class CCompletionList +{ +public: + CCompletionList(); + ~CCompletionList(); + + BOOL IsNewCompletion(const TCHAR *pszContext, const TCHAR *pszBegin, BOOL& rblnNew); + BOOL Add(const TCHAR *pszText, BOOL blnIsKey); + const TCHAR *Get(unsigned __int64 nIndex, BOOL& rblnIsKey); + unsigned __int64 GetCount(); + const TCHAR * GetContext(); + const TCHAR * GetBegin(); + void DeleteList(); + void Invalidate(); + +private: + CCompletionMatch *m_pHead; // head of completions linked list + CCompletionMatch *m_pTail; // tail of completions linked list + CCompletionMatch *m_pLastSearched; + unsigned int m_nLastSearched; + TCHAR *m_pszContext; + TCHAR *m_pszBegin; + TCHAR *m_pszCurrentKey; + unsigned __int64 m_nCount; +} g_Completion; + +// --- begin of CCompletionList implementation --- +CCompletionList::CCompletionList() +{ + m_pHead = NULL; + m_pTail = NULL; + m_nCount = 0; + m_pLastSearched = NULL; + m_pszContext = NULL; + m_pszBegin = NULL; + m_pszCurrentKey = NULL; +} + +CCompletionList::~CCompletionList() +{ + DeleteList(); + + if (m_pszContext) + delete m_pszContext; + + if (m_pszBegin) + delete m_pszBegin; + + if (m_pszCurrentKey) + delete m_pszCurrentKey; +} + +void CCompletionList::Invalidate() +{ + if (m_pszCurrentKey) + { + delete m_pszCurrentKey; + m_pszCurrentKey = NULL; + } +} + +BOOL CCompletionList::IsNewCompletion(const TCHAR *pszContext, const TCHAR *pszBegin, BOOL& rblnNew) +{ + const TCHAR *pszCurrentKey = Tree.GetCurrentPath(); + if (!m_pszContext || + !m_pszBegin || + !m_pszCurrentKey || + (_tcscmp(m_pszContext,pszContext) != 0) || + (_tcscmp(m_pszBegin,pszBegin) != 0) || + (_tcscmp(m_pszCurrentKey,pszCurrentKey))) + { // new completion + DeleteList(); + rblnNew = TRUE; + if (m_pszContext) + { + delete m_pszContext; + m_pszContext = NULL; + } + + if (m_pszBegin) + { + delete m_pszBegin; + m_pszBegin = NULL; + } + + if (m_pszCurrentKey) + { + delete m_pszCurrentKey; + m_pszCurrentKey = NULL; + } + + size_t s = _tcslen(pszContext); + m_pszContext = new TCHAR[s+1]; + if (!m_pszContext) + return FALSE; + _tcscpy(m_pszContext,pszContext); + + s = _tcslen(pszBegin); + m_pszBegin = new TCHAR[s+1]; + if (!m_pszBegin) + return FALSE; + _tcscpy(m_pszBegin,pszBegin); + + s = _tcslen(pszCurrentKey); + m_pszCurrentKey = new TCHAR[s+1]; + if (!m_pszCurrentKey) + return FALSE; + _tcscpy(m_pszCurrentKey,pszCurrentKey); + + return TRUE; + } + + rblnNew = FALSE; + return TRUE; +} + +BOOL CCompletionList::Add(const TCHAR *pszText, BOOL blnIsKey) +{ + if (_tcsnicmp(pszText,m_pszBegin,_tcslen(m_pszBegin)) != 0) + return TRUE; + CCompletionMatch *pNode = new CCompletionMatch; + if (!pNode) + return FALSE; + if (!pNode->Init(pszText)) + return FALSE; + + ASSERT(pNode->m_pszText); + ASSERT(pNode->m_pNext == NULL); + + // add new node to tail + pNode->m_blnIsKey = blnIsKey; + if (m_pTail) + { + pNode->m_pPrev = m_pTail; + ASSERT(m_pTail->m_pNext == NULL); + m_pTail->m_pNext = pNode; + m_pTail = pNode; + } + else + { + ASSERT(m_pHead == NULL); + m_pHead = m_pTail = pNode; + } + + m_nCount++; + + m_pLastSearched = NULL; + + return TRUE; +} + +const TCHAR * CCompletionList::Get(unsigned __int64 nIndex, BOOL& rblnIsKey) +{ + ASSERT(nIndex < m_nCount); + BOOL blnForward; + CCompletionMatch *pNode = NULL; + + unsigned __int64 nRelativeIndex; + + if (m_pLastSearched) + { + pNode = m_pLastSearched; + blnForward = nIndex > m_nLastSearched; + nRelativeIndex = blnForward?(nIndex-m_nLastSearched):(m_nLastSearched-nIndex); + if ((nRelativeIndex > nIndex)||(nRelativeIndex > m_nCount-nIndex-1)) + pNode = NULL; // seraching from tail or from head is more effective + } + + if (!pNode && (nIndex <= m_nCount/2)) + { // search from head + pNode = m_pHead; + blnForward = TRUE; + nRelativeIndex = nIndex; + } + + if (!pNode) + { // search from tail + pNode = m_pTail; + blnForward = FALSE; + nRelativeIndex = m_nCount-nIndex-1; + } + + while(pNode) + { + if (nRelativeIndex == 0) + { + m_nLastSearched = nIndex; + m_pLastSearched = pNode; + rblnIsKey = pNode->m_blnIsKey; + if (!pNode->m_pszText) + ASSERT(FALSE); + return pNode->m_pszText; + } + + nRelativeIndex--; + + pNode = blnForward?(pNode->m_pNext):(pNode->m_pPrev); + } + + ASSERT(FALSE); + return NULL; +} + +unsigned __int64 CCompletionList::GetCount() +{ + return m_nCount; +} + +const TCHAR * CCompletionList::GetContext() +{ + return m_pszContext; +} + +const TCHAR * CCompletionList::GetBegin() +{ + return m_pszBegin; +} + +void CCompletionList::DeleteList() +{ + CCompletionMatch *pNode; + while(m_pHead) + { + pNode = m_pHead; + m_pHead = m_pHead->m_pNext; + delete pNode; + } + m_pTail = NULL; + ASSERT(m_pHead == NULL); + m_nCount = 0; +} + +// --- end of CCompletionList implementation --- + +BOOL FillCompletion(const TCHAR *pszKey) +{ + g_Completion.DeleteList(); + LONG nError; + CRegistryKey Key; + TCHAR *pszSubkeyName = NULL; + DWORD dwMaxSubkeyNameLength; + TCHAR *pszValueName = NULL; + DWORD dwMaxValueNameSize; + + if (!Tree.GetKey(pszKey?pszKey:_T("."),KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE,Key)) + return FALSE; + + BOOL blnCompletionOnKeys = TRUE; + BOOL blnCompletionOnValues = TRUE; + +/* 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; +// } + + size_t nKeyNameSize = 0; + if (pszKey) + { + nKeyNameSize = _tcslen(pszKey); + if (_tcscmp(pszKey,_T("\\"))) + nKeyNameSize++; + } + + if (blnCompletionOnKeys) + { + nError = Key.GetSubkeyNameMaxLength(dwMaxSubkeyNameLength); + if (nError != ERROR_SUCCESS) + return FALSE; + + pszSubkeyName = new TCHAR[nKeyNameSize+dwMaxSubkeyNameLength+1]; + if (!pszSubkeyName) + goto Abort; + + if (pszKey) + _stprintf(pszSubkeyName,_tcscmp(pszKey,_T("\\"))?_T("%s\\"):_T("%s"),pszKey); + + Key.InitSubkeyEnumeration(pszSubkeyName+nKeyNameSize,dwMaxSubkeyNameLength); + while ((nError = Key.GetNextSubkeyName()) == ERROR_SUCCESS) + if (!g_Completion.Add(pszSubkeyName,TRUE)) + { + ASSERT(FALSE); + goto Abort; + } + if ((nError != ERROR_SUCCESS)&&(nError != ERROR_NO_MORE_ITEMS)) + { + ASSERT(FALSE); + goto Abort; + } + } + + if (blnCompletionOnValues) + { + nError = Key.GetMaxValueNameLength(dwMaxValueNameSize); + if (nError != ERROR_SUCCESS) + { + ASSERT(FALSE); + goto Abort; + } + + pszValueName = new TCHAR[nKeyNameSize+dwMaxValueNameSize+1]; + if (!pszValueName) + goto Abort; + + if (pszKey) + _stprintf(pszValueName,_tcscmp(pszKey,_T("\\"))?_T("%s\\"):_T("%s"),pszKey); + + Key.InitValueEnumeration(pszValueName+nKeyNameSize,dwMaxValueNameSize,NULL,0,NULL); + while((nError = Key.GetNextValue()) == ERROR_SUCCESS) + if (!g_Completion.Add(pszValueName,FALSE)) + { + ASSERT(FALSE); + goto Abort; + } + if ((nError != ERROR_SUCCESS)&&(nError != ERROR_NO_MORE_ITEMS)) + { + ASSERT(FALSE); + goto Abort; + } + } + + if (pszValueName) + delete pszValueName; + if (pszSubkeyName) + delete pszSubkeyName; + return TRUE; +Abort: + if (pszValueName) + delete pszValueName; + if (pszSubkeyName) + delete pszSubkeyName; + return FALSE; +} + +const TCHAR * CompletionCallback(unsigned __int64 & rnIndex, + const BOOL *pblnForward, + const TCHAR *pszContext, + const TCHAR *pszBegin) +{ + static TCHAR pszBuffer[COMPLETION_BUFFER_SIZE]; + + // Find first non-white space in context + while(*pszContext && _istspace(*pszContext)) + pszContext++; + + BOOL blnNewCompletion = TRUE; + if (!g_Completion.IsNewCompletion(pszContext,pszBegin,blnNewCompletion)) + { + ASSERT(FALSE); + return NULL; + } + + if (blnNewCompletion) + { + _tcsncpy(pszBuffer,pszBegin,COMPLETION_BUFFER_SIZE-1); + pszBuffer[COMPLETION_BUFFER_SIZE-1] = 0; + TCHAR *pszSeparator = pszBuffer; // set it to aby non null value + if (_tcscmp(pszBuffer,_T("\\"))) + { + pszSeparator = _tcsrchr(pszBuffer,_T('\\')); + if (pszSeparator) + *pszSeparator = 0; + } + + if (!FillCompletion(pszSeparator?pszBuffer:NULL)) + return NULL; + } + + unsigned __int64 nTotalItems = g_Completion.GetCount(); + if (nTotalItems == 0) + return NULL; + + 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; + } + } + BOOL blnIsKey = FALSE; + const TCHAR *pszName = g_Completion.Get(rnIndex,blnIsKey); + + ASSERT(pszName); + + _sntprintf(pszBuffer,COMPLETION_BUFFER_SIZE-1,_T("%s%s"),pszName,(blnIsKey?_T("\\"):_T(""))); + pszBuffer[COMPLETION_BUFFER_SIZE-1] = 0; + return pszBuffer; +} + +void InvalidateCompletion() +{ + g_Completion.Invalidate(); +} diff --git a/rosapps/sysutils/regexpl/Completion.h b/rosapps/sysutils/regexpl/Completion.h new file mode 100644 index 00000000000..b5a08baa979 --- /dev/null +++ b/rosapps/sysutils/regexpl/Completion.h @@ -0,0 +1,17 @@ +/* $Id: Completion.h,v 1.1 2001/01/10 01:25:29 narnaoud Exp $ */ + +// Completion.h - declaration for completion related functions + +#if !defined(PATTERN_H__INCLUDED_) +#define PATTERN_H__INCLUDED_ + +typedef const TCHAR * (*ReplaceCompletionCallback)(unsigned __int64& rnIndex, const BOOL *pblnForward, + const TCHAR *pchContext, const TCHAR *pchBegin); + +extern const TCHAR * CompletionCallback(unsigned __int64 & rnIndex, + const BOOL *pblnForward, + const TCHAR *pchContext, + const TCHAR *pchBegin); + +extern void InvalidateCompletion(); +#endif diff --git a/rosapps/sysutils/regexpl/Console.cpp b/rosapps/sysutils/regexpl/Console.cpp index 73758bc040d..5724ad23c90 100644 --- a/rosapps/sysutils/regexpl/Console.cpp +++ b/rosapps/sysutils/regexpl/Console.cpp @@ -1,4 +1,4 @@ -/* $Id: Console.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: Console.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -27,6 +27,7 @@ #include "ph.h" #include "Console.h" +#define TAB_WIDTH 8 #define MORE_STRING _T("-- Press space to view more. Press q or Ctrl+break to cancel.--") #define MORE_EMPTY_STRING _T(" ") @@ -118,7 +119,7 @@ BOOL CConsole::Write(const TCHAR *p, DWORD dwChars) { if (!Write(_T(" "))) return FALSE; } - while ((m_CursorPosition.X % 8) && (!m_blnDisableWrite)); + while ((m_CursorPosition.X % TAB_WIDTH) && (!m_blnDisableWrite)); dwCharsWrittenAdd++; dwCharsToWrite--; continue; @@ -214,6 +215,11 @@ BOOL CConsole::Write(const TCHAR *p, DWORD dwChars) return ret; } +unsigned int CConsole::GetTabWidth() +{ + return TAB_WIDTH; +} + BOOL CConsole::SetTitle(TCHAR *p) { return SetConsoleTitle(p); @@ -674,85 +680,99 @@ Paste: } } else if (ch == _T('\t')) - { - if (!blnCompletionMode) + { // Tab + + if (!blnCompletionMode) // If tab was pressed after non-tab. We enter in completion mode. { - if (InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) -// nCompletionIndex = 0xFFFFFFFFFFFFFFFF; - nCompletionIndex = (unsigned long long) -1; + // Initialize completion index + if (InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) // If shift was pressed + nCompletionIndex = (unsigned long long) -1; // Last completion else - nCompletionIndex = 0; + nCompletionIndex = 0; // First completion + + // Find completion offset. It points at char after first non-quoted whitespace. dwCompletionOffset = dwCurrentCharOffset; - BOOL b = FALSE; + BOOL blnQuotedParameter = FALSE; while(dwCompletionOffset) { dwCompletionOffset--; if (m_pchBuffer[dwCompletionOffset] == _T('\"')) { - b = !b; + blnQuotedParameter = !blnQuotedParameter; } - else if (!b && _istspace(m_pchBuffer[dwCompletionOffset])) - { - dwCompletionOffset++; + else if (!blnQuotedParameter && _istspace(m_pchBuffer[dwCompletionOffset])) + { // Found ! We are not inside quored parameter and we are on whitespace. + dwCompletionOffset++; // dwCompletionOffset must point at char AFTER first non-quoted whitespace. break; } } + ASSERT(dwCompletionOffset <= dwCurrentCharOffset); + + // Save not changing part (context) of completion in m_pchBuffer1 _tcsncpy(m_pchBuffer1,m_pchBuffer,dwCompletionOffset); m_pchBuffer1[dwCompletionOffset] = 0; + + // Size of changing part dwCompletionStringSize = dwCurrentCharOffset-dwCompletionOffset; + + // Save intial changing part of completion in m_pchBuffer2 if (dwCompletionStringSize) _tcsncpy(m_pchBuffer2,m_pchBuffer+dwCompletionOffset,dwCompletionStringSize); m_pchBuffer2[dwCompletionStringSize] = 0; + + // Calculate cursor position of point between changing and not changing ports 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); - } + } // if first time tab + const TCHAR *pchCompletion = NULL; + + // Direction BOOL blnForward = !(InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED); - if (m_pfReplaceCompletionCallback) + + if (m_pfReplaceCompletionCallback) // If we are using replace completion callback pchCompletion = m_pfReplaceCompletionCallback(nCompletionIndex, - blnCompletionMode?&blnForward:NULL, - m_pchBuffer1,m_pchBuffer2); - if (pchCompletion) + blnCompletionMode?&blnForward:NULL, // If this is first time we call the completion callback, do not change completion index + m_pchBuffer1,m_pchBuffer2); + + if (pchCompletion) // If completion found { - // Set cursor position + // Set cursor position to compeltion position m_CursorPosition = CompletionPosition; - if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE; + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) + return FALSE; // Calculate buffer free space ASSERT(m_dwBufferSize > dwCompletionOffset); DWORD dwFree = m_dwBufferSize - dwCompletionOffset - 1; + // Save old completion string size DWORD dwOldCompletionStringSize = dwCompletionStringSize; // Write completion string to buffer dwCompletionStringSize = _tcslen(pchCompletion); + // If there is not enough space in buffer, so we truncate the completion if (dwCompletionStringSize > dwFree) dwCompletionStringSize = dwFree; + if (dwCompletionStringSize) { + // Copy competion into main buffer _tcsncpy(m_pchBuffer+dwCompletionOffset,pchCompletion,dwCompletionStringSize); -// m_pchBuffer[dwCompletionOffset+dwCompletionStringSize] = 0; // Write completion string to console - if (!Write(m_pchBuffer+dwCompletionOffset,dwCompletionStringSize)) return FALSE; + if (!Write(m_pchBuffer+dwCompletionOffset,dwCompletionStringSize)) + return FALSE; + + // Set new offsets dwCurrentCharOffset = dwLastCharOffset = dwCompletionOffset + dwCompletionStringSize; + ASSERT(dwLastCharOffset < m_dwBufferSize); } - // Erase rest from previous completion string + // Erase rest from previous completion string, if the new completion is shorter than old if (dwOldCompletionStringSize > dwCompletionStringSize) { _tcsnset(m_pchBuffer+dwCompletionOffset+dwCompletionStringSize,_T(' '), @@ -767,22 +787,12 @@ Paste: // Set cursor position m_CursorPosition = pos; - if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) return FALSE; + if (!SetConsoleCursorPosition(m_hStdOut,m_CursorPosition)) + return FALSE; } + } // If completion found - } - else - { -/* if (InputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) - { - nCompletionIndex++; - } - else - { - if (nCompletionIndex) - nCompletionIndex--; - }*/ - } + // Ok, we are in completion mode blnCompletionMode = TRUE; } else if (_istprint(ch)) @@ -854,14 +864,19 @@ 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_hStdIn = CreateFile("CONIN$",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); + //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; + m_hStdOut = CreateFile("CONOUT$",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); + //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; + if (!GetConsoleScreenBufferInfo(m_hStdOut,&info)) + goto Abort; m_wAttributes = info.wAttributes; if (!m_blnOldInputModeSaved) diff --git a/rosapps/sysutils/regexpl/Console.h b/rosapps/sysutils/regexpl/Console.h index cd766d427db..4157cd2c66d 100644 --- a/rosapps/sysutils/regexpl/Console.h +++ b/rosapps/sysutils/regexpl/Console.h @@ -6,9 +6,7 @@ #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); +#include "Completion.h" class CConsole { @@ -29,6 +27,7 @@ public: BOOL Write(const TCHAR *p, DWORD dwChars = 0); CConsole(); virtual ~CConsole(); + unsigned int GetTabWidth(); private: HANDLE m_hStdOut; HANDLE m_hStdIn; diff --git a/rosapps/sysutils/regexpl/Makefile b/rosapps/sysutils/regexpl/Makefile index ef0f980e039..7f726cfc3ef 100644 --- a/rosapps/sysutils/regexpl/Makefile +++ b/rosapps/sysutils/regexpl/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.3 2000/10/24 20:17:41 narnaoud Exp $ +# $Id: Makefile,v 1.4 2001/01/10 01:25:29 narnaoud Exp $ # # ReactOS makefile for RegExpl # @@ -36,7 +36,6 @@ OBJECTS = \ ShellCommandChangeKey.o \ ShellCommandConnect.o \ ShellCommandDACL.o \ - ShellCommandDOKA.o \ ShellCommandDeleteKey.o \ ShellCommandDeleteValue.o \ ShellCommandDir.o \ @@ -51,6 +50,8 @@ OBJECTS = \ ShellCommandsLinkedList.o \ CrtSupplement.c \ TextHistory.o \ + Completion.o \ + Pattern.o \ $(TARGET_NAME).coff CLEAN_FILES = \ diff --git a/rosapps/sysutils/regexpl/Pattern.cpp b/rosapps/sysutils/regexpl/Pattern.cpp new file mode 100644 index 00000000000..58e79d31a18 --- /dev/null +++ b/rosapps/sysutils/regexpl/Pattern.cpp @@ -0,0 +1,55 @@ +/* $Id: Pattern.cpp,v 1.1 2001/01/10 01:25:29 narnaoud Exp $ + * + * regexpl - Console Registry Explorer + * + * Copyright (C) 2000 Nedko Arnaoudov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +// Pattern.cpp: implementation of pattern functions + +#include "ph.h" + +// based on wstrcmpjoki() by Jason Filby (jasonfilby@yahoo.com) +// reactos kernel, services/fs/vfat/string.c +BOOL PatternMatch(const TCHAR *pszPattern, const TCHAR *pszTry) +{ + while ((*pszPattern == _T('?'))||((_totlower(*pszTry)) == (_totlower(*pszPattern)))) + { + if (((*pszTry) == 0) && ((*pszPattern) == 0)) + return TRUE; + pszTry++; + pszPattern++; + } + + if(*pszPattern == _T('*')) + { + pszPattern++; + while (*pszTry) + { + if (PatternMatch(pszPattern,pszTry)) + return TRUE; + else + pszTry++; + } + } + + if (((*pszTry) == 0) && ((*pszPattern) == 0)) + return TRUE; + + return FALSE; +} diff --git a/rosapps/sysutils/regexpl/Pattern.h b/rosapps/sysutils/regexpl/Pattern.h new file mode 100644 index 00000000000..2aaa0d194ec --- /dev/null +++ b/rosapps/sysutils/regexpl/Pattern.h @@ -0,0 +1,12 @@ +/* $Id: Pattern.h,v 1.1 2001/01/10 01:25:29 narnaoud Exp $ */ + +// Pattern.h: decalration for pattern functions + +#if !defined(PATTERN_H__INCLUDED_) +#define PATTERN_H__INCLUDED_ + +#define PATTERN_MATCH_ALL _T("*") + +BOOL PatternMatch(const TCHAR *pszPattern, const TCHAR *pszTry); + +#endif diff --git a/rosapps/sysutils/regexpl/RegistryExplorer.cpp b/rosapps/sysutils/regexpl/RegistryExplorer.cpp index 4700bc2c7f3..c3765928b69 100644 --- a/rosapps/sysutils/regexpl/RegistryExplorer.cpp +++ b/rosapps/sysutils/regexpl/RegistryExplorer.cpp @@ -1,4 +1,4 @@ -/* $Id: RegistryExplorer.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: RegistryExplorer.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -40,7 +40,7 @@ #include "ShellCommandOwner.h" #include "ShellCommandDACL.h" #include "ShellCommandSACL.h" -#include "ShellCommandDOKA.h" +//#include "ShellCommandDOKA.h" #include "ShellCommandConnect.h" #include "ShellCommandNewKey.h" #include "ShellCommandDeleteKey.h" @@ -49,310 +49,9 @@ TCHAR pchCurrentKey[PROMPT_BUFFER_SIZE]; -CRegistryTree Tree(PROMPT_BUFFER_SIZE+1); +CRegistryTree Tree; 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) @@ -413,8 +112,8 @@ int main () CShellCommandSACL SACLCommand(Tree); CommandsList.AddCommand(&SACLCommand); - CShellCommandDOKA DOKACommand(Tree); - CommandsList.AddCommand(&DOKACommand); + //CShellCommandDOKA DOKACommand(Tree); + //CommandsList.AddCommand(&DOKACommand); CShellCommandConnect ConnectCommand(Tree); CommandsList.AddCommand(&ConnectCommand); @@ -463,14 +162,15 @@ int main () //(_L(__TIMESTAMP__)) )) goto Abort; - Tree.SetDesiredOpenKeyAccess(KEY_READ); + //Tree.SetDesiredOpenKeyAccess(KEY_READ); + const TCHAR *pszCurrentPath; GetCommand: // prompt // TODO: make prompt user-customizable Console.EnableWrite(); - _tcscpy(pchCurrentKey,Tree.GetCurrentPath()); - Console.Write(pchCurrentKey); + pszCurrentPath = Tree.GetCurrentPath(); + Console.Write(pszCurrentPath?pszCurrentPath:_T("NULL (Internal Error)")); Console.Write(_T("\n# ")); Console.FlushInputBuffer(); @@ -478,7 +178,8 @@ GetCommand: // Set command line color // Console.SetTextAttribute(/*FOREGROUND_BLUE|*/FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY); - if (!Console.ReadLine()) goto Abort; + if (!Console.ReadLine()) + goto Abort; // Set normal color // Console.SetTextAttribute(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY); @@ -486,7 +187,6 @@ GetCommand: Console.BeginScrollingOperation(); blnCommandExecutionInProgress = TRUE; - // Parse command line (1st step - convert to multi sz) Parser.SetArgumentList(pchCommand); diff --git a/rosapps/sysutils/regexpl/RegistryExplorer.h b/rosapps/sysutils/regexpl/RegistryExplorer.h index e733aaac471..7d6a1a0ce5b 100644 --- a/rosapps/sysutils/regexpl/RegistryExplorer.h +++ b/rosapps/sysutils/regexpl/RegistryExplorer.h @@ -2,7 +2,7 @@ #ifndef _REGISTRY_EXPLORER_H__INCLUDED #define _REGISTRY_EXPLORER_H__INCLUDED -#define CURRENT_VERSION _T("0.10+") +#define CURRENT_VERSION _T("0.20") #define EMAIL _T("registryexplorer@yahoo.com") //#define __L(x) L ## x @@ -41,11 +41,11 @@ #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 +#define COMMAND_NA_ON_ROOT _T(" is not applicable to root key.\n") + #endif //#ifndef _REGISTRY_EXPLORER_H__INCLUDED diff --git a/rosapps/sysutils/regexpl/RegistryKey.cpp b/rosapps/sysutils/regexpl/RegistryKey.cpp index 36579fe70a1..5429022378f 100644 --- a/rosapps/sysutils/regexpl/RegistryKey.cpp +++ b/rosapps/sysutils/regexpl/RegistryKey.cpp @@ -1,4 +1,4 @@ -/* $Id: RegistryKey.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: RegistryKey.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -27,274 +27,438 @@ #include "ph.h" #include "RegistryKey.h" +static TCHAR *g_ppszHiveNames[] = +{ + _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") +}; + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// -CRegistryKey::CRegistryKey(const TCHAR *pchKeyName, class CRegistryKey *pParent) +CRegistryKey::CRegistryKey() { -// 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); - } + m_pszKeyName = NULL; + m_pszMachineName = NULL; + m_CurrentAccess = 0; + m_hKey = NULL; +} + +HRESULT CRegistryKey::InitRoot(const TCHAR *pszMachineName = NULL) +{ + if ((pszMachineName)&& + ((_tcslen(pszMachineName) < 3)|| + (pszMachineName[0] != _T('\\'))|| + (pszMachineName[1] != _T('\\')) + ) + ) + { + return E_INVALIDARG; + } + + HRESULT hr = Uninit(); + if (FAILED(hr)) + return hr; + + if (pszMachineName) + { // copy machine name + size_t size = _tcslen(pszMachineName); + + m_pszMachineName = new TCHAR [size+2]; + if (!m_pszMachineName) + return E_OUTOFMEMORY; + _tcscpy(m_pszMachineName,pszMachineName); + m_pszMachineName[size] = _T('\\'); + m_pszMachineName[size+1] = 0; + } + else + { + m_pszMachineName = NULL; // local registry + } + + ASSERT(m_pszKeyName == NULL); + m_CurrentAccess = 0; + ASSERT(m_hKey == NULL); + + return S_OK; +} + +HRESULT CRegistryKey::Init(HKEY hKey, const TCHAR *pszPath, const TCHAR *pszKeyName, REGSAM CurrentAccess) +{ + HRESULT hr = Uninit(); + if (FAILED(hr)) + return hr; + + if (!pszKeyName || !hKey) + return E_INVALIDARG; + + // copy key name name + size_t size = _tcslen(pszKeyName); + if (pszPath) + size += _tcslen(pszPath); + + m_pszKeyName = new TCHAR [size+2]; + if (!m_pszKeyName) + return E_OUTOFMEMORY; + _stprintf(m_pszKeyName,_T("%s%s\\"),pszPath?pszPath:_T(""),pszKeyName); + + m_CurrentAccess = CurrentAccess; + m_hKey = hKey; + ASSERT(m_hKey); + + return S_OK; +} + +HRESULT CRegistryKey::Uninit() +{ + if (m_pszKeyName) + { + delete [] m_pszKeyName; + m_pszKeyName = NULL; + } + + if (m_pszMachineName) + { + delete [] m_pszMachineName; + m_pszMachineName = NULL; + } + + LONG nError = ERROR_SUCCESS; + if((m_hKey != NULL)&&(!IsHive(m_hKey))) + nError = RegCloseKey(m_hKey); + + m_hKey = NULL; + + return (nError == ERROR_SUCCESS)?S_OK:E_FAIL; +} + +BOOL CRegistryKey::IsHive(HKEY hKey) +{ + return ((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)); } 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); - } + Uninit(); } -TCHAR * CRegistryKey::GetKeyName() +const TCHAR * CRegistryKey::GetKeyName() { - return m_pchKeyName; + return m_pszKeyName?m_pszKeyName:(m_pszMachineName?m_pszMachineName:_T("\\")); } -class CRegistryKey * CRegistryKey::GetChild() +BOOL CRegistryKey::IsRoot() { - return m_pChild; + return m_hKey == NULL; } -CRegistryKey * CRegistryKey::GetParent() +LONG CRegistryKey::OpenSubkey(REGSAM samDesired, const TCHAR *pszSubkeyName, HKEY &rhKey) { - return m_pParent; + if (m_hKey == NULL) + { // subkey of root key is hive root key. + if ((_tcsicmp(pszSubkeyName,_T("HKCR")) == 0)|| + (_tcsicmp(pszSubkeyName,_T("HKEY_CLASSES_ROOT")) == 0)) + { + rhKey = HKEY_CLASSES_ROOT; + + if (m_pszMachineName) + return ERROR_FILE_NOT_FOUND; + + return ERROR_SUCCESS; + } + else if ((_tcsicmp(pszSubkeyName,_T("HKCU")) == 0)|| + (_tcsicmp(pszSubkeyName,_T("HKEY_CURRENT_USER")) == 0)) + { + rhKey = HKEY_CURRENT_USER; + + if (m_pszMachineName) + return ERROR_FILE_NOT_FOUND; + + return ERROR_SUCCESS; + } + else if ((_tcsicmp(pszSubkeyName,_T("HKLM")) == 0)|| + (_tcsicmp(pszSubkeyName,_T("HKEY_LOCAL_MACHINE")) == 0)) + { + rhKey = HKEY_LOCAL_MACHINE; + + if (m_pszMachineName) + return RegConnectRegistry(m_pszMachineName,rhKey,&rhKey); + + return ERROR_SUCCESS; + } + else if ((_tcsicmp(pszSubkeyName,_T("HKU")) == 0)|| + (_tcsicmp(pszSubkeyName,_T("HKEY_USERS")) == 0)) + { + rhKey = HKEY_USERS; + + if (m_pszMachineName) + return RegConnectRegistry(m_pszMachineName,rhKey,&rhKey); + + return ERROR_SUCCESS; + } + else if ((_tcsicmp(pszSubkeyName,_T("HKPD")) == 0)|| + (_tcsicmp(pszSubkeyName,_T("HKEY_PERFORMANCE_DATA")) == 0)) + { + rhKey = HKEY_PERFORMANCE_DATA; + + if (m_pszMachineName) + return RegConnectRegistry(m_pszMachineName,rhKey,&rhKey); + + return ERROR_SUCCESS; + } + else if ((_tcsicmp(pszSubkeyName,_T("HKDD")) == 0)|| + (_tcsicmp(pszSubkeyName,_T("HKEY_DYN_DATA")) == 0)) + { + rhKey = HKEY_DYN_DATA; + + if (m_pszMachineName) + return RegConnectRegistry(m_pszMachineName,rhKey,&rhKey); + + return ERROR_SUCCESS; + } + else if ((_tcsicmp(pszSubkeyName,_T("HKCC")) == 0)|| + (_tcsicmp(pszSubkeyName,_T("HKEY_CURRENT_CONFIG")) == 0)) + { + rhKey = HKEY_CURRENT_CONFIG; + + if (m_pszMachineName) + { + TCHAR *pch = m_pszMachineName; + while (*pch) + pch++; + pch--; + + ASSERT(*pch == _T('\\')); + if (*pch != _T('\\')) + return ERROR_INTERNAL_ERROR; + + *pch = 0; + + LONG nError = RegConnectRegistry(m_pszMachineName,rhKey,&rhKey); + + *pch = _T('\\'); + + return nError; + } + + return ERROR_SUCCESS; + } + else + { + return ERROR_FILE_NOT_FOUND; + } + } + + return RegOpenKeyEx(m_hKey,pszSubkeyName,0,samDesired,&rhKey); } -CRegistryKey * CRegistryKey::UpOneLevel() +LONG CRegistryKey::OpenSubkey(REGSAM samDesired, const TCHAR *pszSubkeyName, CRegistryKey &rKey) { - CRegistryKey *pParent = m_pParent; - ASSERT(m_pChild == NULL); - if (pParent) - { - ASSERT(pParent->m_pChild == this); - pParent->m_pChild = NULL; - } - delete this; - return pParent; + HKEY hKey; + LONG nError = OpenSubkey(samDesired, pszSubkeyName, hKey); + + if (nError == ERROR_SUCCESS) + { + const TCHAR *pszKeyName = GetKeyName(); + size_t size = _tcslen(pszKeyName) + _tcslen(pszSubkeyName) + 1; + TCHAR *pszSubkeyFullName = new TCHAR [size]; + if (!pszSubkeyFullName) + { + nError = RegCloseKey(hKey); + ASSERT(nError == ERROR_SUCCESS); + return ERROR_OUTOFMEMORY; + } + _tcscpy(pszSubkeyFullName,pszKeyName); + _tcscat(pszSubkeyFullName,pszSubkeyName); + HRESULT hr = rKey.Init(hKey,GetKeyName(),pszSubkeyName,samDesired); + delete pszSubkeyName; + if (FAILED(hr)) + { + nError = RegCloseKey(hKey); + ASSERT(nError == ERROR_SUCCESS); + if (hr == (HRESULT)E_OUTOFMEMORY) + return ERROR_OUTOFMEMORY; + else + return ERROR_INTERNAL_ERROR; + } + } + + return nError; } -void CRegistryKey::InitSubKeyEnumeration() +LONG CRegistryKey::GetSubkeyNameMaxLength(DWORD &rdwMaxSubkeyNameLength) { - m_dwCurrentSubKeyIndex = 0; + if (m_hKey == NULL) + { // root key + rdwMaxSubkeyNameLength = 0; + for(int i = 0; i < 7 ; i++) + { + size_t l = _tcslen(g_ppszHiveNames[i]); + if (rdwMaxSubkeyNameLength < l) + rdwMaxSubkeyNameLength = l; + } + + rdwMaxSubkeyNameLength++; // terminating null + + return ERROR_SUCCESS; + } + + LONG nRet; + + nRet = RegQueryInfoKey(m_hKey,NULL,NULL,NULL,NULL,&rdwMaxSubkeyNameLength,NULL,NULL,NULL,NULL,NULL,NULL); + + rdwMaxSubkeyNameLength = (nRet == ERROR_SUCCESS)?(rdwMaxSubkeyNameLength+1):0; + + return nRet; } -TCHAR * CRegistryKey::GetSubKeyName(DWORD& dwError) +void CRegistryKey::InitSubkeyEnumeration(TCHAR *pszSubkeyNameBuffer, DWORD dwBufferSize) { - static TCHAR m_pchSubName[MAX_PATH+1]; - dwError = RegEnumKey(m_hKey,m_dwCurrentSubKeyIndex,m_pchSubName,MAX_PATH + 1); + m_pchSubkeyNameBuffer = pszSubkeyNameBuffer; + m_dwSubkeyNameBufferSize = dwBufferSize; + m_dwCurrentSubKeyIndex = 0; +} + +LONG CRegistryKey::GetNextSubkeyName(DWORD *pdwActualSize) +{ + LONG nError; + + if (m_hKey == NULL) + { + if (m_dwCurrentSubKeyIndex < (DWORD)(m_pszMachineName?5:7)) + { + DWORD dwIndex = m_pszMachineName?m_dwCurrentSubKeyIndex+2:m_dwCurrentSubKeyIndex; + _tcsncpy(m_pchSubkeyNameBuffer,g_ppszHiveNames[dwIndex],m_dwSubkeyNameBufferSize); + nError = ERROR_SUCCESS; + if (pdwActualSize) + *pdwActualSize = strlen(m_pchSubkeyNameBuffer); + } + else + { + nError = ERROR_NO_MORE_ITEMS; + } + } + else + { + DWORD dwActualSize = m_dwSubkeyNameBufferSize; + FILETIME ft; + nError = RegEnumKeyEx(m_hKey, + m_dwCurrentSubKeyIndex, + m_pchSubkeyNameBuffer, + &dwActualSize, + NULL, + NULL, + NULL, + &ft); + if (pdwActualSize) + *pdwActualSize = dwActualSize; + } + m_dwCurrentSubKeyIndex++; - switch (dwError) - { - case ERROR_SUCCESS: - return m_pchSubName; - case ERROR_NO_MORE_ITEMS: - return NULL; - default: - return NULL; - } + + if (pdwActualSize) + *pdwActualSize = strlen(m_pchSubkeyNameBuffer); + return nError; } -void CRegistryKey::UpdateKeyNameCase() +LONG CRegistryKey::GetSubkeyCount(DWORD &rdwSubkeyCount) { - 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; - } - } + return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,&rdwSubkeyCount,NULL,NULL,NULL,NULL,NULL,NULL,NULL); } -void CRegistryKey::InitValueEnumeration() +LONG CRegistryKey::GetMaxValueDataSize(DWORD& rdwMaxValueDataBuferSize) { + return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&rdwMaxValueDataBuferSize,NULL,NULL); +} + +LONG CRegistryKey::GetMaxValueNameLength(DWORD& rdwMaxValueNameBuferSize) +{ + if (!m_hKey) + return 0; // the root key abstraction has only subkeys (hives) + + LONG nError = RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&rdwMaxValueNameBuferSize,NULL,NULL,NULL); + + rdwMaxValueNameBuferSize++; + return nError; +} + +void CRegistryKey::InitValueEnumeration(TCHAR *pszValueNameBuffer, + DWORD dwValueNameBufferSize, + BYTE *pbValueDataBuffer, + DWORD dwValueDataBufferSize, + DWORD *pdwType) +{ + m_pszValueNameBuffer = pszValueNameBuffer; + m_dwValueNameBufferSize = dwValueNameBufferSize; + m_pbValueDataBuffer = pbValueDataBuffer; + m_dwValueDataBufferSize = dwValueDataBufferSize; + m_pdwType = pdwType; + 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) +LONG CRegistryKey::GetNextValue(DWORD *pdwNameActualSize, DWORD *pdwDataActualSize) { - DWORD dwRet = RegEnumValue(m_hKey,m_dwCurrentValueIndex,pchValueNameBuffer,&dwValueNameSize,NULL, - pdwType,lpValueDataBuffer,pdwValueDataSize); + if (!m_hKey) + return ERROR_NO_MORE_ITEMS; // the root key abstraction has only subkeys (hives) + + DWORD dwValueNameBufferSize = m_dwValueNameBufferSize; + DWORD dwValueDataBufferSize = m_dwValueDataBufferSize; + LONG nError = RegEnumValue(m_hKey, + m_dwCurrentValueIndex, + m_pszValueNameBuffer, + &dwValueNameBufferSize, + NULL, + m_pdwType, + m_pbValueDataBuffer, + &dwValueDataBufferSize); + + if (pdwNameActualSize) + *pdwNameActualSize = dwValueNameBufferSize; + + if (pdwDataActualSize) + *pdwDataActualSize = dwValueDataBufferSize; + m_dwCurrentValueIndex++; - return dwRet; + return nError; } -void CRegistryKey::GetLastWriteTime(SYSTEMTIME &st) +LONG CRegistryKey::GetValueCount(DWORD& rdwValueCount) { - FILETIME ftLocal,ft; - RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, - &ft); - FileTimeToLocalFileTime(&ft,&ftLocal); - FileTimeToSystemTime(&ftLocal,&st); + if (!m_hKey) + return 0; // the root key abstraction has only subkeys (hives) + + return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,&rdwValueCount,NULL,NULL,NULL,NULL); } -TCHAR * CRegistryKey::GetLastWriteTime() +LONG CRegistryKey::GetDefaultValue(DWORD *pdwType, + BYTE *pbValueDataBuffer, + DWORD dwValueDataBufferSize, + DWORD *pdwValueDataActualSize) { - 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; -} + DWORD dwBufferSize = dwValueDataBufferSize; + + LONG nError = RegQueryValueEx(m_hKey,NULL,NULL,pdwType,pbValueDataBuffer,&dwBufferSize); -// 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); -} + if (pdwValueDataActualSize && (nError == ERROR_SUCCESS)) + *pdwValueDataActualSize = dwBufferSize; -// 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 + return nError; } const TCHAR * CRegistryKey::GetValueTypeName(DWORD dwType) @@ -302,29 +466,29 @@ const TCHAR * CRegistryKey::GetValueTypeName(DWORD dwType) switch(dwType) { case REG_NONE: - return _T("REG_NONE\t\t"); + return _T("REG_NONE"); case REG_SZ: - return _T("REG_SZ\t\t\t"); + return _T("REG_SZ"); case REG_EXPAND_SZ: - return _T("REG_EXPAND_SZ\t\t"); + return _T("REG_EXPAND_SZ"); case REG_BINARY: - return _T("REG_BINARY\t\t"); + return _T("REG_BINARY"); case REG_DWORD_LITTLE_ENDIAN: - return _T("REG_DWORD_LITTLE_ENDIAN\t"); + return _T("REG_DWORD_LITTLE_ENDIAN"); case REG_DWORD_BIG_ENDIAN: - return _T("REG_DWORD_BIG_ENDIAN\t"); + return _T("REG_DWORD_BIG_ENDIAN"); case REG_LINK: - return _T("REG_LINK\t\t"); + return _T("REG_LINK"); case REG_MULTI_SZ: - return _T("REG_MULTI_SZ\t\t"); + return _T("REG_MULTI_SZ"); case REG_RESOURCE_LIST: - return _T("REG_RESOURCE_LIST\t"); + return _T("REG_RESOURCE_LIST"); 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"); + return _T("Unkown Type"); } } @@ -333,7 +497,57 @@ DWORD CRegistryKey::GetValue(TCHAR *pchValueName, DWORD *pdwType, LPBYTE lpValue return RegQueryValueEx(m_hKey,pchValueName,NULL,pdwType,lpValueDataBuffer,pdwValueDataSize); } -DWORD CRegistryKey::GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor) +LONG CRegistryKey::CreateSubkey(REGSAM samDesired, + const TCHAR *pszSubkeyName, + HKEY &rhKey, + BOOL *pblnOpened, + BOOL blnVolatile) +{ + DWORD dwDisposition; + + LONG nError = RegCreateKeyEx( + m_hKey, + pszSubkeyName, + 0, + NULL, + blnVolatile?REG_OPTION_VOLATILE:REG_OPTION_NON_VOLATILE, + samDesired, + NULL, + &rhKey, + &dwDisposition); + + if ((nError == ERROR_SUCCESS)&&(pblnOpened)) + *pblnOpened = dwDisposition == REG_OPENED_EXISTING_KEY; + + return nError; +} + +LONG CRegistryKey::GetLastWriteTime(SYSTEMTIME &st) +{ + FILETIME ftLocal,ft; + LONG nError = RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&ft); + + if (nError == ERROR_SUCCESS) + { + FileTimeToLocalFileTime(&ft,&ftLocal); + FileTimeToSystemTime(&ftLocal,&st); + } + + return nError; +} + +const TCHAR * CRegistryKey::GetLastWriteTime() +{ + SYSTEMTIME st; + if (GetLastWriteTime(st) != ERROR_SUCCESS) + return _T("(Cannot get time last write time)"); + + 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; +} + +LONG CRegistryKey::GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor) { return RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,pdwSecurityDescriptor,NULL); @@ -344,115 +558,17 @@ LONG CRegistryKey::GetSecurityDescriptor(SECURITY_INFORMATION SecurityInformatio return RegGetKeySecurity(m_hKey,SecurityInformation,pSecurityDescriptor,lpcbSecurityDescriptor); } -DWORD CRegistryKey::GetSubKeyCount() +LONG CRegistryKey::DeleteSubkey(const TCHAR *pszSubkeyName) { - DWORD nCount; - DWORD nRet = RegQueryInfoKeyW(m_hKey,NULL,NULL,NULL,&nCount,NULL,NULL,NULL, - NULL,NULL,NULL,NULL); - if (nRet) - return 0; - return nCount; + return RegDeleteKey(m_hKey,pszSubkeyName); } -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) +LONG CRegistryKey::SetValue(LPCTSTR pszValueName, DWORD dwType, BYTE *lpData, DWORD dwDataSize) { return RegSetValueEx(m_hKey,pszValueName,0,dwType,lpData,dwDataSize); } -DWORD CRegistryKey::DeleteValue(LPCTSTR pszValueName) +LONG CRegistryKey::DeleteValue(const TCHAR *pszValueName) { return RegDeleteValue(m_hKey,pszValueName); } diff --git a/rosapps/sysutils/regexpl/RegistryKey.h b/rosapps/sysutils/regexpl/RegistryKey.h index 38363e55c0b..2de780c4275 100644 --- a/rosapps/sysutils/regexpl/RegistryKey.h +++ b/rosapps/sysutils/regexpl/RegistryKey.h @@ -8,48 +8,250 @@ class CRegistryKey { public: - DWORD DeleteValue(LPCTSTR pszValueName); - 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); + // Constructor. Call InitXXX methods to make real construct. + CRegistryKey(); + + // Call this key to init root key. + // + // Parameters: + // pszMachineName - pointer to buffer containing machine name. NULL means local machine. + // + // Return value: + // S_OK - All ok. + // E_XXX - Error. + HRESULT InitRoot(const TCHAR *pszMachineName = NULL); + + // Call this method to init normal key. + // + // Parameters: + // hKey - handle to opened key. + // pszPath - optional path string. NULL if pszKeyName is the needed name. + // pszKeyName - pointer to buffer conatining name of key. + // CurrentAccess - Access of hKey. + // + // Remarks: + // Constructs key object from handle. + // The constructed object hold the handle and closes it on destruction. Do not close handle outside. + // If pszPath is not NULL, it is concatenated with pszKeyName. + // + // Return value: + // S_OK - All ok. + // E_XXX - Error. + HRESULT Init(HKEY hKey, const TCHAR *pszPath, const TCHAR *pszKeyName, REGSAM CurrentAccess); + + // Call this method to uninitialize the object. + // + // Return value: + // S_OK - All ok. + // E_XXX - Error. + HRESULT Uninit(); + + // Destructor virtual ~CRegistryKey(); + + // Call ths function to check if handle to key is handle to hive root. + // + // Parameters: + // hKey - handle to check. + // + // Return value: + // TRUE - hKey is handle to hive root. + // FALSE - hKey is not handle to hive root. + static BOOL IsHive(HKEY hKey); + + // Call this method to get name of key represented by this object. + // + // Return value: + // Pointer to buffer containing key name. Return value is valid until next call to this object method. + const TCHAR * GetKeyName(); + + BOOL IsRoot(); + + // Call this method to open existing subkey of this key. + // + // Parameters: + // samDesired - deisred access. + // pszSubkeyName - pointer to bufer containing name of key to open. + // rhKey - reference to variable that receives handle of opened key. If method fails, variable value is unchanged. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + LONG OpenSubkey(REGSAM samDesired, const TCHAR *pszSubkeyName, HKEY &rhKey); + + // Call this method to open existing subkey of this key. + // + // Parameters: + // samDesired - deisred access. + // pszSubkeyName - pointer to bufer containing name of key to open. + // rKey - reference to CRegistryKey object. If method succeeds, rKey is initialized with newly opened key. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + LONG OpenSubkey(REGSAM samDesired, const TCHAR *pszSubkeyName, CRegistryKey &rKey); + + // Call this method to get the length in TCHARs of longest subkey name, including terminating null. + // + // Parameters: + // rdwMaxSubkeyNameLength, reference to variable that receives size in TCHARs of longest subkey name. + // + // Return value. + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + LONG GetSubkeyNameMaxLength(DWORD &rdwMaxSubkeyNameLength); + + // Call this method to init subkey enumeration. I.e. before first call to GetSubkeyName() + // + // Parameters: + // pchSubkeyNameBuffer - pointer to buffer receiving subkey name. + // dwBufferSize - size, in TCHARs of buffer pointed by pchSubkeyNameBuffer. + // + void InitSubkeyEnumeration(TCHAR *pchSubkeyNameBuffer, DWORD dwBufferSize); + + // Call this method to get next subkey name. Name is stored in buffer specified in call to InitSubKeyEnumeration. + // + // Parameters: + // pdwActualSize - optional pointer to variable receiving actual size, in TCHARs, of key name. The count returned does not include the terminating null. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + // If no more items available, return error is ERROR_NO_MORE_ITEMS. + LONG GetNextSubkeyName(DWORD *pdwActualSize = NULL); + + // Call this method to get count of subkeys. + // + // Parameters: + // rdwSubkeyCount - reference to variable that receives subkey count. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + LONG GetSubkeyCount(DWORD &rdwSubkeyCount); + + // Call this method to get the length in TCHARs of longest value name, including terminating null. + // + // Parameters: + // rdwMaxValueNameBufferSize receives the length, in TCHARs, of the key's longest value name. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + LONG GetMaxValueNameLength(DWORD& rdwMaxValueNameBufferSize); + + // Call this method to get the size of larges value data. + // + // Parameters: + // rdwMaxValueDataBufferSize receives the length, in bytes, of the longest data component among the key's values. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + LONG GetMaxValueDataSize(DWORD& rdwMaxValueDataBufferSize); + + // Call this method to init subkey enumeration. I.e. before first call to GetSubkeyName() + // + // Parameters: + // pszValueNameBuffer - pointer to buffer receiving value name. If NULL, value name in not received upon iteration. + // dwValueNameBufferSize - size, in TCHARs of buffer pointed by pszValueNameBuffer. If pszValueNameBuffer is NULL, parameter is ignored. + // pbValueDataBuffer - pointer to buffer receiving value name. If NULL, value data is not received upon iteration. + // dwValueDataBufferSize - size, in bytes of buffer pointed by pbValueDataBuffer. If pbValueDataBuffer is NULL, parameter is ignored. + // pdwType - pointer to variable receiving value type. If NULL, value type is not received upon iteration. + void InitValueEnumeration(TCHAR *pszValueNameBuffer, + DWORD dwValueNameBufferSize, + BYTE *pbValueDataBuffer, + DWORD dwValueDataBufferSize, + DWORD *pdwType); + + // Call this method to get next value name/data/type. Name/data/type is/are stored in buffer(s) specified in call to InitValueEnumeration. + // + // Parameters: + // pdwNameActualSize - optional pointer to variable receiving actual size, in TCHARs, of value name. The count returned includes the terminating null. + // pdwActualSize - optional pointer to variable receiving actual size, in bytes, of key name. The count returned does not include the terminating null. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + // If no more items available, return error is ERROR_NO_MORE_ITEMS. + LONG GetNextValue(DWORD *pdwNameActualSize = NULL, DWORD *pdwDataActualSize = NULL); + + // Call this method to get count of values. + // + // Parameters: + // rdwValueCount - reference to variable that receives value count. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + LONG GetValueCount(DWORD& rdwValueCount); + + // Call this method to get data and/or type of default value. + // + // Parameters: + // pdwType - optional pointer to variable receiving default value type. NULL if not requred. + // pbValueDataBuffer - optional pointer to buffer receiving default value data. NULL if not requred. + // dwValueDataBufferSize - size of buffer pointer by pbValueDataBuffer. Ignored if pbValueDataBuffer is NULL. + // pdwValueDataActualSize - optional pointer to variable receiving size, in bytes, of data stored into buffer. If pbValueDataBuffer is NULL, returned value is size of default value data, in bytes. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + LONG GetDefaultValue(DWORD *pdwType, BYTE *pbValueDataBuffer, DWORD dwValueDataBufferSize, DWORD *pdwValueDataActualSize); + + // Call this function to get text representation of value type. + // + // Parameters: + // dwType - type to get text representation from. + // + // Return value: + // text representation od value type. + static const TCHAR * GetValueTypeName(DWORD dwType); + + DWORD GetValue(TCHAR *pchValueName, DWORD *pdwType, LPBYTE lpValueDataBuffer, DWORD *pdwValueDataSize); + + // Call this method to create subkey of this key. + // + // Parameters: + // samDesired - deisred access. + // pszKeyName - pointer to bufer containing name of key to create. + // rhKey - reference to variable that receives handle of opened key. If method fails, variable value is unchanged. + // pblnOpened - optional pointer to variable that receives create/open status. If subkey is opened value is TRUE. If key is created value is FALSE. + // blnVolatile - opitional parameter specifining if created key is volatile. + // + // Return value: + // If the method succeeds, the return value is ERROR_SUCCESS. + // If the method fails, the return value is a nonzero error code defined in winerror.h. + LONG CreateSubkey(REGSAM samDesired, const TCHAR *pszKeyName, HKEY &rhKey, BOOL *pblnOpened = NULL, BOOL blnVolatile = FALSE); + + LONG GetLastWriteTime(SYSTEMTIME& st); + const TCHAR * GetLastWriteTime(); + + LONG DeleteValue(const TCHAR *pszValueName); + LONG DeleteSubkey(const TCHAR *pszPatternSubkeyName); + + LONG SetValue(LPCTSTR pszValueName, DWORD dwType, BYTE *lpData, DWORD dwDataSize); + TCHAR * GetSubKeyNameByIndex(DWORD dwIndex); + LONG GetSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor); + LONG GetSecurityDescriptorLength(DWORD *pdwSecurityDescriptor); + BOOL IsPredefined(); + operator HKEY(){return m_hKey;}; private: DWORD m_dwCurrentSubKeyIndex; + TCHAR *m_pchSubkeyNameBuffer; + DWORD m_dwSubkeyNameBufferSize; + DWORD m_dwCurrentValueIndex; + TCHAR *m_pszValueNameBuffer; + DWORD m_dwValueNameBufferSize; + BYTE *m_pbValueDataBuffer; + DWORD m_dwValueDataBufferSize; + DWORD *m_pdwType; + 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]; + TCHAR *m_pszKeyName; + TCHAR *m_pszMachineName; + REGSAM m_CurrentAccess; }; #endif // !defined(REGISTRYKEY_H__FEF419ED_6EB6_11D3_907D_204C4F4F5020__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/RegistryTree.cpp b/rosapps/sysutils/regexpl/RegistryTree.cpp index b1f26d5c711..4d38cd8730e 100644 --- a/rosapps/sysutils/regexpl/RegistryTree.cpp +++ b/rosapps/sysutils/regexpl/RegistryTree.cpp @@ -1,4 +1,4 @@ -/* $Id: RegistryTree.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: RegistryTree.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -21,37 +21,44 @@ */ // RegistryTree.cpp: implementation of the CRegistryTree class. -// -////////////////////////////////////////////////////////////////////// #include "ph.h" #include "RegistryTree.h" +#include "Pattern.h" +#include "RegistryExplorer.h" -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CRegistryTree::CRegistryTree(unsigned int nMaxPathSize) +CRegistryTree::CRegistryTree() { m_pszMachineName = NULL; - m_samDesiredOpenKeyAccess = 0; - m_pCurrentKey = m_pRoot = NULL; + VERIFY(SUCCEEDED(m_Root.m_Key.InitRoot())); + m_Root.m_pUp = NULL; + m_pCurrentKey = &m_Root; + ASSERT(m_pCurrentKey->m_Key.IsRoot()); 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); + VERIFY(SUCCEEDED(m_Root.m_Key.InitRoot())); + m_Root.m_pUp = NULL; + m_pCurrentKey = &m_Root; + ASSERT(m_pCurrentKey->m_Key.IsRoot()); + + const TCHAR *pszPath = Tree.GetCurrentPath(); + if ((pszPath[0] == _T('\\')) && (pszPath[1] == _T('\\'))) + { // path has machine name + pszPath += 2; + while (*pszPath && (*pszPath != _T('\\'))) + pszPath++; + + ASSERT(*pszPath == _T('\\')); // if path begins with \\ it must be followed by machine name + } + + if (Tree.m_pszMachineName) + SetMachineName(Tree.m_pszMachineName); + + VERIFY(ChangeCurrentKey(pszPath)); } CRegistryTree::~CRegistryTree() @@ -59,388 +66,574 @@ CRegistryTree::~CRegistryTree() if (m_pszMachineName) delete m_pszMachineName; - CRegistryKey *pNode; - while(m_pRoot) + CNode *pNode; + while(m_pCurrentKey->m_pUp) { - pNode = m_pRoot; - m_pRoot = m_pRoot->GetChild(); + pNode = m_pCurrentKey; + m_pCurrentKey = m_pCurrentKey->m_pUp; delete pNode; } - delete [] m_ChangeKeyBuffer; + // We are on root + ASSERT(m_pCurrentKey->m_Key.IsRoot()); + ASSERT(m_pCurrentKey == &m_Root); } 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; + return m_pCurrentKey->m_Key.GetKeyName(); } BOOL CRegistryTree::IsCurrentRoot() { - return m_pRoot == NULL; + return m_pCurrentKey->m_Key.IsRoot(); } -// returns TRUE on success and FALSE on fail -// on fail, extended information can be received by calling GetLastErrorDescription(); -BOOL CRegistryTree::ChangeCurrentKey(const TCHAR *pchRelativePath) +BOOL CRegistryTree::ChangeCurrentKey(const TCHAR *pszRelativePath) { - if (*pchRelativePath == _T('\\')) + if (*pszRelativePath == _T('\\')) + GotoRoot(); // This is full absolute path. + + // split path to key names. + TCHAR *pszSeps = _T("\\"); + + // Make buffer and copy relative path into it. + TCHAR *pszBuffer = new TCHAR[_tcslen(pszRelativePath)+1]; + if (!pszBuffer) + { + SetError(ERROR_OUTOFMEMORY); + return FALSE; + } + + _tcscpy(pszBuffer,pszRelativePath); + + // We accept names in form "\"blablabla\\blab labla\"\\" + size_t size = _tcslen(pszBuffer); + if (size) + { + if (pszBuffer[size-1] == _T('\\')) + pszBuffer[--size] = 0; + + if ((*pszBuffer == _T('\"'))&&(pszBuffer[size-1] == _T('\"'))) + { + size--; + pszBuffer[size] = 0; LONG ConnectRegistry(HKEY hKey); + + pszBuffer++; + } + } + + TCHAR *pszNewKey = _tcstok(pszBuffer,pszSeps); + + if ((!pszNewKey)&&((*pszRelativePath != _T('\\'))||(*(pszRelativePath+1) != 0))) { - 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; + SetError(_T("Invalid key name")); + goto Abort; }; - while (pchNewKey) + + // change keys + while (pszNewKey) { - 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 + if (!InternalChangeCurrentKey(pszNewKey,KEY_READ)) + goto Abort; // InternalChangeCurrentKey sets last error description - 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); + pszNewKey = _tcstok(NULL,pszSeps); } + return TRUE; + +Abort: + delete pszBuffer; + return FALSE; } -TCHAR * CRegistryTree::GetLastErrorDescription() +const TCHAR * CRegistryTree::GetLastErrorDescription() { return m_ErrorMsg; } -CRegistryKey * CRegistryTree::GetCurrentKey() +void CRegistryTree::GotoRoot() { - return m_pCurrentKey; + // Delete current tree + CNode *pNode; + while(m_pCurrentKey->m_pUp) + { + pNode = m_pCurrentKey; + m_pCurrentKey = m_pCurrentKey->m_pUp; + delete pNode; + } + + // We are on root + ASSERT(m_pCurrentKey->m_Key.IsRoot()); + ASSERT(m_pCurrentKey == &m_Root); } -void CRegistryTree::SetDesiredOpenKeyAccess(REGSAM samDesired) +BOOL CRegistryTree::SetMachineName(LPCTSTR pszMachineName) { - m_samDesiredOpenKeyAccess = samDesired; + GotoRoot(); + + // If we are going to local machine... + if (pszMachineName == NULL) + { + // Delete previous machine name buffer if allocated. + if (m_pszMachineName) + delete m_pszMachineName; + + m_pszMachineName = NULL; + m_Root.m_Key.InitRoot(); + return TRUE; + } + + // Skip leading backslashes if any. + while ((*pszMachineName)&&(*pszMachineName == _T('\\'))) + pszMachineName++; + + ASSERT(*pszMachineName); // No machine name. + + TCHAR *pszNewMachineName = new TCHAR[_tcslen(pszMachineName)+3]; // two leading backslashes + terminating null + + if (!pszMachineName) + { + SetError(ERROR_OUTOFMEMORY); + return FALSE; + } + + // Delete previous machine name buffer if allocated. + if (m_pszMachineName) + delete m_pszMachineName; + + m_pszMachineName = pszNewMachineName; + + _tcscpy(m_pszMachineName,_T("\\\\")); // leading backslashes + _tcscpy(m_pszMachineName+2,pszMachineName); // machine name itself + _tcsupr(m_pszMachineName+2); // upercase it + + VERIFY(SUCCEEDED(m_Root.m_Key.InitRoot(m_pszMachineName))); + return TRUE; } -REGSAM CRegistryTree::GetDesiredOpenKeyAccess() const +BOOL CRegistryTree::NewKey(const TCHAR *pszKeyName, const TCHAR *pszPath, BOOL blnVolatile) { - return m_samDesiredOpenKeyAccess; -} + if (!m_pCurrentKey) + { + SetErrorCommandNAOnRoot(_T("Creating new key ")); + return FALSE; + } -int CRegistryTree::ConnectRegistry(HKEY hKey) -{ - CRegistryKey *pKey = new CRegistryKey(hKey,m_pszMachineName); - int ret = pKey->Open(m_samDesiredOpenKeyAccess); - - if (ret == 0) + CRegistryTree Tree(*this); + if (!Tree.ChangeCurrentKey(pszPath)) + { + SetError(Tree.GetLastErrorDescription()); + return FALSE; + } + + BOOL blnOpened; + HKEY hKey; + + LONG nError = Tree.m_pCurrentKey->m_Key.CreateSubkey(KEY_READ, + pszKeyName, + hKey, + &blnOpened, + blnVolatile); + if (nError == ERROR_SUCCESS) + { + LONG nError = RegCloseKey(hKey); + ASSERT(nError == ERROR_SUCCESS); + } + + if ((nError == ERROR_SUCCESS) && blnOpened) { - CRegistryKey *pNode; - while(m_pRoot) - { - pNode = m_pRoot; - m_pRoot = m_pRoot->GetChild(); - delete pNode; - } - m_pCurrentKey = NULL; - m_pRoot = m_pCurrentKey = pKey; + SetError(_T("A key \"%s\" already exists."),pszKeyName); + return FALSE; } - else + + if (nError != ERROR_SUCCESS) { - delete pKey; + SetError(_T("Cannot create key : %s%s\nError %d (%s)\n"), + GetCurrentPath(),pszKeyName,nError,GetErrorDescription(nError)); + + return FALSE; } - 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) +BOOL CRegistryTree::DeleteSubkeys(const TCHAR *pszKeyPattern, const TCHAR *pszPath, 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; + CRegistryKey Key; + if (!GetKey(pszPath,KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS|DELETE,Key)) + return FALSE; + + return DeleteSubkeys(Key, pszKeyPattern, blnRecursive); } + +BOOL CRegistryTree::DeleteSubkeys(CRegistryKey& rKey, const TCHAR *pszKeyPattern, BOOL blnRecursive) +{ + LONG nError; + + // enumerate subkeys + DWORD dwMaxSubkeyNameLength; + nError = rKey.GetSubkeyNameMaxLength(dwMaxSubkeyNameLength); + if (nError != ERROR_SUCCESS) + { + SetError(_T("Cannot delete subkeys(s) of key %s.\nRequesting info about key failed.\nError %d (%s)\n"), + rKey.GetKeyName(),nError,GetErrorDescription(nError)); + return FALSE; + } + + TCHAR *pszSubkeyName = new TCHAR [dwMaxSubkeyNameLength]; + rKey.InitSubkeyEnumeration(pszSubkeyName, dwMaxSubkeyNameLength); + BOOL blnKeyDeleted = FALSE; + while ((nError = rKey.GetNextSubkeyName()) == ERROR_SUCCESS) + { + if (blnRecursive) + { // deltion is recursive, delete subkey subkeys + CRegistryKey Subkey; + // open subkey + nError = rKey.OpenSubkey(DELETE,pszSubkeyName,Subkey); + // delete subkey subkeys + if (DeleteSubkeys(Subkey, PATTERN_MATCH_ALL, TRUE)) + { + AddErrorDescription(_T("Cannot delete subkey(s) of key %s. Subkey deletion failed.\n"),Subkey.GetKeyName()); + return FALSE; + } + } + + if (PatternMatch(pszKeyPattern,pszSubkeyName)) + { + nError = rKey.DeleteSubkey(pszSubkeyName); + if (nError != ERROR_SUCCESS) + { + SetError(_T("Cannot delete the %s subkey of key %s.\nError %d (%s)\n"), + pszSubkeyName,rKey.GetKeyName(),nError,GetErrorDescription(nError)); + + return FALSE; + } + blnKeyDeleted = TRUE; + } + } + + ASSERT(nError != ERROR_SUCCESS); + if (nError != ERROR_NO_MORE_ITEMS) + { + SetError(_T("Cannot delete subkeys(s) of key %s.\nSubkey enumeration failed.\nError %d (%s)\n"), + rKey.GetKeyName(),nError,GetErrorDescription(nError)); + return FALSE; + } + + if (!blnKeyDeleted) + SetError(_T("The key %s has no subkeys that match %s pattern.\n"),rKey.GetKeyName(),pszKeyPattern); + + return blnKeyDeleted; +} + +const TCHAR * CRegistryTree::GetErrorDescription(LONG nError) +{ + switch(nError) + { + case ERROR_ACCESS_DENIED: + return _T("Access denied"); + case ERROR_FILE_NOT_FOUND: + return _T("The system cannot find the key specified"); + case ERROR_INTERNAL_ERROR: + return _T("Internal error"); + case ERROR_OUTOFMEMORY: + return _T("Out of memory"); + default: + return _T("Unknown error"); + } +} + +void CRegistryTree::SetError(LONG nError) +{ + SetError(_T("Error %u (%s)"),nError,GetErrorDescription(nError)); +} + +void CRegistryTree::SetError(const TCHAR *pszFormat, ...) +{ + va_list args; + va_start(args,pszFormat); + if (_vsntprintf(m_ErrorMsg,ERROR_MSG_BUFFER_SIZE,pszFormat,args) < 0) + m_ErrorMsg[ERROR_MSG_BUFFER_SIZE] = 0; + va_end(args); +} + +void CRegistryTree::SetInternalError() +{ + SetError(_T("Internal Error")); +} + +void CRegistryTree::AddErrorDescription(const TCHAR *pszFormat, ...) +{ + size_t size = _tcslen(m_ErrorMsg); + if (size < ERROR_MSG_BUFFER_SIZE) + { + TCHAR *pszAdd = m_ErrorMsg+size; + va_list args; + va_start(args,pszFormat); + size = ERROR_MSG_BUFFER_SIZE-size; + if (_vsntprintf(pszAdd,size,pszFormat,args) < 0) + m_ErrorMsg[size] = 0; + va_end(args); + } +} + +void CRegistryTree::SetErrorCommandNAOnRoot(const TCHAR *pszCommand) +{ + ASSERT(pszCommand); + if (pszCommand) + SetError(_T("%s") COMMAND_NA_ON_ROOT,pszCommand); + else + SetInternalError(); +} + +BOOL CRegistryTree::InternalChangeCurrentKey(const TCHAR *pszSubkeyName, REGSAM DesiredAccess) +{ + size_t size = _tcslen(pszSubkeyName); + TCHAR *pszSubkeyNameBuffer = new TCHAR[size+3]; + if (!pszSubkeyNameBuffer) + { + SetError(_T("Cannot open key : %s%s\nError %d (%s)\n"), + GetCurrentPath(),pszSubkeyName,ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY)); + } + + _tcscpy(pszSubkeyNameBuffer,pszSubkeyName); + if (size && (pszSubkeyName[0] == _T('\"')) && (pszSubkeyName[size-1] == _T('\"'))) + { + pszSubkeyNameBuffer[size-1] = 0; + pszSubkeyName = pszSubkeyNameBuffer+1; + } + + if (_tcscmp(pszSubkeyName,_T(".")) == 0) + { + delete pszSubkeyNameBuffer; + return TRUE; + } + + if (_tcscmp(pszSubkeyName,_T("..")) == 0) + { + // Up level abstraction + if (m_pCurrentKey->m_Key.IsRoot()) + { + // We are on root + ASSERT(m_pCurrentKey->m_pUp == NULL); + SetError(_T("Cannot open key. The root is not child.\n")); + delete pszSubkeyNameBuffer; + return FALSE; + } + + ASSERT(m_pCurrentKey->m_pUp); + if (!m_pCurrentKey->m_pUp) + { + SetInternalError(); + delete pszSubkeyNameBuffer; + return FALSE; + } + CNode *pNode = m_pCurrentKey; + m_pCurrentKey = m_pCurrentKey->m_pUp; + delete pNode; + delete pszSubkeyNameBuffer; + return TRUE; + } + + CNode *pNewKey = new CNode; + if (!pNewKey) + { + SetError(_T("Cannot open key : %s%s\nError %d (%s)\n"), + GetCurrentPath(),pszSubkeyName,ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY)); + delete pszSubkeyNameBuffer; + return FALSE; + } + + if (!InternalGetSubkey(pszSubkeyName,DesiredAccess,pNewKey->m_Key)) + { + delete pNewKey; + delete pszSubkeyNameBuffer; + return FALSE; + } + pNewKey->m_pUp = m_pCurrentKey; + m_pCurrentKey = pNewKey; + + delete pszSubkeyNameBuffer; + return TRUE; +} + +BOOL CRegistryTree::InternalGetSubkey(const TCHAR *pszSubkeyName, REGSAM DesiredAccess, CRegistryKey& rKey) +{ + LONG nError; + HKEY hNewKey = NULL; + TCHAR *pszSubkeyNameCaseUpdated = NULL; + + nError = m_pCurrentKey->m_Key.OpenSubkey(DesiredAccess,pszSubkeyName,hNewKey); + + if (nError != ERROR_SUCCESS) + { + SetError(_T("Cannot open key : %s%s\nError %u (%s)\n"), + GetCurrentPath(),pszSubkeyName,nError,GetErrorDescription(nError)); + + return FALSE; + } + + // enum subkeys to find the subkey and get its name in stored case. + DWORD dwMaxSubkeyNameLength; + nError = m_pCurrentKey->m_Key.GetSubkeyNameMaxLength(dwMaxSubkeyNameLength); + if (nError != ERROR_SUCCESS) + goto SkipCaseUpdate; + + pszSubkeyNameCaseUpdated = new TCHAR [dwMaxSubkeyNameLength]; + m_pCurrentKey->m_Key.InitSubkeyEnumeration(pszSubkeyNameCaseUpdated, dwMaxSubkeyNameLength); + while ((nError = m_pCurrentKey->m_Key.GetNextSubkeyName()) == ERROR_SUCCESS) + if (_tcsicmp(pszSubkeyNameCaseUpdated, pszSubkeyName) == 0) + break; + + if (nError != ERROR_SUCCESS) + { + delete pszSubkeyNameCaseUpdated; + pszSubkeyNameCaseUpdated = NULL; + } + +SkipCaseUpdate: + + HRESULT hr; + ASSERT(hNewKey); + if (pszSubkeyNameCaseUpdated) + { + hr = rKey.Init(hNewKey,GetCurrentPath(),pszSubkeyNameCaseUpdated,DesiredAccess); + if (FAILED(hr)) + { + if (hr == (HRESULT)E_OUTOFMEMORY) + SetError(_T("Cannot open key : %s%s\nError %d (%s)\n"), + GetCurrentPath(),pszSubkeyName,ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY)); + else + SetError(_T("Cannot open key : %s%s\nUnknown error\n"), GetCurrentPath(), pszSubkeyName); + + goto Abort; + } + + delete pszSubkeyNameCaseUpdated; + } + else + { + hr = rKey.Init(hNewKey,GetCurrentPath(),pszSubkeyName,DesiredAccess); + if (FAILED(hr)) + { + if (hr == (HRESULT)E_OUTOFMEMORY) + SetError(_T("Cannot open key : %s%s\nError %d (%s)\n"), + GetCurrentPath(),pszSubkeyName,ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY)); + else + SetError(_T("Cannot open key : %s%s\nUnknown error \n"), + GetCurrentPath(), + pszSubkeyName); + + goto Abort; + } + } + + return TRUE; +Abort: + if (pszSubkeyNameCaseUpdated) + delete pszSubkeyNameCaseUpdated; + + if (hNewKey) + { + LONG nError = RegCloseKey(hNewKey); + ASSERT(nError == ERROR_SUCCESS); + } + + return FALSE; +} + +BOOL CRegistryTree::GetKey(const TCHAR *pszRelativePath, REGSAM DesiredAccess, CRegistryKey& rKey) +{ + CRegistryTree Tree(*this); + + if (!Tree.ChangeCurrentKey(pszRelativePath)) + { + SetError(Tree.GetLastErrorDescription()); + return FALSE; + } + + if (Tree.m_pCurrentKey->m_Key.IsRoot()) + { + HRESULT hr = rKey.InitRoot(m_pszMachineName); + if (FAILED(hr)) + { + if (hr == (HRESULT)E_OUTOFMEMORY) + SetError(_T("\nError %d (%s)\n"), + ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY)); + else + SetInternalError(); + return FALSE; + } + + return TRUE; + } + + // open key with desired access + + // may be call to DuplicateHandle() is better. + // registry key handles returned by the RegConnectRegistry function cannot be used in a call to DuplicateHandle. + + // Get short key name now... + const TCHAR *pszKeyName = Tree.m_pCurrentKey->m_Key.GetKeyName(); + if (pszKeyName == NULL) + { + SetInternalError(); + return FALSE; + } + + size_t size = _tcslen(pszKeyName); + ASSERT(size); + if (!size) + { + SetInternalError(); + return FALSE; + } + + const TCHAR *pszShortKeyName_ = pszKeyName + size-1; + pszShortKeyName_--; // skip ending backslash + size = 0; + while (pszShortKeyName_ >= pszKeyName) + { + if (*pszShortKeyName_ == _T('\\')) + break; + pszShortKeyName_--; + size++; + } + + if (!size || (*pszShortKeyName_ != _T('\\'))) + { + ASSERT(FALSE); + SetInternalError(); + return FALSE; + } + + TCHAR *pszShortKeyName = new TCHAR [size+1]; + if (!pszShortKeyName) + { + SetError(ERROR_OUTOFMEMORY); + return FALSE; + } + + memcpy(pszShortKeyName,pszShortKeyName_+1,size*sizeof(TCHAR)); + pszShortKeyName[size] = 0; + + // change to parent key + if (!Tree.InternalChangeCurrentKey(_T(".."),READ_CONTROL)) + { + ASSERT(FALSE); + SetInternalError(); + return FALSE; + } + + // change back to target key + if (!Tree.InternalGetSubkey(pszShortKeyName,DesiredAccess,rKey)) + { + SetError(Tree.GetLastErrorDescription()); + return FALSE; + } + + return TRUE; +} + diff --git a/rosapps/sysutils/regexpl/RegistryTree.h b/rosapps/sysutils/regexpl/RegistryTree.h index c0a94e9c05b..83471c7a6dd 100644 --- a/rosapps/sysutils/regexpl/RegistryTree.h +++ b/rosapps/sysutils/regexpl/RegistryTree.h @@ -1,3 +1,5 @@ +/* $Id: RegistryTree.h,v 1.2 2001/01/10 01:25:29 narnaoud Exp $ */ + // RegistryTree.h: interface for the CRegistryTree class. // ////////////////////////////////////////////////////////////////////// @@ -7,37 +9,108 @@ #include "RegistryKey.h" +// Max size of error description. #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(); + + // Destructor + virtual ~CRegistryTree(); + + // Call this function after fail of this class method. + // + // Return value: + // Pointer to buffer containing description of last error. + // return value is valid until next method of this class is called. + const TCHAR * GetLastErrorDescription(); + + // Call this function to get string representation (path) of current key. + // + // Return value: + // Pointer to buffer containing current key path. The pointer is valid until next call to this objet method. + const TCHAR * GetCurrentPath() const; + + // Call this function to check if current key is the root key. + // + // Return value: + // FALSE - current key is not the root key. + // TRUE - current key is the root key. + BOOL IsCurrentRoot(); + + // Call this function to change the current key. + // + // Parameters: + // pchRelativePath - relative path to target key. + // + // Return value: + // TRUE - current key changed successfully. + // FALSE - failed to change current key. Call GetLastErrorDescription() to get error description. + BOOL ChangeCurrentKey(const TCHAR *pchRelativePath); + + // Call this function to obtain key at relative path and opened with desired access. + // + // Parametes: + // pchRelativePath - path to key to be opened. + // DesiredAccess - desired access to key. + // rKey - reference to variable that receives pointer to key. Caller must free object with delete operator, when object is not longer needed. + // + // Return value: + // TRUE - key opened successfully. + // FALSE - failed to open desired key path size. Call GetLastErrorDescription() to get error description. + BOOL GetKey(const TCHAR *pchRelativePath, REGSAM DesiredAccess, CRegistryKey& rKey); + + // Call this function to delete key subkeys. + // + // Parameters: + // pszKeyPattern - pattern to specifying which subkeys to delete. + // pszPath - path to key which subkeys will be deleted. + // blnRecursive - if FALSE and particular subkey has subkeys, it will not be deleted. + // + // Return value: + // TRUE - key opened successfully. + // FALSE - error. Call GetLastErrorDescription() to get error description. + BOOL DeleteSubkeys(const TCHAR *pszKeyPattern, const TCHAR *pszPath, BOOL blnRecursive = FALSE); + + BOOL NewKey(const TCHAR *pszKeyName, const TCHAR *pszPath, BOOL blnVolatile = FALSE); + + BOOL SetMachineName(LPCTSTR pszMachineName); + +// Internal methods +private: CRegistryTree(const CRegistryTree& Tree); - virtual ~CRegistryTree(); + // returns description of error value returned by RegXXXX functions in advapi32. + const TCHAR *GetErrorDescription(LONG nError); + + void SetError(LONG nError); + void SetError(const TCHAR *pszFormat, ...); + void SetErrorCommandNAOnRoot(const TCHAR *pszCommand); + void SetInternalError(); + void AddErrorDescription(const TCHAR *pszFormat, ...); + + BOOL InternalChangeCurrentKey(const TCHAR *pszSubkeyName, REGSAM DesiredAccess); + BOOL InternalGetSubkey(const TCHAR *pszSubkeyName, REGSAM DesiredAccess, CRegistryKey& rKey); + void GotoRoot(); + BOOL DeleteSubkeys(CRegistryKey& rKey, const TCHAR *pszKeyPattern, BOOL blnRecursive); + 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; + class CNode + { + public: + CNode *m_pUp; + CRegistryKey m_Key; + } m_Root; + + CNode *m_pCurrentKey; // The current key. + TCHAR m_ErrorMsg[ERROR_MSG_BUFFER_SIZE+1]; // Last error description buffer. + LPTSTR m_pszMachineName; // Pointer to buffer containing machine name with leading backslashes. NULL if local. }; #endif // !defined(REGISTRYTREE_H__239A6461_70F2_11D3_9085_204C4F4F5020__INCLUDED_) diff --git a/rosapps/sysutils/regexpl/SecurityDescriptor.cpp b/rosapps/sysutils/regexpl/SecurityDescriptor.cpp index d29789ad342..d19289dfdb0 100644 --- a/rosapps/sysutils/regexpl/SecurityDescriptor.cpp +++ b/rosapps/sysutils/regexpl/SecurityDescriptor.cpp @@ -1,4 +1,4 @@ -/* $Id: SecurityDescriptor.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: SecurityDescriptor.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -322,4 +322,8 @@ void CSecurityDescriptor::GetCurrentACE_AccessMask(DWORD& dwMask) } } - +void CSecurityDescriptor::GetCurrentACE_Flags(BYTE& bFlags) +{ + ASSERT(m_pCurrentACEHeader != NULL); + bFlags = m_pCurrentACEHeader->AceFlags; +} diff --git a/rosapps/sysutils/regexpl/SecurityDescriptor.h b/rosapps/sysutils/regexpl/SecurityDescriptor.h index 898ad899a18..9cec227d14a 100644 --- a/rosapps/sysutils/regexpl/SecurityDescriptor.h +++ b/rosapps/sysutils/regexpl/SecurityDescriptor.h @@ -16,6 +16,7 @@ const TCHAR * GetSidTypeName(SID_NAME_USE Use); class CSecurityDescriptor { public: + void GetCurrentACE_Flags(BYTE& bFlags); void GetCurrentACE_AccessMask(DWORD& dwMask); PSID GetCurrentACE_SID(); enum ACEntryType diff --git a/rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp b/rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp index 701a7a2bab0..36181961065 100644 --- a/rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandChangeKey.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandChangeKey.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandChangeKey.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -73,7 +73,9 @@ int CShellCommandChangeKey::Execute(CConsole &rConsole, CArgumentParser& rArgume if ((!blnHelp)&&(pchPath != NULL)&&(!rArguments.GetNextArgument())) { - ASSERT(_tcslen(pchPath) <= PROMPT_BUFFER_SIZE); + size_t size = _tcslen(pchPath); + ASSERT(size <= PROMPT_BUFFER_SIZE); + if (!m_rTree.ChangeCurrentKey(pchPath)) { rConsole.Write(m_rTree.GetLastErrorDescription()); diff --git a/rosapps/sysutils/regexpl/ShellCommandConnect.cpp b/rosapps/sysutils/regexpl/ShellCommandConnect.cpp index d81b740d901..cde1b7ca6ef 100644 --- a/rosapps/sysutils/regexpl/ShellCommandConnect.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandConnect.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandConnect.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandConnect.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -75,7 +75,12 @@ int CShellCommandConnect::Execute(CConsole &rConsole, CArgumentParser& rArgument if (blnHelp) rConsole.Write(GetHelpString()); - m_rTree.SetMachineName(pchMachine); + if (!m_rTree.SetMachineName(pchMachine)) + { + rConsole.Write(m_rTree.GetLastErrorDescription()); + rConsole.Write(_T("\n")); + } + return 0; } diff --git a/rosapps/sysutils/regexpl/ShellCommandDACL.cpp b/rosapps/sysutils/regexpl/ShellCommandDACL.cpp index 4c1b50efe5c..62496a4ab72 100644 --- a/rosapps/sysutils/regexpl/ShellCommandDACL.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandDACL.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandDACL.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandDACL.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -64,18 +64,18 @@ int CShellCommandDACL::Execute(CConsole &rConsole, CArgumentParser& rArguments) { rArguments.ResetArgumentIteration(); - const TCHAR *pchKey = NULL; + const TCHAR *pszKey = NULL; BOOL blnDo = TRUE; BOOL blnBadParameter = FALSE; BOOL blnHelp = FALSE; const TCHAR *pchParameter; const TCHAR *pchCommandItself = rArguments.GetNextArgument(); - DWORD dwError; + LONG nError; 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; + pszKey = pchCommandItself + DACL_CMD_LENGTH; } else if (_tcsnicmp(pchCommandItself,DACL_CMD _T("/"),DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0) { @@ -91,11 +91,11 @@ CheckDACLArgument: ||(_tcsicmp(pchParameter,_T("-?")) == 0)) { blnHelp = TRUE; - blnDo = pchKey != NULL; + blnDo = pszKey != NULL; } - else if (!pchKey) + else if (!pszKey) { - pchKey = pchParameter; + pszKey = pchParameter; blnDo = TRUE; } else @@ -110,28 +110,13 @@ CheckDACLArgument: } } - 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(); - } + CRegistryKey Key; + + if (!m_rTree.GetKey(pszKey?pszKey:_T("."),KEY_QUERY_VALUE|READ_CONTROL,Key)) + { + rConsole.Write(m_rTree.GetLastErrorDescription()); + blnDo = FALSE; + } if (blnHelp) { @@ -140,221 +125,245 @@ CheckDACLArgument: 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; + if (!blnDo) + return 0; + + if (Key.IsRoot()) + { // root key + rConsole.Write(DACL_CMD COMMAND_NA_ON_ROOT); + return 0; + } + + DWORD dwSecurityDescriptorLength; + rConsole.Write(_T("Key : ")); + rConsole.Write(_T("\\")); + rConsole.Write(Key.GetKeyName()); + rConsole.Write(_T("\n")); + PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; + TCHAR *pchName = NULL, *pchDomainName = NULL; + try + { + nError = Key.GetSecurityDescriptorLength(&dwSecurityDescriptorLength); + if (nError != ERROR_SUCCESS) + throw nError; - 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); + pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength]; + DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength; + nError = Key.GetSecurityDescriptor((SECURITY_INFORMATION)DACL_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1); + if (nError != ERROR_SUCCESS) + throw nError; + 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) + 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)) + { + DWORD 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; + } - if (pTree) - delete pTree; + BYTE bFlags; + sd.GetCurrentACE_Flags(bFlags); + wsprintf(Buffer,_T("\tFlags: 0x%02lX\n"),bFlags); + rConsole.Write(Buffer); + if (bFlags & CONTAINER_INHERIT_ACE) + { + rConsole.Write(_T("\t\tCONTAINER_INHERIT_ACE\n")); + } + if (bFlags & INHERIT_ONLY_ACE) + { + rConsole.Write(_T("\t\tINHERIT_ONLY_ACE\n")); + } + if (bFlags & INHERITED_ACE) + { + rConsole.Write(_T("\t\tINHERITED_ACE\n")); + } + if (bFlags & NO_PROPAGATE_INHERIT_ACE) + { + rConsole.Write(_T("\t\tNO_PROPAGATE_INHERIT_ACE\n")); + } + if (bFlags & OBJECT_INHERIT_ACE) + { + rConsole.Write(_T("\t\tOBJECT_INHERIT_ACE\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 + } // 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; + } return 0; } diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp b/rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp index 71756a10605..a580489d922 100644 --- a/rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandDeleteKey.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandDeleteKey.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandDeleteKey.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -50,7 +50,7 @@ BOOL CShellCommandDeleteKey::Match(const TCHAR *pchCommand) int CShellCommandDeleteKey::Execute(CConsole &rConsole, CArgumentParser& rArguments) { - const TCHAR *pchKey = NULL, *pchArg; + TCHAR *pchKey = NULL, *pchArg; BOOL blnHelp = FALSE; BOOL blnExitAfterHelp = FALSE; @@ -99,20 +99,72 @@ int CShellCommandDeleteKey::Execute(CConsole &rConsole, CArgumentParser& rArgume rConsole.Write(_T("\n")); } - if (!m_rTree.DeleteKey(pchKey,blnRecursive)) + // search for last key name token + TCHAR *pch = pchKey; + while(*pch) + pch++; + + if (pch > pchKey) + pch--; + + while(*pch == _T('\\')) + *pch = 0; + + while((pch > pchKey)&&(*pch != _T('\\'))) + pch--; + + ASSERT(pch >= pchKey); + + const TCHAR *pszPath; + TCHAR *pszPattern = pch+1; + if (pch == pchKey) + { + pszPath = _T("."); + } + else + { + if (pch-1 == pchKey) + { + rConsole.Write(DK_CMD COMMAND_NA_ON_ROOT); + return 0; + } + else + { + *pch = 0; + pszPath = pchKey; + } + } + + { + size_t s = _tcslen(pszPattern); + if (s && (pszPattern[0] == _T('\"'))&&(pszPattern[s-1] == _T('\"'))) + { + pszPattern[s-1] = 0; + pszPattern++; + } + } + + if (!m_rTree.DeleteSubkeys(pszPattern,pszPath,blnRecursive)) { - rConsole.Write(_T("Cannot delete key.\n")); + rConsole.Write(_T("Cannot delete key(s).\n")); rConsole.Write(m_rTree.GetLastErrorDescription()); } + else + { + InvalidateCompletion(); + } + 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"); + _T("Syntax: ") DK_CMD _T(" [/s] [/?] [PATH]KEY_NAME\n\n") + _T(" PATH - optional path to key which subkey(s) will be deleted. Default is current key.") + _T(" KEY_NAME - name of key to be deleted. Wildcards can be used.") + _T(" /? - This help.\n\n") + _T(" /s - Delete key and all subkeys.\n"); } const TCHAR * CShellCommandDeleteKey::GetHelpShortDescriptionString() diff --git a/rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp b/rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp index a03a1bd7e1f..fdc28eed8db 100644 --- a/rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandDeleteValue.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandDeleteValue.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandDeleteValue.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -44,57 +44,56 @@ CShellCommandDeleteValue::~CShellCommandDeleteValue() { } -BOOL CShellCommandDeleteValue::Match(const TCHAR *pchCommand) +BOOL CShellCommandDeleteValue::Match(const TCHAR *pszCommand) { - return _tcsicmp(pchCommand,DV_CMD) == 0; + return _tcsicmp(pszCommand,DV_CMD) == 0; } int CShellCommandDeleteValue::Execute(CConsole &rConsole, CArgumentParser& rArguments) { rArguments.ResetArgumentIteration(); - TCHAR *pchCommandItself = rArguments.GetNextArgument(); + TCHAR *pszCommandItself = rArguments.GetNextArgument(); - TCHAR *pchParameter; - TCHAR *pchValueFull = NULL; + TCHAR *pszParameter; + TCHAR *pszValueFull = 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)) + if ((_tcsnicmp(pszCommandItself,DV_CMD _T(".."),DV_CMD_LENGTH+2*sizeof(TCHAR)) == 0)|| + (_tcsnicmp(pszCommandItself,DV_CMD _T("\\"),DV_CMD_LENGTH+1*sizeof(TCHAR)) == 0)) { - pchValueFull = pchCommandItself + DV_CMD_LENGTH; + pszValueFull = pszCommandItself + DV_CMD_LENGTH; } - else if (_tcsnicmp(pchCommandItself,DV_CMD _T("/"),DV_CMD_LENGTH+1*sizeof(TCHAR)) == 0) + else if (_tcsnicmp(pszCommandItself,DV_CMD _T("/"),DV_CMD_LENGTH+1*sizeof(TCHAR)) == 0) { - pchParameter = pchCommandItself + DV_CMD_LENGTH; + pszParameter = pszCommandItself + DV_CMD_LENGTH; goto CheckValueArgument; } - while((pchParameter = rArguments.GetNextArgument()) != NULL) + while((pszParameter = rArguments.GetNextArgument()) != NULL) { CheckValueArgument: - if ((_tcsicmp(pchParameter,_T("/?")) == 0) - ||(_tcsicmp(pchParameter,_T("-?")) == 0)) + if ((_tcsicmp(pszParameter,_T("/?")) == 0) + ||(_tcsicmp(pszParameter,_T("-?")) == 0)) { blnHelp = TRUE; break; } - else if (!pchValueFull) + else if (!pszValueFull) { - pchValueFull = pchParameter; + pszValueFull = pszParameter; } else { rConsole.Write(_T("Bad parameter: ")); - rConsole.Write(pchParameter); + rConsole.Write(pszParameter); rConsole.Write(_T("\n")); } } - CRegistryTree *pTree = NULL; - CRegistryKey *pKey = NULL; - TCHAR *pchValueName; - TCHAR *pchPath; + CRegistryKey Key; + TCHAR *pszValueName; + const TCHAR *pszPath; if (blnHelp) { @@ -102,19 +101,19 @@ CheckValueArgument: return 0; } - if (pchValueFull) + if (pszValueFull) { - if (_tcscmp(pchValueFull,_T("\\")) == 0) + if (_tcscmp(pszValueFull,_T("\\")) == 0) goto CommandNAonRoot; - TCHAR *pchSep = _tcsrchr(pchValueFull,_T('\\')); - pchValueName = pchSep?(pchSep+1):(pchValueFull); - pchPath = pchSep?pchValueFull:NULL; + TCHAR *pchSep = _tcsrchr(pszValueFull,_T('\\')); + pszValueName = pchSep?(pchSep+1):(pszValueFull); + pszPath = pchSep?pszValueFull:_T("."); - //if (_tcsrchr(pchValueName,_T('.'))) + //if (_tcsrchr(pszValueName,_T('.'))) //{ - // pchValueName = _T(""); - // pchPath = pchValueFull; + // pszValueName = _T(""); + // pszPath = pszValueFull; //} //else if (pchSep) @@ -122,35 +121,38 @@ CheckValueArgument: } else { - pchValueName = _T(""); - pchPath = NULL; + pszValueName = _T(""); + pszPath = _T("."); } - - 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) + + { + size_t s = _tcslen(pszValueName); + if (s && (pszValueName[0] == _T('\"'))&&(pszValueName[s-1] == _T('\"'))) + { + pszValueName[s-1] = 0; + pszValueName++; + } + } + + if (!m_rTree.GetKey(pszPath,KEY_SET_VALUE,Key)) + { + rConsole.Write(m_rTree.GetLastErrorDescription()); + goto SkipCommand; + } + + if (!Key.IsRoot()) { // not root key ??? - if (pKey->DeleteValue(pchValueName) != ERROR_SUCCESS) - rConsole.Write(_T("Cannot set value\n")); + LONG nError = Key.DeleteValue(pszValueName); + if (nError != ERROR_SUCCESS) + { + char Buffer[254]; + _stprintf(Buffer,_T("Cannot delete value. Error is %u\n"),(unsigned int)nError); + rConsole.Write(Buffer); + } + else + { + InvalidateCompletion(); + } } // if (pKey) else { @@ -159,8 +161,8 @@ CommandNAonRoot: } SkipCommand: - if (pTree) - delete pTree; + // if (pTree) + // delete pTree; return 0; } diff --git a/rosapps/sysutils/regexpl/ShellCommandDir.cpp b/rosapps/sysutils/regexpl/ShellCommandDir.cpp index f74eab5d945..fa405dafcd0 100644 --- a/rosapps/sysutils/regexpl/ShellCommandDir.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandDir.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandDir.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandDir.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -73,35 +73,35 @@ 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(); + const TCHAR *pszParameter; + const TCHAR *pszCommandItself = rArguments.GetNextArgument(); + const TCHAR *pszKey = NULL; - 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)) + if ((_tcsnicmp(pszCommandItself,DIR_CMD _T(".."),DIR_CMD_LENGTH+2*sizeof(TCHAR)) == 0)|| + (_tcsnicmp(pszCommandItself,DIR_CMD _T("\\"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0)) { - pchKey = pchCommandItself + DIR_CMD_LENGTH; + pszKey = pszCommandItself + DIR_CMD_LENGTH; } - else if (_tcsnicmp(pchCommandItself,DIR_CMD _T("/"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0) + else if (_tcsnicmp(pszCommandItself,DIR_CMD _T("/"),DIR_CMD_LENGTH+1*sizeof(TCHAR)) == 0) { - pchParameter = pchCommandItself + DIR_CMD_LENGTH; + pszParameter = pszCommandItself + DIR_CMD_LENGTH; goto CheckDirArgument; } - while((pchParameter = rArguments.GetNextArgument()) != NULL) + while((pszParameter = rArguments.GetNextArgument()) != NULL) { CheckDirArgument: blnBadParameter = FALSE; - if ((_tcsicmp(pchParameter,_T("/?")) == 0) - ||(_tcsicmp(pchParameter,_T("-?")) == 0)) + if ((_tcsicmp(pszParameter,_T("/?")) == 0) + ||(_tcsicmp(pszParameter,_T("-?")) == 0)) { blnHelp = TRUE; - blnDo = pchKey != NULL; + blnDo = pszKey != NULL; } - else if (!pchKey) + else if (!pszKey) { - pchKey = pchParameter; + pszKey = pszParameter; blnDo = TRUE; } else @@ -111,133 +111,124 @@ CheckDirArgument: if (blnBadParameter) { rConsole.Write(_T("Bad parameter: ")); - rConsole.Write(pchParameter); + rConsole.Write(pszParameter); 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(); - } - + CRegistryKey Key; + + if (!m_rTree.GetKey(pszKey?pszKey:_T("."),KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE,Key)) + { + const TCHAR *pszErrorMsg = m_rTree.GetLastErrorDescription(); + rConsole.Write(pszErrorMsg); + blnDo = FALSE; + } + if (blnHelp) { rConsole.Write(GetHelpString()); } - DWORD dwError; + LONG nError; - 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; - } + if (!blnDo) + return 0; + + rConsole.Write(_T("\n Key is ")); + rConsole.Write(Key.GetKeyName()); + + if (!Key.IsRoot()) + { + rConsole.Write(_T("\n Last modify time is ")); + rConsole.Write(Key.GetLastWriteTime()); + } + + rConsole.Write(_T("\n\n")); + unsigned __int64 nTotalItems = 0; + + try + { + ASSERT(nTotalItems == 0); + rConsole.Write(_T("\t(KEY)\t\t\t\t..\\\n")); // parent key abstraction + nTotalItems = 1; - 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()) + DWORD dwMaxSubkeyNameLength; + nError = Key.GetSubkeyNameMaxLength(dwMaxSubkeyNameLength); + if (nError != ERROR_SUCCESS) + throw nError; + + TCHAR *pszSubkeyNameBuffer = new TCHAR[dwMaxSubkeyNameLength]; + if (!pszSubkeyNameBuffer) + throw ERROR_OUTOFMEMORY; + + Key.InitSubkeyEnumeration(pszSubkeyNameBuffer,dwMaxSubkeyNameLength); + while ((nError = Key.GetNextSubkeyName()) == ERROR_SUCCESS) + { + rConsole.Write(_T("\t(KEY)\t\t\t\t")); + rConsole.Write(pszSubkeyNameBuffer); + rConsole.Write(_T("\\\n")); + nTotalItems++; + } + + delete pszSubkeyNameBuffer; + + if (nError != ERROR_NO_MORE_ITEMS) + throw nError; + + DWORD dwMaxValueNameBufferSize; + nError = Key.GetMaxValueNameLength(dwMaxValueNameBufferSize); + if (nError != ERROR_SUCCESS) + throw nError; + + TCHAR *pchValueNameBuffer = new TCHAR[dwMaxValueNameBufferSize]; + if (!pchValueNameBuffer) + throw ERROR_OUTOFMEMORY; + + + DWORD Type; + Key.InitValueEnumeration(pchValueNameBuffer, + dwMaxValueNameBufferSize, + NULL, + 0, + &Type); + + DWORD dwValueNameActualLength; + const TCHAR *pszValueTypeName; + unsigned int nTabSize = rConsole.GetTabWidth(); + unsigned int nTabs; + while((nError = Key.GetNextValue(&dwValueNameActualLength)) == ERROR_SUCCESS) + { + rConsole.Write(_T("\t")); + pszValueTypeName = CRegistryKey::GetValueTypeName(Type); + nTabs = _tcslen(pszValueTypeName)/nTabSize; + nTabs = (nTabs < 4)?(4-nTabs):1; + rConsole.Write(pszValueTypeName); + while(nTabs--) + rConsole.Write(_T("\t")); + rConsole.Write((dwValueNameActualLength == 0)?_T("(Default)"):pchValueNameBuffer); + rConsole.Write(_T("\n")); + nTotalItems++; + } + + delete pchValueNameBuffer; + + if (nError != ERROR_NO_MORE_ITEMS) + throw nError; + + } // try + catch (LONG nError) + { + rConsole.Write(_T("Error ")); + TCHAR Buffer[256]; + rConsole.Write(_itot(nError,Buffer,10)); + rConsole.Write(_T("\n")); + } - 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) + rConsole.Write(_T("\n Total: ")); + TCHAR Buffer[256]; + rConsole.Write(_ui64tot(nTotalItems,Buffer,10)); + rConsole.Write(_T(" item(s) listed.\n")); return 0; } diff --git a/rosapps/sysutils/regexpl/ShellCommandHelp.cpp b/rosapps/sysutils/regexpl/ShellCommandHelp.cpp index 57254c1c264..c0b68bebaaf 100644 --- a/rosapps/sysutils/regexpl/ShellCommandHelp.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandHelp.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandHelp.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandHelp.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -123,7 +123,7 @@ int CShellCommandHelp::Execute(CConsole &rConsole, CArgumentParser& rArguments) const TCHAR * CShellCommandHelp::GetHelpString() { return HELP_CMD_SHORT_DESC - _T("Syntax: ") HELP_CMD _T("[] [/?]\n") + _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"); diff --git a/rosapps/sysutils/regexpl/ShellCommandNewKey.cpp b/rosapps/sysutils/regexpl/ShellCommandNewKey.cpp index 94c8cf5392d..3ba509fdaf7 100644 --- a/rosapps/sysutils/regexpl/ShellCommandNewKey.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandNewKey.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandNewKey.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandNewKey.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -50,41 +50,41 @@ BOOL CShellCommandNewKey::Match(const TCHAR *pchCommand) int CShellCommandNewKey::Execute(CConsole &rConsole, CArgumentParser& rArguments) { - const TCHAR *pchNewKey = NULL, *pchArg; + TCHAR *pszNewKey = NULL, *pszArg; BOOL blnHelp = FALSE; BOOL blnExitAfterHelp = FALSE; BOOL blnVolatile = FALSE; - while((pchArg = rArguments.GetNextArgument()) != NULL) + while((pszArg = rArguments.GetNextArgument()) != NULL) { - if ((_tcsicmp(pchArg,_T("/?")) == 0) - ||(_tcsicmp(pchArg,_T("-?")) == 0)) + if ((_tcsicmp(pszArg,_T("/?")) == 0) + ||(_tcsicmp(pszArg,_T("-?")) == 0)) { blnHelp = TRUE; } - else if ((_tcsicmp(pchArg,_T("/v")) == 0) - ||(_tcsicmp(pchArg,_T("-v")) == 0)) + else if ((_tcsicmp(pszArg,_T("/v")) == 0) + ||(_tcsicmp(pszArg,_T("-v")) == 0)) { blnVolatile = TRUE; } else { - if (pchNewKey) + if (pszNewKey) { rConsole.Write(_T("Wrong parameter : \"")); - rConsole.Write(pchArg); + rConsole.Write(pszArg); rConsole.Write(_T("\"\n\n")); blnHelp = TRUE; } else { - pchNewKey = pchArg; + pszNewKey = pszArg; } } } - if ((!blnHelp) && (!pchNewKey)) + if (!pszNewKey) { rConsole.Write(_T("Key name not specified !\n\n")); blnExitAfterHelp = TRUE; @@ -96,28 +96,74 @@ int CShellCommandNewKey::Execute(CConsole &rConsole, CArgumentParser& rArguments if (blnExitAfterHelp) return 0; else - rConsole.Write(_T("\n")); + rConsole.Write(_T("\n")); } - if (m_rTree.IsCurrentRoot()) - { // root key - rConsole.Write(NK_CMD COMMAND_NA_ON_ROOT); - return 0; - } + // search for last key name token + TCHAR *pch = pszNewKey; + while(*pch) // search end of string + pch++; - if (!m_rTree.NewKey(pchNewKey,blnVolatile)) + if (pch > pszNewKey) // last non-null char + pch--; + + while(*pch == _T('\\')) // ignore ending backslashes + *pch = 0; + + while((pch > pszNewKey)&&(*pch != _T('\\'))) + pch--; + + ASSERT(pch >= pszNewKey); + + const TCHAR *pszPath; + TCHAR *pszSubkeyName = pch+1; + if (pch == pszNewKey) + { + pszPath = _T("."); + } + else + { + if (pch-1 == pszNewKey) + { + rConsole.Write(NK_CMD COMMAND_NA_ON_ROOT); + return 0; + } + else + { + *pch = 0; + pszPath = pszNewKey; + } + } + + { + size_t s = _tcslen(pszSubkeyName); + if (s && (pszSubkeyName[0] == _T('\"')) && (pszSubkeyName[s-1] == _T('\"'))) + { + pszSubkeyName[s-1] = 0; + pszSubkeyName++; + } + } + + if (!m_rTree.NewKey(pszSubkeyName,pszPath,blnVolatile)) { rConsole.Write(_T("Cannot create key.\n")); rConsole.Write(m_rTree.GetLastErrorDescription()); } + else + { + InvalidateCompletion(); + } + 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("Syntax: ") NK_CMD _T(" [/v] [/?] [PATH]KEY_NAME\n\n") + _T(" PATH - optional path to key which subkey will be created. Default is current key.\n") + _T(" KEY_NAME - name of subkey to be created.\n") + _T(" /? - This help.\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"); } diff --git a/rosapps/sysutils/regexpl/ShellCommandOwner.cpp b/rosapps/sysutils/regexpl/ShellCommandOwner.cpp index ff79764787c..11c0d97b770 100644 --- a/rosapps/sysutils/regexpl/ShellCommandOwner.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandOwner.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandOwner.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandOwner.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -108,30 +108,14 @@ CheckOwnerArgument: } } - CRegistryTree *pTree = NULL; - CRegistryKey *pKey = NULL; + CRegistryKey Key; + + if (!m_rTree.GetKey(pchKey?pchKey:_T("."),KEY_QUERY_VALUE|READ_CONTROL,Key)) + { + rConsole.Write(m_rTree.GetLastErrorDescription()); + blnDo = FALSE; + } - 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()); @@ -139,116 +123,112 @@ CheckOwnerArgument: 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; + if (!blnDo) + return 0; + + if (Key.IsRoot()) + { // root key + rConsole.Write(OWNER_CMD COMMAND_NA_ON_ROOT); + return 0; + } + + PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; + TCHAR *pchName = NULL, *pchDomainName = NULL; + try + { + DWORD dwSecurityDescriptorLength; + rConsole.Write(_T("Key : ")); + rConsole.Write(_T("\\")); + rConsole.Write(Key.GetKeyName()); + rConsole.Write(_T("\n")); + dwError = Key.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; + pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength]; + DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength; + dwError = Key.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; - + } + } + 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; + } + return 0; } diff --git a/rosapps/sysutils/regexpl/ShellCommandSACL.cpp b/rosapps/sysutils/regexpl/ShellCommandSACL.cpp index 0665e8edb06..929be091ef0 100644 --- a/rosapps/sysutils/regexpl/ShellCommandSACL.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandSACL.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandSACL.cpp,v 1.2 2000/10/24 20:17:41 narnaoud Exp $ +/* $Id: ShellCommandSACL.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -62,341 +62,382 @@ BOOL CShellCommandSACL::Match(const TCHAR *pchCommand) int CShellCommandSACL::Execute(CConsole &rConsole, CArgumentParser& rArguments) { - TCHAR err_msg[1024]; +#define ERROR_MSG_BUFFER_SIZE 1024 + TCHAR pszError_msg[ERROR_MSG_BUFFER_SIZE]; + pszError_msg[ERROR_MSG_BUFFER_SIZE-1] = 0; + + rArguments.ResetArgumentIteration(); - 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) - { + const TCHAR *pszKey = NULL; + BOOL blnDo = TRUE; + BOOL blnBadParameter = FALSE; + BOOL blnHelp = FALSE; + const TCHAR *pszParameter; + const TCHAR *pszCommandItself = rArguments.GetNextArgument(); + DWORD dwError; + PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; + CSecurityDescriptor sd; + HANDLE hThreadToken = INVALID_HANDLE_VALUE; + + if ((_tcsnicmp(pszCommandItself,SACL_CMD _T(".."),SACL_CMD_LENGTH+2*sizeof(TCHAR)) == 0)|| + (_tcsnicmp(pszCommandItself,SACL_CMD _T("\\"),SACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)) + { + pszKey = pszCommandItself + SACL_CMD_LENGTH; + } + else if (_tcsnicmp(pszCommandItself,SACL_CMD _T("/"),SACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0) + { + pszParameter = pszCommandItself + SACL_CMD_LENGTH; + goto CheckSACLArgument; + } + + while((pszParameter = 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")); - } - } + blnBadParameter = FALSE; + if ((_tcsicmp(pszParameter,_T("/?")) == 0)|| + (_tcsicmp(pszParameter,_T("-?")) == 0)) + { + blnHelp = TRUE; + blnDo = pszKey != NULL; + } + else if (!pszKey) + { + pszKey = pszParameter; + blnDo = TRUE; + } + else + { + blnBadParameter = TRUE; + } + if (blnBadParameter) + { + rConsole.Write(_T("Bad parameter: ")); + rConsole.Write(pszParameter); + 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(); - } + CRegistryKey Key; - if (blnHelp) - { - rConsole.Write(GetHelpString()); - } + ASSERT(hThreadToken == INVALID_HANDLE_VALUE); + + // Open thread token + if (!OpenThreadToken(GetCurrentThread(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,FALSE,&hThreadToken)) + { // OpenThreadToken failed + dwError = GetLastError(); + if (dwError != ERROR_NO_TOKEN) + { + _sntprintf(pszError_msg,ERROR_MSG_BUFFER_SIZE-1,_T("\nCannot open thread token.\nOpenThreadToken fails with error: %u\n"),(unsigned int)dwError); + goto Error; + } + + // 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)) + { + _sntprintf(pszError_msg,ERROR_MSG_BUFFER_SIZE-1,_T("\nCannot open process token.\nOpenProcessToken fails with error: %u\n"),(unsigned int)GetLastError()); + goto Error; + } + } + + ASSERT(hThreadToken != INVALID_HANDLE_VALUE); - if (blnDo&&blnHelp) rConsole.Write(_T("\n")); + // enable SeSecurityPrivilege privilege + 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 + { + _sntprintf(pszError_msg,ERROR_MSG_BUFFER_SIZE-1,_T("\nCannot retrieve the locally unique identifier for %s privilege.\nLookupPrivilegeValue error: %u\n"),SE_SECURITY_NAME,(unsigned int)GetLastError()); + goto Error; + } - if (blnDo) - { - try - { - if (!pKey) - throw (SACL_CMD COMMAND_NA_ON_ROOT); + BOOL blnAdjRet; + blnAdjRet = AdjustTokenPrivileges( + hThreadToken, + FALSE, + &priv, + sizeof(TOKEN_PRIVILEGES), + (PTOKEN_PRIVILEGES)NULL, + (PDWORD)NULL); + dwError = GetLastError(); + if (!blnAdjRet) + { + _sntprintf(pszError_msg,ERROR_MSG_BUFFER_SIZE-1,_T("\nCannot enable %s privilege.\nAdjustTokenPrivileges fails with error: %u%s\n"),SE_SECURITY_NAME,(unsigned int)dwError,(dwError == 5)?_T(" (Access denied)"):_T("")); + goto Error; + } + + if (dwError != ERROR_SUCCESS) + { + if (dwError == ERROR_NOT_ALL_ASSIGNED) + { + _sntprintf(pszError_msg,ERROR_MSG_BUFFER_SIZE-1,_T("\nCannot enable %s privilege.\nThe token does not have the %s privilege\n"),SE_SECURITY_NAME,SE_SECURITY_NAME); + } + else + { + _sntprintf(pszError_msg,ERROR_MSG_BUFFER_SIZE-1,_T("\nCannot enable %s privilege.\nAdjustTokenPrivileges succeds with error: %u\n"),SE_SECURITY_NAME,(unsigned int)dwError); + } + + goto Error; + } + + if (!m_rTree.GetKey(pszKey?pszKey:_T("."),KEY_QUERY_VALUE|READ_CONTROL|ACCESS_SYSTEM_SECURITY,Key)) + { + rConsole.Write(m_rTree.GetLastErrorDescription()); + blnDo = FALSE; + } + + if (blnHelp) + { + rConsole.Write(GetHelpString()); + } - 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 + if (blnDo&&blnHelp) + rConsole.Write(_T("\n")); + + if (!blnDo) + return 0; + + if (Key.IsRoot()) + { + _tcsncpy(pszError_msg,SACL_CMD COMMAND_NA_ON_ROOT,ERROR_MSG_BUFFER_SIZE-1); + goto Error; + } + + DWORD dwSecurityDescriptorLength; + rConsole.Write(_T("Key : ")); + rConsole.Write(_T("\\")); + + rConsole.Write(Key.GetKeyName()); + rConsole.Write(_T("\n")); + dwError = Key.GetSecurityDescriptorLength(&dwSecurityDescriptorLength); + if (dwError != ERROR_SUCCESS) + { + _sntprintf(pszError_msg,ERROR_MSG_BUFFER_SIZE-1,_T("\nCannot get security descriptor's length for current key.\nError: %u\n"),(unsigned int)dwError); + goto Error; + } + + pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength]; + if (!pSecurityDescriptor) + { + _tcsncpy(pszError_msg,_T("\nOut of memory.\n"),ERROR_MSG_BUFFER_SIZE-1); + goto Error; + } + + DWORD dwSecurityDescriptorLength1; + dwSecurityDescriptorLength1 = dwSecurityDescriptorLength; + dwError = Key.GetSecurityDescriptor((SECURITY_INFORMATION)SACL_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1); + if (dwError != ERROR_SUCCESS) + { + _sntprintf(pszError_msg,ERROR_MSG_BUFFER_SIZE-1,_T("\nCannot get security descriptor for current key.\nError: %u%s\n"),(unsigned int)dwError,(dwError == 1314)?_T("(A required privilege is not held by the client.)\n"):_T("")); + goto Error; + } + + sd.AssociateDescriptor(pSecurityDescriptor); + sd.BeginSACLInteration(); + + if ((!sd.DescriptorContainsSACL())||(sd.HasNULLSACL())) + { + _tcsncpy(pszError_msg,_T("Key has not SACL.\n"),ERROR_MSG_BUFFER_SIZE-1); + goto Error; + } + + if (!sd.HasValidSACL()) + { + _tcsncpy(pszError_msg,_T("Invalid SACL.\n"),ERROR_MSG_BUFFER_SIZE-1); + goto Error; + } + + DWORD nACECount; + 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 *pszSID = new TCHAR[dwSIDStringSize]; + + if (!pszSID) + { + _tcsncpy(pszError_msg,_T("\nOut of memory.\n"),ERROR_MSG_BUFFER_SIZE-1); + goto Error; + } + + if(!GetTextualSid(pSID,pszSID,&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(pszSID); + rConsole.Write(_T("\n")); + } + delete pszSID; + + TCHAR *pszName, *pszDomainName; + DWORD dwNameBufferLength, dwDomainNameBufferLength; + dwNameBufferLength = 1024; + dwDomainNameBufferLength = 1024; + + pszName = new TCHAR [dwNameBufferLength]; + if (!pszName) + { + _tcsncpy(pszError_msg,_T("\nOut of memory.\n"),ERROR_MSG_BUFFER_SIZE-1); + goto Error; + } + + pszDomainName = new TCHAR [dwDomainNameBufferLength]; + if (!pszDomainName) + { + _tcsncpy(pszError_msg,_T("\nOut of memory.\n"),ERROR_MSG_BUFFER_SIZE-1); + goto Error; + } + + DWORD dwNameLength = dwNameBufferLength, dwDomainNameLength = dwDomainNameBufferLength; + SID_NAME_USE Use; + if (!LookupAccountSid(NULL,pSID,pszName,&dwNameLength,pszDomainName,&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(pszDomainName); + rConsole.Write(_T("\n")); + rConsole.Write(_T("\tTrustee Name: ")); + rConsole.Write(pszName); + 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) + ASSERT(pSecurityDescriptor); + delete pSecurityDescriptor; + + VERIFY(CloseHandle(hThreadToken)); return 0; +Error: + if (pSecurityDescriptor) + delete pSecurityDescriptor; + + if (hThreadToken != INVALID_HANDLE_VALUE) + VERIFY(CloseHandle(hThreadToken)); + + rConsole.Write(pszError_msg); + return 0; } const TCHAR * CShellCommandSACL::GetHelpString() diff --git a/rosapps/sysutils/regexpl/ShellCommandSetValue.cpp b/rosapps/sysutils/regexpl/ShellCommandSetValue.cpp index b9becbb79dd..e5a72afd955 100644 --- a/rosapps/sysutils/regexpl/ShellCommandSetValue.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandSetValue.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandSetValue.cpp,v 1.2 2000/10/24 20:17:42 narnaoud Exp $ +/* $Id: ShellCommandSetValue.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -104,77 +104,78 @@ CShellCommandSetValue::~CShellCommandSetValue() { } -BOOL CShellCommandSetValue::Match(const TCHAR *pchCommand) +BOOL CShellCommandSetValue::Match(const TCHAR *pszCommand) { - if (_tcsicmp(pchCommand,SET_VALUE_CMD) == 0) + if (_tcsicmp(pszCommand,SET_VALUE_CMD) == 0) return TRUE; - if (_tcsnicmp(pchCommand,SET_VALUE_CMD _T(".."),SET_VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0) + if (_tcsnicmp(pszCommand,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) + if (_tcsnicmp(pszCommand,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) + if (_tcsnicmp(pszCommand,SET_VALUE_CMD _T("\\"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) return TRUE; return FALSE; } int CShellCommandSetValue::Execute(CConsole &rConsole, CArgumentParser& rArguments) { + LONG nError; + rArguments.ResetArgumentIteration(); - TCHAR *pchCommandItself = rArguments.GetNextArgument(); + TCHAR *pszCommandItself = rArguments.GetNextArgument(); - TCHAR *pchParameter; - TCHAR *pchValueFull = NULL; - TCHAR *pchValueData = NULL; + TCHAR *pszParameter; + TCHAR *pszValueFull = NULL; + TCHAR *pszValueData = 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)) + if ((_tcsnicmp(pszCommandItself,SET_VALUE_CMD _T(".."),SET_VALUE_CMD_LENGTH+2*sizeof(TCHAR)) == 0)|| + (_tcsnicmp(pszCommandItself,SET_VALUE_CMD _T("\\"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0)) { - pchValueFull = pchCommandItself + SET_VALUE_CMD_LENGTH; + pszValueFull = pszCommandItself + SET_VALUE_CMD_LENGTH; } - else if (_tcsnicmp(pchCommandItself,SET_VALUE_CMD _T("/"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) + else if (_tcsnicmp(pszCommandItself,SET_VALUE_CMD _T("/"),SET_VALUE_CMD_LENGTH+1*sizeof(TCHAR)) == 0) { - pchParameter = pchCommandItself + SET_VALUE_CMD_LENGTH; + pszParameter = pszCommandItself + SET_VALUE_CMD_LENGTH; goto CheckValueArgument; } - while((pchParameter = rArguments.GetNextArgument()) != NULL) + while((pszParameter = rArguments.GetNextArgument()) != NULL) { CheckValueArgument: blnBadParameter = FALSE; - if (((*pchParameter == _T('/'))||(*pchParameter == _T('-'))) - &&(*(pchParameter+1) == _T('?'))) + if (((*pszParameter == _T('/'))||(*pszParameter == _T('-'))) + &&(*(pszParameter+1) == _T('?'))) { blnHelp = TRUE; } else if (dwType == REG_NONE) { - if (_tcsicmp(pchParameter,_T("b")) == 0) + if (_tcsicmp(pszParameter,_T("b")) == 0) { dwType = REG_BINARY; } - else if (_tcsicmp(pchParameter,_T("dw")) == 0) + else if (_tcsicmp(pszParameter,_T("dw")) == 0) { dwType = REG_DWORD; } - else if (_tcsicmp(pchParameter,_T("dwle")) == 0) + else if (_tcsicmp(pszParameter,_T("dwle")) == 0) { dwType = REG_DWORD_LITTLE_ENDIAN; } - else if (_tcsicmp(pchParameter,_T("dwbe")) == 0) + else if (_tcsicmp(pszParameter,_T("dwbe")) == 0) { dwType = REG_DWORD_BIG_ENDIAN; } - else if (_tcsicmp(pchParameter,_T("sz")) == 0) + else if (_tcsicmp(pszParameter,_T("sz")) == 0) { dwType = REG_SZ; } - else if (_tcsicmp(pchParameter,_T("esz")) == 0) + else if (_tcsicmp(pszParameter,_T("esz")) == 0) { dwType = REG_EXPAND_SZ; } @@ -183,13 +184,13 @@ CheckValueArgument: blnBadParameter = TRUE; } } - else if (pchValueData == NULL) + else if (pszValueData == NULL) { - pchValueData = pchParameter; + pszValueData = pszParameter; } - else if (!pchValueFull) + else if (!pszValueFull) { - pchValueFull = pchParameter; + pszValueFull = pszParameter; } else { @@ -198,18 +199,17 @@ CheckValueArgument: if (blnBadParameter) { rConsole.Write(_T("Bad parameter: ")); - rConsole.Write(pchParameter); + rConsole.Write(pszParameter); rConsole.Write(_T("\n")); } } - if (!pchValueData) + if (!pszValueData) blnHelp = TRUE; - CRegistryTree *pTree = NULL; - CRegistryKey *pKey = NULL; - TCHAR *pchValueName; - TCHAR *pchPath; + CRegistryKey Key; + TCHAR *pszValueName; + const TCHAR *pszPath; if (blnHelp) { @@ -221,19 +221,19 @@ CheckValueArgument: return 0; } - if (pchValueFull) + if (pszValueFull) { - if (_tcscmp(pchValueFull,_T("\\")) == 0) + if (_tcscmp(pszValueFull,_T("\\")) == 0) goto CommandNAonRoot; - TCHAR *pchSep = _tcsrchr(pchValueFull,_T('\\')); - pchValueName = pchSep?(pchSep+1):(pchValueFull); - pchPath = pchSep?pchValueFull:NULL; + TCHAR *pchSep = _tcsrchr(pszValueFull,_T('\\')); + pszValueName = pchSep?(pchSep+1):(pszValueFull); + pszPath = pchSep?pszValueFull:_T("."); - //if (_tcsrchr(pchValueName,_T('.'))) + //if (_tcsrchr(pszValueName,_T('.'))) //{ - // pchValueName = _T(""); - // pchPath = pchValueFull; + // pszValueName = _T(""); + // pszPath = pszValueFull; //} //else if (pchSep) @@ -241,131 +241,130 @@ CheckValueArgument: } else { - pchValueName = _T(""); - pchPath = NULL; + pszValueName = _T(""); + pszPath = _T("."); } - 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 (!m_rTree.GetKey(pszPath,KEY_SET_VALUE,Key)) + { + rConsole.Write(m_rTree.GetLastErrorDescription()); + goto SkipCommand; + } - 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; - } + if (Key.IsRoot()) + goto CommandNAonRoot; + + switch (dwType) + { + case REG_BINARY: + { + HANDLE hFile; + DWORD dwBytesReaded; + hFile = CreateFile(pszValueData,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + rConsole.Write(_T("Cannot open file ")); + rConsole.Write(pszValueData); + rConsole.Write(_T("\n")); + goto SkipCommand; + } + dwValueSize = GetFileSize(hFile,NULL); + if (dwValueSize == (DWORD)-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(pszValueData); + 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); - } + 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,pszValueData)) + { + rConsole.Write(_T("Cannot convert ")); + rConsole.Write(pszValueData); + 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(pszValueData)+1; + if (*pszValueData == _T('\"')) + { + dwValueSize -= 2; + *(pszValueData+dwValueSize) = 0; + pszValueData++; + } + dwValueSize *= sizeof(TCHAR); + pDataBuffer = (BYTE *) new BYTE [dwValueSize]; + _tcscpy((TCHAR *)pDataBuffer,pszValueData); + 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); - } + { + size_t s = _tcslen(pszValueName); + if (s && (pszValueName[0] == _T('\"'))&&(pszValueName[s-1] == _T('\"'))) + { + pszValueName[s-1] = 0; + pszValueName++; + } + } + + nError = Key.SetValue(pszValueName,dwType,pDataBuffer,dwValueSize); + if (nError != ERROR_SUCCESS) + { + char Buffer[254]; + _stprintf(Buffer,_T("Cannot set value. Error is %u\n"),(unsigned int)nError); + rConsole.Write(Buffer); + } + else + { + InvalidateCompletion(); + } SkipCommand: - if (pTree) - delete pTree; - if (pDataBuffer) delete pDataBuffer; return 0; + +CommandNAonRoot: + rConsole.Write(SET_VALUE_CMD COMMAND_NA_ON_ROOT); + return 0; } const TCHAR * CShellCommandSetValue::GetHelpString() diff --git a/rosapps/sysutils/regexpl/ShellCommandValue.cpp b/rosapps/sysutils/regexpl/ShellCommandValue.cpp index 983fd015d4e..05560e38b71 100644 --- a/rosapps/sysutils/regexpl/ShellCommandValue.cpp +++ b/rosapps/sysutils/regexpl/ShellCommandValue.cpp @@ -1,4 +1,4 @@ -/* $Id: ShellCommandValue.cpp,v 1.2 2000/10/24 20:17:42 narnaoud Exp $ +/* $Id: ShellCommandValue.cpp,v 1.3 2001/01/10 01:25:29 narnaoud Exp $ * * regexpl - Console Registry Explorer * @@ -69,7 +69,7 @@ int CShellCommandValue::Execute(CConsole &rConsole, CArgumentParser& rArguments) BOOL blnUnicodeDump = FALSE; BOOL blnBadParameter = FALSE; BOOL blnHelp = FALSE; - DWORD dwError; + LONG nError; DWORD dwValueSize; DWORD dwType = REG_NONE; BYTE *pDataBuffer = NULL; @@ -120,10 +120,9 @@ CheckValueArgument: } } - CRegistryTree *pTree = NULL; - CRegistryKey *pKey = NULL; + CRegistryKey Key; TCHAR *pchValueName; - TCHAR *pchPath; + const TCHAR *pszPath; if (blnHelp) { @@ -142,7 +141,7 @@ CheckValueArgument: TCHAR *pchSep = _tcsrchr(pchValueFull,_T('\\')); pchValueName = pchSep?(pchSep+1):(pchValueFull); - pchPath = pchSep?pchValueFull:NULL; + pszPath = pchSep?pchValueFull:_T("."); //if (_tcsrchr(pchValueName,_T('.'))) //{ @@ -156,271 +155,266 @@ CheckValueArgument: else { pchValueName = _T(""); - pchPath = NULL; + pszPath = _T("."); } - - 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 (!m_rTree.GetKey(pszPath,KEY_READ,Key)) + { + rConsole.Write(m_rTree.GetLastErrorDescription()); + goto SkipValueCommand; + } - 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, + if (Key.IsRoot()) + goto ValueCommandNAonRoot; + + { + rConsole.Write(_T("Value name : \"")); + rConsole.Write(_T("\\")); + rConsole.Write(Key.GetKeyName()); + size_t l = _tcslen(pchValueName); + if (l&& + (*pchValueName == _T('\"'))&& + (pchValueName[l-1] == _T('\"'))) + { + pchValueName[l-1] = 0; + pchValueName++; + } + rConsole.Write(pchValueName); + rConsole.Write(_T("\"\n")); + + nError = Key.GetValue(pchValueName,NULL,NULL,&dwValueSize); + if (nError == ERROR_SUCCESS) + { + pDataBuffer = new BYTE [dwValueSize]; + Key.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 "),(unsigned int)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"), + _T("%c"), #else - _T("%C"), + // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3)) + // %C in format string is a Microsoft extension. + _T("%C"), #endif - iswprint(ch)?ch:L'.'); - } - else - { - unsigned char ch = *(pDataBuffer+j); - _stprintf(Buffer, + iswprint(ch)?ch:L'.'); + } + else + { + unsigned char ch = *(pDataBuffer+j); + + _stprintf(Buffer, #ifdef _UNICODE - _T("%C"), + // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3)) + // %C in format string is a Microsoft extension. + _T("%C"), #else - _T("%c"), + _T("%c"), #endif - isprint(ch)?ch:'.'); - } - rConsole.Write(Buffer); - } // for - } // if - } // for + 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(" ")); - } + // 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, + // write current char representation + if (blnUnicodeDump) + { + ASSERT(j%2 == 0); + wchar_t ch = *(TCHAR *)(pDataBuffer+j); + + _stprintf(Buffer, #ifdef _UNICODE - _T("%c"), + _T("%c"), #else - _T("%C"), + // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3)) + // %C in format string is a Microsoft extension. + _T("%C"), #endif - iswprint(ch)?ch:L'.'); - } - else - { - unsigned char ch = *(pDataBuffer+j); - _stprintf(Buffer, + iswprint(ch)?ch:L'.'); + } + else + { + unsigned char ch = *(pDataBuffer+j); + + _stprintf(Buffer, #ifdef _UNICODE - _T("%C"), + // g++ may print warnings here (warning: __wchar_t format, different type arg (arg 3)) + // %C in format string is a Microsoft extension. + _T("%C"), #else - _T("%c"), + _T("%c"), #endif - isprint(ch)?ch:'.'); - } - rConsole.Write(Buffer); - } // for - } // if - } // for - } // default: - rConsole.Write(_T("\n")); - } // switch - rConsole.Write(_T("\n")); + 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")); + 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; - } + 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; - } + 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); - } + ASSERT(dwBytesWritten == dwValueSize); + VERIFY(CloseHandle(hFile)); + } + } + else + { + rConsole.Write(_T("Error ")); + TCHAR Buffer[256]; + rConsole.Write(_itot(nError,Buffer,10)); + rConsole.Write(_T("\n")); + if (nError == ERROR_FILE_NOT_FOUND) + { + rConsole.Write(_T("(System cannot find the value specified)\n")); + } + } + } SkipValueCommand: - if (pTree) - delete pTree; - if (pDataBuffer) delete pDataBuffer; return 0; +ValueCommandNAonRoot: + rConsole.Write(VALUE_CMD COMMAND_NA_ON_ROOT); + return 0; } const TCHAR * CShellCommandValue::GetHelpString() diff --git a/rosapps/sysutils/regexpl/ph.h b/rosapps/sysutils/regexpl/ph.h index f53c648fd23..9def17cddbe 100644 --- a/rosapps/sysutils/regexpl/ph.h +++ b/rosapps/sysutils/regexpl/ph.h @@ -12,6 +12,10 @@ //#define UNICODE //#define _UNICODE +#ifdef DBG +#define _DEBUG +#endif + #include #include @@ -29,4 +33,9 @@ #include #include +// INHERITED_ACE is from windows 2000 +#ifndef INHERITED_ACE +#define INHERITED_ACE (0x10) +#endif + #endif // !defined(PH_H__FEF419E3_6EB6_11D3_907D_204C4F4F5020__INCLUDED_)