Microsoft C KnowledgeBase articles online

PC Mag, January 1989

It’s weird I was discussing putting this online in a more human readable format, and then  Jeff Parsons over at the incredible full system emulation in javascript site, just did it.

As you may or not be aware of, Microsoft hit it big as a computer languages company, before they added operating systems into it’s portfolio.  And for some weird reason after the whole OS/2 divorce thing, someone decided that everything that had been painfully learned in the earlier eras should just be expunged from history.  Which is a real shame to anyone interested in Basic, Fortran, Pascal, C and MASM.  Years ago I had gone through the steps of extracting the text the only way I could figure out easily, by writing a simple TSR that would dump the contents of the text video buffer, and write it to a file, then press the page down key, and keep repeating the process. The end result being that I had then dumped the MSPL aka the Microsoft Programmer’s Library.  I had put the text into an archive, aptly named Microsoft_Programmers_Library.7z, and pretty much used grep whenever I wanted any information, and left it at that..

It’s really cool to see it slowly transitioning to more useful information.  You can read Jeff’s article Corporations Are Crappy Archivists about his quest for seemingly simple information about ancient Microsoft mice, and the archive of KB’s for Microsoft C.

One thing that is annoying is that information on CD from the late 1980’s seems to be darned near impossible to find.  I know that each generation of machines until about 2005 was exponentially larger than the previous one (post 2007 we hit the iThing world, along with most machines being ‘good enough’ for day to day usage).  I know this ad may seem insane, but Microsoft really was trying to push people to CD distributions.  As we all know that internet thing didn’t quite tickle their fancy.    Did they ever put resources like this online?  Like on BIX or Compuserve?  It seems like an ideal resource.  But I was a kid, and didn’t have that kind of money.

Awesome CD-ROM collection and drive, starting at a mere $899!

So in the interest of a bad idea, here is MSPL, aka qemu/curses in action.

Oh my god, what I have I done!?


8 bit boy & JS-DOS

A long while ago I had combined both 8bit boy & a JAVA port of DOSBox for a run in your browser extravaganza featuring a Russian version of Windows/386 and tetris (along with other Russian adapted games).  But time moves on, and flash apps fall out of favor, and well Oracle did their thing and Java is basically dead in the browser.  I had been trying to go with a javascript solution for a while, but js-dos looks better than the last few iterations.

However I haven’t figured out how to boot into a disk image, and attempting to loop to loop causes it to hang.  So I’m stuck with a simple zip of tetris and using the newer 8bit boy javascript port to hammer out some MOD’s of various theme music.  It’s not perfect but it’s better than being dead, which is where it was before this.

You can see it here.

I though this same tech would be a great way to take my GCC 1.27 build of DooM, and shove it in DOSBox and get it out into the world.  Although its far too slow for me, but it could be this crap laptop.  (my new one should be here in 7 days, but I have to travel again in 5…..).  I had also updated my DJGPP cross project to include 1.27, and rename the v1 as gcc_v139 to at least reflect what it is.

You can check out this super early GCC compiled version of DooM here.

I’ll have to try to convert over all I can.  I hated having all this stuff basically configured, but then thanks to SUN going bust, and Oracle being Oracle it all got screwed over.


What is a VLAN (part 6)

WIth Windows NT installed, it’s time to look at it on the network side.

The killer feature of GNS3 is that we can inspect traffic everywhere we draw a connection.  So simply right click on the connection from the Qemu VM to the Hub, and you can start a packet capture.

GNS3 will then prompt what the link type media is, in this case it’s Ethernet, and what the link name is.  After hitting OK, it’ll then start WireShark on the virtual link.

And in no time we can see the NT machine broadcasting on the network.  OK everything is looking fine.

As you can see our packet is an 802.3 Ethernet packet, with a LLC header, and a NetBIOS packet.  This is what we are expecting as the connection to the hub is ‘raw’.

Now that we have verified that we can connect to the network and capture, we can close Wireshark.

We then should right click on the link, and tell it to stop capturing.

OK, now what about VLANs?  Let’s start with a simple lab.  We are going to get rid of the Hub for now, and add in two switches.  One switch will be our ‘core’ switch, the other will be our access switch.  We will then put our PC onto the access switch, and then setup an 802.1q trunk between the two switches, and then observer the NT broadcase traffic in the trunk so we can see the VLAN tag in action.

Right click on the hub, and delete it.

Yes we do want to delete it

