• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
  • entries
    21
  • comments
    16
  • views
    27368

About this blog

Windows dev-ing bit and bobs

Entries in this blog

adeyblue
When I play games I don't really play anything new. Heck, the last game I bought as it was released was Final Fantasy X, the original version.

The one game I do play and perhaps play too much, is Intelligent Qube (or Kurushi since I'm a contrary European) on the PS1. I usually speedrun it, but then I found a high score for the game on Twin Galaxies of 1,244,800 with an IQ record of 506. This was achieved on the default / easiest difficulty, nevertheless if you've played the game you'll understand that they're both pretty great scores.

The scoring mechanics for the game are relayed via the tutorial and otherwise easily observable so anybody doing a score attack can gauge how they're progressing and what they need to do. How the IQ score is calculated on the other hand is not public knowledge. So seeing as I like to know how things work, can read PlayStation (MIPS) assembly, and some clever people have fitted debuggers into PlayStation emulators, I went to uncover it.

The results I found contained some rather unexpected information.

Read the rest of this entry on Just Let It Flow
adeyblue

Plug in to CL

It's well known that Visual Studio's C compiler hasn't progressed much beyond C89, save for things like variadic macros. What might not be quite as well known is that to rectify this a bit, somebody created a C99 to C89 converter. A decent tool to be sure, but it doesn't integrate well into Visual Studio. Being a seperate program means you have to fudge things to run it instead of cl.exe, or you have to set a pre-build step, save the processed output and then compile those files instead of the ones in your project. It's not terribly friendly for IDE purposes. Wouldn't it be nice if there was a way to intercept the compilation and process the source files as it goes? What isn't well known is that you can do that, with compiler plugins.

The good news about these plugins is that unlike IDE ones such as Visual AssistX, the support is directly in the compiler so you don't have to have a pay-for version to use them. You see, not only does cl.exe have the plethora of options it displays as help, it has undocumented ones too. Ones which allow you to change or add compiler passes and pass your own arguments to them.

Continue reading on Just Let It Flow...
adeyblue
If you haven't been living under a rock (or in a non-Windows world) you'll know that since XP, Windows has had zip file extraction and creation. You may also know that what it doesn't have, is a defined API so us normals can leverage it programmatically. But there are ways and means.

Think about it, the usual way you'd interact with zip files is through the shell. You'd highlight a bunch a files and "Send To" a Compressed Folder or drag them into an existing folder and voila. There's obviously some code behind that's actually doing those things, and since you can do them from 'Open File' dialogs and the like, it can't be code within the Explorer executable.

You can search Google all you want, but you'll only find that MSDN isn't sandbagging and there are no directly exported functions to create zips. What you may find is that shell32 and friends do have functions and interfaces to duplicate the Shell's methods of dragging, dropping and sending to, so that seems a good lead to follow...

Continue reading on Just Let It Flow
adeyblue
CreateConsoleScreenBuffer, what a fabulous function. You ask it nicely, and it gives you as many 'console window content' buffers as you want. With the other supporting functions it's everything you need for a AAA game (ascii-art-animation natch). But backup a minute here. what's that mysteriously reserved parameter for and why is there a flags argument with a weasely worded "only supported screen buffer type"? Sounds like there's something else it can (or at least could) do.

Sure enough, there is. For the function really doesn't just have one defined buffer type, it has two. The second is the truthfully, if optimistically, named CONSOLE_GRAPHICS_BUFFER. Now doesn't that sound fancy? I mean, non-ascii graphics in the console, groovy!

The creation of this 'graphics buffer' works via the magic of that bogus 'reserved' last parameter. Forget about your regions and device contexts though, where we're going is much more low-tech.

Read the rest on Just Let It Flow
adeyblue
Way back in the mysts o' tyme I told a tale of a little picture-in-picture / interactive zoom tool I was working on. Well, a whole year and 4 months later I got round to fixing the buggy bits and wrote some help pages. Now it's ready for public consumption as an Installer, or just a Zip.

It's simple to use. You pick an open window
chooseq.png

And you get another window (optionally always on top) that displays th chosen windows' live client area:
starteu.png

From there you can interact with the source window just as you would the real one with mouseover effects, button clicks etc But that's a bit boring, and with large windows the contents are all small like, so what you can do is select an area
zoomselect.png

and be zoomed into that
zoomed.png

Then you can resize the window to enlarge or reduce the size of the content
zoomedlarge.png

Finally, because it'd be rude not to, you can still interact with the now zoomed and enlarged content
zoominteract.png

If you prefer to see it in moving action, I whipped up an 'ad' on my first go round last year.

[media]http://www.youtube.com/embed/A5k8pKAUtOg?rel=0[/media]

It requires Windows Vista, 7, or 8 and Aero to be enabled and that's about it. It weighs in at about 150K soaking wet and uses a whopping 1.5MB of memory, so if it looks useful, have a go with it.

Installer, Zip.
adeyblue
Microsoft say "Visual Studio Express 2012 for Windows 8 provides tools for Metro style app development. To create desktop apps, you need to use Visual Studio Professional 2012, or higher."

That isn't quite true. In fact, there's no quite about it. In the current RC version on MSDN, it's downright wrong, and simple to achieve too.

So how do you do it?

Before starting the IDE, navigate to
%programfiles%\msbuild\Microsoft.cpp\v4.0\v110\1033
Open general_appcontainer.xml and find the line that contains
Open the IDE and create a Visual C++->Blank App (XAML) project

When created, you can delete almost all things it puts in there. The xaml files, the appxmanifest, the assets and common folders and if you don't need or want precompiled headers you can delete both pch files too.

Now, right click the project file and change these values:

Configuration Properties->General and switch Metro Style App to false.

And there you go! You can compile and debug native, WinRT-less apps using the old guard of WNDCLASSEX and GetModuleHandle type stuff from when men were men and women even moreso. You'll need to readd UNICODE, _UNICODE, _DEBUG/NDEBUG to the preprocessor directives if you need them, and re-enable pdb-generation and the subsystem type in the linker settings.

The only major downside is that the Win32 SDK that comes with this version is severely lacking many major things such as bits for the common controls and GDI32.lib etc. If you have an older SDK you can point it at though, it's isn't that bad. if you don't, you'll also have to remove the entries that aren't kernel32.lib and user32.lib in Linker->Input or generate lib files from the dlls using link.exe.

What does turning the Metro switch off do?

Unsets C/C++->General->Consume Windows Runtime Extensions (No)
This removes the dependency on vscorlib110.dll

Unsets the WINAPI_FAMILY define, which winapifamily.h defaults to WINAPI_FAMILY_DESKTOP_APP
This enables the functions marked in the SDK as being for desktop apps only (basically all the ones you're familiar with from Win32).

Unsets Linker->Windows Metadata->Generate Windows Metadata
Stops the generation of winmd files which have no purpose for non WinRT apps

Removes the non IDE Linker setting: /AppContainer
This turns off the new for Windows 8 [size=2]IMAGE_DLLCHARACTERISTICS_APPCONTAINER flag in the Optional PE Header, and lowers the OS and Subsystem version of the generated exe down to 6.0 (Vista) levels (the default is 6.2 (Win 8))

And that's about it as important stuff goes. Deleting one character and changing three others has turned Microsoft from paragons of virtue, into rotten stinking liars.

If you're only interested in the updated C++ 11 toolchain, it's probably just easier to copy the VC\bin, VC\include and VC\lib directories and use them side by side with your current install of VS. The compiler binaries run on Vista+ as long as msvcr110.dll is in the path somewhere.
adeyblue
If what you're writing already requires a dll, or you can augment an existing one, then you're already set and can use the fact that DllMain gets called when threads are created and destructed to your advantage. If you're not, or can't then you're pretty much stuck for an answer. Conventional wisdom on the web seems to revolve around hooking CreateThread or even use the kernel based notification scheme. However making a whole driver is overkill and with several methods of creating threads called at various levels of Windows, hooking isn't always sufficient either, especially if you want to execute code in the thread context. WMI is also a technical possibility, but with its '10,000 lines of code where 10 will do' philosophy, that's where its staying.

Dll thread_attach notifications work because when threads are created and torn down, ntdll loops around the internal structures corresponding to each module loaded in the process and calls their entry point if they meet certain criteria. The structure for the exe is included in the enumeration but as it doesn't identify as a dll, its entry point isn't called. The thing to do then, is modify the structure to a) look like a dll and b) make it think our entry point is a DllMain...

