Microsoft Tech Ed 2005

by Damon 18. February 2005 06:00
Well, I got verbal confirmation from my new employer that I'll be attending Microsoft Tech Ed this summer. This year's event takes place in Orlando, Florida. Nice location for a geek vacation.

This is kind of a big deal to me because throughout my career things like training and conferences hasn't really worked out. The only trip I've taken on someone else's dime was a two day Scrum Master certification in Denver(Which was cool by the way). Going to a conference (I've heard) is a rejuvenating experience. If you're like me and typically spending more time implementing stuff than reading about the up and coming new tools, this seems like a fantastic way to shuffle off the burnout and get excited about life in the world of Software all over again.

I believe my family is going to come with me for at least part of the week, I think we'll be taking the munchkin to see The Ocean and Seaworld and such the weekend before. As far as the Tech Ed content, I plan to be primarily in the Architecture and Mobile tracts, assuming I can weave a schedule back and forth between those two.

If any other Wisconsin folks are going and need someone to hang out with, contact me.

Tags:

OR Mapping

by Damon 16. February 2005 06:00
I decided this week to scratch an itch I've had on and off for about 5 years. I was writing some data access code for a small web project I'm doing for a bank and started to get the Object/Relational mapper itch again. I have some history with the OR mapper itch. The OR mapper itch replaced the Ojbect Database itch when I realized no one was going to bite on object databases in my lifetime. The first OR tool I ever used was TOPLink, and in my opinion it remains the best by far. I've used many OR tools for many languages since then, all of them have fallen short of solving some part of my data access picture on the applications I've tried them on. To be fair, many of these were due to horrible database design.

At any rate, even in this great day and age I still finding myself writing very similar data access code over and over again for web and windows forms projects. I could, if I had no self respect, just throw SqlDataAdapters all over the place but I usually insist on writing three tier apps with custom types as the means of exchanging data between tiers and layers.

My itch, then, has been to write an OR mapper from the ground up; I want to do this primarly so I'll have one that fits my needs but also just for the experience of designing and building it. I typically work on several things at once, and have some software products of my own that are to be developed this year, so the tool should justify the time it takes to write very quickly. I have some goals for writing the tool that will hopefully make it very interesting to other people:
  1. Support for stored procedures: the MSFT world is very stored proc crazy and very against dynamic SQL, required by every OR mapper I know of. Just having something that can execute a stored proc and map the results back to my application's types would be a big time saver.
  2. Type-to-type mapping: As Philippe DeMilde pointed out one drawback of doing Services Oriented Architecture the right way is the fact that you will end up mapping Message types to the data structure your application uses. This is tedious and prone to human errors. Adding support in this engine to map from instances of one Type to another could be a time saver in many applications.
  3. A nice user interface: This is one thing TOPLink had that I have yet to see anywhere else. The UI should make it so that you configure the tool visually and easily: Connect to a data source, load a Types assembly, highlight a Type/property/table/column/storedproc and display its mapping configuration in a PropertyGrid.
  4. Support Lazy and Eager loading of related Types and Relationships: Lazy loading is really the only way to go so I may force lazy load for Collections.
As I flesh the design out, I'm sure many more things will make themselves known. After giving up on thinking of a clever name for this project I decided to just call it TRAP, meaning "Types, Relationships, and Persistence". After this ephiphany (which occurred Monday afternoon) I went wild and did a component diagram and coded a surprisingly good start to the user interface. The road to completing TRAP will probably be the subject of many of my blog posts for a while.

Behold, a component diagram

Its not much right now, but there is mucho more on the way. The responsibilities for each component should be straightforward.

Types will just represent the mapping structure and data source information and have no intelligence. The Core assembly serves as the interface between consumers of the tool and the internals of the tool. The Engine does the actual work of managing transactions and caching and such. The Provider assembly will implement a couple of default supported persistence targets, like Type-to-SQLServer, Type-to-OleDB and maybe Type-to-Access and Type-to-Type. The idea is that anything that can vary (like SQL dialect or connection string format) will be encapsulated in the provider classes. The Provider, then, is really a plug-in to the engine. I will probably make an identity map/caching mechanism part of the provider model as well.

