145 |
145 |
146 /** |
146 /** |
147 * Java wrapper for Windows registry API RegOpenKey() |
147 * Java wrapper for Windows registry API RegOpenKey() |
148 */ |
148 */ |
149 private static native int[] WindowsRegOpenKey(int hKey, byte[] subKey, |
149 private static native int[] WindowsRegOpenKey(int hKey, byte[] subKey, |
150 int securityMask); |
150 int securityMask); |
151 /** |
151 /** |
152 * Retries RegOpenKey() MAX_ATTEMPTS times before giving up. |
152 * Retries RegOpenKey() MAX_ATTEMPTS times before giving up. |
153 */ |
153 */ |
154 private static int[] WindowsRegOpenKey1(int hKey, byte[] subKey, |
154 private static int[] WindowsRegOpenKey1(int hKey, byte[] subKey, |
155 int securityMask) { |
155 int securityMask) { |
156 int[] result = WindowsRegOpenKey(hKey, subKey, securityMask); |
156 int[] result = WindowsRegOpenKey(hKey, subKey, securityMask); |
157 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
157 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
158 return result; |
158 return result; |
159 } else if (result[ERROR_CODE] == ERROR_FILE_NOT_FOUND) { |
159 } else if (result[ERROR_CODE] == ERROR_FILE_NOT_FOUND) { |
160 logger().warning("Trying to recreate Windows registry node " + |
160 logger().warning("Trying to recreate Windows registry node " + |
165 WindowsRegCloseKey(handle); |
165 WindowsRegCloseKey(handle); |
166 return WindowsRegOpenKey(hKey, subKey, securityMask); |
166 return WindowsRegOpenKey(hKey, subKey, securityMask); |
167 } else if (result[ERROR_CODE] != ERROR_ACCESS_DENIED) { |
167 } else if (result[ERROR_CODE] != ERROR_ACCESS_DENIED) { |
168 long sleepTime = INIT_SLEEP_TIME; |
168 long sleepTime = INIT_SLEEP_TIME; |
169 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
169 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
170 try { |
170 try { |
171 Thread.sleep(sleepTime); |
171 Thread.sleep(sleepTime); |
172 } catch(InterruptedException e) { |
172 } catch(InterruptedException e) { |
173 return result; |
173 return result; |
174 } |
174 } |
175 sleepTime *= 2; |
175 sleepTime *= 2; |
176 result = WindowsRegOpenKey(hKey, subKey, securityMask); |
176 result = WindowsRegOpenKey(hKey, subKey, securityMask); |
177 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
177 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
178 return result; |
178 return result; |
179 } |
179 } |
180 } |
180 } |
181 } |
181 } |
182 return result; |
182 return result; |
183 } |
183 } |
184 |
184 |
196 * Retries RegCreateKeyEx() MAX_ATTEMPTS times before giving up. |
196 * Retries RegCreateKeyEx() MAX_ATTEMPTS times before giving up. |
197 */ |
197 */ |
198 private static int[] WindowsRegCreateKeyEx1(int hKey, byte[] subKey) { |
198 private static int[] WindowsRegCreateKeyEx1(int hKey, byte[] subKey) { |
199 int[] result = WindowsRegCreateKeyEx(hKey, subKey); |
199 int[] result = WindowsRegCreateKeyEx(hKey, subKey); |
200 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
200 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
201 return result; |
201 return result; |
202 } else { |
202 } else { |
203 long sleepTime = INIT_SLEEP_TIME; |
203 long sleepTime = INIT_SLEEP_TIME; |
204 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
204 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
205 try { |
205 try { |
206 Thread.sleep(sleepTime); |
206 Thread.sleep(sleepTime); |
207 } catch(InterruptedException e) { |
207 } catch(InterruptedException e) { |
208 return result; |
208 return result; |
209 } |
209 } |
210 sleepTime *= 2; |
210 sleepTime *= 2; |
211 result = WindowsRegCreateKeyEx(hKey, subKey); |
211 result = WindowsRegCreateKeyEx(hKey, subKey); |
212 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
212 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
213 return result; |
213 return result; |
214 } |
214 } |
215 } |
215 } |
216 } |
216 } |
217 return result; |
217 return result; |
218 } |
218 } |
230 * Retries RegFlushKey() MAX_ATTEMPTS times before giving up. |
230 * Retries RegFlushKey() MAX_ATTEMPTS times before giving up. |
231 */ |
231 */ |
232 private static int WindowsRegFlushKey1(int hKey) { |
232 private static int WindowsRegFlushKey1(int hKey) { |
233 int result = WindowsRegFlushKey(hKey); |
233 int result = WindowsRegFlushKey(hKey); |
234 if (result == ERROR_SUCCESS) { |
234 if (result == ERROR_SUCCESS) { |
235 return result; |
235 return result; |
236 } else { |
236 } else { |
237 long sleepTime = INIT_SLEEP_TIME; |
237 long sleepTime = INIT_SLEEP_TIME; |
238 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
238 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
239 try { |
239 try { |
240 Thread.sleep(sleepTime); |
240 Thread.sleep(sleepTime); |
241 } catch(InterruptedException e) { |
241 } catch(InterruptedException e) { |
242 return result; |
242 return result; |
243 } |
243 } |
244 sleepTime *= 2; |
244 sleepTime *= 2; |
245 result = WindowsRegFlushKey(hKey); |
245 result = WindowsRegFlushKey(hKey); |
246 if (result == ERROR_SUCCESS) { |
246 if (result == ERROR_SUCCESS) { |
247 return result; |
247 return result; |
248 } |
248 } |
249 } |
249 } |
250 } |
250 } |
251 return result; |
251 return result; |
252 } |
252 } |
253 |
253 |
254 /** |
254 /** |
255 * Java wrapper for Windows registry API RegQueryValueEx() |
255 * Java wrapper for Windows registry API RegQueryValueEx() |
256 */ |
256 */ |
257 private static native byte[] WindowsRegQueryValueEx(int hKey, |
257 private static native byte[] WindowsRegQueryValueEx(int hKey, |
258 byte[] valueName); |
258 byte[] valueName); |
259 /** |
259 /** |
260 * Java wrapper for Windows registry API RegSetValueEx() |
260 * Java wrapper for Windows registry API RegSetValueEx() |
261 */ |
261 */ |
262 private static native int WindowsRegSetValueEx(int hKey, byte[] valueName, |
262 private static native int WindowsRegSetValueEx(int hKey, byte[] valueName, |
263 byte[] value); |
263 byte[] value); |
264 /** |
264 /** |
265 * Retries RegSetValueEx() MAX_ATTEMPTS times before giving up. |
265 * Retries RegSetValueEx() MAX_ATTEMPTS times before giving up. |
266 */ |
266 */ |
267 private static int WindowsRegSetValueEx1(int hKey, byte[] valueName, |
267 private static int WindowsRegSetValueEx1(int hKey, byte[] valueName, |
268 byte[] value) { |
268 byte[] value) { |
269 int result = WindowsRegSetValueEx(hKey, valueName, value); |
269 int result = WindowsRegSetValueEx(hKey, valueName, value); |
270 if (result == ERROR_SUCCESS) { |
270 if (result == ERROR_SUCCESS) { |
271 return result; |
271 return result; |
272 } else { |
272 } else { |
273 long sleepTime = INIT_SLEEP_TIME; |
273 long sleepTime = INIT_SLEEP_TIME; |
274 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
274 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
275 try { |
275 try { |
276 Thread.sleep(sleepTime); |
276 Thread.sleep(sleepTime); |
277 } catch(InterruptedException e) { |
277 } catch(InterruptedException e) { |
278 return result; |
278 return result; |
279 } |
279 } |
280 sleepTime *= 2; |
280 sleepTime *= 2; |
281 result = WindowsRegSetValueEx(hKey, valueName, value); |
281 result = WindowsRegSetValueEx(hKey, valueName, value); |
282 if (result == ERROR_SUCCESS) { |
282 if (result == ERROR_SUCCESS) { |
283 return result; |
283 return result; |
284 } |
284 } |
285 } |
285 } |
286 } |
286 } |
287 return result; |
287 return result; |
288 } |
288 } |
301 * Retries RegQueryInfoKey() MAX_ATTEMPTS times before giving up. |
301 * Retries RegQueryInfoKey() MAX_ATTEMPTS times before giving up. |
302 */ |
302 */ |
303 private static int[] WindowsRegQueryInfoKey1(int hKey) { |
303 private static int[] WindowsRegQueryInfoKey1(int hKey) { |
304 int[] result = WindowsRegQueryInfoKey(hKey); |
304 int[] result = WindowsRegQueryInfoKey(hKey); |
305 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
305 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
306 return result; |
306 return result; |
307 } else { |
307 } else { |
308 long sleepTime = INIT_SLEEP_TIME; |
308 long sleepTime = INIT_SLEEP_TIME; |
309 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
309 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
310 try { |
310 try { |
311 Thread.sleep(sleepTime); |
311 Thread.sleep(sleepTime); |
312 } catch(InterruptedException e) { |
312 } catch(InterruptedException e) { |
313 return result; |
313 return result; |
314 } |
314 } |
315 sleepTime *= 2; |
315 sleepTime *= 2; |
316 result = WindowsRegQueryInfoKey(hKey); |
316 result = WindowsRegQueryInfoKey(hKey); |
317 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
317 if (result[ERROR_CODE] == ERROR_SUCCESS) { |
318 return result; |
318 return result; |
319 } |
319 } |
320 } |
320 } |
321 } |
321 } |
322 return result; |
322 return result; |
323 } |
323 } |
324 |
324 |
325 /** |
325 /** |
326 * Java wrapper for Windows registry API RegEnumKeyEx() |
326 * Java wrapper for Windows registry API RegEnumKeyEx() |
327 */ |
327 */ |
328 private static native byte[] WindowsRegEnumKeyEx(int hKey, int subKeyIndex, |
328 private static native byte[] WindowsRegEnumKeyEx(int hKey, int subKeyIndex, |
329 int maxKeyLength); |
329 int maxKeyLength); |
330 |
330 |
331 /** |
331 /** |
332 * Retries RegEnumKeyEx() MAX_ATTEMPTS times before giving up. |
332 * Retries RegEnumKeyEx() MAX_ATTEMPTS times before giving up. |
333 */ |
333 */ |
334 private static byte[] WindowsRegEnumKeyEx1(int hKey, int subKeyIndex, |
334 private static byte[] WindowsRegEnumKeyEx1(int hKey, int subKeyIndex, |
335 int maxKeyLength) { |
335 int maxKeyLength) { |
336 byte[] result = WindowsRegEnumKeyEx(hKey, subKeyIndex, maxKeyLength); |
336 byte[] result = WindowsRegEnumKeyEx(hKey, subKeyIndex, maxKeyLength); |
337 if (result != null) { |
337 if (result != null) { |
338 return result; |
338 return result; |
339 } else { |
339 } else { |
340 long sleepTime = INIT_SLEEP_TIME; |
340 long sleepTime = INIT_SLEEP_TIME; |
341 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
341 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
342 try { |
342 try { |
343 Thread.sleep(sleepTime); |
343 Thread.sleep(sleepTime); |
344 } catch(InterruptedException e) { |
344 } catch(InterruptedException e) { |
345 return result; |
345 return result; |
346 } |
346 } |
347 sleepTime *= 2; |
347 sleepTime *= 2; |
348 result = WindowsRegEnumKeyEx(hKey, subKeyIndex, maxKeyLength); |
348 result = WindowsRegEnumKeyEx(hKey, subKeyIndex, maxKeyLength); |
349 if (result != null) { |
349 if (result != null) { |
350 return result; |
350 return result; |
351 } |
351 } |
352 } |
352 } |
353 } |
353 } |
354 return result; |
354 return result; |
355 } |
355 } |
356 |
356 |
357 /** |
357 /** |
358 * Java wrapper for Windows registry API RegEnumValue() |
358 * Java wrapper for Windows registry API RegEnumValue() |
359 */ |
359 */ |
360 private static native byte[] WindowsRegEnumValue(int hKey, int valueIndex, |
360 private static native byte[] WindowsRegEnumValue(int hKey, int valueIndex, |
361 int maxValueNameLength); |
361 int maxValueNameLength); |
362 /** |
362 /** |
363 * Retries RegEnumValueEx() MAX_ATTEMPTS times before giving up. |
363 * Retries RegEnumValueEx() MAX_ATTEMPTS times before giving up. |
364 */ |
364 */ |
365 private static byte[] WindowsRegEnumValue1(int hKey, int valueIndex, |
365 private static byte[] WindowsRegEnumValue1(int hKey, int valueIndex, |
366 int maxValueNameLength) { |
366 int maxValueNameLength) { |
367 byte[] result = WindowsRegEnumValue(hKey, valueIndex, |
367 byte[] result = WindowsRegEnumValue(hKey, valueIndex, |
368 maxValueNameLength); |
368 maxValueNameLength); |
369 if (result != null) { |
369 if (result != null) { |
370 return result; |
370 return result; |
371 } else { |
371 } else { |
372 long sleepTime = INIT_SLEEP_TIME; |
372 long sleepTime = INIT_SLEEP_TIME; |
373 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
373 for (int i = 0; i < MAX_ATTEMPTS; i++) { |
374 try { |
374 try { |
375 Thread.sleep(sleepTime); |
375 Thread.sleep(sleepTime); |
376 } catch(InterruptedException e) { |
376 } catch(InterruptedException e) { |
377 return result; |
377 return result; |
378 } |
378 } |
379 sleepTime *= 2; |
379 sleepTime *= 2; |
380 result = WindowsRegEnumValue(hKey, valueIndex, |
380 result = WindowsRegEnumValue(hKey, valueIndex, |
381 maxValueNameLength); |
381 maxValueNameLength); |
382 if (result != null) { |
382 if (result != null) { |
383 return result; |
383 return result; |
384 } |
384 } |
385 } |
385 } |
386 } |
386 } |
387 return result; |
387 return result; |
388 } |
388 } |
402 return; |
402 return; |
403 } |
403 } |
404 int[] result = |
404 int[] result = |
405 WindowsRegCreateKeyEx1(parentNativeHandle, toWindowsName(name)); |
405 WindowsRegCreateKeyEx1(parentNativeHandle, toWindowsName(name)); |
406 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
406 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
407 logger().warning("Could not create windows registry " |
407 logger().warning("Could not create windows registry node " + |
408 + "node " + byteArrayToString(windowsAbsolutePath()) + |
408 byteArrayToString(windowsAbsolutePath()) + |
409 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
409 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
410 ". Windows RegCreateKeyEx(...) returned error code " + |
410 ". Windows RegCreateKeyEx(...) returned error code " + |
411 result[ERROR_CODE] + "."); |
411 result[ERROR_CODE] + "."); |
412 isBackingStoreAvailable = false; |
412 isBackingStoreAvailable = false; |
413 return; |
413 return; |
414 } |
414 } |
415 newNode = (result[DISPOSITION] == REG_CREATED_NEW_KEY); |
415 newNode = (result[DISPOSITION] == REG_CREATED_NEW_KEY); |
416 closeKey(parentNativeHandle); |
416 closeKey(parentNativeHandle); |
424 * Logs a warning message, if Windows Registry is unavailable. |
424 * Logs a warning message, if Windows Registry is unavailable. |
425 * @param rootNativeHandle Native handle to one of Windows top level keys. |
425 * @param rootNativeHandle Native handle to one of Windows top level keys. |
426 * @param rootDirectory Path to root directory, as a byte-encoded string. |
426 * @param rootDirectory Path to root directory, as a byte-encoded string. |
427 */ |
427 */ |
428 private WindowsPreferences(int rootNativeHandle, byte[] rootDirectory) { |
428 private WindowsPreferences(int rootNativeHandle, byte[] rootDirectory) { |
429 super(null,""); |
429 super(null, ""); |
430 int[] result = |
430 int[] result = |
431 WindowsRegCreateKeyEx1(rootNativeHandle, rootDirectory); |
431 WindowsRegCreateKeyEx1(rootNativeHandle, rootDirectory); |
432 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
432 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
433 logger().warning("Could not open/create prefs root node " + |
433 logger().warning("Could not open/create prefs root node " + |
434 byteArrayToString(windowsAbsolutePath()) + " at root 0x" + |
434 byteArrayToString(windowsAbsolutePath()) + |
435 Integer.toHexString(rootNativeHandle()) + |
435 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
436 ". Windows RegCreateKeyEx(...) returned error code " + |
436 ". Windows RegCreateKeyEx(...) returned error code " + |
437 result[ERROR_CODE] + "."); |
437 result[ERROR_CODE] + "."); |
438 isBackingStoreAvailable = false; |
438 isBackingStoreAvailable = false; |
439 return; |
439 return; |
440 } |
440 } |
441 // Check if a new node |
441 // Check if a new node |
442 newNode = (result[DISPOSITION] == REG_CREATED_NEW_KEY); |
442 newNode = (result[DISPOSITION] == REG_CREATED_NEW_KEY); |
449 * @see Preferences#absolutePath() |
449 * @see Preferences#absolutePath() |
450 */ |
450 */ |
451 private byte[] windowsAbsolutePath() { |
451 private byte[] windowsAbsolutePath() { |
452 ByteArrayOutputStream bstream = new ByteArrayOutputStream(); |
452 ByteArrayOutputStream bstream = new ByteArrayOutputStream(); |
453 bstream.write(WINDOWS_ROOT_PATH, 0, WINDOWS_ROOT_PATH.length-1); |
453 bstream.write(WINDOWS_ROOT_PATH, 0, WINDOWS_ROOT_PATH.length-1); |
454 StringTokenizer tokenizer = new StringTokenizer(absolutePath(),"/"); |
454 StringTokenizer tokenizer = new StringTokenizer(absolutePath(), "/"); |
455 while (tokenizer.hasMoreTokens()) { |
455 while (tokenizer.hasMoreTokens()) { |
456 bstream.write((byte)'\\'); |
456 bstream.write((byte)'\\'); |
457 String nextName = tokenizer.nextToken(); |
457 String nextName = tokenizer.nextToken(); |
458 byte[] windowsNextName = toWindowsName(nextName); |
458 byte[] windowsNextName = toWindowsName(nextName); |
459 bstream.write(windowsNextName, 0, windowsNextName.length-1); |
459 bstream.write(windowsNextName, 0, windowsNextName.length-1); |
503 */ |
503 */ |
504 private int openKey(byte[] windowsAbsolutePath, int mask1, int mask2) { |
504 private int openKey(byte[] windowsAbsolutePath, int mask1, int mask2) { |
505 /* Check if key's path is short enough be opened at once |
505 /* Check if key's path is short enough be opened at once |
506 otherwise use a path-splitting procedure */ |
506 otherwise use a path-splitting procedure */ |
507 if (windowsAbsolutePath.length <= MAX_WINDOWS_PATH_LENGTH + 1) { |
507 if (windowsAbsolutePath.length <= MAX_WINDOWS_PATH_LENGTH + 1) { |
508 int[] result = WindowsRegOpenKey1(rootNativeHandle(), |
508 int[] result = WindowsRegOpenKey1(rootNativeHandle(), |
509 windowsAbsolutePath, mask1); |
509 windowsAbsolutePath, mask1); |
510 if (result[ERROR_CODE] == ERROR_ACCESS_DENIED && mask2 != mask1) |
510 if (result[ERROR_CODE] == ERROR_ACCESS_DENIED && mask2 != mask1) |
511 result = WindowsRegOpenKey1(rootNativeHandle(), |
511 result = WindowsRegOpenKey1(rootNativeHandle(), |
512 windowsAbsolutePath, mask2); |
512 windowsAbsolutePath, mask2); |
513 |
513 |
514 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
514 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
515 logger().warning("Could not open windows " |
515 logger().warning("Could not open windows registry node " + |
516 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
516 byteArrayToString(windowsAbsolutePath()) + |
517 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
517 " at root 0x" + |
518 ". Windows RegOpenKey(...) returned error code " + |
518 Integer.toHexString(rootNativeHandle()) + |
519 result[ERROR_CODE] + "."); |
519 ". Windows RegOpenKey(...) returned error code " + |
|
520 result[ERROR_CODE] + "."); |
520 result[NATIVE_HANDLE] = NULL_NATIVE_HANDLE; |
521 result[NATIVE_HANDLE] = NULL_NATIVE_HANDLE; |
521 if (result[ERROR_CODE] == ERROR_ACCESS_DENIED) { |
522 if (result[ERROR_CODE] == ERROR_ACCESS_DENIED) { |
522 throw new SecurityException("Could not open windows " |
523 throw new SecurityException( |
523 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
524 "Could not open windows registry node " + |
524 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
525 byteArrayToString(windowsAbsolutePath()) + |
525 ": Access denied"); |
526 " at root 0x" + |
526 } |
527 Integer.toHexString(rootNativeHandle()) + |
527 } |
528 ": Access denied"); |
528 return result[NATIVE_HANDLE]; |
529 } |
|
530 } |
|
531 return result[NATIVE_HANDLE]; |
529 } else { |
532 } else { |
530 return openKey(rootNativeHandle(), windowsAbsolutePath, mask1, mask2); |
533 return openKey(rootNativeHandle(), windowsAbsolutePath, mask1, mask2); |
531 } |
534 } |
532 } |
535 } |
533 |
536 |
546 */ |
549 */ |
547 private int openKey(int nativeHandle, byte[] windowsRelativePath, |
550 private int openKey(int nativeHandle, byte[] windowsRelativePath, |
548 int mask1, int mask2) { |
551 int mask1, int mask2) { |
549 /* If the path is short enough open at once. Otherwise split the path */ |
552 /* If the path is short enough open at once. Otherwise split the path */ |
550 if (windowsRelativePath.length <= MAX_WINDOWS_PATH_LENGTH + 1 ) { |
553 if (windowsRelativePath.length <= MAX_WINDOWS_PATH_LENGTH + 1 ) { |
551 int[] result = WindowsRegOpenKey1(nativeHandle, |
554 int[] result = WindowsRegOpenKey1(nativeHandle, |
552 windowsRelativePath, mask1); |
555 windowsRelativePath, mask1); |
553 if (result[ERROR_CODE] == ERROR_ACCESS_DENIED && mask2 != mask1) |
556 if (result[ERROR_CODE] == ERROR_ACCESS_DENIED && mask2 != mask1) |
554 result = WindowsRegOpenKey1(nativeHandle, |
557 result = WindowsRegOpenKey1(nativeHandle, |
555 windowsRelativePath, mask2); |
558 windowsRelativePath, mask2); |
556 |
559 |
557 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
560 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
558 logger().warning("Could not open windows " |
561 logger().warning("Could not open windows registry node " + |
559 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
562 byteArrayToString(windowsAbsolutePath()) + |
560 " at root 0x" + Integer.toHexString(nativeHandle) + |
563 " at root 0x" + Integer.toHexString(nativeHandle) + |
561 ". Windows RegOpenKey(...) returned error code " + |
564 ". Windows RegOpenKey(...) returned error code " + |
562 result[ERROR_CODE] + "."); |
565 result[ERROR_CODE] + "."); |
563 result[NATIVE_HANDLE] = NULL_NATIVE_HANDLE; |
566 result[NATIVE_HANDLE] = NULL_NATIVE_HANDLE; |
564 } |
567 } |
565 return result[NATIVE_HANDLE]; |
568 return result[NATIVE_HANDLE]; |
566 } else { |
569 } else { |
567 int separatorPosition = -1; |
570 int separatorPosition = -1; |
568 // Be greedy - open the longest possible path |
571 // Be greedy - open the longest possible path |
569 for (int i = MAX_WINDOWS_PATH_LENGTH; i > 0; i--) { |
572 for (int i = MAX_WINDOWS_PATH_LENGTH; i > 0; i--) { |
570 if (windowsRelativePath[i] == ((byte)'\\')) { |
573 if (windowsRelativePath[i] == ((byte)'\\')) { |
602 * @see #openKey(int, byte[],int) |
605 * @see #openKey(int, byte[],int) |
603 */ |
606 */ |
604 private void closeKey(int nativeHandle) { |
607 private void closeKey(int nativeHandle) { |
605 int result = WindowsRegCloseKey(nativeHandle); |
608 int result = WindowsRegCloseKey(nativeHandle); |
606 if (result != ERROR_SUCCESS) { |
609 if (result != ERROR_SUCCESS) { |
607 logger().warning("Could not close windows " |
610 logger().warning("Could not close windows registry node " + |
608 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
611 byteArrayToString(windowsAbsolutePath()) + |
609 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
612 " at root 0x" + |
610 ". Windows RegCloseKey(...) returned error code " + result + "."); |
613 Integer.toHexString(rootNativeHandle()) + |
|
614 ". Windows RegCloseKey(...) returned error code " + |
|
615 result + "."); |
611 } |
616 } |
612 } |
617 } |
613 |
618 |
614 /** |
619 /** |
615 * Implements <tt>AbstractPreferences</tt> <tt>putSpi()</tt> method. |
620 * Implements <tt>AbstractPreferences</tt> <tt>putSpi()</tt> method. |
625 } |
630 } |
626 int result = WindowsRegSetValueEx1(nativeHandle, |
631 int result = WindowsRegSetValueEx1(nativeHandle, |
627 toWindowsName(javaName), toWindowsValueString(value)); |
632 toWindowsName(javaName), toWindowsValueString(value)); |
628 if (result != ERROR_SUCCESS) { |
633 if (result != ERROR_SUCCESS) { |
629 logger().warning("Could not assign value to key " + |
634 logger().warning("Could not assign value to key " + |
630 byteArrayToString(toWindowsName(javaName))+ " at Windows registry node " |
635 byteArrayToString(toWindowsName(javaName)) + |
631 + byteArrayToString(windowsAbsolutePath()) + " at root 0x" |
636 " at Windows registry node " + |
632 + Integer.toHexString(rootNativeHandle()) + |
637 byteArrayToString(windowsAbsolutePath()) + |
633 ". Windows RegSetValueEx(...) returned error code " + result + "."); |
638 " at root 0x" + |
|
639 Integer.toHexString(rootNativeHandle()) + |
|
640 ". Windows RegSetValueEx(...) returned error code " + |
|
641 result + "."); |
634 isBackingStoreAvailable = false; |
642 isBackingStoreAvailable = false; |
635 } |
643 } |
636 closeKey(nativeHandle); |
644 closeKey(nativeHandle); |
637 } |
645 } |
638 |
646 |
670 return; |
678 return; |
671 } |
679 } |
672 int result = |
680 int result = |
673 WindowsRegDeleteValue(nativeHandle, toWindowsName(key)); |
681 WindowsRegDeleteValue(nativeHandle, toWindowsName(key)); |
674 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { |
682 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { |
675 logger().warning("Could not delete windows registry " |
683 logger().warning("Could not delete windows registry value " + |
676 + "value " + byteArrayToString(windowsAbsolutePath())+ "\\" + |
684 byteArrayToString(windowsAbsolutePath()) + "\\" + |
677 toWindowsName(key) + " at root 0x" + |
685 toWindowsName(key) + " at root 0x" + |
678 Integer.toHexString(rootNativeHandle()) + |
686 Integer.toHexString(rootNativeHandle()) + |
679 ". Windows RegDeleteValue(...) returned error code " + |
687 ". Windows RegDeleteValue(...) returned error code " + |
680 result + "."); |
688 result + "."); |
681 isBackingStoreAvailable = false; |
689 isBackingStoreAvailable = false; |
682 } |
690 } |
683 closeKey(nativeHandle); |
691 closeKey(nativeHandle); |
684 } |
692 } |
685 |
693 |
691 */ |
699 */ |
692 protected String[] keysSpi() throws BackingStoreException{ |
700 protected String[] keysSpi() throws BackingStoreException{ |
693 // Find out the number of values |
701 // Find out the number of values |
694 int nativeHandle = openKey(KEY_QUERY_VALUE); |
702 int nativeHandle = openKey(KEY_QUERY_VALUE); |
695 if (nativeHandle == NULL_NATIVE_HANDLE) { |
703 if (nativeHandle == NULL_NATIVE_HANDLE) { |
696 throw new BackingStoreException("Could not open windows" |
704 throw new BackingStoreException( |
697 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
705 "Could not open windows registry node " + |
698 " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); |
706 byteArrayToString(windowsAbsolutePath()) + |
|
707 " at root 0x" + |
|
708 Integer.toHexString(rootNativeHandle()) + "."); |
699 } |
709 } |
700 int[] result = WindowsRegQueryInfoKey1(nativeHandle); |
710 int[] result = WindowsRegQueryInfoKey1(nativeHandle); |
701 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
711 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
702 String info = "Could not query windows" |
712 String info = "Could not query windows registry node " + |
703 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
713 byteArrayToString(windowsAbsolutePath()) + |
704 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
714 " at root 0x" + |
705 ". Windows RegQueryInfoKeyEx(...) returned error code " + |
715 Integer.toHexString(rootNativeHandle()) + |
706 result[ERROR_CODE] + "."; |
716 ". Windows RegQueryInfoKeyEx(...) returned error code " + |
|
717 result[ERROR_CODE] + "."; |
707 logger().warning(info); |
718 logger().warning(info); |
708 throw new BackingStoreException(info); |
719 throw new BackingStoreException(info); |
709 } |
720 } |
710 int maxValueNameLength = result[MAX_VALUE_NAME_LENGTH]; |
721 int maxValueNameLength = result[MAX_VALUE_NAME_LENGTH]; |
711 int valuesNumber = result[VALUES_NUMBER]; |
722 int valuesNumber = result[VALUES_NUMBER]; |
712 if (valuesNumber == 0) { |
723 if (valuesNumber == 0) { |
713 closeKey(nativeHandle); |
724 closeKey(nativeHandle); |
714 return new String[0]; |
725 return new String[0]; |
715 } |
726 } |
716 // Get the values |
727 // Get the values |
717 String[] valueNames = new String[valuesNumber]; |
728 String[] valueNames = new String[valuesNumber]; |
718 for (int i = 0; i < valuesNumber; i++) { |
729 for (int i = 0; i < valuesNumber; i++) { |
719 byte[] windowsName = WindowsRegEnumValue1(nativeHandle, i, |
730 byte[] windowsName = WindowsRegEnumValue1(nativeHandle, i, |
720 maxValueNameLength+1); |
731 maxValueNameLength+1); |
721 if (windowsName == null) { |
732 if (windowsName == null) { |
722 String info = |
733 String info = |
723 "Could not enumerate value #" + i + " of windows node " + |
734 "Could not enumerate value #" + i + " of windows node " + |
724 byteArrayToString(windowsAbsolutePath()) + " at root 0x" + |
735 byteArrayToString(windowsAbsolutePath()) + " at root 0x" + |
725 Integer.toHexString(rootNativeHandle()) + "."; |
736 Integer.toHexString(rootNativeHandle()) + "."; |
726 logger().warning(info); |
737 logger().warning(info); |
727 throw new BackingStoreException(info); |
738 throw new BackingStoreException(info); |
728 } |
739 } |
729 valueNames[i] = toJavaName(windowsName); |
740 valueNames[i] = toJavaName(windowsName); |
730 } |
741 } |
738 * Throws a BackingStoreException and logs a warning message, |
749 * Throws a BackingStoreException and logs a warning message, |
739 * if Windows registry is not available. |
750 * if Windows registry is not available. |
740 */ |
751 */ |
741 protected String[] childrenNamesSpi() throws BackingStoreException { |
752 protected String[] childrenNamesSpi() throws BackingStoreException { |
742 // Open key |
753 // Open key |
743 int nativeHandle = openKey(KEY_ENUMERATE_SUB_KEYS| KEY_QUERY_VALUE); |
754 int nativeHandle = openKey(KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE); |
744 if (nativeHandle == NULL_NATIVE_HANDLE) { |
755 if (nativeHandle == NULL_NATIVE_HANDLE) { |
745 throw new BackingStoreException("Could not open windows" |
756 throw new BackingStoreException( |
746 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
757 "Could not open windows registry node " + |
747 " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); |
758 byteArrayToString(windowsAbsolutePath()) + |
|
759 " at root 0x" + |
|
760 Integer.toHexString(rootNativeHandle()) + "."); |
748 } |
761 } |
749 // Get number of children |
762 // Get number of children |
750 int[] result = WindowsRegQueryInfoKey1(nativeHandle); |
763 int[] result = WindowsRegQueryInfoKey1(nativeHandle); |
751 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
764 if (result[ERROR_CODE] != ERROR_SUCCESS) { |
752 String info = "Could not query windows" |
765 String info = "Could not query windows registry node " + |
753 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
766 byteArrayToString(windowsAbsolutePath()) + |
754 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
767 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
755 ". Windows RegQueryInfoKeyEx(...) returned error code " + |
768 ". Windows RegQueryInfoKeyEx(...) returned error code " + |
756 result[ERROR_CODE] + "."; |
769 result[ERROR_CODE] + "."; |
757 logger().warning(info); |
770 logger().warning(info); |
758 throw new BackingStoreException(info); |
771 throw new BackingStoreException(info); |
759 } |
772 } |
760 int maxKeyLength = result[MAX_KEY_LENGTH]; |
773 int maxKeyLength = result[MAX_KEY_LENGTH]; |
761 int subKeysNumber = result[SUBKEYS_NUMBER]; |
774 int subKeysNumber = result[SUBKEYS_NUMBER]; |
766 String[] subkeys = new String[subKeysNumber]; |
779 String[] subkeys = new String[subKeysNumber]; |
767 String[] children = new String[subKeysNumber]; |
780 String[] children = new String[subKeysNumber]; |
768 // Get children |
781 // Get children |
769 for (int i = 0; i < subKeysNumber; i++) { |
782 for (int i = 0; i < subKeysNumber; i++) { |
770 byte[] windowsName = WindowsRegEnumKeyEx1(nativeHandle, i, |
783 byte[] windowsName = WindowsRegEnumKeyEx1(nativeHandle, i, |
771 maxKeyLength+1); |
784 maxKeyLength+1); |
772 if (windowsName == null) { |
785 if (windowsName == null) { |
773 String info = |
786 String info = |
774 "Could not enumerate key #" + i + " of windows node " + |
787 "Could not enumerate key #" + i + " of windows node " + |
775 byteArrayToString(windowsAbsolutePath()) + " at root 0x" + |
788 byteArrayToString(windowsAbsolutePath()) + " at root 0x" + |
776 Integer.toHexString(rootNativeHandle()) + ". "; |
789 Integer.toHexString(rootNativeHandle()) + ". "; |
777 logger().warning(info); |
790 logger().warning(info); |
778 throw new BackingStoreException(info); |
791 throw new BackingStoreException(info); |
779 } |
792 } |
780 String javaName = toJavaName(windowsName); |
793 String javaName = toJavaName(windowsName); |
781 children[i] = javaName; |
794 children[i] = javaName; |
796 parent.flush(); |
809 parent.flush(); |
797 return; |
810 return; |
798 } |
811 } |
799 if (!isBackingStoreAvailable) { |
812 if (!isBackingStoreAvailable) { |
800 throw new BackingStoreException( |
813 throw new BackingStoreException( |
801 "flush(): Backing store not available."); |
814 "flush(): Backing store not available."); |
802 } |
815 } |
803 int nativeHandle = openKey(KEY_READ); |
816 int nativeHandle = openKey(KEY_READ); |
804 if (nativeHandle == NULL_NATIVE_HANDLE) { |
817 if (nativeHandle == NULL_NATIVE_HANDLE) { |
805 throw new BackingStoreException("Could not open windows" |
818 throw new BackingStoreException( |
806 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
819 "Could not open windows registry node " + |
807 " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); |
820 byteArrayToString(windowsAbsolutePath()) + |
|
821 " at root 0x" + |
|
822 Integer.toHexString(rootNativeHandle()) + "."); |
808 } |
823 } |
809 int result = WindowsRegFlushKey1(nativeHandle); |
824 int result = WindowsRegFlushKey1(nativeHandle); |
810 if (result != ERROR_SUCCESS) { |
825 if (result != ERROR_SUCCESS) { |
811 String info = "Could not flush windows " |
826 String info = "Could not flush windows registry node " + |
812 + "registry node " + byteArrayToString(windowsAbsolutePath()) |
827 byteArrayToString(windowsAbsolutePath()) + |
813 + " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
828 " at root 0x" + |
814 ". Windows RegFlushKey(...) returned error code " + result + "."; |
829 Integer.toHexString(rootNativeHandle()) + |
|
830 ". Windows RegFlushKey(...) returned error code " + |
|
831 result + "."; |
815 logger().warning(info); |
832 logger().warning(info); |
816 throw new BackingStoreException(info); |
833 throw new BackingStoreException(info); |
817 } |
834 } |
818 closeKey(nativeHandle); |
835 closeKey(nativeHandle); |
819 } |
836 } |
836 * given name and creates its underlying Windows registry node, |
853 * given name and creates its underlying Windows registry node, |
837 * if it does not exist. |
854 * if it does not exist. |
838 * Logs a warning message, if Windows Registry is unavailable. |
855 * Logs a warning message, if Windows Registry is unavailable. |
839 */ |
856 */ |
840 protected AbstractPreferences childSpi(String name) { |
857 protected AbstractPreferences childSpi(String name) { |
841 return new WindowsPreferences(this, name); |
858 return new WindowsPreferences(this, name); |
842 } |
859 } |
843 |
860 |
844 /** |
861 /** |
845 * Implements <tt>AbstractPreferences</tt> <tt>removeNodeSpi()</tt> method. |
862 * Implements <tt>AbstractPreferences</tt> <tt>removeNodeSpi()</tt> method. |
846 * Deletes underlying Windows registry node. |
863 * Deletes underlying Windows registry node. |
847 * Throws a BackingStoreException and logs a warning, if Windows registry |
864 * Throws a BackingStoreException and logs a warning, if Windows registry |
848 * is not available. |
865 * is not available. |
849 */ |
866 */ |
850 public void removeNodeSpi() throws BackingStoreException { |
867 public void removeNodeSpi() throws BackingStoreException { |
851 int parentNativeHandle = |
868 int parentNativeHandle = |
852 ((WindowsPreferences)parent()).openKey(DELETE); |
869 ((WindowsPreferences)parent()).openKey(DELETE); |
853 if (parentNativeHandle == NULL_NATIVE_HANDLE) { |
870 if (parentNativeHandle == NULL_NATIVE_HANDLE) { |
854 throw new BackingStoreException("Could not open parent windows" |
871 throw new BackingStoreException( |
855 + "registry node of " + byteArrayToString(windowsAbsolutePath()) + |
872 "Could not open parent windows registry node of " + |
856 " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); |
873 byteArrayToString(windowsAbsolutePath()) + |
|
874 " at root 0x" + |
|
875 Integer.toHexString(rootNativeHandle()) + "."); |
857 } |
876 } |
858 int result = |
877 int result = |
859 WindowsRegDeleteKey(parentNativeHandle, toWindowsName(name())); |
878 WindowsRegDeleteKey(parentNativeHandle, toWindowsName(name())); |
860 if (result != ERROR_SUCCESS) { |
879 if (result != ERROR_SUCCESS) { |
861 String info = "Could not delete windows " |
880 String info = "Could not delete windows registry node " + |
862 + "registry node " + byteArrayToString(windowsAbsolutePath()) + |
881 byteArrayToString(windowsAbsolutePath()) + |
863 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
882 " at root 0x" + Integer.toHexString(rootNativeHandle()) + |
864 ". Windows RegDeleteKeyEx(...) returned error code " + |
883 ". Windows RegDeleteKeyEx(...) returned error code " + |
865 result + "."; |
884 result + "."; |
866 logger().warning(info); |
885 logger().warning(info); |
867 throw new BackingStoreException(info); |
886 throw new BackingStoreException(info); |
868 } |
887 } |
869 closeKey(parentNativeHandle); |
888 closeKey(parentNativeHandle); |
870 } |
889 } |
877 * @param windowsNameArray Null-terminated byte array. |
896 * @param windowsNameArray Null-terminated byte array. |
878 */ |
897 */ |
879 private static String toJavaName(byte[] windowsNameArray) { |
898 private static String toJavaName(byte[] windowsNameArray) { |
880 String windowsName = byteArrayToString(windowsNameArray); |
899 String windowsName = byteArrayToString(windowsNameArray); |
881 // check if Alt64 |
900 // check if Alt64 |
882 if ((windowsName.length()>1) && |
901 if ((windowsName.length() > 1) && |
883 (windowsName.substring(0,2).equals("/!"))) { |
902 (windowsName.substring(0, 2).equals("/!"))) { |
884 return toJavaAlt64Name(windowsName); |
903 return toJavaAlt64Name(windowsName); |
885 } |
904 } |
886 StringBuffer javaName = new StringBuffer(); |
905 StringBuilder javaName = new StringBuilder(); |
887 char ch; |
906 char ch; |
888 // Decode from simple encoding |
907 // Decode from simple encoding |
889 for (int i = 0; i < windowsName.length(); i++){ |
908 for (int i = 0; i < windowsName.length(); i++) { |
890 if ((ch = windowsName.charAt(i)) == '/') { |
909 if ((ch = windowsName.charAt(i)) == '/') { |
891 char next = ' '; |
910 char next = ' '; |
892 if ((windowsName.length() > i + 1) && |
911 if ((windowsName.length() > i + 1) && |
893 ((next = windowsName.charAt(i+1)) >= 'A') && (next <= 'Z')) { |
912 ((next = windowsName.charAt(i+1)) >= 'A') && |
894 ch = next; |
913 (next <= 'Z')) { |
895 i++; |
914 ch = next; |
896 } else if ((windowsName.length() > i + 1) && (next == '/')) { |
915 i++; |
897 ch = '\\'; |
916 } else if ((windowsName.length() > i + 1) && |
898 i++; |
917 (next == '/')) { |
|
918 ch = '\\'; |
|
919 i++; |
899 } |
920 } |
900 } else if (ch == '\\') { |
921 } else if (ch == '\\') { |
901 ch = '/'; |
922 ch = '/'; |
902 } |
923 } |
903 javaName.append(ch); |
924 javaName.append(ch); |
943 * Windows string to '/!'. The java name is then encoded using |
964 * Windows string to '/!'. The java name is then encoded using |
944 * byteArrayToAltBase64() method from |
965 * byteArrayToAltBase64() method from |
945 * Base64 class. |
966 * Base64 class. |
946 */ |
967 */ |
947 private static byte[] toWindowsName(String javaName) { |
968 private static byte[] toWindowsName(String javaName) { |
948 StringBuffer windowsName = new StringBuffer(); |
969 StringBuilder windowsName = new StringBuilder(); |
949 for (int i = 0; i < javaName.length(); i++) { |
970 for (int i = 0; i < javaName.length(); i++) { |
950 char ch =javaName.charAt(i); |
971 char ch = javaName.charAt(i); |
951 if ((ch < 0x0020)||(ch > 0x007f)) { |
972 if ((ch < 0x0020) || (ch > 0x007f)) { |
952 // If a non-trivial character encountered, use altBase64 |
973 // If a non-trivial character encountered, use altBase64 |
953 return toWindowsAlt64Name(javaName); |
974 return toWindowsAlt64Name(javaName); |
954 } |
975 } |
955 if (ch == '\\') { |
976 if (ch == '\\') { |
956 windowsName.append("//"); |
977 windowsName.append("//"); |
957 } else if (ch == '/') { |
978 } else if (ch == '/') { |
958 windowsName.append('\\'); |
979 windowsName.append('\\'); |
959 } else if ((ch >= 'A') && (ch <='Z')) { |
980 } else if ((ch >= 'A') && (ch <='Z')) { |
960 windowsName.append("/" + ch); |
981 windowsName.append('/').append(ch); |
961 } else { |
982 } else { |
962 windowsName.append(ch); |
983 windowsName.append(ch); |
963 } |
984 } |
964 } |
985 } |
965 return stringToByteArray(windowsName.toString()); |
986 return stringToByteArray(windowsName.toString()); |
974 private static byte[] toWindowsAlt64Name(String javaName) { |
995 private static byte[] toWindowsAlt64Name(String javaName) { |
975 byte[] javaNameArray = new byte[2*javaName.length()]; |
996 byte[] javaNameArray = new byte[2*javaName.length()]; |
976 // Convert to byte pairs |
997 // Convert to byte pairs |
977 int counter = 0; |
998 int counter = 0; |
978 for (int i = 0; i < javaName.length();i++) { |
999 for (int i = 0; i < javaName.length();i++) { |
979 int ch = javaName.charAt(i); |
1000 int ch = javaName.charAt(i); |
980 javaNameArray[counter++] = (byte)(ch >>> 8); |
1001 javaNameArray[counter++] = (byte)(ch >>> 8); |
981 javaNameArray[counter++] = (byte)ch; |
1002 javaNameArray[counter++] = (byte)ch; |
982 } |
1003 } |
983 |
1004 |
984 return stringToByteArray( |
1005 return stringToByteArray("/!" + |
985 "/!" + Base64.byteArrayToAltBase64(javaNameArray)); |
1006 Base64.byteArrayToAltBase64(javaNameArray)); |
986 } |
1007 } |
987 |
1008 |
988 /** |
1009 /** |
989 * Converts value string from its Windows representation |
1010 * Converts value string from its Windows representation |
990 * to java string. See |
1011 * to java string. See |
992 * description of the encoding algorithm. |
1013 * description of the encoding algorithm. |
993 */ |
1014 */ |
994 private static String toJavaValueString(byte[] windowsNameArray) { |
1015 private static String toJavaValueString(byte[] windowsNameArray) { |
995 // Use modified native2ascii algorithm |
1016 // Use modified native2ascii algorithm |
996 String windowsName = byteArrayToString(windowsNameArray); |
1017 String windowsName = byteArrayToString(windowsNameArray); |
997 StringBuffer javaName = new StringBuffer(); |
1018 StringBuilder javaName = new StringBuilder(); |
998 char ch; |
1019 char ch; |
999 for (int i = 0; i < windowsName.length(); i++){ |
1020 for (int i = 0; i < windowsName.length(); i++){ |
1000 if ((ch = windowsName.charAt(i)) == '/') { |
1021 if ((ch = windowsName.charAt(i)) == '/') { |
1001 char next = ' '; |
1022 char next = ' '; |
1002 |
1023 |
1003 if (windowsName.length() > i + 1 && |
1024 if (windowsName.length() > i + 1 && |
1004 (next = windowsName.charAt(i + 1)) == 'u') { |
1025 (next = windowsName.charAt(i + 1)) == 'u') { |
1005 if (windowsName.length() < i + 6){ |
1026 if (windowsName.length() < i + 6) { |
1006 break; |
1027 break; |
1007 } else { |
1028 } else { |
1008 ch = (char)Integer.parseInt |
1029 ch = (char)Integer.parseInt( |
1009 (windowsName.substring(i + 2, i + 6), 16); |
1030 windowsName.substring(i + 2, i + 6), 16); |
1010 i += 5; |
1031 i += 5; |
1011 } |
1032 } |
1012 } else |
1033 } else |
1013 if ((windowsName.length() > i + 1) && |
1034 if ((windowsName.length() > i + 1) && |
1014 ((windowsName.charAt(i+1)) >= 'A') && (next <= 'Z')) { |
1035 ((windowsName.charAt(i+1)) >= 'A') && |
1015 ch = next; |
1036 (next <= 'Z')) { |
1016 i++; |
1037 ch = next; |
1017 } else if ((windowsName.length() > i + 1) && |
1038 i++; |
1018 (next == '/')) { |
1039 } else if ((windowsName.length() > i + 1) && |
1019 ch = '\\'; |
1040 (next == '/')) { |
1020 i++; |
1041 ch = '\\'; |
|
1042 i++; |
1021 } |
1043 } |
1022 } else if (ch == '\\') { |
1044 } else if (ch == '\\') { |
1023 ch = '/'; |
1045 ch = '/'; |
1024 } |
1046 } |
1025 javaName.append(ch); |
1047 javaName.append(ch); |
1035 * '/' is encoded as '\'. |
1057 * '/' is encoded as '\'. |
1036 * Then encoding scheme similar to jdk's native2ascii converter is used |
1058 * Then encoding scheme similar to jdk's native2ascii converter is used |
1037 * to convert java string to a byte array of ASCII characters. |
1059 * to convert java string to a byte array of ASCII characters. |
1038 */ |
1060 */ |
1039 private static byte[] toWindowsValueString(String javaName) { |
1061 private static byte[] toWindowsValueString(String javaName) { |
1040 StringBuffer windowsName = new StringBuffer(); |
1062 StringBuilder windowsName = new StringBuilder(); |
1041 for (int i = 0; i < javaName.length(); i++) { |
1063 for (int i = 0; i < javaName.length(); i++) { |
1042 char ch =javaName.charAt(i); |
1064 char ch = javaName.charAt(i); |
1043 if ((ch < 0x0020)||(ch > 0x007f)){ |
1065 if ((ch < 0x0020) || (ch > 0x007f)){ |
1044 // write \udddd |
1066 // write \udddd |
1045 windowsName.append("/u"); |
1067 windowsName.append("/u"); |
1046 String hex = Integer.toHexString(javaName.charAt(i)); |
1068 String hex = Integer.toHexString(javaName.charAt(i)); |
1047 StringBuffer hex4 = new StringBuffer(hex); |
1069 StringBuilder hex4 = new StringBuilder(hex); |
1048 hex4.reverse(); |
1070 hex4.reverse(); |
1049 int len = 4 - hex4.length(); |
1071 int len = 4 - hex4.length(); |
1050 for (int j = 0; j < len; j++){ |
1072 for (int j = 0; j < len; j++){ |
1051 hex4.append('0'); |
1073 hex4.append('0'); |
1052 } |
1074 } |