Microsoft is trying to force everybody to update from the old NT4 domain system to the “new” (as in “was new >10 years ago”) Active Directory system. While that’s probably a good idea for most people there are some like me stuck with a working Samba installation that for some reason needs to continue to use NT4 domains.

Getting a Windows computer to join such a domain has become more difficult with Windows 10. Here is what needs to be done (I write this mostly so I can look it up myself):

1. Make sure your samba server is configured to enforce the NT4 (SMB1) login. samba.conf must contain the following entry:
[global]
// other entries here
server max protocol = NT1

2. Install the SMB1 protocol on the Windows computer. This is done using the “Turn Windows Features on or off” dialog (just type this into the start menu). You need to set the check marks for two entries under “SMB 1.0/CIFS File share Support”:
• SMB 1.0/CIFS Client
• SMB 1.0/CIFS Server

I’m not 100% sure whether the latter is required. I haven’t tried it without.

3. Add the following entries to the registry:
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManWorkstation\Parameters]
"DomainCompatibilityMode"=dword:00000001
"DNSNameResolutionRequired"=dword:00000000


You can either add them manually or copy the above to the .reg file and import that into the registry.

4. Reboot the computer to activate these changes.

Now it should be possible to join the Windows 10 computer to the Samba Domain.

Source: Required Settings for Samba NT4 Domains on the Samba Wiki.

Starting with Windows Vista Microsoft has started to take security really serious. That’s a good thing. Unfortunately in typically Microsoft attitude they think they always know best and that the user is an idiot, so it’s best to keep anything dangerous from him.

Fast forward to Windows 10 and the issue at hand:

Windows 10 tries to identify networks and based on that classifies them as private or public. The Windows firewall then changes some settings based on this classification.

Now imagine a computer installed in a special setting that is connected via LAN to some other computers in the same place. Network wise this is an isolated island, there is no connection to any company LAN or the Internet. All computers have fixed IP addresses, so there is no DHCP server involved, and provide network shares to each other.

Unfortunately Windows sees this setup as an unidentified network and classifies it as a public network. This means that many things – in particular network shares – do not work.

And since Microsoft doesn’t trust users to know what they are doing, there is no easy (GUI) way to change this. It used to be possible in Windows 7 but no longer.

So, what can be done? Google turned up lots of different suggestions but the only one that worked for me was this answer on SuperUser.com.

It gives a PowerShell script which I have adjusted to my needs:

Write-Host "current settings:"
Get-NetConnectionProfile |
Where{ $_.InterfaceAlias -eq 'NetworkCardName'} | ForEach {$_
$_|Set-NetConnectionProfile -NetWorkCategory Private } Write-Host "new settings:" Get-NetConnectionProfile | Where{$_.InterfaceAlias -eq 'NetworkCardName'}

