An observation: Door Store -vs- Vote-For-Me yard signs

Traditional email spam like the unsolicited Door Store ads they drop on my step (in plastic covers to maximize slipping).

Comment spam is a “We’re voting for Mr. Shmiggle” sign put in my yard without my consent.

Now that I’ve worked it out, I understand why comment spam irks me so much more, because it (ab)uses my reputation for its own (search engine) advancement.  But I don’t want to put up a fence by closing comments tho, because I do want my friendly neighbors to visit and talk to me.

So anyway, if anyone using .Text 0.95 is interested, here’s my code to negate the search engine benefit to the comment spammers:

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
	Dim reqURL As String = Request.CurrentExecutionFilePath
	IF reqURL.toLower().indexOf("/archive/")<0 OR Request.Form.ToString()<>"" THEN EXIT SUB
	'-- get content
	Dim oWriter As New StringWriter()
	Server.Execute(reqURL, oWriter)
	Dim strResponse As String = oWriter.ToString()
	oWriter = Nothing

	'-- find comment section
	Dim iStart As Integer, iStop As Integer
	iStart = strResponse.IndexOf("<div id=""comments"">")
	IF iStart>0 THEN iStop = strResponse.IndexOf("</div>", iStart)

	If iStart <> -1 And iStop <> -1 Then
		'-- nofollow comment section's links
		DIM strTarget as string = strResponse.Substring(iStart, iStop - iStart)
		DIM strTargetFixed as string = _
			strTarget.replace("<a target=""_new"" href=""http", _
			"<a target=""_new"" rel=""nofollow"" href=""http")
		strResponse = strResponse.replace(strTarget, strTargetFixed)
	End If

	'-- send content
	Response.End()		'prevent conventional response
End Sub

Just replace the standard Application_BeginRequest procedure with this one in the global.asax.vb file (or absorb mine into it.)  It intercepts outgoing comments and dynamically inserts rel=”nofollow” into any contained links.

It won’t prevent comment spam, but it will negate the search engine benefit to the comment spammer, turning the “Vote-For-Me” signs into mere litter in your yard.

One catch:  this breaks .Text’s inline “Remove Comment” links.  You can still delete them in the the admin area’s Feedback section, tho.  Since the comment spam seems to come in waves, that’s an easier way to delete them all at once anyway.

(I guess my next goal is actually preventing comment spam via a captcha or challenge-reponse mechanism, but til then I feel more luxury of time to explore possibilities.)

Enable concurrent Remote Desktop sessions on Windows XP

It’s possible after all.  XP Pro’s Remote Desktop can be hacked to give concurrent sessions.

To explain:  Windows XP’s Remote Desktop rocks, as does its ability to give me my console session later (with my work uninterrupted) from another machine.  Glaring in its absence, though, is the ability to remotely-rock while someone is locally-rocking the machine.  This can stink in a big way. 

For example, too often I’ve remotely logged in for something quick, only to see this nuisance:

Logon Message
The user --- is currently logged on to this computer. If you continue this user's Windows Session will end and any un-saved data will be lost. Do you want to continue?
Yes   No

Rather inconvenient.  Even worse, though, I’ve often been logged in and working remotely, when someone locally logs in.  No warnings or explanations, just *bam* disconnected!  (At least the first situation confirms the handover with both people.)

For history:  Remote Desktop’s daddy was Windows 2000 Server’s Terminal Services in Remote Administration Mode, which did allow (limited) concurrent sessions.  Microsoft added the console-session flexibility to XP’s Remote Desktop, but dropped the concurrent sessions.  Then 2003 Server’s (renamed) Remote Administration wrapped in XP’s console flexibility.  Later, XP’s SP1 promised concurrent access, then SP2 did.  Two strikes.  It did make an SP2 beta though, before being yanked later…

The silver lining:  Thanks to the termsrv.dll from that SP2 beta, it’s possible to hack XP for concurrent Remote Desktop sessions in a few minutes.  Just change a registry setting, reboot to Safe Mode, replace the DLL, and boot back into homebrewed XP Remote Administration goodness.

For the do-it-yourselfers:  Don’t wait for Longhorn (or whenever-they-may-get-to-it): here’s the how-to article, and here’s the needed termsrv.dll file.

I just stumbled on sala source’s Terminal Server Patch, which wraps up the whole process in a single convenient patch.  Very cool.


SBS2003 VPN: What were they thinking?!

I thought I’d share some Small Business Server 2003 security silliness.  Following is a series of Internet Explorer dialogs when you setup VPN via the Remote Web Workplace:

Microsoft Internet Explorer
After you install Connection Manager, ensure that all users of this computer have strong passwords to protect the security of your Windows Small Business Server network.

File Download - Security Warning
Do you want to run or save this file?
    Name: sbspackage.exe
    Type: Application, 503 KB
    From: ---
Run   Save   Cancel
While files from the Internet can be useful, this file type can potentially harm your computer. If you do not trust the source, do not run or save this software. What's the risk?

Internet Explorer
The publisher could not be verified.  Are you sure you want to run this software?
         Name: sbspackage.exe
    Publisher: Unknown Publisher
