Win32OperatingSystem.st
changeset 4234 062a03e296a0
parent 4233 a66b78f9a1b0
child 4235 88c018e5374d
--- a/Win32OperatingSystem.st	Thu May 27 18:13:23 1999 +0200
+++ b/Win32OperatingSystem.st	Thu May 27 20:04:42 1999 +0200
@@ -6943,11 +6943,9 @@
 			 &modificationTime) == ERROR_SUCCESS) {
 	    nameBuffer[nameSize] = '\0';
 	    classNameBuffer[classNameSize] = '\0';
-printf("name=%s class=%s\n", nameBuffer, classNameBuffer);
 	    subKeyName = __MKSTRING(nameBuffer);
 	    subKeyClassName = __MKSTRING(classNameBuffer);
 	} else {
-printf("RegEnumKey failed\n");
 	}
     }
 %}.
@@ -6994,6 +6992,331 @@
      top := self key:'HKEY_LOCAL_MACHINE'.
      sub := top subKeyNamed:'Software'
     "
+!
+
+createSubKeyNamed:subKeyString
+    "create a new key below mySelf and return a new registry entry for it.
+     If it already exists, return it.
+     Return nil if the new key cannot be created."
+
+    |newEntry subHandle|
+
+%{
+    HKEY myKey, subKey = 0;
+
+    if (__isExternalAddress(__INST(handle)) 
+     && (__isString(subKeyString) || __isSymbol(subKeyString))) {
+	myKey = (HKEY)__externalAddressVal(__INST(handle));
+	if (RegCreateKey(myKey, __stringVal(subKeyString), &subKey) == ERROR_SUCCESS) {
+	    subHandle = __MKEXTERNALADDRESS(subKey);
+	}
+    }
+%}.
+    subHandle notNil ifTrue:[
+	newEntry := self class basicNew 
+			setHandle:subHandle 
+			path:(path , self class separator asString , subKeyString).
+	Lobby register:newEntry.
+	^ newEntry.
+    ].
+    ^ nil
+
+    "
+     |top sub|
+
+     top := self key:'HKEY_LOCAL_MACHINE'.
+     sub := top createSubKeyNamed:'FooBarBaz'.
+    "
+!
+
+deleteSubKeyNamed:subKeyString
+    "delete a key below mySelf.
+     Return true on success."
+
+    |newEntry subHandle|
+
+%{
+    HKEY myKey;
+
+    if (__isExternalAddress(__INST(handle)) 
+     && (__isString(subKeyString) || __isSymbol(subKeyString))) {
+	myKey = (HKEY)__externalAddressVal(__INST(handle));
+	if (RegDeleteKey(myKey, __stringVal(subKeyString)) == ERROR_SUCCESS) {
+	    RETURN (true);
+	}
+    }
+%}.
+    ^ false
+
+    "
+     |top sub|
+
+     top := self key:'HKEY_LOCAL_MACHINE'.
+     sub := top createSubKeyNamed:'FooBarBaz'.
+     top deleteSubKeyNamed:'FooBarBaz'.
+    "
+! !
+
+!Win32OperatingSystem::RegistryEntry methodsFor:'accessing values'!
+
+valueNamed:aValueName
+    "retrieve a value; the returned object depends upon the type:
+	REG_BINARY      -> ByteArray
+	REG_SZ          -> String
+	REG_MULTI_SZ    -> Array of strings
+	REG_DWORD       -> Integer
+	REG_NONE        -> nil
+    "
+
+    |data stringArray|
+%{
+    HKEY myKey;
+    DWORD valueType;
+    union {
+	DWORD dWord;
+	unsigned char dWordBytes[4];
+	unsigned char smallDataBuffer[256];
+    } quickData;
+    int val;
+    DWORD dataSize = sizeof(quickData);
+    unsigned char *dataBuffer = NULL;
+
+    if (__isExternalAddress(__INST(handle)) 
+     && (__isString(aValueName) || __isSymbol(aValueName))) {
+	int ret;
+
+	myKey = (HKEY)__externalAddressVal(__INST(handle));
+
+	/*
+	 * try to get it with one call ...
+	 */
+	ret = RegQueryValueEx(myKey, __stringVal(aValueName), 
+			 NULL,
+			 &valueType,
+			 &quickData, &dataSize);
+
+	if (ret == ERROR_MORE_DATA) {
+	    /*
+	     * nope - need another one ...
+	     */
+	    switch (valueType) {
+		case REG_BINARY:
+		case REG_MULTI_SZ:
+		    data = __BYTEARRAY_UNINITIALIZED_NEW_INT(dataSize);
+		    dataBuffer = __ByteArrayInstPtr(data)->ba_element;
+		    break;
+		case REG_SZ:
+		    data = __MKEMPTYSTRING(dataSize-1);
+		    dataBuffer = __stringVal(data);
+		    break;
+	    }
+	    if (dataBuffer) {
+		ret = RegQueryValueEx(myKey, __stringVal(aValueName), 
+				 NULL,
+				 &valueType,
+				 dataBuffer, &dataSize);
+	    }
+	}
+
+	if (ret == ERROR_SUCCESS) {
+	    switch (valueType) {
+		case REG_NONE:
+		    RETURN (nil);
+
+		case REG_BINARY:
+		    /*
+		     * did we get it with the first call ?
+		     */
+		    if (! dataBuffer) {
+			data = __MKBYTEARRAY(quickData.smallDataBuffer, dataSize);    
+		    }
+		    RETURN (data);
+
+		case REG_SZ:
+		case REG_EXPAND_SZ:
+		    /*
+		     * did we get it with the first call ?
+		     */
+		    if (! dataBuffer) {
+			data = __MKSTRING_L(quickData.smallDataBuffer, dataSize-1);    
+		    }
+		    RETURN (data);
+
+#if 0
+		case REG_DWORD:
+		    /* int in native format */
+		    RETURN (__MKUINT(quickData.dWord));
+#endif
+		case REG_DWORD_LITTLE_ENDIAN:
+		    val = quickData.dWordBytes[3];
+		    val = (val << 8) | quickData.dWordBytes[2];
+		    val = (val << 8) | quickData.dWordBytes[1];
+		    val = (val << 8) | quickData.dWordBytes[0];
+		    RETURN (__MKUINT(val));
+
+		case REG_DWORD_BIG_ENDIAN:
+		    val = quickData.dWordBytes[0];
+		    val = (val << 8) | quickData.dWordBytes[1];
+		    val = (val << 8) | quickData.dWordBytes[2];
+		    val = (val << 8) | quickData.dWordBytes[3];
+		    RETURN (__MKUINT(val));
+
+		case REG_MULTI_SZ:
+		    {
+			char *cp, *cp0;
+			int ns = 0, i;
+
+			cp0 = dataBuffer ? dataBuffer : quickData.smallDataBuffer;
+			cp = cp0;
+			while (*cp) {
+			    while (*cp++) ;;
+			    ns++;
+			    cp++;
+			}
+			stringArray = __ARRAY_NEW_INT(ns);
+
+			i = 0;
+			while (*cp0) {
+			    OBJ s;
+
+			    cp = cp0;
+			    while (*cp++) ;;
+			    s = __MKSTRING(cp0);
+			    __ArrayInstPtr(stringArray)->a_element[i] = s;
+			    __STORE(stringArray, s);
+			    cp++;
+			    cp0 = cp;
+			    i++;
+			}
+			RETURN (stringArray);
+		    }
+	    }
+	}
+    }
+%}.
+    ^ nil
+
+    "
+     |key|
+
+     key := self key:'HKEY_LOCAL_MACHINE\SOFTWARE\eXept\Smalltalk/X'.
+     key valueNamed:'CurrentVersion'
+    "
+!
+
+valueNamed:aValueName put:datum
+    "store a value; the value type depends upon the stored value:
+	ByteArray       -> REG_BINARY
+	String          -> REG_SZ 
+	Array of string -> REG_MULTI_SZ  
+	Integer         -> REG_DWORD  
+	nil             -> REG_NONE  
+    "
+
+    |data stringArray|
+%{
+    HKEY myKey;
+    DWORD valueType = -1;
+    int val;
+    DWORD dataSize = -1;
+    unsigned char *dataPointer = NULL;
+    int datumOk = 1, mustFreeData = 0;
+
+    if (__isExternalAddress(__INST(handle)) 
+     && (__isString(aValueName) || __isSymbol(aValueName))) {
+	int ret;
+	OBJ cls;
+
+	myKey = (HKEY)__externalAddressVal(__INST(handle));
+
+	if (datum == nil) {
+	    valueType = REG_NONE;
+	    dataSize = 0;
+	} else if (__isSmallInteger(datum)) {
+	    valueType = REG_DWORD;
+	    val = __intVal(datum);
+	    dataPointer = (unsigned char *)(&val);
+	    dataSize = sizeof(val);
+	} else if (__isString(datum) || __isSymbol(datum)) {
+	    valueType = REG_SZ;
+	    dataPointer = __stringVal(datum);
+	    dataSize = __stringSize(datum) + 1;
+	} else if (__Class(datum) == ByteArray) {
+	    valueType = REG_BINARY;
+	    dataPointer = __ByteArrayInstPtr(datum)->ba_element;
+	    dataSize = __byteArraySize(datum);
+	} else if (__Class(datum) == LargeInteger) {
+	    valueType = REG_DWORD;
+	    val = __longIntVal(datum);
+	    if (val) {
+		dataPointer = (unsigned char *)(&val);
+		dataSize = sizeof(val);
+	    } else {
+		datumOk = 0;
+	    }
+	} else if (__Class(datum) == Array) {
+	    int i = 0, ns = 0, totalSize = 0;
+
+	    valueType = REG_MULTI_SZ;
+
+	    /*
+	     * must allocate a local buffer
+	     * find size ...
+	     */
+	    for (i=0; i<__arraySize(datum); i++) {
+		OBJ s = __ArrayInstPtr(datum)->a_element[i];
+
+		if (__isString(datum) || __isSymbol(datum)) {
+		    totalSize += __stringSize(datum) + 1;
+		} else {
+		    datumOk = 0;
+		    break;
+		}
+		ns++;
+	    }
+	    if (datumOk) {
+		char *cp;
+
+		/*
+		 * allocate and fill...
+		 */
+		totalSize ++;
+		dataPointer = (char *)(malloc(totalSize));
+		mustFreeData = 1;
+		cp = dataPointer;
+		for (i=0; i<__arraySize(datum); i++) {
+		    OBJ s = __ArrayInstPtr(datum)->a_element[i];
+
+		    strcpy(cp, __stringVal(s));
+		    cp += __stringSize(datum);
+		    *cp++ = '\0';
+		}
+		*cp++ = '\0';
+		dataSize = totalSize;
+	    }
+	} else {
+	    datumOk = 0;
+	}
+
+	if (datumOk) {
+	    ret = RegSetValueEx(myKey, __stringVal(aValueName), 
+				0, valueType,
+				dataPointer, dataSize);
+	    if (mustFreeData) {
+		free(dataPointer);
+	    }
+	    return ((ret == ERROR_SUCCESS) ? true : false);
+	}
+    }
+%}.
+    ^ false
+
+    "
+     |key|
+
+     key := self key:'HKEY_LOCAL_MACHINE\SOFTWARE\eXept\Smalltalk/X'.
+     key valueNamed:'CurrentVersion' put:'3.5.2'
+    "
 ! !
 
 !Win32OperatingSystem::RegistryEntry methodsFor:'enumeration'!
@@ -7119,6 +7442,6 @@
 !Win32OperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.60 1999-05-27 16:13:23 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.61 1999-05-27 18:04:42 cg Exp $'
 ! !
 Win32OperatingSystem initialize!