Continue reading on Just Let It Flow
adeyblue
Wait, there's a disassembler built into Windows? Well, only in the sense that a supermarket that has the ingredients to build a cake. There's no ready made pastry hidden away in the depths of system32, unlike there is for file hashing [sup][1][/sup].

What there is though, is an aisle full of ingredients going by the name of DbgEng.dll. This fellow forms part of the debugging tools triumverate with its more illustrious counterpart dbghelp.dll and the mysterious symsrv.dll. DbgEng contains the interfaces which make up WinDbg's core functionality, a portion of such is disassembling. So, being the sort of chef who would appear on a Gordon Ramsay show in quite short order, I rustled up a quick messily coded bun.

It's not IDA or Hiew, it's not meant to be. But for an 'objdump -d' like, quick and dirty tool that handles the 3 most common Windows architectures (as well as ARM and Alpha!) and doesn't require a toolchain to be installed, it's perfectly acceptable for my uses. It may be for others too, so have at it if you should so desire.

Download it here

x64out.png

AMD64 output with symbols.

armout.png

ARM output from files compiled by eMbedded VC.

The code was to be part of a larger project which never was and so, is in a terrible state mixed with this library and that. In scant consolation, below are the basic steps to how it works, and how you can do it yourself if you're suitably deranged. The help for these interfaces and functions is on MSDN (obviously) and also the debugger.chm help file that comes with the Debugging Tools For Windows package which also houses the up to date headers, libs, and other helpful little programs.

