Alasdair's profilealasdair's brain dumpBlogNetwork Tools Help

alasdair's brain dump

cos otherwise I'll forget I even knew it
6/1/2009

VS2008, Item Templates and Unicode files to ANSI

I’ve just created a load of text files with Visual Studio 2008, only to discover they’re:

Unicode (UTF-8 with signature) – Codepage 65001

Very annoying because I wanted ANSI files, and they get marked as binary in Subversion (well, actually they get automatically tagged with the svn:mime-type “application/octet-stream”).

The cause of this is that the item templates for TextFile in Visual Studio have the Unicode byte marks.

The solution is to knobble them in your copy of visual studio:

Go to

%ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates

and search for TextFile.zip.

On x64 they’re here:

%ProgramFiles(x86)%\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates

Anyway, depending on your edition of Visual Studio and your installation choices, you may find several of these. In each case, you need to overwrite the two-byte or three-byte TextFile.txt in the zip file with a zero-byte version.

You’ll also want to similarly knobble any other TextFile.txt you can find in your Visual Studio directory – there are several in mine which are used to create files when not inside a particular project type.

Once you’ve sorted all this out, you need Visual Studio to refresh template cache:

 

x86: "%ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com" /setup

x64: "%ProgramFiles(x86)%\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com" /setup

 

So, what do you do if you have just created dozens of Unicode files which you now rather wish were ANSI?

Well, my answer in powershell 1.0 is as follows:

Get-ChildItem -recurse -filter "*.sol" | foreach { $_.Name | Out-Default; ( Get-Content $_.PSPath ) | Set-Content $_.PSPath }

Obviously my files all ended in the .sol extension and were spread around a whole directory tree – you can change the options for Get-ChildItem to suit your purposes.

And finally, because for some reason (I think TortoiseSVN had already added the svn:mime-type “application/octet-stream” properties):

svn propdel --recursive --quiet svn:mime-type .\*

And that’s all for now, folks!

4/27/2009

Getting trixbox 2.6.2.2 Postfix to relay through Exchange Server 2007

The scenario here is a trixbox server in a predominantly Microsoft shop, and specifically where emails are to be relayed through the local Exchanger Server 2007.

If you just try to relay doing the obvious it wont work:

http://trixbox1/maint/index.php?generalsettings

General Settings

The reason is not obvious:

  1. Even if you leave the Auth Name and Password blank, Postfix will still attempt authentication
  2. There appears to be a bug in the trixbox GUI where it fails to run Postmap after setting the credentials (see below)
  3. The default trixbox doesn’t have any authentication methods installed which are compatible with Exchange Server 2007
  4. Setting up Relaying on Exchange Server 2007 is 10 times harder than it was in 2000/2003.

There are some articles which explain how to configure Postfix to attempt an anonymous send. This is OK if all target user email addresses are on domains for which the relay server is authoritative, but not good if you want to relay through Exchange Serve 2007, unless you want to build custom receive connectors in Exchange 2007.

