The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,861 other subscribers

Archive for the ‘History’ Category

Some VMS and DCL history links

Posted by jpluimers on 2021/05/25

Last week, I wrote about a bit of my command-line and scripting history at I wanted to know the loaded DLLs in a process like Process Explorer shows, but from the console: Sysinternals ListDLLs to the rescue.

Since information about VMS and DCL is harder to find nowadays, I saved some information in the wayback machine:

By now, there should be a good x86_64 version of OpenVMS, so this is also a reminder to self to see if that can run as a VM and is affordable enough to do some experimentation with.

–jeroen

Posted in Development, History, Scripting, Software Development | Leave a Comment »

I wanted to know the loaded DLLs in a process like Process Explorer shows, but from the console: Sysinternals ListDLLs to the rescue

Posted by jpluimers on 2021/05/20

In Windows, historically most people approach investigation GUI first. Having turned 50 a while ago, I am no exception.

My real roots however are on the command-line and scripting: roughly 1980s Apple DOS, CP/M, SunOS (yay sh Bourne shell!), MS-DOS, 4DOS, and VAX/VMS (yay DCL shell!), from the 1990s on, some Solaris, a little bit of AIX, HP-UX and quite a bit of Linux, MacOS (né OS/XMac OS),  and some BSD descendants derivatives (SunOS, AIX and MacOS are based on the Berkeley Software Distribution), and this century a more growing amount of PowerShell).

So I was glad to find out the makers of Process Explorer also made [WayBack] ListDLLs – Windows Sysinternals | Microsoft Docs (via windows get dlls loaded in process – Google Search)

List all the DLLs that are currently loaded, including where they are loaded and their version numbers.

ListDLLs is a utility that reports the DLLs loaded into processes. You can use it to list all DLLs loaded into all processes, into a specific process, or to list the processes that have a particular DLL loaded. ListDLLs can also display full version information for DLLs, including their digital signature, and can be used to scan processes for unsigned DLLs.

Usage

listdlls [-r] [-v | -u] [processname|pid]
listdlls [-r] [-v] [-d dllname]

Parameter Description
processname Dump DLLs loaded by process (partial name accepted).
pid Dump DLLs associated with the specified process id.
dllname Show only processes that have loaded the specified DLL.
-r Flag DLLs that relocated because they are not loaded at their base address.
-u Only list unsigned DLLs.
-v Show DLL version information.

Download: [WayBack] ListDlls.zip.

Now it is much easier to generate a draft deploy list of DLLs (and for Delphi: BPLs) based on a process running on a development machine.

Example output (the -r flags relocation warnings; the first part is the [WayBack] shim that Chocolatey created around the second which is from SysInternals):

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, History, Software Development, Windows Development | Leave a Comment »

Much Turbo Pascal history (via What is a Delphi DCU file? – Stack Overflow)

Posted by jpluimers on 2021/05/19

Editing [WayBack] What is a Delphi DCU file? – Stack Overflow for more historic correctness and adding links prompted me to archive some older material and search for some more, basically because while historically very relevant, link rot makes a lot of that stuff harder and harder to find.

