16921 key := self key:'HKEY_LOCAL_MACHINE\SOFTWARE\eXept\Smalltalk/X'. |
16921 key := self key:'HKEY_LOCAL_MACHINE\SOFTWARE\eXept\Smalltalk/X'. |
16922 key valueNamed:'CurrentVersion' |
16922 key valueNamed:'CurrentVersion' |
16923 " |
16923 " |
16924 ! |
16924 ! |
16925 |
16925 |
16926 valueNamed:aValueName put:datum |
16926 valueNamed:name put:data |
|
16927 "store a value; the value type depends upon the stored value: |
|
16928 ByteArray -> REG_BINARY |
|
16929 String -> REG_SZ |
|
16930 Array of string -> REG_MULTI_SZ |
|
16931 Integer -> REG_DWORD |
|
16932 nil -> REG_NONE |
|
16933 " |
|
16934 "Transcript showCR: 'name:', name. |
|
16935 Transcript showCR: 'data:', data." |
|
16936 |
|
16937 ^ self valueNamed:name put:data unexpandedReferences:false |
|
16938 ! |
|
16939 |
|
16940 valueNamed:name put:data unexpandedReferences:containsUnexpandedReferences |
16927 "store a value; the value type depends upon the stored value: |
16941 "store a value; the value type depends upon the stored value: |
16928 ByteArray -> REG_BINARY |
16942 ByteArray -> REG_BINARY |
16929 String -> REG_SZ |
16943 String -> REG_SZ OR REG_EXPAND_SZ based on containsUnexpandedReferences |
16930 Array of string -> REG_MULTI_SZ |
16944 Array of string -> REG_MULTI_SZ |
16931 Integer -> REG_DWORD |
16945 Integer -> REG_DWORD |
16932 nil -> REG_NONE |
16946 nil -> REG_NONE |
16933 " |
16947 |
16934 |
16948 containsUnexpandedReferences: |
16935 |data stringArray errorNumber| |
16949 true -> REG_EXPAND_SZ |
|
16950 false -> REG_SZ |
|
16951 |
|
16952 REG_EXPAND_SZ: |
|
16953 Null-terminated string that contains unexpanded references to environment variables (for example, ""%PATH%""). It will be a Unicode or ANSI string, |
|
16954 depending on whether you use the Unicode or ANSI functions. |
|
16955 " |
|
16956 |
|
16957 |nameUtf16Z dataUtf16Z stringArray errorNumber| |
|
16958 |
|
16959 "/ name must be a string, if not return nil |
|
16960 name isString ifFalse: [ |
|
16961 Transcript showCR: 'The registry value name must be a String!!'. |
|
16962 ^ nil |
|
16963 ]. |
|
16964 "/ name asUnicodeString and null terminated |
|
16965 name notNil ifTrue:[ |
|
16966 name isEmpty ifTrue:[nameUtf16Z := (name, (Character codePoint: 0)) asUnicode16String] "/ needed for defaultValue: |
|
16967 ifFalse:[nameUtf16Z := name asUnicode16StringZ] |
|
16968 ]. |
|
16969 "/ data asUnicode16String and null terminated |
|
16970 data notNil ifTrue:[ |
|
16971 data isString ifTrue:[ |
|
16972 data isEmpty ifTrue:[dataUtf16Z := (data, (Character codePoint: 0)) asUnicode16String] "/ for empty data strings |
|
16973 ifFalse:[dataUtf16Z := data asUnicode16StringZ] |
|
16974 ]. |
|
16975 data isArray ifTrue:[ |
|
16976 dataUtf16Z := data collect:[:eachString | "/ for every Array member to be null terminated |
|
16977 eachString asUnicode16StringZ |
|
16978 ] |
|
16979 ] |
|
16980 ]. |
|
16981 |
16936 %{ |
16982 %{ |
16937 /* Registry Element Size Limits |
16983 /* Registry Element Size Limits |
16938 * |
16984 * |
16939 * Found at MSDN: https://docs.microsoft.com/en-us/windows/desktop/SysInfo/registry-element-size-limits |
16985 * Found at MSDN: https://docs.microsoft.com/en-us/windows/desktop/SysInfo/registry-element-size-limits |
16940 * |
16986 * |
16950 * |
16996 * |
16951 * - The file location can be the name of a value or the data of a value. Each backslash in the location string must be preceded by |
16997 * - The file location can be the name of a value or the data of a value. Each backslash in the location string must be preceded by |
16952 * another backslash as an escape character. For example, specify "C:\\mydir\\myfile" to store the string "C:\mydir\myfile". |
16998 * another backslash as an escape character. For example, specify "C:\\mydir\\myfile" to store the string "C:\mydir\myfile". |
16953 * A file location can also be the name of a key if it is within the 255-character limit for key names and does not contain backslashes, |
16999 * A file location can also be the name of a key if it is within the 255-character limit for key names and does not contain backslashes, |
16954 * which are not allowed in key names. |
17000 * which are not allowed in key names. |
|
17001 * |
|
17002 * RegSetValueExW (catches) |
|
17003 * |
|
17004 * LSTATUS RegSetValueExW( |
|
17005 * HKEY hKey, |
|
17006 * LPCSTR lpValueName, |
|
17007 * DWORD Reserved, |
|
17008 * DWORD dwType, |
|
17009 * const BYTE *lpData, |
|
17010 * DWORD cbData |
|
17011 * ); |
|
17012 * |
|
17013 * lpValueName |
|
17014 * The name of the value to be set. If a value with this name is not already present in the key, the function adds it to the key. |
|
17015 * If lpValueName is NULL or an empty string, "", the function sets the type and data for the key's unnamed or default value. |
|
17016 * For more information, see Registry Element Size Limits (above). |
|
17017 * Registry keys do not have default values, but they can have one unnamed value, which can be of any type. |
|
17018 * |
|
17019 * lpData |
|
17020 * The data to be stored. |
|
17021 * For string-based types, such as REG_SZ, the string must be null-terminated. With the REG_MULTI_SZ data type, the string must be terminated |
|
17022 * with **two** null characters. |
|
17023 * Note lpData indicating a null value is valid, however, if this is the case, cbData must be set to '0'. |
|
17024 * |
|
17025 * cbData |
|
17026 * The size of the information pointed to by the lpData parameter, in bytes. |
|
17027 * If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, cbData must include the size of the terminating null character or characters. |
|
17028 * |
|
17029 * Remarks |
|
17030 * Value sizes are limited by available memory. However, storing large values in the registry can affect its performance. |
|
17031 * Long values (more than 2,048 bytes) should be stored as files, with the locations of the files stored in the registry. |
|
17032 * |
|
17033 * Application elements such as icons, bitmaps, and executable files should be stored as files and not be placed in the registry. |
|
17034 * |
|
17035 * If dwType is the REG_SZ, REG_MULTI_SZ, or REG_EXPAND_SZ type and the ANSI version of this function is used (either by explicitly |
|
17036 * calling RegSetValueExA or by not defining UNICODE before including the Windows.h file), the data pointed to by the lpData parameter |
|
17037 * must be an ANSI character string. The string is converted to Unicode before it is stored in the registry. |
|
17038 * |
|
17039 * Note that operations that access certain registry keys are redirected. For more information, see Registry Virtualization and 32-bit and |
|
17040 * 64-bit Application Data in the Registry. |
|
17041 * |
16955 */ |
17042 */ |
16956 |
17043 |
16957 HKEY myKey; |
17044 HKEY myKey; |
16958 DWORD valueType = -1; |
17045 DWORD valueType = -1; |
16959 int val; |
17046 int val; |
|
17047 ULONGLONG longVal; |
16960 DWORD dataSize = -1; |
17048 DWORD dataSize = -1; |
16961 unsigned char *dataPointer = NULL; |
17049 void *dataPointer = NULL; |
16962 int datumOk = 1, mustFreeData = 0; |
17050 int dataOk = 1, mustFreeData = 0; |
16963 |
17051 |
16964 if (__isExternalAddressLike(__INST(handle)) |
17052 if (__isExternalAddressLike(__INST(handle)) |
16965 && __isStringLike(aValueName)) { |
17053 && __isUnicode16String(nameUtf16Z)) { |
16966 int ret; |
17054 int ret; |
16967 OBJ cls; |
17055 OBJ cls; |
16968 |
17056 |
16969 myKey = (HKEY)__externalAddressVal(__INST(handle)); |
17057 myKey = (HKEY)__externalAddressVal(__INST(handle)); |
16970 |
17058 |
16971 if (datum == nil) { |
17059 if (data == nil) { |
16972 valueType = REG_NONE; |
17060 valueType = REG_NONE; |
16973 dataSize = 0; |
17061 dataSize = 0; |
16974 } else if (__isSmallInteger(datum)) { |
17062 } else if (__isSmallInteger(data)) { |
16975 valueType = REG_DWORD; |
17063 valueType = REG_DWORD; |
16976 val = __intVal(datum); |
17064 val = __intVal(data); |
16977 dataPointer = (unsigned char *)(&val); |
17065 dataPointer = &val; |
16978 dataSize = sizeof(val); |
17066 dataSize = sizeof(val); |
16979 } else if (__isStringLike(datum)) { |
17067 } else if (__isUnicode16String(dataUtf16Z)) { |
16980 valueType = REG_SZ; |
17068 valueType = containsUnexpandedReferences == true ? REG_EXPAND_SZ : REG_SZ; |
16981 dataPointer = __stringVal(datum); |
17069 dataPointer = __unicode16StringVal(dataUtf16Z); |
16982 dataSize = __stringSize(datum) + 1; |
17070 dataSize = __unicode16StringSize(dataUtf16Z) * sizeof(wchar_t); |
16983 } else if (__Class(datum) == ByteArray) { |
17071 } else if (__Class(data) == ByteArray) { |
16984 valueType = REG_BINARY; |
17072 valueType = REG_BINARY; |
16985 dataPointer = __ByteArrayInstPtr(datum)->ba_element; |
17073 dataPointer = __ByteArrayInstPtr(data)->ba_element; |
16986 dataSize = __byteArraySize(datum); |
17074 dataSize = __byteArraySize(data); |
16987 } else if (__Class(datum) == LargeInteger) { |
17075 } else if (__Class(data) == LargeInteger) { |
16988 valueType = REG_DWORD; |
17076 valueType = REG_QWORD; |
16989 val = __longIntVal(datum); |
17077 longVal = __longIntVal(data); |
16990 if (val) { |
17078 if (longVal) { |
16991 dataPointer = (unsigned char *)(&val); |
17079 dataPointer = &longVal; |
16992 dataSize = sizeof(val); |
17080 dataSize = sizeof(longVal); |
16993 } else { |
17081 } else { |
16994 datumOk = 0; |
17082 dataOk = 0; |
16995 } |
17083 } |
16996 } else if (__Class(datum) == Array) { |
17084 } else if (__Class(data) == Array) { |
16997 int i = 0, ns = 0, totalSize = 0; |
17085 int i = 0, ns = 0, totalSize = 0; |
16998 |
17086 |
16999 valueType = REG_MULTI_SZ; |
17087 valueType = REG_MULTI_SZ; |
17000 |
17088 |
17001 /* |
17089 /* |
17002 * must allocate a local buffer |
17090 * must allocate a local buffer |
17003 * find size ... |
17091 * find size ... |
17004 */ |
17092 */ |
17005 for (i=0; i<__arraySize(datum); i++) { |
17093 for (i=0; i<__arraySize(dataUtf16Z); i++) { |
17006 OBJ s = __ArrayInstPtr(datum)->a_element[i]; |
17094 OBJ s = __ArrayInstPtr(dataUtf16Z)->a_element[i]; |
17007 |
17095 |
17008 if (__isStringLike(s)) { |
17096 if (__isUnicode16String(s)) { |
17009 totalSize += __stringSize(s) + 1; |
17097 totalSize += __unicode16StringSize(s); |
17010 } else { |
17098 } else { |
17011 datumOk = 0; |
17099 dataOk = 0; |
17012 break; |
17100 break; |
17013 } |
17101 } |
17014 ns++; |
17102 ns++; |
17015 } |
17103 } |
17016 if (datumOk) { |
17104 |
17017 char *cp; |
17105 if (dataOk) { |
|
17106 wchar_t *cp; |
17018 |
17107 |
17019 /* |
17108 /* |
17020 * allocate and fill... |
17109 * allocate and fill... |
17021 */ |
17110 */ |
17022 totalSize ++; |
17111 // (totalSize length * size of wide char) + terminating null character |
17023 dataPointer = (char *)(malloc(totalSize)); |
17112 totalSize = (totalSize * sizeof(wchar_t)) + 1; |
|
17113 dataPointer = malloc(totalSize); |
17024 mustFreeData = 1; |
17114 mustFreeData = 1; |
17025 cp = dataPointer; |
17115 cp = dataPointer; |
17026 for (i=0; i<__arraySize(datum); i++) { |
17116 for (i=0; i<__arraySize(dataUtf16Z); i++) { |
17027 OBJ s = __ArrayInstPtr(datum)->a_element[i]; |
17117 OBJ s = __ArrayInstPtr(dataUtf16Z)->a_element[i]; |
17028 |
17118 |
17029 strcpy(cp, __stringVal(s)); |
17119 memcpy(cp, __unicode16StringVal(s), __unicode16StringSize(s) * sizeof(wchar_t)); |
17030 cp += __stringSize(s); |
17120 cp += __unicode16StringSize(s); |
17031 *cp++ = '\0'; |
|
17032 } |
17121 } |
17033 *cp++ = '\0'; |
17122 *cp++ = '\0'; // adding second terminating null character (for more information see MSDN comment above) |
17034 dataSize = totalSize; |
17123 dataSize = totalSize; |
|
17124 //console_printf("DataSize: %d\n", dataSize); |
17035 } |
17125 } |
17036 } else { |
17126 } else { |
17037 datumOk = 0; |
17127 dataOk = 0; |
17038 } |
17128 } |
17039 |
17129 |
17040 if (datumOk) { |
17130 if (dataOk) { |
17041 ret = RegSetValueExA(myKey, __stringVal(aValueName), |
17131 ret = RegSetValueExW(myKey, __unicode16StringVal(nameUtf16Z), |
17042 0, valueType, |
17132 0, valueType, |
17043 dataPointer, dataSize); |
17133 (LPBYTE) dataPointer, |
|
17134 dataSize); |
17044 if (mustFreeData) { |
17135 if (mustFreeData) { |
17045 free(dataPointer); |
17136 free(dataPointer); |
17046 } |
17137 } |
17047 if (ret == ERROR_SUCCESS) { |
17138 if (ret == ERROR_SUCCESS) { |
17048 RETURN (true); |
17139 RETURN (true); |