I have a Windows VM that can has an internet connection that acts as a tunnel into a VPN, and this VM is supposed to share this internet connection with the host. This works perfectly in principle: On that Windows VM, I have a network interface named `Outbound` which represents the VPN connection, and an interface named `Gateway` which represents the connection that is shared with the host. I use Windows Internet Connection Sharing (ICS) to provide routing to the `Gateway` interface via `Outbound`. For reasons unknown to me, however, this sometimes just breaks and the only way to get it running again is to simply disable ICS on the `Outbound` interface and re-enable it. Doing this through the UI every time became annoying, so I researched how to do it programmatically. There is [a great superuser answer](https://superuser.com/a/649183/222330) which provides _almost_ all the details you need, but not quite. <a href="https://blag.nullteilerfrei.de/2024/06/26/programmatic-internet-connection-sharing/#more-5917" class="more-link">Do you want to know more?</a>


I was writing some Python code that uses [ctypes][] for interfacing with the [Windows ToolHelp API](https://docs.microsoft.com/en-us/windows/win32/api/_toolhelp/). Specifically, I had to [define a Python equivalent][structs] for the [PROCESSENTRY32](https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/ns-tlhelp32-processentry32) struct. Now, the [ctypes][] [struct definitions][structs] are a little annoying because they do not give you type hints. You can add the type hints _on top_ of the `_fields_` attribute but that looks a little silly because you _literally_ [write everything twice][wet]. In Python 3.7+ ((Starting in Python 3.7, dictionaries keep the insertion order.)), you can solve this using a metaclass, and one stigma of metaclasses is that they have very few applications, so I decided to blog about this one: ```python class FieldsFromTypeHints(type(ctypes.Structure)): def __new__(cls, name, bases, namespace): from typing import get_type_hints class AnnotationDummy: __annotations__ = namespace.get('__annotations__', {}) annotations = get_type_hints(AnnotationDummy) namespace['_fields_'] = list(annotations.items()) return type(ctypes.Structure).__new__(cls, name, bases, namespace) ``` and now you can write: ```python class PROCESSENTRY32(ctypes.Structure, metaclass=FieldsFromTypeHints): dwSize : ctypes.c_uint32 cntUsage : ctypes.c_uint32 th32ProcessID : ctypes.c_uint32 th32DefaultHeapID : ctypes.POINTER(ctypes.c_ulong) th32ModuleID : ctypes.c_uint32 cntThreads : ctypes.c_uint32 th32ParentProcessID : ctypes.c_uint32 pcPriClassBase : ctypes.c_long dwFlags : ctypes.c_uint32 szExeFile : ctypes.c_char * 260 ``` The metaclass simply deduces the `_fields_` attribute of the new class for you before the class is _even created_. It might make sense to think of metaclasses as "class creation hooks", i.e. you get to modify what you have written before the class is actually being defined. The following bit is just to be compatible with [PEP-563](https://www.python.org/dev/peps/pep-0563/): ```python from typing import get_type_hints class AnnotationDummy: __annotations__ = namespace.get('__annotations__', {}) annotations = get_type_hints(AnnotationDummy) ``` And then, the following is the actual magic line: ```python namespace['_fields_'] = list(annotations.items()) ``` This adds the attribute `_fields_` before the class is created. [ctypes]: https://docs.python.org/3/library/ctypes.html [structs]: https://docs.python.org/3/library/ctypes.html#structures-and-unions [wet]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself <a href="https://blag.nullteilerfrei.de/2021/06/20/prettier-struct-definitions-for-python-ctypes/#more-5700" class="more-link">Do you want to know what I was coding?</a>


Do you ... analyze a lot of malware? Dynamically, too? Or do you just want to launch suspended processes? Well either way, although this is really easy to do, my intense web research did not yield satisfactory results. So here you go, this will just take the entire command line that is passed to it and execute it as a new, suspended process: ``` #include <Windows.h> #include <Shlwapi.h> BOOL ChrIsWhiteSpace(WCHAR x) { return x == 32 || (x >= 9 && x <= 13); } int WinMainCRTStartup() { int ArgCount = 0; WCHAR* CommandLine = GetCommandLineW(); WCHAR** ArgList = CommandLineToArgvW(CommandLine, &ArgCount); if (ArgList && ArgCount > 1) { WCHAR* PtrRest = StrStrW(CommandLine, ArgList[1]); if (PtrRest) { STARTUPINFOW StartupInfo; PROCESS_INFORMATION ProcessInfo; while (!ChrIsWhiteSpace(*PtrRest)) PtrRest--; GetStartupInfoW(&StartupInfo); CreateProcessW( NULL, ++PtrRest, NULL, NULL, FALSE, CREATE_SUSPENDED | INHERIT_PARENT_AFFINITY | DETACHED_PROCESS | CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &StartupInfo, &ProcessInfo ); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); } LocalFree(ArgList); } ExitProcess(0); } ``` <a href="https://blag.nullteilerfrei.de/2019/05/01/launch-process-suspended/#more-4712" class="more-link">Do you want the Base64 encoded binary?</a>


I have finally solved an annoying problem with my Windows 10 setup which was sortof hard to Google, so I am sharing. For quite some time, the computer had refused to go to sleep when it was not running on battery. Instead of going to sleep when instructed to, it would simply turn off the screen and mute the volume while continuing to *actually not sleep*. Moving the mouse a tiny bit would swiftly end the charade. In a recent fit of rage I decided to inspect the event log, and behold, there were some Kernel Power events that said: > _The system is entering Away Mode._ Which is entirely _not_ what I wanted when I told it to go to sleep. However, there was no option _anywhere_ in the power settings to be found that turned off this _"Away Mode"_. Well, the option actually does exist, but for some reason it is not visible unless you set the `Attributes` value to `2` in the following, easily memorable registry key: ``` HKLM\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\238C9FA8-0AAD-41ED-83F4-97BE242C8F20\25DFA149-5DD1-4736-B5AB-E8A37B5B8187 ``` Armed with this registry tweak, you can go back to the _"advanced"_ power settings, aka: ``` rundll32 shell32.dll,Control_RunDLL PowerCfg.cpl @0,/editplan: ``` Navigate to `Sleep` and there should be an option that says `Allow Away Mode Policy` or something similar. And that policy should be set to no, not even when plugged in, never, just sleep, for crying out loud, why does this even exist.


To reduce the size of some of my virtual machines, I often run the Windows cleanup tool to get rid of update artifacts and temporary files. While the `cleanmgr` command has some undocumented options such as `/setup`, `/autoclean` and `/verylowdisk`, I could not achive what I wanted with any combination of these: I wanted to have one command that simply cleans _everything_ without interaction. TL;DR: Put this in a batch file: ```dos @echo off set rootkey=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches for /f "tokens=*" %%K in ('reg query %rootkey%') do >NUL REG add "%%K" /v StateFlags0000 /t REG_DWORD /d 2 /f cleanmgr /sagerun:0 ``` Essentially, this script manually creates the registry keys that would be created by a call to `cleanmgr /sageset:0` and checking all the boxes. It then runs `cleanmgr /sagerun:0` which non-interactively calls `cleanmgr` performing every cleanup task available. Remember to run this as an administrator to remove Windows update artifacts. <a href="https://blag.nullteilerfrei.de/2018/08/10/cleaning-up-windows-without-interaction/#more-4583" class="more-link">Would you like to have that as PowerShell?</a>


I am writing a backup script which is supposed to backup data to a remote server, encrypted, and run as a scheduled task on a Windows machine. If you want all of that, you will have to store the encryption key somewhere. Instead of storing the password in plaintext, I had the idea to use the [Data Protection API]. Initially worried that I might have to write a wrapper for [CryptProtectData] myself, I quickly found the decent looking github project [DPAPIbridge]. Ultimately however, I figured out that Powershell can do all things. Presenting `vault.ps1`: ```powershell Param( [string] $StoreSecret, [Parameter(Mandatory=$True,Position=0)] [string] $filename ) [void] [Reflection.Assembly]::LoadWithPartialName("System.Security") $scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser if ($StoreSecret -eq "") { $data = Get-Content $filename $ciphertext = [System.Convert]::FromBase64String($data) $plaintext = [System.Security.Cryptography.ProtectedData]::Unprotect( $ciphertext, $null, $scope ) [System.Text.UTF8Encoding]::UTF8.GetString($plaintext) } else { $plaintext = [System.Text.UTF8Encoding]::UTF8.GetBytes($StoreSecret) $ciphertext = [System.Security.Cryptography.ProtectedData]::Protect( $plaintext, $null, $scope ) [System.Convert]::ToBase64String($ciphertext) > $filename } ``` This script can be run as `vault.ps1 [-StoreSecret SECRET] FILE`. If the optional argument is present, it will store a protected blob containing `SECRET` in `FILE`, otherwise it will read a blob of protected data from `FILE` and print the enclosed secret string. [DPAPIbridge]: https://github.com/vincepare/DPAPIbridge [Data Protection API]: https://msdn.microsoft.com/en-us/library/ms995355.aspx [CryptProtectData]: https://msdn.microsoft.com/de-de/library/windows/desktop/aa380261(v=vs.85).aspx [Borg]: https://borgbackup.readthedocs.io/en/1.1.2/usage/general.html?highlight=borg_passcommand#environment-variables


I am quite unsatisfied with the current state of full disk encryption solutions available for use with Windows 10 on a Laptop with SSD. This blag post will mirror some of what [Bruce Schneier already said on the matter][Schneier2]: I will discuss some of the options and point out problems. I am not offering a solution, just a variety of bad choices to pick from. [Schneier2]: https://www.schneier.com/blog/archives/2015/06/encrypting_wind.html <a href="https://blag.nullteilerfrei.de/2017/12/23/the-full-disk-encryption-dilemma-for-windows-10/#more-4393" class="more-link">Do you want to know more?</a>


So you develop in [Microsoft Visual Studio Community Edition](https://www.visualstudio.com/de/vs/community/) and you long for the old days when there was a way to get the [MSDN Library](https://msdn.microsoft.com/en-us/library/) as an offline help file? Fear not, you still can. Open Visual Studio, type `Ctrl`+`Q` to open the quick access bar, usually located in the upper right corner of your interface. Enter `Help Viewer`, it should yield one result by that name, marked as an *"individual component"*. Selecting that entry should allow you to download and install the Help Viewer. Now relaunch Visual Studio and start the Help Viewer via quick access in the same way. You will be prompted whether you want to download some *content* - and I bet you do.


Part of me wants to write about all the [horror](https://www.bleepingcomputer.com/news/security/ten-malicious-libraries-found-on-pypi-python-package-index/) and [glory](https://crates.io) there is to be seen in package management, but quite frankly it'll take too long. Instead, I will just leave you with a tiny piece of advice. Here comes. If you are on Windows and you want to install a *legitimate* Python package (like for example [PyCryptodome](https://pypi.python.org/pypi/pycryptodome), because naturally you are **fully aware** that [PyCrypto is dead](https://github.com/dlitz/pycrypto/issues/173).), which in reality is a bottomless pit, at the center of which there is a C library, straight from hell - then maybe get the [Microsoft Compiler for Python](http://www.microsoft.com/en-us/download/details.aspx?id=44266) instead of, who knows, wasting hours or even days looking for a less reasonable solution. Credit, as so very often, [goes to stackoverflow](https://stackoverflow.com/a/27327236/1578458).


The color that [PuTTY](http://www.putty.org/) uses for blue is simply too dark. The scrollback buffer, by default, is 200 lines. That's ridiculous, I have several gigabytes of RAM going to waste here. In case you have a lot of stored sessions, it's quite tiresome to use PuTTY to go through all of them and fix whatever settings you would like to change. You can edit them directly in the registry, though - or use this Python <b>3</b> script! ```python from winreg import OpenKey, EnumKey, QueryValueEx, SetValueEx, \ KEY_WRITE, KEY_READ, HKEY_CURRENT_USER as HKCU class callrange: def __init__(self, call_function): self.call = call_function def __getitem__(self,index): try: return self.call(index) except OSError: raise IndexError with OpenKey(HKCU,"SOFTWARE\SimonTatham\PuTTY\Sessions") as sessions: for s in callrange(lambda i: EnumKey(sessions,i)): with OpenKey(sessions,s,access=KEY_WRITE|KEY_READ) as key: for name,value in [ ('Colour14','100,100,250'), ('Colour15','120,120,250'), ('TerminalType','xterm'), ('ScrollbackLines',6000) ]: type = QueryValueEx(key,name)[1] SetValueEx(key,name,0,type,value) ``` By the way, searching the tubes reveals [some useful suggestions to improve PuTTY's default settings](http://dag.wiee.rs/blog/content/improving-putty-settings-on-windows).


Are you also annoyed with the Windows lock screen? You know, the one you must swipe or click away before you can enter your login data. The one that doesn't even respond to shift anymore since Windows 10. It can be disabled as follows: * Open the Group Policy Editor. Either 1. press `Win+R` and run `gpedit` or, if you don't have `gpedit.msc`, 2. open the Microsoft Management Console by pressing `Win+R` and entering `mmc`. Go to `File` &rarr; `Add/Remove Snap-In`, select the Group Policy Object Editor, press `Add`, `Finish` and `OK`. Expand the Local Computer Policy. * Navigate to 3. Computer Configuration 4. Administrative Templates 5. Control Panel 6. Personalization, edit `Do not display the lock screen` and set it to `Enabled`.


Well. In case you have not stumbled across the <a href="http://stackoverflow.com/questions/18115644/vim-has-many-ui-bugs-on-cygwin-on-windows-8" target="_blank">corresponding StackOverflow post</a>, and if you have always wondered why vim does not work properly in cygwin, just ```bash [rattle@ALICE:~]$ cat .vimrc set nocompatible set backspace=indent,eol,start ``` and your worries will be over.


Finally there is an official way of setting a text file as your Desktop Background: <a href="http://technet.microsoft.com/en-us/sysinternals/bb897557.aspx" title="Windows Sysinternals BgInfo">Windows Sysinternals BgInfo</a>. This tool can show a lot of information about your system but may also show the contents of a Textfile: Press the button `Custom...` on the right and then `New...`. There you may select `Contents of a file` and include a path to the text file. After you saved the BfInfo config file somewhere on your system, you can call BgInfo in the following way to update the background image: ```Winbatch bginfo c:\System\config\bginfo.bgi /timer:0 ``` This may be useful to show log files that you want to keep an eye on or the shadowfile of your favorite TaskWarrior report.