/* (C) 2003-2007 Willem Jan Hengeveld * Web: http://www.xs4all.nl/~itsme/ * http://wiki.xda-developers.com/ * * $Id: pregutl.cpp 1921 2008-07-31 17:08:31Z itsme $ * * bug: specifying invalid string with '-d' can cause whole registry to be deleted * pregutl -d hklm\software\somekey 0000101a */ // NOTE: boost 1.30 -> 1.33 : changed from regex_match param boost::regbase::icase // to regex constructor param boost::regex_constants::icase #include #include "debug.h" #include "args.h" #include #include #include #include #include "stringutils.h" #include "vectorutils.h" #ifndef _WIN32_WCE #include "filefunctions.h" #include #endif #ifdef WINCEREGUTL #ifndef _WIN32_WCE // include only for win32 version #include #include "dllversion.h" #endif #endif #define STD_NAME_BUF_SIZE 256 #define STD_VALUE_BUF_SIZE 32768 // this registry value type is specific to windows ce #ifndef REG_MUI_SZ #define REG_MUI_SZ (21) #endif #if defined(WIN32REGUTL) || defined(_WIN32_WCE) #define __RegCloseKey RegCloseKey #define __RegCreateKeyEx RegCreateKeyEx #define __RegDeleteKey RegDeleteKey #define __RegDeleteValue RegDeleteValue #define __RegEnumKeyEx RegEnumKeyEx #define __RegEnumValue RegEnumValue #define __RegOpenKeyEx RegOpenKeyEx #define __RegQueryInfoKey RegQueryInfoKey #define __RegQueryValueEx RegQueryValueEx #define __RegSetValueEx RegSetValueEx #endif #ifdef WINCEREGUTL #define __RegCloseKey CeRegCloseKey #define __RegCreateKeyEx CeRegCreateKeyEx #define __RegDeleteKey CeRegDeleteKey #define __RegDeleteValue CeRegDeleteValue #define __RegEnumKeyEx CeRegEnumKeyEx #define __RegEnumValue CeRegEnumValue #define __RegOpenKeyEx CeRegOpenKeyEx #define __RegQueryInfoKey CeRegQueryInfoKey #define __RegQueryValueEx CeRegQueryValueEx #define __RegSetValueEx CeRegSetValueEx #endif // todo: // - support 'REGEDIT4' fileformat header. // - support unicode files // - change 'r' option in non-recursive option // - add option to choose how to mix keys and values. // ( full cross product, or values per key. ) // - support comments at end of line // - support [-HKEY\path] delete registry key syntax // - support valuename=- delete registry value syntax // - make it easier to specify quotes in string format // introduce 'string:' format specifier, which does not need delimiting quotes. // - fix sz and multisz decoding, to properly convert from utf16 -> utf8 std::string GetNameFromSetSpec(const std::string& spec, size_t start); std::string GetValueSpecFromSetSpec(const std::string& spec, size_t start); enum RegAction { DO_LOAD, DO_LIST, DO_DELETE, #ifndef _WIN32_WCE DO_SET, #endif DO_CREATE, }; bool g_outputFullHex= false; // do not try to print ascii from binary regblobs bool g_outputAllDataHex= false; // do not parse registry data at all, always print the raw data. bool g_outputAllKeysHex= false; // hex dump of keys too. bool g_doRecurse= true; bool g_doFlushkeys= false; std::string reghexdump(const ByteVector& data); #ifdef WINCEREGUTL bool ITRegistryFlush() { DWORD outsize=0; BYTE *outbuf=NULL; HRESULT res= ItsutilsInvoke(L"ITRegistryFlush", 0, NULL, &outsize, (BYTE**)&outbuf); if (outbuf!=NULL) LocalFree(outbuf); return res==0; } #endif class RegistryKey; /* class RegistryData { }; class DwordData : public RegistryData { public: DwordData(ByteVector& data) { } }; class BinaryData : public RegistryData { public: BinaryData(ByteVector& data) { } }; class StringData : public RegistryData { public: StringData(ByteVector& data) { } }; class StringListData : public RegistryData { public: StringListData(ByteVector& data) { } }; */ StringList g_warnings; void DumpWarnings() { for (size_t i= 0 ; i'~') qstr+=stringformat("\\x%02x", (unsigned char)str[i]); else qstr+=str[i]; } return qstr+"\""; } std::string MultiszAsString() const { StringList list= GetStringList(); for (size_t i=0 ; i RegistryValueMap; typedef std::vector RegistryKeyList; class RegistryKey { public: static RegistryKey FromKeySpec(const std::string& keyspec) { HKEY hRoot; std::string path; size_t slashpos= keyspec.find_first_of("/\\"); // 0x80000000 HKEY_CLASSES_ROOT hkcr // 0x80000001 HKEY_CURRENT_USER hkcu // 0x80000002 HKEY_LOCAL_MACHINE hklm hkpr // 0x80000003 HKEY_USERS hku // 0x80000004 HKEY_PERFORMANCE_DATA hkpd // 0x80000005 HKEY_CURRENT_CONFIG hkcc // 0x80000006 HKEY_DYN_DATA hkdd // 0x80000050 HKEY_PERFORMANCE_TEXT hkpt // 0x80000060 HKEY_PERFORMANCE_NLSTEXT hkpn // if (stringicompare(keyspec.substr(0,slashpos), "hkcr")==0) hRoot= HKEY_CLASSES_ROOT; else if (stringicompare(keyspec.substr(0,slashpos), "hkey_classes_root")==0) hRoot= HKEY_CLASSES_ROOT; else if (stringicompare(keyspec.substr(0,slashpos), "hkcu")==0) hRoot= HKEY_CURRENT_USER; else if (stringicompare(keyspec.substr(0,slashpos), "hkey_current_user")==0) hRoot= HKEY_CURRENT_USER; else if (stringicompare(keyspec.substr(0,slashpos), "hklm")==0) hRoot= HKEY_LOCAL_MACHINE; else if (stringicompare(keyspec.substr(0,slashpos), "hkey_local_machine")==0) hRoot= HKEY_LOCAL_MACHINE; else if (stringicompare(keyspec.substr(0,slashpos), "hku")==0) hRoot= HKEY_USERS; else if (stringicompare(keyspec.substr(0,slashpos), "hkey_users")==0) hRoot= HKEY_USERS; #ifdef HKEY_PERFORMANCE_DATA else if (stringicompare(keyspec.substr(0,slashpos), "hkpd")==0) hRoot= HKEY_PERFORMANCE_DATA; else if (stringicompare(keyspec.substr(0,slashpos), "hkey_performance_data")==0) hRoot= HKEY_PERFORMANCE_DATA; #endif #ifdef HKEY_CURRENT_CONFIG else if (stringicompare(keyspec.substr(0,slashpos), "hkcc")==0) hRoot= HKEY_CURRENT_CONFIG; else if (stringicompare(keyspec.substr(0,slashpos), "hkey_current_config")==0) hRoot= HKEY_CURRENT_CONFIG; #endif #ifdef HKEY_DYN_DATA else if (stringicompare(keyspec.substr(0,slashpos), "hkdd")==0) hRoot= HKEY_DYN_DATA; else if (stringicompare(keyspec.substr(0,slashpos), "hkey_dyn_data")==0) hRoot= HKEY_DYN_DATA; #endif #ifdef HKEY_PERFORMANCE_TEXT else if (stringicompare(keyspec.substr(0,slashpos), "hkpt")==0) hRoot= HKEY_PERFORMANCE_TEXT; else if (stringicompare(keyspec.substr(0,slashpos), "hkey_performance_text")==0) hRoot= HKEY_PERFORMANCE_TEXT; #endif #ifdef HKEY_PERFORMANCE_NLSTEXT else if (stringicompare(keyspec.substr(0,slashpos), "hkpn")==0) hRoot= HKEY_PERFORMANCE_NLSTEXT; else if (stringicompare(keyspec.substr(0,slashpos), "hkey_performance_nlstext")==0) hRoot= HKEY_PERFORMANCE_NLSTEXT; #endif else if (isdigit(keyspec[0])) { hRoot= (HKEY)(0x80000000+strtoul(stringptr(keyspec), 0, 0)); } else hRoot= HKEY_LOCAL_MACHINE; if (slashpos==keyspec.npos) path= ""; else path= keyspec.substr(slashpos+1); //debug("FromKeySpec: %08lx - %s\n", hRoot, path.c_str()); return RegistryKey(hRoot, path); } RegistryKey() : m_hRoot(0), m_path(), m_hKey(0), m_suppress_errors(false) { } RegistryKey(HKEY hRoot) : m_hRoot(hRoot), m_path(), m_hKey(0) { } RegistryKey(const RegistryKey& hKey) : m_hRoot(hKey.GetRoot()), m_path(hKey.GetPath()), m_hKey(0) { } RegistryKey& operator=(const RegistryKey& rk) { m_hRoot=rk.GetRoot(); m_path= rk.GetPath(); m_hKey= 0; return *this; } RegistryKey(const RegistryKey& hRoot, const std::string& path) : m_hRoot(hRoot.GetRoot()), m_hKey(0) { m_path= hRoot.GetPath(); if (!m_path.empty()) m_path += "\\"; m_path += path; } ~RegistryKey() { Close(); } void Close() { __RegCloseKey(m_hKey); m_hKey= 0; } bool Open() { if (m_hKey) return true; DWORD dwAccessTypes[5]= {0xf003f, 0x20019, KEY_ALL_ACCESS|DELETE, KEY_ALL_ACCESS, KEY_READ}; LONG res=-1; for (int i=0 ; i<5 ; i++) { res= __RegOpenKeyEx(m_hRoot, ToWString(m_path).c_str(), 0, dwAccessTypes[i], &m_hKey); if (res==ERROR_SUCCESS) break; } if (res!=ERROR_SUCCESS) { if (!m_suppress_errors) error(res, "Failed to open key %hs:'%hs'", GetRootName().c_str(), m_path.c_str()); m_hKey= 0; return false; } m_dwMaxSubKeyNameLength= STD_NAME_BUF_SIZE; m_dwMaxValueNameLength= STD_NAME_BUF_SIZE; m_dwMaxValueLength= STD_VALUE_BUF_SIZE; /* * * this does not seem to work on ce/rapi * __RegQueryInfoKey(m_hKey, NULL, NULL, NULL, NULL, &m_dwMaxSubKeyNameLength, NULL, NULL, &m_dwMaxValueNameLength, &m_dwMaxValueLength, NULL, NULL); if ( m_dwMaxSubKeyNameLength==0 && m_dwMaxValueNameLength==0 && m_dwMaxValueLength==0) { debug("ERROR: noinfo\n"); m_dwMaxSubKeyNameLength= STD_NAME_BUF_SIZE; m_dwMaxValueNameLength= STD_NAME_BUF_SIZE; m_dwMaxValueLength= STD_VALUE_BUF_SIZE; } */ return true; } HKEY GetHKey() { Open(); return m_hKey; } void info() { std::Wstring regclass; regclass.resize(256); DWORD cbClass= regclass.size(); DWORD nSubKeys=0; DWORD maxSubKeyNameLength=0; DWORD maxClassLength=0; DWORD nValues=0; DWORD maxValueNameLength=0; DWORD maxValueLength=0; Open(); // BUG: only the key and value counts are returned LONG res= __RegQueryInfoKey(m_hKey, stringptr(regclass), &cbClass, NULL, &nSubKeys, &maxSubKeyNameLength, &maxClassLength, &nValues, &maxValueNameLength, &maxValueLength, NULL, NULL); if (res != ERROR_SUCCESS) { error(res, "__RegQueryInfoKey(%hs:'%hs')", GetRootName().c_str(), m_path.c_str()); return ; } regclass.resize(cbClass); debug("regclass='%hs' nkeys=%d nvals=%d maxkey=%d maxcls=%d maxname=%d maxval=%d\n", regclass.c_str(), nSubKeys, maxSubKeyNameLength, maxClassLength, nValues, maxValueNameLength,&maxValueLength); } // returns the roothive of this key HKEY GetRoot() const { return m_hRoot; } // returns the full path to this key std::string GetPath() const { return m_path; } // returns the name of this key std::string GetName() const { size_t pos= m_path.find_last_of("\\/"); if (pos!=m_path.npos) return m_path.substr(pos+1); else return m_path; } // returns the name of the hive of this key std::string GetRootName() const { if (m_hRoot==HKEY_CLASSES_ROOT ) return "HKCR"; if (m_hRoot==HKEY_CURRENT_USER ) return "HKCU"; if (m_hRoot==HKEY_LOCAL_MACHINE ) return "HKLM"; if (m_hRoot==HKEY_USERS ) return "HKU"; #ifdef HKEY_PERFORMANCE_DATA if (m_hRoot==HKEY_PERFORMANCE_DATA ) return "HKPD"; #endif #ifdef HKEY_CURRENT_CONFIG if (m_hRoot==HKEY_CURRENT_CONFIG ) return "HKCC"; #endif #ifdef HKEY_DYN_DATA if (m_hRoot==HKEY_DYN_DATA ) return "HKDD"; #endif #ifdef HKEY_PERFORMANCE_TEXT if (m_hRoot==HKEY_PERFORMANCE_TEXT ) return "HKPT"; #endif #ifdef HKEY_PERFORMANCE_NLSTEXT if (m_hRoot==HKEY_PERFORMANCE_NLSTEXT) return "HKPN"; #endif return "unknown"; } // creates a new subkey bool CreateSubKey(const std::string& keyname) { if (!Open()) return false; HKEY hk; DWORD disp; LONG res= __RegCreateKeyEx(m_hKey, ToWString(keyname).c_str(), 0, NULL, 0, 0, NULL, &hk, &disp); if (res != ERROR_SUCCESS) { error(res, "Failed to create subkey %hs:'%hs'\\'%hs'", GetRootName().c_str(), m_path.c_str(), keyname.c_str()); return false; } __RegCloseKey(hk); return true; } // deletes a childless subkey from this key bool DeleteSubKey(const std::string& keyname) { if (!Open()) return false; LONG res= __RegDeleteKey(m_hKey, ToWString(keyname).c_str()); if (res != ERROR_SUCCESS) { error(res, "Failed to delete subkey %hs:'%hs'\\'%hs'", GetRootName().c_str(), m_path.c_str(), keyname.c_str()); return false; } return true; } // delete all children bool DeleteChildren() { bool bRes= true; StringList children= GetSubKeyNames(); for (StringList::iterator i= children.begin() ; i!=children.end() ; ++i) { bRes = bRes && DeleteSubKey(*i); } return bRes; } bool DeleteValue(const std::string& valuename) { if (!Open()) return false; LONG res= __RegDeleteValue(m_hKey, ToWString(valuename).c_str()); if (res != ERROR_SUCCESS) { error(res, "Failed to delete value %hs:'%hs'\\'%hs'", GetRootName().c_str(), m_path.c_str(), valuename.c_str()); return false; } return true; } //------------------------------------------------------------------- // deletes this key and all it's children bool DeleteKey() { if (!DeleteChildren()) return false; Close(); if (!GetParent().DeleteSubKey(GetName())) return false; return true; } //------------------------------------------------------------------- // creates registry key bool CreateKey() { m_suppress_errors= true; if (Open()) { m_suppress_errors= false; Close(); return true; } m_suppress_errors= false; if (m_path.empty()) return false; if (!GetParent().CreateKey()) return false; if (!GetParent().CreateSubKey(GetName())) return false; debug("created key %hs\\%hs\n", GetRootName().c_str(), GetPath().c_str()); return true; } void DumpKey() { debug("[%hs\\%hs]\n", GetRootName().c_str(), GetPath().c_str()); try { DumpValues(); } catch(std::string &e) { debug("ERROR: %s\n", e.c_str()); } debug("\n"); if (!g_doRecurse) return; try { DumpChildren(); } catch(std::string &e) { debug("ERROR: %s\n", e.c_str()); } } //------------------------------------------------------------------- void DumpValues() { RegistryValueMap map= GetValues(); for (RegistryValueMap::iterator i= map.begin() ; i!=map.end() ; ++i) { if (g_outputAllKeysHex) { std::wstring wkey= ToWString((*i).first); debug(";%hs\n", reghexdump(ByteVector((BYTE*)stringptr(wkey), (BYTE*)(stringptr(wkey)+wkey.size()))).c_str()); } debug("%hs=%hs\n", (*i).first.c_str(), (*i).second.AsString().c_str()); DumpWarnings(); } } void DumpChildren() { RegistryKeyList list= GetSubKeys(); for (RegistryKeyList::iterator i= list.begin() ; i!=list.end() ; ++i) { (*i).DumpKey(); } } //------------------------------------------------------------------- // returns parent to this key RegistryKey GetParent() { size_t pos= m_path.find_last_of("\\/"); if (pos!=m_path.npos) return RegistryKey(m_hRoot, m_path.substr(0, pos)); else return RegistryKey(m_hRoot); } StringList GetSubKeyNames() { StringList list; if (!Open()) throw stringformat("GetSubKeyNames(%hs:'%hs'): could not open", GetRootName().c_str(), m_path.c_str()); for (int i=0 ; true ; i++) { DWORD cbName = m_dwMaxSubKeyNameLength+1; std::Wstring wname; wname.resize(cbName); LONG res =__RegEnumKeyEx(m_hKey, i, stringptr(wname), &cbName, NULL, NULL, NULL, NULL); if (res==ERROR_NO_MORE_ITEMS) break; if (res!=ERROR_SUCCESS) { error(res, "__RegEnumKeyEx(%hs:'%hs', %d)", GetRootName().c_str(), GetPath().c_str(), i); continue; } wname.resize(cbName); list.push_back(ToString(wname)); } return list; } RegistryKeyList GetSubKeys() { RegistryKeyList list; if (!Open()) throw stringformat("GetSubKeys(%hs:'%hs'): could not open", GetRootName().c_str(), m_path.c_str()); for (int i=0 ; true ; i++) { DWORD cbName = m_dwMaxSubKeyNameLength+1; std::Wstring wname; wname.resize(cbName); LONG res =__RegEnumKeyEx(m_hKey, i, stringptr(wname), &cbName, NULL, NULL, NULL, NULL); if (res==ERROR_NO_MORE_ITEMS) break; if (res!=ERROR_SUCCESS) { error(res, "__RegEnumKeyEx(%hs:'%hs', %d)", GetRootName().c_str(), GetPath().c_str(), i); continue; } wname.resize(cbName); std::string aname= ToString(wname); if (aname.empty()) debug("ERROR converting subkey %d of %s : %s\n", i, m_path.c_str(), hexdump((BYTE*)wname.c_str(), wname.size(), 2).c_str()); else list.push_back(RegistryKey(*this, aname)); } return list; } StringList GetValueNames() { StringList list; if (!Open()) throw stringformat("GetValueNames(%hs:'%hs'): could not open", GetRootName().c_str(), m_path.c_str()); for (int i=0 ; true ; i++) { DWORD cbName = m_dwMaxValueNameLength+1; std::Wstring wname; wname.resize(cbName); LONG res= __RegEnumValue(m_hKey, i, stringptr(wname), &cbName, NULL, NULL, NULL, NULL); if (res==ERROR_NO_MORE_ITEMS) break; if (res==ERROR_MORE_DATA) { wname.resize(cbName); res= __RegEnumValue(m_hKey, i, stringptr(wname), &cbName, NULL, NULL, NULL, NULL); } if (res!=ERROR_SUCCESS) { error(res, "GetValueNames: __RegEnumValue(%hs:'%hs', %d)", GetRootName().c_str(), GetPath().c_str(), i); continue; } wname.resize(cbName); list.push_back(ToString(wname)); } return list; } RegistryValueMap GetValues() { RegistryValueMap map; if (!Open()) throw stringformat("GetValues(%hs:'%hs'): could not open", GetRootName().c_str(), m_path.c_str()); for (int i=0 ; true ; i++) { DWORD cbName = m_dwMaxValueNameLength+1; std::Wstring wname; wname.resize(cbName); DWORD cbData = m_dwMaxValueLength; ByteVector data; data.resize(cbData); DWORD dwType; LONG res= __RegEnumValue(m_hKey, i, stringptr(wname), &cbName, NULL, &dwType, vectorptr(data), &cbData); if (res==ERROR_NO_MORE_ITEMS) break; if (res==ERROR_MORE_DATA) { wname.resize(cbName); data.resize(cbData); res= __RegEnumValue(m_hKey, i, stringptr(wname), &cbName, NULL, &dwType, vectorptr(data), &cbData); } if (res!=ERROR_SUCCESS) { error(res, "GetValues: __RegEnumValue(%hs:'%hs', %d)", GetRootName().c_str(), GetPath().c_str(), i); continue; } wname.resize(cbName); data.resize(cbData); map[ToString(wname)]= RegistryValue(dwType, data); } return map; } RegistryValue GetValue(const std::string& valuename) { if (!Open()) throw stringformat("GetValue(%hs:'%hs', '%hs'): could not open", GetRootName().c_str(), m_path.c_str(), valuename.c_str()); DWORD cbData = m_dwMaxValueLength; ByteVector data; data.resize(cbData); DWORD dwType; LONG res= __RegQueryValueEx(m_hKey, ToWString(valuename).c_str(), NULL, &dwType, vectorptr(data), &cbData); if (res==ERROR_MORE_DATA) { data.resize(cbData); res= __RegQueryValueEx(m_hKey, ToWString(valuename).c_str(), NULL, &dwType, vectorptr(data), &cbData); } if (res!=ERROR_SUCCESS) throw stringformat("GetValue(%hs:'%hs', '%hs'): __RegQueryValueEx:%08lx", GetRootName().c_str(), GetPath().c_str(), valuename.c_str(), res); data.resize(cbData); return RegistryValue(dwType, data); } bool SetValue(const std::string& valuename, const RegistryValue& value) { if (!Open()) throw stringformat("SetValue(%hs:'%hs', '%hs'): could not open", GetRootName().c_str(), m_path.c_str(), valuename.c_str()); //debug("setting [%s] %s to %s\n", m_path.c_str(), valuename.c_str(), value.AsString().c_str()); ByteVector data= value.GetData(); LONG res= __RegSetValueEx(m_hKey, ToWString(valuename).c_str(), NULL, value.GetType(), vectorptr(data), data.size()); if (res!=ERROR_SUCCESS) throw stringformat("SetValue(%hs:'%hs', '%hs'): __RegSetValueEx:%08lx", GetRootName().c_str(), GetPath().c_str(), valuename.c_str(), res); debug("set value %hs\\%hs %hs : %hs\n", GetRootName().c_str(), GetPath().c_str(), valuename.c_str(), value.AsString().c_str()); return true; } private: HKEY m_hRoot; std::string m_path; HKEY m_hKey; DWORD m_dwMaxSubKeyNameLength; DWORD m_dwMaxValueNameLength; DWORD m_dwMaxValueLength; bool m_suppress_errors; }; std::string reghexdump(const ByteVector& data) { std::string str; if (data.empty()) return ""; str.resize(data.size()*3-1); for (size_t i=0 ; i 65536 ) // - read until line has EOLN while (line.size() && (line[line.size()-1]=='\r' || line[line.size()-1]=='\n')) { line.resize(line.size()-1); } return true; } #ifndef _WIN32_WCE bool ProcessRegFile(const std::string& filename) { FILE *f= fopen(filename.c_str(), "r"); if (f==NULL) { perror(filename.c_str()); return false; } RegistryKey curkey; std::string line; while (ReadLine(f, line)) { while (line.size() && isspace(line[line.size()-1])) { line.resize(line.size()-1); } if (line.size()==0) continue; else if (line=="REGEDIT4") continue; else if (line[0]=='[' && line[line.size()-1]==']') { curkey= RegistryKey::FromKeySpec(line.substr(1, line.size()-2)); curkey.CreateKey(); } else if (line[0]==';') { // skip comments. } else { // remove leading whitespace line.erase(0, line.find_first_not_of(" \t")); std::string valuename= GetNameFromSetSpec(line, 0); std::string valuespec= GetValueSpecFromSetSpec(line, 0); //debug("valline: %hs = %hs\n", valuename.c_str(), valuespec.c_str()); curkey.SetValue(valuename, RegistryValue::FromValueSpec(valuespec)); } } fclose(f); return true; } #endif bool IsValueNameSpec(const std::string& spec) { if (spec[0]!=':') return false; if (spec.find('=')==std::string::npos) return true; if (spec[1]=='\'' || spec[1]=='\"') { size_t endquote= findendquote(spec, 2, spec[1]); if (endquote==std::string::npos) { throw stringformat("IsValueNameSpec: missing endquote in '%hs'", spec.c_str()); } return endquote==spec.size(); } return false; } std::string GetNameFromValueNameSpec(const std::string& spec, size_t start) { if (spec[start]=='\'' || spec[start]=='\"') { size_t endquote= findendquote(spec, start+1, spec[start]); //debug("GetNameFromValueNameSpec:%s\n", spec.substr(1, endquote-3).c_str()); return unescape(spec.substr(start, endquote-start-1)); } //debug("GetNameFromValueNameSpec:%s\n", spec.substr(1).c_str()); return spec.substr(start); } bool IsSetSpec(const std::string& spec) { if (spec[0]!=':') return false; if (spec.find('=')==std::string::npos) return false; if (spec[1]=='\'' || spec[1]=='\"') { size_t endquote= findendquote(spec, 2, spec[1]); if (endquote==std::string::npos) { throw stringformat("IsSetSpec: missing endquote in '%hs'", spec.c_str()); } //debug("isset: endq=%d size=%d c=%c\n", endquote, spec.size(), spec[endquote]); if (endquote==spec.size()) return false; return (spec[endquote]=='='); } return true; } std::string GetNameFromSetSpec(const std::string& spec, size_t start) { if (spec[start]=='\'' || spec[start]=='\"') { size_t endquote= findendquote(spec, start+1, spec[start]); //debug("GetNameFromSetSpec:%s\n", spec.substr(1, endquote-3).c_str()); //todo: check for missing quote. return unescape(spec.substr(start+1, endquote-start-2)); } size_t eqpos= spec.find('='); //debug("GetNameFromSetSpec:%s\n", spec.substr(1,eqpos-1).c_str()); return spec.substr(start,eqpos-start); } std::string GetValueSpecFromSetSpec(const std::string& spec, size_t start) { if (spec[start]=='\'' || spec[start]=='\"') { size_t endquote= findendquote(spec, start+1, spec[start]); //debug("GetValueSpecFromSetSpec:%s\n", spec.substr(endquote).c_str()); //todo: check for missing quote. size_t eqpos= spec.find('=', endquote); return spec.substr(eqpos+1); } size_t eqpos= spec.find('='); //debug("GetValueSpecFromSetSpec:%s\n", spec.substr(eqpos+1).c_str()); return spec.substr(eqpos+1); } bool IsRegFile(const std::string& filespec) { return filespec[0]=='@'; } std::string GetFilenameFromRegfileSpec(const std::string& filespec) { return filespec.substr(1); } void checkparameters(RegAction action, const RegistryKeyList& keys, const StringList& names, const RegistryValueMap& values) { if (action==DO_CREATE && names.size()) throw std::string("checkparameters: create with name"); if (action==DO_CREATE && values.size()) throw std::string("checkparameters: create with 'name=value'"); if (action==DO_CREATE && keys.size()==0) throw std::string("checkparameters: create without keys"); if (action==DO_DELETE && values.size()) throw std::string("checkparameters: delete with 'name=value'"); if (action==DO_DELETE && keys.size()==0) throw std::string("checkparameters: delete without keys"); if (action==DO_LIST && values.size()) throw std::string("checkparameters: list with 'name=value'"); if (action==DO_LIST && keys.size()==0) throw std::string("checkparameters: list without keys"); #ifndef _WIN32_WCE if (action==DO_SET && names.size()) throw std::string("checkparameters: set value with bare name"); if (action==DO_SET && values.size()==0) throw std::string("checkparameters: set without values"); #endif } #ifdef _WIN32_WCE int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // DebugOutputDebugString(); DebugSetLogfile("regbk.log"); debugt("starting registry dump\n"); RegAction action= DO_LIST; bool fRecurse= false; RegistryKeyList keys; StringList names; RegistryValueMap values; StringList regfiles; StringList args; if (!SplitString(ToString(lpCmdLine), args, false)) { error("Error in commandline"); return false; } StringList keylist; g_outputFullHex= true; for (StringList::iterator i= args.begin() ; i!=args.end() ; ++i) { std::string& arg= *i; if (arg[0]=='-') switch(arg[1]) { case 'X': g_outputFullHex= false; break; } else { keylist.push_back(arg); } } if (keylist.size()==0 || tolower(keylist[0])=="install") { if (keylist.size()) DebugSetLogfile("\\SD Card\\regbk.log"); RegistryKey::FromKeySpec("HKCU").DumpKey(); RegistryKey::FromKeySpec("HKLM").DumpKey(); RegistryKey::FromKeySpec("HKCR").DumpKey(); } else { for (int i=0 ; i):filename' to read the value from \n"); debug("\n"); debug(" with hex() and file() a value type may be specified, either as a decimal nr\n"); debug(" or as a typename: none, sz, binary, dword, ... etc\n"); debug("\n"); debug("keys are specified as follows:\n"); debug(" HKLM\\Software\\HTC\n"); debug("\n"); debug("if multiple keys and keyvals are specified pregutl\n"); debug("operates on all combinations\n"); } int main(int argc, char *argv[]) { DebugStdOut(); RegAction action= DO_LIST; RegistryKeyList keys; StringList names; RegistryValueMap values; StringList regfiles; try { for (int i=1 ; i