Drag out a switch, and then right click and rename it to core.

Now we are going to configure the core switch.

Right click on the core switch, and choose configure.

By default every port is on VLAN 1, and is a port type of ‘access’.  You would typically connect end devices like servers to access ports.  I probably should have deleted them all, but since we are going from my session I deleted ports 0 & 1.

Now I’m going to add port 0 with a native VLAN of 1, but a type of dot1q. This port will be used to connect to the access switch.

And then port 1 will be an access port on VLAN 2.  Hit OK and it’ll close the window.

And we are good to go.

*HOWEVER* this is a source of some confusion at least for me.  Go back and right click on the core switch, and look at the ports.  GNS3 for me changed the port numbers so it did not preserve my port choices, however there is still an access port on VLAN 2, and an 802.1q port.

As you can see on the core switch, port 6 is now the dot1q trunk port, and port 7 is the VLAN 2 access port.

Add in a second switch, and change it’s hostname to access

Now let’s configure this switch the same way we configured the core.

Same steps, in that we delete some ports first

Add in an access port for the Qemu PC on VLAN 2

And then add in a port with a type of dot1q, and a native VLAN of VLAN 1.

And our access switch is configured, so you can hit OK.

As you can see GNS3 has changed our trunk port to port 7, and our Qemu access port is now port 6.  This should be a bug…

So with this confusion in mind we connect port 7 of the access switch to port 6 of the core switch, by selecting the cable tool, and the appropriate ports.

And we will now have connected the two switches.  Now to connect the Qemu PC.

Again using the cable tool, it’s the only port on the Qemu VM

And to port 6 of the access switch.

Now we can start a capture on the connection between the two switches.  Right click on the link and start the capture.  It’ll be the same as last time, the default options are fine, and it’ll start Wireshark.

Now when the NT server sends a packet on the network, the access port is in VLAN 2.  Broadcast packets will be sent to all the other member ports on the network, in this case we do have an access port on the core switch in VLAN 2.  But while the packet is going between switches it needs a way to identify what VLAN the traffic came from, so as you can see from the capture There is now another protocol layer going on.  In this case we have an Ethernet II packet, but now the next layer is the 802.1Q frame, that gives the priority level, along with the VLAN number.  Then the NetBIOS packet is under that.  As you can see it is *NOT* TCP/IP only, but rather any Ethernet frame can be encapsulated in a VLAN, and then across 802.1q links they can be transmitted by encapsulating the packet in an 802.1q header to keep track of which VLAN the traffic was bound to.

But how about data egressing on the other side?

Let’s take a HUB and drag it out to the infrastructure pane.

Now we are going to connect that hub on any port to the core switch.

In this case, port 7 was our access port on VLAN 2.

And now we can start a capture on the connection from the core switch to the hub.

And as you can see the NetBIOS arrives on the other side without any 802.1q header, and any machine on the other side wouldn’t even know it’s been through an 802.1q trunk, or that it’s even on a VLAN.

So why use VLANs?  Isn’t it easy enough to add infrastructure for every network as needed?  Sure you *could* but it becomes very costly.  And you end up supporting quite a number of devices.  Then it never fails that you have one user or device in part of the network that doesn’t warrent a good network connection, but when it breaks, like it always does they generate a lot of heat about it.  Just as LAN segmentation is a popular way corporations restrict internal access as they can have firewalls to control traffic entering and leaving each network.  But doing this the old way means that every tiny move add and change will require someone to do something physically making it very expensive to maintain.  VLANS solve these issues by letting you deploy good infrastructure everywhere that everyone can benefit from as they can share the hardware, however with things like QOS, you can ensure that they do not stomp on each-other for the uplinks, but they are isolated in their own VLANs.

And what is the big deal with 802.1q?  Well going back to our VLANs vs using physical switches, if we had 1,000 VLANS on a switch, and we wanted to connect 300 of those VLANs to a single server without 802.1q you would need 300 network cards.  Just as adding another switch would require you to use 1,000 ports to carry all those VLANs from one switch to another.  By using 802.1q to tag each VLAN through the trunk port it lets you use a single physical connection, and appear on each network.

Hopefully this is enough to get you started, both in terms of how to set things up, but what to look for.

What is a VLAN (part 5)

With the textmode setup complete, it’s time to do the graphical setup of Windows NT 4.0


You can use any name/org

Select how many licenses you have for your NT Server.

Give the server a name

