Managed World

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

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]
# Monday, May 07, 2007

I know, no posts in a while. There's a good reason though: last night, at 10:32pm, my wife gave birth to our beautiful baby son. He weighed 8lbs 13oz, and measured 20.5 inches. The name isn't "official" yet, but we are leaning strongly towards "Alexander Lewis Olson". Needless to say, I'm just soaking it all in and enjoying fatherhood.

Once we are out of the hospital (we wanted a home birth, so long story), I'll write up a longer post with our birth story. It was filled with all sorts of turns and changes, but it ended well, so we are happy :).

And with that, I leave you with some pictures of our beautiful baby boy. Sorry about the size of the pictures, but I'm a bit too pre-occupied to resize them right now :).

Posted in Personal
 #       Comments [15]

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)