Sunday, October 20, 2024

Fix Microsoft Defender Antivirus Offline Scan

Windows 10 and later has "Microsoft Defender Antivirus Offline Scan", which can remove some malware that cannot be removed without restarting Windows. First, you click on the "Scan Options":


Then you select "Microsoft Defender Antivirus (offline scan)", and click "Scan now":


Windows will then prompt you to confirm, and restart Windows.

But after migrating Windows to a larger SSD, somehow I lost the recovery partition on my boot drive, and after getting prompted to restart Windows, Windows does not actually restart.

Then I found online that when the recovery partition is not present, this feature will not work. So I started to restore the recovery partition on my boot drive.

First I ran "reagentc /info" on the command line, and confirmed that "Windows RE" was disabled:

reagentc /info

Then I confirmed that "Windows RE" could not be simply enabled by running "reagentc /enable":

reagentc /enable

After that, I started to re-create the recovery partition.

1. In the Windows Disk Management tool, I shrank the main Windows partition to make room at the end of the disk to create a new partition:


The partition size was set to 1024MB, or 1GB. A simple volume was created, and a drive letter "R" was temporarily assigned.  Then I create the directory "R:\Recovery\WindowsRE".

2. I mounted Windows installation iso file as drive "F". I then used the following command to list all the Windows images available:

    dism /Get-WimInfo /WimFile:D:\sources\install.wim

I then picked the index in the result list that matched my installation, created a directory "C:\Mount", and then ran

  dism /Mount-Wim /WimFile:F:\sources\install.wim /Index:<IndexNumber> /MountDir:C:\Mount /ReadOnly

3. I then copied the hidden, protected operating system file "C:\Mount\Windows\System32\Recovery\Winre.wim" into "R:\Recovery\WindowsRE" as well as "C:\Windows\System32\Recovery".

4. I then unmounted the image: 

   dism /Unmount-Wim /MountDir:C:\Mount /Discard

5. Then I ran the following:

   reagentc /setreimage /path R:\Recovery\WindowsRE
   reagentc /enable

6. At this point, Windows RE has been enabled:


7. The drive letter "R" was removed.

8. Finally, to turn the new partition into a recovery partition, I used "diskpart":

  diskpart
  list disk
  select disk <DiskNumber>  (replace <DiskNumber> with the number of your disk)
  list partition
  select partition <PartitionNumber>  (replace <PartitionNumber> with the number of the recovery partition)
  set id=27 override ("set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac override" for GPT drive)

After that, the "Microsoft Defender Antivirus Offline Scan" is working again.

Disclaimer and Caution: Be very careful with "diskpart" and the Windows Disk Management tool! Serious data loss could occur if you execute anything wrong!




Saturday, January 20, 2024

Proof That (a^2+b^2)/(ab+1) Is a Square When It is an Integer

Let a, b be positive integers. When 

k = a2 + b2
ab + 1

is an integer, it is a square.

Proof:

We will refer to this as Equation (*) hereafter.

We will first prove the trivial case where a = b. If a = b, this becomes

k = 2a2
a2 + 1
or

k = 2
1 + 1/(a2)

Because a > 0, the denominator is greater than 1, so k < 2. Since k is a positive integer, k can only be 1. This means that a = 1. Since a = b,  b = 1. The statement is trivially true. Conversely, if k = 1, we have

a2 + b2 = ab + 1

(a − b)2 = 1 − ab

1 − ab  ≥  0

ab  ≤  1

which can be true only if a = 1, b = 1.

To further simplify the proof, we can exclude the special case a > b = 1, and k > 1 as well. When b = 1, we have
k = a2 + 1 = a + 1 − 2a
a + 1 a + 1
This means that 2a is divisible by a + 1. In other words, 2a = m (a + 1), (2  m)a = m for some positive integer m. But from  m > 0 we conclude that 2 > m, m = 1, so 2a = a + 1, and a = 1, k = 1 as well.

Therefore, without losing generality, we can assume that a > b > 1, and k > 1.

Multiply both sides of Equation (*) by b, we have

a2b + b3 = kb
ab + 1

Perform long division by (ab + 1), we get:

(ab + 1 − 1)a + b3 = kb
ab + 1

(ab + 1)a + b3 − a = kb
ab + 1

a + b3 − a = kb
ab + 1
"Move" a to the right:
b3 − a = kb  a
ab + 1

This leads to

b3 − a = (kb − a)(ab + 1)


There are three possible cases: 1. (kb − a) > 0, 2. (kb − a) < 0, and 3. (kb − a) = 0.

Case 3 means that b3 − a = 0, a = b3. Substitute this into Equation (*), we get k = b2, which proves the original statement to be true. So we only need to prove that Case 1 and Case 2 are either not possible or yield a k = c2 for some integer c.

Case 2 is not possible because if (kb − a) < 0, we have

b3 − a = (kb − a)(ab + 1) < 0

a − b3 = (a − kb)(ab + 1) > 0

