macOS “Optimized Battery Charging” in Windows 10 / Boot Camp causes MacBook Pro battery to not charge

On a MacBook Pro 16-inch 2019 (Intel), under macOS Ventura 13.1, if

  • the “Optimized Battery Charging” option is turned on in System Settings -> Battery
  • the power adapter is plugged in
  • the battery has charged to 80% or more under macOS
  • the machine is then rebooted into Windows 10, using Boot Camp
  • then: in Windows, the battery will not charge at all. Windows will report the battery as “Plugged in” but the battery will not charge. The battery will slowly drain to 0% as the machine is used.


Disable Optimized Battery Charging temporarily or permanently before rebooting into Windows 10 under Boot Camp, in System Settings -> Battery -> Battery Health -> Info disclosure


Optimized Battery Charging is a new feature introduced in recent macOS versions to preserve the health of Intel MacBook Pro batteries. It is known that if a laptop is not being used on battery, then it is best to charge to 80% instead of full. macOS purports to learn its user’s laptop battery usage patterns, and will charge the battery to 80% under normal adapter usage, and only begins charging to full when it expects the user to go to battery power soon.

However, it seems to do this by instructing some SMC/firmware level controller to stop charging the battery once current capacity hits 80% or more. When rebooted into Windows 10, which does not understand this optimized charging feature, there is no corresponding instruction to begin charging the battery again when the capacity falls below 80%. The consequence is that the laptop battery will steadily drain to 0%, and nothing will make it charge again until the machine is rebooted back into macOS.

This is an understandable edge case that Apple engineers didn’t test for. However, it seems to have started only recently (I don’t recall macOS Monterey having this behavior). Until it is fixed, if regular Windows 10 / Boot Camp usage is expected, it is best to leave the Optimized Battery Charging feature turned off on the macOS side — temporarily or permanently.

Worth noting that there are multiple other possible reasons that Windows 10 / Boot Camp is causing battery drain on a MacBook Pro. For example, the 16-inch 2019 MBP’s white 96W USB-C charger looks identical to the 87W USB-C charger from previous-gen MacBook Pro 15. If mistakenly or deliberately used to power the 16-inch MBP, then under full load the 87W adapter is insufficient to run the laptop. In this scenario the OS will tap the battery in complement with the adapter, causing a steady drain. Windows also runs more inefficiently than macOS on MacBook Pro, so under full CPU/GPU usage, it seems to take more power sometimes than even the 96W adapter can provide.

However, in either of those cases, the drain is very slow. In the case of the Optimized Battery Charging bug described above, under full CPU/GPU usage, the battery drains extremely quickly, with 30 minutes of usage causing 50% or more battery drain sometimes. This is because in this case, the laptop is not drawing power from the adapter at all.

IKEv2 VPN on Ubuntu – IKE authentication credentials are unacceptable

I used these straightforward strongswan IKEv2 VPN setup instructions to set up a IKEv2 VPN on my Ubuntu server.

However, instead of self-generating my own certificate authority and having to deal with manually trusting this untrusted CA on every device I have to use VPN on, I decided that since I had letsencrypt in standalone mode set up on my server already (and the vpn subdomain properly covered under the certificate), I might as well use that certificate instead. I’m sure I’m committing half a dozen security sins, but it saves me time that I used to spend googling “how to trust certificate authority on [device name]”.

Setting up letsencrypt certificates with strongswan-based VPN is out of scope for this post, but in short, the difference is minimal. Instead of using the fake CA’s .pem, just symlink the letsencrypt certificate and key to /etc/ipsec.d/certs and /etc/ipsec.d/private. Remember to add a post_hook to /etc/letsencrypt/renewal/ to reboot strongswan after certificate renewal.

This worked great on macOS High Sierra and iOS 11. However, Windows 10 (Fall Creators) refused to connect to the VPN, stating that “IKE authentication credentials are unacceptable”.

The top google results for this were highly misleading for this particular context. It’s not about subjectAltName or Server Authentication flags or whatever.

It turns out that unlike macOS or iOS, Windows 10 wasn’t processing the full set of root and intermediate CA certificates, even though I symlinked the fullchain.pem to /etc/ipsec.d/certs. After throwing a symlink from /etc/letsencrypt/live/[domain]/chain.pem to /etc/ipsec.d/cacerts, Windows finally relented and let me connect to the VPN.

YMMV, because judging by the Google results, there are a lot of sources of error that yield the exact same, mildly useless “IKE authentication credentials are unacceptable” error message. However, this particular error is non-obvious, and worth looking at if you’re running into the same issue.

