Thursday, November 23, 2006

[VBScript] Configure

Below is retake on the Include subroutine which heads up the vast majority of my scripts. This incarnation puts a wrapper around Include and is called, for want of a better word, Configure. This subroutine takes no parameters at all. Rather, it builds up a filename based on WScript.ScriptFullName with ".cfg" tagged on, reads it in and then hands it over to ExecuteGlobal. This means that the .cfg file must contain functioning VBScript code.

Provided the .cfg sits side-by-side with the .vbs, the .vbs should work. And if you change locations, change the .cfg code. If the .cfg can't be found, you get an error message. I haven't put in any error trapping yet.

Had fun with "With"/"End With" on this one.

So in the .vbs we have
and in the .cfg we have (for example)

Saturday, November 11, 2006

[Observation] freshmeat, no. CodePlex, yes?

Seems that freshmeat don't want Windows-only projects. So it may be CodePlex you'll find the project on. More details when they come to hand.

[Delphi] COM of libiconv

I have just finished my first serious bit of Delphi programming, using Turbo Delphi Explorer. As a RAD/IDE it's pretty good. However, given the limitations of the Explorer version, I'll upgrade to the Pro version fairly soon.

COMlibiconv is an in-process COM object and was born out of the company's need to convert some multibyte encodings into Unicode. It's based on DIConverters, a unit made available by Ralf Junker of
The Delphi Inspiration. DIConverters is licensed as LGPL. COMlibiconv will also be LGPL.

(Did I mention that I'm working again? No? Okay, well now I work as a software engineer for Strapper Technologies, of Fremantle, WA, Australia, makers of the Protium language.)

I'll be posting version 1.0 of the project up on Freshmeat by the end of next week, God willing.

COMlibiconv appears to work. I've used it in VBScript, late-bound, as
and I think my boss has used it, early-bound, in VB6.

At this stage the methods and properties exposed are as follows (taken from the source):
The function iconv_toUnicode takes a string defining the name of the multibyte encoding, the string to be converted, and two integers stating where to start and when to finish. I should probably give those default values so that the method can be called with just the encoding and the string.

ErrorCode contains an integer value which, when Success is false, represents what went wrong. An enumeration of possible error values is indicated and may make it into the next version.

Aliases gives all the various names for an encoding, indexed by a number from zero to the number of encodings (which can be found using Count).

CNames is also indexed in a similar way, and returns what I have called the 'CName' of the encoding. It's stuff that was in the DIConverters unit. I haven't found a use for it, but included it anyway.

The next version will, God willing, contain a method to allow conversions from Unicode back to multibyte.

If you're interested in this, and it hasn't appeared on Freshmeat by 18th November 2006, write a comment to remind me.

© Copyright Bruce M. Axtens, 2006

Thursday, September 21, 2006

[Observations] Microsoft Changes Attitude Toward FOSS?

After years of looking on FOSS as a disease, Microsoft have started talking with, and indeed collaborating with, the FOSS commmunity. For some the change is too unreal, with many taking a cynical, unbelieving attitude. For others, it's a godsend.

Check out Port 25's posting about a recent cooperation between Microsoft and Mozilla, titled
Why I invited Mozilla

Then, if you have the time and bandwidth, there's a 1 hour video interview with Bill Hilf of the Open Source Software Lab at Microsoft

It seems almost too good to be true. What do you think?

Thursday, September 07, 2006

[Observations] Wardriving

Last night I went war ... er ... bussing. From part way through the 879's route as far as the stop nearest home, there must have been over 30 hot spots. At least three weren't encrypted, and "offered" subnets to the passerby.

I'm on an 879 again this morning (2006-09-07, Thursday, after 09:00.) We haven't gone three kilometres yet and already
NetStumbler has a list of over 50 hits. About half have WEP and the rest don't. And again about 1 in 10 of the total are open to the public.

Pardon my naivety, but is this the usual state of affairs?

It introduces an interesting ethical issue: no one can stop you stealing another's bandwidth if they don't take steps to protect it. It seems that you can sit in a tree outside their front gate, downloading to your heart's content and they wouldn't know it, until their ISP bills them for exceeding their download allowance, or they ring the ISP to ask why they've been shaped only to be told that one day last week they downloaded 5G of something or other.

NetStumbler's own help file says, under the heading "Wardriving", "... To avoid using the networks that you observe, go to the Network Control Panel and unbind TCP/IP from your wireless LAN card." (Inevitably?) ethics aren't mentioned.

[Later, 09:30] On the way into the Busport (inner city Perth) the list expanded rather dramatically. Some of the SSID's are more meaningful: PCEC_Dimension_Data and BHPB_NiW_Avaya_Voip, for instance. The name "metromesh" keeps coming up ... eight times so far. I wonder what that's all about?

Waiting for a 36 to take me to Midland. May start cycling there next week ... only about 30 kilometres each way.

Now working for Strapper Technologies. More about that later.

Wednesday, August 30, 2006

[VBScript] StandardLibrary.zip

As promised in the previous posting, Standard Library is now available as a ZIP. Thanks to Perth Linux Users Group for the storage space.

Saturday, August 12, 2006

[VBScript] Standard Library

My apologies for the hiatus between entries. I have been struggling with the "black dog."

Recently, I was asked to make the Standard Library available, so here it it. For ease of digestion, I have segmented it, though you will find that some functions make use of routines in other segments. I will in due course make the whole file available in a single ZIP. Until then, you'll have to navigate as best you can.

Cheers, comments, creative criticism and corrections all gratefully received. It's been a few months since I last used the library; you may find the odd rough edge. (I have edited the file a little for publication, but only to remove references to previous employers' sites, and a few redundant comments.)

