Managed World

Techno-babble from yet another babbler RSS 2.0
# Thursday, July 19, 2007

So I've gotten into a new hobby as of late. Why? Simple: my son. You see, many of the hobbies I've had in the past are "loner" hobbies that don't involve many people well: playing RPGs, programming video games, etc. I had some criteria that I was thinking about. First of all, I wanted it to be a family friendly hobby (so my son can get involved if he's interested). Second, it needed to be outdoors (I'm stuck inside enough because of my day job, no reason to make it worse). Lastly, it needed to be somewhat "geeky" still.

After doing some research, I found one that fit the bill quite well that piqued my interested: R/C Airplanes. Yes, you heard me right, I'm getting into R/C Airplanes. I put some research into it to make sure I got the right way, went down to check out one of the local R/C clubs and their flying field, and even attended their Open House and was able to fly the plane I eventually bought in person. It was a GREAT experience and somewhat of a "high" to be able to fly an R/C plane. GREAT hobby with lots of great people.

I also figure that getting into a hobby that has NOTHING to do with computers will also help make me a little more "well-rounded" that I possibly was before. You know, give me some fresh life experiences that I can bring into the other areas of my life.

So in that vein, yesterday I went down to the LHS (Local Hobby Shop) and picked up my new baby:

Oh yeah! All the goods I needed to get started. The Arrow has a 63" wingspan and a semi-symmetrical wing that makes it a good training airplane, as well as still being able to maneuverable enough to pull off some easier aerobatics. It is also a Glow Engine ("glow" being a type of fuel). I went this route instead of electric because I wanted a larger, more powerful plane that will handle the higher winds we get here in the Northwest (read: beefier than an electric in the same price range).

Tonight, I fully plan on putting this bad boy together and starting to charge the batteries. Then, next Tuesday (weather permitting and if my AMA membership card arrives in time), I'm off to the local airfield to do some training with a club instructor. Oh yeah! Summer is here, and I couldn't be more excited about it!

I already bought my second plane as well. It is a SIG Four-Star 40 in kit format. So, basically, I will be putting it together from the ground up myself (from the balsa wood baby!). It will be a great feeling to put something together with my own hands and then getting to fly it through the air.

Posted in Personal
 #       Comments [5]

Just an FYI for my readers. If you read this blog merely for technical enjoyment, all my "work-related" type posts will be done on my blog over on MSDN.

The reason I am doing this is that I want this blog to become more personal (like Rory's blog) and center more around my family and hobbies. Since the two areas are very different and aren't nearly as related as they were in the past, I made the decision to separate the two. I'm sorry if this inconveniences you, but I'm tired of not posting personal stuff to this blog because it doesn't contribute to my "work".

So expect some upcoming posts on my new hobby coming up :).

Posted in Blog
 #       Comments [0]

James Conard announces over on his blog that our team has just released the Windows Server 2008 Developer Training Kit for Beta 3. Mosey on over and check it out. You can find resources on everything from WCF, to Cardspace, to WF, to Windows Eventing, to PowerShell, to IIS 7, to Transactional NTFS.

So if you are a developer interested in checking out Windows Server 2008, make sure to grab it.

 #       Comments [1]
# Monday, June 25, 2007

Do you want to have a great job where you get paid to have fun? Well, there is a job opening on the team I work for here at Microsoft.

So, if you want to work for the greatest team in Developer & Platform Evangelism here at Microsoft, check it out. You'll get lots of opportunities to not only drive adoption of Windows Server Virtualization in the community, but you get to work directly with the product team as well. If that sounds exciting, make sure to apply.

Posted in Personal
 #       Comments [0]
# Wednesday, June 20, 2007

The more I work with TxF, the more I realize that our (Microsoft's) coverage of certain KTM topics is sorely lacking. One of those areas is around documentation and samples of managing resource managers (important if you are wanting to investigate programatically the running status of a resource manager).

Sometimes, being an evangelist can be quite fun (or frustrating) because the documentation leaves something to be desired and you can't run to the internet because the only results you get back or to the documentation on MSDN. And of course, since you're on the cutting searching for the control codes online provides you with two results, both pointing back to MSDN. It becomes doubly "interesting" if you are a managed developer because a large number of management-oriented information for KTM is all done through DeviceIoControl (an API that is NOT fun to try to P/Invoke into, especially using certain control codes).

Anyways, that's all beside the point... moving right along.

If you are writing an application to monitor TxF (or even building it into your own application), there are some core "things" that you need to do. One of the first ones (and the one I will cover in this post) is to get a list of transactions in a given resource manager. This is done using the FSCTL_TXFS_LIST_TRANSACTIONS control code.

What structure is DeviceIoControl passing back to us in this instance? A TXFS_LIST_TRANSACTIONS structure. Looking at this structure, we see two fields: NumberOfTransactions and BufferSizeRequired.
That's nice and all, but where is the information about those transactions? The information is stored in a TXFS_LIST_TRANSACTIONS_ENTRY structure.

The trick is that the TXFS_LIST_TRANSACTIONS_ENTRY structure is mentioned nowhere in the documentation for FSCTL_TXFS_LIST_TRANSACTIONS. So how do you get to it? An array of TXFS_LIST_TRANSACTIONS_ENTRY structures are stored in memory after your TXFS_LIST_TRANSACTIONS structure. So assuming you have two running transactions in the given resource manager, you would pass in a pointer to the TXFS_LIST_TRANSACTIONS structure, and here is what the memory would actually look like coming back from DeviceIoControl:

The impact of this is that you need to allocate enough memory for not only your TXFS_LIST_TRANSACTIONS structure, but the array of TXFS_LIST_TRANSACTIONS_ENTRY structures as well. You might notice a little bit of a "chicken and egg" problem here. If I'm using FSCTL_TXFS_LIST_TRANSACTIONS to retrieve the transactions, how could I know how many entry structures to allocate when I don't know how many transactions there are yet?

Well, assuming there are one or more running transactions in the resource manager, you have to call DeviceIoControl with FSCTL_TXFS_LIST_TRANSACTIONS at least twice: once to find out how big of a buffer you need to allocate (read: to calculate how many ENTRY structures to accomodate for), and then another time after allocating the extra memory to have it fill the actual ENTRY structures.

Why do I say "at least" twice? Because, between the time we make our first call and the time we make our second call, more transactions could have appeared and we will have to allocate even more memory. A little bit of a "cat and mouse game," I must say.

If you are a managed developer, this may sound a bit scary. Don't be scared though, it's not too bad (and I know I at least have fun writing this kind of lower-level code :P).

So let's dive right in and look at the code to make this work!

In pseudo-code, this is what we have to do:

------------------------
while (true)
{
     // Deallocate memory from last loop through this

     // Allocate memory for transaction list buffer

     // Call DeviceIoControl with FSCTL_TXFS_LIST_TRANSACTIONS

     // If DeviceIoControl Succeeded

          // Get list of transaction entries after TXFS_LIST_TRANSACTIONS structure
}

// Deallocate any remaining memory
------------------------

Not that bad really. So here it is implemented in native code:

 

    1 #include <windows.h>

    2 #include <tchar.h>

    3 #include <stdio.h>

    4 #include "Winioctl.h"

    5 

    6 int _tmain(int argc, LPTSTR argv)

    7 {

    8     DWORD lastError, bytesReturned;

    9     HANDLE rmDirectory;

   10     TXFS_LIST_TRANSACTIONS *txList = NULL;

   11 

   12     // Get handle to directory where resource manager resides

   13     rmDirectory = CreateFile(TEXT("C:\\"),

   14         GENERIC_READ,

   15         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,

   16         NULL,

   17         OPEN_EXISTING,

   18         FILE_FLAG_BACKUP_SEMANTICS,

   19         NULL);

   20 

   21     if (rmDirectory != INVALID_HANDLE_VALUE)

   22     {

   23         // Get a list of transactions within the given

   24         // resource manager

   25         DWORD neededBufferSize = sizeof(TXFS_LIST_TRANSACTIONS);

   26         while (true)

   27         {

   28             // Deallocate previously allocated memory if we are back

   29             // here after getting back ERROR_MORE_DATA

   30             if (NULL != txList)

   31             {

   32                 delete[] (char*)txList;

   33                 txList = NULL;

   34             }

   35 

   36             // Get the list of running transactions in the RM

   37             txList = (TXFS_LIST_TRANSACTIONS*)new char[neededBufferSize];

   38             if (!DeviceIoControl(rmDirectory,

   39                     FSCTL_TXFS_LIST_TRANSACTIONS,

   40                     NULL,

   41                     0,

   42                     txList,

   43                     neededBufferSize,

   44                     &bytesReturned,

   45                     NULL))

   46             {

   47                 // How did we fail?

   48                 lastError = GetLastError();

   49                 if (lastError == ERROR_MORE_DATA)

   50                 {

   51                     // We need to enlarge the buffer and try again

   52                     neededBufferSize = txList->BufferSizeRequired;

   53                     continue;

   54                 }

   55                 else

   56                 {

   57                     _tprintf(TEXT("Unhandled exception: %u\n"), lastError);

   58                     break;

   59                 }

   60             }

   61             else

   62             {

   63                 _tprintf(TEXT("Transaction Count: %u\n\n"), txList->NumberOfTransactions);

   64 

   65                 // List Tx details

   66                 TXFS_LIST_TRANSACTIONS_ENTRY *txEntry;

   67                 txEntry = (TXFS_LIST_TRANSACTIONS_ENTRY *)((char *)txList + sizeof(TXFS_LIST_TRANSACTIONS));

   68                 for (DWORD i = 0; i < txList->NumberOfTransactions; i++)

   69                 {

   70                     txEntry += i;

   71 

   72                     // Get GUID string

   73                     WCHAR szGuid[40];

   74                     StringFromGUID2(txEntry->TransactionId, (WCHAR *)&szGuid, 40);

   75 

   76                     // Print Tx info

   77                     _tprintf(TEXT("TX %s: %u\n"),

   78                         szGuid,

   79                         txEntry->TransactionState);

   80                 }

   81 

   82                 break;

   83             }

   84         }

   85 

   86         // Any memory left to deallocate?

   87         if (NULL != txList)

   88         {

   89             delete[] (char*)txList;

   90             txList = NULL;

   91         }

   92     }

   93     else

   94     {

   95         _tprintf(TEXT("Unable to get valid handle to Resource Manager\n"));

   96         return 1;

   97     }

   98 

   99     _tprintf(TEXT("\nPress any key to exit...\n"));

  100     getchar();

  101 

  102     return 0;

  103 }

And that's how you do it. It's not the most fun getting in to DeviceIoControl (unless you're a geek like me and enjoying this kind of stuff), but hopefully with this post out there to help it will be easier to find out how to do this since there is a lack of documentation around this area.

In closing, there is some work that needs to be done around making management of kernel-level transactions a lot easier than it is now. In some ways, it is pretty clear that this is still a "1.0" technology. So while you could use the KTM directly for your transaction coordination, I would highly recommend sticking with using DTC for your transaction coordination as it is much more mature from a management perspective (and there are quite a few enhancements with DTC in Vista and Windows Server 2008).

Posted in
 #       Comments [0]
# Friday, June 08, 2007

Well, it's official, again, for now. I just went and canceled my WoW account. With the birth of my first child, I have come to the realization that I don't have enough time for WoW (or, better put, what time I do have should be spent either with my son, or doing a hobby that's creative and produces results I can show off).

What's funny is that I don't miss it in the least bit. At first, I made the decision to stop playing WoW because I simply had to play games where I could pause at a moment's notice to help out with Baby Xander. Then, after several weeks of not playing WoW, I realized I didn't miss it at all and have really enjoyed spending time either with music, or in doing Windows system programming in C (yeah, I'm a geek, I know it).

So, I say farewell to World of Warcraft for the third time in my life. Hopefully this is for good (or until the _next_ expansion pack comes out :P).

P.S. Back to reading my current book, Windows Internals.

Posted in Personal
 #       Comments [4]

Contact

Email Me Send mail to the author(s)

Calendar

<July 2007>
SunMonTueWedThuFriSat
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

About this site

Jason Olson's thoughts on Programming, Games, Music and Life in General

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Jason Olson

Sign In
All Content © 2008, Jason Olson
Theme based on 'Business' created by Christoph De Baene (delarou)