Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Main.cpp
- */
- #include <iostream>
- #include "AquireInput.h"
- #include "Error.h"
- #include "Help.h"
- #include "RegAdd.h"
- #include "RegQuery.h"
- int wmain(int argc, wchar_t* argv[])
- {
- RegBlock aVal;
- int result = getInput(argc, argv, aVal);
- switch (result)
- {
- case REG_ADD: add(aVal); break;
- case REG_QUERY: query(aVal); break;
- case REG_DELETE: break;
- case REG_HELP_GENERAL:
- case REG_HELP_ADD:
- case REG_HELP_QUERY:
- case REG_HELP_DELETE: help(result); break;
- default: error(result); break;
- }
- return 0;
- }
- /*
- AquireInput.cpp
- */
- #include <queue>
- #include "AquireInput.h"
- #include "Help.h"
- struct RegBlock
- {
- std::wstring lHkey = L"";
- std::wstring lHkeyPath = L"";
- std::wstring lValueName = L"";
- std::wstring lDataType = L"";
- std::wstring lData = L"";
- bool lViewed[12] = { false };
- std::map<std::string, bool> lOptions = {
- { "/k",false },
- { "/d",false },
- { "/s",false },
- { "/c",false },
- { "/e",false },
- { "/z",false },
- { "/f",false }
- };
- };
- // Parameter handles
- #define V (0)
- #define VE (1)
- #define T (2)
- #define D (3)
- #define F (4)
- #define S (5)
- #define K (6)
- #define C (7)
- #define E (8)
- #define Z (9)
- #define VA (10)
- uint8_t checkIdentifer(std::wstring arg, bool viewed[])
- {
- if (arg == L"/v" && !viewed[V])
- {
- viewed[VE] = true; // Deactivate value empty arg
- return V;
- }
- if (arg == L"/ve" && !viewed[VE])
- {
- viewed[V] = true; // Deactivate value specify arg
- return VE;
- }
- if (arg == L"/k" && !viewed[K])
- {
- viewed[D] = true; // Deactivate data search arg
- return K;
- }
- if (arg == L"/d" && !viewed[D])
- {
- viewed[K] = true; // Deactivate key value search arg
- return D;
- }
- if (arg == L"/t" && !viewed[T]) return T;
- if (arg == L"/f" && !viewed[F]) return F;
- if (arg == L"/s" && !viewed[S]) return S;
- if (arg == L"/c" && !viewed[C]) return C;
- if (arg == L"/e" && !viewed[E]) return E;
- if (arg == L"/z" && !viewed[Z]) return Z;
- return L'x';
- }
- bool validDataType(std::wstring aDataType)
- {
- if (getDataTypeMacro(aDataType) != NULL) return true;
- return false;
- }
- bool validKeyName(std::wstring s)
- {
- // Test if a minimum string length has been met
- if (s.size() < 3) return false;
- if (s.size() == 3)
- {
- if (s.substr(0, 3) == L"HKU") return true;
- return false;
- }
- else
- {
- std::wstring lHkey = s.substr(0, 4);
- if (lHkey == L"HKCR") return true;
- if (lHkey == L"HKCC") return true;
- if (lHkey == L"HKCU") return true;
- if (lHkey == L"HKLM") return true;
- if (lHkey.substr(0, 3) == L"HKU") return true;
- return false;
- }
- }
- bool setHKey(std::wstring s, RegBlock &aVal)
- {
- // Test if a minimum string length has been met
- if (s.size() < 3) return false;
- // Addresses case in which user only input 'ADD HKU'
- if (s.size() == 3)
- {
- if (s.substr(0, 3) == L"HKU")
- {
- aVal.lHkey = L"HKU";
- }
- return true;
- }
- else
- {
- std::wstring lHkey = s.substr(0, 4);
- // Test if a lHkeyPath has been inputted
- if (s.size() > 4)
- {
- aVal.lHkeyPath = s.substr(5);
- }
- if (lHkey == L"HKCR") aVal.lHkey = L"HKCR";
- if (lHkey == L"HKCC") aVal.lHkey = L"HKCC";
- if (lHkey == L"HKCU") aVal.lHkey = L"HKCU";
- if (lHkey == L"HKLM") aVal.lHkey = L"HKLM";
- if (lHkey.substr(0, 3) == L"HKU")
- {
- aVal.lHkey = L"HKU";
- if (s.size() > 4)
- {
- aVal.lHkeyPath = s.substr(4);
- }
- }
- return true;
- }
- }
- int getInput(int argc, wchar_t* argv[], RegBlock& aVal)
- {
- std::queue<std::wstring> lQueue;
- // Add argv values to lQueue
- for (int i = 1; i < argc; i++)
- {
- lQueue.push(argv[i]);
- }
- if (lQueue.size() == 0) return MISSING_CORE_PARAMETER;
- // Get action (ADD,DELETE,QUERY..ect);
- std::wstring lCurrentVal = lQueue.front();
- lQueue.pop();
- // Guard against repeat parameter/sytax e.g /v Hello /ve /f /f
- //bool lViewed[12] = { false };
- #define lViewed (aVal.lViewed)
- if (lCurrentVal == L"ADD")
- {
- if (lQueue.size() == 0) return MISSING_CORE_PARAMETER;
- lCurrentVal = lQueue.front();
- // Check if ADD HELP was requested
- if (lCurrentVal == L"/?") return REG_HELP_ADD;
- // Check & Set HKEY value
- if (!validKeyName(lCurrentVal)) return NON_VALID_HKEY;
- setHKey(lCurrentVal, aVal);
- lQueue.pop();
- // Check validity of parameter
- while (lQueue.size())
- {
- lCurrentVal = lQueue.front();
- lQueue.pop();
- switch (checkIdentifer(lCurrentVal, lViewed))
- {
- case V: lViewed[V] = true;
- aVal.lValueName = lQueue.front();
- lQueue.pop();
- break;
- case VE: lViewed[VE] = true;
- break;
- case T: lViewed[T] = true;
- lCurrentVal = lQueue.front();
- if (!validDataType(lCurrentVal)) return NON_VALID_DATA_TYPE;
- aVal.lDataType = lCurrentVal;
- lQueue.pop();
- break;
- case D: lViewed[D] = true;
- aVal.lData = lQueue.front();
- lQueue.pop();
- break;
- case F: lViewed[F] = true;
- aVal.lOptions["/f"] = true;
- break;
- default: return UNKNOWN_PARAMETER;
- }
- }
- return REG_ADD;
- }
- if (lCurrentVal == L"QUERY")
- {
- if (lQueue.size() == 0) return MISSING_CORE_PARAMETER;
- lCurrentVal = lQueue.front();
- // Check if ADD HELP was requested
- if (lCurrentVal == L"/?") return REG_HELP_QUERY;
- // Check & Set HKEY value
- if (!validKeyName(lCurrentVal)) return NON_VALID_HKEY;
- setHKey(lCurrentVal, aVal);
- lQueue.pop();
- // Check validity of parameter
- while (lQueue.size())
- {
- lCurrentVal = lQueue.front();
- lQueue.pop();
- switch (checkIdentifer(lCurrentVal, lViewed))
- {
- case V: lViewed[V] = true;
- aVal.lValueName = lQueue.front();
- lQueue.pop();
- break;
- case VE: lViewed[VE] = true;
- break;
- case S: lViewed[S] = true;
- aVal.lOptions["/s"] = true;
- break;
- case F: lViewed[F] = true;
- aVal.lOptions["/f"] = true;
- aVal.lData = lQueue.front();
- lQueue.pop();
- break;
- case K: lViewed[K] = true;
- aVal.lOptions["/k"] = true;
- break;
- case D: lViewed[D] = true;
- aVal.lOptions["/d"] = true;
- break;
- case C: lViewed[C] = true;
- aVal.lOptions["/c"] = true;
- break;
- case E: lViewed[E] = true;
- aVal.lOptions["/e"] = true;
- break;
- case T: lViewed[T] = true;
- lCurrentVal = lQueue.front();
- if (!validDataType(lCurrentVal)) return NON_VALID_DATA_TYPE;
- aVal.lDataType = lCurrentVal;
- lQueue.pop();
- break;
- case Z: lViewed[Z] = true;
- aVal.lOptions["/z"] = true;
- break;
- default: return UNKNOWN_PARAMETER;
- }
- }
- // Make sure that search options are not enabled without first specifing a search criteria
- if (lViewed[K] || lViewed[D] || lViewed[C] || lViewed[E] || lViewed[T])
- {
- if (!lViewed[F]) return UNKNOWN_PARAMETER;
- }
- return REG_QUERY;
- }
- if (lCurrentVal == L"DELETE")
- {
- return REG_DELETE;
- }
- if (lCurrentVal == L"/?")
- {
- return REG_HELP_GENERAL;
- }
- return UNKNOWN_ACTION;
- }
- /*
- RegQuery.cpp
- */
- #include "RegQuery.h"
- #include <queue>
- #include <iomanip>
- #include <string>
- #include <io.h>
- #include <fcntl.h>
- #include <algorithm>
- #include <fstream>
- #define MAX_KEY_LENGTH 255
- #define MAX_VALUE_NAME 32786
- #define MAX_DATA_VALUE 2000000
- std::wstring NULLWST = L""; // Placeholder null value
- inline unsigned hexValidInt(int aVal)
- {
- if (aVal < 0)
- {
- aVal += 256;
- return aVal;
- }
- return aVal;
- }
- template <typename I> std::string n2hexstr(I w, size_t hex_len = 2) {
- static const char* digits = "0123456789ABCDEF";
- std::string rc(hex_len, '0');
- for (size_t i = 0, j = (hex_len - 1) * 4; i < hex_len; ++i, j -= 4)
- {
- rc[i] = digits[(w >> j) & 0x0f];
- }
- // Corrects the order of the hex numbers e.g 34FE is corrected to FE34
- std::swap_ranges(std::begin(rc)+2, std::end(rc), std::begin(rc));
- return rc;
- }
- inline unsigned int convertData(DWORD &aRegType, DWORD &aDataLength, wchar_t *aData, std::wstring &aDataResult)
- {
- std::wstring lDataResult;
- if (aRegType == REG_DWORD ||
- aRegType == REG_QWORD ||
- aRegType == REG_DWORD_LITTLE_ENDIAN ||
- aRegType == REG_QWORD_LITTLE_ENDIAN ||
- aRegType == REG_DWORD_BIG_ENDIAN)
- {
- // Reverse loop
- for (int i = (aDataLength * 0.5) - 1; i >= 0; i--)
- {
- if (aData[i] == 0) continue;
- lDataResult += convertToWstr(n2hexstr(hexValidInt(aData[i]),2));
- }
- }
- if (aRegType == REG_BINARY || aRegType == REG_NONE)
- {
- for (int i = 0; i < (aDataLength * 0.5); i++)
- {
- lDataResult += convertToWstr(n2hexstr(hexValidInt(aData[i]),4));
- }
- }
- if (aRegType == REG_SZ || aRegType == REG_MULTI_SZ)
- {
- int lEnd = (aDataLength * 0.5) - 1;
- // Avoid adding trailing zero
- if (aRegType == REG_MULTI_SZ)
- {
- lEnd = (aDataLength * 0.5) - 2;
- }
- for (int i = 0; i < lEnd; i++)
- {
- if (aData[i] == 0)
- {
- lDataResult += L"\0";
- continue;
- }
- lDataResult += aData[i];
- }
- }
- aDataResult = lDataResult;
- return 0;
- }
- struct RegValue
- {
- std::wstring lValueName;
- unsigned int lRegType;
- std::wstring lDataValue;
- };
- inline std::wstring constructKeyPath(std::wstring &aHkeyPath, std::wstring &aSubKey)
- {
- std::wstring lSlash = L"\";
- std::wstring lFullPath;
- if (aSubKey == L"")
- {
- lFullPath = aHkeyPath;
- }
- else
- {
- lFullPath = aHkeyPath + lSlash + aSubKey;
- }
- return lFullPath;
- }
- inline unsigned int getValueNameList(HKEY hKey, std::wstring &aHkeyPath, std::wstring &aSubKey, std::queue<std::wstring> &aValueList)
- {
- std::wstring lFullPath = constructKeyPath(aHkeyPath, aSubKey);
- LPCTSTR lpSubKey = lFullPath.c_str();
- int lResult = RegOpenKeyEx(
- hKey,
- lpSubKey,
- 0, //add var
- KEY_QUERY_VALUE, //add var
- &hKey
- );
- if (lResult != ERROR_SUCCESS)
- {
- return lResult;
- }
- // Variables related to RegEnumValue
- LPDWORD lpReserved = NULL;
- LPDWORD lpType = NULL;
- LPBYTE lpData = NULL;
- LPDWORD lpcbData = NULL;
- DWORD dwIndex = 0;
- // Avoid adding lpValueName initial value
- bool lSkip = true;
- while (lResult != ERROR_NO_MORE_ITEMS)
- {
- wchar_t lpValueName[MAX_VALUE_NAME];
- DWORD lpcchValueName = MAX_VALUE_NAME;
- // Add the list of value names to a vector list
- if (!lSkip)
- {
- aValueList.push(lpValueName);
- }
- else
- {
- lSkip = false;
- }
- lResult = RegEnumValue(
- hKey,
- dwIndex,
- lpValueName,
- &lpcchValueName,
- lpReserved,
- lpType,
- lpData,
- lpcbData
- );
- dwIndex++;
- // Return an error if lResult is not an acceptable error
- if (lResult != ERROR_SUCCESS && lResult != ERROR_NO_MORE_ITEMS)
- {
- RegCloseKey(hKey);
- return lResult;
- }
- }
- //Close key
- RegCloseKey(hKey);
- return lResult = 0;
- }
- inline unsigned int getSubKeyList(HKEY hKey, std::wstring &aHkeyPath, std::wstring &aSubKey, std::deque<std::wstring> &aSubKeyList)
- {
- std::wstring lFullPath = constructKeyPath(aHkeyPath, aSubKey);
- LPCTSTR lpSubKey = lFullPath.c_str();
- DWORD i, lResult;
- lResult = RegOpenKeyEx(
- hKey,
- lpSubKey,
- 0,
- KEY_READ,
- &hKey
- );
- TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
- DWORD cbName; // size of name string
- TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name
- DWORD cchClassName = MAX_PATH; // size of class string
- DWORD cSubKeys = 0; // number of subkeys
- DWORD cbMaxSubKey; // longest subkey size
- DWORD cchMaxClass; // longest class string
- DWORD cValues; // number of values for key
- DWORD cchMaxValue; // longest value name
- DWORD cbMaxValueData; // longest value data
- DWORD cbSecurityDescriptor; // size of security descriptor
- FILETIME ftLastWriteTime; // last write time
- TCHAR achValue[MAX_VALUE_NAME];
- DWORD cchValue = MAX_VALUE_NAME;
- // Get the class name and the value count.
- lResult = RegQueryInfoKey(
- hKey, // key handle
- achClass, // buffer for class name
- &cchClassName, // size of class string
- NULL, // reserved
- &cSubKeys, // number of subkeys
- &cbMaxSubKey, // longest subkey size
- &cchMaxClass, // longest class string
- &cValues, // number of values for this key
- &cchMaxValue, // longest value name
- &cbMaxValueData, // longest value data
- &cbSecurityDescriptor, // security descriptor
- &ftLastWriteTime); // last write time
- // Enumerate the subkeys, until RegEnumKeyEx fails.
- if (cSubKeys)
- {
- for (i = 0; i<cSubKeys; i++)
- {
- cbName = MAX_KEY_LENGTH;
- lResult = RegEnumKeyEx(hKey, i,
- achKey,
- &cbName,
- NULL,
- NULL,
- NULL,
- &ftLastWriteTime);
- if (lResult == ERROR_SUCCESS)
- {
- // Attach parent key to child sub keys
- // e.g: key01/subkey01
- std::wstring lRelativePath = achKey;
- if (aSubKey != L"")
- {
- lRelativePath = aSubKey + L"\" + achKey;
- }
- aSubKeyList.push_back(lRelativePath);
- }
- }
- }
- //Close key
- RegCloseKey(hKey);
- return lResult;
- }
- inline unsigned int getValueData(HKEY aHkey, std::wstring &aHkeyPath, std::wstring &aSubKey, std::wstring &aValueName, RegValue &aValueData)
- {
- std::wstring lFullPath = constructKeyPath(aHkeyPath, aSubKey);
- LPCTSTR lSubKey = lFullPath.c_str();
- LPCTSTR lValueName = aValueName.c_str();
- DWORD dwFlags = RRF_RT_ANY;
- DWORD pdwType;
- wchar_t *pvData = new wchar_t[MAX_DATA_VALUE];
- DWORD pcbData = MAX_DATA_VALUE;
- int lResult = RegGetValue(
- aHkey,
- lSubKey,
- lValueName,
- dwFlags,
- &pdwType,
- pvData,
- &pcbData
- );
- // Check if lResult is okay
- if (lResult != ERROR_SUCCESS)
- {
- delete[] pvData;
- return lResult;
- }
- if (pcbData >= MAX_DATA_VALUE)
- {
- std::cout << "Data Value Exceeded! Registery data value > 2MB!" << std::endl;
- return lResult;
- }
- // Convert data values & Store results
- std::wstring lDataValue;
- convertData(pdwType, pcbData, pvData, lDataValue);
- aValueData.lDataValue = lDataValue;
- aValueData.lValueName = lValueName;
- aValueData.lRegType = pdwType;
- delete[] pvData;
- return lResult;
- }
- /*
- Show related functions
- */
- inline std::wstring getHkeyStringName(HKEY aHkey)
- {
- if (aHkey == HKEY_CLASSES_ROOT) return L"HKEY_CLASSES_ROOT\";
- if (aHkey == HKEY_CURRENT_CONFIG) return L"HKEY_CURRENT_CONFIG\";
- if (aHkey == HKEY_CURRENT_USER) return L"HKEY_CURRENT_USER\";
- if (aHkey == HKEY_LOCAL_MACHINE) return L"HKEY_LOCAL_MACHINE\";
- if (aHkey == HKEY_USERS) return L"HKEY_USERS\";
- return L"NULL";
- }
- inline std::wstring getDataTypeStringName(unsigned int &aDataType)
- {
- if (aDataType == REG_SZ) return L"REG_SZ";
- if (aDataType == REG_MULTI_SZ) return L"REG_MULTI_SZ";
- if (aDataType == REG_EXPAND_SZ) return L"REG_EXPAND_SZ";
- if (aDataType == REG_DWORD) return L"REG_DWORD";
- if (aDataType == REG_DWORD_BIG_ENDIAN) return L"REG_DWORD_BIG_ENDIAN";
- if (aDataType == REG_DWORD_LITTLE_ENDIAN) return L"REG_DWORD_LITTLE_ENDIAN";
- if (aDataType == REG_QWORD) return L"REG_QWORD";
- if (aDataType == REG_QWORD_LITTLE_ENDIAN) return L"REG_QWORD_LITTLE_ENDIAN";
- if (aDataType == REG_BINARY) return L"REG_BINARY";
- if (aDataType == REG_NONE) return L"REG_NONE";
- return L"NULL";
- }
- unsigned int WriteToConsole(std::wstring &aString)
- {
- int lResult = ERROR_SUCCESS;
- static HANDLE lConsoleAccess = GetStdHandle(STD_OUTPUT_HANDLE);
- lResult = WriteConsoleW(
- lConsoleAccess,
- aString.c_str(),
- aString.size(),
- NULL,
- NULL
- );
- return lResult;
- }
- // Testing
- //#define __nonEnglishMode
- //#define __writeToDisk
- #if defined (__writeToDisk)
- std::wofstream file;
- #endif
- inline void show(HKEY aHkey, std::wstring &aHkeyPath, std::wstring &aSubKey, RegValue &aValueData, bool aDisplayPath, bool aDisplayValue, bool aLastItem)
- {
- // Display Key Path HKEY/key/key..ect
- if (aDisplayPath)
- {
- std::wstring lSlash = L"\";
- std::wstring lFullPath;
- #if defined (__writeToDisk)
- file << L"n";
- #endif
- // Only attach subkey to path name if it is supplied
- if (aSubKey == L"")
- {
- lFullPath = getHkeyStringName(aHkey) + aHkeyPath + L"n";
- }
- else
- {
- lFullPath = getHkeyStringName(aHkey) + aHkeyPath + lSlash + aSubKey + L"n";
- }
- //fwprintf(stdout, L"%s",lFullPath.c_str());
- WriteToConsole(lFullPath);
- #if defined (__writeToDisk)
- file << lFullPath;
- #endif
- }
- if (aDisplayValue)
- {
- // Show registry value name
- std::wstring lValueName = (aValueData.lValueName);
- if (lValueName == TEXT("")) lValueName = TEXT("(Default)");
- // Show registry type
- std::wstring lDataType = getDataTypeStringName(aValueData.lRegType);
- std::wstring lDataValue;
- // Show registry data
- if (lDataType == L"REG_DWORD" ||
- lDataType == L"REG_QWORD" ||
- lDataType == L"REG_DWORD_LITTLE_ENDIAN" ||
- lDataType == L"REG_QWORD_LITTLE_ENDIAN" ||
- lDataType == L"REG_DWORD_BIG_ENDIAN")
- {
- lDataValue = L"0x0" + (aValueData.lDataValue);
- }
- else
- {
- lDataValue = (aValueData.lDataValue);
- }
- std::wstring lKeyValue = L" " + lValueName + L" " + lDataType + L" " + lDataValue + L"n";
- //fwprintf(stdout,L"%s",lKeyValue.c_str());
- WriteToConsole(lKeyValue);
- #if defined (__writeToDisk)
- file << lKeyValue;
- #endif
- }
- #if defined (__writeToDisk)
- if (file.fail())
- {
- file.clear();
- }
- #endif
- }
- DWORD getDataTypeFilterMacro(std::string &aDataType)
- {
- if (aDataType == "REG_SZ") return RRF_RT_REG_SZ;
- if (aDataType == "REG_MULTI_SZ") return RRF_RT_REG_MULTI_SZ;
- if (aDataType == "REG_EXPAND_SZ") return RRF_RT_REG_EXPAND_SZ;
- if (aDataType == "REG_DWORD") return RRF_RT_DWORD;
- if (aDataType == "REG_DWORD_BIG_ENDIAN") return RRF_RT_DWORD;
- if (aDataType == "REG_DWORD_LITTLE_ENDIAN") return RRF_RT_DWORD;
- if (aDataType == "REG_QWORD") return RRF_RT_QWORD;
- if (aDataType == "REG_QWORD_LITTLE_ENDIAN") return RRF_RT_QWORD;
- if (aDataType == "REG_BINARY") return RRF_RT_REG_BINARY;
- if (aDataType == "REG_NONE") return RRF_RT_REG_NONE;
- return RRF_RT_ANY;
- }
- bool isMatch(RegValue &aRegValueData, std::wstring &aDataType, std::wstring &aSearchItem, std::wstring &aKeyName, bool lCaseSensitive = false, bool lExactMatch = false, bool aSearchKeyOnly = false, bool aSearchDataOnly = false)
- {
- bool lResult = false;
- std::wstring lSearchItem = aSearchItem;
- std::wstring lValueName = aRegValueData.lValueName;
- std::wstring lDataValue = aRegValueData.lDataValue;
- std::wstring lKeyName = aKeyName;
- // Convert to lowercase
- if (!lCaseSensitive || !lExactMatch)
- {
- std::transform(lSearchItem.begin(), lSearchItem.end(), lSearchItem.begin(), ::tolower);
- std::transform(lValueName.begin(), lValueName.end(), lValueName.begin(), ::tolower);
- std::transform(lDataValue.begin(), lDataValue.end(), lDataValue.begin(), ::tolower);
- std::transform(lKeyName.begin(), lKeyName.end(), lKeyName.begin(), ::tolower);
- }
- // Search Key Names
- if (aSearchKeyOnly)
- {
- // Split and store the last key
- // ...MyCo//Key1//Key3 ->> Key3
- auto const pos = lKeyName.find_last_of('\');
- lKeyName = lKeyName.substr(pos + 1);
- if (lKeyName == lSearchItem)
- {
- return true;
- }
- return false;
- }
- // Search Data
- if (aSearchDataOnly)
- {
- if (lDataValue == lSearchItem)
- {
- return true;
- }
- return false;
- }
- // Search both key name and data value
- if (!aSearchKeyOnly && !aSearchDataOnly)
- {
- if (lValueName == lSearchItem)
- {
- return true;
- }
- if (lDataValue == lSearchItem)
- {
- return true;
- }
- return false;
- }
- return false;
- }
- bool query(RegBlock &aVal)
- {
- int lResult;
- #if defined (__writeToDisk)
- file.open("screen_output.txt", std::wofstream::app | std::wofstream::in);
- #endif
- // Variables related to Queries/Find
- HKEY hkey = getHkeyMacro(aVal.lHkey);
- std::wstring lHkeyPath = aVal.lHkeyPath;
- bool lValueNameEmpty = aVal.lValueName.empty();
- bool lFind = aVal.lOptions["/f"];
- bool lSearchRecursive = aVal.lOptions["/s"];
- bool lFilterDataType = !(aVal.lDataType.empty());
- bool lCaseSensitive = aVal.lOptions["/c"];
- bool lExactMatch = aVal.lOptions["/e"];
- bool lSearchKeyOnly = aVal.lOptions["/k"];
- bool lSearchDataOnly = aVal.lOptions["/d"];
- // Specify the search value to use, either the key name or search param input
- std::wstring lSearchItem = aVal.lData;
- if (!lValueNameEmpty)
- {
- lSearchItem = aVal.lValueName;
- }
- std::deque<std::wstring> lSubKeyList;
- std::queue<std::wstring> lValueList;
- // Get the list of value names if none is provided
- if (lValueNameEmpty)
- {
- lResult = getValueNameList(hkey, lHkeyPath, NULLWST, lValueList);
- if (lResult != ERROR_SUCCESS)
- {
- error(lResult);
- return false;
- }
- }
- else
- {
- std::wstring lValueName = aVal.lValueName;
- lValueList.push(lValueName);
- }
- // Get inital list of sub keys
- lResult = getSubKeyList(hkey, lHkeyPath, NULLWST, lSubKeyList);
- if (lResult != ERROR_SUCCESS)
- {
- error(lResult);
- return false;
- }
- RegValue lRegValueData;
- std::wstring lCurrentSubKey = NULLWST;
- std::wstring lCurrentValue = NULLWST;
- unsigned int lMatchTotal = 0;
- // Allows for the last subkey within the dequeue to be shown
- lSubKeyList.push_back(L"End");
- bool lDisplayPath = false;
- bool lDisplayValue = true;
- bool lNewLine = false;
- bool lMatch = false;
- while (lSubKeyList.size())
- {
- // Search and Display keys when searching in KEY ONLY mode
- if (lSearchKeyOnly)
- {
- lMatch = isMatch(
- lRegValueData,
- aVal.lDataType,
- lSearchItem,
- lCurrentSubKey,
- lCaseSensitive,
- lExactMatch,
- lSearchKeyOnly,
- lSearchDataOnly
- );
- if (lMatch)
- {
- lDisplayPath = true;
- lDisplayValue = false;
- show(hkey, lHkeyPath, lCurrentSubKey, lRegValueData, lDisplayPath, lDisplayValue, false);
- lDisplayPath = false;
- lDisplayValue = true;
- lNewLine = true;
- lMatchTotal++;
- }
- }
- // Display the key path in the case of empty key && list keys when not in recursive/search mode
- if (lValueList.size() == 0 && !(lFilterDataType || lFind) && lValueNameEmpty)
- {
- show(hkey, lHkeyPath, lCurrentSubKey, lRegValueData, true, false, false);
- }
- else
- {
- lDisplayPath = true;
- }
- while (lValueList.size() && !lSearchKeyOnly)
- {
- lCurrentValue = lValueList.front();
- lValueList.pop();
- lResult = getValueData(hkey, lHkeyPath, lCurrentSubKey, lCurrentValue, lRegValueData);
- if (lResult != ERROR_SUCCESS)
- {
- error(lResult);
- return false;
- }
- if (lFind || lFilterDataType)
- {
- lMatch = isMatch(
- lRegValueData,
- aVal.lDataType,
- lSearchItem,
- lCurrentSubKey,
- lCaseSensitive,
- lExactMatch,
- lSearchKeyOnly,
- lSearchDataOnly
- );
- if (lMatch)
- {
- if (lSearchKeyOnly)
- {
- lDisplayPath = true;
- lDisplayValue = false;
- }
- show(hkey, lHkeyPath, lCurrentSubKey, lRegValueData, lDisplayPath, lDisplayValue, false);
- lDisplayPath = false;
- lDisplayValue = true;
- lMatchTotal++;
- lNewLine = true;
- }
- }
- else
- {
- show(hkey, lHkeyPath, lCurrentSubKey, lRegValueData, lDisplayPath, lDisplayValue, false);
- lDisplayPath = false;
- }
- }
- if (lSearchRecursive && !(lFilterDataType || lFind))
- {
- lNewLine = true;
- }
- if (lNewLine)
- {
- fwprintf(stdout, L"n");
- lNewLine = false;
- }
- // Remove visted Sub-Key from deque
- lCurrentSubKey = lSubKeyList.front();
- lSubKeyList.pop_front();
- if (lSearchRecursive && lCurrentSubKey != L"End")
- {
- // If the parent key contains sub-keys, add them to lSubKeyList,
- // in the order they were retrieved from RegEnumEx.
- std::deque<std::wstring> lTemp;
- lResult = getSubKeyList(hkey, lHkeyPath, lCurrentSubKey, lTemp);
- while (lTemp.size())
- {
- lSubKeyList.push_front(lTemp.back());
- lTemp.pop_back();
- }
- // A non-error. Error: "Invalid Handle"
- // This error code just states that the current key being accessed
- // does not contain any sub-keys.
- if (lResult == 6) lResult = 0;
- if (lResult != ERROR_SUCCESS)
- {
- error(lResult);
- return false;
- }
- // Get the current keys value names
- if (!lSearchKeyOnly)
- {
- lResult = getValueNameList(hkey, lHkeyPath, lCurrentSubKey, lValueList);
- // Ignore key values that cannot be accessed. Error "Access Denied"
- // Keys cannot be accessed in regedit (admin), so this is a UAC issue.
- if (lResult == 5) lResult = 0;
- if (lResult != ERROR_SUCCESS)
- {
- error(lResult);
- return false;
- }
- }
- }
- }
- #if defined (__writeToDisk)
- file.close();
- #endif
- if (lFind || lFilterDataType)
- {
- std::cout << "End of search : " << lMatchTotal << " match(es) found." << std::endl;
- }
- return true;
- }
Add Comment
Please, Sign In to add comment