As knife manufacturers have no way of controlling how people use their knives, so I have no control over where and how you use the code on this weblog. I have tried as much as possible to acknowledge my sources. I would appreciate it if you also would do the same.

Okay, with that out of the way, let's begin.

I have adopted an Hungarian variable naming regime that is a bit different to the usual given in VBScript examples from Microsoft. Objects start with "o", collections with "c", strings with "s", numbers with "n", booleans with "b", dates with "d", arrays with "a", and variants with "v". I must confess, however, that I have not always followed my own standards.

First, a few symbols and standard objects.
Next a symbol table class, similar to that used in CLIVE.
Next, String manipulation tools. There are lots of things in here: LeftOf, RightOf, CountFields, NthField, BeginsWith, EndsWith, Contains, ForceExtension, Subst, Subst2, DQ, Between, Wrap (which puts HTML markup around text), RemoveSpaces, Zerofill2, RightFill, and LeftFill.
The one date manipulation function came out of a problem with encoding dates in Access. See the link for a fuller description.
Arrays: AAdd, InArray, StrInArray, AMax and Amin.
File manipulation code: CollectFiles, ReadFile, ReadFirstLine, Exists, WriteFile, Env and IncludeClass. Essentially wrappers around existing functionality, but with more flavour.
How do you classify the "mexican if"?
Now we get into some serious Active Directory (AD) and Windows Management Interface (WMI) code. As much as possible I've included the relevant attributions for stuff I have lifted and/or adapted.

First, domain access: GetAvailableNTDomains
Then computers: GetRemoteEnvironment, GetOnlineComputers, GetNetView, GetComputers, GetNBT, GetNBTA, GetDomainComputers, GetSpecs, ResolveIP, DetectTempFolder, and ExistsFolder.
Also user-specific tools: GetOUofUser, GetLoginProfiles, GetMac, GetComputerUsers, GetComputerUsers2, GetDomainUser, and GetNameAndDescription.
I didn't use them often, but there are function here for Group access as well: GetComputerGroups and GetGroups.
Okay, now we get onto the application control routines, starting with Excel: ExcelStart, ExcelNewSheet and ExcelColumnNames.
Then, Access routines: CreateDatabase, OpenDatabase, OpenRecordSet, CreateStructure and CreateIndex.
One lonely email-specific tool: ErrorEmail.
Internet Explorer tools: ModalDialog, ModalText, ModalThing, ReadClipboard, WriteClipboard.
An LDAP function: GetDefaultNamingContext
A function, CaptureDOS. It runs a command in the CMD shell, captures the output to a text file, and then sucks the data into a string variable.
Logging variables and functions: LogTo, Log, Die and Faint.
Next comes a testing module which is only executed if the library itself is executed directly. For example:
    CSCRIPT StandardLibrary.vbs

