MindBlaster Article Posted

Posted March 8, 2010 10:05 AM Categories: .NET | Coding4Fun | Wiimote | XNA | Hardware | PDC2009 | MIX10

mindblaster My latest Coding4Fun article on the creation of my game MindBlaster is now available!  This is a game I wrote using XNA Game Studio 3.1 that combines a Nintendo Wiimote and a Neurosky MindSet headset to create a game you play entirely with your head.  If you were at PDC09 and stopped by the Coding4Fun area you may have seen it, or, if you’ll be at MIX10, please stop by the Coding4Fun area and see this and 3 or 4 more even better projects by Coding4Fun authors.

Links

Acer 1420P Leaky Handle Driver Fix

Posted January 31, 2010 12:07 PM Categories: Acer 1420p | C/C++ | PDC2009

Download: SDTabletPCFix_1.0.0.0.zip

I wasn’t lucky enough to receive the Acer 1420P laptop given out at PDC this year since I was “staff”, however I wound up picking one up on eBay for a very reasonable price.  I received it last week, added an additional 2GB of RAM, used my Windows Home Server to save off the original hard drive image, and then repaved the machine, installing Windows 7 Ultimate x64, drivers, and applications from scratch.  Earlier this week I noticed the machine was consuming over 3GB of memory with only 1 or 2 applications open.  Looking at Task Manager, the RAM usage by process looked normal, which didn’t match the total memory usage.  After reading the Performance tab a bit more, I saw that the operating system had over 5 million handles open!

Back on the Processes tab, I turned on the Handles column and saw that a process named SDTabletPC.exe was consuming 5 million handles, and it was growing by 10 handles per second.  Check it out for yourself.

SDTabletPC.exe file is installed and run after installing the latest accelerometer driver (v1.00.00.16) from Acer’s support site.  This driver and executable are responsible for rotating the screen based on the machine orientation in tablet mode.  On the original PDC laptop image, an older version of the driver is used which uses rundll32 and load SDTablet.dll.  This version suffers from the same issue but I did not write this fix to work with that version since the newer driver is available.  Back to the research…

Next, I fired up Processor Explorer and saw that almost all of the 5 million handles were open file handles to \Device\STHall, which is the device name for the internal accelerometer.  I downloaded the free copy of IDA, an extremely powerful native code disassembler, and started poking around the executable.  I found several functions which made calls to CreateFile, trying to open the above device, but never closed those handles with a call to CloseHandle.  Excellent.

I was unable to fix the executable by patching in calls to CloseHandle, so I took another approach.  I wrote a very small app in C which finds the SDTabletPC.exe process, opens a process handle to it, enumerates all of its open handles, and forcefully closes all those that are handles to \Device\STHall.  The application then sleeps for 5 seconds and repeats the process forever.

I have put the application and its source code up for download here.

Note that this fix is only for the latest version of the driver shown here, version 1.00.00.16.  Another note:  The leaky handle issue exists in both the original driver included with the PDC laptop image (which runs as a rundll32 process against SDTablet.dll), and this updated driver, but my fix only works for the updated driver.  I know it won’t work with the driver installed in the default PDC image and I can’t guarantee it’ll work with newer drivers, or that newer drivers will even need the fix.

Why force you to upgrade to this version?  Well, as noted on Microsoft’s PDC Tablet site, there’s supposed to be an updated driver on Windows Update that gets rid of the amazingly annoying “Portrait mode may not work with certain applications" (or words to that effect) message box every single time you rotate the machine, however, it’s not on Windows Update.  This driver on Acer’s site is the updated version that fixes that issue.  Sadly, it doesn’t fix the leaking problem.  I know the tablet site says “don’t install any drivers outside Windows Update”, but this is the only way to get the updated rotation driver, or to install the driver with a clean Win7 install.

Update 2/6/10: An additional note for those of you on the original PDC image updating to this newer driver: Be sure to check for the following registry key and if it exists, remove it:

HKLM\Software\Microsoft\Windows\CurrentVersion\Run, SDTablet = Rundll32 %SystemRoot%\System32\SDTablet.dll,MainThread

This key starts the original version of the rotation driver, and it appears it is not properly cleaned up for everyone and may result in TWO processes eating 10 handles per second.  Thanks to Chad Boles for getting the key location for me.

So, if you’re still running the original PDC driver, make sure you head to Acer’s support site and download this version:

image

If you don’t care about the details, download and give it a try.  For those that care about down and dirty C, let’s continue to the details on how it works…

Step 1: Find the SDTabletPC.exe process and get its process ID

Digging around, I found this sample from MSDN which demonstrates how to use the Tool Help Library to take a snapshot of all system processes and query information about them.  For this application, the code can be shortened to just enumerate the running processes, find the one whose process name matches SDTabletPC.exe, and get its process ID:

// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
{
    DisplayError(L"Could not take snapshot of processes");
    return 1;
}
 
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
 
// Retrieve information about the first process,
// and exit if unsuccessful
if(!Process32First(hProcessSnap, &pe32))
{
    DisplayError(L"Could not query first process");
    CloseHandle(hProcessSnap);          // clean the snapshot object
    return(FALSE);
}
 
// Now walk the snapshot of processes, and
// display information about each process in turn
do
{
    if(_wcsicmp(L"SDTabletPC.exe", pe32.szExeFile) == 0)
    {
        pid = pe32.th32ProcessID;
        break;
    }
}
while(Process32Next(hProcessSnap, &pe32));
 
CloseHandle(hProcessSnap);
 

 

Next up, I found this sample from SysInternals which tells us the rest of what we need to know: how to enumerate handles belonging to a specific process, get the name of the handle, and close the handle.  I was able to modify that code into the following:

Step 2: Open a duplicable handle to the process

A handle can be opened to any process by calling OpenProcess and passing in the process ID of the process to open.  By passing the PROCESS_DUP_HANDLE argument, we can later use this handle in a call to NtDuplicateObject to get a queryable handle.

/* open the SDTabletPC.exe process */
if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid)))
{
    DisplayError(L"Could not open SDTabletPC.exe PID.");
    return 1;
}

Step 3: Get all system handles

This code retrieves all system handles from all processes via the NtQuerySystemInformation method.

/* NtQuerySystemInformation won't give us the correct buffer size, so we guess by doubling the buffer size. */
while ((status = NtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
    handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);

Step 4: Enumerate the handles, close those that match

The handles are enumerated, looking for those that belong to the SDTabletPC.exe process based on the process ID which owns the handle.  For each of the handles that match, its ObjectNameInformation is retrieved using the NtQueryObject method.  This stru

ct contains the handle name.  This name is compared with \Device\STHall, and, if it matches, it is closed with a call to DuplicateHandle, which closes the handle by passing in the DUPLICATE_CLOSE_SOURCE parameter.  The application then sleeps for 5 seconds and repeats this process again.

for (i = 0; i < handleInfo->HandleCount; i++)
{
    SYSTEM_HANDLE handle = handleInfo->Handles[ i ];
    HANDLE dupHandle = NULL;
    UNICODE_STRING objectName;
    ULONG returnLength;
 
    /* Check if this handle belongs to the PID the user specified or if it has the access mask below which will hang NtQueryObject */
    if (handle.ProcessId != pid || handle.GrantedAccess == 0x0012019f)
        continue;
 
    /* Duplicate the handle so we can query it. */
    if(!NT_SUCCESS(NtDuplicateObject(processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, 0, 0, 0)))
        continue;
 
    /* query the handle for its name information */
    if (!NT_SUCCESS(NtQueryObject(dupHandle, ObjectNameInformation, objectNameInfo, objectNameInfoSize, &returnLength)))
    {
        objectNameInfoSize = returnLength;
 
        /* Reallocate the buffer and try again. */
        objectNameInfo = realloc(objectNameInfo, returnLength);
        if (!NT_SUCCESS(NtQueryObject(dupHandle, ObjectNameInformation, objectNameInfo, returnLength, NULL)))
        {
            CloseHandle(dupHandle);
            continue;
        }
    }
 
    /* Cast our buffer into an UNICODE_STRING. */
    objectName = *(PUNICODE_STRING)objectNameInfo;
 
    /* Kill the original handle */
    if (objectName.Length && _wcsicmp(objectName.Buffer, L"\\Device\\STHall") == 0)
        DuplicateHandle(processHandle, (HANDLE)handle.Handle, NULL, NULL, 0, FALSE, DUPLICATE_CLOSE_SOURCE);
 
    /* Kill the duplicated handle */
    CloseHandle(dupHandle);
}

There is a little more going on in the actual application, so be sure to check out the included source code if you’re interested in this kind of thing.  Give it a try and let me know how it works for you.  It’s been running stably for myself and a few other testers, so please let me know if it does not work for you.

And a huge “thank you” to Greg Duncan for testing out the app several times as I wrote it!

Coding4Fun at PDC Video Recap

Posted December 19, 2009 4:45 PM Categories: .NET | Coding4Fun | XNA | Events | Channel 9 | PDC2009

c9logo It looks like all of the Coding4Fun videos pertaining to PDC09 have been posted along with most (all?) of the Channel 9 Live videos.  For those interested in the Coding4Fun recap vids, have a look…

Get Microsoft Silverlight
Channel 9 Live at PDC09: Coding4Fun
Clint Rutkas, Brian Peek and Tim Higgins with Scott Hanselman
Recorded Live, November 19th 2009 at 11:00AM (PST)

Get Microsoft Silverlight
Coding4Fun at PDC 2009
With our lab coats in hand, we brought Drinktendr, Mind Blaster, Laser graffiti, Wi-Fi Warthogs and finally Goblin XNA (augmented reality)!

PDC09, Coding4Fun, and Mind Blaster

Posted November 23, 2009 1:59 AM Categories: .NET | Coding4Fun | XNA | PDC2009 | Events | Hardware | Channel 9

Another PDC is over and I’m happily relaxing before work starts again on Monday.  Lots of announcements, free laptops for attendees (not me, sadly), and plenty of time spent in our Coding4Fun area with my project.  We even had the opportunity to take part in a live broadcast on Channel 9!  The recording for that show should be available shortly.

We had 5 fantastic projects in the Coding4Fun area this year:

image
Drinktendr by Clint Rutkas
image
Laser Graffiti by Jeremiah Morrill
image
Goblin XNA by Ohan Oda
image
Wi-Fi Warthogs by Tim Higgins

And what was my big project this year?  A fun little game titled Mind Blaster, a space shoot ‘em up game played entirely with your head!

Mind Blaster

How does one do that? Well…

This past July I found a brain-wave sensing headset from Neurosky called the MindSet.  They are now shipping headsets at $200 each and provide a free set of development tools to use the headset in your own apps.  Part of this toolkit provides support for using the headset in .NET using C#.  This headset uses 4 dry sensors to measure alpha, beta, theta and gamma waves produced by your brain, runs them through a proprietary algorithm they’ve developed, and scores your concentration/focus and relaxation individually on a scale from 1 to 100.

The second piece of hardware involved is a Nintendo Wiimote, gutted and strapped to the top of the headset.  With an IR bar on the top of the monitor, this provides full head-tracking in 2 dimensions.  Interfacing to this device is quite easy using my managed library which you may have heard of…

With these two things strapped to the user’s head, the game, written using XNA, takes shape.  Move your head to move a targeting reticule around the screen.  Hover the reticule over an enemy, then begin focusing your attention on that enemy.  The harder you think and the more you concentrate, the faster the enemies heat up and then explode.  Enemies will shoot back, and you can target their missiles to blow them up before they hit the screen.  Here’s a short video of the game in action.

A simple but fun little game.  I even had several people come back multiple times during PDC to attempt to better their score.

I owe a lot of people a huge amount of credit for bringing all of this to life….

  • Joey Buczek for all of the 3d models and artwork in the game
  • David Wallimann for all of the sound effects and music in the game
  • Rick Barraza for the idea of moving the game into a space environment.  Better than the road I was heading down… :)
  • Greg Hyver and Johnny Liu from Neurosky for getting me set up with headsets and providing loaners for PDC
  • Michelle Leavitt for an infinite amount of playtesting
  • The XNA folks who created the various tutorials and starter kits whose code saved me a ton of time in creating the game.  Without these, I’d probably still be writing particle engines, bloom shaders and various other pieces from scratch….these are a huge time saver!

