Inside and Out…

An attempt to understand technology better…

Archive for the ‘Windows API’ Category

Lessons in Exception Handling

Posted by Gaurav Khanna on May 13, 2007

Working on the CLR’s exception handling subsystem is not just challenging but also gives unique opportunities to understand how the various exception handling subsystems (e.g. SEH, C++ EH, etc) work, and in particular, how they interoperate with one another. It was such case that had me discuss one such issue with Kevin, development lead of the JIT, that he mentions here.

That discussion got me exploring the interoperability aspects of EH further and resulted in the bullets listed below. Incase you are interested, download the PDF version of this article from here and the accompanying source code from here. For those uninitiated to exception handling, Matt Pietrek’s must read article is here.

Now, onto the interoperability aspects of EH.

Note: the following discussion is in context of the x86 platform

  • Catching an exception using __try/__except SEH handler will result in RtlUnwind being called without exception record

    Structured Exception Handling (SEH)
    is built into the Windows OS and it is how the OS processes the exceptions. Compilers offer their own specific ways of setting up a SEH handler. To setup one using Microsoft Visual C++, we use __try/__except keywords. For example:

    __try
    {
    printf(“Calling the /EHSc function\n“);
    InvokeCPPFunction();
    }
    __except (IsForUs(GetExceptionInformation()))
    {
    printf(“In __except\n“);
    }

    If the InvokeCPPFunction throws an exception, the OS will invoke the filter function (the IsForUs function referenced in the braces of __except) and check its return value. The filter function can be passed exception details that can be retrieved using the GetExceptionInformation function and using that information, it can decide whether it wants to process the exception or not.

    If the filter function returns EXCEPTION_CONTINUE_EXECUTION, the OS retries the instruction that created the exception. However, if the return value is EXCEPTION_CONTINUE_SEARCH, it tells the OS that the filter function has declined to process the exception and the OS continues its search for the handler in the SEH handler chain (that is available from FS:0 on x86 machines for each OS thread).

The filter function can also return EXCEPTION_EXECUTE_HANDLER to tell the OS that it wants to handle the exception and the OS proceeds to invoke the funclet within the __except block. But before invoking the funclet, the OS has to unwind the call stack. On x86, the code generated by VC++ compiler does this by invoking RtlUnwind API, with NULL for the third argument – this argument is a pointer to the exception record for the exception being processed. This is done by the compiler by invoking GlobalUnwind (an internal function) after doing some processing. GlobalUnwind makes the call to RtlUnwind as shown below:

@_EH4_GlobalUnwind@4:

70508FB2 push ebp

70508FB3 mov ebp,esp

70508FB5 push ebx

70508FB6 push esi

70508FB7 push edi

70508FB8 push 0

70508FBA push 0

70508FBC push offset ReturnPoint (70508FC7h)

70508FC1 push ecx

70508FC2 call RtlUnwind (70526620h)

The highlighted red line is the one where NULL is pushed for exception record.

What this implies that all SEH handlers that are in the x86 FS:0 chain, prior to the one that agreed to process the exception, will be called by the OS once again to give them a chance to do some cleanup (e.g. release resources) – this is typically known as unwinding of the stack. And since the unwind was initiated with a NULL for the exception record, if your SEH handler relies on checking the exception record for details before deciding to do the cleanup, it can potentially fail (e.g. not end up doing the cleanup)!

  • Corollary Lesson: Don’t throw (and expect to catch correctly) exception across environment boundaries. E.g. throwing a C++ exception and trying to catch it using a SEH handler

    Since a C++ application can have a mix of both C++ exception handling constructs and SEH exception handing constructs, it is easy to commit the mistake of writing code that throws an exception from C++ EH and excepts that to be correctly caught and processed in SEH EH constructs – the focus is on correct processing.

    Let’s extend the previous example. Assume that InvokeCPPFunction is a function in a DLL that was compiled to use C++ EH (using the /EHSc switch) and implemented as shown below:

    class CPPClass2
    {
    public:
    CPPClass2()
    {
    printf(“CPPClass2 constructor\n“);
    }
    ~CPPClass2()
    {
    printf(“CPPClass2 destructor\n“);
    }
    };

    class CPPClass
    {
    public:
    CPPClass()
    {
    printf(“CPPClass constructor\n“);
    }
    void ThrowException()
    {
    CPPClass2 cpp2;
    throw 1;
    }
    ~CPPClass()
    {
    printf(“CPPClass destructor\n“);
    }
    };

    __declspec (dllexport) void InvokeCPPFunction()
    {
    CPPClass cpp;
    cpp.ThrowException();
    }