Write-Host "Beliebige Taste um fortzufahren..."
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")  It reads all connection profiles, filters for the one that apply to a network adapter with a given name (which I renamed to make it unique) and changes this profile to be private. It then displays the new settings and waits for the user to press a key. In order to work, this script must be started with administrator privileges. Of course, that would have been too simple: Microsoft also by default prevents the execution of PowerShell scripts. Again, that might be a valid security measure but in this situation it’s merely a pain in the lower back. So in order to allow scripts, we need to change this setting as suggested in yet another answer on SuperUser.com: Start PowerShell as administrator and run the following command: set-executionpolicy remotesigned  This allows the execution of local scripts, which is what we want. It also allows remote scripts if those are signed, which isn’t particularly what I want but apparently you can’t get one without the other. Diesmal funktioniert alles [music video] Even after Microsoft abandoned the stupid idea of the Windows 8 start screen and gave us back the start menu in Windows 10 there is still a lot to desire. Of course you can replace the the start menu with a tool like Open Shell (formerly known as Classic Shell) which improves it quite a lot. Or you use a separate launcher like the Portable Apps Launcher. I have switched to Open Shell but I also use JumpFolder to create my own, multiple “Start Menus” using the jump list that every icon on the taskbar has had since Windows 7. Basic usage means that you put the JumpFolder.exe into any directory on your disk, add subdirectories containing shortcuts to the programs you want to start, pin JumpFolder.exe to the Windows taskbar and start it once. After that the jump list of this icon will show you all those shortcuts: (In case you are curious: These shortcuts start Civilization, the original DOs game from 1991, 7 Kingdoms, a Windows game from 1997) and Todolist by Abstract Spoon. I can definitely recommend the games but the todo list is not my favourite, but hey, it’s free.) Note that even though the JumpFolder homepage states that it requires Windows 7, it also works for later Windows versions, including Windows 10. But the number of entries in the jump list is limited (by default to 10 entries which can be increased, but even then, vertical space on a monitor is limited) and it would be nice to have more than one. But there can only be one JumpFolder.exe icon on the taskbar. So, what can be done? Simple: Create a shortcut to JumpFolder.exe itself and pin that shortcut to the taskbar. OK, here are the steps: 1. Create a new directory. 2. Put the JumpFolder.exe file into it 3. Create a shortcut to that executable in the same folder and give it a unique name, e.g. “MyJumpFolder1” 4. Optionally, assign an icon to this shortcut. 5. Pin this shortcut to the taskbar 6. Create subdirectories for categories (e.g. “games” and “tools” and put shortcuts into these subdirectories. 7. Start the shortcut on the taskbar. It will now parse the subdirectories and create a jump list from them. 8. Voila: You have a unique “start menu”. Now rinse and repeat for each additional “start menu” you want. Of course the shortcuts can be for anything, e.g. open a folder or start a program passing it parameters. This way you can create a “start menu” for your music, by putting several shortcuts to your music player into the subdirectories passing it e.g. the directory containing the music files it should play. Eg. for VLC it would look like this: c:\path\to\VLC.exe "c:\path\to\Peter Fox" (The parameter is the directory containing mp3s with music from Peter Fox’ album Stadtaffe“.) My current music “start menu” looks like this: The same principle can also be used to create entries with jump lists in the start menu, but personally I find that a lot less useful. I stumbled upon JumpFolder a few years ago when I was considering writing such a program myself. I’ve even got the source code from back then. But it didn’t keep my interest after I discovered that such a program already exists. Due the the COVID19 pandemic I am currently working from home, using Putty + ssh + Remote Desktop to log into and work on my office PC. For this to work, the office PC must be turned on and booted. So far I have let it running 24h which is really a waste of energy but since sometimes nobody is in the office at all, that was the most fool proof way. Today I have had some time at my hands waiting for an Ubuntu server to finish installing, so I thought about alternatives. • One would have been Wake on LAN (WOL), if the BIOS of my computer supported it, but unfortunately it doesn’t (see edit below). • Waking up using the RTC (real time clock) is actually an option in the BIOS, but that would have woken it up every day rather than just on weekdays. Finally I stumbled upon an article on How-To Geek about “How to Make Your PC Wake From Sleep Automatically“. The Windows Scheduler has an option to wake up the computer to run a task. Note that it works only if the computer wasn’t turned off but rather sent into hibernation. So I set up a task that runs “cmd.exe” with the parameter “/c exit” weekly on Monday to Friday at 7:30. Of course I tested it first with a on time schedule and it worked fine. So now I have sent my office PC into hibernation. We’ll see whether it is available on Monday when I want to log into it. EDIT: It turns out that my office PC supports WOL even though it’s not visible in the BIOS. But the network card properties under Windows have a setting for it: So when I read the hint from Vandrovnik on the international Delphi Praxis forum, I ssh’d into the company intranet and was able to simply wake up my office PC using the wakeonlan tool installed on the remote logon computer: wakeonlan [hardware address] Great, this is much more flexible than I thought. Since Microsoft will end the free support for Windows 7 in January 2020, we are updating all our computers to Windows 10 (I would really have liked to avoid that. Windows 7 is definitely not the best Windows ever but its annoyances are known. Windows 10 started to annoy me with new so called “features” immediately after the installation finished. But hey, that’s what you get when you make a living developing software for this stinking pile of sh*t. sorry excuse for an operating system.) Anyway: As before, when I updated from Windows 8 to Windows 8.1, the Windows 10 update broke my Delphi 6 and 2007 installations. Fortunately my workarounds / fixes for Windows 8.1 also work for Windows 10. Also fortunately I blogged about them so I could look them up. In theory it is simple to install the dotNet 2.0 framework on Windows 10: Just go to “Programs and Features”, select “Turn Windows Features on or off”, set the checkmark for “.NET Framework 3.5 (includes .NET 2.0 and 3.0)”, press OK and let Windows download the necessary files from Windows Update. Unfortunately this only works most of the time. If you are unlucky like me and it doesn’t, you will start an odyssey of downloading installers from Microsoft (which also fail, because they try to download files from Windows Update for whatever reason), using the dism tool and possibly Power Shell to install it offline (both of which failed too in my case) and then either despair or find a reference to the “Missed Features Installer”. When I arrived there, I was very suspicious (and so should you!) of downloading and using such a 3rd party installer. I used the download from Computer Bild not because I think they are the most brilliant computer magazine in Germany (they are not) but at least I trust them not to distribute malware (which is more than I trust the computer magazine CHIP). In addition, I used Virus Total to scan the installer. It gave me a thumbs up, so I was brave enough to run it. Guess what? It worked. I now have a working .NET 3.5 and 2.0 framework on my computer and could finally install the program I actually wanted to install: The AVT Universal Package for accessing a camera. Sometimes your program needs to block the screen saver from automatically kicking in. My use case was that the program was recording data and whenever the screen saver was active, the data was lost (No idea why, it probably had something to do with the way HID is implemented in Windows.) So I was looking for a way to fix that without forcing the user to turn off the screen saver. The methods that used to work under Windows XP no longer work in Windows 7 and later (I don’t care about Vista), so I googled and found this question on StackOverflow. The Windows API functions PowerCreateRequest + PowerSetRequest mentioned in the highest voted answer looked promising. Unfortunately they don’t seem to be available in Delphi (Delphi 2007, which I used for that project, is too old to know them, but I couldn’t find them in Delphi 10.3 either). The first task was therefore to get a function declaration for Delphi. Google didn’t help here which meant that I had to create them myself. Not a big deal: type TPowerCreateRequest = function(_Context: PReasonContext): THandle; stdcall; TPowerSetRequest = function(_Handle: THandle; _RequestType: TPowerRequestType): LongBool; stdcall; TPowerClearRequest = function(_Handle: THandle; _RequestType: TPowerRequestType): LongBool; stdcall;  I prefer loading such functions at runtime rather than the program not starting because some external reference is not avaiable. These functions are exported by kernel32.dll.  FDllHandle := SafeLoadLibrary(kernel32); PowerCreateRequest := GetProcAddress(FDllHandle, 'PowerCreateRequest'); PowerSetRequest := GetProcAddress(FDllHandle, 'PowerSetRequest'); PowerClearRequest := GetProcAddress(FDllHandle, 'PowerClearRequest'); if not Assigned(PowerCreateRequest) or not Assigned(PowerSetRequest) or not Assigned(PowerClearRequest) then raise EOsFunc.Create(_('Could not initialize the PowerXxxxRequest functions from kernel32.'));  Usage is not without its own problems. First, I had to declare the constants and parameters: const POWER_REQUEST_CONTEXT_VERSION = 0; POWER_REQUEST_CONTEXT_DETAILED_STRING = 2; POWER_REQUEST_CONTEXT_SIMPLE_STRING = 1; type PReasonContext = ^TReasonContext; TReasonContext = record Version: ULONG; Flags: DWORD; case Boolean of False: ( SimpleReasonString: PWideChar; ); True: ( Detailed: record LocalizedReasonModule: HMODULE; LocalizedReasonId: ULONG; ReasonStringCount: ULONG; ReasonStrings: PPWideChar; end; ); end; type {$MinEnumSize 4}
TPowerRequestType = (
PowerRequestDisplayRequired = 0,
PowerRequestSystemRequired = 1,
PowerRequestAwayModeRequired = 2,
PowerRequestExecutionRequired = 3);