Setting up OpenSSH Server on Windows 10 Anniversary Update

UPDATE 2017-12-22

Microsoft now ships a real SSH server (and client!) with Windows Fall Creators Update, no Cygwin or Linux subsystem required. Finally.

This post remains for historical context only.

Microsoft has finally landed its anniversary update for Windows 10. Among all the random useless features, is an actual Ubuntu Linux subsystem within Windows, with the ridiculously silly name “Bash on Ubuntu on Windows”. Goodbye Cygwin?

One of the first things I wanted to try was to setup the SSH server, so I can remote-login from my real box. Getting one up was actually fairly easy, if you can deal with a few problems with weird, weird red-herring error messages.

The problem

To recap, installing the OpenSSH server is as easy as popping open a bash shell (I assume you figured out how to get the Linux subsystem installed already and popped open Ubuntu )

sudo apt-get install openssh-server

If you try to now start the server with

sudo service ssh start

It’ll respond with

initctl: Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/upstart: Connection refused

but subsequently

Starting OpenBSD Secure Shell server sshd [OK]

When you now try to connect in from a remote host, there are two outcomes:

  1. There is no SSH server on port 22.
  2. There is an SSH server on port 22, but it responds only to your Windows password and not your Ubuntu Linux user password. If login is successful, it drops you into a DOS prompt instead of a bash prompt. Trying to run bash within the prompt generates a response:
    "Error: 0x80070005".


There are multiple underlying problems here.

  1. First, it’s important to note that there exists a separate Windows SSH server (separate from the OpenSSH server from the Ubuntu subsystem installation) now on port 22. If you telnet (yes, telnet) into port 22, and the host greeting is SSH-2.0-MS_1.100, you’ve run into the Microsoft SSH implementation (hence the MS part in the greeting).

    I’m not sure what this server is supposed to do (and, in fact, starting SSH servers on standard ports without explicitly telling the user seems like a potential security problem to me, in addition to being kind of jerk-ish). I do know it is launched when you reboot with Developer Mode on. You know, Developer Mode, the mode you have to turn on to run Bash on Ubuntu on Windows. This server is occupying port 22, so you cannot launch another SSH server to listen on this port. This is the problem that is causing the silent failure of sshd to start up, not a broken Upstart or any of that nonsense the error message being displayed is referring to.

  2. Apparently the Ubuntu compatibility layer on Windows does not implement chroot or one of the related system calls needed for OpenSSH privilege separation at the time of this post.
  3. If you launched bash from DOS cmd.exe, instead of the Bash on Ubuntu on Windows shortcut, /mnt/c/Users/[Windows Username] (the directory you start with in DOS) is not your Linux home directory. .ssh config files left in this directory will not configure your OpenSSH server.

Symptoms & Solutions

  1. To resolve the problem of conflicting SSH servers, set your OpenSSH server on a different port : one other than 22. This can be done by editing /etc/ssh/sshd_config and changing the Port configuration. Be sure to open this new port in your Windows Firewall for inbound connections, as this firewall configuration will not be automatically done for you. I set mine to 60022.
  2. To enable login, also change UsePrivilegeSeparation in the same config file to No. Failure to do so will cause the server to respond with Connection reset by nnn.nnn.nnn.nnn
  3. To enable public key auth and set other configurations, the Linux subsystem home directory is, as in normal Ubuntu, /home/<yourname>.

Having done this, now you can start or restart in the bash shell

sudo service ssh restart

And connect from remote host with your Ubuntu user credentials and/or public key:
$ ssh -p 60022
Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 3.4.0+ x86_64)