We have two classes, CPPClass & CPPClass2 that have destructors each. InvokeCPPFunction instantiates CPPClass object, cpp, and invokes the ThrowException method, which in turn, instantiates CPPClass2 object, cpp2, and throws an exception.

As per the C++ semantics, when this exception is caught, the destructors should be invoked as they are expected to do the cleanup for the respective class instance. However, this depends upon who catches the exception.

In our previous example, InvokeCPPFunction was invoked from within __try/__except SEH mechanism. Hence, when ThrowException throws an exception, the OS walks the FS:0 chain to look for a handler that will handle the exception. When the OS comes to our __except block, if the filter funclet returns EXECEPTION_EXECUTE_HANDLER, as per our last discussion, RtlUnwind is invoked with a NULL for the exception record pointer.

When this happens and the unwind call comes to C++ exception handler, the C++ EH does not process the unwind since the exception record is NULL. This is because C++ EH only processes the unwind when the exception code in the exception record has the C++ exception code (0Xe06d7363). Thus, no destructors are invoked and that is not something you want. Below is the output this example:

Hence, it’s important to catch the exception in the environment/EH-context it was thrown in, since that EH-context will know how to process it correctly.

Posted in Development, Exception Handling, Windows, Windows API | Leave a Comment »

[Download] TransNTFS v1.0.0.1 – support for folders, symbolic and hard links and more

Posted by Gaurav Khanna on March 18, 2007

I have updated TransNTFS, my managed implementation for the transactional NTFS APIs that have been introduced with Windows Vista. TransNTFS now also supports the following operations under a transaction:

It comes with complete documentation (as always) and can be downloaded from http://www.wintoolzone.com/ListDotNET.aspx?Listtype=3

Posted in .NET Framework, Development, Downloads, Managed C++, Windows API | Leave a Comment »

[Download] TransNTFS – Managed implementation of Transactional NTFS (TxF) APIs

Posted by Gaurav Khanna on March 15, 2007

Sometime back, I had made a post regarding a native C++ class I had authored for using some of the Transactional NTFS (TxF)APIs introduced in Windows Vista.

Almost two weeks from that post, I just finished my managed implementation, TransNTFS, that enables you to use the TxF APIs from managed code. As always, Managed C++ enabled the implementation with excellent ease. It comes with complete documentation and can be downloaded from http://www.wintoolzone.com/ListDotNET.aspx?Listtype=3.

Below is an example usage of how to copy a file under a transaction:

using System;
using System.Collections.Generic;
using System.Text;
using WinToolZone;
namespace ManagedTransactionCopyDemo
{
class Program
{
static void Main(string[] args)
{
TransNTFS refTC = new TransNTFS();
// Init the transaction
bool fSuccess = refTC.BeginTransaction();
if (fSuccess)
{
fSuccess = refTC.CopyFile("d:\\transcopy.pdb", "d:\\t.pdb", false);
if (fSuccess)
{
fSuccess = refTC.Commit();
if (fSuccess)
{
Console.WriteLine("Copy successful!");
}
else
{
ShowErrorAndExit("Commit failed!", refTC.LastError);
}
}
else
{
ShowErrorAndExit("Copy failed!", refTC.LastError);
}
}
else
{
ShowErrorAndExit("Unable to start the transaction!", refTC.LastError);
}
}
private static void ShowErrorAndExit(string p, int p_2)
{
Console.WriteLine("ERROR: {0}", p);
Console.WriteLine("CODE: {0}", p_2);
System.Environment.Exit(1);
}
}
}

Posted in .NET Framework, Development, Downloads, Windows, Windows API | 1 Comment »

Programming the Transactional NTFS (TxF)

Posted by Gaurav Khanna on March 1, 2007