[rollup='Pseudocode steps']
// setup
DebugCreate(IDebugClient)
IDebugClient->QueryInterface(IDebugControl)
IDebugControl->SetOutputCallbacks()
IDebugClient->SetEventCallbacks()
// launch the helper process
IDebugClient->CreateProcessAndAttach(0, "host.exe", DEBUG_ONLY_THIS_PROCESS, 0, 0)
IDebugControl->WaitForEvent()
// set the default symbol options
IDebugClient->QueryInterface(IDebugSymbols3)
IDebugSymbols3->SetSymbolOptions(SymbolOptions);
// unload all the existing symbols
IDebugSymbols3->GetNumberModules()
foreach(module)
{
IDebugSymbols3->GetModuleParameters(ModParams)
IDebugSymbols3->GetModuleNames(ModParams.Base, moduleName)
IDebugSymbols3->Reload("/u " + moduleName")
}
// map the file to be disassembled into the relevant processes
MappedFile = MapAsDataFileInCurrentProcess("C:\Mod\\to\\disasm.dll")
IDebugControl->SetEffectiveProcessorType(MappedFile->NtHeaders.FileHeader.Machine)
MappedAddress = MapDataFileAsExeIntoHostExe(out MappedSize) // 1
// load it as a virtual module in the target process
IDebugSymbols3->Reload("/s /f /w =,0x)
// check that it loaded where we want it
IDebugSymbols3->GetModuleByModuleName(, &realModuleBase)
// if not, load a second virtual module at this address
// this is so any absolute addressed symbols can be resolved
if(realModuleBase != MappedFile->NtHeaders.OptionalHeader.ImageBase)
{
IDebugSymbols3->Reload("/s /f /w =,0x)
}
// get setup for the disassembly
IDebugControl->SetAssemblyOptions(DEBUG_ASMOPT_*)
From there you can enumerate the symbols using:
IDebugSymbols3::GetSymbolEntriesByName("!*", &numSymbols)
for(numSymbols)
{
IDebugSymbols3::GetSymbolEntryInformation(symId, &entry);
IDebugSymbols3::GetSymbolEntryString(symId)
}
or get the sections via investigating the Nt and section headers of the mapped file
and then output the disassembly via:
DEBUG_SYMBOL_ENTRY symEntry = /**/;
ULONG64 endOfInstruction = symEntry.Offset;
ULONG64 endOfSymbol = symEntry.Offset + symEntry.Size; // 2
while(endOfInstruction < endOfSymbol)
{
IDebugControl::OutputDisassembly(DEBUG_OUTCTL_THIS_CLIENT, endOfInstruction, DEBUG_DISASM_MATCHING_SYMBOLS, &endOfInstruction);
}
--- end

1. MapDataFileAsExeIntoHostExe() should map the file and its sections as if it were to be executed, e.g. with the section alignment specified in the NtHeader. The handle to the host.exe process is given to you by DbgEng through the IDebugEventCallbacks::CreateProcess callback. Use MapViewOfFileEx or equivalent to attempt to map the file at it's preferred base address (MappedFile->NtHeaders.OptionalHeader.ImageBase)
2. Some symbols don't have a size entry. In this case, DisAsm sorts all symbols by offset and takes the start of the next symbol as the end of the current one.
[/rollup]

[1] - The lesser known tool is certutil.exe, the command line to hash files is
certutil -hashfile
Hash name can be SHA1, SHA256, SHA384, SHA512, MD2, MD4, MD5, must be uppercase
adeyblue
Linux people who have to work in Windows are sometimes found lamenting about the basic tools it has which are absent from Microsoft's product. While recent developments of Windows have implemented variously featured versions of whoami, ln, cat, grep, ps and chmod, one app that's so far evaded the conversion is chroot.

Whatever the reason may be for its absence, it is definitely not because there's is no support mechanism for it. Just like in Linux, it's a single function call.


NtSetInformationProcess(hProcess, ProcessDeviceMap, &hObjectDirectory, sizeof(hObjectDirectory));


Ok, so it's technically one function call, but there needs to be a bit of setup beforehand...

Continue reading on Just Let it Flow
adeyblue
It doesn't sound like it should be so hard. I mean, the shell has managed to produce it every time you've logged on since Windows XP. MSDN has a page dedicated to user profiles that includes a section on where it is and how its treated. It details that a users picture lives in their temp directory, except for most times when it doesn't. It's not wrong in its description. The picture will turn up if you open the User Account control panel, but if you're trying to grab it programatically, asking the user to open Control Panel and all that or even worse, opening it from your own code and killing the window just as quick aren't fantastic solutions.

If you've searched for this before or being otherwise snooping through the shell's exported functions, you may have seen something called SHGetUserPicturePath or its ex version SHGetUserPicturePathEx. Just the sound of their names elicit sounds of joy, a joy that the long search is over. And it should be, except that it isn't. For one thing, up until a few weeks ago there was no public record of how to use them or what they do, at least not one picked up by Google. Now that's been rectified (with the docs above) and given the MSDN page, 2+2 would suggest these are the functions called upon opening the control panel.

Continue reading on Just Let It Flow
adeyblue
We all need ideas. Whether you've just finished something, or are getting a little bit bored with your current project you can't help but let your mind drift to the next cool thing you'll create. Sometimes the ideas come thick and fast, other times they're like gold dust. When I'm in the second camp, and reading the various boards I read, I will quite happily steal other peoples.

One such board is Sysinternals'. They do winternals, I do winternals, they have a suggestion section and I want ideas. It's a perfect fit. On a previous visit, one of the suggestions I found was for a program that could list active hooks. Given my previous excursions into user/win32k territory, it didn't seem like it'd be too hard. And apart from the digging around assembly listings for the structure offsets, it wasn't, and that was more time-intensive than difficult. At any rate, I am now the owner of 14 versions of win32k.sys' symbols. I don't even have 14 games on my computer!

Rather than just dumping a download link and saying what it does (like I semi-did last time), I thought I'd deconstruct the hows and why's of the kernel side of the query. Needless to say, much of what follows is discussion of undocumented things. I am aware this makes Raymond Chen cry. Sorry fella.

Continue reading on Just Let It Flow

Apologies to BenS1, I didn't notice the comment on the previous blog entry. Looks like I went and did what you were after anyway :)
adeyblue
Sorry to crush your hopes but this isn't a post about my new job as a prostitute army drill sergeant. Nope, it's just another post of me shilling my wares.

In some distant part of the mists o'time, I wrote a little tool who purpose was to report pending messages and other misc info for a thread and the windows it owns. It's safe to say this was tangentially useful at best.

That was until I saw somebody, somewhere, ask if there was a tool that would or could list currently active Windows hooks and had an idea. After that idea sank (pineapple juice and tea do not go together even if you like them both), I went and stuck hook enumeration together with message and window enumeration to add to my previous work of desktop heap enumeration. Yep, if you need things enumerating, you can count on me.

So here we have it, MsgLister + hooks = MsgHookLister. The download zip contains the source for the app and the driver that pokes into undocumented Windows structures as well as x64 and x86 binaries.

A screenie of window mode
windowsxx.png

And of hook mode - how exciting
hooks.png

Hmm, what to enumerate now...
adeyblue
DLL hell isn't just the name given to managing monstrous dependency chains. It's also the name given to the phenomenon of pulling your hair out because LoadLibrary is returning NULL or because your dotNet app is throwing lots of System.DllNotFoundExceptions. The usual statement Windows gives as witness to these crimes is 'Module not found' as if it were some blind referee or umpire giving a call against the local sports team, while you swear blind at the injustice and can point at the exact file you wanted in an Explorer window.

On the surface of things it may seem like a hard luck story. Sure you can go hook this and that in effort to figure out why appending the filename to the dll search path resulted in failure, but like Bud Selig calling the 2002 All-Star game a tie, Windows levels the playing field by housing a certain tool you can leverage no matter which language you're coding in. All without having to write any more code in investigative anger nor download anything neither.

Continue reading on Just Let It Flow
adeyblue

U-A-Ceen Nothing Yet

Detecting whether UAC is enabled or not is something I've never needed to do. I can't really see how it can affect anything you architect one way or another but nevertheless, some people think it's necessary and nice to know.

While investigating something else, I stumbled across a more accurate method of making the determination as opposed to reading the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA registry value. Looking around the Internet, it seems reading that key is often touted as the way to do it. There's nothing wrong with using this method, well, apart for one caveat: if the state of UAC has changed and the computer hasn't restarted yet, you'll get an erroneous result [sup][1][/sup].

Being Windows, and its tens of thousands of undocumented functions, you'd expect there to be at least one function that returns whether an integral part of the OS is enabled or not. A quick search of exports with 'elevat' in the name in the big ol' database returned these matches for Vista:

elevated.png

Knowing that all the useful goodies are hidden in either kernel32 or ntdll, and having a name exactly along the lines of what I was looking for, CheckElevationEnabled seemed like a great place to start.

[source lang="asm"]
public _CheckElevationEnabled@4

var_4 = dword ptr -4
pBool = dword ptr 8

mov edi, edi
push ebp
mov ebp, esp ; standard prolog
push ecx ; make some stack space
lea eax, [ebp+var_4] ; get a pointer to it
push eax ; pass it on
call ds:__imp__RtlQueryElevationFlags@4 ; RtlQueryElevationFlags(&x)
test eax, eax
jl short loc_77C200DF ; jump if !NT_SUCCESS
mov eax, [ebp+var_4] ; put the filled in value in eax
mov ecx, [ebp+pBool] ; move our pointer to ecx
and eax, 1 ; mask off all but the lowest bit
mov [ecx], eax ; here's how we know pBool is a pointer
xor eax, eax ; set error to STATUS_SUCCESS

loc_77C200DF: ; CODE XREF: CheckElevationEnabled(x)+12
push eax
call ds:__imp__RtlNtStatusToDosErrorNoTeb@4 ; translate STATUS_* to ERROR_*
leave
retn 4
[/source]
Or in C
[source lang="c"]
DWORD WINAPI CheckElevationEnabled(BOOL* pResult)
{
DWORD x;
NTSTATUS stat = RtlQueryElevationFlags(&x);
if(NT_SUCCESS(stat))
{
*pResult = (x & 1);
}
return RtlNtStatusToDosErrorNoTeb(stat);
}
[/source]

Unfortunately, it didn't really clear anything up. It's obviously checking whether a flag/bit is set, but there's no info on what the flag refers to or where it's coming from. It'd be easy to guess it is doing what we'd like it to but more spelunking is needed, next stop RtlQueryElevationFlags:

[source lang="asm"]
_RtlQueryElevationFlags@4 proc near

pFlags = dword ptr 8

mov edi, edi
push ebp
mov ebp, esp
mov eax, [ebp+pFlags]
and dword ptr [eax], 0 ; clear the slate
test byte ptr ds:7FFE02F0h, 2 ; test the second bit of the address
jz short loc_77CEEE74 ; go to next if not set
mov dword ptr [eax], 1 ; set flags to one if it is

loc_77CEEE74: ; CODE XREF: RtlQueryElevationFlags(x)+12
test byte ptr ds:7FFE02F0h, 4 ; test the third bit
jz short loc_77CEEE80 ; skip to next test if not set
or dword ptr [eax], 2 ; or on the relevant flag is it is

loc_77CEEE80: ; CODE XREF: RtlQueryElevationFlags(x)+21
test byte ptr ds:7FFE02F0h, 8 ; test the fourth bit
jz short loc_77CEEE8C ; skip to exit
or dword ptr [eax], 4 ; or on the relevant flag if it is

loc_77CEEE8C: ; CODE XREF: RtlQueryElevationFlags(x)+2D
xor eax, eax ; return STATUS_SUCCESS
pop ebp
retn 4
_RtlQueryElevationFlags@4 endp
[/source]

Rather strangely, the data it queries comes directly from a byte at a hardcoded address offset rather than via a kernel API call or a specific global pointer. From a strictly disassembly point of view, there's absolutely nothing new to go on to figure what the flags mean or represent. It did show that the error checking in CheckElevationEnabled is superfluous but other than that, nothing.

Of course, this is Windows and ntdll specifically, so it's unlikely that this requires a look at the source to figure out. Taking off the obvious 2f0 offset, googling or querying the address in WinDGB [sup][2][/sup] shows that 0x7ffe0000 is the address where the KUSER_SHARED_DATA [sup][3][/sup] (also called UserSharedData) structure lives. This structure is just a big bunch of parameters shared between user and kernel mode in memory that is mapped to the same address in every process. Forget PHP, this is a true superglobal.

Knowing the name makes the format easy to figure out. One option is to use a tool like Dia2Dump to list all the types and members from ntdll's symbols and grep the results. In a nice change of pace for this specific struct however, looking at the wdm.h or ntddk.h header files in the WDK, reveal it in C form, completely documented, and with some helpful comments to boot.

Back to the matter at hand, checking the struct for offset 0x2f0 reveals the queried structure bits to be:
[source lang="c"]
union {
ULONG SharedDataFlags;
struct {

//
// The following bit fields are for the debugger only. Do not use.
// Use the bit definitions instead.
//

ULONG DbgErrorPortPresent : 1;
ULONG DbgElevationEnabled : 1; // second bit
ULONG DbgVirtEnabled : 1; // third bit
ULONG DbgInstallerDetectEnabled : 1; // fourth bit
ULONG DbgSystemDllRelocated : 1;
ULONG DbgDynProcessorEnabled : 1;
ULONG DbgSEHValidationEnabled : 1;
ULONG SpareBits : 25;
} DUMMYSTRUCTNAME2;
} DUMMYUNIONNAME2;
[/source]

It's nice to put a name to data. Names which coincide with the settings found in the registry key are especially pleasing as it means this is undoubtedly the in-memory equivalent of those values. In order, the second bit denotes whether UAC is enabled, the third failed registry/file write virtualisation, and the fourth whether installers are detected and automatically elevated.

From the slight chance of wrong data from the registry, the train arrives into its station with an extra three methods of querying UAC. A direct read of a hardcoded address (not that that's recommend), a straight call to RtlQueryElevationFlags [sup][4][/sup], or if you only care about UAC and not virtualisation or installer detection, CheckElevationEnabled.

If only this was useful in some way, oh well.




Notes:
[sup][1][/sup] Despite the minor stated limitation, this is the method employed by ?IEStubIsLuaEnabled@@YGHXZ, ordinal 30 in iertutil.dll on Vista and above

[sup][2][/sup] WinDBG has the !ksuser extension to display the data contained in the KUSER_SHARED_DATA mapping

[sup][3][/sup] KUSER_SHARED_DATA contents from Windows 7 SP1 32-bit layout via ntdll.dll's symbols.
To dump it yourself, get the PDB and run 'dia2dump -t "A:\Path\To\ntdll\symbols.pdb" > symboltypes.txt'
See ntddk.h or wdm.h in the DDK for the struct in C format.
[source lang="text"]
UserDefinedType: _KUSER_SHARED_DATA
Data : this+0x0, Member, Type: unsigned long, TickCountLowDeprecated
Data : this+0x4, Member, Type: unsigned long, TickCountMultiplier
Data : this+0x8, Member, Type: volatile struct _KSYSTEM_TIME, InterruptTime
UserDefinedType: _KSYSTEM_TIME

Data : this+0x14, Member, Type: volatile struct _KSYSTEM_TIME, SystemTime
UserDefinedType: _KSYSTEM_TIME

Data : this+0x20, Member, Type: volatile struct _KSYSTEM_TIME, TimeZoneBias
UserDefinedType: _KSYSTEM_TIME

Data : this+0x2C, Member, Type: unsigned short, ImageNumberLow
Data : this+0x2E, Member, Type: unsigned short, ImageNumberHigh
Data : this+0x30, Member, Type: wchar_t[0x104], NtSystemRoot
Data : this+0x238, Member, Type: unsigned long, MaxStackTraceDepth
Data : this+0x23C, Member, Type: unsigned long, CryptoExponent
Data : this+0x240, Member, Type: unsigned long, TimeZoneId
Data : this+0x244, Member, Type: unsigned long, LargePageMinimum
Data : this+0x248, Member, Type: unsigned long[0x7], Reserved2
Data : this+0x264, Member, Type: enum _NT_PRODUCT_TYPE, NtProductType
Data : this+0x268, Member, Type: unsigned char, ProductTypeIsValid
Data : this+0x26C, Member, Type: unsigned long, NtMajorVersion
Data : this+0x270, Member, Type: unsigned long, NtMinorVersion
Data : this+0x274, Member, Type: unsigned char[0x40], ProcessorFeatures
Data : this+0x2B4, Member, Type: unsigned long, Reserved1
Data : this+0x2B8, Member, Type: unsigned long, Reserved3
Data : this+0x2BC, Member, Type: volatile unsigned long, TimeSlip
Data : this+0x2C0, Member, Type: enum _ALTERNATIVE_ARCHITECTURE_TYPE, AlternativeArchitecture
Data : this+0x2C4, Member, Type: unsigned long[0x1], AltArchitecturePad
Data : this+0x2C8, Member, Type: union _LARGE_INTEGER, SystemExpirationDate
UserDefinedType: _LARGE_INTEGER

Data : this+0x2D0, Member, Type: unsigned long, SuiteMask
Data : this+0x2D4, Member, Type: unsigned char, KdDebuggerEnabled
Data : this+0x2D5, Member, Type: unsigned char, NXSupportPolicy
Data : this+0x2D8, Member, Type: volatile unsigned long, ActiveConsoleId
Data : this+0x2DC, Member, Type: volatile unsigned long, DismountCount
Data : this+0x2E0, Member, Type: unsigned long, ComPlusPackage
Data : this+0x2E4, Member, Type: unsigned long, LastSystemRITEventTickCount
Data : this+0x2E8, Member, Type: unsigned long, NumberOfPhysicalPages
Data : this+0x2EC, Member, Type: unsigned char, SafeBootMode
Data : this+0x2ED, Member, Type: unsigned char, TscQpcData
Data : this(bf)+0x2ED:0x0 len(0x1), Member, Type: unsigned char, TscQpcEnabled
Data : this(bf)+0x2ED:0x1 len(0x1), Member, Type: unsigned char, TscQpcSpareFlag
Data : this(bf)+0x2ED:0x2 len(0x6), Member, Type: unsigned char, TscQpcShift
Data : this+0x2EE, Member, Type: unsigned char[0x2], TscQpcPad
Data : this+0x2F0, Member, Type: unsigned long, SharedDataFlags
Data : this(bf)+0x2F0:0x0 len(0x1), Member, Type: unsigned long, DbgErrorPortPresent
Data : this(bf)+0x2F0:0x1 len(0x1), Member, Type: unsigned long, DbgElevationEnabled
Data : this(bf)+0x2F0:0x2 len(0x1), Member, Type: unsigned long, DbgVirtEnabled
Data : this(bf)+0x2F0:0x3 len(0x1), Member, Type: unsigned long, DbgInstallerDetectEnabled
Data : this(bf)+0x2F0:0x4 len(0x1), Member, Type: unsigned long, DbgSystemDllRelocated
Data : this(bf)+0x2F0:0x5 len(0x1), Member, Type: unsigned long, DbgDynProcessorEnabled
Data : this(bf)+0x2F0:0x6 len(0x1), Member, Type: unsigned long, DbgSEHValidationEnabled
Data : this(bf)+0x2F0:0x7 len(0x19), Member, Type: unsigned long, SpareBits
Data : this+0x2F4, Member, Type: unsigned long[0x1], DataFlagsPad
Data : this+0x2F8, Member, Type: unsigned __int64, TestRetInstruction
Data : this+0x300, Member, Type: unsigned long, SystemCall
Data : this+0x304, Member, Type: unsigned long, SystemCallReturn
Data : this+0x308, Member, Type: unsigned __int64[0x3], SystemCallPad
Data : this+0x320, Member, Type: volatile struct _KSYSTEM_TIME, TickCount
UserDefinedType: _KSYSTEM_TIME

Data : this+0x320, Member, Type: volatile unsigned __int64, TickCountQuad
Data : this+0x320, Member, Type: unsigned long[0x3], ReservedTickCountOverlay
Data : this+0x32C, Member, Type: unsigned long[0x1], TickCountPad
Data : this+0x330, Member, Type: unsigned long, Cookie
Data : this+0x334, Member, Type: unsigned long[0x1], CookiePad
Data : this+0x338, Member, Type: __int64, ConsoleSessionForegroundProcessId
Data : this+0x340, Member, Type: unsigned long[0x10], Wow64SharedInformation
Data : this+0x380, Member, Type: unsigned short[0x10], UserModeGlobalLogger
Data : this+0x3A0, Member, Type: unsigned long, ImageFileExecutionOptions
Data : this+0x3A4, Member, Type: unsigned long, LangGenerationCount
Data : this+0x3A8, Member, Type: unsigned __int64, Reserved5
Data : this+0x3B0, Member, Type: volatile unsigned __int64, InterruptTimeBias
Data : this+0x3B8, Member, Type: volatile unsigned __int64, TscQpcBias
Data : this+0x3C0, Member, Type: volatile unsigned long, ActiveProcessorCount
Data : this+0x3C4, Member, Type: volatile unsigned short, ActiveGroupCount
Data : this+0x3C6, Member, Type: unsigned short, Reserved4
Data : this+0x3C8, Member, Type: volatile unsigned long, AitSamplingValue
Data : this+0x3CC, Member, Type: volatile unsigned long, AppCompatFlag
Data : this+0x3D0, Member, Type: unsigned __int64, SystemDllNativeRelocation
Data : this+0x3D8, Member, Type: unsigned long, SystemDllWowRelocation
Data : this+0x3DC, Member, Type: unsigned long[0x1], XStatePad
Data : this+0x3E0, Member, Type: struct _XSTATE_CONFIGURATION, XState
[/source]

[sup][4][/sup] Here's a simple wrapper for RtlQueryElevationFlags so you don't have to bother with the function typedefs and all that jazz.
[source lang="cpp"]
enum ElevationFlags
{
ELEVATION_UAC_ENABLED = 1,
ELEVATION_VIRTUALIZATION_ENABLED = 2,
ELEVATION_INSTALLER_DETECTION_ENABLED = 4
};

void GetElevationFlags(ElevationFlags* pFlags)
{
assert(pFlags);
typedef NTSTATUS (NTAPI*pfnRtlQueryElevationFlags)(ElevationFlags*);
HMODULE hNtdll = GetModuleHandle(L"ntdll.dll");
pfnRtlQueryElevationFlags rtlQueryElevationFlags = (pfnRtlQueryElevationFlags)GetProcAddress(hNtdll, "RtlQueryElevationFlags");
assert(rtlQueryElevationFlags);
rtlQueryElevationFlags(pFlags);
}
[/source]
adeyblue
Yep, I'm now on iTunes and further reducing the Gamedev's journals' 'hit to miss ratio of useful-ity' at the same time. My place on iTunes isn't in any technical sections, heck no. I do have a hackintosh set up but after it took me 10 minutes to figure out where the off button was, the idea that I'm currently not in any position to be doing anything useful on that platform yet sprang to mind.

So what am I on about? A bit of background. First, the BBC were recently running a sitcom competition which I entered and didn't win. A production company then ran a competition for a stage based sitcom, which I entered and didn't win. Then I started sending stuff into BBC Radio 7's Newsjack, which I've also been unsuccessful with. They say 'if you can't beat them, join them' and as I've been unable to join them, I went the other way and have beaten them into submission** with my own one man news parodying sketch show which is what is on iTunes.

As with most shows, it ends with a song. The first of such being Gaddafi singing a song to give his side of the current situation.
[media]
[/media]
Video link with lyrics

In other news, WindowWatcher (see previous post) is finished. I just have to bother to create a page on the website for it and then actually properly open it for public consumption.

Also, despite (or maybe because of) me not actually ever owning a NES, I've started watching episodes of Chrontendo. A chronological documentary (well, it's factual at any rate) of a guy going through the history of the machine giving 3-5 minute histories and other bits of info on every NES games released. There's also a sister series about the Master System, which is where I started watching from. This is probably the easiest way of finding episodes of each.

----

** It's totally not a coincedence that the series has finished its current run, leaving me nothing to write for
adeyblue
No, it's not an Andy Williams inspired poem, it's actual pictures of the thing I've been working on. Imagine that.

Enter WindowWatcher:
onepb.png

It's a single window, that displays another single window, keeping it on top. Great for watching stuff like TV or Youtube playlists in a small corner of your workspace while working in the rest of it. It's also great for tasks that would otherwise require flicking back and forth between windows, reading documentation and key tapping in the IDE for instance.

As you can see from above, you can zoom into specific areas, repeatedly if so desired. After that you can resize the window to blow up that specific portions way beyond normal size:
threev.png

Of course, passive viewing by itself isn't brilliant. To address this WindowWatcher allows interaction too, anything you could do with the mouse and keyboard in the original window you can do via it. Posting to Twitter or Facebook, STFW-ing and faffing with WMP playlists being my current poisons:

fourq.png

Topping it off there's a simple plugin API for those stubborn windows which don't react normally to window messages.

Those windows better watch out, there's a new stalker in town.
adeyblue
It happens to be that time again, where all the loved up people get all mushy with their sentimental I love you's. Just like Christmas though, there are no doubt some people who have a distaste for all that jazz.

So here's something I do every year, and that's write a poem that's not in the least bit mushy or about loving someone, but it is pretty UK centric:

Hey, how ya doing? Nice to have your support
You're in on the ground floor I'm glad to import
A brand new prodigy, a rapping sensation
Spitting truth at a rate that outpaces inflation
With rhythmic oration I'm laying tracks in the booth
Should've used my hands though, shouting at nails is no use
Laying it out like Shayne Ward, yo this is gonna be handsome
Directing the youth from gangs and onto Esther Rantzen
Showing them hey, guys there's no need to boast
Truth is real beauty and you can spread that on your toast
The track's finally finished now I can record the words
Who's got the piece of paper with my list of verbs?

Read the exciting conclusion on Just Let It Flow. it contains an actual verse from the song, the video shoot, Loose Women, Cricket, a brilliant pun or two, a non-surgical replacement for bum pumping and that old favourote Aesop's Fables.
adeyblue
What do you get when you combine C#, C++/CLI, Access 2003, VirtualBox, a few ISOs and too much free time?

You get a 345MB database of the complete API and dependency history of 32-bit Windows. Yep, every OS module from Win95 onwards has had its imports, exports, and selected PE header info extracted and committed to a handy-dandy Access 2000 format database. That's a chronicle of 41 OS versions, 47,000+ modules, over 2,100,000 exports and over 5,125,000 imports. It also contains a bunch of premade SQL queries for statistical usage and some useful ones too such as "Which modules import a specific function?" and "What are the differences between dll version x and y?"

An idea of what data is available:

Platforms
platforms-162x300.png

OS Export counts
exportcounts-186x300.png

Modules which import a specific function on a specific OS, here its SHUnicodeToAnsi on Vista SP0
shunicodetoansiimporters-243x300.png

You can download the 35MB 7-zip archive as well as lark around with other statisical data on the registry and resources from that cheekily embedded link. Happy querying.
adeyblue
There's tonnes of example on how to use SWbemDateTime to convert from FILETIME's or CDates in VBScript, yet I couldn't find any for C++. So here's how...

All WMI queries that give or take datetime values, do so in a certain format called CIM_DATETIME. For scripting guys, this is only a minor inconvenience. The following listing is the entire code to display the OS install date in various formats:


' Create a new datetime object.
Set dateTime = CreateObject("WbemScripting.SWbemDateTime")

' Retrieve a WMI object that contains a datetime value.
for each os in GetObject( _
"winmgmts:").InstancesOf ("Win32_OperatingSystem")

' The InstallDate property is a CIM_DATETIME.
MsgBox os.InstallDate
dateTime.Value = os.InstallDate

' Display the year of installation.
MsgBox "This OS was installed in the year " & dateTime.Year

' Display the installation date using the VT_DATE format.
MsgBox "Full installation date (VT_DATE format) is " _
& dateTime.GetVarDate

' Display the installation date using the FILETIME format.
MsgBox "Full installation date (FILETIME format) is " _
& dateTime.GetFileTime
next
Set datetime = Nothing

For the native coders among us, the standard Win32 time functions neither produce nor consume this format meaning we have to perform some jiggery poker to get it to play nice.

Read the rest on Just Let It Flow
adeyblue
We all know that stepping over array bounds is easily managed in C and C++. So much so that the C standard library has a function, gets, which may as well be named 'cause_buffer_overflow'. The consequences of overflowing a buffer are also understood, pretty much anything can happen. To demonstrate just how serious this can be, I'd like to relay something based on a true story:

"I'm a wizzy coder, do all my work in C
Function upon function of technical wizardry
I'm a scanf lord, the King Midas of gets
All I touch becomes gold and I don't have to fret"
That was the old me, coding with no fear of reprises
And no hard line respecter of stack buffer sizes
Until one fateful day when I was processing a file
Part of an assignment I'd grown to revile
It'd taken me a week, well I was just lazy
So like any respective student, I crammed like crazy
Line length was hardcoded, 80 chars in size
Thinking that was all was the start of my demise
Sample appointments piped into stdin
Consumed by gets, listed and linked in
I set off a test; you know to check my work
When I returned it was stuck looping on Captain Kirk
He was booked for back spasms; that much I remember
Thinking he ain't nothing but a Picard pretender
I attached a debugger to pacify the problem kitten
But everywhere I looked memory had been overwritten
Line by line and char by char
My buffer was filling up far too far
Off into the lands of the undefined realm
My program went careering with no-one at the helm
Surely it'd crash soon, there had to be an end
But the data kept coming like a royal stipend
First the window went white; Windows said it had to close
But it was running rampant just inches from my nose
The control-c combo, a press of escape
The keys mean nothing, hell I even pressed break
Explorer went down citing an access violation
But I know that's a euphemism for backdoor propagation
The assimilation had begun, the wallpaper turned green
I moved from the monitor to swerve the scanner beam
"We are the Borg, resistance is futile
Our boys are quite ugly but our dames are nubile
If you want to see them dance and be left with no saliva
Please accept the dialog to install our unsigned driver"
There was the crack, the weakness of the queen
User-mode was knackered but the kernel was still clean
I wondered how to extract these ring 3 dwellers
When my deflector dish contained nothing but half-eaten mozzarella
I changed my footwear, took off my red shirt
Whitened my face and brought in a little squirt
The dialog counted down, we couldn't wait any longer
Although the smelly-sock repeller couldn't get any stronger
I tried to hack it open, create some interface
When Wesley said "What about livekd from that sysinternals place?"
That was it; we were in, but with no symbols bestowed
.restart for a quick kill but the attempt was vetoed
Now I've seen the episode, I tried some root commands
"sudo rm /the_borg_and_their_plans"
'> sudo undefined', '> ...their_plans are locked'
Then "Shouldn't you have a nap?"; the USB lines aren't blocked?
The dialog timed out, the install progress blinked
And the toaster's trying to tell me that I need 40 winks?
"Can you believe this?" I scoffed at the distraction
"I believe the message intended a swift course of action"
Wesley piped up, the sweat glistening on his brow
"Powering down to S3, it's all we can do now"
From 80 up to 90, the install was relentless
And I'd missed borgesses in states of undressedness
The toaster powered down, the install had completed
"We are the Borg, we cannot be defeat..."
One syllable to go and that's where it stopped
As I unplugged the computer and the scan field dropped
Did they manage to spread? How far did it go?
And all this from a humble single byte overflow
I really didn't mean it, I promised to be good
I'll query buffer sizes and be a security stud
Or better yet change to std::getline
and make C++ a bedfellow of mine
No percent formats in sight, yeah, onto bigger better things
No char pointer reallocs only std::strings
I didn't switch completely, it has to be told
Because of the aftermath of that day which I'll now extol
After it all happened there was a knock at the door
"I believe you ordered some food, and wait there's more
It's totally free, yes nothing to pay"
Can you believe it? Undefined behaviour finally went my way
The day that started with coding and ended with tomatoed bread
Could've only been better if I'd got some Borg boobies instead
But as it stands now, I've learned how to go far
Respect buffer sizes but ignore Kirk's lower lumbar

If you got here that means you didn't baulk after the flimsy setup. You can find more of my well, technical poetry I'd guess you call it here, if you can stomach them that is. Oh and no, it wasn't based on a true story at all. I'd never use gets in a million years :-)
adeyblue
Recently WinDevs, the guys in charge of developing the Getting Started content for native developers on MSDN, and I had a short conversation relating to message loops. They're in the process of creating a Win32 tutorial in the vein of TheForgers teaching the basics of creating a small Direct2D drawing app. The message loop used in their tutorials is the ubiquitous:


MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}


On a forum I visit, one of the denizens had pointed out in response to an unrelated query that the GetMessage documentation states -1 can be returned on failure and that the loop above should not be used, instead advising programmers to use:


MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}


As the tutorial is aimed at beginners and no doubt intended to teach best practices, I mentioned the contradictory advice to them. After a bit of investigation, they've since explained the incongruity. MSDN mentions as examples that an invalid HWND and an invalid message pointer can be causes of a -1 return. Being curious about such things and not entirely trusting of MSDN's words, I wondered what exactly causes such a return...

Read the rest of the entry on Just Let It Flow