1 7 8 package java.util.prefs; 9 10 import java.util.Map ; 11 import java.util.TreeMap ; 12 import java.util.StringTokenizer ; 13 import java.io.ByteArrayOutputStream ; 14 import java.util.logging.Logger ; 15 16 28 29 class WindowsPreferences extends AbstractPreferences { 30 31 34 private static Logger logger; 35 36 39 private static final byte[] WINDOWS_ROOT_PATH 40 = stringToByteArray("Software\\JavaSoft\\Prefs"); 41 42 46 private static final int HKEY_CURRENT_USER = 0x80000001; 47 private static final int HKEY_LOCAL_MACHINE = 0x80000002; 48 49 52 private static final int USER_ROOT_NATIVE_HANDLE = HKEY_CURRENT_USER; 53 54 57 private static final int SYSTEM_ROOT_NATIVE_HANDLE = HKEY_LOCAL_MACHINE; 58 59 63 private static final int MAX_WINDOWS_PATH_LENGTH = 256; 64 65 68 static final Preferences userRoot = 69 new WindowsPreferences (USER_ROOT_NATIVE_HANDLE, WINDOWS_ROOT_PATH); 70 71 74 static final Preferences systemRoot = 75 new WindowsPreferences (SYSTEM_ROOT_NATIVE_HANDLE, WINDOWS_ROOT_PATH); 76 77 78 private static final int ERROR_SUCCESS = 0; 79 private static final int ERROR_FILE_NOT_FOUND = 2; 80 private static final int ERROR_ACCESS_DENIED = 5; 81 82 83 private static final int NATIVE_HANDLE = 0; 84 private static final int ERROR_CODE = 1; 85 private static final int SUBKEYS_NUMBER = 0; 86 private static final int VALUES_NUMBER = 2; 87 private static final int MAX_KEY_LENGTH = 3; 88 private static final int MAX_VALUE_NAME_LENGTH = 4; 89 private static final int DISPOSITION = 2; 90 private static final int REG_CREATED_NEW_KEY = 1; 91 private static final int REG_OPENED_EXISTING_KEY = 2; 92 private static final int NULL_NATIVE_HANDLE = 0; 93 94 95 private static final int DELETE = 0x10000; 96 private static final int KEY_QUERY_VALUE = 1; 97 private static final int KEY_SET_VALUE = 2; 98 private static final int KEY_CREATE_SUB_KEY = 4; 99 private static final int KEY_ENUMERATE_SUB_KEYS = 8; 100 private static final int KEY_READ = 0x20019; 101 private static final int KEY_WRITE = 0x20006; 102 private static final int KEY_ALL_ACCESS = 0xf003f; 103 104 108 private static int INIT_SLEEP_TIME = 50; 109 110 113 private static int MAX_ATTEMPTS = 5; 114 115 118 private boolean isBackingStoreAvailable = true; 119 120 123 private static native int[] WindowsRegOpenKey(int hKey, byte[] subKey, 124 int securityMask); 125 128 private static int[] WindowsRegOpenKey1(int hKey, byte[] subKey, 129 int securityMask) { 130 int[] result = WindowsRegOpenKey(hKey, subKey, securityMask); 131 if (result[ERROR_CODE] == ERROR_SUCCESS) { 132 return result; 133 } else if (result[ERROR_CODE] == ERROR_FILE_NOT_FOUND) { 134 logger().warning("Trying to recreate Windows registry node " + 135 byteArrayToString(subKey) + " at root 0x" + 136 Integer.toHexString(hKey) + "."); 137 int handle = WindowsRegCreateKeyEx(hKey, subKey)[NATIVE_HANDLE]; 139 WindowsRegCloseKey(handle); 140 return WindowsRegOpenKey(hKey, subKey, securityMask); 141 } else if (result[ERROR_CODE] != ERROR_ACCESS_DENIED) { 142 long sleepTime = INIT_SLEEP_TIME; 143 for (int i = 0; i < MAX_ATTEMPTS; i++) { 144 try { 145 Thread.sleep(sleepTime); 146 } catch(InterruptedException e) { 147 return result; 148 } 149 sleepTime *= 2; 150 result = WindowsRegOpenKey(hKey, subKey, securityMask); 151 if (result[ERROR_CODE] == ERROR_SUCCESS) { 152 return result; 153 } 154 } 155 } 156 return result; 157 } 158 159 162 private static native int WindowsRegCloseKey(int hKey); 163 164 167 private static native int[] WindowsRegCreateKeyEx(int hKey, byte[] subKey); 168 169 172 private static int[] WindowsRegCreateKeyEx1(int hKey, byte[] subKey) { 173 int[] result = WindowsRegCreateKeyEx(hKey, subKey); 174 if (result[ERROR_CODE] == ERROR_SUCCESS) { 175 return result; 176 } else { 177 long sleepTime = INIT_SLEEP_TIME; 178 for (int i = 0; i < MAX_ATTEMPTS; i++) { 179 try { 180 Thread.sleep(sleepTime); 181 } catch(InterruptedException e) { 182 return result; 183 } 184 sleepTime *= 2; 185 result = WindowsRegCreateKeyEx(hKey, subKey); 186 if (result[ERROR_CODE] == ERROR_SUCCESS) { 187 return result; 188 } 189 } 190 } 191 return result; 192 } 193 196 private static native int WindowsRegDeleteKey(int hKey, byte[] subKey); 197 198 201 private static native int WindowsRegFlushKey(int hKey); 202 203 206 private static int WindowsRegFlushKey1(int hKey) { 207 int result = WindowsRegFlushKey(hKey); 208 if (result == ERROR_SUCCESS) { 209 return result; 210 } else { 211 long sleepTime = INIT_SLEEP_TIME; 212 for (int i = 0; i < MAX_ATTEMPTS; i++) { 213 try { 214 Thread.sleep(sleepTime); 215 } catch(InterruptedException e) { 216 return result; 217 } 218 sleepTime *= 2; 219 result = WindowsRegFlushKey(hKey); 220 if (result == ERROR_SUCCESS) { 221 return result; 222 } 223 } 224 } 225 return result; 226 } 227 228 231 private static native byte[] WindowsRegQueryValueEx(int hKey, 232 byte[] valueName); 233 236 private static native int WindowsRegSetValueEx(int hKey, byte[] valueName, 237 byte[] value); 238 241 private static int WindowsRegSetValueEx1(int hKey, byte[] valueName, 242 byte[] value) { 243 int result = WindowsRegSetValueEx(hKey, valueName, value); 244 if (result == ERROR_SUCCESS) { 245 return result; 246 } else { 247 long sleepTime = INIT_SLEEP_TIME; 248 for (int i = 0; i < MAX_ATTEMPTS; i++) { 249 try { 250 Thread.sleep(sleepTime); 251 } catch(InterruptedException e) { 252 return result; 253 } 254 sleepTime *= 2; 255 result = WindowsRegSetValueEx(hKey, valueName, value); 256 if (result == ERROR_SUCCESS) { 257 return result; 258 } 259 } 260 } 261 return result; 262 } 263 264 267 private static native int WindowsRegDeleteValue(int hKey, byte[] valueName); 268 269 272 private static native int[] WindowsRegQueryInfoKey(int hKey); 273 274 277 private static int[] WindowsRegQueryInfoKey1(int hKey) { 278 int[] result = WindowsRegQueryInfoKey(hKey); 279 if (result[ERROR_CODE] == ERROR_SUCCESS) { 280 return result; 281 } else { 282 long sleepTime = INIT_SLEEP_TIME; 283 for (int i = 0; i < MAX_ATTEMPTS; i++) { 284 try { 285 Thread.sleep(sleepTime); 286 } catch(InterruptedException e) { 287 return result; 288 } 289 sleepTime *= 2; 290 result = WindowsRegQueryInfoKey(hKey); 291 if (result[ERROR_CODE] == ERROR_SUCCESS) { 292 return result; 293 } 294 } 295 } 296 return result; 297 } 298 299 302 private static native byte[] WindowsRegEnumKeyEx(int hKey, int subKeyIndex, 303 int maxKeyLength); 304 305 308 private static byte[] WindowsRegEnumKeyEx1(int hKey, int subKeyIndex, 309 int maxKeyLength) { 310 byte[] result = WindowsRegEnumKeyEx(hKey, subKeyIndex, maxKeyLength); 311 if (result != null) { 312 return result; 313 } else { 314 long sleepTime = INIT_SLEEP_TIME; 315 for (int i = 0; i < MAX_ATTEMPTS; i++) { 316 try { 317 Thread.sleep(sleepTime); 318 } catch(InterruptedException e) { 319 return result; 320 } 321 sleepTime *= 2; 322 result = WindowsRegEnumKeyEx(hKey, subKeyIndex, maxKeyLength); 323 if (result != null) { 324 return result; 325 } 326 } 327 } 328 return result; 329 } 330 331 334 private static native byte[] WindowsRegEnumValue(int hKey, int valueIndex, 335 int maxValueNameLength); 336 339 private static byte[] WindowsRegEnumValue1(int hKey, int valueIndex, 340 int maxValueNameLength) { 341 byte[] result = WindowsRegEnumValue(hKey, valueIndex, 342 maxValueNameLength); 343 if (result != null) { 344 return result; 345 } else { 346 long sleepTime = INIT_SLEEP_TIME; 347 for (int i = 0; i < MAX_ATTEMPTS; i++) { 348 try { 349 Thread.sleep(sleepTime); 350 } catch(InterruptedException e) { 351 return result; 352 } 353 sleepTime *= 2; 354 result = WindowsRegEnumValue(hKey, valueIndex, 355 maxValueNameLength); 356 if (result != null) { 357 return result; 358 } 359 } 360 } 361 return result; 362 } 363 364 370 private WindowsPreferences(WindowsPreferences parent, String name) { 371 super(parent, name); 372 int parentNativeHandle = parent.openKey(KEY_CREATE_SUB_KEY, KEY_READ); 373 if (parentNativeHandle == NULL_NATIVE_HANDLE) { 374 isBackingStoreAvailable = false; 376 return; 377 } 378 int[] result = 379 WindowsRegCreateKeyEx1(parentNativeHandle, toWindowsName(name)); 380 if (result[ERROR_CODE] != ERROR_SUCCESS) { 381 logger().warning("Could not create windows registry " 382 + "node " + byteArrayToString(windowsAbsolutePath()) + 383 " at root 0x" + Integer.toHexString(rootNativeHandle()) + 384 ". Windows RegCreateKeyEx(...) returned error code " + 385 result[ERROR_CODE] + "."); 386 isBackingStoreAvailable = false; 387 return; 388 } 389 newNode = (result[DISPOSITION] == REG_CREATED_NEW_KEY); 390 closeKey(parentNativeHandle); 391 closeKey(result[NATIVE_HANDLE]); 392 } 393 394 402 private WindowsPreferences(int rootNativeHandle, byte[] rootDirectory) { 403 super(null,""); 404 int[] result = 405 WindowsRegCreateKeyEx1(rootNativeHandle, rootDirectory); 406 if (result[ERROR_CODE] != ERROR_SUCCESS) { 407 logger().warning("Could not open/create prefs root node " + 408 byteArrayToString(windowsAbsolutePath()) + " at root 0x" + 409 Integer.toHexString(rootNativeHandle()) + 410 ". Windows RegCreateKeyEx(...) returned error code " + 411 result[ERROR_CODE] + "."); 412 isBackingStoreAvailable = false; 413 return; 414 } 415 newNode = (result[DISPOSITION] == REG_CREATED_NEW_KEY); 417 closeKey(result[NATIVE_HANDLE]); 418 } 419 420 425 private byte[] windowsAbsolutePath() { 426 ByteArrayOutputStream bstream = new ByteArrayOutputStream (); 427 bstream.write(WINDOWS_ROOT_PATH, 0, WINDOWS_ROOT_PATH.length-1); 428 StringTokenizer tokenizer = new StringTokenizer (absolutePath(),"/"); 429 while (tokenizer.hasMoreTokens()) { 430 bstream.write((byte)'\\'); 431 String nextName = tokenizer.nextToken(); 432 byte[] windowsNextName = toWindowsName(nextName); 433 bstream.write(windowsNextName, 0, windowsNextName.length-1); 434 } 435 bstream.write(0); 436 return bstream.toByteArray(); 437 } 438 439 448 private int openKey(int securityMask) { 449 return openKey(securityMask, securityMask); 450 } 451 452 462 private int openKey(int mask1, int mask2) { 463 return openKey(windowsAbsolutePath(), mask1, mask2); 464 } 465 466 478 private int openKey(byte[] windowsAbsolutePath, int mask1, int mask2) { 479 481 if (windowsAbsolutePath.length <= MAX_WINDOWS_PATH_LENGTH + 1) { 482 int[] result = WindowsRegOpenKey1(rootNativeHandle(), 483 windowsAbsolutePath, mask1); 484 if (result[ERROR_CODE] == ERROR_ACCESS_DENIED && mask2 != mask1) 485 result = WindowsRegOpenKey1(rootNativeHandle(), 486 windowsAbsolutePath, mask2); 487 488 if (result[ERROR_CODE] != ERROR_SUCCESS) { 489 logger().warning("Could not open windows " 490 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 491 " at root 0x" + Integer.toHexString(rootNativeHandle()) + 492 ". Windows RegOpenKey(...) returned error code " + 493 result[ERROR_CODE] + "."); 494 result[NATIVE_HANDLE] = NULL_NATIVE_HANDLE; 495 if (result[ERROR_CODE] == ERROR_ACCESS_DENIED) { 496 throw new SecurityException ("Could not open windows " 497 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 498 " at root 0x" + Integer.toHexString(rootNativeHandle()) + 499 ": Access denied"); 500 } 501 } 502 return result[NATIVE_HANDLE]; 503 } else { 504 return openKey(rootNativeHandle(), windowsAbsolutePath, mask1, mask2); 505 } 506 } 507 508 521 private int openKey(int nativeHandle, byte[] windowsRelativePath, 522 int mask1, int mask2) { 523 524 if (windowsRelativePath.length <= MAX_WINDOWS_PATH_LENGTH + 1 ) { 525 int[] result = WindowsRegOpenKey1(nativeHandle, 526 windowsRelativePath, mask1); 527 if (result[ERROR_CODE] == ERROR_ACCESS_DENIED && mask2 != mask1) 528 result = WindowsRegOpenKey1(nativeHandle, 529 windowsRelativePath, mask2); 530 531 if (result[ERROR_CODE] != ERROR_SUCCESS) { 532 logger().warning("Could not open windows " 533 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 534 " at root 0x" + Integer.toHexString(nativeHandle) + 535 ". Windows RegOpenKey(...) returned error code " + 536 result[ERROR_CODE] + "."); 537 result[NATIVE_HANDLE] = NULL_NATIVE_HANDLE; 538 } 539 return result[NATIVE_HANDLE]; 540 } else { 541 int separatorPosition = -1; 542 for (int i = MAX_WINDOWS_PATH_LENGTH; i > 0; i--) { 544 if (windowsRelativePath[i] == ((byte)'\\')) { 545 separatorPosition = i; 546 break; 547 } 548 } 549 byte[] nextRelativeRoot = new byte[separatorPosition+1]; 551 System.arraycopy(windowsRelativePath, 0, nextRelativeRoot,0, 552 separatorPosition); 553 nextRelativeRoot[separatorPosition] = 0; 554 byte[] nextRelativePath = new byte[windowsRelativePath.length - 555 separatorPosition - 1]; 556 System.arraycopy(windowsRelativePath, separatorPosition+1, 557 nextRelativePath, 0, nextRelativePath.length); 558 int nextNativeHandle = openKey(nativeHandle, nextRelativeRoot, 559 mask1, mask2); 560 if (nextNativeHandle == NULL_NATIVE_HANDLE) { 561 return NULL_NATIVE_HANDLE; 562 } 563 int result = openKey(nextNativeHandle, nextRelativePath, 564 mask1,mask2); 565 closeKey(nextNativeHandle); 566 return result; 567 } 568 } 569 570 578 private void closeKey(int nativeHandle) { 579 int result = WindowsRegCloseKey(nativeHandle); 580 if (result != ERROR_SUCCESS) { 581 logger().warning("Could not close windows " 582 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 583 " at root 0x" + Integer.toHexString(rootNativeHandle()) + 584 ". Windows RegCloseKey(...) returned error code " + result + "."); 585 } 586 } 587 588 594 protected void putSpi(String javaName, String value) { 595 int nativeHandle = openKey(KEY_SET_VALUE); 596 if (nativeHandle == NULL_NATIVE_HANDLE) { 597 isBackingStoreAvailable = false; 598 return; 599 } 600 int result = WindowsRegSetValueEx1(nativeHandle, 601 toWindowsName(javaName), toWindowsValueString(value)); 602 if (result != ERROR_SUCCESS) { 603 logger().warning("Could not assign value to key " + 604 byteArrayToString(toWindowsName(javaName))+ " at Windows registry node " 605 + byteArrayToString(windowsAbsolutePath()) + " at root 0x" 606 + Integer.toHexString(rootNativeHandle()) + 607 ". Windows RegSetValueEx(...) returned error code " + result + "."); 608 isBackingStoreAvailable = false; 609 } 610 closeKey(nativeHandle); 611 } 612 613 619 protected String getSpi(String javaName) { 620 int nativeHandle = openKey(KEY_QUERY_VALUE); 621 if (nativeHandle == NULL_NATIVE_HANDLE) { 622 return null; 623 } 624 Object resultObject = WindowsRegQueryValueEx(nativeHandle, 625 toWindowsName(javaName)); 626 if (resultObject == null) { 627 closeKey(nativeHandle); 628 return null; 629 } 630 closeKey(nativeHandle); 631 return toJavaValueString((byte[]) resultObject); 632 } 633 634 641 protected void removeSpi(String key) { 642 int nativeHandle = openKey(KEY_SET_VALUE); 643 if (nativeHandle == NULL_NATIVE_HANDLE) { 644 return; 645 } 646 int result = 647 WindowsRegDeleteValue(nativeHandle, toWindowsName(key)); 648 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { 649 logger().warning("Could not delete windows registry " 650 + "value " + byteArrayToString(windowsAbsolutePath())+ "\\" + 651 toWindowsName(key) + " at root 0x" + 652 Integer.toHexString(rootNativeHandle()) + 653 ". Windows RegDeleteValue(...) returned error code " + 654 result + "."); 655 isBackingStoreAvailable = false; 656 } 657 closeKey(nativeHandle); 658 } 659 660 666 protected String [] keysSpi() throws BackingStoreException { 667 int nativeHandle = openKey(KEY_QUERY_VALUE); 669 if (nativeHandle == NULL_NATIVE_HANDLE) { 670 throw new BackingStoreException ("Could not open windows" 671 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 672 " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); 673 } 674 int[] result = WindowsRegQueryInfoKey1(nativeHandle); 675 if (result[ERROR_CODE] != ERROR_SUCCESS) { 676 String info = "Could not query windows" 677 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 678 " at root 0x" + Integer.toHexString(rootNativeHandle()) + 679 ". Windows RegQueryInfoKeyEx(...) returned error code " + 680 result[ERROR_CODE] + "."; 681 logger().warning(info); 682 throw new BackingStoreException (info); 683 } 684 int maxValueNameLength = result[MAX_VALUE_NAME_LENGTH]; 685 int valuesNumber = result[VALUES_NUMBER]; 686 if (valuesNumber == 0) { 687 closeKey(nativeHandle); 688 return new String [0]; 689 } 690 String [] valueNames = new String [valuesNumber]; 692 for (int i = 0; i < valuesNumber; i++) { 693 byte[] windowsName = WindowsRegEnumValue1(nativeHandle, i, 694 maxValueNameLength+1); 695 if (windowsName == null) { 696 String info = 697 "Could not enumerate value #" + i + " of windows node " + 698 byteArrayToString(windowsAbsolutePath()) + " at root 0x" + 699 Integer.toHexString(rootNativeHandle()) + "."; 700 logger().warning(info); 701 throw new BackingStoreException (info); 702 } 703 valueNames[i] = toJavaName(windowsName); 704 } 705 closeKey(nativeHandle); 706 return valueNames; 707 } 708 709 715 protected String [] childrenNamesSpi() throws BackingStoreException { 716 int nativeHandle = openKey(KEY_ENUMERATE_SUB_KEYS| KEY_QUERY_VALUE); 718 if (nativeHandle == NULL_NATIVE_HANDLE) { 719 throw new BackingStoreException ("Could not open windows" 720 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 721 " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); 722 } 723 int[] result = WindowsRegQueryInfoKey1(nativeHandle); 725 if (result[ERROR_CODE] != ERROR_SUCCESS) { 726 String info = "Could not query windows" 727 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 728 " at root 0x" + Integer.toHexString(rootNativeHandle()) + 729 ". Windows RegQueryInfoKeyEx(...) returned error code " + 730 result[ERROR_CODE] + "."; 731 logger().warning(info); 732 throw new BackingStoreException (info); 733 } 734 int maxKeyLength = result[MAX_KEY_LENGTH]; 735 int subKeysNumber = result[SUBKEYS_NUMBER]; 736 if (subKeysNumber == 0) { 737 closeKey(nativeHandle); 738 return new String [0]; 739 } 740 String [] subkeys = new String [subKeysNumber]; 741 String [] children = new String [subKeysNumber]; 742 for (int i = 0; i < subKeysNumber; i++) { 744 byte[] windowsName = WindowsRegEnumKeyEx1(nativeHandle, i, 745 maxKeyLength+1); 746 if (windowsName == null) { 747 String info = 748 "Could not enumerate key #" + i + " of windows node " + 749 byteArrayToString(windowsAbsolutePath()) + " at root 0x" + 750 Integer.toHexString(rootNativeHandle()) + ". "; 751 logger().warning(info); 752 throw new BackingStoreException (info); 753 } 754 String javaName = toJavaName(windowsName); 755 children[i] = javaName; 756 } 757 closeKey(nativeHandle); 758 return children; 759 } 760 761 767 public void flush() throws BackingStoreException { 768 769 if (isRemoved()) { 770 parent.flush(); 771 return; 772 } 773 if (!isBackingStoreAvailable) { 774 throw new BackingStoreException ( 775 "flush(): Backing store not available."); 776 } 777 int nativeHandle = openKey(KEY_READ); 778 if (nativeHandle == NULL_NATIVE_HANDLE) { 779 throw new BackingStoreException ("Could not open windows" 780 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 781 " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); 782 } 783 int result = WindowsRegFlushKey1(nativeHandle); 784 if (result != ERROR_SUCCESS) { 785 String info = "Could not flush windows " 786 + "registry node " + byteArrayToString(windowsAbsolutePath()) 787 + " at root 0x" + Integer.toHexString(rootNativeHandle()) + 788 ". Windows RegFlushKey(...) returned error code " + result + "."; 789 logger().warning(info); 790 throw new BackingStoreException (info); 791 } 792 closeKey(nativeHandle); 793 } 794 795 796 801 public void sync() throws BackingStoreException { 802 if (isRemoved()) 803 throw new IllegalStateException ("Node has been removed"); 804 flush(); 805 } 806 807 814 protected AbstractPreferences childSpi(String name) { 815 return new WindowsPreferences (this, name); 816 } 817 818 824 public void removeNodeSpi() throws BackingStoreException { 825 int parentNativeHandle = 826 ((WindowsPreferences )parent()).openKey(DELETE); 827 if (parentNativeHandle == NULL_NATIVE_HANDLE) { 828 throw new BackingStoreException ("Could not open parent windows" 829 + "registry node of " + byteArrayToString(windowsAbsolutePath()) + 830 " at root 0x" + Integer.toHexString(rootNativeHandle()) + "."); 831 } 832 int result = 833 WindowsRegDeleteKey(parentNativeHandle, toWindowsName(name())); 834 if (result != ERROR_SUCCESS) { 835 String info = "Could not delete windows " 836 + "registry node " + byteArrayToString(windowsAbsolutePath()) + 837 " at root 0x" + Integer.toHexString(rootNativeHandle()) + 838 ". Windows RegDeleteKeyEx(...) returned error code " + 839 result + "."; 840 logger().warning(info); 841 throw new BackingStoreException (info); 842 } 843 closeKey(parentNativeHandle); 844 } 845 846 853 private static String toJavaName(byte[] windowsNameArray) { 854 String windowsName = byteArrayToString(windowsNameArray); 855 if ((windowsName.length()>1) && 857 (windowsName.substring(0,2).equals("/!"))) { 858 return toJavaAlt64Name(windowsName); 859 } 860 StringBuffer javaName = new StringBuffer (); 861 char ch; 862 for (int i = 0; i < windowsName.length(); i++){ 864 if ((ch = windowsName.charAt(i)) == '/') { 865 char next = ' '; 866 if ((windowsName.length() > i + 1) && 867 ((next = windowsName.charAt(i+1)) >= 'A') && (next <= 'Z')) { 868 ch = next; 869 i++; 870 } else if ((windowsName.length() > i + 1) && (next == '/')) { 871 ch = '\\'; 872 i++; 873 } 874 } else if (ch == '\\') { 875 ch = '/'; 876 } 877 javaName.append(ch); 878 } 879 return javaName.toString(); 880 } 881 882 888 889 private static String toJavaAlt64Name(String windowsName) { 890 byte[] byteBuffer = 891 Base64.altBase64ToByteArray(windowsName.substring(2)); 892 StringBuffer result = new StringBuffer (); 893 for (int i = 0; i < byteBuffer.length; i++) { 894 int firstbyte = (byteBuffer[i++] & 0xff); 895 int secondbyte = (byteBuffer[i] & 0xff); 896 result.append((char)((firstbyte << 8) + secondbyte)); 897 } 898 return result.toString(); 899 } 900 901 921 private static byte[] toWindowsName(String javaName) { 922 StringBuffer windowsName = new StringBuffer (); 923 for (int i = 0; i < javaName.length(); i++) { 924 char ch =javaName.charAt(i); 925 if ((ch < 0x0020)||(ch > 0x007f)) { 926 return toWindowsAlt64Name(javaName); 928 } 929 if (ch == '\\') { 930 windowsName.append("//"); 931 } else if (ch == '/') { 932 windowsName.append('\\'); 933 } else if ((ch >= 'A') && (ch <='Z')) { 934 windowsName.append("/" + ch); 935 } else { 936 windowsName.append(ch); 937 } 938 } 939 return stringToByteArray(windowsName.toString()); 940 } 941 942 948 private static byte[] toWindowsAlt64Name(String javaName) { 949 byte[] javaNameArray = new byte[2*javaName.length()]; 950 int counter = 0; 952 for (int i = 0; i < javaName.length();i++) { 953 int ch = javaName.charAt(i); 954 javaNameArray[counter++] = (byte)(ch >>> 8); 955 javaNameArray[counter++] = (byte)ch; 956 } 957 958 return stringToByteArray( 959 "/!" + Base64.byteArrayToAltBase64(javaNameArray)); 960 } 961 962 968 private static String toJavaValueString(byte[] windowsNameArray) { 969 String windowsName = byteArrayToString(windowsNameArray); 971 StringBuffer javaName = new StringBuffer (); 972 char ch; 973 for (int i = 0; i < windowsName.length(); i++){ 974 if ((ch = windowsName.charAt(i)) == '/') { 975 char next = ' '; 976 977 if (windowsName.length() > i + 1 && 978 (next = windowsName.charAt(i + 1)) == 'u') { 979 if (windowsName.length() < i + 6){ 980 break; 981 } else { 982 ch = (char)Integer.parseInt 983 (windowsName.substring(i + 2, i + 6), 16); 984 i += 5; 985 } 986 } else 987 if ((windowsName.length() > i + 1) && 988 ((windowsName.charAt(i+1)) >= 'A') && (next <= 'Z')) { 989 ch = next; 990 i++; 991 } else if ((windowsName.length() > i + 1) && 992 (next == '/')) { 993 ch = '\\'; 994 i++; 995 } 996 } else if (ch == '\\') { 997 ch = '/'; 998 } 999 javaName.append(ch); 1000 } 1001 return javaName.toString(); 1002 } 1003 1004 1013 private static byte[] toWindowsValueString(String javaName) { 1014 StringBuffer windowsName = new StringBuffer (); 1015 for (int i = 0; i < javaName.length(); i++) { 1016 char ch =javaName.charAt(i); 1017 if ((ch < 0x0020)||(ch > 0x007f)){ 1018 windowsName.append("/u"); 1020 String hex = Integer.toHexString(javaName.charAt(i)); 1021 StringBuffer hex4 = new StringBuffer (hex); 1022 hex4.reverse(); 1023 int len = 4 - hex4.length(); 1024 for (int j = 0; j < len; j++){ 1025 hex4.append('0'); 1026 } 1027 for (int j = 0; j < 4; j++){ 1028 windowsName.append(hex4.charAt(3 - j)); 1029 } 1030 } else if (ch == '\\') { 1031 windowsName.append("//"); 1032 } else if (ch == '/') { 1033 windowsName.append('\\'); 1034 } else if ((ch >= 'A') && (ch <='Z')) { 1035 windowsName.append("/" + ch); 1036 } else { 1037 windowsName.append(ch); 1038 } 1039 } 1040 return stringToByteArray(windowsName.toString()); 1041 } 1042 1043 1046 private int rootNativeHandle() { 1047 return (isUserNode()? USER_ROOT_NATIVE_HANDLE : 1048 SYSTEM_ROOT_NATIVE_HANDLE); 1049 } 1050 1051 1054 private static byte[] stringToByteArray(String str) { 1055 byte[] result = new byte[str.length()+1]; 1056 for (int i = 0; i < str.length(); i++) { 1057 result[i] = (byte) str.charAt(i); 1058 } 1059 result[str.length()] = 0; 1060 return result; 1061 } 1062 1063 1066 private static String byteArrayToString(byte[] array) { 1067 StringBuffer result = new StringBuffer (); 1068 for (int i = 0; i < array.length - 1; i++) { 1069 result.append((char)array[i]); 1070 } 1071 return result.toString(); 1072 } 1073 1074 1077 protected void flushSpi() throws BackingStoreException { 1078 } 1080 1081 1084 protected void syncSpi() throws BackingStoreException { 1085 } 1087 1088 private static synchronized Logger logger() { 1089 if (logger == null) { 1090 logger = Logger.getLogger("java.util.prefs"); 1091 } 1092 return logger; 1093 } 1094} 1095 | Popular Tags |