| 15914 | ! |
| 15915 | |
| 15916 | valueTypeAndSize:nameString |
| 15917 | "Returns a Windows registry dictinary (#type -> size) based on value name |
| 15918 | REG_NONE -> nil |
| 15919 | REG_BINARY -> ByteArray |
| 15920 | REG_SZ -> String |
| 15921 | REG_EXPAND_SZ -> String (unexpadned windows variables) |
| 15922 | REG_DWORD -> Integer (can be LITTLE_ENDIAN or BIG_ENDIAN) |
| 15923 | REG_DWORD -> 64bit Integer |
| 15924 | REG_MULTI_SZ -> Array of strings (note: dataSize returns number of bytes) |
| 15925 | " |
| 15926 | |
| 15927 | |windowsRegistryTable nameUtf16Z errorNumber| |
| 15928 | |
| 15929 | windowsRegistryTable := Dictionary new. |
| 15930 | |
| 15931 | "/ adding terminating null into empty string |
| 15932 | nameString notNil ifTrue:[ |
| 15933 | nameUtf16Z := nameString isEmpty ifTrue:[(nameString, (Character codePoint: 0)) asUnicode16String] "/ needed for defaultValue |
| 15934 | ifFalse:[nameString asUnicode16StringZ] |
| 15935 | ]. |
| 15936 | |
| 15937 | %{ |
| 15938 | HKEY myKey; |
| 15939 | DWORD valueType; |
| 15940 | |
| 15941 | DWORD dataSize, sizeInChars, sizeInBytes = 0; |
| 15942 | |
| 15943 | if (__isExternalAddressLike(__INST(handle)) |
| 15944 | && __isUnicode16String(nameUtf16Z)) { |
| 15945 | int ret; |
| 15946 | |
| 15947 | myKey = (HKEY)__externalAddressVal(__INST(handle)); |
| 15948 | |
| 15949 | // Getting valuetype and dataSize (actual data is not important) |
| 15950 | ret = RegQueryValueExW(myKey, __unicode16StringVal(nameUtf16Z), |
| 15951 | NULL, |
| 15952 | &valueType, |
| 15953 | NULL, |
| 15954 | &dataSize); |
| 15955 | |
| 15956 | if (ret == ERROR_SUCCESS) { |
| 15957 | switch (valueType) { |
| 15958 | case REG_NONE: // returns alwyas REG_NONE -> 0 |
| 15959 | __AT_PUT_(windowsRegistryTable , @symbol(REG_NONE), __MKUINT(0)); |
| 15960 | break; |
| 15961 | |
| 15962 | case REG_BINARY: |
| 15963 | sizeInBytes = dataSize; |
| 15964 | __AT_PUT_(windowsRegistryTable , @symbol(REG_BINARY), __MKUINT(sizeInBytes)); |
| 15965 | break; |
| 15966 | |
| 15967 | case REG_SZ: |
| 15968 | sizeInChars = (dataSize / sizeof(wchar_t)) - 1; // (datasize / character width) - terminating NULL |
| 15969 | __AT_PUT_(windowsRegistryTable , @symbol(REG_SZ), __MKUINT(sizeInChars)); |
| 15970 | break; |
| 15971 | |
| 15972 | case REG_EXPAND_SZ: |
| 15973 | sizeInChars = (dataSize / sizeof(wchar_t)) - 1; // (datasize / character width) - terminating NULL |
| 15974 | __AT_PUT_(windowsRegistryTable , @symbol(REG_EXPAND_SZ), __MKUINT(sizeInChars)); |
| 15975 | break; |
| 15976 | |
| 15977 | case REG_DWORD_LITTLE_ENDIAN: |
| 15978 | sizeInBytes = dataSize; // bytes of the registry type |
| 15979 | __AT_PUT_(windowsRegistryTable , @symbol(REG_DWORD_LITTLE_ENDIAN), __MKUINT(sizeInBytes)); |
| 15980 | break; |
| 15981 | |
| 15982 | case REG_DWORD_BIG_ENDIAN: |
| 15983 | sizeInBytes = dataSize; // bytes of the registry type |
| 15984 | __AT_PUT_(windowsRegistryTable , @symbol(REG_DWORD_BIG_ENDIAN), __MKUINT(sizeInBytes)); |
| 15985 | break; |
| 15986 | |
| 15987 | case REG_QWORD: |
| 15988 | sizeInBytes = dataSize; // bytes of the registry type |
| 15989 | __AT_PUT_(windowsRegistryTable , @symbol(REG_QWORD), __MKUINT(sizeInBytes)); |
| 15990 | break; |
| 15991 | |
| 15992 | case REG_MULTI_SZ: |
| 15993 | { |
| 15994 | /* dataSize note: |
| 15995 | * Since we are not reading the actual data there is unknown number of terminaing NULL (every array item has one) and |
| 15996 | * the end of the array has addtional one. User has to count manually the number of terminaing NULL(s). |
| 15997 | * |
| 15998 | * A general formula for calculating size for REG_MULTI_SZ: |
| 15999 | * ((array node size(1) + terminating NULL) + (array node size(2) + terminating NULL) + ... + (array node size(n) + terminating NULL)) * character width (sizeof(wchar_t)) - last terminating NULL (-1) |
| 16000 | * A Smalltalk/C way: |
| 16001 | * (((Array at: 1) size + 1) + ((Array at: 2) size + 1) + ... + ((Array at: n) size + 1))) * sizeof(wchar_t) - 1 |
| 16002 | */ |
| 16003 | sizeInBytes = dataSize; |
| 16004 | __AT_PUT_(windowsRegistryTable , @symbol(REG_MULTI_SZ), __MKUINT(sizeInBytes)); |
| 16005 | break; |
| 16006 | } |
| 16007 | default: |
| 16008 | console_printf("[warning]: Unknown RegistryEntry valueType: %d\n", valueType); |
| 16009 | break; |
| 16010 | } |
| 16011 | } else { |
| 16012 | errorNumber = __MKSMALLINT(ret); |
| 16013 | } |
| 16014 | } |
| 16015 | |
| 16016 | %}. |
| 16017 | errorNumber notNil ifTrue:[ |
| 16018 | (OperatingSystem errorHolderForNumber:errorNumber) reportError. |
| 16019 | ]. |
| 16020 | ^ windowsRegistryTable |
| 16021 | |
| 16022 | " |
| 16023 | |key| |
| 16024 | |
| 16025 | key := Dictionary new. |
| 16026 | key := self key:'HKEY_LOCAL_MACHINE\SOFTWARE\eXept\Smalltalk/X'. |
| 16027 | key valueTypeAndSize:'CurrentVersion' |
| 16028 | " |