Recreating a Lost or Removed EFI Windows Boot Partition (Repair Windows Boot)

Recreating a Lost or Removed EFI Windows Boot Partition

In case you remove an SSD with a Windows Boot Partition that boots an installation of Windows, you'll need to recreate the boot system to be able to successfully boot again.  To recreate the boot EFI partition on another drive or partition, perform the following:

1) Create or use an existing Windows installation disc or flash drive (you can use Rufus USB to format a flash drive with a Windows ISO)
2) Boot PC using your Windows installation media (a CD, DVD, flash drive, etc containing Windows installation files)
3) Press SHIFT + F10 on the first screen to bring up Command Prompt
4) Run the following commands and click Enter each time at Command Prompt:

diskpart
list disk
select disk N (N refers to the disk which contains the deleted the EFI System partition)
list partition
create partition efi size=200
format quick fs=fat32
list partition
list volume (find the volume letter which belongs to the installed Windows OS)
exit (exit diskpart)
bcdboot M:\windows (M refers to the volume letter of installed Windows OS)

Add any additional Windows installations by repeating the bcdboot command followed by the installation path for any other Windows installations you want added to the menu.  For example, I added my Windows 7 partition using the below command:

bcdboot P:\windows

You should now be able to boot Windows again without needing the old boot partition or drive.

Instructions were modified from this post.

Ryzen Windows 10 Random BSOD Fix – Mouse Becomes Unresponsive, System Slows to a Crawl, and Then Crashes

Ryzen Windows 10 Random BSOD Fix

For the longest time, I could not figure out why I couldn't get Windows 10 to consistently install or run in a stable fashion for longer than a few minutes on my Ryzen 1700X or my Ryzen 3900X AMD CPU. 

After trying everything I could think of and pulling my hair out, I found a simple solution that appears to have worked!  Simply disable Link State Power Management in your Power Setting's active power plan.

Go to the "Control Panel" -> "Power Options" -> Click on the "Change plan settings" link for your selected power plan -> click on the "Change advanced power settings" link -> navigate to the "PCI Express" category -> find the "Link State Power Management" option -> set it to "Off" (for both on battery and plugged in).

In general, there are several reasons why a computer can suffer a catastrophic Blue Screen of Death (BSOD) issue, but in my case, it turns out I just needed to adjust some power settings to compensate for a storage controller bug found in some solid state hard drives.  Thanks Reddit users for helping me find the fix!

https://www.reddit.com/r/Amd/comments/cx3rpb/new_system_with_ryzen_and_windows_10_freezes/#t1_eykk63l

Run Everything as an Administrator in Windows 10 by Default – Same Windows 7 Behavior

Run Everything as an Administrator in Windows 10 by Default – Same Windows 7 Behavior

To run everything as an administrator in Windows 10, there are several settings that must be changed.  In Windows 7, you would only have to disable UAC for the current user:

This isn't good enough in Windows 10.  You have to disable UAC for the current user AND do the following:

Run gpedit.msc to open the Local Group Policy Editor. Expand Computer Configuration, Windows Settings, Security Settings, Local Policies, and Security Options. Four settings need to be updated:

  1. Set "User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode" to Elevate without prompting.
  2. Set "User Account Control: Detect application installations and prompt for elevation" to Disabled.
  3. Set "User Account Control: Run all administrators in Admin Approval Mode" to Disabled.
  4. Set "User Account Control: Only elevate UIAccess applications that are installed in secure locations" to Disabled.

The LGPE automatically saves all changes, so exit it and reboot.

Please read more here:

https://superuser.com/questions/1002262/run-applications-as-administrator-by-default-in-windows-10

Common Internet File System (CIFS) – Windows 10 and Windows 7 – Accessing SMB1 Using Anonymous (guest) Account

Common Internet File System (CIFS) – Login Using Anonymous (Guest) Account to Network Shares & NAS Systems

Windows 7:

To map and connect to a network share that is using the SMB1 protocol in Windows, there are a few things that you need to do depending on which version of Windows you use.  In Windows 7, it should be pretty easy.  When mapping the network drive, be sure to check the "Connect using different credentials" box.  For the login, use "anonymous".  Leave the password field blank (don't provide a password).

Windows 10:

Windows 10 doesn't support the SMB1 protocol by default.  However, it can be enabled.  To enable SMB1 support, go to the Control Panel, click on "Programs and Features", and then click on the "Turn Windows features on or off" link in the left sidebar.  Under the "SMB 1.0" category, enable the "SMB 1.0/CIFS Client" by clicking the checkbox and making sure it's in a checked state.  Uncheck the "SMB 1.0/CIFS Automatic Removal" entry if it's enabled as it will cause anonymous logins to SMB1.0 shares to fail.

The next step is to configure Windows 10 to allow anonymous logins to network shares.

To enable access under the guest account from your computer, you need to use the Group Policy Editor (gpedit.msc). Go to the section: Computer Configuration -> Administrative templates -> Network -> Lanman Workstation. Find and enable the policy "Enable insecure guest logons". These policy settings determine whether the SMB client will allow the guest logon to the SMB server.

More Detailed Guide | Archived Copy

Windows 7 and 10:

If you get a message that a drive is already mapped using different credentials, simply map the connection using its IP address instead rather than its name. 

Destroy Windows 10 Spying – Fix for Skype

Destroy Windows Spying

Destroy Windows Spying is a great little utility that stops Microsoft from collecting some telemetry without your permission on Windows 7 and Windows 10.  It is an open source project hosted on GitHub.

Download and use Destroy Windows Spying for both Windows 7 and Windows 10. 

After you run Destroy Windows Spying, Skype may not work due to an overly aggressive hosts file entry.   To fix it, remove the following entry from the C:\Windows\System32\drivers\etc\hosts file:

client-s.gateway.messenger.live.com

 

Installing Chrome WebDriver (Linux Script)

Installing Chrome WebDriver (Linux Script)

Find out which version of Chrome is installed on your system before running the below commands.  You can find out your chrome version by running the following command:

google-chrome --version

Adjust the version number (replace {VERSION_NUMBER})  in the below commands to match the version installed on your system!!!

sudo -i
cd ~/Downloads
rm chromedriver_linux64.zip
wget -N https://chromedriver.storage.googleapis.com/{VERSION_NUMBER}/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
mv chromedriver /usr/bin/chromedriver
chown root:root /usr/bin/chromedriver
chmod +x /usr/bin/chromedriver

Selenium and other libraries that rely on the Chrome WebDriver should now work properly.

ASP.NET MVC – Smart Way to Prevent Cross-Site Request Forgery (CSRF) Attempts – WebAPI (AJAX XHR) and Normal POST Operations

ASP.NET MVC – The Smart Way to Prevent Cross-Site Request Forgery (CSRF) Attempts

WebAPI (AJAX XHR) and Normal POST Operations

If your ASP.NET MVC application uses some WebAPI endpoints which are called using XHR (AJAX) requests from clientside JavaScript, you can still protect against CSRF attacks by validating the origin of such a request (when it is an AJAX request) or perform the default action of validating the anti-CSRF token (for POST form requests).

I modified the below code from https://stackoverflow.com/questions/35085507/set-validateantiforgerytoken-attribute-to-get-post-for-same-action-mvc5#answer-35085970 or ARCHIVE

using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Web.Helpers;
using System.Linq;
using System.Collections.Generic;
using System.Configuration;
namespace System.Web.Mvc
{
    /// <summary>
    /// Cross-Site Request Forgery (CSRF) Prevention Filter for WebAPI and Normal MVC Controllers
    /// Normal POST operations = token is checked
    /// Normal controller GET operations = ignored
    /// WebAPI requests = check to make sure they were initiated by an AJAX request from a trusted origin
    /// </summary>    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class ValidateAntiForgeryTokenPOSTOrAJAXOrigin : FilterAttribute, IAuthorizationFilter
    {
        private string _salt;        

        public ValidateAntiForgeryTokenAttribute2() : this(AntiForgery.Validate)
        {
        }        

        internal ValidateAntiForgeryTokenAttribute2(Action validateAction)
        {
            Debug.Assert(validateAction != null);
            ValidateAction = validateAction;
        }
        
        [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AdditionalDataProvider", Justification = "API name.")]
        [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AntiForgeryConfig", Justification = "API name.")]
        [Obsolete("The 'Salt' property is deprecated. To specify custom data to be embedded within the token, use the static AntiForgeryConfig.AdditionalDataProvider property.", error: true)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        
        public string Salt
        {
            get { return _salt; }
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    throw new NotSupportedException("The 'Salt' property is deprecated. To specify custom data to be embedded within the token, use the static AntiForgeryConfig.AdditionalDataProvider property.");
                }
                _salt = value;
            }
        }

        internal Action ValidateAction { get; private set; }        
        
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            string validOrigins = ConfigurationManager.AppSettings["AllowedEnvironments"]; // Example in web.config <add key="AllowedEnvironments" value="https://testurl.com:4443,https://testurl.com,https://testurl2.com" />
            bool skipCheck = false;
            
            if(ConfigurationManager.AppSettings["LocalDevMode"] == "1")
            {
                skipCheck = true;
            }
            
            // In AJAX requests, the origin header is always sent (UNLESS IT'S COMING FROM THE SAME ORIGIN), so we can validate that it comes from a trusted location to prevent CSRF attacks - but if one isn't sent, we won't do anything (assume trusted)
            // In which case, we don't need to do any token checking either 🙂
            if(!skipCheck && !string.IsNullOrEmpty(validOrigins))
            {
                List<string> validOriginURLs = validOrigins.Split(',').ToList();
                if(filterContext.HttpContext.Request.Headers["Origin"] != null && !string.IsNullOrEmpty(filterContext.HttpContext.Request.Headers["Origin"].ToString()))
                {
                    string origin = filterContext.HttpContext.Request.Headers["Origin"];
                    if(!validOriginURLs.Contains(origin))
                    {
                        filterContext.Result = new RedirectResult("~/Home/InvalidRequest");
                        skipCheck = true; // Still set to true to prevent additional validation
                    }
                    else
                    {
                        skipCheck = true;
                    }
                }
            }
        
            if(!skipCheck){
                var request = filterContext.HttpContext.Request.HttpMethod;
                if (request != "GET" && (!filterContext.HttpContext.Request.IsAjaxRequest() || (filterContext.HttpContext.Request.IsAjaxRequest() && (filterContext.HttpContext.Request.Headers["X-Request-With"] == null || filterContext.HttpContext.Request.Headers["X-Requested-With"] != "XMLHttpRequest"))))
                {
                    // Do normal form POST antiforgery token check
                    if (filterContext == null)
                    {
                        throw new ArgumentNullException("filterContext");
                    }                    try
                    {
                        ValidateAction();
                    }
                    catch(Exception e)
                    {
                        filterContext.Result = new RedirectResult("~/Home/InvalidRequest");
                    }
                }
            }
        }
    }
}

 

ASP.NET Web API – Accessing Session Information

ASP.NET Web API – Accessing Session Information

If WebAPI needs access to SESSION information, here's how to do it:

https://stackoverflow.com/questions/9594229/accessing-session-using-asp-net-web-api#answer-17539008 or ARCHIVE

ASP.NET MVC – Using a Global Controller Filter to Add Information to the ViewBag

Using a Global Controller Filter to Add Information to the ViewBag

There are times where you may want to add information to the ViewBag in ASP.NET MVC that should be available to all of the views referenced within certain controllers.  For this situation, you can create a global filter that can be applied at the controller or action specific level to make certain information available to the view via the usage of the ViewBag.

Here's a basic filter example:

public class TestInformationFilter : ActionFilterAttribute
{
    public override void OnActionExceuting(ActionExecutingContext context){
        // Set ViewBag Vars
        context.Controller.ViewBag.UserFirstName = context.Session["FirstName"];
        
        // Complete normal actions
        base.OnActionExecuting(context);
    }
}

Register your global filter by editing the FilterConfig.cs file found in the App_Start folder like so:

public class FilterConfig{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters){
        filters.Add(new TestInformationFilter());
    }
}