But (a − kb) > 0 means that (a − kb) ≥ 1 since a, k, and b are all integers. So

a − b3  ≥  ab + 1

a − b3 > ab

This contradicts the fact that > 1. So case 2 is not possible.

Case 1 is complicated. From (kb − a) > 0, (ab + 1) > 0 we also get b3 − a > 0. This in turn would mean that (kb − a) < b, because otherwise we would have

b3 − a = (kb − a)(ab + 1) ≥ b(ab + 1) > bab > b3

which is not possible when a > 0. Therefore, combine (kb − a) < b and kb > a, we get that (k − 1)b < a < kb, or

c = kb − a, where 0 < c < b.

Substitute a = kb − c into Equation (*), we have

(kb − c)2 + b2 = k((kb − c)b + 1)

(k2 + 1)b2 − 2kcb + c2 = k2b2 − kbc + k

b2 − kcb + c2 − k = 0

k = c2 + b2
cb + 1

Please note that here the value of k is the same as the original, we have not re-defined k. Repeat the same argument above, we again have three possibilities. While kc − b < 0 remains impossible, kc − b = 0 leads to k = c2, b = c3 (in which case the original assertion is true), and we are left with kc − b > 0, a recursive Case 1. However, this recursion cannot continue indefinitely, because a and b are both finite, yet at each step we have a > b > 1, and k > 1, and each time when we swap the roles of a and b, we are reducing the value of the smaller number by at least one.
In other words, Case 1 either does not hold, or can be reduced to k = c2 for some integer 0 < c < b.

QED


In this proof, I have produced a formula for generating a > b > 1, and k > 1 where Equation (*) holds.

Start with any b > 1, let a = b3, Equation (*) will be satisfied:

k = (b3)2 + b2 = b6 + b2 = b2(b4 + 1) = b2
b3b + 1 b4 + 1 b4 + 1

Let a1 = ka  b = b5  b, we will have

k = a12 + a2 = b10 − 2b6 + b2 + b6 = b2(b8 − b4 + 1) = b2
a1a + 1 b8 − b4 + 1 b8 − b4 + 1

This process can be repeated indefinitely.

Saturday, October 21, 2023

Fixing GE WBSE3120B1WW Washing Machine

This is a twenty year old washing machine. Today it wanted to quit. Its motor no longer turned. although the water pump still worked, so water was getting drained when the time was up. 

I tried resetting the machine following the instructions found on YouTube: unplugged it, and then plugged it back in after one minute. Within 30 seconds after it was plugged back in, I opened and closed the lid six times, each time the magnetic switch clicked.

That did not help. So, I opened its front panel, and measured the voltages on the motor connector pins. I could not find a diagram for this washing machine online, but I did notice that the label on the motor says "115 V 60HZ 9.2/7.3A", so I knew that at least one of the pins on the connector should read 110 V.

None of the pins had 110 V. So, I knew that the motor was not getting adequate power. So I decided to trace the connection from the motor to the control panel.

After removing the control panel, I saw that there was a schematic diagram for this washing machine stored behind the control panel. Thanks, GE!

The diagram is too big to fix onto an 8 inch by 14 inch scanner surface. The following is the portion of the diagram on the motor connection:


The way GE marks the wire colors is that the first letter is the initial of the main color, and the second letter is the color of the stripe. For example, VW is a violet color wire with white stripe. RB is a red wire with a blue stripe. A wire with a solid color starts with the initial of the color, and then followed by the letter "X". For example, solid yellow would be YX, and solid red would be RX. "NX" is for solid navy blue. From this diagram, we can see that we should be getting 110 V on the navy wire "NX". 

The navy blue wire goes to a relay, as one would expect. The relay looks like this:



Of course, we now need to test this relay and see if it is indeed causing the problem. In fact, broken connections on M1, M3, or M7 could all cause the motor not to get power.

I removed the control board from its plastic housing, think that I might have to remove this relay from the circuit board for testing. But it turned out to be much simpler than I thought: the solder around one of its pins were burned away, and the pin did not appear to have contact with the circuit board. So, I cleaned the pin and re-soldered the pin to the circuit board.

I reinstalled the control panel back onto the washing machine. It is now working fine. 


 

Thursday, June 15, 2023

A Botched Attempt to Update TFS Server 2018 but with A Good Ending

 When updating TFS Server 2018, I left the "install search"  check box checked, and it led to a disaster. 

The "elastic search" service that TFS Server 2018 tried to install went berserk, and ate up a lot of RAM. So much so that another VM on the same host that ran the SQL server slowed down to a crawl. Then the TFS Server 2018 update failed with a message saying "TF255356: The following error occurred when configuring the Team Foundation databases: TF400711: Error occurred while executing servicing step 'Install Local Contribution Web Platform On Prem' for component Publish Extensions during FinishInstallUpdates". The reason in the log file: SQL timeout.

Not knowing what was going on in the background, I stopped the update, restored the database, and re-tried several times. Each time I got the same error.

