no message

svn path=/trunk/; revision=1500
This commit is contained in:
Nedko Arnaudov 2001-01-10 01:25:29 +00:00
parent 48b5533bd5
commit 1688a8d7c5
29 changed files with 3494 additions and 2470 deletions

View file

@ -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)
{

View file

@ -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 <nedkohome@atia.com>
*
* 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();
}

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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 = \

View file

@ -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 <nedkohome@atia.com>
*
* 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;
}

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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_)

View file

@ -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;
}

View file

@ -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_)

View file

@ -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;
}

View file

@ -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

View file

@ -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());

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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()

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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("[<COMMAND>] [/?]\n")
_T("Syntax: ") HELP_CMD _T(" [<COMMAND>] [/?]\n")
_T(" COMMAND - Command for which help will be displayed.\n")
_T(" /? - This help.\n\n")
_T("Without parameters, command lists available commands.\n");

View file

@ -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");
}

View file

@ -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;
}

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -12,6 +12,10 @@
//#define UNICODE
//#define _UNICODE
#ifdef DBG
#define _DEBUG
#endif
#include <TCHAR.H>
#include <stdio.h>
@ -29,4 +33,9 @@
#include <conio.h>
#include <limits.h>
// INHERITED_ACE is from windows 2000
#ifndef INHERITED_ACE
#define INHERITED_ACE (0x10)
#endif
#endif // !defined(PH_H__FEF419E3_6EB6_11D3_907D_204C4F4F5020__INCLUDED_)