Spelunking Windows – Tokens for fun and profit

I want to shutdown/restart my machine programmatically. There’s an API for that:

-- kernel32.dll
BOOL
InitiateSystemShutdownExW(
    LPWSTR lpMachineName,
    LPWSTR lpMessage,
    DWORD dwTimeout,
    BOOL bForceAppsClosed,
    BOOL bRebootAfterShutdown,
    DWORD dwReason);

Wow, it’s that easy?!!

OK. So, I need the name of the machine, some message to display in a dialog box, a timeout, force app closure, reboot or not, and some reason why the shutdown is occuring. That sounds easy enough. So, I’ll just give it a call…

local status = core_shutdown.InitiateSystemShutdownExW(
  nil,    -- nil, so local machine
  nil,    -- no special message
  10,     -- wait 10 seconds
  false,  -- don't force apps to close
  true,   -- reboot after shutdown
  ffi.C.SHTDN_REASON_MAJOR_APPLICATION);

And what do I get for my troubles?
> error: (5) ERROR_ACCESS_DENIED

Darn, now I’m going to have to read the documentation.

In the Remarks of the documentation, it plainly states:

To shut down the local computer, the calling thread must have the SE_SHUTDOWN_NAME privilege.

Yah, ok, right then. What’s a privilege? And thus Alice went down into the rabbit’s hole…

As it turns out, there are quite a few concepts in Windows that are related to identity, security, authorization, and the like. As soon as you log into your machine, even if done programmatically, you get this thing called a ‘Token’ attached to your process. The easiest way to think of the token is it’s your electronic proxy and passport. Just like your passport, this token contains some basic identity information about who you are (name, identifying marks…). Some things in the system, such as being able to access a file, can be handled simply by knowing your name. These are simple access rights. But, other things in the system require a ‘visa’, meaning, not only does the operation have to know who you are, but it also needs to know you have the proper permissions to perform the operation you’re about to perform. It’s just like getting a visa stamped into your passport. If I want to travel to India, my passport alone is not enough. I need to get a visa as well. The same is true of this token thing. It’s not enough that I simply have an identity, I must also have a “privilege” in order to perform certain operations.

In addition to having a privilege, I must actually ‘activate’ it. So, yes, the system may have granted me the privilege, but it’s like super powers, you don’t want them to always be active. It’s like when you’re walking down the street in that foreign country you’re visiting. You don’t walk down the street flashing your fancy passport showing everyone the neat visas you have stamped in there. If you do, you’ll likely get a crowd following you trying to relieve you of said passport. So, you generally keep it to yourself, and only flash it when the need arises. So too with token privilege. Yes, you might have the ability to reboot the machine, but you don’t always want to have that privilege enabled, in case some nefarious software so happens to come along to exploit that fact.

Alright, that’s enough analogizing. How about some code. Well, it can be daunting to get your head around the various APIs associated with tokens. To begin with, there is a token associated with the process you’re currently running in, and there is a token associated with every thread you may launch from within that process as well. Generally, you want the process token if you’re single threaded. That’s one API call:

BOOL
OpenProcessToken (
    HANDLE ProcessHandle,
    DWORD DesiredAccess,
    PHANDLE TokenHandle
    );

This is one of those standard API calls where you pass in a couple of parameters (ProcessHandle, DesiredAccess), and a ‘handle’ is returned (TokenHandle). You then use the ‘handle’ to make subsequent calls to the various API functions. This is ripe for wrapping up in some nice data structure to deal with it.

I’ve created the ‘Token’ object, as the convenience point. One of the functions in there is this one:

getProcessToken = function(self, DesiredAccess)
  DesiredAccess = DesiredAccess or ffi.C.TOKEN_QUERY;
	
  local ProcessHandle = core_process.GetCurrentProcess();
  local pTokenHandle = ffi.new("HANDLE [1]")
  local status  = core_process.OpenProcessToken (ProcessHandle, DesiredAccess, pTokenHandle);

  if status == 0 then
    return false, errorhandling.GetLastError();
  end

  return Token(pTokenHandle[0]);
end

One of the important things to take note of when you create a token is the DesiredAccess. What you can do with a token after it is created is somewhat determined by the access that you put into it when you create it. Here are the various options available:

static const int TOKEN_ASSIGN_PRIMARY    =(0x0001);
static const int TOKEN_DUPLICATE         =(0x0002);
static const int TOKEN_IMPERSONATE       =(0x0004);
static const int TOKEN_QUERY             =(0x0008);
static const int TOKEN_QUERY_SOURCE      =(0x0010);
static const int TOKEN_ADJUST_PRIVILEGES =(0x0020);
static const int TOKEN_ADJUST_GROUPS     =(0x0040);
static const int TOKEN_ADJUST_DEFAULT    =(0x0080);
static const int TOKEN_ADJUST_SESSIONID  =(0x0100);

For the case where we want to turn on a privilege that’s attached to the token, we will want to make sure the ‘TOKEN_ADJUST_PRIVILEGES’ access right is attached. It also does not hurt to add the ‘TOKEN_QUERY’ access as well. It’s probably best to use the least of these rights as is necessary to get the job done.

Setting a privilege on a token is another bit of work. It’s not hard, but it’s just one of those things where you have to read the docs, and look at a few samples on the internet in order to get it right. Assuming your token has the TOKEN_ADJUST_PRIVILEGES access right on it, you can do the following:

Token.enablePrivilege = function(self, privilege)
  local lpLuid, err = self:getLocalPrivilege(privilege);
  if not lpLuid then
    return false, err;
  end

  local tkp = ffi.new("TOKEN_PRIVILEGES");
  tkp.PrivilegeCount = 1;
  tkp.Privileges[0].Luid = lpLuid;
  tkp.Privileges[0].Attributes = ffi.C.SE_PRIVILEGE_ENABLED;

  local status = security_base.AdjustTokenPrivileges(self.Handle.Handle, false, tkp, 0, nil, nil);

  if status == 0 then
    return false, errorhandling.GetLastError();
  end

  return true;
end

Well, that gets into some data structures, and introduces this thing called a LUID, and that AdjustTokenPrivileges function, and… I get tired just thinking about it. Luckily, once you have this function, it’s a fairly easy task to turn a privilege on and off.

OK. So, with this little bit of code in hand, I can now do the following:

	local token = Token:getProcessToken(ffi.C.TOKEN_ADJUST_PRIVILEGES);
	token:enablePrivilege(Token.Privileges.SE_SHUTDOWN_NAME);

This just gets a token that is associated with the current process and turns on the privilege that allows us to successfully call the shutdown function.

In totality:

-- test_shutdown.lua
local ffi = require("ffi");

local core_shutdown = require("core_shutdown_l1_1_0");
local errorhandling = require("core_errorhandling_l1_1_1");
local Token = require("Token");

local function test_Shutdown()
  local token = Token:getProcessToken();
  token:enablePrivilege(Token.Privileges.SE_SHUTDOWN_NAME);
	
  local status = core_shutdown.InitiateSystemShutdownExW(nil, nil,
    10,false,true,ffi.C.SHTDN_REASON_MAJOR_APPLICATION);

  if status == 0 then
    return false, errorhandling.GetLastError();
  end

  return true;
end

print(test_Shutdown());

And finally we emerge back into the light! This will now actually work. It’s funny, when I got this to work correctly, I pointed out to my wife that my machine was rebooting without me touching it. She tried to muster a smile of support, but really, she wasn’t that impressed. But, knowing the amount of work that goes into such a simple task, I gave myself a pat on the back, and smiled inwardly at the greatness of my programming fu.

Tokens are a very powerful thing in Windows. Being able to master both the concepts, and the API calls themselves, gives you a lot of control over what happens with your machine.


Spelunking Windows – Exploring the file system

I’m working on programs that generally make your stuff available to you “from any device anywhere”. While some of the work is of the generic internet high performance server variety, some of it is much more esoteric. A lot of your “stuff” is in files located on your machine. Widows has a wild array of filesytem related APIs, and it can be a daunting task to try and wrap your head around it to achieve some given task.

I set out a task for myself to turn the file system into a relatively easy to query “database” to get lists of files that meet certain criteria based on their various attributes. Some queries that I’m interested in:

List all directories on my machine
List all files that contain “.lua”
List all files which are hidden
List all system files
List all compressed files

Of course, using the standard search capabilities that are built into Windows, you can perform some of these tasks. This is different from the generally useful ‘find’ command of the command shell as well, as that command is interested in searching the contents of the file.

Yes, there are numerous tools and ways to perform these tasks, so what I am exploring is how you would actually create such a tool from scratch if you were so inclined.