Anything goes in this section, and the stuff below is what was in there the last time I tested the file, which was sometime in January 2006.
Okay, that's the end of it.

I don't know when I'll be doing VBScript again; I have designed the Sudoku solver but haven't coded it yet. I had thought of doing it as an HTA.

At the moment I'm looking into the ISIS database technology (a friend has developed a Win32 Unicode-enabled version), serial i/o, FreeBASIC, and xbScript.

I hope to recommence regular postings soon, likely in support of a new language, Protium. Until then.

© Copyright Bruce M. Axtens, 2006

Sunday, May 14, 2006

[News] Working again ...

... at Lion Nathan's Swan Brewery.

Thanks, by the way, to all the visitors who keep my stats at an average of 10 visits per week.

More code is in the works: a tcl archive exploder, and a Sudoku solver written as an HTA.

Don't hold your breath!

Sunday, April 09, 2006

[VBScript] When did I log on/off?

The Australian federal government has brought in new laws which seem to require a return to the old days of clocking in at the beginning of the working day and clocking out at the end. As a contractor I don't think I'm going to notice a big difference ... if I want to get paid for the hours I work, then I fill out my timesheet appropriately.

If you aren't in the habit of keeping this kind of information, don't worry too much: Windows keeps a track of your login and logout in one of its Event Logs. Getting that information is fairly easy, if you know what you're looking for. Otherwise its like the proverbial needle in the haystack.

The script outputs into an Excel spreadsheet, the date of each logon in a separate column containing time of logon and logoff. Please note that the script was designed to query someone else's machine, and will likely need modification if you are trying to get your own data out of your own event log.

Here's the code.

As is often the case in my scripts, the preamble loads external code libraries. The former is a the standard library and the latter (see the end of the posting) a symbol table class, based on the Scripting.Dictionary object.
Next comes code to split up the event log's timestamp, followed by the routine to store logon date and logon and logoff times into spreadsheet cells.
Next comes the variable declarations. In retrospect the variables sComputer and sUser could have been Const rather than Dim. For that matter they could have been taken from the command line. Note the double backslash in the uUser variable: this is needed for where it occurs in the WMI call.
This is the core of the script: pointing WMI at sComputer and executing an SQL query against Win32_NTLogEvent. It asks for everything from the 'Security' Logfile where the EventCode matches a logon or a logoff and where the User matches sUser.
Then the script starts to do things with the list of events now stored in cEvents. First a Dictionary is loaded with logons as (zero, comma, TimeSplit of datestamp) and logoffs as (one, comma, TimeSplit of datestamp). The reason for this is that there may be more than one logon and logoff event for a given user during a working day. By storing the logon and logoff times in this way, the first "0" reference can be assumed to be the first logon off the day, and the last "1" can be assumed to be the last logoff of the day.
From the Dictionary wrapper class the keys are extracted. A check is put in here to make sure that there are records to be reported.
Next comes the Excel interactions. The ExcelStart and ExcelNewSheet macros are listed at the bottom of this posting.
What follows is the guts of the Excel reporting. Despite the possibility of incorrect recording, the assumption is that the report will contain the first logon and the last logoff. If a logon occurs after the last logoff, it is discarded. The script is unable to cope with the situation where someone logs on today and logs off tomorrow.

Note that a check is made not to report more dates than MAX_INSTANCE, a limit that has not yet been encountered. AMax and AMin are listed at the bottom of the posting.
Excel is left running with the results of the report. It's up to the user to save it, print it or whatever. To finish, the macros ExcelStart, ExcelNewSheet, AMax and AMin, and the ClassSymTab class as promised.

