Win32OperatingSystem.st
branchjv
changeset 23758 8fcc24554bc7
parent 23614 1c6f89bd0de6
child 23759 3db8d48a8cb1
equal deleted inserted replaced
23614:1c6f89bd0de6 23758:8fcc24554bc7
 16531     "
 16531     "
 16532      (self key:'HKEY_CLASSES_ROOT\MicrosoftWorks.WordProcessor\CLSID') defaultValue
 16532      (self key:'HKEY_CLASSES_ROOT\MicrosoftWorks.WordProcessor\CLSID') defaultValue
 16533     "
 16533     "
 16534 !
 16534 !
 16535 
 16535 
 16536 defaultValue:datum
 16536 defaultValue:data
 16537     "store a value; the value type depends upon the stored value:
 16537     "store a value; the value type depends upon the stored value:
 16538 	ByteArray       -> REG_BINARY
 16538 	ByteArray       -> REG_BINARY
 16539 	String          -> REG_SZ
 16539 	String          -> REG_SZ
 16540 	Array of string -> REG_MULTI_SZ
 16540 	Array of string -> REG_MULTI_SZ
 16541 	Integer         -> REG_DWORD
 16541 	Integer         -> REG_DWORD
 16542 	nil             -> REG_NONE
 16542 	nil             -> REG_NONE
 16543     "
 16543     "
 16544 
 16544 
 16545     ^ self valueNamed:'' put:datum
 16545     ^ self valueNamed:'' put:data
 16546 
 16546 
 16547     "
 16547     "
 16548      (self key:'HKEY_CLASSES_ROOT\MicrosoftWorks.WordProcessor\CLSID') defaultValue
 16548      (self key:'HKEY_CLASSES_ROOT\MicrosoftWorks.WordProcessor\CLSID') defaultValue
 16549     "
 16549     "
 16550 !
 16550 !
 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);