Now, how do these functions work?

The first thing to do is creating a power request with PowerCreateRequest. This function requires a PReasonContext pointer which must be initialized correctly. The Version and Flags fields are simple: Assign one of the POWER_REQUEST_CONTEXT_xxx constants declared above. But what about the other fields? I decided to go with the simple case, that is: Set Flags to POWER_REQUEST_CONTEXT_SIMPLE_STRING and provide a value for SimpleReasonString.

var
FRequestHandle: THandle;
FContext: TReasonContext;
FReason: array[0..255] of WideChar;
// [...]
FContext.Version := POWER_REQUEST_CONTEXT_VERSION;
FContext.Flags := POWER_REQUEST_CONTEXT_SIMPLE_STRING;
FContext.SimpleReasonString := @FReason;
FRequestHandle := PowerCreateRequest(@FContext);
if FRequestHandle = INVALID_HANDLE_VALUE then
RaiseLastOSError;


Where FReason is an array of WideChar. My tests showed that the TReasonContext record and the reason string it points to must be available through the lifetime of the reason context. If it isn’t, the reason displayed by the powercfg tool (see below) will be corrupted. Therefore I did not use a WideString but a static array.

After the power request has been created, calls to PowerSetRequest and PowerClearRequest are possible.

  Win32Check(PowerSetRequest(FRequestHandle, PowerRequestDisplayRequired));


