001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.registry; 020 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.StringWriter; 024import java.util.ArrayList; 025 026import lucee.commons.cli.Command; 027import lucee.commons.lang.StringUtil; 028import lucee.runtime.functions.string.ParseNumber; 029import lucee.runtime.op.Caster; 030import lucee.runtime.type.util.ListUtil; 031 032 033/** 034 * 035 */ 036public final class RegistryQuery { 037 038 private static final char DQ='"'; 039 private static final int lenDWORD=RegistryEntry.REGDWORD_TOKEN.length(); 040 private static final int lenSTRING=RegistryEntry.REGSTR_TOKEN.length(); 041 private static final String NO_NAME="<NO NAME>"; 042 043 /** 044 * execute a String query on command line 045 * @param query String to execute 046 * @return 047 * @throws IOException 048 * @throws InterruptedException 049 */ 050 public static String executeQuery(String[] cmd) throws IOException, InterruptedException { 051 return Command.execute(cmd).getOutput(); 052 } 053 054 /** 055 * gets a single value form the registry 056 * @param branch brach to get value from 057 * @param entry entry to get 058 * @param type type of the registry entry to get 059 * @return registry entry or null of not exist 060 * @throws RegistryException 061 * @throws IOException 062 * @throws InterruptedException 063 */ 064 public static RegistryEntry getValue(String branch, String entry, short type) throws RegistryException, IOException, InterruptedException { 065 String[] cmd = new String[]{"reg","query",cleanBrunch(branch),"/v",entry}; 066 RegistryEntry[] rst = filter(executeQuery(cmd),branch,type); 067 if(rst.length==1) { 068 return rst[0]; 069 //if(type==RegistryEntry.TYPE_ANY || type==r.getType()) return r; 070 } 071 return null; 072 } 073 074 /** 075 * gets all entries of one branch 076 * @param branch 077 * @param type 078 * @return 079 * @throws RegistryException 080 * @throws IOException 081 * @throws InterruptedException 082 */ 083 public static RegistryEntry[] getValues(String branch, short type) throws RegistryException, IOException, InterruptedException { 084 String[] cmd = new String[]{"reg","query",branch}; 085 return filter(executeQuery(cmd),cleanBrunch(branch),type); 086 } 087 088 /** 089 * writes a value to registry 090 * @param branch 091 * @param entry 092 * @param type 093 * @param value 094 * @throws RegistryException 095 * @throws IOException 096 * @throws InterruptedException 097 */ 098 public static void setValue(String branch, String entry, short type, String value) throws RegistryException, IOException, InterruptedException { 099 100 if(type==RegistryEntry.TYPE_KEY) { 101 String fullKey=ListUtil.trim(branch,"\\")+"\\"+ListUtil.trim(entry,"\\"); 102 //String[] cmd = new String[]{"reg","add",cleanBrunch(fullKey),"/ve","/f"}; 103 String[] cmd = new String[]{"reg","add",cleanBrunch(fullKey),"/f"}; 104 executeQuery(cmd); 105 } 106 else { 107 if(type==RegistryEntry.TYPE_DWORD)value=Caster.toString(Caster.toIntValue(value,0)); 108 String[] cmd = new String[]{"reg","add",cleanBrunch(branch),"/v",entry,"/t",RegistryEntry.toStringType(type),"/d",value,"/f"}; 109 executeQuery(cmd); 110 } 111 } 112 113 /** 114 * deletes a value or a key 115 * @param branch 116 * @param entry 117 * @throws IOException 118 * @throws InterruptedException 119 */ 120 public static void deleteValue(String branch, String entry) throws IOException, InterruptedException { 121 if(entry==null) { 122 String[] cmd = new String[]{"reg","delete",cleanBrunch(branch),"/f"}; 123 executeQuery(cmd); 124 //executeQuery("reg delete \""+List.trim(branch,"\\")+"\" /f"); 125 } 126 else { 127 String[] cmd = new String[]{"reg","delete",cleanBrunch(branch),"/v",entry,"/f"}; 128 executeQuery(cmd); 129 //executeQuery("reg delete \""+List.trim(branch,"\\")+"\" /v "+entry+" /f"); 130 } 131 } 132 133 private static String cleanBrunch(String branch) { 134 branch=branch.replace('/', '\\'); 135 branch=ListUtil.trim(branch,"\\"); 136 if(branch.length()==0) return "\\"; 137 return branch; 138 } 139 140 141 /** 142 * filter registry entries from the raw result 143 * @param string plain result to filter regisry entries 144 * @param branch 145 * @param type 146 * @return filtered entries 147 * @throws RegistryException 148 */ 149 private static RegistryEntry[] filter(String string,String branch, short type) throws RegistryException { 150 branch=ListUtil.trim(branch,"\\"); 151 StringBuffer result=new StringBuffer(); 152 ArrayList array=new ArrayList(); 153 String[] arr=string.split("\n"); 154 155 for(int i=0;i<arr.length;i++) { 156 String line=arr[i].trim(); 157 int indexDWORD=line.indexOf(RegistryEntry.REGDWORD_TOKEN); 158 int indexSTRING=line.indexOf(RegistryEntry.REGSTR_TOKEN); 159 160 if((indexDWORD!=-1) || (indexSTRING!=-1) ) { 161 int index=(indexDWORD==-1)?indexSTRING:indexDWORD; 162 int len=(indexDWORD==-1)?lenSTRING:lenDWORD; 163 short _type=(indexDWORD==-1)?RegistryEntry.TYPE_STRING:RegistryEntry.TYPE_DWORD; 164 165 if(result.length()>0)result.append("\n"); 166 167 String _key=line.substring(0,index).trim(); 168 String _value=StringUtil.substringEL(line,index+len+1,"").trim(); 169 170 if(_key.equals(NO_NAME)) _key=""; 171 if(_type==RegistryEntry.TYPE_DWORD)_value=String.valueOf(ParseNumber.invoke(_value.substring(2),"hex",0)); 172 RegistryEntry re = new RegistryEntry(_type,_key,_value); 173 if(type==RegistryEntry.TYPE_ANY || type==re.getType()) array.add(re); 174 //} 175 } 176 else if(line.indexOf(branch)==0 && (type==RegistryEntry.TYPE_ANY || type==RegistryEntry.TYPE_KEY)) { 177 line=ListUtil.trim(line,"\\"); 178 if(branch.length()<line.length()) { 179 array.add(new RegistryEntry(RegistryEntry.TYPE_KEY,ListUtil.last(line,"\\",true),"")); 180 } 181 } 182 } 183 return (RegistryEntry[])array.toArray(new RegistryEntry[array.size()]); 184 } 185 186 187 188 189 190 191 192 193 194 195 196static class StreamReader extends Thread { 197 private InputStream is; 198 private StringWriter sw; 199 200 StreamReader(InputStream is) { 201 this.is = is; 202 sw = new StringWriter(); 203 } 204 205 @Override 206 public void run() { 207 try { 208 int c; 209 while ((c = is.read()) != -1) 210 sw.write(c); 211 } 212 catch (IOException e) { } 213 } 214 215 String getResult() { 216 return sw.toString(); 217 } 218 } 219} 220 221 222