One of the key new features of Windows Vista is a component called the Kernel Transaction Manager (KTM) that brings inherent support for transactional development in not just the kernel-mode but also for user mode. Infact, NTFS has been enhanced to use and support transactions such that couple of new APIs (e.g. CopyFileTransacted, MoveFileTransacted just to name a few) have surfaced up. You can get more details on Transactional NTFS here.

To demonstrate the power of the new APIs, I wrote a C++ class library (unmanaged), CTransCopy, that allows you to:

  • Copy files under a transaction
  • Move files under a transaction
  • Commit or Rollback the transaction
  • Let you wire up a callback handler for copy/move progress

You can download it from http://www.wintoolzone.com/ListWin32.aspx?Listtype=5. The zipped archive also contains a sample client source code. BTW, since the .LIB file containing the class was compiled using VC++ 2005 compiler, you will need the same to link against it and write an application. You can use VC++ 2005 Express Edition. Below is an example usage of the same:

CTransCopy tcopy;

if (tcopy.IsOSSupported() == FALSE)
{
printf(“This application requires Windows Vista or later.”);
return -1;
}

if (tcopy.Init() == FALSE)
{
printf(“Init failed with error %08X\n”,tcopy.LastError());
return -1;
}

// Setup a callback for progress
tcopy.SetCopyCallback(ProgressCallback);

if (tcopy.CopyFileW(L”D:\\KGK\\Development\\VS\\Windows Vista\\VC\\TransCopy\\debug\\transcopy.pdb”,
L”D:\\transcopy.pdb”,FALSE) == FALSE)
{
printf(“Copy/move failed with error %08X\n”,tcopy.LastError());
tcopy.Rollback();
return -1;
}

if (tcopy.Rollback() == FALSE)
{
printf(“Rollback failed with error %08X\n”,tcopy.LastError());
return -1;
}

if (tcopy.Commit() == FALSE)
{
printf(“Commit failed with error %08X\n”,tcopy.LastError());
return -1;
}

printf(“Copy/move successful!\n”);

The ProgressCallback function is implemented as shown below:

void ProgressCallback(LARGE_INTEGER total, LARGE_INTEGER transferred)
{
double percent = (transferred.QuadPart*100.00)/total.QuadPart;
printf(“%f%% over\n”,percent);
}

Posted in .NET Framework, Development, Downloads, Windows, Windows API | 1 Comment »

DesktopSMS – Send, Receive and Reply to SMS from the desktop

Posted by Gaurav Khanna on July 31, 2006

Ever wanted to compose SMS from the ease of desktop instead of the phone? Wanted to be notified on the desktop, while you are working, when a SMS is received and reply to it from there itself?

DesktopSMS, for Windows Mobile 5.0 based SmartPhone and PocketPC devices, will let you do just that! Based upon .NET Framework 2.0, .NET Compact Framework 2.0 and Windows Mobile 5.0, it allows you to compose, receive and reply to SMS while the phone is connected to your machine via ActiveSync. Below are some screenshots of the same:

Main window to send SMS

Likewise, when a SMS is received, a popup comes on your screen that will allow you to reply as well:

Popup on message receipt

You can even select recepients from Microsoft Outlook’s Contact folder as message receipient, provided they have mobile phone number specified. It comes with complete documentation and installer.

Download DesktopSMS from http://www.wintoolzone.com/showpage.aspx?url=listdotnet.aspx?Listtype=1

Technorati : , , , , , ,
Del.icio.us : , , , , , ,

Posted in .NET Compact Framework, .NET Framework, Downloads, Windows API, Windows CE/Windows Mobile | Leave a Comment »

WinToolZone.Bluetooth – Added device enumeration support

Posted by Gaurav Khanna on July 6, 2006

WinToolZone.Bluetooth, the managed Bluetooth API for the desktop that I am working on, now has the support for enumerating devices as well. The snippet below exemplifies it:

    Bluetooth bth = new Bluetooth();
            
    // EnumRadios(bth);

    if (bth.RefreshDevices(false, true, true, true, true, null) == false)
    {
         Console.WriteLine("Unable to enum devices");
         return;
    }

    foreach (BluetoothDevice device in bth.Devices)
    {
         Console.WriteLine("Devicename: {0}", device.Name);
         Console.WriteLine("LastSeen: {0}", device.LastSeen.ToString());
         Console.WriteLine("LastUsed: {0}", device.LastUsed.ToString());
         Console.WriteLine("Connected: {0}", device.IsConnected.ToString());
         Console.WriteLine("Remembered: {0}", device.IsRemembered.ToString());
         Console.WriteLine("Authenticated: {0}", device.IsAuthenticated.ToString());
         Console.WriteLine("DeviceClass: {0}", device.DeviceClassID);
         Console.WriteLine("Address: {0}\n", device.Address.ToString());
                
    }

