Thursday, December 31, 2015

Inspecting Windows Updates

If you're curious or paranoid, you might want to know what files a certain Windows update contains. Every Windows update has a KB article number, and that article - publicly accessible online (support.microsoft.com/kb/number) - contains a list of affected files. Sometimes this list is in the article itself as a table; sometimes it's downloadable in CSV form.

If you're extra paranoid, you can download the MSU (standalone update package) from the KB article. Use wusa to expand it, like so:

wusa C:\full\path\to\update.msu /extract:C:\path\to\destfolder

That folder will then contain an XML document listing the CAB packages to install as well as an install order text file if the update runs commands directly. You can extract the CAB files with WinRAR or the expand utility. Inside each of those is one XML document listing the affected files (usually inside WinSxS); many files have a manifest that does things like creating hardlinks or shortcuts.

This post was adapted from an answer I wrote on Super User.

Wednesday, December 30, 2015

Application-Authenticated Databases

I discovered today that Sybase SQL Anywhere has a feature that attempts to authenticate applications. It appears that "OEM Authenticated Edition" is designed to be shipped as a component of other products. If you're only reading from the database (as I was for a long time), you won't notice anything special. 

The "authenticated" part comes into play when clients attempt to write to the database. Writes fail with an "authentication violation" unless a connection variable has been set that identifies the client program. The command to authenticate looks like this:

set temporary option connection_authentication='Company=companyname;
Application=applicationname;
Signature=hexstring'

Once the right authentication string is sent, writes are enabled. Interestingly enough, writes are always allowed in the first 30 seconds of the connection, a kind of grace period. Since I didn't know about this initially, I was very confused as to why some writes would work and then the rest would fail.

Now, you might think that this is a security feature, but it's basically completely pointless in that role. No connection can be established to the database without a username and password, and in most cases read access is plenty. The authentication string is constant for each application and can't be easily changed, so once it's extracted from a client program (or from the network), other applications can just send the right string and be on their merry way. I believe this feature is actually designed to combat piracy, making it a little more difficult to use a database that came as part of a certain application as a generic database server.

Tuesday, December 29, 2015

Checking what program owns a handle

It may, from time to time, be useful to determine what program has a handle to a certain resource open. The most well-known type of handle is a file handle, but there can be handles to all manner of objects, like registry keys, desktops, and processes.

Process Explorer has a pane in its window specifically for handles, but you have to enable it by checking Show Lower Pane under View and making sure that Lower Pane View is set to Handles. Clicking on a process running under a security context you have access to produces a list of handles that process has open. You can search for a handle by using Find Handle or DLL under Find; it will search the Name column of the handles pane, so you can search for files, processes, or anything that has a unique name.

Aside: Process handles are interesting because a process won't vanish from Task Manager until [1] it exits/terminates and [2] all handles to it and its threads are closed. Therefore, it's possible for programs to keep the corpse of a dead process around by leaking/holding handles to the process object.

Monday, December 28, 2015

SMS web service that allows polling for replies

I have no affiliation with any of the companies mentioned here.

I have recently become interested in sending and receiving SMS messages from .NET applications. I looked at several, including the ever-popular Twilio. It looked good, but there was one problem: incoming messages are only accessible by registering a URL that Twilio will make a web request to upon receipt. That's a showstopper for me because I really don't want to fiddle around with web applications or try to get my application to talk to an ASP.NET server.

Several searches later, I found ClickSend, which does exactly what I want. They allow me to poll their website, which results in an XML document containing replies that I haven't seen yet. Perfect.

Sunday, December 27, 2015

Application Compatibility Toolkit: Fixing other people's mistakes

While doing research for a Super User answer, I reminded myself of the existence of the Application Compatibility Toolkit. The ACT is highly interesting in that it exists only because software developers wrote buggy code that worked by chance at one point but then broke in a later version of Windows. It's not intended to be used by normal users, but it doesn't hurt to have a little knowledge about the ACT.

Some Compatibility Fixes in the Compatibility Administrator
Perhaps the most interesting part of the ACT is the Compatibility Administrator, which is used to apply fixes to programs. If you look in the "Compatibility Fixes" entry in the left pane, you'll see a big list of fixes that Microsoft has developed to address common issues. Under Applications, you'll see a surprisingly massive list of buggy programs and the fixes Microsoft applied to them. I noticed a couple well-respected programs that I have personally used.

You can apply fixes (or compatibility modes, which are groups of fixes) to arbitrary applications by adding entries to a custom database. Once you're done, you can install it on the machine and/or save it for use on other computers.

Saturday, December 26, 2015

JPG Surprise: Rotation might not be real

Today I was working with a Micca M703, a digital picture frame that does slideshows from JPG files on flash drives. It gave me some problems with image rotation; some images displayed sideways on the Micca but correctly on my computer. Research indicated that the Micca doesn't do any auto-rotation to fit the screen, so I was quite confused.

It turns out that I when I rotated the images on my computer (using the convenient context menu items Windows provides for pictures), the image data wasn't transformed, but some bit was set somewhere that causes well-behaved programs to treat the image as if it had actually been rearranged. The Micca doesn't, apparently, respect that option.

So, I had to open each such picture and resave it with Paint.NET to actually rotate the image in its data.

Friday, December 25, 2015

Abiathar Christmas 2015

Merry Christmas!

During December 25, 2015 (my time), Abiathar's "empty workspace" background image will be this:

The Abiathar background, but in red and green

Thursday, December 24, 2015

Solving the runas.exe mystery

Last time, I presented a strange problem I was having with runas.exe. I believe I have found the answer:

"Run as different user" sets the startup directory of the new process to the directory that contains the executable. runas.exe, however, always sets the startup directory to System32.

The unexpected current directory confused the program in question, which explains why only "Run as different user" worked. In fact, runas.exe requires a fully-qualified path if the target program is not on the system path, even if launched from the directory containing the EXE.

Wednesday, December 23, 2015

Runas.exe not working? "Run as different user" might

I am currently experiencing a strange phenomenon. I'm trying to use runas.exe to run a certain program as a domain user while logged in as a local user on a domain-joined machine. The application launches, but it misbehaves in an unusual fashion. (It wouldn't launch at all if ran as a local user.) However - here's the strange part - it works just fine if I Shift+right-click it and use "Run as different user."

Currently, I'm researching/investigating the difference between runas.exe and that option; the best leads I have at the moment are the /env and /profile (or /noprofile) switches for runas.

I guess what I've learned so far is that "Run as different user" might work if runas.exe doesn't.

Updated 12/24/2015: I solved the mystery.

Tuesday, December 22, 2015

Forcing Domain Workstations to Show Local Users on the Sign-in Screen

Your domain users may find it necessary to log back into a local account. This is simple enough with the .\ trick (prefixing a username with that in the Windows logon UI makes Windows look for a local account instead of one from the domain), but your users might be confused or just inconvenienced by typing weird characters in the username field, or they might not remember their username (especially if it was created as a Microsoft account).

There is a Group Policy setting that can help with this. It's called "Enumerate local users on domain-joined computers" in Logon under System in the Computer Configuration's Administrative Templates. Enable that, and the logon UI will display all local user accounts.

Note that this only works for Windows 8 and above.

Monday, December 21, 2015

Testing for membership in a certain domain in Windows batch script

If you want to test for the current user's membership in a certain domain in a Windows batch script, the whoami utility has you covered. Pipe it into findstr /i "domainname\\" to test whether the output includes your domain's name. The double backslash is there to represent a single backslash (escaping), the one that separates the domain component from the username component.

findstr sets the errorlevel to 1 if the string is not found or to 0 if it is. So, you can use an if statement to act on the domain membership or lack thereof:

whoami | findstr /i "kingdom\\"
if errorlevel 1 (
 REM do some non-domain business
) else (
 REM do some domain business
)

Sunday, December 20, 2015

Icon Impersonation

Some software companies give their programs an icon in the style of more popular software suites. I have on my desktop at the moment a program that tries to look like part of the Office 2013 suite.

The problem? Such false icon associations might initially make the user feel good ("oh, I know how to use Word, I can do this too!"), but the user will soon be confused, disappointed, and upset when the program fails to adhere to all the UI patterns of the suite it's imitating. Also, experienced users will just think it's silly.

The moral? Develop your own look, and do your best to have an intuitive interface that won't leave the user disillusioned when it is discovered that you're not really part of what you're impersonating.

Thursday, December 17, 2015

Windows 8 Surprise: Domain Membership Disables PIN Login

If you join a Windows 8 machine to a domain, you'll notice that you lose the ability to sign in with a four-digit PIN. If you want to re-enable PIN login, you'll need to enable a Group Policy setting:

Computer Configuration\Administrative Templates\System\Logon\Turn on PIN sign-in

There is a good reason, however, for not allowing PINs. Even if you log in with a PIN, the domain controller needs your full password to let you touch domain services. So, the machine on which you configured the PIN has to store your password and give it to the domain controller when you log in with a PIN.

Since the local system needs access to the password (because you don't enter it), it has to keep it unhashed, using reversible encryption. An attacker with physical access to the machine could find the encrypted password and decrypt it with the machine's key, which also has to be stored somewhere. There are only ten thousand possible PINs, so offline cracking of the password would not be hard. It is generally considered A Bad Thing for access to a single workstation granting access to a domain secret.

You might not want to allow PIN sign-in for your domain.

Wednesday, December 16, 2015

Netstat Surprise: Process Headers are Footers

Sometimes I need to examine the list of network connections/listeners and what process created them. For that, I generally use netstat -bna because the netstat utility is guaranteed to be on every modern Windows machine. However, the output format recently caused me a good deal of confusion and some lost time.

See, the utility prints the name of the owning process on the line after all the connections it owns. I would expect those headers to be, well, headers, but no no, they are footers. I suppose I should have seen this - it's reasonably intuitable if you check the top or bottom of the list - but in my defense, I was dealing with a massive amount of connections, so I had to Ctrl+C the program so as to not scroll the interesting ones out of the console buffer.

It would make more sense, in my opinion, for these markers to actually be headers.

Tuesday, December 15, 2015

Using Windows EFS with the SYSTEM Account

Recently I found myself wanting to encrypt files that would be used by a service running as SYSTEM. I didn't want to use BitLocker on the drive, so the Encrypting File System (EFS) seemed like the easiest option.

The first order of business was to get an EFS certificate for the machine account. There's probably a fancy way to do this if you have a domain, but I just fired up a SYSTEM command prompt with psexec /s /i cmd.exe. In that prompt, I ran the cipher /e /s:folder with "folder" replaced with the name of the directory containing all the files that needed encryption. That generated an EFS certificate and key for the computer account and then encrypted the directory and its files.

If you're curious, you can examine the machine's certificate store by running certlm.msc. EFS certificates (for all enrolled users) appear under Trusted People. A certificate's thumbprint can be retrieved by opening its properties and looking at the Details tab.

EFS certificates in certlm.msc

Then, I needed to grant some users access to the encrypted data. That's rather simple if you have domain; you can use cipher /adduser /user:domain\username /s:folder. If you don't, you'll need to retrieve the certificate thumbprint for the user. In that case, the command is cipher /adduser /certhash:thumbprint /s:folder. If you copy the thumbprint from the certificate management MMC window, you'll need to remove the spaces from between the hexadecimalized bytes.

Now system services can access encrypted files and selected standard users can touch them too.

Monday, December 14, 2015

URLs Are More Than Strings

Every so often, I see a program that assumes one page/site is represented by exactly one URL. That's not right because of things like extra slashes and percent-sign escape characters. Now, it's perhaps unreasonable to expect every application to condense URLs into some standard form (and avoid breaking them in the process), but I just noticed this in Blogger's statistics page:


What's up with those two Google entries? One has a trailing slash, one doesn't. If I was direly needing to analyze my traffic sources, this would make it a bit more complicated. URLs are more than strings, they are the string representation of pages.

Sunday, December 13, 2015

IPsec Surprise: Endpoint IP Required

I recently set up an IPsec environment (specifically, server isolation) on Windows Server 2012 R2, and had a hard time getting clients to talk to the server. The last problem I had to solve involved the endpoint configuration in the Connection Security Rules. Initially, I had set both endpoints to be any address, thinking that the port and protocol rules would make the rule apply to what I wanted. Making Endpoint 1 be the machine running the isolated service made the connections work.

This may or may not be a bug/surprise in Windows Server, but it looks like it fixed my problem. At least it's another thing to try if you're having IPsec issues.

Saturday, December 12, 2015

Transferring Profiles to New Accounts with Windows Easy Transfer

Or, "Windows 10 Easy Transfer: Missing in Action."

Today I found myself needing to move a Windows profile to a new account on the same machine. That is, I wanted a new domain user account to have the same stuff (documents, settings, etc.) as an existing non-domain user. Some Internet searching turned up Windows Easy Transfer, a utility that comes with Windows 7 and is usually used for moving files to new computers.

First, you'll need to log into the machine with the new account so it has a profile. Then, switch to any account that is a local administrator, and open Windows Easy Transfer.

On startup, Windows Easy Transfer lets you choose your transfer medium - Easy Transfer cable, network, or external drive. The external drive option actually lets you store the MIG (migration) file anywhere, including the current drive. To start out, tell Windows Easy Transfer that the machine is the "old" computer. Select just the profile that needs to be transferred. There's not much purpose in securing the MIG with a password, so you can skip that. The program will write that profile's documents and settings to the MIG file.

Close Windows Easy Transfer, then open it again. This time, tell it you're on the "new" computer. Open the MIG. The trick in cross-account profile transferring is to press the "Advanced settings" link, which lets you change the account mapping. Map the old account to the new account, and start the process. Depending on the size of all the things, it could go quickly or take a while. You can erase the MIG once it's done.

Now the wrinkle: In Windows 8.1, Easy Transfer was gutted. There's no longer any option to create a MIG file or otherwise be the "old" computer, so the above procedure is impossible. In Windows 10, Easy Transfer is completely absent. I believe the recommended alternative for system administrators is the User State Migration Tool, which comes with the Windows AIK, and is supremely difficult to use compared to Easy Transfer. Clearly they should rename it to Hard Transfer.

Friday, December 11, 2015

If there are secrets in your client, you're toast

Programs that communicate over a network to a central server tend to have some type of authentication and access control. That's great, but I've seen several implementations that have no real security, only the appearance of it. Such software usually fits into one of two categories:

  1. Client-side security. Programs with this problem rely entirely on the client to check access controls. The absence of checks on the server side means that anybody can bypass the authentication or authorization by throwing together their own client that talks to the server directly, issuing whatever commands the user feels like. Moving the security into the server will probably be a large undertaking for the developers, but it's absolutely essential.
  2. Client-held secrets. By "client-held" I mean "burned into the client program." This is a distinct issue from problem #1, though programs with the first often have the second too. Some developers think that obfuscation (to make, say, a string not visibly appear in the EXE) will sufficiently protect any sensitive configuration/information. It won't. A sufficiently determined user can get access to any data that flows through a program running under their own local security context. (Try creating a dump file of a running program and then inspecting that.) This issue also covers "encryption" algorithms that rely on the secrecy of the algorithm to be secure. To remedy this, I suggest using asymmetric-key cryptography and well-known algorithms.

Thursday, December 10, 2015

Chrome Surprise: "Prevent this page from creating additional dialogs" Not Taking Effect

Some annoying web pages, upon being exited, produce dialog boxes begging you to not leave. Somehow, the pages manage to produce yet another, similar dialog after you choose to indeed leave. Chrome, fortunately, has a checkbox called "Prevent this page from creating additional dialogs" designed to combat such behavior.

Interestingly, though, checking that box and then pressing the X in the upper-right of the JavaScript dialog seems to cancel the entire closing action. The checkbox, if the page produces another dialog, is still unchecked. That's understandable, given that the user chose to remove the entire dialog and not save what was in it. I do wish, however, that the checkbox's state would be saved, as I believe it would lessen the confusion of panicked novice users.

Wednesday, December 9, 2015

Creating Video Series Thumbnails with Paint.NET

For my YouTube videos that are part of a series, I like to overlay an image specific to the episode with a series image. This lets people get a glimpse of what an episode is about while also making the video's membership in the series immediately visible. To create such images, I use Paint.NET. First, for each series, I prepare the overlay:
  1. Put together an overlay. It can even be translucent in some parts!
  2. Create a new Paint.NET image with the same size as your episode images.
  3. Make the first layer completely transparent.
  4. Add a new layer above the first layer and paste the overlay into it.
  5. Save it as a PDN.
When this image project is opened, Paint.NET makes the bottom (empty) layer the default. That's really convenient, because it lets me do this:
  1. Prepare an episode image.
  2. Open the base PDN file.
  3. Paste the episode image. It goes into the bottom plane.
  4. Do a Save As to produce a flattened, final thumbnail.
This process is nothing revolutionary; it's just that Paint.NET has all this polish that makes it great for these things.

Tuesday, December 8, 2015

ASCII 255: "I Can't Believe It's not a Space!"

Character 255 has two uses of which I take advantage frequently. (As frequently as one can take advantage of nonstandard characters.) It looks just like a space, but has these special properties:

  1. It doesn't get eaten by applications that try to remove extra space. If you're trying to hand-align some text, you might need character 255 to stop your fancy diagram from getting crushed against the left margin.
  2. It prevents words around it from being broken across lines. If you have, say, a name that contains initials ("C. K. Williams", for instance), you might want a 255 between the initials and maybe also between the last initial and the written-out component.
You can insert a 255 by pressing 2, then 5, then 5 again on your numeric keypad while holding the right-hand Alt key. NumLock probably has to be on. The HTML entity is   - "non-breaking space."

Sunday, December 6, 2015

DirectoryServices.AccountManagement Surprise: FindByIdentity Can Throw

The convenient, high-level feel of .NET's System.DirectoryServices.AccountManagement classes would make one think that they shield you from the internals of LDAP. That does not appear to be the case. Passing a string with unusual characters as a username to the FindByIdentity function on a principal class results in a DirectoryServices exception. (I used non-printing ASCII, accidentally.) The message contains an LDAP query, indicating that special characters are not always escaped correctly.

Where's My BIOS Setup Key?

I have noticed a disturbing trend in modern BIOSes. It has been a good long while since I've seen a machine that says "Press [key] to enter Setup." The lack of message would be fine if BIOS manufacturers decided on a setup key, but they haven't. I've seen Delete, Enter, F12, F10, F1, and F2. The result of these circumstances is that I end up pressing all the keys hopefully quick enough to make the computer give me a menu before the OS starts.

I'm sure the manufacturers removed the message because it was scary, or ugly, or something, but could we please either have a subtle message or a standard key?

Friday, December 4, 2015

Finding Strings in a Running Program's Memory

There is a simple, effective tool from Sysinternals called Strings that examines a binary file for textual strings. If you want to look for strings in the memory of a process, you'll need to get a dump of its memory. That can be accomplished very easily by selecting the process in Task Manager, right-clicking its entry, and choosing "Create dump file." Run the resulting file through strings.exe, optionally with a custom minimum string length specified with -n.

Since most processes (even the simple Notepad) will have lots of strings in their memory, you might want to pipe the output into findstr. Example command:

strings notepad.DMP | findstr Important

That will print every string in the dump file (i.e. process's memory at the time of the dump) that contains the word "Important".

(I am aware of the strings view in the VMMap utility, but it appears to not always work.)

Thursday, December 3, 2015

Windows 10 Server Wi-Fi: Missing in Action

I have a laptop on which I installed the Windows Server Technical Preview 3, the third preview of the Windows 10 server OS. Today I found myself without a spare Ethernet cable for it, but I figured Wi-Fi would do the job. Apparently it won't - Windows always says "no connections available", even though I've confirmed that the Wi-Fi adapter/driver is present and enabled. Even pressing "Connect to" in Network Connections with it selected does nothing. I guess WSTP3 doesn't support Wi-Fi? That would be a shame.

Wednesday, December 2, 2015

Blogger UI Glitch: Overlapping Highlight

I just noticed while examining my blogs' statistics that mousing over an element in the left menu produces a highlight box that appears over the content in the main pane:


Notice how the gray highlight around "Stats" spills over into the URL section. It's not important in the least, but it's interesting to note.

Tuesday, December 1, 2015

What's in Your Downloads?

Many Internet surfers download numerous files over the years. Those files usually go into a Downloads folder, are run/installed/examined, and then ignored. I just noticed that my Downloads folder contains over 9000 files, if you count extracted subfolders, totaling more than 22 GB. (That's only a little more than 1% of my hard drive's capacity, but still. 22 GB.)

The Properties window of my Downloads folder
The vast majority - perhaps even all - of those files are no longer needed. If they are needed, I should organize and move them to a more suitable location so I can find them later. If they were just a one-off thing, well, the space could go to something useful.

What's in your Downloads?

Monday, November 30, 2015

Windows Server Licensing: CALs

I have determined that the licensing scheme for Microsoft's server products is really surprising. By "surprising", I mean that it violates my expectations for how ownership works.

Basically, in addition to the OS license itself, you're supposed to have a Client Access License for every user or device that will be served by that product. These don't appear to be actually enforced by software, but they're needed so you can comply with the Microsoft licensing agreement and not get fined if you get audited.

If you use user CALs, every physical person that is served by the machine needs a CAL. (CALs are assigned to a server.) If you use device CALs, every device needs a CAL. "Device" includes both workstations and network appliances, and DHCP clients!

In summary, it seems that Windows Server can be installed without CALs, but legally, CALs are required.

Sunday, November 29, 2015

Unfocusable Windows

I sometimes use an application that owns a window that likes to vanish. The window is never visible in the task bar, so if I accidentally put several other windows over it (or hit Windows+M), it's difficult to find. Normally, Alt+Tab would fix all my problems, but in this case, the window just disappears when I try to Alt+Tab to it. I know it's still there - it's in the Task Manager list, and it stays while I hold Alt+Tab while over the window. It just won't allow itself to be focused.

Not sure what's up with that. I wonder if there's a solution.

Saturday, November 28, 2015

How to Install ODBC Drivers Manually

Today I found myself wanting to install some ODBC drivers without installing the whole program responsible for them. Doing it manually isn't too hard:

  1. Decide on or find a name for the interface. This is what goes in ODBC connection strings as the Driver parameter. You should probably use the standard driver name for your database product, maybe look at a computer that already has it installed.
  2. Open the Registry Editor and navigate to HKLM\SOFTWARE\ODBC\ODBCINST.INI.
  3. Under ODBC Drivers, add a new string value named the same as the driver. Set its data to Installed.
  4. Create a new key/folder under ODBCINST.INI with the same name as the driver.
  5. Create entries named Driver and Setup, both containing the full path to the driver DLL without quotes around it. Some database products may require additional configuration here.
  6. If you're on a 64-bit machine and there is a 32-bit version of the driver, repeat steps 3 through 5 for the 32-bit file, in HKLM\SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI.
No reboot required.

Friday, November 27, 2015

The Invisible Windows Defender Icon

After some Windows update a few months ago, the icon for Windows Defender turned completely white. It's not following the style of the network connectivity and volume control icons; it's just a white outline of what it used to be. I only know it's there because there's a conspicuous blank space in my notification overfill area:

What's up with that center area?
Holding my mouse down over it reveals its shape:

It was really hard to press Alt+PtScn while holding the mouse button
It would be nice if the icon was either visible or not there.

(For the curious: the icon in the upper-right is Folding@home, the one at the bottom is f.lux, and the one in the bottom-right is the Adobe Application Updater.)

Wednesday, November 25, 2015

Chrome Surprise: Zoom Settings are Remembered by Domain

I just now investigated an interesting phenomenon. Opening an image in a new tab in Google Chrome from my web e-mail interface and then zooming it resulted in the main mail tab also being zoomed when I went back to it. I also have noticed the zoom level changing while the web app loads (i.e. when I log in). That's kind of strange, but there is a reasonable explanation.

It appears that Google Chrome stores zoom levels based on the page's domain (the part between the protocol and the slash after the TLD), not the URL or tab. The image I opened was hosted on the same site as the web app, so zooming it changed my zoom level for the entire domain. The log-in screen redirects me through a couple pages on different subdomains, so different stored zoom levels came into play.

Tuesday, November 24, 2015

When Faint Squares Appear Around Desktop Icons

For the past few weeks, I have been seeing faint gray squares around some (not all) of my desktop icons.
Prism, WavePad, and OBS have the square, but the others don't
I researched the issue, and apparently the squares surround icons that didn't get resized. Resized? The issue appears when the icon size on the desktop is changed to something non-even by holding the Control key and scrolling the mouse wheel. I'm not sure what causes some icons to resize and some not.

The standard size can be restored by choosing an icon size under "View" in the desktop's context menu.

Sunday, November 22, 2015

ActiveNav Update Plan

Despite having written several articles about it, I have still not released ActiveNav. That's because I don't feel that it's ready for serious use. I have been collecting things that need to be done before it is releasable, and here are some of the more easily definable ones that I frequently find myself wanting:

  • Change bind to automatically find a destination server and domain name if none are specified.
  • Allow binding to the Configuration and other non-primary Active Directory partitions.
  • Add useful in-program help for commands like find that have many subcommands.
  • Add support for invoking Active Directory actions (like SetPassword) on objects.
  • Make ce forgiving of case-sensitivity errors.
I would have some "writing" updates on the list, but expanding the scope from just reading will be a very big job.

Thursday, November 19, 2015

Idea: "Hide" for Network Adapters

I have a couple virtualization solutions installed on my machine, so I have lots of virtual network adapters. In fact, I have no fewer than six Ethernet adapters, five of which are virtual and almost never used. The last seems to be my actual network adapter, plus stuff from Hyper-V; it's a virtual switch.

Anyway, when I want to look at my network usage in Task Manager, it's kind of difficult:


Wouldn't it be great if I could hide or at least rename some of these? I understand that the possibility of hidden network adapters throws the door wide open for suspicious activity, but maybe a "Show all" link in the Task Manager UI could help with that; programs using the normal enumeration API would still see the full list.

Wednesday, November 18, 2015

Misplaced Underlining in Image Links

I have noticed this small issue on two major sites now, one of which is Blogger. These sites are styled in such a way that links do not have underlines unless the mouse is over them. When I mouse over a link element that contains an image, an underline appears only under text, which in this case is a single space, so the result is a bizarre extra line segment. In this picture, my mouse is over the blue creature:
There are two simple solutions I can think of for this problem:

  1. Remove the space character and create padding some other way
  2. Use CSS to remove hover underlining for the link containing the picture

Tuesday, November 17, 2015

Checking for the Presence of an Active Directory Attribute with ActiveNav

There are many Active Directory attributes that aren't present for every record of a certain type. For instance, I recently wanted to see how many users in an OU had a home directory mapped, so I needed to check each entry for the presence of a homeDirectory attribute. That can be accomplished with ActiveNav in two ways, both of which use the find command:

  1. find filter attribute like * finds all entries that have the attribute containing any value.
  2. find sort attribute str sorts the list of entries by the attribute, which has the side effect of removing entries that don't have the attribute from the result set.
I tested these on string values, but I'm not sure whether they'll work for System.__ComObject values.

Monday, November 16, 2015

Active Directory Surprise: logonCount Attribute Isn't Replicated

Today while curiously browsing around an Active Directory environment with ActiveNav, I noticed that all the logonCount values were way lower than they should have been. That user attribute should keep a tally of how many times the person has logged onto any workstation. I soon realized that I had connected ActiveNav to a relatively new domain controller. Since that controller hadn't been online as long as the other, not nearly as many logons had been checked against it. The logonCount attribute is not replicated between domain controllers, so each controller keeps its own copy; therefore, there is no way to get an authoritative answer for the number of a user's logons from just one query.

Saturday, November 14, 2015

Troubleshooting Xamarin Deployment to Android Devices

I tend to experience bizarre issues with widely used programs, and my interactions with Xamarin (a toolkit for building mobile apps with .NET and Visual Studio) did not buck the trend.

First, I received an error indicating that no project was set to deploy. That was solved by opening the solution's properties and checking the "Deploy" box under the appropriate project in the Configuration section.

Then, there were errors in the deployment stage, something about being unable to deploy the previous version. Apparently, I didn't have any virtual devices set up as deployment targets. The emulator manager (AVD) wouldn't even open; a console window appeared, scrolled through a whole lot of messages, and vanished. To correct that, I had to launch Xamarin Studio (not Visual Studio) or Android Studio to get the targets set up. I could then launch the AVD to add an emulator.

Finally, I had problems getting the remote debugger for my real phone to work. It turns out that since I installed the Android ADB drivers on my computer while the phone was plugged in, I needed to purge the authorization list in the phone's developer tools and reconnect it to get the "do you want to trust this machine" dialog.

Friday, November 13, 2015

When VirtualBox Doesn't Show 64-bit OS Options

VirtualBox (and VMware Player, for that matter) have a dropdown for the OS of the virtual machine. Sometimes, 64-bit options don't appear. That usually happens for one of two major reasons:

  1. Hardware virtualization is not enabled, and it's required for 64-bit virtual machines. Check your BIOS and enable Intel VT-x or the AMD equivalent.
  2. Another application is holding exclusive control of hardware virtualization. That other program is usually another hypervisor, but I've heard that some antivirus solutions do this. The most likely culprit for Windows hosts is Hyper-V, which runs all the time as a system service if you have it installed. Uninstall it or stop the service to use a different hypervisor.

Thursday, November 12, 2015

Position of Newly Installed Windows 8 Program Tiles

It would be really nice if the Start screen tiles for newly installed programs in Windows 8 were arranged in an intuitive fashion. Currently, there is no pattern that I can discern:

My Start screen (or part of it)
I don't remember ever explicitly pinning anything to my Start screen, though I may have unpinned some bothersome default apps (creating the blank space under Access). All the programs I've installed have been jumbled into various groups, apparently without regard for publisher, type, name, or even color. That just clutters up the first picture of my computing experienceTM.

Actually, it would be even better if every new program shortcut was left down in the "all apps" section so I alone would be responsible for the arrangement of my Start screen. (It belongs to me, after all.)

Even so, I should organize my Start screen.

Wednesday, November 11, 2015

My Linux Saga: A Drama in Four Acts

A couple days ago, I figured I would give Linux a go. Several people I know love the whole open-source philosophy and therefore Linux, but I was primarily interested in producing a set of steps with which Abiathar can be installed on a Linux machine. Prior to this experience, I had used Linux about five times, and never in a serious capacity.

I tell the story in present tense for dramatic effect.

Act I: Hardware


I happen to have an Ubuntu GNOME 14.04 installation ISO laying around my drive for some reason, so I'll go with that. I'm not super interested in blowing away any real machines for this experiment, so virtualization it is. I've had success with VirtualBox, so we'll start with that. I create a new VM, give it 2GB of RAM, a single CPU, a 30GB SATA hard drive, and a DVD drive for the ISO. 

I turn it on and a purple-ish screen appears with a little keyboard and a person-looking logo thing at the bottom. Keyboard equals happy man? I think I'll start with the GUI, thanks, so I press nothing. A text screen appears with some dots that animate between blue and white. I wait a while and am rewarded for my patience with an error message about intel_rapl.

Welcome to Linux?

I wait a couple seconds, try pressing some buttons, try Ctrl+Alt+Delete, and nothing happens. I try a reset and get the same thing.

Fast-forward through thirty minutes of fiddling with hardware settings in VirtualBox, most of which either produced the same error or something else that sounds bad. I also try upgrading VirtualBox to the newest version, which gives me more buttons to press, but none of them help. So I abandon VirtualBox and try Microsoft Hyper-V, which I have used successfully exactly once. Does Hyper-V even work with non-Windows OSes? Beats me.

This should be good.

I create a new VM with similar specs. There doesn't appear to be a way to insert a SATA controller in Generation 1 Hyper-V machines, so IDE it is. I start the VM, connect to it with the Virtual Machine Connection, and receive the same error. Huh. Some Googling told me that the message is actually non-obstructive (read: spurious) despite how scary it looks. Perhaps VirtualBox would have worked after all. Oh well, we're with Hyper-V now.

After waiting several minutes, I receive a textured background and a setup utility-ish UI thing that tells me I should have an Internet connection for best results. Whoops, I forgot to install a network adapter. So I do that, and reboot the VM.

Act II: Setup


Both recommendation lights are green in the setup-starting dialog. Let's do this!

Setup asks me for a username, a password, and a computer name. Interestingly, after I fill in my username, it appends "-Virtual-Machine" to it for the computer name. I change the name to something more creative, like linuxvm. It thinks my password is weak, but I don't care, and it seems to be OK with that.

There is then a checkbox that allows the installation of proprietary components (some media player or codec or something). It is cleared by default. Heaven forfend there be non-open-source software on my machine! I check the box. Viva closed-source.

I start the installation. A progress bar dialog appears, spewing a bunch of piped text into the details box that I expanded for curiosity's sake. Hard drive activity is solid for quite a few minutes, and eventually I am presented with a logon screen. I type my password, press Enter, and receive what I believe to be a desktop. It is blank save for a black menu-bar thing at the top (which contains a single full word, "Activities") and a neat background in the main area.

Act III: Upgrades


At this point I am still feeling good about achieving my goal of running .NET software on Linux. The only thing I know is that sudo apt-get installs stuff, but I'm sure Google will help me figure out what stuff I need to install and what other line noise I need to put on a command line. Before I do that, though, I download the .NET software I would like to run and try double-clicking it for laughs. As expected, it doesn't work - Archive Manager attempts to open it, but fails, which makes sense considering that EXEs aren't archives.

Sometime during that experiment a Software Updater message made an appearance, so I figure I might as well make sure I'm running the most up-to-date version of everything before I begin in earnest. I press the Update button, and it prompts me for my password. I provide it, but I have no idea how to verify whether the prompt is legit. Good thing I'm not running any unvetted software yet.

Another progress bar appears, so I wait a while, then get some water, and when I come back the desktop has locked itself. Security is nice. I am pleased. I enter my password and press Enter to unlock. The UI clears the password box and does nothing else. I am not pleased. I try several more times, and receive nothing but a cleared text field. Deliberately entering the password wrong does produce a suitable message. There's a little link to log in as a different user - there are no other users, unless you count root - which I press. I get a list of users, which contains only me. I click me, and enter my password. It unlocks. Huh.

When the updater is done, Ubuntu tells me I should reboot. (See, even Linux needs to restart after important operations!) I do so using the little power icon in the upper-right of the desktop.

When the system comes back up, I get a kernel panic.

I stress that I have done essentially nothing to my system other than updating, much less anything questionable/unsupported. I haven't even opened Terminal yet! All I did was do what the GUI wanted me to.

I Google up some instructions to fix this. There is a boot menu that appears before GNOME (the desktop, I suppose) that contains an entry with "advanced options." The resulting advanced menu lets me boot from the old version. Neat! Everything is good.

While I was waiting for the Software Updater, I discovered on the Internet that there is a new Ubuntu version, Ubuntu 15. I figure now is a good a time as ever to upgrade to that, hopefully skipping all incremental "updates." Following some instructions, I change a line in a config file using an elevated (sudo'd) instance of gedit and then run a command to do the update. A bunch of stuff downloads and lots of text comes flying down the terminal.

In the middle of all that, a message box appears informing me that do-release-upgrade has encountered a problem and needs to close. I choose to send the error report, and it sends, but the text spew continues, as does hard drive activity. I let it run to completion, at which point it tells me that some errors occurred during the upgrade, but it seems that the errors only have to do with fontconfig, which can't be too critical, right?

I use the GUI to restart, but the system hangs in text mode at "Waiting for processes to terminate." I wait a good long while, but it stays there, with 0% CPU utilization (as reported by Hyper-V) and no visible disk usage. I cut the virtual power.

When the system comes back up, I get another kernel panic. I try the old version. Kernel panic. I try the recovery mode. Kernel panic. I give up and erase the virtual hard drive.

Act IV: Fresh start


Maybe things will work better if I'm on version 15 from the start. I download an ISO from the Ubuntu web site and put it in Hyper-V in a machine with the same specs. The purple screen and intel_rapl message appear again, followed by a black screen with a flashing text-mode cursor. Not good.

I reset. Wanting to be a happy man, I use my keyboard when indicated and fiddle around with some advanced settings in accordance with some other instructions I found somewhere. The black screen continues no matter what settings I choose or how long I wait. I am not a happy man, and my keyboard does nothing helpful.

I try the same in VirtualBox and experience the same failure.

Epilogue


I give up.

I tried, I really did. I wanted to like Linux, but I can't like something that I just can't make work. Maybe I picked a bad distro. Maybe there's something up with these hypervisors. Who knows.

Windows it is. 

Tuesday, November 10, 2015

Tips for Running Ubuntu Linux Under Hyper-V

Just today I got an Ubuntu installation running under Microsoft Hyper-V, and along the way I discovered some tips that may be helpful to others:

  • The VM, for easiest setup, should be Generation 1. (This option only appears on the Windows 8 or newer edition of Hyper-V. Don't worry about it if you don't see anything about generations.)
  • The hard drive image should be presented to the VM as a SATA or IDE drive. Bizarre error messages will result if you try to present it as SCSI.
  • There will be error-looking messages about intel_rapl, both in setup and during normal boot. They appear to not matter. Just wait while the message is on the screen during setup; the process will continue normally.
  • If there's a kernel panic, the Caps Lock and Scroll Lock lights will blink rapidly and will not return to their original states even after you click out of the Hyper-V Virtual Machine Connection window.
  • There are Integration Services for several Linux distributions, including Ubuntu, which allow dynamic resizing of the view window, among other things.

Monday, November 9, 2015

VirtualBox Strangeness: Touchpad Click Doesn't Always Count

I have yet to upgrade to VirtualBox 5, so this issue may actually be resolved.

I noticed while working with VirtualBox that the manager program's UI doesn't always respond correctly to clicks that I make by pressing down with my stylus onto the touchpad. For instance, clicking on the Settings button in the toolbar makes the button look pressed-in, but nothing actually happens unless I click by pressing the dedicated "click" button on the touchpad.

Also, clicking on the X button on the "there's a new version available" message box does the standard press animation, but the box doesn't close unless I click OK. Huh.

Sunday, November 8, 2015

Preempting CryptoWall with Group Policy Software Restriction Policies

The famous ransomware trojan known as CryptoWall does its work by downloading a malicious EXE to the user's temp directory and then running it from there. It doesn't make sense for any legitimate program to be executing from the Temp directory, so we might as well remove that option outright.

That can be accomplished with Group Policy, Software Restriction Policies specifically. Those are under Security Settings, which is accessible in MMC at secpol.msc. You might need to use the "Add Software Restriction Policies" entry on the context menu before the folder can be expanded. When that's done, create a New Path Rule under Additional Rules. Enter %TEMP% as the path and set the security level to Disallowed.

Danger: it's possible to cause great inconvenience with these policies. I am not responsible for anything you mess up. Be careful.

Saturday, November 7, 2015

False Traffic Sources

When I look at the Blogger statistics page for this site, I see a lot of traffic (i.e. referring URLs) from web pages that don't contain any links to my site. One of the two major "sources" is a shady-sounding web site and the other is an app page on Google Play.

My guess is that the owners of those pages are trying to drive traffic there by requesting lots of pages from my site and specifying a fake Referer [sic] URL. Maybe they're hoping I'll see it in the top traffic sources list, click it, and be interested? Seems like a lot of work for just a few potential converts.

Thursday, November 5, 2015

Android Studio Installer Exit Code 1223

I am currently trying to deploy Android Studio to several Windows machines with an unattended installation, but the installer (which is an EXE, not an MSI) sometimes exits with code 1223. When that happens, shortcuts aren't created on the desktop or in the Start menu, but the files are placed in a Program Files directory and work correctly. Some research suggests that this exit code occurs with unattended (/S) installs only.

I have noticed - but not confirmed - a correlation between the ACLs on the directory containing the installer and the exit code. When normal users are not allowed to read the installer, even if the install program is run as an administrator or the system, the exit code sometimes happens. I have not seen it happen when everyone has read access to the directory. Further study may confirm or deny this hypothesis.

Wednesday, November 4, 2015

Connecting Hyper-V Guests to the Network

Today I set up Hyper-V (Microsoft's virtualization technology) for the first time. It was very easy for the most part; the only strange thing was the connection of the VM to the network. The Network Adapter dropdown only contained "Not Connected", so I was uncertain as to how to allow the VM to see the real network.

Apparently, a virtual network has to be created before a VM can be connected. That can be accomplished by opening the Virtual Network Manager (if you're running Windows Server 2008 or 2008 R2) or the Virtual Switch Manager (if you're on anything newer). That entry can be found in the Actions pane of the Hyper-V Manager snap-in for MMC.

To create the virtual network/switch, select the desired type ("External" allows connections to the real network) and press the Create button. Set the name if desired, and OK out of the network window. The network/switch now appears in the Network Connections dropdown.

It would be nice if Hyper-V included an external network/switch by default to minimize confusion. At least the connection bridge works with a minimum of fuss - that feature has given me trouble in both VirtualBox and VMware Player.

Tuesday, November 3, 2015

Removing "Windows protected your PC" Messages

Many major browsers produce warnings when downloading rarely-seen files. Attempting to run those files results in the appearance of a "Windows protected your PC" message and no execution of the actual program. These messages can be very annoying, especially when it is known that the file is benign yet rare.

The unsafeness of files is remembered in an NTFS Alternate Data Stream. When the Windows ZIP extractor decompresses an archive, it replicates that tag to all the output files. The tag can be removed in one of two ways:
  • Open the Properties sheet of a downloaded file (before decompressing it if it's a ZIP) and press Unblock near the bottom
  • Download the Sysinternals Streams utility and run it with "-d" followed by a wildcard mask of files from which to purge ADS's
Files without the Zone.Identifier tag are much less likely to arouse SmartScreen's suspicion.

Monday, November 2, 2015

Identifying the Source of an Untitled Window

Sometimes, bothersome windows may appear without any indication as to what program created them. The best way to find such windows' source is to identify the process that owns it, and then figure out what product the process belongs to. My preferred procedure:

  1. Download Sysinternals Process Explorer
  2. Run the program and accept the EULA
  3. Drag from the "Find Window's Process" icon (looks like a target) on the toolbar to the mystery window
  4. Look at the application name and company name columns for the newly selected row, which is the process that owns the window
  5. If those data aren't helpful enough, Google the process name
This also works for windows that don't even have title bars, like those that are just gray rectangular regions. If you want to poke harder at mystery windows, try Spy++, which comes with Visual Studio.


Inspired by this Super User question and my answer there.

Sunday, November 1, 2015

When Thief (FICS Client) Won't Change Piece Sets

I recently experienced a strange problem with the FICS online chess client called Thief. It refused to change its piece set to anything but the first four, which were all vector-based. Some inspection of the "THIEF" folder in Documents revealed that the folder that should contain bitmap-based piece sets was completely empty.

It appears that the Thief installer is designed for single-user systems, and doesn't play well with over-the-shoulder elevation (i.e. situations where an administrative user types a password so the program starts as the admin on the original user's desktop). Though Thief places some files in its Program Files subdirectory, the majority of its data goes in per-user locations like Documents, and apparently it gets confused when the shell is running under a different user as the installer, and so doesn't place the bitmap graphics in the right folder.

The solution is to temporarily make the main user of Thief an administrator and run the installer as the same user who is logged on.

Saturday, October 31, 2015

Uninstaller Shortcuts in the Windows 8 Age

Back when Windows XP was the newest Microsoft consumer OS, it was common practice for program installers to create folders in the Start menu "All Programs" list. Each such program's folder contained a shortcut to the program itself, and sometimes a help file or uninstaller.

Nowadays, with the Start menu flattened by Windows 8's Start screen (and, to some extent, the incremental search of Windows 7 and 10's Start text box), I frequently see uninstaller shortcuts come up. It doesn't make sense to me that a particular uninstaller should be readily accessible - it's not like I'm going to remove a program on a daily basis. It's even worse when the shortcut is just called "Uninstall" with no indication as to what program owns it.

I think it's time we stop placing shortcuts to uninstallers. Windows XP and its rigid Start hierarchies are long gone.

Friday, October 30, 2015

Translating Any Principal Name to a SID in .NET

Windows security identifiers (SIDs) are represented in .NET by the SecurityIdentifier class in the System.Security.Principal namespace. .NET provides intuitively apparent ways of getting the SID of a real account (Sid on the UserPrincipal class) or of a well-known account like System (use the SecurityIdentifier constructor that takes a WellKnownSidType). Neither of those methods, however, work for more esoteric principals like TrustedInstaller or for arbitrary user input.

A convenient way to get the SID that represents the account named by a string is to create a new NTAccount object. Then call Translate on that object, passing the Type object for SecurityIdentifier (which you can get in VB.NET with a GetType expression). That produces a real SecurityIdentifier instance that can be used wherever you need to identify a principal.

Thursday, October 29, 2015

Programmatically Creating Group Policy Shortcuts

.NET has official, documented, managed APIs for modifying registry-based Group Policy, but there are no such facilities for non-registry-based preferences like shortcuts. Some poking around in a shortcut-having policy object's folder in SYSVOL reveals that shortcuts are stored in an XML file called Shortcuts.xml in a folder called Shortcuts under Preferences in the GPO's folder. That format is easy to figure out, but I found that creating that structure manually had no effect. Strangely, the Group Policy Editor showed the shortcuts that I created, but neither the reporting module nor client computers paid it attention until I opened the shortcut properties in the GPE and saved it.

I concluded that there must be some other bookkeeping responsible for enabling types of preferences. There is indeed - I discovered that the Active Directory representation of Group Policy Objects includes two fields called gPCMachineExtensionNames and gPCUserExtensionNames. Those objects are found in the Policies container under System in the main directory partition, though it won't appear in Active Directory Users and Computers unless you enable advanced mode. Each field is a list of pairs of GUIDs, representing Group Policy client extensions. It looks like [{GUID}{GUID}][{GUID}{GUID}], where each bracket-enclosed GUID pair is one extension, and the exact number of entries depends on which preferences are present..

To enable the processing of shortcuts, prepend

[{00000000-0000-0000-0000-000000000000}{CEFFA6E2-E3BD-421B-852C-6F6A79A59BC1}]

and append

[{C418DD9D-0D14-4EFB-8FBF-CFE535C8FAC7}{CEFFA6E2-E3BD-421B-852C-6F6A79A59BC1}]

to the appropriate property on the policy object. You can discover the GUIDs of other extensions by creating a GPO with only administrative template policies, observing the field value, adding an entry of the desired type, and seeing what got added to the field.

The best way to fiddle with Active Directory directly in .NET is to use the DirectoryEntry class from System.DirectoryServices. Make sure to call CommitChanges on DirectoryEntry after you've changed the values.

Tuesday, October 27, 2015

PowerShell Bitwise Operators

PowerShell, the fancy new-ish alternative to ye olde command prompt, does have bitwise operators, though they're a little bit difficult to guess. They're handy when using .NET methods that take flags enums as parameters. Named operators start with a hyphen and go between their operands as you would expect. All the bitwise operators are prefixed with "b", so for example "-band" is bitwise and; "-bxor" is bitwise exclusive-or. 8 -bxor 9 produces 1.

Monday, October 26, 2015

Machines Can Be Admins Too

An interesting thing about Windows account management and Active Directory is that machine accounts can do everything a user account can, like be a member of a group. That membership then applies to that computer's SYSTEM account's actions on the network. If a machine account is added to the Domain Admins group, processes running as SYSTEM on that machine will have complete access to the domain. However, that access only comes into play at the next boot; existing processes use a token that does not include newly added group memberships.

Sunday, October 25, 2015

Accessing the Real System32 From 32-bit Programs

On 64-bit editions of Windows, 32-bit programs that attempt to read from or write to System32 will actually perform their operations on SysWOW64, which is also in the Windows directory. That can be a problem if you want to do something with the real System32 files from a 32-bit program, especially without the source code of that program. (Programs can opt out of the redirection by calling the Wow64DisableWow64FsRedirection function.)

For example, I recently wanted to inspect the contents of the Local Group Policy files with a hex editor, which happened to be a 32-bit application. Those files are under System32 and have no useful counterpart in SysWOW64.

The solution is to use a special pseudo-folder called Sysnative instead of System32. \Windows\Sysnative is accessible for 32-bit applications (though you won't see it in a directory listing), but is not at all navigable by or visible to 64-bit applications. Its contents are the real contents of System32, and any files under it are the authoritative versions.

Friday, October 23, 2015

Modifying Group Policy with .NET

There is precious little information on programmatic access to Group Policy, and many people say automatic configuration of Group Policy settings can't be done, but it totally can if you put in a little effort.

First, you'll need the Group Policy Management Console class library, which comes with the Group Policy Management Console in Remote Server Administration Tools. Connect to a domain controller by creating a new GPDomain object. Create a new GPO by calling CreateGpo on your GPDomain. To actually get at the policy settings, you'll need to get a ComputerConfiguration object from the Computer property on Gpo, a PolicySettings object from the Policy property on ComputerConfiguration, and a RegistryPolicy object from the GetRegistry function on PolicySettings (not in read-only mode). To get the user policies, use the User property on Gpo instead of Computer.

The methods on RegistryPolicy that start with "Write" allow you to create registry entries that the policy will enforce. When you're finished writing policies, call Save on the RegistryPolicy object with the parameter True if you're updating the computer policy or False if you're updating the user policy. To figure out what entries do what, you'll need the help of policy definitions (ADMX files).

These can be read with ADMX Migrator, and are found in the \Windows\PolicyDefinitions folder on every machine. (The authoritative copy should be on SYSVOL in a domain, but local copies work too.) In ADMX Migrator, right-click "ADMX Templates" in the left pane and choose "Load Template" to open an ADMX file. Browse around the folders until you find the setting you're looking for, and then note the registry key and value that the setting affects. To see what data you should write, check the Values tab. For settings that have extra configuration (beyond Enabled/Disabled), check the Presentation and Value Lists tab.

Microsoft set up a Group Policy search web site/database thing that lets you get the same info, but as of this writing it has some weird behavior with settings that have extra configuration. It does, interestingly, tell you which ADMX file is responsible for each setting, so that could help you even if the value name isn't quite right.

To link (i.e. actually make it have an effect) the GPO to the domain or to an OU, first call GetSom on your GPDomain. GetSom takes the LDAP-style fully-qualified name of the Scope of Management; the DirectoryServices namespace might help you find available SOMs. Call LinkGpo on your Som with the Gpo object and the position at which to insert it; a constant 1 works. The resulting GpoLink object allows you to change the enforcement and enabledness of the GPO. Once that's done, your GPO is linked and in action.

Thursday, October 22, 2015

Registry Policy (.POL) Format

Microsoft published the format of the registry policy (Local Group Policy or backed-up Group Policy) files, but their document is not at all specific about the byte-level arrangement of the information. I did some tinkering with the .POL files and figured out everything I need to know.

A .POL file starts with the four-byte integer 0x67655250, which is the string "PReg". The file's version follows as a four-byte little-endian integer. The main body of the file consists of records for registry values to update. All text in the body appears to be UTF-16LE, so when it's storing only ASCII, there's a null byte after each character.

At the beginning of a record, there is an open bracket "[" (yes, the punctuation in the MSDN document is literal) and a null byte after it. The path to the key (folder as seen in Registry Editor) follows, also as UTF-16LE, and is terminated by a null character (two null bytes after the last real character). There is then a literal semicolon character, including the null, and the name of the value (name of the entry as seen in Registry Editor). Some values are special, and I don't understand them fully; see the Microsoft document.

After another semicolon character, the data type appears as a four-byte little-endian integer. Common values are 1 (string), 2 (expand string), 4 (four-byte little-endian integer), and 11 (QWORD, LE). The full list appears at line 4884 in this copy of WinNT.h.

The next semicolon-delimited field is the size of the data, which is again a four-byte little-endian integer, and appears all the time, even for types whose data are always a constant size. Finally, after another semicolon character, the data appears. Numeric types are represented in binary; string types always are in UTF-16LE and null-terminated. The record is finished off with a "]" character. No null appears between the ending bracket of one record and the opening bracket of the next.

Wednesday, October 21, 2015

.NET DirectorySecurity Oddities

It's great that .NET has managed APIs for file and directory ACLs, but DirectorySecurity seems to be a little rickety. In particular, I've found that setting the ACL on a directory sometimes does nothing if the directory is hidden. Also, the SetAccessControl instance method on DirectoryInfo has been less reliable in my experience than the SetAccessControl static method on Directory. When I take care to avoid those pitfalls, DirectorySecurity works well.

Tuesday, October 20, 2015

Adobe Acrobat Unattended Install Difficulties

I am attempting to do an unattended deployment of Adobe Acrobat (not Adobe Reader) via msiexec, and I am having a lot of trouble. The installer process sometimes exits with code 1603, which is a generic installation failure. On some machines, the installation works fine after a couple tries, but on others, it never works no matter how much I reboot or retry.

I did recently dig up an Adobe KB article that seems relevant, but it's for an older version (not DC), though a more recent document indicates that the parameter is still useful. I will try the MSI parameters and the registry tweak to see if they help.

Sunday, October 18, 2015

WCF Surprise: Renamed Machines Temporarily Use Old SAM Name

Recently, I was messing around with WCF's impersonation/identification feature on machine accounts, i.e. with WCF clients running as SYSTEM on their respective machines. Meanwhile, I noticed that a machine had a wrong name; I must have forgotten to change the WDS naming scheme before deploying to it. So I changed the name and rebooted as suggested. When the machine came back up, I was surprised to learn that it was still identifying to other machines with its old name.

The server checks the client computer's name by reading ServiceSecurityContext.Current.WindowsIdentity.Name, which produces the name in NetBIOS form, DOMAIN\MACHINE$. Puzzled, I checked the Active Directory record for the machine, and all relevant attributes had been updated to reflect the change. The computer itself displayed the new name in system properties. The WCF server application had been restarted (for other reasons) since the change. Therefore, I have no idea why it was seeing the old name.

If you know what's going on, feel free to leave a comment or answer my Server Fault question.

Saturday, October 17, 2015

Simple, Effective Copy Protection with Asymmetric-Key Cryptography

Copy protection can be a hard problem, and in the end there's really no way for copyright holders to win. Then again, locks are for honest people, so there is a benefit to licensing checks as long as they are simple to implement and don't cause pain for legitimate users.

Asymmetric-key cryptography can be used to build a simple yet reasonably strong method of licensing enforcement. It can't do much if your users are willing and able to whack the executable to remove the checks, but not many manageable systems can. What it can do very well is make sure that a license key is present and produced by a trusted agent. This is how it works:

  • An asymmetric key pair is generated. The public half is burned into the distributed application, and the private half is kept secret with the licensing agents.
  • When a copy is bought, some identifying information about the legal owner is recorded, hashed, and signed with the private key. The resulting file is the license key, and is sent to the owner.
  • When the application starts, it gathers all that identifying information, hashes it, and checks it by decrypting the signed version in the license file with the public key.
Note that this does require a persistent, unique piece of data to identify an owner, so it works better for server applications (especially ones bound to a domain) than end-user applications.

Friday, October 16, 2015

Windows 8 Won't Pin Control Panel Items to Start

I check Windows Update semi-frequently, especially after I install a new device or a large Microsoft program. Windows 8 makes it a bit inconvenient to get to the desktop Windows Update - typing "windows" at the Start screen never makes it bring Windows Update to the top of the list even though "windows update" is the only thing I ever type there that starts with "windows". At least it eventually learns that I prefer the desktop version to the "Check for updates" Metro settings option.

Anyway, I went to pin Windows Update to the Start screen (I had just decided to use the screen for its intended purpose - as a dashboard - and make a "Management" section), but I found that Windows will not allow me to pin a Control Panel entry, even the desktop ones that are basically applications in their own right, to the Start menu. In fact, right-clicking on them in the search results list does nothing at all. Metro settings and files also don't make the pinnability cut, but folders do. Huh.

Thursday, October 15, 2015

Robotics - Meet the Sponsors

Today, both robotics teams gave a presentation to a panel of community engineers selected by the coach. The presentations were about the teams' status, plan, and mission. Personally, I think it's a bit early in the season for this type of meeting, though corporate-style state-of-the-project meetings do have value. Nevertheless, each team discussed the parts of the robot that were together and touched on team workings, introducing each member.

A tiny amount of actual work was done after the presentations, and I learned that the veteran team has started programming with Android Studio. Both teams still have a long way to go; neither robot moves, neither has any useful appendages, and only one has wheels.

I'm not actually sure whether the engineers from the community are potential mentors or sponsors, but they're apparently important - there were cheesecake bites at the meeting.

Monday, October 12, 2015

Fixing Unbootable 15-Series HP Notebooks with Caps Lock Steady Blink

Yesterday I participated in the repair of an HP 15-R110dx notebook computer that refused to boot or do anything at all. When powered on, its Caps Lock key light blinked once every three or four seconds; the pattern wasn't described in any HP documentation that I could find.

It turns out that the CMOS state was corrupt or unusable in some way, so the CMOS battery needed a disconnect/reconnect cycle. Actually performing the repair was exceptionally difficult because the RAM and CMOS battery are under a host of important and inconvenient-to-remove parts, and not accessible from the bottom.

The general procedure to fix this problem is:
  1. Remove the main battery and disconnect the power cable
  2. Remove RAM and CMOS battery
  3. Press the power button (discharges any extra energy)
  4. Reinsert RAM and CMOS battery
  5. Connect power cable and/or main battery
  6. Reboot when prompted about CMOS corruption
Step 2 is written here as five simple words, but it is a challenge, as is reassembly. Disassembly goes like this:
  1. Remove all screws from bottom panel
  2. Remove the DVD drive
  3. Remove the screws hidden under the DVD drive slot
  4. Remove the screws hidden under the back two rubber feet
  5. Pry the keyboard out and disconnect its cable
  6. Pry the larger surrounding plastic piece off
    • Be careful to remove the keyboard separately or you risk tearing the power button cable. (Guess who did that. Twice.)
  7. Unscrew the metal plate and remove it
  8. Unscrew the motherboard and tip it up toward the screen
    • Screws for the motherboard are marked with white arrows.
  9. Remove the RAM and CMOS battery on the underside of the motherboard.
    • Yes, the RAM is on the underside of the motherboard, under all that other stuff. That is just appalling.
If you damaged the power cable in substep 6, you'll need to short across it when applying power for step 3. Fortunately, it's possible to solder it back together.

RubberWilbur's video guide to RAM replacement for these models was very helpful for the disassembly operation. For putting it back together, assembly is the reverse of disassembly.

Once everything is back together and powered, BIOS should come up with a message about CMOS corruption and a directive to press Enter. Press Enter (or just reboot) - CMOS will be reset and all will be good.

Sunday, October 11, 2015

Pasting YouTube Tag Lists

While drafting a post in which I complained about being unable to usefully paste into the YouTube tag list for a video, I noticed that the feature I wanted is already there, just not easily discoverable. Though it does not seem possible to get anything useful by copying from the tag list, YouTube will split a tag list into individual tags if you delimit the tags by commas, not semicolons or spaces or anything else. Therefore, you can prepare a list of tags and easily paste it into each video in a series without having to retype it every time.

Saturday, October 10, 2015

Power Cables and Data Cables from Different Computers

Today I needed to get some data off of an unbootable hard drive that was in a mount in a machine. Since I did not have a special screwdriver and the mount looked very difficult to work with, I decided I would just leave the drive where it was and connect cables from the real machine to it. The problem with that idea was that all the SATA power cables in the real machine were super short and could not reach.

So I carefully positioned the two machines so that the data cable would reach the hard drive from the bootable machine and connected a power cable from the unbootable machine to the drive. I powered on the unbootable machine first (I'm sure it got stuck in BIOS or something, no monitor was on it), then the bootable machine. The contraption worked - the drive was accessible and stayed online as long as I kept the old machine on.

This is also a good trick for situations where a motherboard is out of power cable slots.

Friday, October 9, 2015

Abiathar Confidential - Security & Privacy

I have written these things before, but I thought it would be good to put them all together in one place for easy reference.

Abiathar operates almost completely offline. It works perfectly fine without an Internet connection, but when the Internet is accessible, Abiathar updates itself. That may raise some concerns about the security and privacy of the whole system.

Abiathar uses the network for only three operations: automatic self-update, VeriMaps verification and temporary logo display. On startup, it checks my public Dropbox to see if there is a new version available. If so, a prompt is displayed asking for confirmation. If the user accepts the update, the updater application downloads a script from my Dropbox that can perform only three types of operations: download a file, delete an existing file, and mark a downloaded file to be executed after other operations complete. The entire checking and download processes are done over TLS.

There is the possibility of a critical update, a situation in which I have deemed an update so necessary that Abiathar should not be used at all until the update is installed. This mechanism has never been used, and probably won't ever be - it's for updates that fix earth-shattering, data-destroying bugs. Even if this flag is set on an update, the user still has the option of canceling the update, though the prompt appears in the console window of the temporary updater program instead of the Windows Forms UI of Abiathar proper.

The VeriMaps verifier is used when a maps file that claims to be VeriMaps-signed is opened. The matching public certificate is retrieved from my Dropbox (again over a TLS connection) and used to verify the file's authenticity.

The final type of network usage is purely cosmetic: temporary changes of the big background image in the main form. On startup, a download of a file at a certain path in my Dropbox is attempted. If it succeeds, the resulting image replaces the standard blue-text logo. The downloaded image is not persisted at all on the client, and it is redownloaded for every launch as long as it exists. I have set a temporary logo only once, on Independence Day, as a test of the system.

No user data is ever sent out by Abiathar.

Thursday, October 8, 2015

Centering Objects on Other Objects

There are several programs in which I frequently find myself wanting to align some object to the center (either horizontal or vertical) of another object. Unfortunately, I rarely see that feature. Visual Studio has Format | Align | Centers (or Middles), but there does not appear to be such an option in Adobe Flash Pro (the IDE/designer, not the player). That's a shame, because a lot of the arrangements I would like to produce require perfect centering of objects on other objects.

There might be such an option in Flash, but I am not seeing it and Googling has not helped me yet.

Tuesday, October 6, 2015

.NET Monitor Locks are Re-Entrant

The purpose of the Monitor class in .NET (used by "SyncLock" in VB.NET and "lock" in C#) is to prevent different threads from entering a critical section at the same time. Care must be taken by the programmer to ensure that deadlocks - situations in which threads are waiting for each other directly or indirectly - are impossible. I recently needed to write a recursive function that happened to require careful threading, so I was concerned that the second invocation would hang waiting for the first to finish.

Fortunately, Monitor locks are re-entrant. If a section is entered for a given lock object on the same thread (e.g. in a recursive situation), the section will not be released until a matching amount of Exit calls are made. [Source: MSDN's article on Monitor.Enter]

Sunday, October 4, 2015

Power Failures Happen

Today while attempting to switch off my monitors, I accidentally hit the toggle button for my computer's power, immediately turning it off. Whoops. That's alright, NTFS is designed to be resilient in the face of power loss, so I turned my computer back on. After BIOS did its thing, Windows 8.1 ran some sort of "automatic repair" on my computer and attempted some operation. (Before asking me, and without telling me what it was!)

Automatic Repair couldn't fix the "problem", and so it dumped me into the repair mode UI. Since I was fairly certain that nothing was wrong with the machine, I chose the Continue (try to boot normally) option, which is under the advanced tools menu for some reason. After sitting at a black screen with high disk utilization for a few minutes, Windows came up as normal with only the expected event 51 entries in the Event Log.

So all that was a really long-winded way of saying that everything was fine.

I really wish more programmers would account for the fact that power failures can happen at any time, and that it shouldn't be an earth-shattering catastrophe if the program or machine doesn't go down gracefully. I understand that there are certain critical operations that cannot be continued if power is lost in the middle, but surely an attempt can be made to continue with whatever state was saved to disk before panicking and displaying scary messages to the user.

Saturday, October 3, 2015

Keep My Place in Disconnected Network Folder Structures

I frequently have to browse the directory trees of remote machines, and since mapping a network drive for each place would create a big mess (there are lots of places I need to look at), I have to use double-backslash UNC paths to get where I want. That works great, and I do my work until I need to go somewhere else. I then close my laptop - disconnecting it from the network - and carry it with me. When I reopen it, all the Explorer windows browsing network folders are showing me the Network screen (the list of computers on the domain).

That's rather inconvenient, because there is no indication of what I was doing with that window. It would be really nice if Explorer instead grayed everything and put up a "remote session disconnected" panel that could be clicked to attempt a new connection.

Thursday, October 1, 2015

Keeping Windows Forms Controls Centered

Windows Forms designers may find it necessary to keep a control centered in its container but not stretched if the container expands (e.g. if the user maximizes the window). The way to accomplish this is actually quite simple, and requires no math whatsoever. Simply setting the Anchor property to nothing along a certain axis results in the control staying perfectly centered without any change in size. Setting that property to Bottom only, for example, keeps the control's bottom edge stuck relative to the bottom of the container but allows it to slide horizontally to remain centered.

Wednesday, September 30, 2015

Store Relative Paths if Possible

Semi-recently, I was working with a program that managed many files as part of a project. I was collaborating on this project, so I placed the project folder and all of its files in a shared Dropbox folder. However, there was a problem - the program could not open the project file on any other computer because it stored absolute paths to the files it depended on. I was able to work around it; because the program ran under DOSBox, changing the drive and folder structure to be the same everywhere was not too difficult.

That experience was rather inconvenient, and I wish more programs that reference multiple files in a binder of some sort would make an effort to store only relative paths. That way, people can collaborate more easily, and the project can be moved around on the same computer (or backed up) without problems. Optimally, warnings should be produced if the user adds files to the project that are not in the project's root directory or a subdirectory thereof.

Monday, September 28, 2015

When Context Menus Open Slow

On several otherwise-fast Windows computers, I have noticed a delay of one or two whole seconds between when I right-click the desktop or a folder and when the context menu appears. Though two seconds might not sound like a lot, it really throws me off when something that should be instantaneous takes any noticeable amount of time.

The culprit for the slowness is virtually always the same: one of the entries is added by a program that takes a while to initialize. That misbehaving program is almost always a management application for graphics drivers, and the reason for its slowness is almost always that it is written for a high-impact framework like Java or .NET.

Relevant: Is it okay to write in-process shell extensions in managed code?

The AMD Catalyst Center is notorious for creating context menu slowness, but I've experienced it with nVidia's equivalent. Incidentally, I have never once wanted to use the context menu item that brings up graphics card settings, and I certainly don't need it there whenever I right-click any folder ever.

Uninstalling the management program (but not the drivers!) will add speed to context menus.

Sunday, September 27, 2015

Checking Whether a Dependency is Available in .NET

It may be desirable to have a .NET program that can use a library but can also function without it. Such programs are made slightly difficult to write by the fact that .NET assemblies must produce a list at compile-time of what other assemblies they depend upon. If one of those assemblies cannot be loaded at run-time, problems occur.

Fortunately, the errors are normal exceptions and can be caught and handled like any other, if you're careful. The exception for a missing dependency will be thrown when a method that references a type in the missing assembly is entered. Therefore, the presence of the optional library can be checked by wrapping in a try/catch block a call to a short method that uses one of the library's types. If the library is missing, an exception will be thrown, but execution can continue as long as you don't call any methods that involve the missing types.