Friday May 20 2022 @ 2:09 AM

One of the big downsides to enabling Opcache in PHP is that you lose hot-reloading of changed scripts. One way to get that ability back is to use IDEA File Watchers.

First, implement an endpoint in your application to clear caches:


Then, add a new File Watcher that invokes that endpoint:

Mission accomplished!

Wednesday January 27 2021 @ 3:44 PM

The Good

Let’s get the easy stuff out of the way: The high refresh-rate screen and high resolution cameras are clearly superior to what anyone might be upgrading from. I’m very thankful that Apple and Samsung are FINALLY getting on the higher refresh bandwagon. Moving from 85hz CRT to 60hz LCD was noticeable back in the early 2000s. I can appreciate the benefit of a higher quality front-facing selfie camera. I did not get a chance to test any of the cameras, but I’m sure they are great. 9 out of 10.

The Bad

I want a single main camera on the back. Anything more is a waste of my money and my attention. I don’t have any time or attention to deal with switching between cameras. If I did, I would pull out a DSLR. The point of a camera on a phone is to take quick shots in the moment, dealing with a poorly designed camera app’s ‘pro’ mode is a tax on my sanity I wish not to pay. Failure to understand obvious common use cases at a huge cognitive and financial expense to the consumer; 2 out of 10.

The Ugly

The first thing you’re subjected to when you turn on the phone is page after page of legal terms and conditions. These use dark patterns to get you to agree to terms and conditions that are optional. Additionally, I would guess more than 90% of users have already agreed to these terms on their previous device. There are FULL PAGE lists of terms from Google, then Samsung, then ATT. On some, when you try to skip the optional terms, there’s a huge warning of things you’re going to miss out on. This is disgusting. These legal terms are not comprehensible by consumers. Heck, even attorneys can’t understand these terms. Hundreds of pages of legalese that are comprehensible to exactly zero people is a fall-flat-on-your-face failure: 0 out of 10.

After agreeing to all the required terms, you’re asked to log in to all your accounts. Not all your google accounts, but Google, Samsung, and ATT. This should not be part of the system-modal setup process. Each one you have to skip and again get subjected to ARE YOU SURE YOU DON’T WANT ALL THESE GREAT BENEFITS!? Even worse, Google followed up with a spam email (Including a gaudy emoji!) to finish the process. It's not even the consumer-facing model number. Exploiting human psychology for personal greed: 0 out of 10.

When you finally make it to the home screen, there’s a huge flurry of non-dismissible notifications about finishing setup, installing updates, and syncing accounts. The flurry is disorienting and the ‘complete setup’ notification being non-dismissible is frustrating. The flurry of updates mean the phone is using a lot of bandwidth and CPU power right at the most critical moment: unboxing. This scenario occurs in 100% of cases. This is an enormous QA failure: 0 out of 10.

Shortly after you realize the home screen and app drawer are filled with garbage shovel-ware from Google, Samsung, and ATT. About half of these applications cannot be uninstalled or disabled. From my experience, some of these applications even exploit this uninstallability to send advertising notifications. Jailbreaking a phone to get arround these issues is almost definitely against the DMCA and thus illegal. Trapping the user like this is shockingly unethical: 0 out of 10.

Presumably, largely thanks to Apple and the power of newer devices, ‘user experience’ features like blur, translucency, and animations are now pervasive. Except for blur, these features and embellishments can be hugely advantageous to usability. Unfortunately, Apple and Google have largely put more focus on visual appeal and oohs-and-aahs than usability. As a prime example, Apple has a added settings to disable translucency and motion because users get physically sick when subjected to these features. Additionally, the transitions are often physically disorienting because they convey physical movement that is either impossible or immediately self contradictory (think a screen sliding toward the top of the screen then coming back from the bottom). Embarrassingly these settings are swept into the accessibility settings. Last time I checked, disabling bad design was not an accessibility concern. Somewhat less disorienting is the fact phone applications run full screen, so there’s very little context conveyed. Animation has helped a little here. Giving Google and Apple the benefit of the doubt, I suspect translucency was an attempt at giving context, but this lead to contrast issues and may explain the advent of the blur effect now used on both platforms. But this blur effect makes me physically ill, likely because my eye’s consider it something they need to correct via focus but cannot. Additionally, it’s implemented in a physically-impossible presentation. Google allows animations to be disabled completely, but one cannot selectively disable the bad animations and leave helpful ones. Worse, Google does not offer a way to disable blur or translucency. I find making a computer UI that makes users physically ill a complete and utter failure. 0 out of 10.

This brings us to the physical design. While setting up my accounts, I needed to look up a password in my password manager. I gently placed the hefty phone on my desk, opened the password manager, found the password, then gently picked the phone back up to enter it into the text field. While picking up the phone, the apparently ultra-sharp bezel scraped the surface of my desk. It felt like fingernails on a chalk board. I turned the phone over and discovered it had scraped off the finish of my desk. Apparently the back of the phone has a bezel that is a literal physical hazard. Unbelievable. 0 out of 10.

The white crud here is the finish of my desk this phone scrapped off when it was in gentle, momentary contact