This call prevents the screen saver from starting automatically. A call to PowerClearRequest supposedly turns that off again (but I haven’t tested it).

I mentioned the powercfg tool above. It’s a Windows command line tool that among other functionality can display processes that have active power requests. e.g.

powercfg /requests
DISPLAY:
[PROCESS] \Device\HarddiskVolume2\Source\dzlib\tests\BlockScreenSaver\BlockScreenSaver.exe
test

SYSTEM:
None.

AWAYMODE:
None.

EXECUTION:
None.

PERFBOOST:
None.


The string “test” is the reason I passed to PowerCreateRequests.

I mentioned that failing to preserver the reason string results in a corrupted message in the display. It looked like this:

powercfg /requests
DISPLAY:
[PROCESS] \Device\HarddiskVolume2\Source\dzlib\tests\BlockScreenSaver\BlockScreenSaver.exe
?a?E?I???↑?E?↑?E?↑?E?↑?E?↑


Note that this tool requires administrator privileges (but power requests don’t).

I have added this code to my dzlib. It’s in u_dzOsUtils. There is also a simple test / demo program BlockScreenSaver.

If you would like to comment on this, go to this post in the international Delphi Praxis forum.

… seems to be the motto of Microsoft.

How else can you explain that a recent update of Windows 7 and Windows 10, that broke older versions of one of our programs (no idea yet what exactly is the problem, but the error code indicates an out of memory error) has different effects.

Windows 7 shows a dialog that the program could not be started and even gives some additional information. But that’s not good enough, the user could be irritated by telling him a program has crashed. So Windows 10 goes a step further and simply does … nothing. The program starts (as you can verify in the task manager), but nothing appears on the screen.

If you have administrator privileges, you can look into the event log (If you know how to do that). If you haven’t or don’t know how to, you are lost.

<sarcasm>Great feature, guys!</sarcasm>

So I don’t forget: According to an article in c’t magazine, disabling the “DiagTrack” service (“Connected User Experience and Telemetry”) will completely disable user tracking in Windows 10. They also say that they did not see any negative effects.

Source: Telefonierverbot in c’t 01/2019 page 172 (in German)