Run   Don't Run
This file does not have a valid digital signature that verifies its publisher. You should only run software from publishers you trust. How can I decide what software to run?

Connect to Small Business Server
Do you wish to install the connection to Small Business Server?
Yes   No   

Notice the Big Red Flag??  Microsoft’s SBS team never signed the VPN installer (sbspackage.exe), so IE on XPSP2 (and presumably 2003SP1 now) does its scary “don’t take candy from strangers” warning.  (How long has Microsoft been touting executable signing now?!?) 



Getter/Setter Properties in OO Javascript

I just asked a guru of advanced Object-Oriented Javascript, Douglas Crockford the following question.  For posterity, and for other possible takers, I’m posting it here too.

Also, for the record, this has nothing to do with IE’s proprietary — but wonderful — setExpression method or CSS expression capabilities.  Those dynamic properties only apply to DOM objects, not custom Javascript objects.

Do you know of a way to define dynamic object properties in Javascript?

For example, VBScript lets us define classes such as this:

CLASS myClass
PUBLIC phrase
PUBLIC PROPERTY GET firstword ‘get first word from phrase
firstword = left(phrase, instr(phrase, ” “))
PUBLIC PROPERTY LET firstword(v) ‘set phrase’s new first word
phrase = v & ” ” & phrase

This demonstrates two important features:
1. the firstword property can return dynamic results (depending on the current value of the phrase property). 
2. setting the firstword property can run other code (which dynamically prepends to the phrase property).

We can fully accomplish #1 (Property Get) in Javascript, by reassigning the toString method/property to a function like so:

function myConstructor(){
var self = this; //preserve object’s context
this.phrase = ”;
this.firstword = function(v){
if(v){self.phrase = v + ‘ ‘ + self.phrase}; //LET
return self.phrase.substring(0, self.phrase.indexOf(‘ ‘)); //GET
this.firstword.toString = this.firstword;

…But I’ve found no way to achieve #2 (Property Let or Set) in Javascript.  I can set firstword as a method, but setting the property value overwrites the method definition (and all subsequent GETs return that static value).

I’ve extensively searched, but found no answer (at least not before Javascript 2.0, which doesn’t yet exist).  Any ideas from the experts?

Update: Douglas Crockford responded that he doesn’t care for getter/setter properties, since “it allows simple assignment to have side effects, which I think works against reliability.”  (I take that as a “No, it’s not possible.”)
    My current need is that I’m patterning my custom object after part of the DOM, whose objects certainly do have getter/setters.  I agree with Douglas that getter/setter side effects can be dangerous (esp. in the hands of a poor coder, as with any powerful code construct), but I think the use of methods -vs- getter/setter properties should be in the realm of “best practice” rather than a language limitation. 

Answered: line-breaks in VBScript constants

I’ve run into this often: the need to have a VBScript constant containing a line-break character.  Today I finally got a definitive answer on whether it’s possible (for the impatient, the answer is NO).

If you’re interested in history…

Of course this is right out:

CONST blah = “hello

…It’s just bad syntax.  The closing string quote has to be on the same line as the opening one.

The normal approach I’ve tried was this:

CONST blah = “hello ” & vbCRLF & ” there”

..But the ampersand (concatenation operator) automatically makes it an expression to the VBScript compiler, and therefore it assumes “not constant.” This is of course despite the fact that both parts are known at the time of compilation (which is the main criterion for a constant — value is known at compile time).  Anyway, the ampersand is right out.

Now in JScript/Javascript/ECMAScript, you can do this:

var blah = “hello \r\n there”

…The \r\n switches define the line-break character, they go inside the string, and they are only interpreted when it’s read. 

Unfortunately, there’s no similar switch in VBScript.  While HTML does honor ASCII codes like &#10; or &#13;, and web browsers honor hexadecimal codes in URLs, VBScript does neither.  So these also don’t work:

CONST blah =“hello &#10;&#13; there”
CONST blah = “hello %0A%0D there”
CONST blah = “hello 0x0A0x0D there”

So I was reading a blog entry by Eric Lippert (who I believe wrote most of VBScript) today, and he mentioned Constant Folding, and proceeded to outline the mechanics behind this VBScript constant problem.  It rung a bell, I asked about line-breaks in VBScript constants in his comments, and Eric responded:
“Sorry, you are correct — there’s no way to do that. Sub-optimal, I know. “
…Straight from the dev’s mouth.

SO, if you need a line-break in a VBScript constant, just use a variable instead:

DIM blah
blah = “hello ” & vbCRLF & ” there”

…Yes, there may be some slight performance penalty compared to a constant, but it is script after all — racing performance ain’t the point.

Mapping/Connecting a Drive Letter to a WebDAV or Front Page website

Mapping/Connecting a Drive Letter to a WebDAV or Front Page website


Apparently Windows XP makes this possible through an integrated WebDAV client and updated Net Use command.  For icing: if you have a Passport, you can map your online Documents folder to a drive letter with this command:
net use * “ Web Documents/Documents” /persistent:yes /user:

Tons of cool possibilities with this…  (Now if we could just do the same with FTP!)

I just setup a webDAV-enabled website in IIS, enabled HTTPS, setup a couple virtual directories with pass-through authentication to my file server, and voila! thanks to the above trick, I can have secure, full-control remote access to it from anywhere.

Actually, there was a lot of toil to the process, since there are a lot of bugs and tricky bits with DAV, HTTPS, and UNC Virtual Directories.  Here’s useful info I found when wrestling my share of them…



Passthrough Authentication:

Web Folders:

Virtual PC: Shrinking a new Virtual Disk

Lemme see if I’ve got this process straight now. Create the Virtual Machine, then…

  1. Host: Compress the Virtual Disk file.
  2. VM: Start the VM and Install the Guest OS.
  3. Guest: Disable pagefile entirely, and restart OS.
  4. Guest: Stop all services.
  5. Guest: Compress entire hard drive(s).
  6. Guest: Defrag til the cows come home (at least 20x).
  7. Guest: Restart needed network services, so I can…
  8. Guest: Install Eraser, create a new “zeroes” method of unused space overwriting, setup unused space task.
  9. Guest: Run Eraser (possibly 2x).
  10. Guest: Shut down OS & VM.
  11. Host: Run Virtual Disk Wizard to compress Virtual Disk to new file.
  12. Host: Defrag Virtual Disk file til the cows come home.

Dang… that’s involved! VMWare definitely beats Virtual PC here.

It’s several hours worth of drive grinding, in fact, but it’ll get that image file as small as possible, and should make it run faster.

Alright, so I’ve doc’d the process for future reference. Some further explanation and tips:

  • I compressed twice, both in the guest and host OS. This does several things:

    1. Sacrifices CPU for better hard disk performance, which is Virtual PC’s speed bottleneck.
    2. Frees more space in the Guest OS, which can then be zeroed-out and shrunk more effectively by the Host OS’s file compression.
    3. Achieves an overall smaller image file. When combined with “trimming the Windows fat” *, it can make VMs of most basic Windows installs fit on a single CD.

  • I stopped all services for the compression and defrag. This unlocks more files which can then be compressed and defragged.
  • I defragged til the cows come home, because…

    1. A spanking fresh Windows install is already quite fragmented, and file compression fragments it much more.
    2. Windows’ built-in defragger is by no means thorough. Running it several dozen times is as close as it gets. Fortunately this can (now) easily be scripted for easy walking-away.
    3. Theoretically, free-space defragmentation should also help the external compression scheme too, but this is the worst . Most 3rd-party defrag tools would be more effective at this.

  • Step 8 may need to be repeated. I’m not sure why, but sometimes Eraser doesn’t do the trick the 1st try. The indication of this is the Virtual Disk file not actually shrinking.
  • I suggest disabling Undo disks for this process. It only adds one more looong step of merging the undo disk with the original.
  • Step 3: If you’ve got the RAM (say 1GB), give it to the VM and disable its pagefile. That’ll further bypass the slow disk issue.
  • Step 12: I use Defragmentor Lite for single-file defragging. I also sometimes find it effective to switch between that and Windows’ defrag utility.
  • * “Trimming the Windows Fat”

    1. Uninstalling via Windows Add/Remote Components: MSN Explorer and most of Windows’ Accessories (I just keep Paint around for screenshots).
    2. Uninstalling via various obscure commands:

      • Agent: %windir%\system32\RunDll32.exe advpack.dll,LaunchINFSection %windir%\INF\agtinst.inf, RemoveAgent
      • Messenger: %windir%\System32\RunDll32.exe advpack.dll,LaunchINFSection %windir%\INF\msmsgs.inf,BLC.Remove

    3. Deleting various nonessential files:

      1. All temp files
      2. Search for files matching “*.bmp; *.wma; *.wmv; *.wav”. Of these, most of the biggest ones can be deleted without being noticed.
      3. Possibly %windir%/DriveCache/ ? Hardware won’t change in a VM. I’ve successfully done it before without problem. The worst that should happen is prompting for the install CD. Not sure what other repercussions this could have.

As way of disclaimer: I’m no expert/guru/pro with VPC. These are just my learnings and observations so far after a few years’ use and fiddling. I’ll gladly defer to the pros on this, but I haven’t seen much on this subject either.

2005-03-12 update: I just found out that SP1 for VPC makes the disk prep steps slightly simpler (the “zeroing” part).  It does this via a new Virtual Disk Pre-compactor CD image which it makes available for mounting, which saves the extra hassle of installing and configuring Eraser.  (via Robert Moir’s excellent VPC site)

“Show friendly HTTP error messages”

I’d just like to volunteer something: “Show friendly HTTP error messages” was one of the worst thought-out features ever added to IE.

The few times I’ve missed it on a new development workstation have been absurdly baffling (“give me some useful error information!!!”).  The many times a user has said “it doesn’t work” but had no more details and no error message have been all the more painful to track down.


(at least the fix is scriptable, so I’ve just added it to my standard “prefs” scripts..)