Tuesday, March 14, 2006

[News] Looking for work ... again

Went and visited three new (to me) employment agencies today. Gryphon, Sinclair Knight Merz and Candle. I also went to the offices of the City of Perth and picked up a busking permit application. Do I have the guts to stand up and sing, a capella, in Murray St. Mall?

Friday, February 24, 2006

[News] Codeaholic/LL

That's it then ... 99.9% of the languages that were listed down the left hand side are now over on the Code-a-holic Language List.

Mate! I'm glad that's over.

Wednesday, February 22, 2006

[News] Today and Tomorrow

Today it was swapping hard drives; sharing receipt printer; finding, downloading, and failing to get working the old touch-screen software; telling all the other machines to use LPT6 when running the POS application, but making sure that the POS machine itself still uses LPT1 (using Clipper 5.3); and getting the floppy drive to work in the SERVER.

Today I celebrated by 45th birthday. One of the gifts I received was a PLUG membership. Eventually the ancient source codes promised but never delivered on Code-a-holic will find their way there.

Tomorrow is the first day (of about 1.5 weeks) at Home Open working on the help desk. More news, and code, as it comes to hand.

Friday, February 10, 2006

[News] End of Contract ... again

The Holy Grail, permanent work, remains elusive. I have good KSAs (Knowledge, Skills, Attitudes) but employers seem only interested in having me around for a few weeks ... maybe it's my deodorant / mouthwash / politics / religion ...

A couple of times it's been suggested I try out writing for a living. What do I live on in the meantime? Others have suggested getting a heavy-rigid licence and signing up to be a bus driver. That's tempting, and it may leave time to write. But it also means stepping into the twilight between an IT career and "something else."

So Monday it's climb back into the suit, catch the bus into town, and go door to door, employment agency to employment agency, saying, "Hey, remember me? I'm looking for a job (again.)"

[Languages] The Left-Hand List