I'm pretty eager to scratch this itch, especially since I view it as part of the bigger goal of offering 2 products for sale by the end of the year. I imagine by the end of this weekend (depends greatly on my other commitments) I will have a simple "select *" test working round trip: designing it in the UI and running the OR mapper from unit tests. That reminds me, I should add a Tests assembly out there and create a test database with all of the items I want to support. Stay tuned.

Tags:

Product keys

by Damon 13. February 2005 06:00
I have had the pleasure of working on a couple of smaller shrink-wrapped products, and I know many people interested in the shrink wrapped product business. One of the small challenges involved in selling people software is managing your licensing. Back in the 90s almost all consumer software had a CDKey, but it was a joke since all one had to do was dial in to your favorite BBS or call up a friend and ask them for their key. Piracy laws were there but if you were willing to do it, it was no issue.


In today's connected world there are some more complicated schemes. I thought Windows XP product protection was the ultimate protection: it was actually tied to your specific hardware.

So, with that in mind, I set out to try to create something similar in managed code. I wanted to support the following features:
  • Ability to tie an installation to specific hardware
  • Ability to automate the registration process
  • Mitigate any risks to the security that could arise from reverse engineering the code

Step 1, tie an installation to a piece of hardware was easy enough. Using the System.Management namespace and some cryptic Windows object queries, you can obtain all kinds of hardware information. There are ways to PInvoke even more information, but this was good enough to start. Once some hardware information is obtained, a trap door hash algorithm is applied to obfuscate the specific data used. We'll call this part a hardware key.



Step 2, automate the process. Assume now that some kind of product key has been given to a client, and the hardware key has been generated by the software. An online system could easily be created to associate a hardware key to a product key, and for some that might be enough. However, the software should ideally be able to determine if it should allow itself to run. Even more ideally the software should be able to make this determination without connecting to an online system ever time it starts up. By introducing some more complexity this can be accomplished.

We could create RSA key data, or a complete digital certificate, that represents the company licensing the software for use. Due to the great properties of an RSA public/private key pair the company could keep an RSA key (safely) RSA private key data that could be used to sign a "license file". If the license file contains the hardware key, the RSA public parameters, and a signature created based on the hardware key the client could use this license file to determine if its OK to run or not. Consider this scenario:
  1. New installation creates a hardware key
  2. New installation sends its product key and hardware key to a web service hosted by the product company
  3. The web service stores the product key and hardware key, in order to deny permission to other hardware trying to run with this key
  4. The web service creates a private key signature of the hardware key + product key, and sends this information back to the client along with the RSA public key data
  5. The client, whenever it attempts to run, can re-calculate the hardware key, and use the RSA data to verify the signature and allow itself to run


Step 3, code obfuscation is the best way to mitigate the risk of comprimising this strategy, however by using the digital signature piece knowledge of how the system works does not ruin the whole system, and that is the mark of good security. Contact me for code if you are interested. Maybe I should just post code? I suppose I will refactor the system to work within the .NET LicenseManager API, which I found after I got this working the first time.

Tags:

Slacking

by Damon 11. February 2005 06:00
Well, so much for my goal of trying to blog once per week.

With trying to wrap everything up with my last job, starting this new job, and having a grand total of four entities asking for my time right now, I'm somewhat behind on my contributions to the .NET community. (That would be this blog)

I promise this weekend I'll get to at least one of the things I've either promised or thought about posting:
  • SSL-like key exhange algorithm in managed code
  • Creating a verifiable CD-key scheme using managed code and crypto.
  • Creating Designer surfaces in .NET
  • WYSIWYG printing for the compact framework
  • Litmus test rants for enums, services, reference data and more
  • Creating RSS using XSLT and custom types
All in all, I have a lot on my mind and posting about it helps organize those thoughts. I suppose if anyone out there wants to see one of these items before the other, send me an email and I'll do that one first.

