Re: Reading Windows-Registry from BlackBox

From: Self <treutwein.59.Verwaltung.Uni-Muenchen>
Date: Fri, 9 Mar 2001 09:29:29 +0200

> 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

This archive was generated by hypermail 2.3.0 : Thu Sep 26 2013 - 06:27:44 UTC