Six years or more after its introduction, the phone still has a pointless curve on it that constantly creates false-positive touch screen interactions because human flesh, required to supply enough friction to hold the phone and prevent it from falling, comes in contact with the screen there; worse, the flesh occludes portions of the screen. Additionally, there is still a ridiculous pinhole for the front facing camera that cuts out of all content that is displayed on the device to no benefit except marketing bullet points for screen coverage. There have been numerous generations of the phone since this problem would have been woefully apparent. There is no excuse any more, 0 out of 10.

I managed an $800 trade in value for a phone I paid $350 for a year ago, so really this is only costing me $400 for a flagship phone, $750 if you include the cost of replacing the trade-in. That sure sounds like a pretty good deal...

Verdict: Disgusted; Google, Samsung, and ATT should be ashamed. The device unconditionally makes the user physically ill and permanently damages any surface it’s put in contact with. On top of that, it’s been intentionally designed to exploit human behavior for personal greed. 100% of QA testers should have experienced this same outcome with minimal effort. I’m returning it.

Monday November 30 2020 @ 2:06 PM

I spent the evening of Black Friday taking pictures of manhole covers for bonus vitality points. I captured the apparent full history of AT&T break up and reformation. Lincoln park cover was pretty cool. Found a nice pair of well testing holes. Apparently there's texture/pattern for what kind of hole it is. Enjoy the fruits of my labor!


I just walking around for 1.5 hours taking pictures of manhole covers; which is, admittedly, weird.

Theres basically no one outside so I would just meander around the middle of the street.

Some guy asks me “are you alright?”

and I'mm like “yeah”

and he goes “are you sure?

I'm thinking maybe he thinks I'm drunk, considering I'm walking around the middle of the street.

So I get straight to the point and say it “I'm just looking at these manhole covers”

He continues: “do you need anything?”

I'm thinking 'jesus, just let me be!' but appreciate the concern

I respond “no, I’m good”

And he abruptly asks “do you want any drugs? any party starters?”

I'm like "What??"

And he removes his mask and shouts louder. DO YOU NEED ANY DRUGS?

On one hand relieved me that I no longer had to be nice to this guy that seemed worried about me and could just leave, but who the heck blurts that out on the street?

Wednesday September 9 2020 @ 9:05 PM

  • Loud, non-optional, non-mutable, sudden announcements from Cortana
  • Unnskippable forced usage of privacy violating Microsoft account
  • No ability to change network/wifi after setup so if wifi has captive portal, you’re effectively bricked
  • Numerous pages of confusing unilateral legalese
  • Sketchy ahead-of-time requests for sweeping privacy violating permissions
  • Loads of cutesy, unprofessional text without any progress indicators
  • Instead of baking the first account into the image, user must wait for account creation process to complete
  • Manual and tech support are online-only or the information is connected via a website. If the new computer is a replacement for a defective one and it’s the only way a user has to get online, this could be very bad

Monday August 17 2020 @ 3:59 PM

Microsoft Teams, Slack, Zoom, I have a feature suggestion: AI powered verbal-tic and meeting etiquette notifications powered by automated transcription.

  • "If you can help it, you might consider trying to avoid saying the word 'um' during the next meeting"
  • "Your speech sounded heavy on business-speak but conveyed little meaning"
  • "It sounded like you interrupted people a lot; try waiting before speaking"
  • "You were usually the one talking and were repeatedly interrupted after long monologs; consider giving others a chance to speak up"
  • "You kept asking 'right?' but didn't give other people a chance to answer"

Saturday July 25 2020 @ 7:09 PM

On Easter, I was overwhelmed by all the pro-Easter posts and the deep baggage they (unintentionally) brought along. In response, I posted a provocative anti-religious statement which I intended to provoke a discussion. The post was insensitive and deeply hurt some people and I am truly sorry for the pain it caused.

I wanted to follow up with a more thorough and thoughtful response.

What is Religious Baggage?

For many folks, religious holidays are a time for celebration. For other folks, they are a periodic reminder of pain and suffering often inflicted by religious believers.

It hurts me deeply to know that so many of my fellow humans are part of such widely accepted, deeply troubling, historically (and contemporarily) terrorizing philosophy without a solid rational foundation. Religions’ untouchable status and people’s imposition of paramount respect for it makes discussing it social taboo. On top of all that, religion is almost always a deeply personal and long-held belief; there’s no way to quickly and easily separate with it. Attacking the beliefs is instead almost always considered an attack on the believer. Regardless of the benefit to individuals or society either historically or today, convincing a believer to acknowledge the harm religion imparts today is almost impossible.

Taken literally, most prominent religious texts describe a god and belief system that is Truly Awful. Ignoring the numerous inconsistencies and mistranslations that prove it can’t possibly be taken literally, these texts condone sexism, homophobia, slavery, eye-for-an-eye, crimes against humanity, genocide, and worse. They have been the source of hate, numerous wars, and crimes against humanity. God either doesn’t exist, was powerless to stop these atrocities, let the atrocities happen, or intended for them to happen.

Many believers accept only some portion of these texts as truth. Simultaneously declaring a religious text as the word of god, inspired by god, or historically accurate while self-declaring they know which parts are and aren’t truthful creates a personal and intellectually dishonest line which is mysterious, inconsistent, and shifting. Where this line is drawn is what separates the murderous believers from the kindhearted ones. However, their ‘faith’ is not dissimilar - it’s based on the same text and is backed by the same evidence.

This is Religious Baggage. 

The impact on me