Post Script: My "IT Slavery" article wasn't meant as an attack at anyone except the specific individuals I had those conversations with. You know who you are. I really didn't mean to discourage anyone from the rewarding field of consulting either. I've actually gotten email from a student saying
  • I am a student studying C# and I found your blog through google. I don't think I want to be a consultant now.
  • Obviously, despite the issues, consulting is still the life from me, just be aware of what you get yourself into kids.

    Tags:

    Master Pages in .NET 1.1

    by Damon 26. January 2005 06:00


    In the place I am consuling right now, the Enterprise Architecture team has created a library that mimics the ASP.NET 2.0 Master Pages functionality. VS.NET 2005 is not production ready yet, and like many other large shops they typically do not use something before it has had at least one service pack. Sound thinking; being on the bleeding edge is fun but hard to justify the risks for big business.

    Still, this is very useful stuff. Lacking the source code to this library, I sat down myself to try to duplicate this. The implementation used at work is an HttpModule, but I remembered using Page.LoadControl() to solve a problem recently, and I wondered if it might be just that simple...

                       private void Page_Load(object sender, System.EventArgs e)

                       {

                                 string controlToLoad = Request["c"];

                                 if (null != controlToLoad)

                                 {

                                          Control c = Page.LoadControl("controls/" + controlToLoad);

                                          myControl.Controls.Add( c );

                                 }

                                 else

                                 {

                                          Label l = new Label();

                                          l.Text = "No control to load";

                                          myControl.Controls.Add(l);

                                 }

                       }

    So, with the name of the content control as part of the URL, I started experimenting.

    Twelve lines of code, and it seemingly works. I have an ASPX page which I call Master.aspx. On this page, I have whatever heard/footer common info, and in the place where content sould vary an <asp:PlaceHolder Runat="server" EnableViewState="True"/> So far, it seems to work, although I've only briefly tested it. Is this too easy? Does anyone know of any issues with this method?

    Tags:

    IT Slavery

    by Damon 25. January 2005 06:00

    Something has been bothering me, something that I need to get off my chest.

    Since I put up this blog, I've had several people contact me because they found my resume via a search engine. In talks with these folks, they of course ask me what I'm looking for in a job, and why I might leave my current position, etc. Many times, I have had a phone or personal conversation that goes something like the following:

    Me: One thing that is important to me is freedom, ability to do side work for extra money and own any code that I write at home.
    Them: Well, we have to protect our business...
    Me: I understand that, and of course I could not do anything that was competing with you, but rather smaller projects off hours for people who can't afford a consulting company.
    Them: Well, we're looking for someone to help grow our business. We need someone who can help with sales calls and write proposls, and your skills are clearly what we are looking for. If you have extra time we would expect you to spend that time helping us with sales, and writing proposals, and preparing demo programs.
    Me: I see, so, I assume side work like this would not be allowed at your firm?
    Them: Correct. We expect you to be too busy to do side work anyway.
    Me: Ok. So, I assume I would be compensated for the time I spend doing these things, since you have identified these activities as vital to your business.
    Them: Well, no. Only billable work is payable. Sales work is not billable. Our people are salaried and no compensation is available for sales work.
    Me: (In a last ditch effort to make some sense of where this person is coming from) Oh, I see, so you must offer some small sales commission or annuity based income if the sales effort is successful then?
    Them: (Answering in a tone that I might expect if I'd offered to sell them Crack Cocaine while speaking Russian) No ...
    Me: I'm not sure this is a good fit.

    Someone called me again today, and I had this conversation with them. Before I make my point, let me reiterate:

    • Doing work outside the company is forbidden
    • I am expected to work overtime constantly, as part of my job
    • No addtional compensation is available, even though the work is of vast benenfit to the company

    Are we becoming a nation of white-collar slaves? Are we so averse to risk we'll let somone own every hour of our lives as long as they promise a regular paycheck? Don't get me wrong, I understand that from time to time at any company there will be a need to put in more time. When something big hits, its "All hands on deck", and you hope your efforts are remembered later. But, this all to common conversation is insane. You will require me to work overtime, so much so that I can't even go work at Blockbuster for free movies if that's what I wanted to do. You won't pay me for overtime, and on top of that you won't even throw me a bone if my efforts bring great success to the company.

    Why anyone would knowingly enter into this is beyond me. If you have technical skills as well as the ability to not make an fool of your company in a sales meeting, you're probably not going to have too much time finding employment. Furthermore, if you are actually successful in being a sales person and delivering work, why would you want to do so for free so that someone else can reap the benefits of your skills and your hard work? On top of that, if I turn out to be no good at this task, you'll likely fire me and replace me with someone who is good at that task. If I turn out to be good at the dual life of delivering good work and doing sales, I might start to think I should be working for myself, or having other people work for me.

    Can someone please explain this to me?

    Now, I am not advocating getting paid if you happen to think about work at home, and as I already said, I think employers asking a little extra during a crunch is perfectly acceptable. However, asking someone for their talents, and giving them an up front guarantee that you will in no way pay them for their time nor will you let them supplement their income is ridiculous. Saying that you'll "take care" of someone, implying that they might get a slightly bigger raise next year if they work 500 hours of overtime, is also completely ridiculous. We all know that the time we could trust Corporate America to be fair ended long before we had horrible examples like Enron to show us that "We'll take care of you" is a crock. If you intended to pay me for my time, pay me for my time.  If you try to paint a scenario in which you want me to think you are going to pay me for my time but the only vehicle for this is a yearly review, I'm going to be very suspicious of your intentions of goodwill and fairness. 

    I'm not advocating a strict "What's in it for me?" policy either, although you are the only person looking out for you, usually. I am happy to say that I have also talked to two or three business owners lately who sing a much different tune. These conversations include things like:

    • If you bring us a sale because of your relationships, reputation, or time spent, we'll cut you in
    • If we ask you to work off hours on sales work, we'll throw you a bone for your time if the sale does not pan out
    • We won't pay you hourly for your time on sales work, but if you do help us get sales we will give you a small %
    • Share the work, share the reward
    Fair is fair. Something for something. Why do so many employers in IT offer Nothing for Everything?

    Am I being unreasonable and selfish here? I don't think so, but comments are always welcome.

    Tags:

    FileSystemWatcher on the Compact Framework

    by Damon 20. January 2005 06:00
    In order to keep people well fed here, I'm thinking I'll try to post something interesting once a week or so. I've got enough things in my vault to fill in the gaps if I don't have time to write something new...

    Today I'll share another small .Net Compact Framework item. You may be familiar with OpenNet CF, which fills in the gaps for many of the familiar things missing in the compact framework. However, some of these gems rely on the existence of "aygshell.dll" as part of the OS image. This may leave you without a Managed solution and without the ability to PInvoke your way to your goal.

    One such handy tool is FileSystemWatcher. Supposing you need to write code to fire an event when a file is created in a certain directory.

    There are a few things you'd want to think about:

    • Thread safety.
    • Ability to work with a UI thread safely
    • Ability to detect if a large file is completely done, as opposed to just in the process of being created.

    One approach might be to create a class, call it something original like FileSystemWatcher. This class can have Start() and Stop() methods. Internally, it will create a thread that runs at a specified interval and does a directory search based on a given path and given search pattern. (Maybe *.jpg) Since there is no Thread.Abort() on the compact framework the class will need to put mutexes in the right places so that it can be killed by having a _stop bit somewhere.

    With that out of the way, you can detect changes. By using Control.Invoke and an EventHandler, you can safely notify UI controls that the file they are looking for has been found. What about knowing when a file is complete? This part could be OS specific. On CE.NET, the filesystem creates a 4096 byte file pointer on the filesystem as soon as a new file is created. Detecting unchanging file sizes greater than 4096 bytes with FileInfo will then tell you that a file is complete. If your program needs to respond to files being written to a filesystem by webservice, network share, FTP, or Http download, you can delay processing untill the file is done. Not pretty, but if your OS image is missing some things, what can you do but improvise (Or write native )? Maybe I should write a cleaner C++ version which could then be PInvoked? Maybe if I find myself with a great deal of spare time on my hands!

    By adding some code, the file change and file delete events could be detected as well. I won't post the code for this particular item here but I can help anyone who needs this functionality in the CF.

    Tags:

    New Job

    by Damon 19. January 2005 06:00
    Well, I suppose it is now official. I have resigned my position at Centare Group and accepted another position.

    My time at Centare was pretty good. It was there that I eventually started to grow into the leadership/senior roles I've always wanted. It was during my time there that my daughter was born, and a lot of other huge life events happened. It was at Centare that I wore the title "Microsoft Business Group Manager" for a while and did a great deal of work with Brian Tinkler trying to get Centare up and running and known as a solid Microsoft partner. (After many years of good rep as a solid IBM partner) Either because of, or inspite of, those early efforts Centare went from zero to several .NET people.

    My new gig will be Principal Architect at SafeNet Consulting Services. They are also looking to grow their Microsoft practice and the opportunity seems like the right thing at the right time.
    Not only will I get a fancy title on my business cards, but SafeNet's model will offer me a little more freedom where my own business endeavors are concerned. Hopefully, this opportunity combined with some big personal events (like building a house) will make this a fantastic year for me and my family.

    One of the biggest take aways from my leadership reading this year is the notion of the Abundance Mentality. In keeping to this principle, I wish Centare all the success in the world, and look forward to chasing after my own.

    Tags:

    Compact framework

    by Damon 15. January 2005 06:00
    While surfing the dotnet public newsgroups for solutions to other issues, I came across two questions over and over again related to the Compact Framework. Perhaps if I post solutions here Google will help people find the answer in plain English and C#.
    1. How can I be sure to run only 1 instance of my application on the compact framework?
    2. Dotfuscator Community Edition doesn't work on the compact framework!

    Like most things that are missing from the CF, the easiest solution to #1 involves using PInvoke to access functionality in the Win32API:

                       [DllImport("coredll.dll")]

                       private static extern int  FindWindow(string lpClassName, string lpWindowName);

     

                       [DllImport("coredll.dll")]

                       private static extern bool SetForegroundWindow(int hwnd);

                int hWnd = FindWindow( null,  "Main Window title");    // you can also add your app class name

                if (hWnd != 0)    

                {     // bring to the front the other instance

                    SetForegroundWindow(hWnd);

                                          return;

                } // else run new instance

    As I said, I also saw tons of posts related to Dotfuscator not running with Compact Framework Assemblies even though the vendor swears it does. The solution I found is twofold. The problem with the version distributed with Visual Studio 2003 usually manifests itself with something like "Unable to load some of the types"

    1. Register your copy of Dotfuscator and download the update for the community edition from their site.
    2. Even with some things in the GAC or plainly referenced by hard paths in your solution, Dotfuscator had trouble finding some of my assemblies. Changing some of my references (such as the System.Data.SqlServerCe reference) to "copylocal" allowed dotfuscator to run successfully on a very large compact framework application.

    Happy coding.

    Tags:

    User Group Presentation

    by Damon 12. January 2005 06:00
    I did my cryptography presentation at the Wisconsin .NET user's group last night. It seems to have went well. Many thanks to WINETA for having me, and for the kind words and excellent questions from those who attended.
    If they let me come back, Designer Support is the next topic I'd like to tackle. Designer support is probably one of the coolest features in .NET that is seldom used or talked about and yet is very powerful if you take the time to do it.

    With the UG presentation out of the way, I can return to pondering some of my other tasks, such as the ASP.NET issue I posted before.

    Tags:

    About the author

    Damon Payne is a Microsoft MVP specializing in Smart Client solution architecture. 

    INETA Community Speakers Program

    Month List

    Page List

    flickr photostream