I’m not going to build a domain, so a stand alone server is fine.

You can give the Administrator account a password if you so desire.

I don’t need any emergency repair disk, as this server is the epitome of disposable.

I added all the components.  Again for this test it really doesn’t matter.

Configure the networking

Now for the fun part, we are going to configure the networking.

I’m sticking to ‘wired’ networking.  I’ll save RAS for another lifetime.

Everyone wants to be a webserver.  Sure why not.

You can either manually select a NIC, or just let it auto-detect.  We are going to auto-detect it though.

And it’ll correctly identify the AMD PCNet card.

I selected all the protocols available.  I didn’t bother adding other ones like AppleTalk.



It’ll prompt for the media type and duplex.  The card isn’t real and it’ll work fine no matter what.  I just leave the options alone.

Our network doesn’t have any DHCP server.  Since we are plugged into a simple hub.  DHCP requests will fail.  Let’s give it a static address.  For Advanced people, yes you could wireshark on the wire to observe the DHCP.  We will touch on how to do that later, as I just want to get NT installed .

There is no need for a gateway.

We don’t have any bindings that need adjusting, so you can just hit Next

And Next again

Again, no domain, so run in workgroup mode.

Finish, although it’s far from over.

IIS components to install.  I just hit OK for the defaults.

Confirm the creation of the directory

And the child directories

And creating the IIS child directories

Gopher isn’t happy without a domain name, but I don’t care.

Select your timezone.  Or don’t.  This is from 1996, so many of the timezones are no-longer correct.  Just as DST has changed so many times.  But it really doesn’t matter yet again.

The display adapter is SVGA compatible.

Move the resolution slider to 800×600

Then hit OK.  It’ll want to test the resolution

Everything looks good

YES I saw the bitmap


OK to accept the display at 800×600

Files will finally start to copy

And now we can finally restart are computer.

By default the NT Loader will wait for 30 seconds.  You can hit enter to get it to load right away or wait.

But we have now completed installing Windows NT, so we can now move on to capturing some traffic, aka part 6..

What is a VLAN (part 4)

In this post we are going to install Windows NT 4.0 Server into our VM.

The first step is to turn the VM on.  Simply right click on the VM, and choose Start. The red dot will then turn green.  Although it may appear that nothing is happening we just can’t see it yet.

Right click again, and choose the console, and VNC will then connect to the Qemu VM, and we can now interact with it.

And here is where we start installing Windows NT 4.0.  I’ll just put the keys in parenthesis of what I’m doing. In this case just hit:




(page down) until you get to the end, then hit (f8) to agree to the license

The default options are OK.  (enter)



I chose NTFS for my server.  Although I’m not interested in creating a domain, so FAT will work too.  It really doesn’t matter.




Waiting for the files to copy


On reboot if you have selected NTFS it’ll convert the filesystem like this:

converting FAT to NTFS

After the conversion, NT will reboot again, then it’ll continue the setup process.

Otherwise you’ll just reboot directly into the graphical setup of Windows NT, and we can continue in part 5.

What is a VLAN (part 3)

In our previous post, we configured a Qemu template for Windows NT.

With the NT template ready we will be prompted to give this project a name.

So I called this one ‘what-is-a-vlan’ sticking with the theme.

Now we can drag components out.  I selected the NT template that I’ve created, and dragged it out to the design pane.  Now we have a computer!

I then selected a simple Ethernet hub, to begin verifying that our configuration is working.  Just drag it out to the toplogy pane.

Now for the fun part, we are going to connect the Windows NT VM to the Hub.  Right click on the Qemu VM, and it’s available Ethernet interfaces will pop up.  It only has one, so select Ethernet 0.

Now you can select the Hub to complete the connection.  Hubs repeat every packet they receive, and don’t change anything.  They offer zero intelligence, and have no way to save you from yourself, if you do anything stupid (see creating a loop).  Every packet that comes into a hub is sent to every port going out.  They don’t care about protocols, or anything they just simply repeat.


So this will be our simple network.  The next thing to do is to turn on our PC, and install Windows NT 4.0.  I’ll save that for the next step which you can follow here.  If you don’t care about installing Windows, then you can skip to the following step where we will do a simple packet capture of the NT machine connected to the hub so we can observe how it’s packets look.

What is a VLAN (part 2)

In the last post, we quickly went over the default install of GNS3.

