bool saveAsXml(xmlWriter w, bool bFakedXml, string strKeyname, int hKey, string strLimitValue) { // write key name int classLength = 0; int cSubKeys = 0; // number of subkeys int cbMaxSubKey = 0; // longest subkey size int cchMaxClass = 0; // longest class string int cValues = 0; // number of values for key int cchMaxValue = 0; // longest value name int cbMaxValueData = 0; // longest value data int cbSecurityDescriptor = 0; // size of security descriptor FILETIME ftLastWriteTime = new FILETIME(); // last write time int i; int retCode; // Get the class name and the value count. retCode = RegQueryInfoKeyA(hKey, // key handle null, // buffer for class name ref classLength, // length of class string 0, // reserved ref cSubKeys, // number of subkeys ref cbMaxSubKey, // longest subkey size ref cchMaxClass, // longest class string ref cValues, // number of values for this key ref cchMaxValue, // longest value name ref cbMaxValueData, // longest value data ref cbSecurityDescriptor, // security descriptor ref ftLastWriteTime); // last write time if (retCode != ERROR_SUCCESS) { return(false); } // Enumerate the child keys, until RegEnumKeyEx fails. byte [] achKey = new byte[cbMaxSubKey + 1]; xmlElement wkey = new xmlElement(XML_KEY); if (strKeyname.Length > 0) { if (!bFakedXml) // standard xml { wkey.addAttrib(getEscapedXmlString(XML_NAME), getEscapedXmlString(strKeyname)); if (cSubKeys > 0 || cValues > 0) { wkey.write(w, 1, false, true); } else { wkey.writeEmpty(w, 1, false, true); } } else // faked xml { wkey.setName(getEscapedXmlString(strKeyname)); } } // each 50 values, we pump a window message, to check out whether the user hit ESCAPE if ((_nSaveCounter++ % 50) == 0) { // this could be done.... } // save values ArrayList arrValues = addRegistryValues(hKey); int nbItems = arrValues.Count; for (int j = 0; j < nbItems; j++) { keyValue p = (keyValue)arrValues[j]; if (strLimitValue.Length != 0 && p.getName().CompareTo(strLimitValue) != 0) { continue; } if (p.getName().CompareTo(IDS_DEFAULTVALUENAME) != 0 || p.getValue().CompareTo(IDS_DEFAULTVALUEVALUE) != 0) { int dwType = p.getType(); if (!bFakedXml) // standard xml { xmlElement wvalue = new xmlElement(XML_VALUE); wvalue.addAttrib(XML_NAME, getEscapedXmlString(p.getName())); wvalue.addAttrib(XML_VALUE2, getEscapedXmlString(p.getValue())); if (dwType != REG_SZ && dwType != REG_NONE) { wvalue.addAttrib(XML_TYPE, getEscapedXmlString(stringFromValueType(dwType))); } wvalue.writeEmpty(w, 1, false, true); } else // faked xml { wkey.addAttrib(getEscapedXmlString(p.getName()), getEscapedXmlString(p.getValue())); } } } if (strKeyname.Length != 0) { if (bFakedXml) { if (cSubKeys > 0) { wkey.write(w, 1, false, true); } else { wkey.writeEmpty(w, 1, false, true); } } } for (i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++) { int achKeyMaxLength = cbMaxSubKey + 1; retCode = RegEnumKeyExA(hKey, i, ref achKey[0], ref achKeyMaxLength, 0, null, ref cchMaxClass, ref ftLastWriteTime); if (retCode == ERROR_SUCCESS && achKeyMaxLength > 0) { achKey[achKeyMaxLength] = 0; // force EOL Encoding ascii = Encoding.ASCII; // Convert the new byte[] into a char[] and then into a string. char[] asciiChars = new char[ascii.GetCharCount(achKey, 0, achKeyMaxLength)]; ascii.GetChars(achKey, 0, achKeyMaxLength, asciiChars, 0); string sKeyName = new string(asciiChars); // open sub keys int hSubkey = 0; if (RegOpenKeyA(hKey, sKeyName, ref hSubkey) == ERROR_SUCCESS) { if (!saveAsXml(w, bFakedXml, sKeyName, hSubkey, strLimitValue)) { return(false); } RegCloseKey(hSubkey); } } } // end for if (strKeyname.Length != 0) { if (!bFakedXml) { if (cSubKeys > 0 || cValues > 0) { wkey.writeClosingTag(w, -1, false, true); } } else { // with faked xml, we only need to actually close the tag when there // are keys under it, otherwise, we did a WriteEmpty above. if (cSubKeys > 0) { wkey.writeClosingTag(w, -1, false, true); } } } return(true); }
ArrayList addRegistryValues(int hKey) { ArrayList arrValues = new ArrayList(); int classLength = 0; int cSubKeys = 0; // number of subkeys int cbMaxSubKey = 0; // longest subkey size int cchMaxClass = 0; // longest class string int cValues = 0; // number of values for key int cchMaxValue = 0; // longest value name int cbMaxValueData = 0; // longest value data int cbSecurityDescriptor = 0; // size of security descriptor FILETIME ftLastWriteTime = new FILETIME(); // last write time int j; int retValue; // Get the class name and the value count. retValue = RegQueryInfoKeyA(hKey, // key handle null, // buffer for class name ref classLength, // length of class string 0, // reserved ref cSubKeys, // number of subkeys ref cbMaxSubKey, // longest subkey size ref cchMaxClass, // longest class string ref cValues, // number of values for this key ref cchMaxValue, // longest value name ref cbMaxValueData, // longest value data ref cbSecurityDescriptor, // security descriptor ref ftLastWriteTime); // last write time // Enumerate the child keys, until RegEnumKeyEx fails. byte [] achValueName = new byte[cchMaxValue + 1]; byte [] achValueData = new byte[cbMaxValueData + 1]; string strDefaultName = IDS_DEFAULTVALUENAME; // (Default) string strDefaultValue = IDS_DEFAULTVALUEVALUE; // (value not set) // Enumerate the key values. if (cValues != 0 && cValues != -1 && retValue == ERROR_SUCCESS) { for (j = 0, retValue = ERROR_SUCCESS; j < cValues; j++) { int cchValueName = cchMaxValue + 1; int cchValueData = cbMaxValueData + 1; int dwType = 0; achValueName[0] = 0; achValueData[0] = 0; string sValueName = ""; retValue = RegEnumValueA(hKey, j, ref achValueName[0], ref cchValueName, 0, ref dwType, ref achValueData[0], ref cchValueData); if (retValue == ERROR_SUCCESS) { keyValue p = new keyValue(); if (cchValueName == 0 && sValueName.Length == 0) { if (cchValueData == 0 && achValueData[0] == 0) { p.setKeyValue(strDefaultName, strDefaultValue, dwType); } else { p.setKeyValue(strDefaultName, convertToString(REG_SZ, achValueData, cchValueData), dwType); } } else { Encoding ascii = Encoding.ASCII; // Convert the new byte[] into a char[] and then into a string. char[] asciiChars = new char[ascii.GetCharCount(achValueName, 0, cchValueName)]; ascii.GetChars(achValueName, 0, cchValueName, asciiChars, 0); string asciiString = new string(asciiChars); sValueName = asciiString; p.setKeyValue(sValueName, convertToString(dwType, achValueData, cchValueData), dwType); } arrValues.Add(p); } } } // end if (cValues && cValues!=-1) // now sort all this int nNbItems = arrValues.Count; // make sure we have at least a default value to play with bool bFound = false; int i = 0; while (!bFound && i < nNbItems) { keyValue p = (keyValue)arrValues[i++]; bFound = (p.getName().CompareTo(strDefaultName) == 0); } if (!bFound) { // this is a fake add, just to visually match what's shown in regedit keyValue p = new keyValue(); p.setKeyValue(strDefaultName, strDefaultValue, REG_SZ); arrValues.Insert(0, p); } return(arrValues); }