The legendary full page colour advert published in the 12th 1983 issue of Byte Magazine on page 456 is at the bottom of this post (Many BYTE magaine issues have been archived at https://archive.org/details/byte-magazine).

The smaller version below is from WayBack: Sip from the Firehose : November 2008 marks the 25th anniversary of Turbo Pascal v1.0! (this article is not available on the Embarcadero or Idera site any more).

I also included more adverts in reverse chronological order at the end:

The last two via [WayBack] saundby.com: Software for the Ampro Little Board.

--jeroen

Read the rest of this entry »

Posted in Conference Topics, Conferences, CP/M, Delphi, Development, Event, History, MS-DOS, Pascal, Power User, Software Development, Turbo Pascal, UCSD Pascal, Z80 | Leave a Comment »

Certified Secure – XS4ALL Challenge

Posted by jpluimers on 2021/04/23

This was a cool one a few years back: [WayBack] Certified Secure – XS4ALL Challenge

–jeroen

Posted in Fun, History, Power User, Security | Leave a Comment »

The Architecture of Open Source Applications: Sendmail

Posted by jpluimers on 2021/04/12

Cool historic article: [WayBack] The Architecture of Open Source Applications: Sendmail by Eric Allman.

It is Chapter 17 of this book [WayBack]:

The Architecture of
Open Source Applications

Amy Brown and Greg Wilson (eds.)
ISBN 978-1-257-63801-7

I totally missed that book being published in 2014.

Great historic read!

–jeroen

Posted in *nix, *nix-tools, History, Power User, sendmail | Leave a Comment »

em-dosbox – Windows 3.11 on the Web

Posted by jpluimers on 2021/03/22

Cool: [Archive.is/WayBack] em-dosbox – Windows 3.11 on the Web.

Via [WayBack] JRWR – Forrest F. on Twitter: “I love this thing, http://vrcade.io/win311 Boots into Windows 3.11 with a internet connection (over a fake modem!)”

–jeroen

Read the rest of this entry »

Posted in History, Windows, Windows 3.11 | 2 Comments »

You are likely to be eaten by a grue! #NerdStitch cross stitch project- Zork 1 (Apple II version)

Posted by jpluimers on 2021/03/08

This is so cool: [WayBack] Glenda 🐰 on Twitter: “You are likely to be eaten by a grue! Just finished a new #NerdStitch cross stitch project- Zork 1 (Apple II version). The second adventure game I ever played. #zork #EatenByAGrue #apple2 #Infocom” .

That cursor!

Read the rest of this entry »

Posted in Fun, History | Leave a Comment »

Delphi XE7 introduced const support for dynamic arrays; prior versions used [] only for sets.

Posted by jpluimers on 2021/03/02

A few things to learn from [WayBack] delphi – Constant array of cardinal produces error ‘Constant expression violates subrange bounds” – Stack Overflow:

  • Delphi XE7 introduced compiler support for const dynamic arrays.
  • Compiler errors can completely put you in the wrong direction.
  • Command-line compilers indicate BDS versions which can confuse you for the exact product versions (thanks Rudy Velthuis for correcting that).

Sets

In this case, Delphi XE6 and below regard the [...] construct for constants as a set of Byte of which the maximum value is 255.

So this already fails with E1012 Constant expression violates subrange bounds, even though 257 perfectly fits the subrange of Cardinal:

const
  CardinalArray: array of Cardinal = [257];

The documentation (which has not changed since Delphi 2007) puts you in a totally different direction: [WayBack] x1012: Constant expression violates subrange bounds

x1012: Constant expression violates subrange bounds

This error message occurs when the compiler can determine that a constant is outside the legal range. This can occur for instance if you assign a constant to a variable of subrange type.

program Produce;
var
  Digit: 1..9;
begin
  Digit := 0;  (*Get message: Constant expression violates subrange bounds*)
end.
program Solve;
var
  Digit: 0..9;
begin
  Digit := 0;
end.

The alternative is to use a non-dynamic array that uses parenthesis instead of square brackets for initialisation:

const
  CardinalArray: array[0..0] of Cardinal = (257);

Dynamic arrays

Const initialisation of dynamic arrays only made a tick mark on the box in [Archive.is] What’s New in Delphi and C++Builder XE7 – RAD Studio: String-Like Operations Supported on Dynamic Arrays, but in fact this code works in Delphi XE7 and up just fine:

program Cardinals;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

const
  CardinalArray: array of Cardinal = [257]; // fails until Delphi XE6 with "E1012 Constant expression violates subrange bounds"

const
  ANSICOLORS: array of Cardinal = [
    $000000,//0
    $800000,//1, compilation error starts with this value
    $008000,//2
    $808000,//3
    $000080,//4
    $800080,//5
    $008080,//6
    $D0D0D0,//7
    $3F3F3F,//8
    $FF0000,//9
    $00FF00,//A
    $FFFF00,//B
    $0000FF,//C
    $FF00FF,//D
    $00FFFF,//E
    $FFFFFF];//F

var
  AnsiColor: Cardinal;

begin
  try
    for AnsiColor in AnsiColors do
      Writeln(Format('$%6.6x', [AnsiColor]));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Output:

$000000
$800000
$008000
$808000
$000080
$800080
$008080
$D0D0D0
$3F3F3F
$FF0000
$00FF00
$FFFF00
$0000FF
$FF00FF
$00FFFF
$FFFFFF

Note that dynamic arrays are unlike regular arrays, which for instance means that nesting them can get you into a different uncharted territory when using multiple dimensions.

Unlike an array, a dynamic array has notice of length. Which means it needs extra memory for it.

So where regular multi-dimensional arrays are blocks of memory. Multi-dimensional dynamic arrays are a dynamic array on each dimension level, which means extra length keeping, and the seemingly odd Copy behaviour described in [WayBack] Things that make you go ‘urgh’… | Delphi Haven:

What’s the flaw in this test code?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
program Project1;
{$APPTYPE CONSOLE}
var
  Arr1, Arr2: array of array of Integer;
  I, J: Integer;
begin
  SetLength(Arr1, 5, 5);
  for I := 0 to 4 do
    for J := 0 to 4 do
      Arr1[I, J] := I * J;
  Arr2 := Copy(Arr1);
  for I := 0 to 4 do
    for J := 0 to 4 do
      if Arr2[I, J] <> Arr1[I, J] then
      begin
        WriteLn('Nope');
        Break;
      end;
  Write('Press ENTER to exit...');
  ReadLn;
end.

with these comments

Rudy Velthuis:

Dynarrays are single-dimensional. One can get the illusion of multi-dimensionality because the Delphi syntax lets you access them using a[5,6] syntax, and SetLength takes more than one dimension parameter, and indeed, the docs even mention multi-dimensional, but that doesn’t change anything. You don’t have a multi-dimensional dynarray, you have a dynarray than contains other dynarrays. Each of these is one-dimensional. IOW, you don’t have one array, you have a cluster of dynarrays.

Copy() handles dynarrays. These are one-dimensional, so it only does one dimension (what else?). IOW, the behaviour is correct and actually well known.

Franćois:

I’m with you Chris. I don’t think this is “well known”, maybe because mono-dimensional dynamic arrays are probably used much more than multidimensional ones.
And also, the documentation is blaringly silent on this behavior. (credit to DelphiBasics to mention it: http://www.delphibasics.co.uk/RTL.asp?Name=Array)
The more visibility it gets, the less bugs we’ll have to deal with.

IMO, I don’t see why “copy” would not behave recursively and copy each sub-array as well. It seems that it is the intuitive behavior people tend to expect in the 1st place. (either nothing at all like Arr1:=Arr2, or a full recursive copy)
But since it’s been like that for some time, I doubt it can change for compatibility reasons (breaking code relying explicitly on this behavior).

Chris:

Thanks for the support! On my reading, the help strongly implies the behaviour I was expecting, and therefore, implies the actual behaviour to be a bug. Specifically, the entry for Copy (http://docwiki.embarcadero.com/VCL/en/System.Copy) includes the line:

Note: When S is a dynamic array, you can omit the Index and Count parameters and Copy copies the entire array.

What could ‘the entire array’ mean? According to Rudy, this can’t mean more than one dimension because dynamic arrays aren’t multidimensional. And yet, the Delphi Language Guide talks of ‘multidimensional dynamic arrays’ quite clearly (http://docwiki.embarcadero.com/RADStudio/en/Structured_Types#Multidimensional_Dynamic_Arrays). See also the docs for SetLength (http://docwiki.embarcadero.com/VCL/en/System.SetLength).

–jeroen

Posted in Delphi, Development, History, Software Development, Undocumented Delphi | Leave a Comment »

Futurist 20 years ago “The Internet will not become a mass medium” – via littlewisehen on Twitter: “Also sprach der Zukunftsforscher… 😂”

Posted by jpluimers on 2021/03/02

Today exactly 20 years ago, a futurist indicated “The Internet will not become a mass medium”.

Source: [WayBack] littlewisehen on Twitter: “Also sprach der Zukunftsforscher… 😂 https://t.co/taNRUxZD3S”

Via:

Thomas also made this great (German) observation:

2001 war vielfach noch Modem und ISDN angesagt, Flatrates waren gerade wieder abgeschafft worden, DSL gab es in machen Gegenden, war bei 2 Mbit aber mehr als doppelt so teuer wie heute 16 Mbit. Erinnert sich noch jemand an die unsäglichen AOL-CDs, die allen Zeitschriften beilagen?
Es gab noch keine “sozialen” Netzwerke und von mobilem Internet hat man nur geträumt. Selbst dumme Handys waren noch nicht so weit verbreitet wie heute Smartphones, und es kostete richtig Geld, eines anzurufen.

Das ist noch keine 20 Jahre her, aber ich komme mir gerade vor, als ob ich die Zeit des Schwarz-Weiß-Fernsehens beschriebe.

Google Translate actually does a halfway decent job on that (see below) which I’ve edited to this:

2001 was in many cases still the era of modem and ISDN. Flat rates had just been abolished again, there was DSL available in some areas, but at 2 Mbit was more than twice as expensive as todays 16Mbit. Does anyone remember the inexpressible AOL CDs that came with all the magazines?
There were no “social” networks and you could only dream of mobile Internet. Even dumb phones were not as widespread as smartphones are today, and it costed real money to call a mobile phone.

That was only 20 years, but it just feels as describing  black and white television.

Unedited Google Translate:

Read the rest of this entry »

Posted in History | Leave a Comment »

Evil environment variables….

Posted by jpluimers on 2021/02/11

I totally agree with Nick Craver “I absolutely hate environmental variables for configuration. They’re brittle, they’re ambient, they can be changed and FUBAR any known state underneath you, they’re an attack vector, just…”.

A little event in the early 1990s made me cautious whenever I see environment variables in use.

One of my clients had a network that had to be separated into three logical areas: one for workstations communicating with a certain server and some equipment, and another for a different server and other equipment, and finally a bunch of semi-local workstations that did some peer-to-peer and specialised equipment communication.

For that era, this was a LOT of stuff to manage.

Since users always were working from the same computers, and there was very little overlap between the areas, I created a bunch of login scripts. Since this was Novell NetWare 3.x era, you only had default, system and user login scripts (see [WayBack] NetWare 3 Login Script Fundamentals), of which only system+default or system+user could be combined. No groups scripts yet (:

So I introduced an environment variable NETWORK that would hold the kind of logical network.

Boy was I surprised that a few days later, the head of administration came to me with a problem: one of his administration programs – despite no documentation mentioning anything about such a feature – suddenly asked for a license!

A few hours of phone calls and trying later, we found the culprit: that software had an undocumented feature: when the NETWORK environment variable was set, it assumed a large corporate, with a very special license feature.

That was the day, I started to be wary of environment variables.

The workaround was simple: have the program being started with a batch file, temporarily clean the NETWORK environment variable, then run the application, and finally restore the environment variable.

Inspired by two tweets I got within a few days time:

–jeroen

Read the rest of this entry »

Posted in History, Power User, Security | Leave a Comment »