Feb 21 2006

I wish I would have though of this

I was looking at CNN and noticed that Symantic had identified a flaw in Apple’s Bluetooth, allowing individuals to infect a user’s machine through Apple’s wireless implementation. Its not too surprising that a flaw was found there (I’m surprised Windows hasn’t had more problems in this area) — this seems like a likely place where vulnerabilities would popup. Anyway — security researchers have such a great job — all they have to do is basically try to break their computer. Although, I do cause a number of crashes when I first start researching new API so maybe that could be a future profession.

–Terry


Feb 21 2006

Kenny’s first letter to mom

I got this message from my wife today. Apparently, Kenny took it upon himself during his quiet time to write Alyce a note. Here’s the message that she sent to me. Remember, he’s only 4 and wrote this all by himself:

Hi Terry,

This would be under the heading “things that make it all worthwhile.” Kenny
made me a card during his quiet time today.

It says, “i luv yw Frum Kenny”

So cute! It’s going on the fridge.

Hope you’re having a great day. Love you bunches.

Alyce

I was so impressed that he actually spelled out the words correctly if you spelled phonetically. Plus, I was impressed that he wrote the note for no other reason than he loves his mom. I did a quick scan of the note in case anyone is interested in seeing his handy work. Now if I can just teach him how to write code in PHP. :) kennyletter2.jpg
–Terry


Feb 21 2006

Google acknowledges security concerns with Desktop Search V.3

Its interesting to see how Google’s attitude towards many things have changed throughout the years.  In a recent article posted on ZDNET, Google’s representatives officially note that their new “Search Across Computers” feature in version 3 of their Desktop Search is indeed a concern for enterprise organizations.  But their answer is somewhat gauling.  They say:

“At the end of the day, each company should make its own decision. If they are uncomfortable, they shouldn’t enable the feature,” Ku said. “It’s about what a company deems to be best corporate policy.”

This is true — but each company’s policy will only be as good as those that implement it.  Since Google’s desktop search utility doesn’t have a simple method for administrators to limit the functionality of the tool (its either all or nothing, unless you have the enterprise tool) — all it takes is one person on a companies interanet to download, install and enable this feature and suddenly, the organization is exposed. 

But as I said, this isn’t the type of answer that I would have expected from Google — a company who’s mantra is “do no evil”.  While the company skirts close to a gray area — they certainly have provided software that potentially could be (and I’m sure has been) abused by its users simply because they don’t completely understand the new functionality.

–Terry


Feb 21 2006

Exposing a C# component as a COM Server and other GAC related issues