It is much better (more secure, less likely to accidently create an open relay) to get Postfix to authenticate against Exchange and the grant it the appropriate permissions to relay. Here’s how.

  1. Set the credentials as show above. That’s the easy part.
  2. Rebuild the saslpasswd database file:
    at the trixbox command line:
    postmap hash:/etc/postfix/saslpasswd
  3. Add appropriate authentication mechanisms to Postfix:
    1. Enable the CentOS Base Package in http://trixbox1/maint/index.php?repo
      Note – I’ve just looked again and I think they may have put the required sasl packages into the trixbox repository, obviating the need for this step.
    2. If you’re happy with the command line, use something like:
      yum install cyrus-sasl-ntlm
      yum install cyrus-sasl-gssapi

      (not tested)

      - Otherwise -
    3. If you haven’t already made the Package Manager fix, do so now:
      vi /etc/php.ini
      Change:

      max_execution_time = 300
      memory_limit = 256M

      Restart apache:

      service httpd restart

    4. Go to the package manager at http://trixbox1/maint/index.php?packages
      - it will take a while to load

      Select to install the following and click the install button:

      cyrus-sasl-ntlm
      cyrus-sasl-gssapi

    5. Restart Postfix:

      service postfix restart
  4. In the Windows world:
    1. If you haven’t already done so, create the user account in active directory. Make sure the password matches what you entered in the very first step in this article.
    2. If you try to send mail now, it might work. Specifically, it depends on the way the “MAIL FROM:” address correlates with the list of domains for which this server is authoritative. If you get mails bouncing with the dreaded message:

      5.7.1 Client does not have permissions to send as this sender

      Or, if you simply aren’t seeing any mails at all, move on to the next step
    3. Open the Exchange Management Shell, because the incantation we’re about to do has no GUI equivalent.
    4. You will normally have two Receive Connectors called “Default XXX” and “Client XXX”. Get their names as follows:

      Get-ReceiveConnector
    5. Use the name of your “Default XXX” connector and your chosen user name (mine is “voip”) to grant that user full relay rights:

      add-adpermission -identity "Default XXX" -user "voip" -ExtendedRights ms-Exch-SMTP-Accept-Any-Recipient
      add-adpermission -identity "Default XXX" -user "voip" -ExtendedRights ms-Exch-SMTP-Accept-Any-Sender
    6. There are some constraints on the settings of the “Default XXX” Receive connector, but I think the defaults are fine. Let me know if you have problems.
  5. Done & Dusted!

It reality, stuff seldom works out first time. The tools I found helpful were:

PuTTY – don’t even start working with trixbox unless you have this

webmin installed on the asterisk box:

    See http://www.webmin.com/rpm.html
    cd /etc/yum.repos.d
    vi webmin.repo
        a
        Paste this (with right mouse button)
[Webmin]
name=Webmin Distribution Neutral
baseurl=
http://download.webmin.com/download/yum
enabled=1
        <esc>
        :wq
    rpm --import
http://www.webmin.com/jcameron-key.asc
    yum install webmin
    Check it out by browsing to https://trixbox1:10000

webmin has the ability to edit Postfix settings in a nice environment and to look into Postfix mail queues, logs and even mailboxes to see what’s going wrong.


Microsoft Network Monitor 3.2 – great for watching the SMTP conversation

3/8/2009

Part 2: The file foo.asmx has not been pre-compiled, and cannot be requested

It turns out you can also get this error from mixing up your 32-bit and 64-bit DLLs. Running in the Visual Studio debugger with Cassini as your webserver, everything's 32-bit, but if you try to run a 64-bit website and one or more DLLs are compiled as x86, you get this error as well. I tracked it down by setting a virtual directory on my local IIS7 on my Vista x64 developer's rig to point to the code which was working when I pressed F5, but failing on the production server. Pointing at the PrecompiledWeb gave the same result as on the production server, but pointing at the source code told be which DLL was an "invalid image" or some such nonsense - i.e. the one compiled for the wrong target architecture.
2/24/2009

Adventures with .NET and COM

I was working with PDFCreator and downloaded the 0.9.7 release. It refused to install the pdfforge .NET dll because it said I hadn’t got .NET 1.1. Well, as most .NET 1.1 assemblies will run happily in .NET 2.0, I thought I’d have a go with it.

I got the pdfforge dll and test scripts from SourceForge and tried the scripts. No dice. So next I looked at the assembly in Reflector and found an unresolved reference to iTextSharp, which also thinks its a .NET 1.1 assembly. The plot thickens though, as when I got the iTextSharp DLL, it still wouldn’t load it. It turns out that in the comments in SVN, the pdfCreator guys did say they built iTextSharp from source, and they’re reference is to v 4.1.2.1 without a strong name, whereas the latest release binary of iTextSharp is 4.1.2.0 with a strong name. In order to get them to “talk” I needed to either change the reference baked in to pdfforge.dll or change the assembly version baked in to iTextSharp (and remove it’s strong name), or build iTextSharp from source…