We are now going to configure a QEMU template for Windows NT.  I’m going with Windows NT as its pretty resource low, has TCP/IP and other protocols like IPX/SPX which can be routed and NetBEUI which has to be bridged.

We are going to use the Qemu option

Although we do get this warning, it really doesn’t matter.  NT runs fine.

Give the machine a name

The default 256MB of RAM is more than enough.

Set the console to VNC, as NT is graphical

I set it to use the included qemu-2.4.0’s Qcow2 image format for the virtual hard disk

The default options are fine.

I’m not going to try to build anything that sophisticated, so 500MB is more than enough for NT 4.0 .  If you do want something more involved 2GB is the effective limit for a boot disk for NT 4.0 SP1

The default name is fine too.

We do however need to make some changes.  The network card needs to be the AMD PCnet version, and we need to add an additional flag to Qemu to restrict the CPU functionality to a 486 so that NT will install without any issues.

So the networking tab will let you change the type.  AMD PCNet is the one that is supported out of the box, and verified working!

On the Advanced settings tab, is where you can add the -cpu 486 flag, as indicated above.

On the CD/DVD tab, you will want to point it to an ISO of Windows NT.  It doesn’t matter if it’s Workstation, Server, Enterprise, Terminal Server.  They all install the same.

It will prompt you if you want to copy the ISO into the default images directory.  It really doesn’t matter one way or the other.

Qemu image configured for NT

Now the image is configured for NT.

Now we can continue to building our first topology (AKA Part 3).


What is a VLAN (part 1)

I got this question the other day, and I thought I’d make something of it.

“What is a VLAN?”

And more importantly…

Do you know of a good tutorial  / tool / game that I can use to understand vlans?

Sure do, GNS3.  So in this series as I know I’ll have to break it up as it’s going to be a LOT of images, I’m going to go over the installation of GNS3 on Windows (I’m not interested in obsolete package versions on whatever distro of the minute is the fancy in Linux world), I’ll go over how to use QEMU to install a Windows NT VM, go over how networking works with a simple hub, then install two switches, a trunk connection, and show how to observe the VLAN tagging in action.  Then add in other VM’s and more VLANs and then go over bridging vs routing.

The installation options are pretty simple.  I’m going to just stick with the default.

You can install it wherever you like.  You don’t have to install it on the C drive if you do not wish to.

And with that, hit next and it’s installed.

Im not interested in the solar winds stuff, so I just declined.  Nothing was missed.  After that go ahead and launch GNS 3, and you are welcomed with this screen.

I’m going to run everything on my computer.  I’m not going to get into slave machines, or even wondering why they don’t just launch multiple instances of dynamips where needed.  Or even what capabilities there are or even at the moment trying to force my MinGW Dynamips into the project.

It’ll pick a port and host binding.  It’ really doesn’t matter too much, maybe you want it for a proper LAN connection.  again I’m focused on using this as a self contained thing so the default option ought to work.

And with that said we can now move onto configuring a QEMU template for Windows NT (part 2).

OpenBSD 6.2 shipping

It’s that time of the year again!

As always information is available on the OpenBSD site.  The release notes go over all the changes, but the biggest change that caught my eye was this one:

  • The i386 and amd64 platforms have switched to using clang(1) as the base system compiler.

There has been long talk about moving away from GCC on OpenBSD, but many of the older platforms were ‘trapped’ on GCC as they only have support for the CPU in older releases.  And they have long since said it was difficult in submitting patches up stream and dealing with regressions.  Sadly for GCC this has been an industry thing with even Apple moving away from GCC based compilers to CLANG.

Maybe it’s just inevitable, things change.

At least the Clang competition is driving progress from GCC too, so at least current and new platforms benefit from the competition.  Also VMM is getting stronger, I should try it some day….

GCC 1.27 & MS-DOS

Inspired by Building and using a 29-year-old compiler on a modern system, i thought I too could get this ancient version of GCC working.  At the time I never had bothered with the older version as I had always assumed that there were many fixes and adaptations to GCC  for it to run on MS-DOS via GO32/DJGPP.  However after doing this, its obvious that GO32/DJGPP was rather built around GCC’s stock output, which would sure make a lot more sense.

And it turns out that the target machine being an i386 Sequent running BSD is the best match, both in turns of underscores, and debugging format.  At first I had tried the AT&T SYSV i386 target, however it couldn’t link anything from the standard libraries that DJGPP has as they all have a leading underscore.  After starting to mess with internal macros to turn things on and off, and re-define how various portions of assembly are emittied, I found the Sequent target and went with that and everything was fine, and using the existing build infrastructure for GCC 1.39 I now could actually run hello world!