There will be much more to come on this game over the coming weeks.  I will be doing an extensive article on Coding4Fun detailing how the game was created.  At that time, the full source code will also be released.  I will probably also write up a short post-mortem on the creation and exhibition of the game in the style of those seen in Game Developer magazine.

PDC 2009

Posted November 9, 2009 1:33 AM Categories: .NET | Coding4Fun | XNA | Events | Hardware | Coding4Fun Show | Channel 9 | PDC2009

Before and AfterPDC 2009, starting November 17th, is almost upon us and I’ll be heading out to the conference once again with my Coding4Fun/Channel 9 playmates.  Anyone else heading out to the big show?

We won’t be doing a Coding4Fun session like we did last year, but I will have another fun project for people to check out in the Coding4Fun area.  I can’t give out details until after the show begins, but you can probably guess there is a Wiimote in the mix somewhere.  And some spiffy new hardware.  And maybe some XNA.  Look for the details here after the show, and an article with full source code shortly thereafter.

We also have 4 or 5 other developers with their latest and greatest projects, all of which are nothing short of incredible and put mine to shame.  I will likely be doing a compendium Coding4Fun Show with all of this year’s project authors so those not in attendance can see their incredible work.

I will also be hosting a table during lunch on Monday, November 16th during the FREE Windows 7 Developer Bootcamp.  The topic at my table will be XNA.  So, if you’re attending the all-day bootcamp on Monday and want to talk about all things XNA, be sure to stop by.  I’d love to hear how other people are using XNA and, if they’re not, why and how they should, even if it’s just for fun.

If anyone will be attending the conference, please let me know so we can meet up for lunch or a beverage.  Hope to see you all there!

My Info

  • View Brian Peek's profile on LinkedIn

Sponsored Ad

My Book

Sponsored Ad