Prominent religious beliefs describe me, a homosexual, as someone who should forever be shameful for who I am and that I will suffer in eternal hell (to put it mildly). The mere presence of anything Christian, be it a bible, a cross, a Jesus fish, “in god we trust” on currency, “under god” in the pledge of allegiance, or a reference from a politician, or a Christian person makes me feel uncomfortable. For a decade I lived in fear while being routinely teased and bullied for being gay, even before I came out.

Not all religious believers are homophobic. However, it’s very difficult to accept non-homophobic believers at their word when they say they are accepting of who I am. I do not know where that acceptance came from, and I worry about its sincerity.

Over time, I ascertain the beliefs of people I know. I love my mom, I trust her, and I can’t imagine a world without her. I love the amazing people I work with at a YMCA camp I’ve been part of for 23 years. These people have never hurt me. But the background discomfort continues to linger. Maybe I have a personal problem. Maybe it’s the Religious Baggage.

I am not only worried for myself; I am worried for the millions of people that live in constant fear because of who they are. I am lucky to have loving and supporting family and friends, but others aren’t as lucky. LGBTQ people are still mistreated and murdered because of who they are, often for religious reasons. My battle against religion is just one part of how I try to protect others.

The impact on children

Children are especially susceptible to religious teachings because they take what they hear as the truth without thinking critically about the origins of those teachings. They have very little personal experience or cultural knowledge to pull from when they evaluate what they perceive including stories and statements made by authority figures like teachers and parents. This is why nearly every country on Earth has various rating systems to describe acceptable audiences. Video games, books, movies, and music are all rated or categorized to protect underage children from being exposed to potentially harmful content fearing they might misunderstand the context. One type of content that has escaped these protections is religion content.

LGBTQ youth are three times as likely to have considered or actually tried to commit suicide - not to mention pervasive bullying or other mental health concerns. From my personal experience, these attitudes are often rooted in religion. Regardless of what you believe, clearly the protections in place have fallen short.

I believe that religious texts should be considered restricted content for these reasons:

  1. Religious texts are typically considered ‘the word of god’ and that ‘god is a perfect being’. Yet the internal inconsistencies beg to differ with these claims. These mixed signals are complex enough that they may not be realized by children
  2. While religious texts are typically presented as fact, young children aren’t yet developed enough to know fact from fiction on their own
  3. Much of the abhorrent violence in religious texts is presented as acceptable or even suggested; this may persuade children that violence is acceptable if not desirable
  4. The statements about how people should or should not live and corresponding extreme consequences can have damaging effects on developing psyche
  5. The known mistranslations and artifacts from improper duplication are not properly annotated in most copies of religious texts

There is clear historical value in knowing about and understanding the bible (to the extent it can be understood). However, reading on their own, how is a child supposed to pick-and-choose which parts of the bible they should take literally? Appeal to authority like a church or parent is inappropriate as it does not let the child’s belief system develop independently. Most copies of religious texts do not include annotations like “this part is historically accurate”, “this part is metaphor”, “this part should be considered awful”, or “just skip this part”. Even with annotations, splicing up the bible into these types of categories sends mixed and inconsistent signals, something that I believe to be a dishonest thing to do to a child.

Here is my position on Religious Baggage and its impact on children:

  • Letting a child read the bible, even through inaction, without huge explicit declarations of its fictionality and caveats that clearly delineate the terrible parts from the not-terrible parts - possibly leading to being ashamed of who they are - ranges from psychological neglect to psychological abuse.
  • Repeatedly explicitly or implicitly leveraging an inescapable, eternal torture as a method to modify a child’s behavior is psychological abuse.
  • Repeatedly explicitly or implicitly using the bible as an explanatory device for how the natural world works is educational neglect.
  • Subduing curiosity and inquiry into the natural world by suggesting unproven and unlikely alternatives as causal is educational neglect.
  • Genital mutilation including circumcision and female genital mutilation without consent is physical abuse.

I would never feel comfortable letting a child get involved with religions because of the mind field of abuse religious texts, teachings, and practices create. Unfortunately, these practices are considered socially acceptable so must sit on the sideline, terribly uncomfortably, until mindsets evolve to a point where challenging these practices is considered inoffensive.

Why disbelieve?

First of all, disbelief is the default state. There are an infinite set of things that don't exist but a finite set of things that do. The burden of proof is on the believer.

Despite religious text being comforting or maybe even convincing, none of it crosses the threshold into evidentiary support for a basis of truth. The text was written well after the documented events within it occurred, were repeatedly (mis)translated, unreliably duplicated, and manipulated for personal gain.

As time passes and humanity's understanding of the world around us develops, the explanatory power of religious text slowly diminishes. At the same time, none of the content is reinforced by substantiating evidence. It’s a one-way street from supposed fact to disproven fiction.

As time passes, more and more miracles and attributions to god can be described by natural processes discovered through science. The “literal word of god” has slowly devolved into supposed metaphors.

The bible ascribes an origin of the universe (a simpler system) to a god, which now necessitates an origin story for god (a more complex system). The bible ascribes the origins of humanity to a nonsensical scenario in the garden of Eden, but evolution is a much simpler, perfectly reproducible, repeatedly observed, and documented system which easily explains the origins of humanity.