And below is an output screenshot:

Bluetooth device enumeration output using WinToolZone.Bluetooth

Technorati : , , , ,
Del.icio.us : , , , ,
Ice Rocket : , , , ,
43 Things : , , , ,

Posted in .NET Framework, Development, Managed C++, Windows API | 1 Comment »

Programming the Windows RSS Platform

Posted by Gaurav Khanna on July 2, 2006

One of the interesting things that has been introduced with Internet Explorer 7 (IE7) is the central repository of RSS feeds that will be maintained on the machine running IE7. This is called as the Common Feed List (CFL) and it can be accessed by any application via the COM based API that is being provided alongside. Infact, I wrote IEFeedManager that leverages this API to manage the CFL and also use it to view the RSS feeds.

In this post, I will explain how you can get started to program for this new RSS platform using the managed world. Note: You will need to have IE7 installed on your machine.

First, you will need to add the reference to the COM API library. Right-click your project->Add Reference.. and select the COM tab. You will see Microsoft Feeds listed as shown below:

Microsoft Feeds in the COM tab

Once you add the reference, you will see Microsoft.Feeds.Interop assembly being referenced in your project. Include the namespace with the same name in your project and your are ready to go.

The starting point in the CFL is the FeedManager object. This will allow you to enumerate all the feeds contained in the root folder of CFL, enumerate subfolders and the feeds contained within them. It implements the IFeedManager interface and a typical instantiation will be like this:

private IFeedsManager feedManager = new FeedsManagerClass();

Once you have the IFeedManager instance, you can access the root CFL folder (of the type IFeedFolder) as shown below:

feedRootFolder = (IFeedFolder)feedManager.RootFolder;

Next, you can enumerate the contained subfolders:

IFeedsEnum colSubFolder = (IFeedsEnum)feedRootFolder.Subfolders;

foreach(IFeedFolder feedFolder in colSubFolder)