I had to try to complete the update on a different machine, with a different SQL server. Since this was no longer a minor update, I upgraded the TFS Server 2018 to Azure DevOps Server 2022. Everything worked. Then I tried to move the SQL databases to the old SQL server. As soon as I completed the move, the TFS server, oh no, the Azure DevOps Server 2022, slowed down to a crawl again. 

It seemed that I had to leave the TFS server, oh wait, the Azure DevOps Server 2022, on the new hosts. So I started to clean up the old hosts and tried to remove any traces of the old TFS Server installations. There were several TFS Server folders in "C:\Program Files". I tried to delete them all, since they no longer show up on the installed applications list of Windows. But the TFS Server 2018 folder could not be deleted because it was in use by some running process. 

I sorted the running processes by memory usage, and saw that at the top there was a running process for "elastic search" that ate up a huge amount of RAM. Then I discovered that this process was from a Windows service installed by the TFS Server 2018. The service was "elasticsearch-service-x64". Its files were in the TFS Server 2018 folder. I stopped the service, and then removed it by running "sc delete elasticsearch-service-x64" on a admin command prompt. 

Now the host has regained all the RAM, everything is back to normal. The SQL server is no longer running at a snails pace. And the server is now the latest -- Azure DevOps Server 2022.0.1.



Saturday, May 27, 2023

OData Route 404 Error after Migrating from .NET Framework to .NET Core

 I have a global OData function in .NET Framework that uses a routing attribute:

[ODataRoute("GetSalesStats(SellerId={sellerId}, BuyerId={buyerId}, FromTime={fromTime}, ToTime={toTime})")]

This was working fine. Now with .NET 7 (.NET Core), I started using HttpGet attribute for routing:

[HttpGet("odata/GetSalesStats(SellerId={sellerId}, BuyerId={buyerId}, FromTime={fromTime}, ToTime={toTime})")]

This did not work. The difference is that the HttpGet attribute does not like the spaces after the commas. After removing the spaces, the following works fine:

[HttpGet("odata/GetSalesStats(SellerId={sellerId},BuyerId={buyerId},FromTime={fromTime}, ToTime={toTime})")]

Now I just need to go find all the spaces that I need to remove:-).

Update: When an entity has multiple key columns, the "OData Connected Service" tool for adding "Connected Service" in Visual Studio 2022 seems to add the key columns in alphabetical order. When you have routing attribute specified for an OData action, and the order of the parameters is different, you will get an HTTP 404 error as well. For example, for querying by primary key, you would have something like

[HttpGet("odata/UserData(PropertyName={propertyName},UserId={userId})")]

Even though you would setup the UserId as the first key column and the PropertyName as the second key column, the generated OData client always sends in the PropertyName as the first parameter, and the UserId as the second parameter. If you specify them in the "wrong" order, you will get an HTTP 404 error for it.

Sunday, February 5, 2023

"IIS Web App Manage" Step on TFS Build/Release Server

When trying to deploy to an IIS server from a TFS Build/Release Server, I ran into an error at the step for "IIS Web App Manage". The error code was 0x80090016, and the message was "Failed to commit configuration changes". "Keyset does not exist".

I googled for these errors online. All I found was that the machine keys in the folder "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys" were corrupted, and needed to be re-created with "iissetup.exe /install SharedLibraries". 

BTW, the error code  0x80090016 means "Your computer's Trusted Platform Module has malfunctioned".

Well, I tried to run "iissetup.exe /install SharedLibraries" to fix the problem after backing up the affected files. But that did not work for me. In fact, I was getting "0x80070005" error after running "iissetup.exe /install SharedLibraries" even though new key files were generated.

It turned out that in my case, the key files were not the problem. The problem was that my VSTS Agent service was running in a domain user account that did not have administrator access. Once I granted the user administrator access, the TFS Release Server was able to complete the step just fine.

 


Sunday, November 13, 2022

Transfer Music Manually From iTunes to iPhone

 This seems to be a very simple task. But I did not figure out how to do it until recently. I found this article: https://www.lifewire.com/how-to-sync-your-itunes-music-library-to-the-iphone-2438724, and I was able to copy individual songs to my iPhone manually:


However, there are a couple of important issues with this choice though:
  1. You could lose all the songs that were on the iPhone but not in iTunes. That was what happened to me. When I realized that was what happened, and tried to restore my iPhone from my PC, I found that iTunes' PC backup contains only the latest. The songs on my iPhone that were not on the PC (I copied them to my iPhone from another PC  long time ago) are now gone.
  2. You cannot turn off "Manually manage music and videos" without losing songs that only exist on your iPhone. When you try to turn it off, iTunes will prompt you with this dialog box:

Obviously, the situation is less than ideal. Ideally, we should be able to drag songs that only exist on the iPhone back to iTunes, and vice versa. You should not lose things on either side. 

Oh well. The price we pay for monopolies/authoritarianism.