> From: "Zinn, Helmut" <Helmut.Zinn{([at]})nowhere.xy> To: blackbox{([at]})nowhere.xy
> Subject: Reading Windows-Registry from BlackBox
> Date: Fri, 9 Mar 2001 08:55:49 +0100
> does anybody know how two read the whole registry via a BlackBox program?
>
Hi Helmut,
vielleicht hilft folgendes weiter (aus dem EthOberon for
Windows, Rel. 2.4). Wahrscheinlich wird es ein bischen
Massage brauchen, aber ...
Das nächste ist folgender Link auf eine Help-Datei zur
Windows API Dokumentation:
http://www.cs.virginia.edu/~lcc-win32/
bzw:
ftp://ftp.cs.virginia.edu/pub/lcc-win32/win32hlp.exe
Alles Gute weiterhin
Bernhard
(* Copyright (c) 1994 - 2000 Emil J. Zeller *)
MODULE Registry; (** non-portable / source: Win32.Registry.Mod *) (* ejz *)
IMPORT SYSTEM, Kernel32, Kernel, ADVAPI32;
(** This module provides an interface to the Windows registry. To read Oberon
configuration data stored in the registry use Oberon.OpenScanner and the commands
System.Set and System.Get . *)
CONST
(** root keys *)
ClassesRoot* = ADVAPI32.HKEYClassesRoot; CurrentUser* = ADVAPI32.HKEYCurrentUser;
(** result codes *)
Done* = 0; Failed* = 1; NotFound* = 2;
TYPE
PathEnumerator* = PROCEDURE (path: ARRAY OF CHAR);
KeyValueEnumerator* = PROCEDURE (key, value: ARRAY OF CHAR);
VAR
oberonRoot*, (** root path for all Oberon settings *)
oberonSystem*: ARRAY Kernel32.MaxPath OF CHAR; (** path for System settings *)
res*: LONGINT; (** Done, Failed, NotFound *)
stamp*: LONGINT; (** Time stamp of last modification to the registry. *)
hFile: Kernel32.HANDLE; logfile: BOOLEAN;
PROCEDURE Append(VAR to: ARRAY OF CHAR; this: ARRAY OF CHAR);
VAR i, j, l: LONGINT;
BEGIN
i := 0; WHILE to[i] # 0X DO INC(i) END;
l := LEN(to)-1; j := 0;
WHILE (i < l) & (this[j] # 0X) DO
to[i] := this[j]; INC(i); INC(j)
END;
to[i] := 0X
END Append;
PROCEDURE AppendCh(VAR to: ARRAY OF CHAR; this: CHAR);
VAR i: LONGINT;
BEGIN
i := 0; WHILE to[i] # 0X DO INC(i) END;
IF i < (LEN(to)-1) THEN
to[i] := this; to[i+1] := 0X
END
END AppendCh;
(** Get the full path to Oberon settings stored under key.
Note: Oberon uses CurrentUser as root key. *)
PROCEDURE OberonPath*(path: ARRAY OF CHAR; VAR fullPath: ARRAY OF CHAR);
BEGIN
COPY(oberonRoot, fullPath); AppendCh(fullPath, "\"); Append(fullPath, path)
END OberonPath;
(** Set a key/value pair, key = "" sets the default value for path. *)
PROCEDURE SetKeyValue*(root: ADVAPI32.HKEY; path, key, value: ARRAY OF CHAR);
VAR hKey: ADVAPI32.HKEY; i: LONGINT;
BEGIN
IF ADVAPI32.RegCreateKeyEx(root, path, 0, NIL, ADVAPI32.RegOptionNonVolatile,
{ADVAPI32.KeySetValue, ADVAPI32.KeyCreateSubKey}, NIL, hKey, NIL) # ADVAPI32.Success
THEN
res := NotFound; RETURN
END;
i := 0; WHILE value[i] # 0X DO INC(i) END; INC(i);
IF ADVAPI32.RegSetValueEx(hKey, key, 0, ADVAPI32.RegSZ, value, i) = ADVAPI32.Success
THEN
INC(stamp); res := Done
ELSE
res := Failed
END;
ADVAPI32.RegCloseKey(hKey)
END SetKeyValue;
(** Retrieve the value stored under key. use key = "" to retrieve the default value for
path. *) PROCEDURE GetKeyValue*(root: ADVAPI32.HKEY; path, key: ARRAY OF CHAR; VAR value:
ARRAY OF CHAR);
VAR hKey: ADVAPI32.HKEY; type, len, ret: LONGINT; buf: POINTER TO ARRAY OF CHAR;
BEGIN
IF ADVAPI32.RegOpenKeyEx(root, path, 0, {ADVAPI32.KeyQueryValue}, hKey) #
ADVAPI32.Success THEN
res := NotFound; RETURN
END;
len := LEN(value); type := ADVAPI32.RegNone;
ret := ADVAPI32.RegQueryValueEx(hKey, key, NIL, type, value, len);
IF (type # ADVAPI32.RegSZ) OR (ret # ADVAPI32.Success) THEN
IF (type = ADVAPI32.RegSZ) & (ret = ADVAPI32.ErrorMoreData) THEN
NEW(buf, len+1);
ADVAPI32.RegQueryValueEx(hKey, key, NIL, type, buf^, len);
COPY(buf^, value); res := Done
ELSE
res := NotFound
END
ELSE
res := Done
END;
ADVAPI32.RegCloseKey(hKey)
END GetKeyValue;
(** Delete key and its value, key = "" deletes the default value for path. *)
PROCEDURE DeleteKeyValue*(root: ADVAPI32.HKEY; path, key: ARRAY OF CHAR);
VAR hKey: ADVAPI32.HKEY;
BEGIN
IF ADVAPI32.RegOpenKeyEx(root, path, 0, {ADVAPI32.KeySetValue}, hKey) # ADVAPI32.Success
THEN
res := NotFound; RETURN
END;
IF ADVAPI32.RegDeleteValue(hKey, key) = ADVAPI32.Success THEN
INC(stamp); res := Done
ELSE
res := NotFound
END;
ADVAPI32.RegCloseKey(hKey)
END DeleteKeyValue;
(** Recursive delete all sub-paths, keys and values in path.
Note: be very careful when using this procedure!!! *)
PROCEDURE DeletePath*(root: ADVAPI32.HKEY; path: ARRAY OF CHAR);
VAR buffer: ARRAY Kernel32.MaxPath OF CHAR; hKey: ADVAPI32.HKEY; size: LONGINT;
BEGIN
IF ADVAPI32.RegOpenKeyEx(root, path, 0, ADVAPI32.KeyAllAccess, hKey) # ADVAPI32.Success
THEN
res := NotFound; RETURN
END;
size := Kernel32.MaxPath;
WHILE ADVAPI32.RegEnumKeyEx(hKey, 0, buffer, size, NIL, NIL, NIL, NIL) =
ADVAPI32.Success DO
DeletePath(hKey, buffer);
IF res # Done THEN
ADVAPI32.RegCloseKey(hKey); RETURN
END;
size := Kernel32.MaxPath
END;
ADVAPI32.RegCloseKey(hKey);
IF ADVAPI32.RegDeleteKey(root, path) = ADVAPI32.Success THEN
INC(stamp); res := Done
ELSE
res := Failed
END
END DeletePath;
(** Enumerate all sub-paths in path. *)
PROCEDURE EnumeratePath*(root: ADVAPI32.HKEY; path: ARRAY OF CHAR; enum: PathEnumerator);
VAR subPath: ARRAY Kernel32.MaxPath OF CHAR; hKey: ADVAPI32.HKEY; ret, i, size: LONGINT;
BEGIN
ret := ADVAPI32.RegOpenKeyEx(root, path, 0, {ADVAPI32.KeyEnumerateSubKeys}, hKey);
IF ret # ADVAPI32.Success THEN
res := NotFound; RETURN
END;
i := 0;
WHILE ret = ADVAPI32.Success DO
size := Kernel32.MaxPath;
ret := ADVAPI32.RegEnumKeyEx(hKey, i, subPath, size, NIL, NIL, NIL, NIL);
IF ret = ADVAPI32.Success THEN enum(subPath) END;
INC(i)
END;
ADVAPI32.RegCloseKey(hKey); res := Done
END EnumeratePath;
(** Enumerate all key/value pairs in path.*)
PROCEDURE EnumerateKeyValue*(root: ADVAPI32.HKEY; path: ARRAY OF CHAR; enum:
KeyValueEnumerator);
VAR
key, value: ARRAY Kernel32.MaxPath OF CHAR; hKey: ADVAPI32.HKEY;
ret, i, type, kLen, vLen: LONGINT;
BEGIN
ret := ADVAPI32.RegOpenKeyEx(root, path, 0, {ADVAPI32.KeyQueryValue}, hKey);
IF ret # ADVAPI32.Success THEN
res := NotFound; RETURN
END;
i := 0;
WHILE ret = ADVAPI32.Success DO
kLen := Kernel32.MaxPath; vLen := Kernel32.MaxPath; type := ADVAPI32.RegNone;
ret := ADVAPI32.RegEnumValue(hKey, i, key, kLen, NIL, type, value, vLen);
IF (ret = ADVAPI32.Success) & (type = ADVAPI32.RegSZ) THEN enum(key, value) END;
INC(i)
END;
ADVAPI32.RegCloseKey(hKey); res := Done
END EnumerateKeyValue;
PROCEDURE*OutputFileString(VAR str: ARRAY OF CHAR);
VAR n: LONGINT;
BEGIN
n := 0; WHILE str[n] # 0X DO INC(n) END;
Kernel32.WriteFile(hFile, str, n, n, NIL);
IF logfile THEN Kernel32.FlushFileBuffers(hFile) END
END OutputFileString;
PROCEDURE InitConsole();
VAR rect: Kernel32.SmallRect; file: ARRAY 260 OF CHAR; con: ARRAY 64 OF CHAR; i, j:
LONGINT;
BEGIN
Kernel32.OutputString := NIL; logfile := FALSE; hFile := Kernel32.InvalidHandleValue;
GetKeyValue(CurrentUser, oberonSystem, "Console", con);
IF res = Done THEN
IF con[0] = '"' THEN con[0] := con[1] END;
IF CAP(con[0]) = "C" THEN (* console window *)
con := "ETH Oberon - Console";
Kernel32.AllocConsole(); Kernel32.SetConsoleTitle(con);
hFile := Kernel32.GetStdHandle(Kernel32.STDOutput);
Kernel32.SetConsoleScreenBufferSize(hFile, 80 + ASH(1024, 16));
rect.top := 0; rect. left := 0; rect.bottom := 24; rect.right := 79;
Kernel32.SetConsoleWindowInfo(hFile, Kernel32.True, rect)
ELSIF CAP(con[0]) = "S" THEN (* standard output -> requires CUI*)
hFile := Kernel32.GetStdHandle(Kernel32.STDOutput)
ELSIF CAP(con[0]) = "F" THEN (* log file *)
con := "Oberon.Log"; logfile := TRUE;
Kernel32.GetModuleFileName(Kernel.hInstance, file, 260);
i := 0; j := 0;
WHILE file[i] # 0X DO
IF file[i] = "\" THEN j := i+1 END;
INC(i)
END;
file[j] := 0X; i := 0;
WHILE con[i] # 0X DO
file[j] := con[i]; INC(i); INC(j)
END;
file[j] := 0X;
hFile := Kernel32.CreateFile(file, {Kernel32.GenericWrite}, {Kernel32.FileShareRead},
NIL, Kernel32.CreateAlways, {Kernel32.FileAttributeNormal}, Kernel32.NULL); i := 1;
WHILE (i <= 9) & (hFile = Kernel32.InvalidHandleValue) DO
file[j] := CHR(i+ORD("0")); file[j+11] := 0X;
hFile := Kernel32.CreateFile(file, {Kernel32.GenericWrite}, {Kernel32.FileShareRead},
NIL, Kernel32.CreateAlways, {Kernel32.FileAttributeNormal}, Kernel32.NULL); INC(i)
END
END;
IF hFile # Kernel32.InvalidHandleValue THEN
Kernel32.OutputString := OutputFileString
ELSIF (CAP(con[0]) # "N") & (Kernel32.OutputString = NIL) THEN (* debugger *)
Kernel32.OutputString := Kernel32.OutputDebugString
END
ELSE
Kernel32.OutputString := Kernel32.OutputDebugString
END;
Kernel.InstallTermHandler(ShutdownConsole)
END InitConsole;
PROCEDURE *ShutdownConsole();
BEGIN
IF logfile & (hFile # Kernel32.InvalidHandleValue) THEN
Kernel32.CloseHandle(hFile); hFile := Kernel32.InvalidHandleValue
END;
Kernel32.OutputString := Kernel32.OutputDebugString
END ShutdownConsole;
PROCEDURE Init();
VAR
file, name, value, software, version: ARRAY Kernel32.MaxPath OF CHAR;
buf: POINTER TO ARRAY OF SYSTEM.BYTE; adr: Kernel32.ADDRESS; len, i: LONGINT; ch: CHAR;
BEGIN
res := Done; stamp := 0;
Kernel32.GetModuleFileName(Kernel.hInstance, file, Kernel32.MaxPath);
len := ADVAPI32.GetFileVersionInfoSize(file, NIL); NEW(buf, len);
ADVAPI32.GetFileVersionInfo(file, 0, len, buf^);
ADVAPI32.VerQueryValue(buf^, "\StringFileInfo\040904e4\FileDescription", adr, len);
IF len >= Kernel32.MaxPath THEN HALT(99) END;
SYSTEM.MOVE(adr, SYSTEM.ADR(software), len);
ADVAPI32.VerQueryValue(buf^, "\StringFileInfo\040904e4\FileVersion", adr, len);
IF len >= Kernel32.MaxPath THEN HALT(99) END;
SYSTEM.MOVE(adr, SYSTEM.ADR(version), len);
(* cmd { "-" name [ "=" value ] } *)
name := ""; i := 0;
adr := Kernel32.GetCommandLine();
REPEAT
SYSTEM.GET(adr, ch); INC(adr);
IF ch = "-" THEN
value[i] := 0X; i := 0;
IF name = "Registry" THEN COPY(value, version) END
ELSIF ch = "=" THEN
value[i] := 0X; i := 0; COPY(value, name)
ELSIF ch > " " THEN
value[i] := ch; INC(i)
ELSE
value[i] := 0X
END
UNTIL ch = 0X;
IF (i > 0) & (name = "Registry") THEN
value[i] := 0X; COPY(value, version)
END;
oberonRoot := "Software\"; Append(oberonRoot, software);
AppendCh(oberonRoot, "\"); Append(oberonRoot, version);
OberonPath("System", oberonSystem)
END Init;
BEGIN
Init(); InitConsole()
END Registry.
Received on Fri Mar 09 2001 - 07:29:29 UTC