r9754: Upgrading with the command line utility now works, at least partially (-:
[kai/samba.git] / source4 / scripting / libjs / winreg.js
1 /*
2         winreg rpc utility functions 
3         Copyright Andrew Tridgell 2005
4         released under the GNU GPL v2 or later
5 */      
6
7 libinclude("base.js");
8
9 /*
10   close a handle
11 */
12 function __winreg_close(handle)
13 {
14         var io = irpcObj();
15         io.input.handle = handle;
16         this.winreg_CloseKey(io);
17 }
18
19
20 /*
21   open a hive
22 */
23 function __winreg_open_hive(hive)
24 {
25         var io = irpcObj();
26         io.input.system_name = NULL;
27         io.input.access_required = this.SEC_FLAG_MAXIMUM_ALLOWED;
28         var status;
29         if (hive == "HKLM") {
30                 status = this.winreg_OpenHKLM(io);
31         } else if (hive == "HKCR") {
32                 status = this.winreg_OpenHKCR(io);
33         } else if (hive == "HKPD") {
34                 status = this.winreg_OpenHKPD(io);
35         } else if (hive == "HKU") {
36                 status = this.winreg_OpenHKU(io);
37         } else {
38                 this._last_error = "Unknown hive " + hive;
39                 return undefined;
40         }
41         if (!status.is_ok) {
42                 return undefined;
43         }
44         return io.output.handle;
45 }
46
47 /*
48   open a handle to a path
49 */
50 function __winreg_open_path(path)
51 {
52         var s = string_init();
53         var i, components = s.split('\\', path);
54         var list = new Object();
55
56         list.length = 0;
57
58         /* cope with a leading slash */
59         if (components[0] == '') {
60                 for (i=0;i<(components.length-1);i++) {
61                         components[i] = components[i+1];
62                 }
63                 components.length--;
64         }
65         
66         if (components.length == 0) {
67                 return undefined;
68         }
69
70         var handle = this.open_hive(components[0]);
71         if (handle == undefined) {
72                 return undefined;
73         }
74
75         if (components.length == 1) {
76                 return handle;
77         }
78
79         var hpath = components[1];
80
81         for (i=2;i<components.length;i++) {
82                 hpath = hpath + "\\" + components[i];
83         }
84
85         io = irpcObj();
86         io.input.handle  = handle;
87         io.input.keyname = hpath;
88         io.input.unknown = 0;
89         io.input.access_mask = this.SEC_FLAG_MAXIMUM_ALLOWED;
90         var status = this.winreg_OpenKey(io);
91
92         this.close(handle);
93
94         if (!status.is_ok) {
95                 return undefined;
96         }
97         if (io.output.result != "WERR_OK") {
98                 return undefined;
99         }
100         
101         return io.output.handle;
102 }
103
104 /*
105         return a list of keys for a winreg server given a path
106         usage:
107            list = reg.enum_path(path);
108 */
109 function __winreg_enum_path(path)
110 {
111         var list = new Object();
112         list.length = 0;
113
114         if (path == null || path == "\\" || path == "") {
115                 return new Array("HKLM", "HKU");
116         }
117         
118         var handle = this.open_path(path);
119         if (handle == undefined) {
120                 return undefined;
121         }
122
123         var io = irpcObj();
124         io.input.handle            = handle;
125         io.input.name = new Object();
126         io.input.name.length = 0;
127         io.input.name.size   = 32;
128         io.input.name.name   = NULL;
129         io.input.class = new Object();
130         io.input.class.length = 0;
131         io.input.class.size   = 1024;
132         io.input.class.name   = NULL;
133         io.input.last_changed_time = 0;
134
135         var idx = 0;
136         for (idx=0;idx >= 0;idx++) {
137                 io.input.enum_index = idx;
138                 var status = this.winreg_EnumKey(io);
139                 if (!status.is_ok) {
140                         this.close(handle);
141                         return list;
142                 }
143                 var out = io.output;
144                 if (out.result == "WERR_MORE_DATA") {
145                         io.input.name.size = io.input.name.size * 2;
146                         idx--;
147                         if (io.input.name.size > 32000) {
148                                 this.close(handle);
149                                 return list;
150                         }
151                         continue;
152                 }
153                 if (out.result != "WERR_OK") {
154                         this.close(handle);
155                         return list;
156                 }
157                 list[list.length] = out.name.name;
158                 list.length++;
159         }
160
161         this.close(handle);
162         return list;
163 }
164
165
166 /*
167         return a list of values for a winreg server given a path
168         usage:
169            list = reg.enum_values(path);
170
171         each returned list element is an object containing a name, a
172         type and a value
173 */
174 function __winreg_enum_values(path)
175 {
176         var data = datablob_init();
177         var list = new Object();
178         list.length = 0;
179
180         var handle = this.open_path(path);
181         if (handle == undefined) {
182                 return undefined;
183         }
184
185         var io = irpcObj();
186         io.input.handle      = handle;
187         io.input.name        = new Object();
188         io.input.name.length = 0;
189         io.input.name.size   = 128;
190         io.input.name.name   = "";
191         io.input.type        = 0;
192         io.input.value       = new Array(0);
193         io.input.size        = 1024;
194         io.input.length      = 0;
195
196         var idx;
197         for (idx=0;idx >= 0;idx++) {
198                 io.input.enum_index = idx;
199                 var status = this.winreg_EnumValue(io);
200                 if (!status.is_ok) {
201                         this.close(handle);
202                         return list;
203                 }
204                 var out = io.output;
205                 if (out.result == "WERR_MORE_DATA") {
206                         io.input.size = io.input.size * 2;
207                         io.input.name.size = io.input.name.size * 2;
208                         idx--;
209                         /* limit blobs to 1M */
210                         if (io.input.size > 1000000) {
211                                 this.close(handle);
212                                 return list;
213                         }
214                         continue;
215                 }
216                 if (out.result != "WERR_OK") {
217                         this.close(handle);
218                         return list;
219                 }
220                 var el   = new Object();
221                 el.name  = out.name.name;
222                 el.type  = out.type;
223                 el.rawvalue = out.value;
224                 el.value = data.regToVar(el.rawvalue, el.type);
225                 el.size  = out.size;
226                 list[list.length] = el;
227                 list.length++;
228         }
229
230         this.close(handle);
231         return list;
232 }
233
234
235 /*
236   create a new key
237     ok = reg.create_key(path, key);
238 */
239 function __winreg_create_key(path, key)
240 {
241         var handle = this.open_path(path);
242         if (handle == undefined) {
243                 return undefined;
244         }
245
246         var io = irpcObj();
247         io.input.handle = handle;
248         io.input.name = key;
249         io.input.class = NULL;
250         io.input.options = 0;
251         io.input.access_required = this.SEC_FLAG_MAXIMUM_ALLOWED;
252         io.input.secdesc = NULL;
253         io.input.action_taken = 0;      
254
255         var status = this.winreg_CreateKey(io);
256         this.close(handle);
257         if (!status.is_ok) {
258                 return false;
259         }
260         if (io.output.result != "WERR_OK") {
261                 return false;
262         }
263         this.close(io.output.new_handle);
264         return true;
265 }
266
267
268 /*
269   return a string for a winreg type
270 */
271 function __winreg_typestring(type)
272 {
273         return this.typenames[type];
274 }
275
276 /*
277   initialise the winreg lib, returning an object
278 */
279 function winregObj()
280 {
281         var reg = winreg_init();
282         security_init(reg);
283
284         reg.typenames = new Array("REG_NONE", "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", 
285                                   "REG_DWORD", "REG_DWORD_BIG_ENDIAN", "REG_LINK", "REG_MULTI_SZ",
286                                   "REG_RESOURCE_LIST", "REG_FULL_RESOURCE_DESCRIPTOR", 
287                                   "REG_RESOURCE_REQUIREMENTS_LIST", "REG_QWORD");
288
289         reg.close       = __winreg_close;
290         reg.open_hive   = __winreg_open_hive;
291         reg.open_path   = __winreg_open_path;
292         reg.enum_path   = __winreg_enum_path;
293         reg.enum_values = __winreg_enum_values;
294         reg.create_key  = __winreg_create_key;
295         reg.typestring  = __winreg_typestring;
296
297         return reg;
298 }