Monday, January 23, 2006

Given: Windows 2000 machine in a local network that badly needs updates. No internet access due to high risk of attacks to the exposed system. Windows update server in the same local network.Problem: Windows 2000 won't update from server in local network, because service runs on non-standard port for this OS. Windows 2000 update client supplied with SP4 (aka SUS client) can only update from WSUS service on port 80.

Why the problem: Usually server machines in local networks run all kinds of services including intranet web sites and web-services among them. Needless to say that port 80 is very popular among these due to a browser preference to treat it like default. No surprise that update service is running on different port, but Windows 2000 deliberately looks for this service on port 80 (where it was in old good times) and to change this ill behavior it needs an update. A typical chicken and egg problem and here is how to resolve it.

So, what?: After update SUS client becomes WSUS client, which is able to operate with any port, but to bootstrap the process you need to make WSUS service available somewhere on port 80. If port 80 on server is busy with another service you need to use port 80 from another available machine - i.e. forward or map port. Which machine? The most simple - the same machine client is running - localhost. Just forward WSUS service port (e.g. 8530) from remote server to port 80 on local machine and tell old client to use the latter.

Copy setup_windows_update_localhost.reg to setup_windows_update_intranet.reg and edit the latter to use http://intranet:8530 (example server) for subsequent updates. Port mapping is not needed from now on, so shutdown the software.

In case of one-time update you probably do not need to keep link with WSUS server on this machine. Then after repeated restarts and updates to make sure everything is installed successfully, launch setup_windows_update_default.reg file to remove WSUS server settings from the registry.

Monday, January 16, 2006

Here is XSLT transformation engine for Windows in just 4k of JScript code using MSXML SDK. Copy the snippet below and paste into mbxsl.wsf file then launch it to get usage help.

MSXML is probably the fastest and the worst engine at the time being. Do not ask why - it's empirical. You can try to catch that feeling by getting Windows Scripting Host 5.6 SDK, MS XML 4.0 SDK and making a simple XSLT transformation engine that should output text result in specific encoding like windows-1251. There are several ways to make the engine and only one to make it work as expected. Ok, let's finish this fast:

.transformNode() always returns UTF-16 string (no way to convert/iconv it while writing).transformNodeToObject() requires output to be well-formed XML if the output is DOMDocument. I didn't find anything else in these SDK's to substitute in this field, so no luck with plain text output. You can use IStream interface described below, but you will not find neither IStream interface nor it's ADODB.Stream implementation reference in these SDKs. So, I didn't know anything about ADODB.Stream and thought there must be another method described in SDKs to do the task. I've found IXSLProcessor interface, which, unfortunately, doesn't allow me to save "encoding" header in xml declaration along with (correctly, btw) encoded data via opened TextStream. Even though I didn't need that header to output plain text at the first time, later it turned into a problem. How much did you understood so far? Consider how many garbage had filtered through my head before I came up with the solution.. Ok, after some google cache data mining on IXSLProcessor+IStream I've found Rob Shields page, which fortunately contained an example of IStream implementation. I probably stop for now and post a solution "how to implement a binary XSLT transformation engine in JScript with MSXML".

If you need to make correct XSLT tranformation in MSXML with correct encoding specified in xsl:output try this:cscript mbxsl.wsf /xml:in.xml /xsl:filter.xsl /out:result.out