(Sorry about the initial formatting in Firefox. Wordpress didn’t like the xml style comments that get inserted into C# so I’ve removed them.)
Exposing a C# component as a COM Server and other GAC related issues
There are actually quite a few good sites that document how this works, but during the process of setting up a .NET component as a COM server, I ran into a number of issues that I hadn’t expected and thought I would post some information and hopefully save other folks the headaches. And I guess this is partly due to the fact that I was mostly interested in setting up my objects for vbscript/PHP/python access and in order for that to happen, the COM object would need to support late binding. Most of the documentation you will find online only will note how to create a COM server that supports early binding through the use of the generated type library. I’m hoping that this post will fill in some of those gaps.

Exposing the COM object:

So lets start with the basics. You have a .NET component and you want to expose it as a COM object – what exactly do you need to do to make this work. Well, first, you need to create the interface, event and vtable. So here’s the steps and example code:

  1. import the System.Runtime.InteropServices;
  2. Next, we need to setup the COM interfaces. The first option defines the interface and sets up the vtable to expose the objects of the component. Next, you setup the Events and finally, attach the final automatic commands to the main class. Also, of note. You need to create unique GUID statements for each of these three elements. So example, the code would look like:

using System;
using System.Runtime.InteropServices;
namespace MARCEngine5
{

[Guid("337B0A89-A6A6-4122-8932-D2809352BF6D")]
public interface MARC21_Interface
{
[DispId(1)]
int MarcFile(string sSource, string sDest);

[DispId(2)]
int MarcFileEx(string sSource, string sDest, int lFlag);

[DispId(3)]
int GetError{get;set;}

[DispId(4)]
int MMaker(string sSource, string sDest);

[DispId(5)]
int MMakerEx(string sSource, string sDest, int lFlag);

[DispId(6)]
int MARC2MARC21XML(string sSource, string sDest, bool bNamespace);

[DispId(7)]
int XML2XML(string sSource, string sDest, string sXSLTPath);

[DispId(8)]
int ReadMARC21XML(string sSource, string sDest, string sXSLT, int lFlag);

[DispId(9)]
int XML2MARC(string sSource, string sDest, string sXSLT, string sMARCXSLT, int lFlag) ;

[DispId(10)]
int MARC2XML(string sSource, string sDest, string sXSLT);

[DispId(11)]
int XMLFile(string sSource, string sDest);

[DispId(12)]
int XMLtoXML(string sSource, string sDest, string sXSLTPath);

[DispId(13)]
int MARCXMLtoMARC(string sSource, string sDest, string XSLT);

[DispId(14)]
int XMLtoMARC(string sSource, string sDest, string sXSLT, string sMARCXSLT);

}

[Guid("92F0772D-0E9B-41a3-B1B0-216DEAF813A6"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface MARC21_Events

{}

[Guid("D4F347E9-AEFB-461f-AAC8-04315C79327A"),
ClassInterface(ClassInterfaceType.AutoDual),
ComSourceInterfaces(typeof(MARC21_Events))]
public class MARC21: MARC21_Interface

{

3) Next, the assembly will need to have a set GUID for the assembly itself. In the AssemblyInfo.cs file, you need to set the GUIDAttribute element with a unique GUID that will identify the component when registered. Oh, and the GUIDAttribute is in the System.Runtime.InteropServices namespace, so that will need to be imported into this file. Example:

[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile(@"..\..\MARCEngine.snk")]
[assembly: AssemblyKeyName("")]
[assembly: GuidAttribute("39BD230C-F771-4f31-97CD-822E93208197")]

4) Something you might have noted in the above code snippet is that the class as been given a strong name. This is being set in the AssemblyKeyFile. Why is this there? Well, in order to setup your component as a COM server, you will need to move your component into the GAC (Global Assembly Cache). However, only strong-named components can be moved into the GAC, so you need to sign the component. How do you sign a component….Microsoft provides a tool in the SDK called sn.exe. You need to use this tool to create a keyfile that will assign a strong name to a defined component. However, something that the documentation doesn’t tell you is that once you sign a component, a number of things need to happen.

  • Once a component has been signed, all components that it references must be signed. This means that if you have created another component an have referenced it within this object (for example, you are creating the COM component as a wrapper around a number of .NET assemblies), all referenced components must be signed as well
  • Once a component has been signed, all files that access this newly signed referenced component must be recompiled. A component compiled against a component without a strong name cannot then use the component within a re-compile once the component has been given a strong name.

5) Once you’ve setup the above, you need to compile and create a type library. The easiest way to do this is to set an option in the project’s build options. Under build, there is an option marked as “Build for COM Interop”. Set this to true (see below). This option will essentially performs the task of running the regasm command, both registering the component and generating the type library.

interop.PNG

6) Ok – you’ve compiled your code and everything is working on your machine. How do I move this to someone else’s. Easy, right? Ha! You would wish. Basically, when installing your COM component onto someone else’s machine, you need to do the following:

  1. Register your assembly (Regasm)
  2. Move your assembly to the GAC (gacutil)
  3. Move all referenced assemblies to the GAC (gacutil)

Now, the three steps above are basically what setting the Register for COM Interop option did for you when you built the component. However, now you have to do this for your clients and the utilities that I’ve noted, the Regasm and gacutil, these are utilities that likely will not be on your client’s machine. The gacutil generally ships with the SDK – the Regasm ships with Framework 1.1+. So you will likely need to fine another method to register your component

7) Fortunately, the .NET framework provides a method that can be used to register assemblies and move them into the GAC. These methods are found in the System.EnterpriseServices.Internal namespace. So, what I’ve found (and what I’m doing with MarcEdit) is that building a bootloader to handle this process for you is generally the simpliest way of setting up your assembly for COM. The code for this is very simple. You utilized the Publish Object in the System.EnterpriseServices.Internal namespace, calling functions: RegisterAssembly and GACInstall. Likewise, then you uninstall your application, you will want to call: UnRegisterAssembly and GACRemove to clean your assemblies from the GAC and remove the necessary registery entries. So an example of this type of code would be:

Publish p = new Publish();

if (Array.BinarySearch(args,”-u”)>-1)
{
//We are uninstalling….
if (System.IO.File.Exists(AppPath() + @”MARCEngine.dll”))
{
p.UnRegisterAssembly(AppPath() + “mengine60.dll”);
p.UnRegisterAssembly(AppPath() + “marc82utf8.dll”);
p.UnRegisterAssembly(AppPath() + “meUTF2MARC.dll”);
p.UnRegisterAssembly(AppPath() + “MARCEngine.dll”);
p.GacRemove(AppPath() + “MARCEngine.dll”);
p.GacRemove(AppPath() + “mengine60.dll”);
p.GacRemove(AppPath() + “marc82utf8.dll”);
p.GacRemove(AppPath() + “meUTF2MARC.dll”);
}
}else{
//We are uninstalling….
if (System.IO.File.Exists(AppPath() + @”MARCEngine.dll”))
{
p.RegisterAssembly(AppPath() + “mengine60.dll”);
p.RegisterAssembly(AppPath() + “marc82utf8.dll”);
p.RegisterAssembly(AppPath() + “meUTF2MARC.dll”);
p.RegisterAssembly(AppPath() + “MARCEngine.dll”);
p.GacInstall(AppPath() + “MARCEngine.dll”);
p.GacInstall(AppPath() + “mengine60.dll”);
p.GacInstall(AppPath() + “marc82utf8.dll”);
p.GacInstall(AppPath() + “meUTF2MARC.dll”);
}
}

And that’s pretty much it. Simple right? J There are a number of very good links that provide a better explaination to some or parts of this process, starting with Microsoft’s documentation. Some of these links are:

If anyone has any other questions about how this works, feel free to give me a holler or leave a comment.

–Terry


Feb 20 2006

Kennyisms

I love listening to Kenny as he continues to grasp new concepts.  Case in point…we have a dog, a yellow lab., and will be having her spayed.  I doubt he understands what it means, but he’s heard me talk about it.  Well, we borrowed a kitty movie from the local library and at the end of the movie, it says something like, always remember to spay or neuter your pets.  Well, he comes up to my wife and says: “I learned a new word on my kitty show but it’s not a bad word it’s a good word.  It’s ’stay new to your pet’.”  Apparently, it took her a little while to realize exactly what was being said — at which point, she explained what that meant for Goldie…and I laughed and laughed. :)

–Terry


Feb 19 2006

MarcEdit 5.0 & COM II

So it looks like I’ve gotten this working.  I’m going to be sending a private build out to a few testers tomorrow to see if they can confirm that it’s working outside of my controlled environment.  The solution ended up being one that I wasn’t all that wild about, but there wasn’t much I could do about it since Microsoft setup the model as to how .NET and COM interact. 

So here’s the solution…within .NET, there is something called the GAC (Global Assembly Cache).  The GAC is where system wide assemblies get installed.  It’s a special location that requires administrator rights to install into.  It’s also a place that requires assemblies to have strong names, which means that every library linked to the library must have a strong name…ie., more work for me.  Anyway, what it comes down to is that to implement COM, a new library: MARCEngine.dll and MARCEngine.tlb were created to wrap the .NET functionality being exposed.  On installation, the MARCEngine.dll library is installed into the GAC…but so are the mengine60.dll, the marc82utf8.dll and the meUTF2MARC.dll libraries because they are directly referenced to the MARCEngine.dll library. 

I had hoped that I would be able to avoid dealing with the GAC and simply register the generated TypeLib if possible — but there were a number of issues with that — the primary one being that the TypeLibrary in .NET only provides early-binding functionality, something not allowed in scripting languages like VBscript, hence the necessary of COM (for power users) made working with the GAC unavoidable.  Right now, I am testing three things:

  1. On install/reinstall, the libraries and GAC are being refreshed rather than having objects installed side-by-side (Think DLL-Hell without the fun)
  2. That if a guest user installs the program, that just the COM functionality is simply disabled — and the rest of the program installs normally (I personally am running the program off a USB key most of the time, so this is important to me)
  3. That the Object is just being registered once it gets outside my controlled enviroment. 