The list of programming languages on the left-hand side is shrinking. That's A to E done. They've all been moved over to the language list on Code-a-holic/LL.
Over the next few weeks I'll be posting the rest of the data I have on those languages (the bare minimum of name, link, and description.) If anyone's interested in the metacard database or having an XML-ish file with all of the extra details (platform, users' group, date of last activity, etc.), please leave a comment.
Leave a comment too, if you can see anything that needs changing / updating.

Thursday, February 02, 2006

[VBScript] CliVE - Command Language Interpreter VBScript Environment

A few years back ZATZ Publishing, in their DominoPower Magazine, published an article entitled Using Python to create a command line interpreter for Notes. Not being that au fait with Python I decided to have a go at doing the same thing in VBScript. CliVE is the result.

CliVE takes the basic CLI mechanism of my previous posting (
[VBScript] CLI Framework) and adds a couple of extra bits: Loading, Saving, and a shorthand for 'WScript.Echo'

First the code supporting the standard header.
Then support for putting script files on the commandline. Files specified on the command line are loaded and interpreted, one after the other.
This is the main interpreter loop.

The aSession array stores each line passed to Evaluate so that a given session's script can be stored.

In the main loop, a prompt is output and input received. The sLine is split into a two element list: the first element being the keyword; the second being all subsequent text.

There are a few keywords starting with a dot. These are peculiar to CliVE:
.quit
.exit
Synonyms for WScript.Quit
.echo
?
Synonyms for WScript.Echo. Unlike other dot commands, the line starting with this command is passed to the Evaluate function.
.save
Saves the contents of the aSession array to SaveClive.clive unless a filename is given as an argument.
.run
.load
Reads the filename given in the argument and executes the code therein by passing it to ExecuteGlobal.
.debug
An empty procedure. A place to put test code.
All other commands are treated as VBScript commands and are passed to the Evaluate subroutine.
Evaluate, Save, LoadRun and Debug.

Note that the code for Evaluate traps errors, and displays an error message. Note also that LoadRun has no such protection. It's something one might want to add ASAP!

Note also the call to AAdd, which adds the evaluated command to the aSession array if the command works without error.
Rather than reproduce the entire StandardLibrary (1500+ lines), here are the referenced routines (AAdd, Exists, ReadFile, WriteFile), plus supporting symbols.

Wednesday, February 01, 2006

Friday, January 27, 2006

[VBScript] Where else have I logged in on this network?

It's not so much a question for me -- I remotely log into many pcs daily as part my job, and try to leave as few tracks as possible. However, today a customer rang saying she'd lost a few important Favourites and had no backup. The best way I could think of helping her, was to locate all the machines she's logged into and see if any of the Favourites could be found.

I did find what she was looking for. Here's the code I used.

First the standard header implementing the synthetic include (derived from
Rube Goldberg Memorial Scripting Page)
StandardLibrary.vbs is getting big. 1500+ lines of code.

Next a little function for a right fill. Having needed this only once, I haven't included it in the StandardLibrary.
Now the main body of the script.

1. Check commandline to see if a username is specified.
1.1 If nothing specified, throw a fit.
2. Get an array of all the computers currently online.
2.1 No error checking here but there ought to be
3. Tell everyone what's going on.
4. Loop through the names of the online machines
4.1 Trim off the leading \\ put on by NET VIEW
4.2 Write out the name, right filled with dots
4.3 Get an array of the login profiles for the computer
4.4 Scan the array to see if contains the the username (case insensitive search)
4.4.1 If found say so with a CRLF
4.4.2 otherwise issue a CR

The calls to BeginsWith are commented out. They apply only to my situation where a company edict ensures that all desktop pc names start with PC and all laptops with LP.
The supporting library rountines are below, First GetOnLineComputers with its supporting routines, GetNetView, CaptureDOS and ReadFile
Next, BeginsWith (included for completeness sake)
Then GetLoginProfiles, plus support routine AAdd
And, finally, StrInArray.
Unfortunately, this does not run quickly. It can take ages to get through the entire list and sometimes hangs inexplicably. Your mileage may vary.

If anyone comes up with a faster way of doing this I'd be very interested.

Monday, January 23, 2006

[Euphoria] Structured Access, part 2

I knew I had it somewhere. Okay, these implement the following: BYTE, BYTES, WORD, DWORD, QWORD, ASCIIZ and PSTRING. You can pull the data one chunk at a time as per the last posting or else pull a whole set all at once.

The file versions don't work and I'm not sure why, and as I said before, I don't have the time to do anything about it.

By the way, this was written before Euphoria 2.5. In fact, possibly before 2.4 so the code may need some tweaking.

mread is like the getmem of the previous posting. memread takes a sequences of reads. I will eventually post an example (if I can find one).

(Since writing part 1, I've been in touch with CChris from
Euphoria Standard Library who has taken over the development of getmem. It's great to be able to give something back to the Euphoria community after all these years (I've been using it since version 1.5).)

Tuesday, January 17, 2006

[Euphoria] Structured Access

Late last century, in a developing part of the world, I tried writing a diskette cataloguer. It worked okay, once I'd figured out how to do all the gymnastics necessary for BIOS calls. In the process I wrote a function to access memory in a structured way. Brilliant as Euphoria sequences are, they are just that: sequences. There's little in the way of structure, unless you apply some of your own.

I've reproduced the function in its entirety below. Essentially, the code takes data from memory in a structure way, that is, in terms of BYTE, BYTES, WORD, DWORD or ASCIIZ.

An attempt was made to make the functions applicable to files. Those routines don't work, and I haven't taken the time to find out why. Good as Euphoria is, there's no Mac OS X version (so I can't use it at home) and there's no opportunity to use it at work -- Euphoria's not in the SOE. If you're interested in looking at the code, write.
As an example of how to use getmen, below is the code for GetDriveParameterTable
As an example of the BYTES parameter:
The ASCIIZ parameter is like the BYTES except it keeps working its way through memory until it encounters a binary zero and then returns everything up to that point.

From memory I remember writing a version of getmem() which received a sequence of BYTE, WORD, etc. specifications and returned the resulting sequence of results. When I find it I'll post it.

Enjoy.