Make all views from a controller have access to this ViewBag information by applying the filter to the controller:

[TestInformationFilter]
public class MyController{
   // My controller code here
}

CentOS – Using NAT with KVM Guests

CentOS – Using NAT with KVM Guests

Please note that all commands in this guide must be run on the main HOST machine (the physical machine).  They should not be run on KVM guests (virtual machines).

If your server has a limited number of IPv4 addresses, it might be best to setup and run some virtual machines that are configured to use the default NAT network interface that KVM provides.  This will allow you to run multiple virtual machines that share the same IP address.  Think of it as setting up a home network with multiple devices with certain ports forwarded to specific devices for incoming connections.

First, create the virtual machines that are going to use NAT using virt-manager as you normally would.  In the virtual machine configuration wizard, assign the default NAT network interface named "virbr0".  After the virtual machines have been created, shut down the virtual machines.  Now, we'll assign these virtual machines static LAN IP addresses so that we can port forward certain ports and always have them reach the proper virtual machines. 

The first thing we need to do is get the MAC address of each virtual machine.  Write down the name of the virtual machine and its MAC address, as we'll need this information later on when we edit the NAT interface and assign static LAN IP addresses to our virtual machines.  Run this command to retrieve the MAC address for a specific virtual machine.

virsh dumpxml VM_NAME | grep -i '<mac'