gcc_v1 -v -E hello.c -o hello.i
gcc version 1.39
cpp_v1 -v -undef -D__GNUC__ -DGNUDOS -Dunix -Di386 -D__unix__ -D__i386__ hello.c -o hello.i
GNU CPP version 1.39
gcc_v1 -v -S hello.i -o hello.s
gcc version 1.39
cc1_v1 hello.i -quiet -version -o hello.s
GNU C version 1.27 (80386, BSD syntax) compiled by GNU C version 5.1.0.
gcc_v1 -v -c hello.s -o hello.o
gcc version 1.39
as -o hello.o hello.s
gcc_v1 -v -o hello hello.o
gcc version 1.39
ld -o hello C:/dos/xdjgpp.v1/lib/crt0.o hello.o -lc

go32 version 1.12.maint3 Copyright (C) 1994 DJ Delorie

hello from DJGPP v1/GCC 1.39!

Wasn’t that great?  Then going through my ‘test’ programs I went to try to build the infocom interpreter, and that is when things went off the rails.

funcs.o: Undefined symbol __udivsi3 referenced from text segment
options.o: Undefined symbol __divsi3 referenced from text segment
options.o: Undefined symbol __divsi3 referenced from text segment
print.o: Undefined symbol __divsi3 referenced from text segment
print.o: Undefined symbol __udivsi3 referenced from text segment
support.o: Undefined symbol __divsi3 referenced from text segment
gcc_v1: Program ld got fatal signal 1.

I’ve had some issues with GCC and these ‘built in’ functions before.  This was an early major stumbling block back in the x68000 GCC days, where after a lot of searching I was able to find 68000 versions of various math routines that were in the native Hudson Soft assembler to link in.  While GCC 1.x does have a libgnu/gnulib to include these functions it warns you over and over to not use GCC to build them, but rather the native CC.  But the problem is that I don’t have a native CC.

But I managed to save myself after googling around by finding srt0.c from 386BSD.  Namely these two:

.globl ___udivsi3
  movl 4(%esp),%eax
  xorl %edx,%edx
  divl 8(%esp)

.globl ___divsi3
  movl 4(%esp),%eax
  xorl %edx,%edx
  idivl 8(%esp)

I ended up having to removing a single underscore, but now I could link infocom, and even better it runs!

Wanting to try something far more exciting, I went ahead and tried to build DooM.  However GCC 1.27 has an issue with m_fixed.c  I fired up GDB to at least take a look, although I’m not sure where the fault lies.

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Breakpoint 1, 0x752c5ad5 in msvcrt!_exit () from C:\WINDOWS\System32\msvcrt.dll
(gdb) bt
#0 0x752c5ad5 in msvcrt!_exit () from C:\WINDOWS\System32\msvcrt.dll
#1 0x752bb379 in msvcrt!abort () from C:\WINDOWS\System32\msvcrt.dll
#2 0x0045805c in final (first=0xe066a0, file=0x75312688 <msvcrt!_iob+128>, write_symbols=NO_DEBUG, optimize=0)
at final.c:653
#3 0x00403198 in rest_of_compilation (decl=0x722718) at toplev.c:1296
#4 0x0040fbce in finish_function () at c-decl.c:3272
#5 0x004040c0 in yyparse () at c-parse.y:224
#6 0x0040239d in compile_file (name=0xe00def "C:/dos/xdjgpp.v1/tmp/cca02992.cpp") at toplev.c:837
#7 0x00403a33 in main (argc=11, argv=0xe00f90, envp=0xe01598) at toplev.c:1556

With the code being:
      if (! constrain_operands (insn_code_number))
        abort ();

So I assume some error with constrain_operands? Not that it makes it any better.  However I know this one file compiles fine with 1.39, and since we are on the i386 another alternative is just to used the assembly version that was hiding in the readme..

DooM mostly built by GCC 1.27

And much to my amazement, it works!  Keeping in mind that this is using an a.out tool chain, along with the last DPMI enabled GO32 extender.

Considering the compiler dates back from September 5th, 1988 it’s really great to see it running.

I’ll have to upload source (GCC 1.27/DooM) & binaries later.  But I imagine it should also run on EMX/RSX for a Win32 version.