--- 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!