(And if you telnet, the host message should be something like
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.7

Processing monitoring and Settlers of Catan save failure

process monitor finding Catan issues
Some versions of Bigfish Games’ Settlers of Catan (a faithful reproduction of the board game) have a strange issue, in which under certain operating contexts, it will not save a game. The error message reported is a generic and not-at-all useful ” an error has occurred while saving “. I suspected this was due to the fact that it failed to create a savegame directory, and indeed, a bit of sleuthing indicates that on Windows XP, the directory at C:\Documents and Settings\All Users\Application Data\Microsoft\MSN Games\Catan is missing (obviously on Vista, this would be somewhere else – probably C:\Users\…). Instead of creating this directory, Catan simply fails to save the game. The program runs fine otherwise.

Of course, it was not obvious where Catan was trying to save its games – finding out that missing directory was the culprit took a bit of investigation. I took a wild stab at the start by creating a “save” directory in its own program files directory. No such luck. Time to bring out the big guns.

A number of ways could have been used, but one is to use the awesome Sysinternals tool Process Monitor, or Procmon.exe. It tracks events and calls from a process, such as filesystem accesses, and has advanced filtering capability to organize and show only the events of interest to a debugging human.

With ProcMon, I simply filtered on the Catan process and tried to save a game as foo. Then, viewing the event log (screenshot 1), it was obvious that CreateFile calls to create foo.sav failed, with the exact target path specified. A quick Windows Explorer excursion confirms that the path does not exist. Creating that directory, of course, solved the savegame problem.

The moral of the story is that ProcMon is a fine tool for tracking mysterious interactions between an application and a system. For something like failing to make a saved game (in this narrow gamig context) or various system-related errors in general (especially when you lack the source code to debug in depth), it sometimes pays to examine the exact sequence of calls and events that led up to the failure. The solution could be very trivial, if you only knew what and where things failed.

Baldur’s Gate 1 graphics glitch and disabling NVidia hardware acceleration

If you have a series 8 NVidia graphics card (say, an 8600M GT) with current drivers (as of the time of this post, of course), you’re likely to see graphics glitches (screenshot 1) in Baldur’s Gate 1. One workaround is to use 16-bit color and software transparent BLT. Another strategy, if your CPU is powerful enough to shoulder some 2D graphics work, is to temporarily turn off hardware acceleration for DirectDraw and avoid the bug entirely. black boxes in Baldur's Gate under Nvidia 2D acceleration

However, disabling hardware acceleration under Vista is apparently easier said than done. Instead of using the Personalization -> Display Settings control panel (as one might think to do based on Windows XP experience), the correct solution is to use the DirectX SDK and dxcpl.exe, the DirectX Control Panel (located within the SDK distribution under Utilities\bin\[cpu_arch]\. From within this control panel, pick DirectDraw on the upper tab bar. Amongst the various configuration options available on that tab, the only one you care about is the box to turn on or turn off hardware acceleration. Turn that off (temporarily, of course) and you’re good to go.

The Context

Baldur’s Gate 1 performs surprisingly well under Windows Vista, despite being a venerable (some might say, ‘ancient’) 10-year old RPG. Unfortunately it’s plagued by a number of graphics glitches when running on NVidia cards. In essence, a number of items and sprites (items on the belt, the timepiece to the lower left corner, birds flying overhead, for example) will be surrounded by black outlines. Further, on your character paper doll in the Inventory screen, giant black boxes obscure much of the figure. In some cases, the ‘fog of war’ on the unexplored regions of a map will be rectangular black boxes, rather than the ‘foggy’ darkness you’re used to. These glitches are widely experienced.

For this very annoying problem, two workarounds are available.

1. Trade color depth for correctness

The prevalent strategy, as noted in a forum post at Spellhold Studios, is to switch on Software Transparent BLT and use 16-bit color depth. This apparently routes around whatever strange bug NVidia managed to introduce in their graphics acceleration layer.

This method works just fine, but was not ideal for me. The game runs at 640 x 480, and is already quite pixelated when scaled up to full screen. 16-bit vs 32-bit color is somewhat noticeable, once at that scale.

2. Trade performance for correctness

Here’s another classic trade-off. Since the problem is obviously arising from the DirectX layer and its interaction with NVidia graphics hardware (boot into safe mode and run BG1 to verify this), another solution is to just kick NVidia out of the loop by disabling hardware acceleration for DirectDraw. This is feasible if you’re doing this on a fast machine (and if you’re using a series-8 card in that box, I’d assume it’s pretty fast anyway) – after all, BG1 is a 10-year old game. Your Core 2 Duo or quad-core Xeon can use some exercise anyway.

Of Hardware Acceleration Controls

In the glory days of XP, this simply meant right-click on Desktop -> Properties -> Settings -> Advanced -> Troubleshoot -> Hardware Acceleration slider (dear god that’s convoluted). In Vista, the analogous experience is right-click on Desktop -> Personalize -> Display Settings -> Advanced Settings -> Troubleshoot -> Change Settings (I see you still haven’t hired a good user experience designer, Microsoft).

The problem now is that if you try this with your NVidia card and Vista, you’ll just be staring at a disabled ‘Change Settings’ button and a terse message: 'Your current display driver does not allow changes to be made to hardware acceleration settings.' If you also try the old standby dxdiag, you might be surprised to know that the Disable buttons have been removed from the DirectX Features box on the Display tab. Thanks, NVidia and Microsoft. Apparently they really don’t want us changing these settings.

But we don’t really want to change much – just the DirectX technologies, and in fact, just the 2D-based DirectDraw (since 3D is more or less irrelevant for BG1), and only for a short while. Enter the DirectX SDK.

The SDK is meant for developing and debugging DirectX-based programs, but it comes with a fair suite of nifty utilities, one of which being the DirectX Control Panel: dxcpl.exe. Download the 400+ MB SDK (this is the 2008 version of the SDK — you might look for a newer version if you’re on Win 7; I think the control panel still ships with the latest versions) and grab the control panel in Utilities\bin (starting from where you installed the SDK to). Make sure that if you are on x64 (x86_64) that you also use the x86 architecture control panel for BG1, as it seems to be required to affect 32-bit mode apps (see comments for this post for more details).

In the control panel, use the DirectDraw tab – in the set of checkboxes, uncheck the “Use Hardware Acceleration” box. Fire up BG1 and see the non-black-boxed goodness of 1998 graphics (screenshot 2).
Baldur's Gate playing normally after disabling Nvidia-accelerated DirectDraw
If you were disabling acceleration for another reason, this control panel should work for you too – pick the appropriate tab and have at it. Do not forget to turn acceleration back on after the session. You probably do not want unaccelerated graphics performance in your normal, non-glitchy apps.

Turning off hardware accelerated DirectDraw avoids the BG1 black-box bug. You’ll have to assess for yourself which is more expendable: color depth (trivial to change directly from BG1’s Options configuration) or graphics performance (more difficult to tweak, but perhaps compensated by CPU performance).

DirectX SDK vs Settings slider

In any case, the DirectX control panel is a somewhat useful trick to know in general, especially when faced with Vista’s obstinate insistence on not letting you change graphics acceleration settings. The control panel provides all the functionality that the old XP Settings slider would have give you – except in a much more technical interface. In fact, the old slider more or less tweaked settings in the Direct3D and DirectDraw tabs, except in a coarse-grained, all-or-nothing kind of way. Here at least you have fine-grained control on most of the detailed options in each panel.

Still, such a pain.

Know that tweaking these settings are done at your own risk (NVidia and MS obviously are against it), and may or may not work at all depending on your setup, your driver version, and pure luck. On the plus side, if you ever need to write some DirectX apps, the SDK is now just a few clicks and SDK path text fields away from Visual Studio 2005/2008, so the 400 MB bandwidth and disk space isn’t completely wasted. Hopefully.

UPDATE 9/8/2008
It’s come to my attention that some people still have problems after applying this fix – namely, there are cursor trails on menu screens. I cannot reproduce this issue locally on my 8600M GT, but it’s possible that there are new problems introduced with newer series-8 cards and drivers. If this is the case, I’d recommend using the first workaround — that is, using Software BLT and 16-bit color, rather than the DirectDraw workaround.

UPDATE 7/15/2009
There is now a Nvidia driver .dll patcher available for BG1-era Infinity Engine games at Spellhold Studios. They also explain what the underlying issue is and what the DLL wrapper does to work around the bug. I have not personally tested this fix. It does install a new graphics DLL that overrides existing calls, so it is theoretically possible that it may introduce other issues, but I am told by others that it works quite well. Check it out — it saves you a lot of trouble of ticking DirectDraw boxes on and off, if you don’t mind unofficial DLL patching.

There are still people arriving at this page, 7 years later after the initial post. At this point, you should probably just buy the remastered Baldur’s Gate Enhanced Edition on Steam instead. Much, much less hassle.

Windows IE 6 ignores text/plain mimetype

A fairly border-case scenario that probably rarely comes up, but appears to be another gotcha. So apparently IE 6 for Windows, on occasion, decides it knows better than the web server what format a file is. Instead of using the mimetype supplied by the web server, as all good browsers tend to do, IE performs some heuristics on the file and overrides the mimetype with its own guess. The type text/plain is one such stupid circumstance.

Annoyingly, IE will insist on downloading plaintext files in some cases, instead of rendering it in browser. This usually occurs if a script is attempting to generate a “text/plain” document on the fly, but can also happen under other circumstances if the IE hard-coded heuristics comes up with a different result than the server-proclaimed mimetype.

A client-side workaround for text/plain is possible. You’d need to edit the Windows Registry (oh joy). In HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings, add the DWORD key IsTextPlainHonored and set value to 0x1. This will make IE behave correctly for text/plain mimetypes. This solution comes per the MS Knowledgebase article, “Text/Plain” Content-Type Header Field Is Ignored. There are also some further explanations on how mimetypes are resolved in the MSDN article, on mimetype detection in IE.

Unfortunately, this is not a solution if this behavior comes up in a web-based tool for external use – as every client machine registry will have to be thus modified. This change may also carry security implications (actually, I’m completely guessing here, because I don’t quite see why the IE team decided to “not honor” mimetypes for text/plain…).

The context:

A PHP script in a project I maintain pulls a text file from a remote location, and then prints it to the browser as Content-type: text/plain. A hack to be sure, but simple enough to get the job done. This works out fine in Firefox, etc, but not in Windows IE. IE insists that this is a PHP script file that must be downloaded. Of course, once downloaded, you can fire up Notepad and see that it’s bloody plaintext. Firefox et al will render it in browser as expected.

In this case, the script was only used for internal testing, so I switched all the test machines to honor plaintext mimetypes. A longer term workaround would probably involve porting the output to XML instead.

CVS, Cygwin, and error code 0xc0000022

In short, if your project crashes at library load time after a round trip through CVS, you might want check your NTFS execute permissions on the DLLs that the project depends on. Also, if your application mysteriously blows up with error code 0xc0000022, you’d do well to make sure that:

  • all DLLs that your program depends on are valid and locateable.
  • Check all its DLL dependencies for permission problems. As in, permissions on the DLLs that your program depends on should be set to be executable for your user.

In one of my Windows projects, I wrote some code that relied a number of DLLs. To save myself sometime, I compiled these DLLs and checked in the compiled binaries into the CVS repository.

On another machine, I checked out the project via the cvs utility, under Cygwin, to work on it. As a Unix-y kind of guy, I prefer the tools that I’m used to. Everything compiled fine, but at runtime the application crashes before it gets to main(). ” The application failed to initialize properly (0xc0000022) … ” After some dependency tracking to find out if I lost a DLL somewhere, first via Dependency Walker, then via gflags, nothing unusual turned up.

Then I noticed that replacing the checked out libraries with fresh copies of the same DLLs fixed the issue. The problem was that upon checking md5 sum against the old and new libraries, they were exactly the same. There was no damage or corruption.

Turns out, of course, that Execute permissions were off on all those DLLs that I checked out. Apparently Cygwin’s cvs does not set execute bits on DLL files, and since you’re usually using ntsec settings with Cygwin, this causes a security/permissions problem on the Windows side. As a result, the project compiles just fine, fails at runtime, and gives you a completely obtuse error message that means very little unless you’ve done this sort of thing before. Cygwin and cvs’s role in this was also not a very obvious thing to deduce.

Two hours of my life, right there.

Turning off the Unused Icons Wizard

Having been pestered by the Windows XP Desktop Cleaning Wizard one too many times, I wanted to turn the bloody thing off. Turns out it was under Display -> Desktop tab -> Customize Desktop -> a check box to turn off the wizard.

Interesting that a system maintenance service is actually controlled by a setting in the same tab that sets my Desktop picture – a similar jarring mix of purposes would be rare to find in a Mac system preference panel. I ended up having to Google “unused icons” and “Windows” to find out this little piece of information.

In a timed fire event like this, a logical “opt-out” solution would have been to have the rather intrusive wizard offer an option to deactivate itself – permanently if necessary. Instead, I had to go hunt down the magical control that triggers this wizard once some number of days. This is really poorly designed, but rather symptomatic of typical Windows UIs for preferences.

Without strong cues, users tend to overlook settings that are deeply hidden. A check box on a tab, from a dialog box that is opened by some button, on a tab of a control panel, is already pushing it. Who usually explores beyond what he can skim at a glance from a control panel window? Who actually drills down regularly into all those “Advanced” and “Properties” buttons, which hide dialog boxes, which themselves possess tabs (or, dear god, another “Properties” button that opens up yet another dialog)? The problem is compounded by the fact that there lacks a sufficiently powerful search interface to find the specific setting you want from the operating system.

Conventional wisdom holds that most users never change preferences from their defaults. I keep wondering if it’s that they simply can’t find the damn thing in a reasonable amount of time, or have enough cues to know that these things can be changed. The Desktop Cleaning Wizard certainly never hinted that its presence can be made to go away. If I were a less motivated user, I’d probably settle for ignoring the notification until it goes away on its own.