The nice thing is, if a user installs without the necessary permissions to install the COM, the bootloader that does the registration will be in the program directory so COM setup can be done at a later time.

Anyway, lots of work yet todo.  I’m hoping that I’ll get the OK from my testers in the next day or two, and given no problems, I’ll be looking at posting the revision on Tuesday or Wed.

Cheers,

–Terry


Feb 18 2006

Playstation 3 for $800+

There was a news report on slashdot that I’m hoping was overestimated — but there is a report that the Playstation 3 may sell for nearly $900 dollars.  For that kindof cash, you might as well spend a few extra bucks and get a real computer from Alienware (I love their tower designs) with the new AMD64 dual core chips.

–Terry


Feb 18 2006

MarcEdit 5.0 and COM

I’m looking to release an update to MarcEdit this weekend to include the following:

  1. COM automation objects to the new MARCEngine
  2. zipped version of files needed to run the command-line version of MarcEdit on other platforms

So what’s been the hangup with the COM — well two things.  First, Microsoft has a C# specification on how to create COM objects.  Part of that specification includes the ability to provide functions with optional parameters.  Well, this option appears to only be consumed in VB.NET, not C#.  What a pain.  This means that in some cases, two functions will now exist (Function and FunctionEx) when in some cases, only one existed in the older versions of MarcEdit. 

The other problem, registering these components on others machines.  I’ve got it running just fine on my machine, but I’m trying to come up with a fairly none evasive (i.e., non-GAC) way to register the COM objects.  I have a couple of ideas — so long as they work in testing, I’ll push out the update.

–Terry


Feb 18 2006

Code4Lib: Feb. 17: Final thoughts

Just some final thoughts on this conference.  First, IRC…I’ve not spent a whole lot of time playing around on the code4lib IRC channel – but the IRC added a very interesting dynamic to this conference.  In fact, in some cases, the back conversation provided as much information as the presentations.  It was great.  My goal now is to keep on IRC and coming back to the code4lib channel and community. 
Oh, and something that was interesting…since I use Windows, I had to find a free IRC client and the only one that I really could find that was any good was Chatzilla for Firefox.  This got me thinking – I’m wondering how difficult it would be to write a IE IRC plugin so that I can get onto IRC from either browser (I tend to use both, IE 7 and Firefox equally). 
Also, it was great to finally put a face to a number of folks that I’ve chatted with only through email or have been aware of only poriforally.  I guess this is pretty much been my own fault for not being an active part of the code4lib community in the past.  Hopefully, remeding that will help keep me connected with great individuals that I got to meet over the past three days. 
As the final presentation says, code4lib:  code=love, love=code. 


Feb 18 2006

Code4Lib: Feb. 16: 20 minute sessions 2 + breakouts/lighting talks

Teaching the Library and Information Community How to Remix Information
Raymond Yee
The one thing that sticks out in this session is that someone is actually showing MLIS students how information can be remixed.  I just got out of an MLIS program 3 years ago, and I don’t remember this type of a class being available.  Hopefully this means that library schools are starting to teach this concept.
Two Paths to Interoperable Metadata
Devon Smith
Because of MarcEdit, I was very interested in Devon’s presentation.  To be honest, he got my attention when he said that XSLT was simply the wrong model for doing metadata transformation (at this point, it’s the best the rest of us got) since nearly every transformation system I’m working on uses XSLT.  However, apparently, OCLC uses a different system that they have been developing called Steel and ROM (Record Object Model).  The process uses maps and provides transform reversability.  Its something I’d like to test, but unfortunately, OCLC isn’t currently looking to make this tool available as open source.
The Case for Code4Lib 501c(3)
Roy Tennant
Roy talked about some of the different options code4lib could utilize if the group wanted to become more formalized.  The conversation ranged from non-profit, a cooperative, etc.  A breakout session followed that discussed this in further detail.
Breakouts/Lighting sessions:
I attended the metadata crosswalk breakout session to get a bit more information on the OCLC steel methodology and then was one of 22 folks that gave lighting talks.  I did mine on MarcEdit 5.0, partly because I think that this group could find a lot of its functionality useful for testing their own tools or to have others within their organization use.