{ // Do something with “folder” object }

Likewise, the Feeds property of an IFeedFolder can used to access the feeds (of the type IFeed) contained in the folder and work with them:

IFeedsEnum colFeeds = (IFeedsEnum)feedFolder.Feeds;
foreach (IFeed feed in colFeeds)

{ // Do something with the “feed” object }

Now that you have the IFeedFolder object and the contained IFeed objects, you can use a variety of properties and method to work with them. For example, to refresh the feed, invoke the Download method against the IFeed object. To delete a folder and its contained feeds (and subfolders as well), invoke the Delete method against the IFeedFolder object.

You could also set the auto-refresh (of the feed) interval using the Interval property of the feed. Not just that, you can even wire up for a notification against a feed folder or a feed so that if they are modified externally (e.g. another application) or are updated (or deleted), your application can be notified about all such behavior!

Possibilities are endless. The new RSS platform is quite powerful in terms of the APIs it provides to do a variety of tasks. Check the detailed documentation here.

Technorati : , , , ,
Del.icio.us : , , , ,
Buzznet : , , , ,

Posted in .NET Framework, Tips, Windows API | Leave a Comment »

Working with NTFS Access Control using .NET Framework 2.0

Posted by Gaurav Khanna on July 12, 2005

.NET Framework 2.0 (“Whidbey”) has introduced a new set of classes in the Framework Class Library (FCL) that allows you to work with the NTFS Access Control Lists. You can get object owners, security descriptors, create security descriptors, and much more. All of this resides under the System.Security.AccessControl namespace.

Below is a snippet that exemplifies how to use it. Scenario: You need to create a child folder without the permissions inherited by the parent folder, but with only permissions explicitly set on the parent folder.

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Security.AccessControl; 
using System.IO; 
using System.Security.Principal;

namespace AceInheritRemove
{

    class Program
    {

        static void Main(string[] args)
        {
            // Get the object and its SecDescp

            DirectoryInfodir = newDirectoryInfo("e:\\kgk\\test"); 
            DirectorySecuritysec = dir.GetAccessControl(AccessControlSections.All); 

            // Create an empty Security Descp... 
            DirectorySecuritysecNew = newDirectorySecurity();

            // Get the explicit perms on the object. 
            AuthorizationRuleCollectioncol= sec.GetAccessRules(true, false, typeof(SecurityIdentifier));

            // List all the explicitly set permissions on the object... 
            foreach(FileSystemAccessRulerule in col)
            {

                // Add the explicit permission to the new Security Descp. 
                secNew.AddAccessRule(rule); 
                Console.WriteLine("{0}", rule.FileSystemRights.ToString());
            }

            // Create a child folder with the explicit permissions only... 
            DirectoryInfoinfo2 = newDirectoryInfo("e:\\kgk\\Test\\Child"); 
            info2.Create(secNew);

        }

    }
}

Posted in .NET Framework, Development, Tips, Windows API | 1 Comment »

SetAccessRuleProtection and Inherited NTFS Permissions

Posted by Gaurav Khanna on July 12, 2005

Continuing from my last post, the same can be achieved using SetAccessRuleProtection as shown below:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.AccessControl;
using System.IO;
using System.Security.Principal;

namespace AceInheritRemove
{
    class Program
    {
        static void Main(string[] args)
        {
            // Get the object and its SecDescp 
            DirectoryInfo dir = new DirectoryInfo("e:\\kgk\\test");
            DirectorySecurity sec = dir.GetAccessControl(AccessControlSections.All);

            sec.SetAccessRuleProtection(true, false);

            // Create a child folder with the explicit permissions only... 
            DirectoryInfo info2 = new DirectoryInfo("e:\\kgk\\Test\\Child");
            info2.Create(sec);

            dir.SetAccessControl(sec);
        }
    }
}

Posted in .NET Framework, Development, Windows API | 1 Comment »

CERapi – Using CEFolder and CEFile

Posted by Gaurav Khanna on April 1, 2005

CERapi allows you to work with the file system of the Windows CE device and the snippet below shows how easy it is to do the same:

// Working with device folders

CEFolder rootFolder = newCEFolder(\\storage\\My Documents);
Console.WriteLine(“Path: {0}”,rootFolder.Path);
Console.WriteLine(“Total Files: {0}”,rootFolder.TotalFileCount);
Console.WriteLine(“Total SubFolders: {0}”,rootFolder.TotalSubFolderCount);

// Copy File from desktop
Console.WriteLine(“Move C:\\CASDEMO.TXT to device: {0}”,rootFolder.MoveFileFromDesktop(“c:\\CASDEMO.TXT”).ToString());
string
[] arrFolders = rootFolder.SubFolders;
foreach(stringstrFolder in
arrFolders)
Console.WriteLine(“SubFolder: {0} “,strFolder);

Console.WriteLine(“”);

string[] arrFiles = rootFolder.Files;
foreach(stringstrFile in
arrFiles)
Console.WriteLine(“File: {0} “,strFile);

Console.WriteLine(“”);

Console.WriteLine(“Parent Folder: {0}”, rootFolder.ParentFolder);
Console.WriteLine(“Archive: {0}”,rootFolder.IsArchive.ToString());
Console.WriteLine(“Created on: {0}”,rootFolder.CreationTime.ToString());
Console.WriteLine(“LastAccessed on: {0}”,rootFolder.LastAccessTime.ToString());
Console.WriteLine(“LastWritten on: {0}”,rootFolder.LastWriteTime.ToString());
Console.WriteLine(“Size: {0}”,rootFolder.Size.ToString());
Console.WriteLine(“OID on: {0}”,rootFolder.OID.ToString());
Console.WriteLine(“CreateFolder: {0}”,rootFolder.CreateFolder(“SubFolder”).ToString());
Console.WriteLine(“DeleteFolder: {0}”,rootFolder.DeleteFolder(“SubFolder”).ToString());

Download CERapi from http://www.wintoolzone.com/showpage.aspx?url=dotnet.aspx

Posted in .NET Compact Framework, .NET Framework, Windows API, Windows CE/Windows Mobile | Leave a Comment »