Using the MAC address information from the VMs we want to use NAT with, edit the default NAT interface by running the below command. 

virsh net-edit default

If for some reason the NAT interface is not named default, you can find it by running the below command:

virsh net-list

After the <range /> entry, assign the static LAN IP addresses similar to the following:

<dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
      <host mac='52:54:00:ff:4a:2a' name='vm1' ip='192.168.122.13'/>
      <host mac='52:54:00:bb:35:67' name='vm2' ip='192.168.122.14'/>
      <host mac='52:54:00:aa:d9:f2' name='vm3' ip='192.168.122.15'/>
</dhcp>

Save the file with your desired values and quit the editor.  Restart the NAT interface by running the below commands:

virsh net-destroy default
virsh net-start default

Now, you'll need to setup your iptables port forwarding rules.  Adjust the below rules as necessary (changing the port numbers to the ones you want to use) and then save them so that they persist:

iptables -I FORWARD -o virbr0 -d 192.168.122.13 -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport 39989 -j DNAT --to 192.168.122.13:39989
iptables -I FORWARD -o virbr0 -d 192.168.122.14 -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport 39990 -j DNAT --to 192.168.122.14:39990
iptables -I FORWARD -o virbr0 -d 192.168.122.15 -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport 39991 -j DNAT --to 192.168.122.15:39991
iptables -t nat -A POSTROUTING -s 192.168.122.0/24 -j MASQUERADE
iptables -A FORWARD -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i virbr0 -o br0 -j ACCEPT
iptables -A FORWARD -i virbr0 -o lo -j ACCEPT
iptables-save
service iptables save

Congrats, your virtual machines are now using NAT, have been assigned static LAN IP addresses, and iptables rules on the host server have been configured to port forward specific ports to each NAT VM.


Persistently Saving NAT Port Forward Rules

The only solution I found that would persistently save my NAT forwarding rules is to create a libvirt hook bash script as mentioned here

service iptables stop
iptables -F
service iptables save
service iptables start
mkdir -p  /etc/libvirt/hooks
nano  /etc/libvirt/hooks/qemu

The contents of the "/etc/libvirt/hooks/qemu" file should look similar to the following:

#!/bin/bash
# IMPORTANT: Change the "VM NAME" string to match your actual VM Name.
# In order to create rules to other VMs, just duplicate the below block and configure
# it accordingly.
if [ "${1}" = "vm1" ]; then   # Update the following variables to fit your setup
   GUEST_IP=192.168.122.13
   GUEST_PORT=39989
   HOST_PORT=39989   if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
    /sbin/iptables -D FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
    /sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
   if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
    /sbin/iptables -I FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
    /sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
fi
if [ "${1}" = "vm2" ]; then   # Update the following variables to fit your setup
   GUEST_IP=192.168.122.14
   GUEST_PORT=39990
   HOST_PORT=39990   
   if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
        /sbin/iptables -D FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
        /sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
   if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
        /sbin/iptables -I FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
        /sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
fi
if [ "${1}" = "vm3" ]; then   # Update the following variables to fit your setup
   GUEST_IP=192.168.122.15
   GUEST_PORT=39991
   HOST_PORT=39991
   if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
        /sbin/iptables -D FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
        /sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
   if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
        /sbin/iptables -I FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
        /sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
fi

Save and exit.  Make the script executable.

chmod +x /etc/libvirt/hooks/qemu

Reboot the host server.


Old Instructions for Persistent Saving (Non-Working)

If your iptables forwarding rules are not persisted after the host machine is rebooted or shutdown, run the following commands:

sudo -i
yum install -y iptables-services
systemctl stop firewalld
systemctl disable firewalld
systemctl enable iptables
nano /etc/sysconfig/iptables-config 

Change the below values to "yes":

IPTABLES_SAVE_ON_RESTART="yes"
IPTABLES_SAVE_ON_STOP="yes"

Save and exit.  Reboot the server.

If you're still having issues, try this (will clear your existing iptables rules):

iptables-save > iptables_bk
service iptables stop
iptables -F
<run iptables NAT rules here>
<run any other iptables rules you want>
service iptables save
service iptables start

More Detailed Guide