Archives for: February 2008
18/02/08
The joy of proper command line tools
I seem to be having lots of these problems lately that somehow always come up, but never get solved. This time it was the problem of creating a zip file including a large source code hierarchy, but excluding certain directories along the way. More specifically, there are directories called .svn, obj or bin at various places in the hierarchy, and I don't want to include those. Although I've looked around many times, I was never able to find a compression tool that would allow me to specify exclusions flexibly enough to take care of this use case - go try it with your favourite packer if you think I'm wrong. Most of them have an exclusion feature, but not a single one that I found was able to handle this case.
The solution was really simple: use some command line tools. No, not stupid Windows ones, proper GNU ones. Cygwin was, of course, already on my machine, so I simply created this little bash script:
#!/bin/bash FIND=/usr/bin/find GREP=/usr/bin/grep EXCLUSION='(/(.svn|obj|bin|build)/|.suo$|.user$|.exe$|.dll$|.pdb$|~$)' while [ "$1" != "" ]; do $FIND "$1" -type f | $GREP -E -v $EXCLUSION shift done
This script takes file or directory names on the command lines and lists all files hierarchically from those starting points, excluding those that match particular (regular expression) patterns. Simple, isn't it? Having this as a separate script allows me to reuse it (from the Cygwin command line, of course):
./listfiles.sh Demo cheatsheet.tex cheatsheet.pdf "Workshop C#.pptx" | zip -9 complete.zip -@
And since I need to run that command regularly, I have created another little script that runs it. Done. On to something useful. How in the world do Windows users live without this sort of functionality? Are you one of them? Tell me!
Yes... I know I should have a much closer look at PowerShell to see how it can help me with this. I have actually looked at PowerShell in some depth, but from the perspective of a programmer, not a system administrator. I promise, I'll try to find the time to see about this, and report my findings.
08/02/08
.NET 3 - The Game Challenge at VBUG Newcastle
I did that presentation there yesterday. I had added a piece on top, to stretch things a bit more in the direction of WCF: the Game Status Viewer uses an additional published service to query game status information and displays that in a console window.
Here are the slides and samples in that most current version: Net3GameChallengeNewcastle.zip (393498 bytes)
During the presentation I also mentioned that permissions problem that comes up when you run the sample from Step6 as an "ordinary" user. If this happens, you will get an error message like this: HTTP could not register URL http://+:8888/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details).
The link to the Microsoft page has all the information you need, not just for Vista, but also for other Windows versions. On Vista, you use the netsh tool (as administrator) to add an entry to the urlacl list:
netsh> http add urlacl url=http://+:8888/ user=\Everyone
Of course this example is not very secure - modify as needed. Removing the entry from the urlacl list is equally easy to do:
netsh> http delete urlacl url=http://+:8888/
A word of caution: in any real world application you should carefully evaluate your requirements when this happens to you. These URL namespaces are protected for good reason, and making them available for arbitrary use may have security implications. If you examine the default urlacl list, you will see that there are entries there for certain use cases, like the one for the URL http://+:80/Temporary_Listen_Addresses/. You should probably use those in most cases instead of creating your own.
Important Update:I just heard from my friend Dominick that I'm really full of shit (update to the update: Dominick just asked me to make it clear that "full of shit" were not the words he used <g>
with regard to that recommendation I was making above. The entry http://+:80/Temporary_Listen_Addresses/ is in fact there for a particular purpose, but that purpose is not for anybody else to use it. It is also highly doubtful whether it's a good idea for that entry to be there at all, since it introduces a security hole by default... well, that was actually something that came to my mind when I saw it, but I wasn't going to go into it in any detail. Anyway, apparently this hole should really have been removed in .NET 3.5, but it didn't happen. In any case, again, it's not recommended you use it.
So what are you supposed to do? In general, Microsoft takes the position that establishing a listener on a machine is always an operation that should require administrative privileges. I'm not entirely sure I agree with that, but that's a different matter - in any case it always requires an administrator to do some configuration work when a process that doesn't have admin privileges itself wants to do some listening. In the case of a boring TCP listener, it will be the Windows Firewall that reacts to this, and it brings up the usual nice UI that allows anybody with a knowledge of the Administrator password to do what's necessary to make the process work. In the case of the HTTP listener, like in that demo of mine, it's not the firewall, but instead http.sys, the subsystem for the handling of HTTP communications, that reacts to the listener becoming active. Http.sys in turn requires some special privilege handling because it uses a mechanism known as port sharing internally - yes, even if there isn't actually any port sharing (in the colloquial sense) going on. For some reason, the powers that be at Microsoft have decided that a UI for this configuration, like the one the firewall has, is not needed... or whatever. In any case, it's not there. And that's what makes fiddling with netsh necessary.
Back to the question what you're supposed to do. There are a few different things you could do. First - don't use HTTP. WCF makes it very simple to go for TCP instead, for instance, and while there's still security infrastructure in place, it's a lot easier for the end user to deal with, assuming he knows the Administrator password. Of course one downside of this is that you can't publish anything that requires HTTP to comply with expectations, like XML Web Services. Second - establish your own specific rule using netsh. Specific to your application, that is. The optimal way of configuring this rule would involve specifying a URL that's as complete as you can make it, use a non-standard port, and create your own user group to assign the privilege to. If you don't want your own user group, at least make sure not to use \Everyone - NT AUTHORITY\INTERACTIVE or NT AUTHORITY\Authenticated Users is a lot better than that.
So that's it. I wasn't going to go into a great level of detail on this, but there you go... at least I think my recommendation makes a lot more sense now. Dominick has a wrap up of his http.sys related discussion on his blog (and here's his original post). He's also written a tool for http.sys acl configuration on Windows XP and Server 2003, which you can find here.
05/02/08
Vista spooling/printing delay - solved
I've been having a weird problem with printing on my Xerox Phaser 8550 from Vista. One of those issues that have been around forever, but I never found time to look into. The problem was that after a print job had been spooled, it sat in the print queue for something over a minute before being sent to the printer. At least it was my impression that this was the case, although of course it's kind of hard to see what's really going on once the job is in the queue.
I searched around for a while today and found a bunch of people with similar problems, which were apparently related to a Vista fix (KB935807). In many cases these issues were about Canon printers and/or came up only in conjunction with Word 2007, so that didn't seem to fit my own problem. I still tried switching off Windows Firewall, which helped a lot of these people, but that didn't change anything about the issue I was seeing. Of course I also tried reinstalling the driver (btw - if you have trouble doing that, try first removing the printer that's already installed), but to no avail.
In the end I'm still not sure what the actual problem was, but I did find a workaround. I configured my port to use the LPR protocol instead of port 9100 RAW for the network communication. I had to enter a queue name for this configuration, but "lp" was either the right guess or it just didn't matter. In any case my printer now starts working almost immediately after spooling a job, like it always used to do way back when I was using XP. Great.