I will begin at the beginning. Exploring the file system doesn’t require that much. Just a few data structures, and 3 function calls. The key components are the following:
(Full Source Available here: https://github.com/Wiladams/TINN/tree/master/tests FileSystemItem.lua, test_filesystem.lua)

ffi.cdef[[
typedef struct _WIN32_FIND_DATAW {
    DWORD dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD nFileSizeHigh;
    DWORD nFileSizeLow;
    DWORD dwReserved0;
    DWORD dwReserved1;
    WCHAR  cFileName[ MAX_PATH ];
    WCHAR  cAlternateFileName[ 14 ];
} WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;

HANDLE
FindFirstFileExW(
  LPCWSTR lpFileName,
  FINDEX_INFO_LEVELS fInfoLevelId,
  LPVOID lpFindFileData,
  FINDEX_SEARCH_OPS fSearchOp,
  LPVOID lpSearchFilter,
  DWORD dwAdditionalFlags);

BOOL
FindNextFileW(HANDLE hFindFile,
  LPWIN32_FIND_DATAW lpFindFileData);

BOOL
FindClose(HANDLE hFindFile);
]]

The three functions; FindFirstFileExW, FindNextFileW, FindClose; combine to form an ‘iteration’ set. The iteration begins with FindFirstFileExW, which also returns the first results, and continues with FindNextFileW. After all is done, you finish up with FindClose, to recover the system resources that were allocated for this little search. Although there are flags to be set to enhance the search capabilitie, I don’t actually want to use them as I can create much more interesting search filters from the Lua side.

First things first though. The ‘handle’ that is created when you call ‘FindFirstFileExW’ must be cleaned up with a matching ‘FindClose’. If you don’t do this, you’ll end up with a leaked handle, which is essentially a resource leak. You don’t want that, so a ‘smart pointer’ is created to deal with the lifetime of that thing.

ffi.cdef[[
typedef struct {
  HANDLE Handle;
} FsFindFileHandle;
]]
local FsFindFileHandle = ffi.typeof("FsFindFileHandle");
local FsFindFileHandle_mt = {
  __gc = function(self)
    core_file.FindClose(self.Handle);
  end,

  __index = {
    isValid = function(self)
      return self.Handle ~= INVALID_HANDLE_VALUE;
    end,
  },
};
ffi.metatype(FsFindFileHandle, FsFindFileHandle_mt);

This little wrapper ensures that whenever the handle is no longer being referenced, it will automatically get cleaned up because the __gc method will call ‘FindClose()’, which is exactly what we want. Here is how it can be used:

local rawHandle = core_file.FindFirstFileExW(lpFileName,
  fInfoLevelId,
  lpFindFileData,
  fSearchOp,
  lpSearchFilter,
  dwAdditionalFlags);

local handle = FsFindFileHandle(rawHandle);

Alright, so there’s a nicely wrapped handle to the beginning of the iterator. The full iterator looks like this:

-- Iterate over the subitems this item might contain
FileSystemItem.items = function(self, pattern)
	pattern = pattern or self:getFullPath().."\\*";
	local lpFileName = core_string.toUnicode(pattern);
	--local fInfoLevelId = ffi.C.FindExInfoStandard;
	local fInfoLevelId = ffi.C.FindExInfoBasic;
	local lpFindFileData = ffi.new("WIN32_FIND_DATAW");
	local fSearchOp = ffi.C.FindExSearchNameMatch;
	local lpSearchFilter = nil;
	local dwAdditionalFlags = 0;

	local rawHandle = core_file.FindFirstFileExW(lpFileName,
		fInfoLevelId,
		lpFindFileData,
		fSearchOp,
		lpSearchFilter,
		dwAdditionalFlags);

	local handle = FsFindFileHandle(rawHandle);
	local firstone = true;

	local closure = function()
		if not handle:isValid() then 
			return nil;
		end

		if firstone then
			firstone = false;
			return FileSystemItem({
				Parent = self;
				Attributes = lpFindFileData.dwFileAttributes;
				Name = core_string.toAnsi(lpFindFileData.cFileName);
				Size = (lpFindFileData.nFileSizeHigh * (MAXDWORD+1)) + lpFindFileData.nFileSizeLow;
				});
		end

		local status = core_file.FindNextFileW(handle.Handle, lpFindFileData);

		if status == 0 then
			return nil;
		end

		return FileSystemItem({
				Parent = self;
				Attributes = lpFindFileData.dwFileAttributes;
				Name = core_string.toAnsi(lpFindFileData.cFileName);
				});

	end
	
	return closure;
end

Refer to the full source to see it in context.

Here is how I would use it:

local depthQuery = {}

depthQuery.traverseItems = function(starting, indentation, filterfunc)
  indentation = indentation or "";

  starting = starting or FileSystemItem({Name="c:"});

  for item in starting:items() do
    if filterfunc then
      if filterfunc(item) then
        if item.Name ~= '.' and item.Name ~= ".." then
          io.write(indentation, item.Name, '\n');
        end
      end
    else
      if item.Name ~= '.' and item.Name ~= ".." then
        io.write(indentation, item.Name, '\n');
      end
    end
		
    if item:isDirectory() and item.Name ~= "." and item.Name ~= ".." then
      depthQuery.traverseItems(item, indentation.."  ", filterfunc);
    end
  end
end

-- Iterate all files/directories on 'c:' drive
depthQuery.traverseItems(FileSystemItem({Name="c:"}));

Scanning the entire c: drive on my recently new lenovo X1 carbon takes about 6 seconds, and there are a few hundred thousand files on it. Most of the time is spent on the string creation and io. On smaller directory searches, the scan is essentially instantaneous.

With these basics in hand, I can now do some more interesting queries.

local function passLua(item)
  return item.Name:find(".lua", 1, true);
end

depthQuery.traverseItems(FileSystemItem({Name="c:"}), "", passLua);

In this case, I want to find all the files on my system that have ‘.lua’ in their name. The ‘passLua()’ function is very simple, just doing a string compare. Of course, you have the full power of Lua and any libraries at your disposal. You could even open up the file if you like, and read the contents and decide whether you wanted to pass it along or not. Your filter just returns ‘true’ to pass it along, or ‘false’ to block it.

The FileSystemItem object has some of the file’s properties readily available, so they can be a part of the filtering as well. If I wanted a list of all the directories on my ‘c:’ drive, I would do the following:

local function passDirectory(item)
  return item:isDirectory();
end

depthQuery.traverseItems(FileSystemItem({Name="c:"}), "", passDirectory);

Of course, if you were using the .net frameworks, or Java, or Python, or any number of mature libraries in the world, you’d be thinking this was very simple work indeed, and what’s all the fuss? No fuss, really. The key here is showing how simple it really is to do these things, and create your own. I find it useful to do it in Lua because it’s easier than trying to do it with some more involved environments. Once the basic wrappers are in place, spelunking around becomes much easier.

Windows is a vast landscape of mature APIs which have evolved over time to meet the needs of diverse consumers over the years. The APIs are raw, and at times daunting. With a little bit of wrapping though, exploring them becomes much easier. In this particular case, by doing everything from the low level ffi to the higher level iterator, I’ve put in place some rope ladders, pitons, and other core exploration equipment. Now I can reap the benefits and do some more exploration with relative ease and safety.


When Is Software Engineering – Surely a database is required

So, I’ve gotten data, and presented it on a web page in JSON format.  If that’s not engineering, I’m not sure what is, but way, surely a database of sorts must be involved.

There are plenty of times in my code where I need to quickly filter some ‘records’ performing some activity only on those records that meet a particular criteria.  Given that Lua is table based, everything of interest becomes a ‘record’.  This applies to “classes” as well as the more garden variety of ‘records’ that might be streaming out of an actual database, or in my recent example, a simple iterator over the services on my machine.  It would be nice if I had some fairly straight forward way to deal with those records.   What I need is an iterator based query processor.

The requirements are fairly simple.  There are three things that are typical of record processors:

record source –  The source of data.  In my case, the source will be any iterator that feeds out simple key/value table structures.

projection – In database terminology, ‘projection’ is simply the list of fields that you want to actually present in the query results.  I might have a record that looks like this:

{name = "William", address="1313 Mockingbird Lane", occupation="enng"}

I might want to just retrieve the name though, so the projection would be simply:

{name = "William"}

filter – I want the ability to only retrieve the records that meet a particular criteria.

I will ignore aggregate functions, such as groupby, sort, and the like as those do not work particularly well with a streaming interface. What follows is a simple implementation of a query processor that satisfies the needs I listed above:

-- Query.lua
--

--[[
	the query function receives its parameters as a single table
	params.source - The data source.  It should be an iterator that returns
	table values

	params.filter - a function, that receives a single table value as input
	and returns a single table value as output.  If the record is 'passed' then
	it is returned as the return value.  If the record does not meet the filter
	criteria, then 'nil' will be returned.

	params.projection - a function to morph a single entry.  It receives a single
	table value as input, and returns a single table value as output.

	The 'filter' and 'projection' functions are very similar, and in fact, the
	filter can also be used to transform the input.  They are kept separate 
	so that each can remain fairly simple in terms of their implementations.
--]]

local query = function(params)
	if not params or not params.source then
		return false, "source not specified";
	end

	local nextRecord = params.source;
	local filter = params.filter;
	local projection = params.projection;


	local function closure()
		local record;

		if filter then
			while true do
				record = nextRecord();	
	
				if not record then
					return nil;
				end
				
				record = filter(self, record);

				if record then
					break;
				end
			end
		else
			record = nextRecord();
		end

		if not record then
			return nil;
		end

		if projection then
			return projection(self, record);
		end

		return record;
	end

	return closure;
end

-- A simple iterator over a table
-- returns the embedded table entries
-- individually.
local irecords = function(tbl)
	local i=0;

	local closure = function()
		i = i + 1;
		if i > #tbl then
			return nil;
		end

		return tbl[i];
	end

	return closure	
end

-- given a key/value record, and a filter table
-- pass the record if every field in the filtertable
-- matches a field in the record.
local recordfilter = function(record, filtertable)
	for key,value in pairs(filtertable) do
		if not record[key] then 
			print("record does not have field: ", key)
			return nil;
		end

		if tostring(record[key]) ~= tostring(value) then
			print(record[key], "~=", value);
			return nil;
		end
	end

	return record;
end

return {
  irecords = irecords,
  recordfilter = recordfilter,
  query = query,
}

The ‘query()’ function represents the bulk of the operation. The other two functions help in forming iterators and doing simple queries.

Here is one example of how it can be used:

-- test_query.lua
--

local JSON = require("dkjson");
local Query = require("Query");
local irecords = Query.irecords

local records = {
  {name = "William", address="1313 Mockingbird Lane", occupation = "eng"},
  {name = "Daughter", address="university", occupation="student"},
  {name = "Wife", address="home", occupation="changer"},
}

local test_query = function()
  local source = irecords(records);

  local res = {}

  for record in Query.query {
    source = source, 
	
    projection = function(self, record)
      return {name=record.name, address=record.address, };
    end,

    filter = function(self, record)
      if record.occupation == "eng" then
        return record;
      end
    end
  } do
    table.insert(res, record);
  end

  local jsonstr = JSON.encode(res, {indent=true});
  print(jsonstr);
end

test_query();

Which results in the following:

[{
    "name":"William",
    "address":"1313 Mockingbird Lane"
  }]

This uses the iterator, a specified filter, and projection. The query() function itself is an iterator, so it will iterate over the data source, and apply the filter and projection to each record, returning results. Nice and easy, very Lua like.

Now that I have a very rudimentary query processor, I can apply it to my web case. So, if I rewrite the web page that’s showing the services on my machine, and can deal with a little bit of query processing:

--[[
	Description: A very simple demonstration of one way a static web server
	can be built using TINN.

	In this case, the WebApp object is being used.  It is handed a routine to be
	run for every http request that comes in (HandleSingleRequest()).

	Either a file is fetched, or an error is returned.

	Usage:
	  tinn staticserver.lua 8080

	default port used is 8080
]]

local WebApp = require("WebApp")


local HttpRequest = require "HttpRequest"
local HttpResponse = require "HttpResponse"
local URL = require("url");
local StaticService = require("StaticService");
local SCManager = require("SCManager");
local JSON = require("dkjson");
local Query = require("Query");
local utils = require("utils");


local getRecords = function(query)
  local mgr, err = SCManager();
  local filter = nil;
  local queryparts;

  if query then
    queryparts = utils.parseparams(query);

    filter = function(self, record)
      return Query.recordfilter(record, queryparts);
    end
  end

  local res = {};

  for record in Query.query {
    source = mgr:services(), 
    filter = filter,
    } do
      table.insert(res, record);
  end
  return res;
end

local HandleSingleRequest = function(stream, pendingqueue)
	local request, err  = HttpRequest.Parse(stream);

	if not request then
		print("HandleSingleRequest, Dump stream: ", err)
		return 
	end

	local urlparts = URL.parse(request.Resource)
	local response = HttpResponse.Open(stream)

	if urlparts.path == "/system/services" then
		local res = getRecords(urlparts.query);
		local jsonstr = JSON.encode(res, {indent=true});

		--print("echo")
		response:writeHead("200")
		response:writeEnd(jsonstr);
	else
		response:writeHead("404");
		response:writeEnd();
	end

	-- recycle the stream in case a new request comes 
	-- in on it.
	return pendingqueue:Enqueue(stream)
end


--[[ Configure and start the service ]]
local port = tonumber(arg[1]) or 8080

Runtime = WebApp({port = port, backlog=100})
Runtime:Run(HandleSingleRequest);

Here I have introduced the ‘getRecords()’ function, which takes care of getting the raw records from the list of services, and running the query to filter for the ones that I might want to see. In this case, a filter is created if the user specifies something interesting in the url. Without a filter, the url is simply:


http://localhost:8080/system/services

In which case you’ll get the list of all services on the machine, regardless of their current running state.

If you wanted to filter for only the services that were currently running, you would specify a URL such as this:


http://localhost:8080/system/services?State=RUNNING

And if you want to look for a particular service, by name, you would do:


http://localhost:8080/system/services?ServiceName=ACPI

[{
    "ServiceType":"KERNEL_DRIVER",
    "ProcessId":0,
    "DisplayName":"Microsoft ACPI Driver",
    "ServiceName":"ACPI",
    "ServiceFlags":0,
    "State":"RUNNING"
  }]

Of course, you can also do simple combinations:


http://localhost:8080/system/services?State=RUNNING;ServiceType=KERNEL_DRIVER

This will return the list of all the kernel drivers that are currently running.

Of course, if you’re sitting on your local machine, you could bring up the TaskManager, export the list of services, import it into a real database/excel, and perform queries to your heart’s content…

This type of coding makes spelunking your system really easy. The fact that it’s available through a web interface opens up some possibilities in terms of display, interaction, and accessibility. Since the stream is just JSON, it could be fairly straight forward to present this information in a much more interesting form, perhaps by using d3 or webgl, or who knows what.

So, is this software engineering?

Having gone from a low level system call to a higher level web based interface with interactive query capabilities, I’d say it must be approaching the term. Perhaps the ‘engineering’ lies in the simplicity. Rather than this being a fairly large integrated system, it’s just a few lines of script code that ties together well.

I believe the “engineering”, and thus an “engineer” comes from being able to recognize the minimal amount of code necessary to get a job done. The “engineering” lies in the process of finding those minimal lines of code.


When Is Software Engineering – Hitting the Interwebs

So far, I’ve tamed an OS API that gives me the list of services running on my machine. I’ve been able to slap an iterator on it so that I could more easily deal with the information within my scripting language. Surely this is engineering?

My daughter, who knows Python, is not impressed. Next step, surely if I can make this information readily available through a web interface, it will be “Engineering”…

local WebApp = require("WebApp")

local HttpRequest = require "HttpRequest"
local HttpResponse = require "HttpResponse"
local URL = require("url");
local StaticService = require("StaticService");
local SCManager = require("SCManager");
local JSON = require("dkjson");

local HandleSingleRequest = function(stream, pendingqueue)
  local request, err  = HttpRequest.Parse(stream);

  if not request then
    print("HandleSingleRequest, Dump stream: ", err)
    return
  end

  local urlparts = URL.parse(request.Resource)

  if urlparts.path == "/system/services" then
    local mgr, err = SCManager();
    local res = {}

    for service in mgr:services() do
      if service.Status.State == "RUNNING" then
        table.insert(res, service);
      end
    end

    local jsonstr = JSON.encode(res, {indent=true});

    local response = HttpResponse.Open(stream)
    response:writeHead("200")
    response:writeEnd(jsonstr);
  else
    local filename = './wwwroot'..urlparts.path;
    local response = HttpResponse.Open(stream);
    StaticService.SendFile(filename, response)
  end

  -- recycle the stream in case a new request comes
  -- in on it.
  return pendingqueue:Enqueue(stream)
end

Runtime = WebApp({port = 8080, backlog=100})
Runtime:Run(HandleSingleRequest);

Surely this is engineering!! The business end of this code is right there with the familiar mgr:services() iterator. In this case, I take each of the records returned and stuff them into a table. Then, after all are returned, I turn that into a JSON string, and return it as the web result.

RunningServices

I only want to return the services that are in a “RUNNING” state, so I do that check before I actually stuff the record into the table. Well, there you have it. I’ve now gone from simply being able to make a simple system call, to being able to display the results of that call in a webpage accessible on my machine.  Is this “Software Engineering” yet?

Does it become engineering because I wrote the code that consumes a lower level framework?  Does it become engineering if I actually wrote the lower level framework?  Is it only engineering if I wrote the OS that supports that lower level framework?

As Doctor Evil would say; “Somebody throw me a frickin bone…”

I’ll try to impress my daughter with this code, then I’ll try it out on the cocktail circuit.  Perhaps someone will see this as software engineering…

But wait, there’s more!  That ‘query’ where I filtered for only the “RUNNING” services looked a bit enemic, and what about changing the state of those services?  Surely there’s room to do some engineering in there…

 


When Is Software Engineering – Of Iterators and Closures

Last time around, I flexed my “software engineering” muscles by tackling an obscure Windows API using a scripting language. This works out well for when I’m at a cocktail party. I can keep people enthralled with my skills an an engineer by throwing out words like “SC Handle”, and “Enum Process Info”. The less my audience knows, the more intelligent I appear to be, and they can believe that my “engineer” title is well deserved.

Well, I haven’t been getting the intended response out of the cocktail scene of late, so I decided to master a couple new words. “Iterator” is a nice word because it doesn’t mean much more than enumerate, or list, or count, but it’s not in common usage, other than by the geeky programming crowd. So, it’s a sure win for the cocktail circuit. The other word is much more powerful because it sounds like prison, or a roadblock, or something “closure”.

Building off of my last bit of code, where I can make a single call to get a list of services running on my machine, it would be nice to get an ‘iterator’ on that set of services so I can then do more interesting things.

Ultimately, I want to be able to write the following code:

local mgr, err = SCManager();
for service in mgr:services() do
  print(service.ServiceName, service.DisplayName);
end

Which might result in the following kind of output:

KeyIso        CNG Key Isolation
Netlogon      Netlogon
SamSs         Security Accounts Manager
VaultSvc      Credential Manager
...

Actually, if I just queried for all services on my Windows machine, I’d get a few hundred of them listed, but you should get the general idea.

The trick here is in the ‘services()’ function of the SCManager object. That is what is known as an iterator, and it’s what gets me phone numbers at the parties. The code looks like this:

SCManager.services = function(self, dwServiceType)
  local InfoLevel = ffi.C.SC_ENUM_PROCESS_INFO;
  local dwServiceType = dwServiceType or ffi.C.SERVICE_TYPE_ALL;
  local dwServiceState = dwServiceState or ffi.C.SERVICE_STATE_ALL;
  local lpServices = nil;
  local cbBufSize = 0;
  local pcbBytesNeeded = ffi.new("DWORD[1]");
  local lpServicesReturned = ffi.new("DWORD[1]");
  local lpResumeHandle = ffi.new("DWORD[1]");
  local pszGroupName = nil;

  local status = service_core.EnumServicesStatusExA(
    self.Handle,
    InfoLevel,
    dwServiceType,
    dwServiceState,
    lpServices,
    cbBufSize,
    pcbBytesNeeded,
    lpServicesReturned,
    lpResumeHandle,
    pszGroupName);

  if status == 0 then
    local err = error_handling.GetLastError();

    if err ~= ERROR_MORE_DATA then
      return false, err;
    end
  end

  -- we now know how much data needs to be allocated
  -- so allocate it and make the call again
  cbBufSize = pcbBytesNeeded[0];
  lpServices = ffi.new("uint8_t[?]", cbBufSize);

  local status = service_core.EnumServicesStatusExA(
    self.Handle,
    InfoLevel,
    dwServiceType,
    dwServiceState,
    lpServices,
    cbBufSize,
    pcbBytesNeeded,
    lpServicesReturned,
    lpResumeHandle,
    pszGroupName);

    if status == 0 then
      local err = error_handling.GetLastError();
      return false, err;
    end
	
    local nServices = lpServicesReturned[0];

    local idx = -1;

    local function closure()
      idx = idx + 1;
      if idx >= nServices then
        return nil;
      end

      local res = {};

      local services = ffi.cast("ENUM_SERVICE_STATUS_PROCESSA *", lpServices);

      if services[idx].lpServiceName ~= nil then
        res.ServiceName = ffi.string(services[idx].lpServiceName);
      else
        return nil;
      end

      if services[idx].lpDisplayName ~= nil then
        res.DisplayName = ffi.string(services[idx].lpDisplayName);
      end

      local procStatus = {
        State = serviceState[services[idx].ServiceStatusProcess.dwCurrentState] or "UNKNOWN",
        ServiceType = getServiceType(services[idx].ServiceStatusProcess.dwServiceType),
        ProcessId = services[idx].ServiceStatusProcess.dwProcessId,
        ServiceFlags = services[idx].ServiceStatusProcess.dwServiceFlags,
	}
      res.Status = procStatus;

      return res;
    end

    return closure;
end

It’s not as silly as it might at first seem. There are two calls to the EnumServicesStatusExA() function. This is in classic Windows API style. The first call tells you how big of a buffer you need to allocate if you want to get the full results back at once. The second call actually retrieves all the data into a single chunk of memory. At this point you actually have all the data (there’s an edge case where you might have more services than will fit into the maximum 64k buffer, but I’m ignoring that for the moment).

The ‘closure()’ function is what actually gets returned when you call ‘mgr:services()’. This is the only little bit of magic that requires some explaining. This is particular to the way Lua works with iterators. that is, a function can return another function, and if the context is a ‘for’ loop, the returned function will be called repeatedly until it returns the ‘nil’ value.

I so happened to name the function ‘closure’, but that’s not necessary, it could be named anything. The easiest way to think about the ‘closure’ is; it’s a function which always has access to those variables that were enclosed in the wrapper function around it. So, for example, when I could do this:

local nextRecord = mgr:services();
while true do
  local record = nextRecord();
  if record == nil then
    break;
  end
  print(record.ServiceName, record.DisplayName);
end

The ‘for record in mgr:services() do’ is just a short hand for the while loop form that I’ve written above. Each time the ‘nextRecord()’ call is made, the ‘closure’ function is called, and it still has access to the variables that were in place from the last time around. Thus, the ‘idx’ value can be incremented each time through, and it won’t be reset. That’s the magic of closures, and this is how ‘iterators’ are implemented.

If my coding foo were more substantial, I might be able to tie this in to monads, but then people might think I’m talking about biology, nematodes, advertising, or math, so I’ll leave it at that.

With this newfound vacabulary in hand, I’m sure my cocktail party prospects will be on the rise once again.

This is pretty satisfying. I have tamed the system call, and managed to coerce the results into a form that is much more native to the scripting environment. Now all I have to do is get it into a form that is suitable for publishing on the web. Along the way, I’m going to have to introduce some stream based query capability, as well as JSON, but that’s another story.


When Is Software Engineering – That’s just coding…

Over the past couple of weeks, I’ve been thinking the following; Am I a “Software Engineer”? “Am I just a hacker?”, “What is software ‘Engineering’ exactly?”.

When I was in high school, about ready to go to college, I told my math professor that I was studying “Electrical Engineering and Computer Science”. With a puzzled look, he said “what is computer science?”. This was no dullard of a man. He was actually a wealthy man who took up teaching as his way of paying back society for the public school education he had received. He was a Berkeley grad, who had worked on the Manhattan project. He was a true “Engineer”. His question was essentially along the lines of; “I know what engineers do, and we use machines to help, and sometimes you have to program those machines, but is there really a whole “science” behind it?”

Granted, this was back in 1982, so times were a bit different with respect to computing, but this stuck in my mind.

Then, recently, I was discussing the same question with a colleague at work.  The line of reasoning we were pursuing was, “How much of our time and engineering is truly “engineering”, and how much of it is simply “coding”.  Coding is that mindless thing we do when we’re banging at our keyboards, looking up documentation on obscure functions, just trying to use some library that someone has provided.  We didn’t really consider this “engineering” because it’s basically just a translation job.  I’ve spent a fair bit of time with the Windows headers of late, and I can tell you, 90% of that time I would consider to be “coding”, but not “engineering”.

Here is one example.  I want to get the list of services that are running on my local machine and project that out to the internet as a JSON structure, so I can easily display it in a web page.  There’s a core function in Windows to get things started:

 

BOOL
EnumServicesStatusExA(
  SC_HANDLE             hSCManager,
  SC_ENUM_TYPE          InfoLevel,
  DWORD                 dwServiceType,
  DWORD                 dwServiceState,
  LPBYTE                lpServices,
  DWORD                 cbBufSize,
  LPDWORD               pcbBytesNeeded,
  LPDWORD               lpServicesReturned,
  LPDWORD               lpResumeHandle,
  LPCSTR                pszGroupName
);

 

Well, that’s a mouthful. First of all you have to discover that this call actually exists, and figure out all the parameters. Luckily MSDN documentation exists, so at least you can read about it. You might even get lucky enough to find an example laying around on the internet to help show you how to use it.

Since I’m using a scripting language, my first task is to wrap this in an ffi.cdef[[]] so that I can call it easily. In order to do that, I have to put everything into ffi.cdef[[]], the structures, enums, function call prototypes, etc. After all is said and done, I can make a call that looks like this:

local InfoLevel = ffi.C.SC_ENUM_PROCESS_INFO;
local dwServiceType = dwServiceType or ffi.C.SERVICE_TYPE_ALL;
local dwServiceState = dwServiceState or ffi.C.SERVICE_STATE_ALL;
local lpServices = nil;
local cbBufSize = 0;
local pcbBytesNeeded = ffi.new("DWORD[1]");
local lpServicesReturned = ffi.new("DWORD[1]");
local lpResumeHandle = ffi.new("DWORD[1]");
local pszGroupName = nil;

local status = service_core.EnumServicesStatusExA(
  self.Handle,
  InfoLevel,
  dwServiceType,
  dwServiceState,
  lpServices,
  cbBufSize,
  pcbBytesNeeded,
  lpServicesReturned,
  lpResumeHandle,
  pszGroupName);

That’s only the beginning. I have to call it again after allocating some space to receive the results… Although there’s a lot of little bits and pieces here, is this ‘engineering’?

If 90% of our time is “coding”, I would say at least 75% of that time is spent on this type of activity. You’re trying to use some API in some library, and you’re doing a lot of scaffolding, and boilerplate work. What is the skill involved here? Well, an experienced coder will be more familiar with the various idioms involved, such as make this call to figure out how much space to allocate, then allocate, then make the call again. They’ll also be familiar with the fact that a return value of 0 == failure in this case, and that you need to call GetLastError() to figure out what could really be wrong, if anything. I might call myself an “engineering” for having gained the wisdom and years of experience necessary to perform this particular task efficiently, but I’m not sure I’d call it “software engineering”.

But, this is only the beginning of the journey on this particular task. Ultimately I need to get this information projected out to the internet. There will be iterators, queries, and other big words involved, and somewhere along the line, I might find the dividing line where software turns into engineering.


The Challenge of Writing Correct System Calls

If you are a veteran of using Windows APIs, you might be familiar with some patterns. One of them is the dual return value:

int somefunc();

Documentation: somefunc(), will return some value other than 0 upon success. On failure, it will return 0, and you can then call GetLastError() to find out which error actually occured…

In some cases, 0 means error. In some cases, 0 means success, and anything else is actually the error. In some cases they return BOOL, and some BOOLEAN (completely different!).

Another pattern is the “pass me a buffer, and a size…”

int somefunc(char *buff, int sizeofbuff)

Documentation: Pass in a buffer, and the size of the buffer. If the ‘sizebuff’ == 0, then the return value will indicate how many bytes need to be allocated in the buffer, so you can call the function again.

A slight variant is this one:

int somefunc(char *buff, int * sizeofbuff)

In this case, the return value of the function will indicate whether there was an error or not. If there was an error such as: ERROR_INSUFFICIENT_BUFFER, then the ‘sizeofbuff’ was stuffed with the actual size needed to fulfill the request.

This can be very confusing to say the least. What makes it more confusing, at least in the Windows world, is that there is no single way this is done. Windows APIs have existed since the beginning of time, so there is as much variety in the various APIs as there are programmers who have worked on them over the years.

How to bring sanity to this world? I’ll examine just one case where I use Lua to make a more sane picture. I want to get the current system time. In kernel32, there are a few date/time formatting functions, so I’ll use one of those. Here is the ffi to the one I want:

ffi.cdef[[
int
GetTimeFormatEx(
    LPCWSTR lpLocaleName,
    DWORD dwFlags,
    const SYSTEMTIME *lpTime,
    LPCWSTR lpFormat,
    LPWSTR lpTimeStr,
    int cchTime
);
]]

That’s one hefty function to get a time printed out in a nice way. There are pointers to unicode strings, pointers to structures that contain the system time, size of buffers, buffers in unicode…

In the end, I want to be able to do this: GetTimeFormat(), and have it print: “7:54 AM”

Alrighty then. Can’t be too hard…

local GetTimeFormat = function(lpFormat, dwFlags, lpTime, lpLocaleName)
  dwFlags = dwFlags or 0;
	
  --lpFormat = lpFormat or "hh':'mm':'ss tt";
  if lpFormat then
    lpFormat = k32.AnsiToUnicode16(lpFormat);
  end

  -- first call to figure out how big the string needs to be
  local buffsize = k32Lib.GetTimeFormatEx(
    lpLocaleName,
    dwFlags,
    lpTime,
    lpFormat,
    lpDataStr,
    0);

  -- buffsize should be the required size
  if buffsize < 1  then
    return false,  k32Lib.GetLastError();
  end

  local lpDataStr = ffi.new("WCHAR[?]", buffsize);
  local res = k32Lib.GetTimeFormatEx(
    lpLocaleName,
    dwFlags,
    lpTime,
    lpFormat,
    lpDataStr,
    buffsize);


  if res == 0 then
    return false, Lib.GetLastError();
  end

  -- We have a widechar, turn it into ASCII
  return k32.Unicode16ToAnsi(lpDataStr);
end

Not too bad, if a bit redundant. There are a couple of things of note, which are easy to miss if you’re not paying close attention.

First of all, I’m following the convention that any system function that succeeds should return the value, and if it fails, it should return false, and an error.

First thing to do is deal with default parameters. The dwFlags parameter is an integer, so if it has not been specified, a default value of ’0′ will be used. If you don’t do this, then a ‘nil’ will be passed to the system function, and that will surely not work.

The time value can be passed in. If it is, it will be used. If not, then the nil in this position will result in using current system time. Same goes for localeName, and lpFormat. If they are nil, then the system default values will be used, according to the function call documentation.

The next important thing is, turning the lpFormat string into a unicode string if it was specified. Lua, by default, deals in straight ANSII 7/8 bit strings, not unicode, so by default, I assume what’s been specified is a standard Lua ansii string, so I convert it to unicode.

And finally, the first function call to the system. In this first call, I want to get the size of the buffer needed, so I pass in ’0′ as the size of the buffer. The return value of the function will be the size of the buffer needed to fill in the string. Of course, if the return value is ’0′, then the ‘GetLastError()’ function must be called to figure out what was wrong. In this case, it could be that one of the parameters specified was wrong, or something else. But, bail out at any rate.

Now that I know how big the buffer needs to be (in unicode characters, not in bytes?), I allocate the appropriate buffer, and make the call again, this time passing in the specified buffer.

Last step, take the unicode string that was returned, and turn it back into an ansii string so the rest of Lua can be happy with it.

There are a couple more error conditions that could possibly be handled, like checking the types of the passed in parameters, or the size of the needed buffer might change between the two system calls, but this is a ‘good enough’ approach.

It’s 38 lines of boilerplate code to ensure the simplicity and relative correctness of a single system call. With literally hundreds of very interesting system calls in the Win32 system, you can imagine how challenging it can get to do these things right.

Of course, this is why libraries exist, because someone has actually gone through and done all the challenging work to get things right. I find that doing this work in Lua is pretty easy. The biggest challenge is reading and interpreting the documentation of the API. Sometimes it’s clear, sometimes it’s not. Once conquered though, it sure does make programming in Windows a lot easier. I suspect the same it true of any language/os binding.


Follow

Get every new post delivered to your Inbox.

Join 31 other followers