Well, enter the Reflexil add-in for Reflector. Wow! With this I had a choice – it’ll let me fiddle with assembly versions, strip strong names, fiddle with assembly references, even hack the code & save it back. Get it from SourceForge.

 

Reflexil in Reflector

 

So, with my demo code running nicely in c#:

using System;
using pdfforge.PDF;

namespace AcsComms
{
    class Program
    {
        static void Main( string[] args )
        {
            PDF pdf = new PDF();
            pdf.CreatePDFTestDocument( @"C:\Temp\PDF\Testy.PDF", 1, "Have at it, matey!" );
        }
    }
}

I tried to RegAsm the pdfforge.dll. Two gotchas here.

  1. The first time I did it, I forgot to use the /codebase option, so COM & mscoree couldn’t find the DLL.
  2. On my x64 Vista, I used the RegAsm in C:\Windows\Microsoft.NET\Framework\v2.0.50727, which is 32-bit. Consequently the registry entries got written to HKEY_CLASSES_ROOT\Wow6432Node\CLSID, and I could only use the DLL in 32-bit land, e.g.

    C:\Windows\SysWOW64\wscript.exe "C:\Program Files (x86)\PDFCreator\PlugIns\pdfforge\nUp.vbs"

    This was fixed by re-running RegAsm in the 64-bit framework directory:

    C:\Windows\Microsoft.NET\Framework64\v2.0.50727\regasm "c:\Program Files (x86)\DFCreator\PlugIns\pdfforge\pdfforge.dll" /codebase

 

So now I can just double-click on the demo .vbs scripts and they work just fine!

1/25/2009

New ACS Solutions Website on OfficeLive.com

Well, ever since the old Rackspace server contract finished, I've had the www.acs-solutions.co.uk domain pointing at the most excellent new poundhost server (silly name but great value and great service) with a trivial holding page. I thought "I must do it properly. I'll get help from a designer, create a great CSS layout, build it using the Microsoft tools - ASP.NET (+- MVC), SQL Server, and maybe a CMS like Sharepoint or DotNetNuke". But the simple facts are that ACS Solutions is a software company, not a web design company, we needed a "shop front" now, and nobody really cares how we've done it... So after a bit a of faffing about, I cheated.

I set up a website on www.officelive.com and used the passable content editing tools to enter the content and give it a basic layout. I picked a colour scheme from their palette which I hope isn't too horrid. It was, to be honest, very easy. I'd recommend it to anyone wanting to create a basic business website without support from a "computer person". The layout uses tables. which is yukky and quite a surprise in this day and age, but right now it’ll have to do.

There are some disadvantages though with OfficeLive. When you get started, it asks if you want to register a domain name. Well, we've had acs-solutions.co.uk for years, so for me and most established companies,the answer is going to be "no". So I got a website with the catchy and memorable url ACSSolutionscouk.Tech.officelive.com. I had expected that there'd be some simple way I could point my DNS at their servers and make it work as www.acs-solutions.co.uk. However, on closer inspection, the supported method is to change your domain's DNS servers to point to the officelive DNS. Arrgghhh! I can't hand complete control over to my domain! What about my mail with spam filtering by postini, my SPF records, my other hosts, etc? Well, the answer lay with a neat trick I learned from Matt Lee when we were at the NHS.

Being an open-source dude, Matt was fronting websites with Apache httpd, and using a module called mod_rewrite to forward requests to a remote website. The thing is, we're a Microsoft shop and don't want to run Apache when we've got IIS7. The good new is that since Windows 2008 and IIS7 were released, the IIS team have released loads of additional modules, and yep, one of them is URL Rewrite. This brings most of the power of mod_rewrite to the Microsoft webserver. We’ve used it effectively as a “404 handler”, so if a page or file exists on our hosted webserver, it’s served straight out, otherwise it’s fetched from our new OfficeLive website. All done in two simple rules.