We know of countless instances of humans writing fiction and presenting it as fact. We also know humans that lived thousands of years ago had basically no understanding of the world they lived in. They had little to no understanding of physics, biology, chemistry, math, astronomy, cosmology, etc. They were a superstitious people ruled by authoritarians. It is very easy and rational to conclude that the bible was the convergence of an uninformed people documenting a superstition and best-for-that-time understanding of how the universe worked - if not an instruction book to keep subordinates in line or to give them hope.

One of the most paradoxical parts about religion is god’s control and judgement. Prophecies and control over our own lives must be mutually exclusive and judgement over our actions must exclude interference from god. What control over our world, us, or other people does god actually have? What separates our actions and god’s impact on them when we are being judged and the pearly gates? How do prophecies and free-will (if such a thing exists) play into it? If god set the world in motion into a predetermined path, how is judgement even relevant? The answers to these questions must all be compatible with each other. As far as I can tell, there is no possible explanation that satisfies these requirements and thus a world with a judgmental god is impossible.

Even still, who will be in heaven if and when we get there? What if my utopia includes a person whose utopia excludes me? Are people living in their own simulation and destined to their own simulated heaven? If so, why would anyone involve themselves with the religious beliefs of the others in their simulation in an attempt to get to heaven?

I chose to believe in what’s provably true or statistically more likely - regardless of the comfort it may impart. It’s the only rational approach.

Friday November 20 2020 @ 10:05 PM

One of the most tedious tasks about building software is tracing errors that manifest when testing.

Where does trouble hide?

If you’re lucky, you get a stack trace, but this stack trace is almost always squirreled away inside a container or server log. If you’re testing a website in a browser, this typically means finding a terminal window or log file and copying and pasting file name into an editor, possibly with a line number, to find the code that caused the issue.

A common process could be:

  1. SSH into server or connect to a docker container
  2. Change to one of many log directories
  3. grep through the logs to find the error and/or stack trace
  4. Switch back to the IDE

Business users or maybe QA testers might not have the tools to convey what or where something went wrong. Information may be inaccessible to them and “The report doesn’t work” might be all the information you get.

If an automated selenium test is running against a headless container, you might be at a loss as to what the screen looked like when the test failed.

If the problem is in production, it can be difficult surface errors to the user such that they are actionable and can be clearly communicated to across a support team to developers. Generic errors make tracking down the source of an error or steps to reproduce difficult.

Why bother making an effort

Implementing visible error handling and integrated stack traces will save you a ton of research time and code navigation time.

Users may be able to work around problems in your application

Surfacing technical errors in the user interface when running on non-prod

Surfacing technical aspects of an error, like a stack trace, will help reduce research costs when investigating issues. Developers save time by skipping a step or two when researching what went wrong. Non-technical users will benefit because they will be able to send developers more information about a problem.

Hyperlinked stack traces using IDEA links

It’s already pretty easy to navigate to files and line numbers in IntelliJ IDEA (and related products like PyCharm, PHPStorm, RubyMine, WebStorm, etc). Just enter part of a file name and the line number:

But what if we can skip this step entirely? Enter IDEA’s REST API. This API can be leveraged to directly link from a stack trace in a browser or log to the line in IDEA. The first invocation will trigger this security check:


After which, clicking on a hyperlinked stack frame will jump directly to the code

JS implementation:

window.onerror = function(msg, source, lineno, colno, error){
const url = new URL(source);
let folder = url.pathname.endsWith('.js')?'':'pages';
let extension = url.pathname.endsWith('.js')?'':'.php';
title: "Unexpected client-side error",
message: "An unexpected error occurred; try reloading the page or contacting support.",
type: message.ERROR,
exception: `${error}

PHP implementation:

function getStackTraceLink($file, $line, $args, $printLinks = true)
$text = ($file ?? '') . ':' . ($line ?? '');
if (!$printLinks)
return $text . $args;
$filePath = preg_replace("(.*/TurboKiva/src/webroot/)", 'TurboKiva/src/webroot/', $file);
$url = "http://localhost:63342/api/file/$filePath:$line";

return "$text" . $args;

Exposing selenium tests using VNC and screenshots

Running selenium tests in a headless docker container can make it difficult to see what went wrong.

Selenium publishes debug version of their docker image selenium/node-chrome-debug which runs an integrated VNC server. Make it easy to connect by hyperlinking to the URL on test startup:

Additionally, expose screenshots of test failures:

Screenshots can also be exposed using TeamCity test attachments

Java code to take a screenshot and print a link:

static {
isTeamCity = Boolean.parseBoolean(System.getenv("teamcity"));
if (isTeamCity) {"Running in TeamCity");
artifactDirectory = new File("./ui-test/artifacts");"Artifact directory: " + artifactDirectory.getAbsolutePath());
if (artifactDirectory.exists()) {
try {"Clearing artifact directory");
} catch (IOException e) {
log.error("Unable to clear artifact directory", e);
} else {"Creating artifact directory");
if (!artifactDirectory.mkdirs())
log.error("Could not create artifact directory");

public void takeScreenshotAndPrintLink(RemoteWebDriver webDriver) {
try {
File screenshotFile = createArtifactOrTempFile("TurboKivaScreenshot", ".png");
Files.write(screenshotFile.toPath(), webDriver.getScreenshotAs(OutputType.BYTES));
if (isTeamCity) {"Writing screenshot: " + screenshotFile.getAbsolutePath());
System.out.printf("##teamcity[testMetadata type='image' value='%s']%n",
} else {
log.error("See screenshot of failure: " + screenshotFile.toURI());
} catch (Exception e) {

private File createArtifactOrTempFile(String prefix, String suffix) throws IOException {
if (isTeamCity) {
return File.createTempFile(prefix, suffix, artifactDirectory);
} else {
return File.createTempFile(prefix, suffix);

I also use a TestNG TestListener to get a screenshot of every failure:

public class AudoDriverScreenshoter implements ITestListener {
private static final Logger log = LoggerFactory.getLogger(AudoDriverScreenshoter.class);

public void onTestFailure(ITestResult result) {
try {
AutoDriverTest instance = (AutoDriverTest) result.getInstance();
}catch(Exception ex){
log.error("Could not take screenshot of test failure", ex);

Consistent messaging for frontend and backend, including AJAX calls

Providing a consistent look and feel for errors and messages makes for a polished UX and helps with tooling. I consider the following fields as a good base: type, title, description, technical (omitted on prod)

Exposing a similar API for both PHP and JS allow for easy development. A common format for AJAX results can even include messages and integarted with a frontend framework to make it trivial to bubble up actionable errors from the backend without involving matching frontend changes.

Debug tools

I find it helpful to expose a list of environment information on non-prod and for admins on prod. This will make it a lot easier to diagnose issues with environments. This will also drastically reduce a flood of QA tickets when an environment issue arrises. It also lets testers load tickets up with delicious technical details so that engineers can quickly get to the root of a problem without going back and forth with testers.

Some platforms and frameworks already have sophisticated tools built in or tools contributed by the community:

Selenium base test

All my tests need similar functionality so I've written my own base class to provide common functionality. One of the most valuable features is automatically giving each test class a fresh, clean database to execute against.

Another benefit to a common base test is easier access to selenium. Because of the consistent messeging, its easy to trigger a test failure if ERROR messages are detected at the end of any test.

IDEA integration

IDEA provides excellent code navigation between tests. Maximizing these features requires properly configuring IDEA. Once configured, it's trivial to run a single test, navigate between tests, and to re-run failed tests.

Hyperlinks that authenticate

When a test fails, the next case is almost always to attempt to reproduce. To speed up reproduction, print a link that instantly logs into the application with the test user with the existing test data. This makes logging in even easier than using a password manager.

Here you can see a log entry "Homepage (logged in)" that opens a browser to the account for this test case. When a failure occures, you can use this link to jump right into where it failed to see where things went wrong.

Here we have a link that logs directly into the admin dashboard and other services like VNC into Selenium:


Investing time into error handling and messaging to enable better visibility when things go wrong and enable quick code navigation pays off dividends over the life of a project.

Monday June 22 2020 @ 12:59 AM

I posted this article a while back on another blog. It has since been removed so I'm reproducing it here. Enjoy!



There are few reasons to switch from MBR on BIOS to GPT on UEFI, but some like adventure. Current OS and motherboard support is quite inconsistent and not well documented. If you first installed on the former and want to switch to the latter without having to lose all your data or re-install Windows, then this is your guide.

The basic idea is to backup the current install to a disk image, erase the disk, then reload the backup. Windows ships with a disk imaging tool and an image restore tool. Unfortunately the restore tool (wbadmin) requires the target partition to be at least the same size as the original backup, so we have to use another method for restore.

WARNING: You may lose all the data on your disk during this process. Make sure to back up your data!


  • A UEFI motherboard
  • A copy of Windows 7 64bit installed to a local disk partitioned using MBR
  • Windows install media (DVD, Hard disk, USB stick)
  • Backup destination with enough space to hold a copy of your existing Windows install
  • Sufficient free space on the Windows partition; the new partition will be about a gigabyte larger.


  1. Backup your Windows installation and all other partitions on the physical disk to another physical disk. This backup can be done using the built-in image tool found within the control panel under “Backup and Restore” behind the “Create a system image” link. NOTE: The rest of this guide will assume just one partition to be restored.
  2. Reboot the computer to a Windows install disk.
  3. Open the command prompt
    1. press Shift + F10 at the “Install Windows” window.
  4. Repartition the disk
    1. diskpart
    2. list disk
    3. select disk x (where x is the number of the disk to convert)
    4. WARNING: This is your last chance to go back!
    5. clean
    6. convert gpt
    7. create partition ESP size=128
    8. format fs=fat32 quick
    9. assign letter=i or any other free drive letter
    10. create partition MSR size=128
    11. create partition primary
    12. format fs=ntfs label="Windows" quick
    13. active
    14. assign letter=y or any other free drive letter
    15. exit
  5. Mount the backup VHD
    1. diskpart
    2. select vdisk file=filename.vhd where filename.vhd is your disk backup
    3. attach vdisk
    4. assign letter=z or any other free drive letter for your new partition
    5. exit
  6. Restore the files from the image
    1. z: (where z is the letter of your VHD)
    2. xcopy * y:\ /e /c /h /k /o /b /q /y (where d is the letter of your new partition)
      1. e = copy all subdirectories even if they are empty
      2. c = ignore errors
      3. h = copy hidden and system files
      4. k = retain readonly flag
      5. o = copy file ownership
      6. b = copy links as links
      7. q = quiet mode (should speed things up)
      8. y = always respond with yes instead of prompting
    3. Wait for the copy to complete. Commenter Niko has an excellent point here: There may be permission errors which you can probably ignore. These are likely for special system folders like "System Volume Information". Turn off quiet mode to be sure or if the process doesn't work and you want to verify this isn't the cause.
  7. Copy EFI bootloader to ESP partition
    1. i: (where z is the letter of your ESP partition)
    2. mkdir EFI
    3. cd EFI
    4. mkdir Boot
    5. mkdir Microsoft
    6. cd Microsoft
    7. mkdir Boot
    8. copy x:\Windows\Boot\EFI\bootmgfw.efi i:\EFI\Microsoft\Boot
    9. copy x:\Windows\Boot\EFI\bootmgfw.efi i:\EFI\Boot\bootx64.efi
  8. Create BCD
    1. This step varies quite a bit, depending on your system’s hardware, existing NVRAM (non-volatile memory on your motherboard), and hidden BCD stores scattered around your system’s disks and partitions.
    2. Cross your fingers and hope that this step can be done automatically
      1. bootrec /RebuildBcd
    3. If things don’t work out, you will have to resort to using bcdedit. A few notes about BCD edit: it operates on the motherboard’s NVRAM unless you specify a file. As far as I can gather, the NVRAM store doesn’t matter as my PC basically ignores any setting within and boots just fine after I’ve erased it.
      1. i:
      2. cd EFI\Microsoft\Boot
      3. bcdedit /createstore BCD
      4. bcdedit /store BCD  /create /d "Windows Boot Manager" {bootmgr}
        1. Commenter Manuel says this should be bcdedit /store BCD /create {bootmgr} /d “Windows Boot Manager” but I haven't tested this. This may depend on the version of BCD edit you are using.
      5. bcdedit /store BCD /create /d “Windows 7” /application osloader
      6. The previous command will return a GUID, referred to later as <guid>
      7. bcdedit /store BCD /set {bootmgr} default <guid>
      8. bcdedit /store BCD /set {bootmgr} path \EFI\Microsoft\Boot\bootmgfw.efi 
      9. bcdedit /store BCD /set {bootmgr} locale en-us
      10. bcdedit /store BCD /set {bootmgr} displayorder {default}
      11. bcdedit /store BCD /set {bootmgr} timeout 10
      12. bcdedit /store BCD /set {default} device partition=c:
      13. bcdedit /store BCD /set {default} osdevice partition=c:
      14. bcdedit /store BCD /set {default} path \windows\system32\winload.efi
      15. bcdedit /store BCD /set {default} systemroot \windows
  9. Change your motherboard firmware to run in UEFI mode
  10. You should now be able to select your Windows disk as your startup disk.

Good luck!

More Reading


Tuesday March 16 2021 @ 5:35 PM

Documented somewhat old profile picture picker that uses face detection:

Updated Tune Controller:

Updated NoiseCaster

Tuesday September 17 2019 @ 3:13 PM

In December of 2018, I reported to WinRAR that the trial was displaying an ActiveX warning:

WinRAR showing ActiveX warning

Their response, in it's entirety sans boilerplate footer:


I have forwarded your e-mail to a responsible person.

The best way to get off such requester is to buy WinRAR.

Otherwise please uninstall WinRAR. 


As of September 2019, it is still happehing. I reached out to WinRAR support again. Their reply:

I guess you have changed the Internet Explorer Options for security to very high.

Please change it back to default value - or allow ActiveX.

Tuesday December 31 2019 @ 2:04 PM

I made a few menu extras for macOS to control iTunes and my Integra preamplifier. Enjoy!

Tune Controller

Onkyo Remote


Monday April 30 2018 @ 4:38 PM


I wanted to setup remote access to my LAN from outside my home through my pfsense router running on a Zotac CI323 nano. I thought "Hey, this is the most common use case for VPN, it should be easy!".

After hours of fuddling with IPSec and windows giving vague useless errors, I decided to give OpenVPN a shot.

I used the pfsense built-in wizard and the addon package openvpn-client-export along with one of the numerous how-to guides.

I setup for a route to be pushed on the server:

I turned on float for the clients:

Finally the VPN connection that connected (the tray icon turned green and the log showed no errors) but connecting to devices within the LAN didn't work (although connecting to the router worked fine). I thought "At least the hard part, authentication, was out of the way".


Fortunately, my neighbor let me use her Wi-Fi to troubleshoot my connection. I already gave up getting another IP from my ISP since they required I convert to a commercial account and using my mobile phone as a Wi-Fi hotspot was out of the question since family is grandfathered into a cheaper unlimited data plan which I could not break out of unless I signed up for my own line at $80 a month. Of course it was fun explaining to the ISP tech support rep how my switch did not have a WAN port, what the difference between a hub and a switch is, and explaining to the mobile phone carrier that 3mbps means megabit not megabyte (and that megabyte is no longer 1024 based, hello mebibit)


You can use Wireshark to verify which machines are receiving which packets.

To start, I started pinging my main machine from my laptop:

Start Wireshark, select the appropriate interface, start capturing, and add a filter 'icmp' to show only the ping packets.

Here we can see that my Mac was not returning replies. I found this curious, if it received the request, where was the reply? You can verify what the router is receiving by capturing its packets.

On pfsense you can use the built-in packet capture tool based on tcpdump. Make sure to select the appropriate interface and filter to ICMP packets.

In my case, pfsense confirmed no replies were being sent. As it turns out, if no route exists to a destination, no packet is sent. This can be further diagnosed using a traceroute:


traceroute -d


To view a list of all static routes on a system


route print


netstat -nr

We can solve this problem by adding a static route:


sudo route -n add

But this is unsustainable as we would need to add this route to every machine in the LAN. Another option is a DHCP classless static lease.

Static routes over DHCP

You can enter a classless static route into the DHCP options in pfsense under the DHCP server menu using an option number of 121.

The classless static routes have a really screwy format entered as:


In my case of with a subnet mask of and a gateway of I get (in decimal) 24:10:0:8:10:0:0:1 (notice the missing trailing 0 from which in hex is 18:0A:00:08:0A:00:00:01

Be careful setting up a classless static route because Windows will silently refuse to take a DHCP lease if it's not perfectly formatted.

You can debug this situation by trying to manually renew and you will get this output showing invalid data:

To view static routes on MacOS coming from DHCP discovery response:

ipconfig getpacket `en1`

In my case, my Mac has a static lease which doesn't get the special bits from pfsense so I'm sticking with the manually added static route.

Even after all that, my Mac could still not ping my Windows machine connected through the VPN. It turns out Windows Firewall was on! I didn't want to turn off the firewall for public networks where I'm connecting to the VPN from so I needed to get Windows to treat the VPN as a 'private' network. This is not an easy task with the Home version of Windows 10 that came on my laptop. I finally found this exhaustive guide to changing the network location which had the key PowerShell command (make sure to run as Administrator):


(For demonstration purposes only; in this example it shows my home Wi-Fi which is already private)

In the end, I was finally able to connect both ways through the VPN.

Monday July 10 2017 @ 8:30 PM

This is the third rewrite of my site, and it has been 15 years since the last rewrite. It has also been many years since I posted, mostly because I post my ramblings on facebook now.

Monday May 9 2011 @ 8:57 PM

Otherwise unmarked; ATT, you almost tricked me!

Almost tricked again!

I would be terribly surprised if the answer was not "pay us more money!"

Tuesday January 25 2011 @ 8:41 PM

It's here!

Tuesday February 23 2010 @ 6:14 PM

Some background: My primary checking account, which I opened 10 years ago in Cleveland Ohio, is with National City bank. National City bank was relatively recently acquired by PNC bank. As I have gone to various universities in Ohio and not yet settled at a new semi-permanent address, I still have all my statements go to my parents house in Cleveland.

Two or so months ago PNC sent all their newly acquired customers a letter in the mail enumerating how fantastic PNC is, how much their new customers are going to love PNC, how smooth and seamless the transition is going to be, and how uniquely fantastic their customer service is.

For the past month or so my local National City branch in Columbus Ohio has had National City banners no-doubt covering up PNC signs where National City signs used to be.

This past weekend, I saw on the local news how they were closing all the National City branches in Columbus and opening on Monday as PNC branches.

I went to deposit a check on Monday February 22nd. Normally I would use the ATM but I decided to go inside to clarify how my account was going to change/has changed. I gave the teller my endorsed check. She asked for my PNC card. I handed her my National City card. She said “this isn’t a PNC card” and I confirmed, “yes, correct” as I recalled the letter they had sent me and imagining what was about to ensue. She asked for my SSN and typed some stuff into her computer and said “your account hasn’t been converted yet and you wont be able to deposit your check here. You will have to use an ATM.” When I asked why they couldn’t run both National City and PNC software on their computers, the teller’s manager responded “the applications are too large to run more than one on the computer at a time.” Ignoring how much of a complete pile of bullshit that was (dumb terminal emulator’s don’t use much memory), A “seamless transition” would have them using 2 computers, one for converted accounts and one for unconverted. I was then informed that accounts in from north Ohio have not yet been transfered to PNC and that they wont transfer for another two months.

This situation is both foreseeable and expected. The Ohio State University draws students from all over Ohio, including northern Ohio and many of those students no doubt have National City accounts. Not to mention simple data-mining would have easily exposed that the address I have statements to is two hours away from the ATM where I deposit all my checks. Considering the letter PNC sent regarding the seamless transition, PNC’s sham is quite transparent.

Before I left the branch, I asked for a customer service number to report my issues to. The representative I spoke with gave me more excuses, was completely uninterested in my problems, refused to report my problems, and ended the call by essentially saying ‘since I can’t help you, I’m going to end this call’. Again, considering the letter PNC sent regarding their extraordinary customer service, PNC is quite obviously full of crap.

At this point I was considering switching banks. I head across the street to Chase. In the past I had regularly received cash incentive offers from chase to open a checking account. I asked the woman helping me if I could take advantage of a similar offer without having the actual junk mail with the offering on it, and she said I would have to have the letter.

Apparently Chase doesn’t offer a free checking account. Their cheapest account has a six dollar a month fee. She insisted that their great debit card offering and fantastic free savings account would make up for the fee. The savings account had a remarkably low 0.05 APY, which is a slap in the face. The debit card itself had an annual fee of 25 dollars, and the rewards associated with it were in ‘points’. Realizing the points were just a trick to confuse potential customers, I confronted her about it. She claimed that everyone she has ever spoken with has had no trouble fully understanding how the points work. The card gives 10 + (1.1 * dollars) per purchase back in points. Of course it isn’t explained so eloquently on their marketing material.

I asked her what the point-to-cash conversion rate was. Her response was that there was no conversion rate. I asked her if one could redeem points for cash and she said one could. I again asked her what the conversion rate was. She reiterated that there is no rate. I asked her how much cash one would receive if one decided to redeem one’s points for cash. She explained that would depend on how many points one had. Well no shit. I called her out on it and asked her to just explain how it would work with 1000 points. She then said it depends on if one redeems the points for a gift card or cash. At this point I started to lose it. I said obviously were talking about the cash redemption here. She then said she doesn’t know what the conversion rate was and that there was no way for her to find out. We, together, couldn’t even figure it out on the redemption website.

After doing some quick mental math by estimating, I told her to get what I have with National City with Chase I would be spending eight dollars a month. She gave me this look like I was exaggerating and was well over what I would actually be paying and then pulled out a calculator and calculated the actual cost per month and in an accusatory tone told me $8.08. Are you kidding me?

I honestly don’t understand how chase can have a single satisfied customer.

Moving on to the only remaining bank in the area, Huntington. Based on the specifications of the National City account I currently had, and what the Chase respective had told me, I drilled the Huntington representative on their specifics. During which she insinuated that I was nit-picking and purposefully wasting her time. I would not have to be as nit-picky if their offerings weren’t designed to tick and confuse customers in an effort to extort as many hidden fees as they could. To win my business she offered to give me a free half-order of checks. When I asked her how many boxes/books/checks a half-order consisted of, she again claimed I was nit-picking. Excuse me for requiring quantifiable terms.

How absolutely frustrating.

Wednesday January 27 2010 @ 10:34 PM

It was Thomas Jefferson who called for "A wise and frugal Government which shall leave men free to regulate their own pursuits of industry ....and shall not take from the mouth of labor the bread it has earned..." He was right.

Prove it.

The circumstances of our time demand that we reconsider and restore the proper, limited role of government at every level.

Limited government doesn't work. Without regulation, Selfish jerks suppress everyone they can.

But most Americans do not want to turn over the best medical care system in the world to the federal government.

Best by what metric? Cost? No. IMR? No. Life expectancy? No. Coverage? No. A direct relationship between wealth and care? Yes!

we welcome your ideas on Facebook and Twitter.


We are blessed here in America with vast natural resources, and we must use them all.

What the fuck?

A child's educational opportunity should be determined by her intellect and work ethic, not by her zip code.

You forgot their parents wealth.

As Senator-elect Scott Brown says, we should be spending taxpayer dollars to defeat terrorists, not to protect them.

That's so un-American I can't even comment.

Here at home government must help foster a society in which all our people can use their God-given talents in liberty to pursue the American Dream. Republicans know that government cannot guarantee individual outcomes, but we strongly believe that it must guarantee equality of opportunity for all.

The first sentence contradicts the second.

Over-regulating employers won't create more employment; overtaxing investors won't foster more investment.

However not regulating or taxing does foster corruption!

The Scriptures say[...]

What some work of fiction says should have nothing to do with our government.

America must always be a land where liberty and property are valued and respected, and innocent human life is protected.

This further contradicts Senator Brown's statement.

Where opportunity is unequal, we must make it open to everyone.

Continued contradiction.

Monday October 5 2009 @ 7:52 PM

Sending DatagramPackets in Java will throw a Message too long.

Seems the maximum message size on Windows is (64KiB -28B) = 65508 (I have no idea where that 28 came from) and on MacOSX (at least on 10.5.8 on my MacPro) is 9KiB (9216B). These were determined from incrementing the size of the message from 1 until the IOException was thrown. The big surprise is when you develop on a Windows box and you run your app on a Mac and the DataGramPackets never arrive.

Monday October 5 2009 @ 7:42 PM

Who would have thought? Use a RandomAccessFile instead! =)

Notice to Sun (Oracle?): It would be cool if this were not only mentioned in the documentation but very clear, as it has potential for data loss, and in my case would have saved me a lot of time.

Thursday August 6 2009 @ 1:12 AM

So GE contracts out their consumer electronics to some other company but still sticks their logo on them. What's cool about this is that it's nearly impossible to find a manual! I have a 'GE' alarm clock and I was looking for the manual. Google was no help. GE's consumer electronics page doesn't list anything about alarm clocks! The bottom of the alarm clock says 'Thomson Multimedia Inc' which google doesn't like either.

GE's consumer phone section links to (god I hate that domain) which sounds promising and here's where the sleuthing comes in. If you that URL back to 2003ish you get a really well written language selection drop down which doesn't like. Dicking around with the URL and you can eventually get to an english page where you can follow links to alarm clocks and then GET THE PDF!

GE 7-4853c Manual

Thanks for making things so easy for your customers GE!

The combination of features that make this alarm clock better than all others is:

  • Dual alarm
  • Custom timed Nap mode
  • Custom snooze time
  • Big dim (in the dark) light sensitive display
  • Easy alarm and clock set via switch instead of holding buttons
  • Set time via back and forward (gets really fast if you hold it down long) instead of lame minute/hour buttons
What it's missing:
  • Custom alarm duration