I hope to replace the OfficeLive site with a full custom effort at some point, but frankly it’s probably not going to be for a while because it just works.

11/15/2008

ContentDisposition Parser .NET Framework Bug

The .NET System.Net.MIME classes are rubbish. They don't help you parse an incoming email and they have (at least one) serious bug. ContentDisposition doesn't respect RFC 822, which is almost pre-historic in Internet terms. See the bug reports on Microsoft Connect: 339010 - ContentDisposition doesn't respect RFC 822 (Section 5) (requires a login).

Using the rather splendid http://referencesource.microsoft.com/Default.aspx I was able to quickly configure Visual Studio 2008 SP1 to go get the PDBs for the .NET framework and then download the source as required - very cool!

I found the offending code in the .NET library (as other's before me also had):

// MailBnfHelper.cs line 823:

static int ReadDateNumber(string data, ref int offset, int maxSize)
{
    int res = 0;
    int maxLength = offset + maxSize;
    
    if (offset >= data.Length)
        throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
    
    for (; offset < data.Length && offset < maxLength; offset++)
    {
        if (data[offset] < '0' || data[offset] > '9')
            break;
        res = (res * 10) + (data[offset] - '0');
    }

    if(res == 0)
        throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
    
    return res;
}

The biggest problem is this:

if(res == 0)
    throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));

This procedure is used to read time components and Timezone. Any value which is 0 will throw an exception. This means any time where the hours, minutes or seconds are zero, and all mail from the +0000 timezone.

There's another bug with the timezones as they can be alpha, e.g. GMT, and they fail too.

This is a weak area of the framework and it simply validates the use of 3rd party mail products that actually work.

10/24/2008

Windows Internal Database

On Wikipedia there's a short article about Windows Internal database. There are several important facts they mention, and some they don't:

  1. You can connect to it with any version of SQL Server Management Studio, including SQL Server Management Studio Express
  2. It only allows connections for the local machine - it does not listen on TCP/IP or externally accessible named pipes.
  3. The pipe name you type into the server name is \\.\pipe\mssql$microsoft##ssee\sql\query

    image 
  4. Although you can create databases and drop objects, the super-secure mechanism to stop you using it for your own purposes is that you can't create objects (tables, stored procs, etc). What you get is:

    Msg 33003, Level 16, State 1, Line 1
    DDL statement is not allowed.
  5. The workaround for point 4 above is to put the database in single user mode while you're doing the DDL:
  6. -- before

    alter database banana set single_user;

    go

     

    -- create whatever

    if object_id( 'bob' ) is not null

          drop table bob;

     

    create table bob (x int );

    go

     

    -- after

    alter database banana set multi_user;

    go

7/20/2008

The file foo.asmx has not been pre-compiled, and cannot be requested"

There are a few reasons this can occur - in my instance I found that the PrecompiledWeb worked fine if I pointed my local IIS at it, but when I copied it to the live server, some of the pages - and critically, 3 out of 4 of my webservice .asmx pages wouldn't work with the above error.

It turns out the pages which failed referenced a number of DLLs in the GAC which were on my development PC but not the deployment server. In my case it was the Microsoft Enterprise Application Blocks, but this could have been any referenced assembly. I had the Enterprise Library 4.0 registered in the GAC on my PC and referenced by the website, but only version 3.1 on the deployment server.

So, the only nastiness really is that the error message is misleading...

5/14/2008

ORCA - MSI File Viewer and Editor

Don't leave home without it!

Read about it here.

Command line options here.

Get it here.

 

Alasdair Cunningham-Smith

Occupation
Location
Interests
Work: MS Developer and SQL Server guru. Work for my own company, ACS Solutions Limited.
There are no categories in use.