Backup Procedure Using WSL

February 1st, 2020

Using Microsoft Windows Subsystem for Linux (WSL) to gain access to Linux command line tools within Microsoft Windows 10, I was able to create a consistent backup procedure that can be performed in Windows and Linux environments. I used SyncToy and File Checksum Integrity Verifier (FCIV) to perform backups before adopting this standard approach.

Except where noted, the following procedure can be performed in both Windows and Linux environments.

  1. Navigate to Desired Folder’s Parent.
    $ cd /mnt/c/myfolderparent

  2. Generate SHA1 Digest File.
    $ find ./myfolder -type f \
    -exec sha1sum -b "{}" + > ~/myfolder.sha1

  3. Verify SHA1 Digest File (optional).
    $ sha1sum -c ~/myfolder.sha1

    or

    $ sha1sum -c --quiet ~/myfolder.sha1

    Note: myfolder.sha1 contains relative paths. The above command requires execution from a directory where relative paths lead to the files desired for integrity checks.

  4. Mount Destination (optional)
    1. Create Mount Point
      $ mkdir /mnt/usbdrive

    2. Review Mount Options of Mounted Fixed Drives
      $ mount

    3. Mount Drive
      $ sudo mount -t drvfs f: /mnt/usbdrive \
      -o noatime,uid=1000,gid=1000

      This command is specific to Microsoft Windows; a similar command is available in the Linux environment. “f:” is the drive letter that Microsoft Windows assigned to the inserted USB drive in this example. Options are specified to match those highlighted above for the already mounted fixed drives.

  5. Perform Copy
    1. Dry Run
      $ rsync -n -av --delete --force --progress \
      --human-readable ./myfolder/ /mnt/usbdrive/myfolder

    2. Live Run
      $ rsync -av --delete --force --progress \
      --human-readable ./myfolder/ /mnt/usbdrive/myfolder

      The trailing ‘/’ of the source folder is important to the command’s correctness.

  6. Move Checksum File
    $ cp ~/myfolder.sha1 /mnt/usbdrive/.

  7. Verify File Integrity
    $ cd /mnt/usbdrive
    $ sha1sum -c myfolder.sha1

C#: Using Declaration

January 7th, 2020
Posted in C# | No Comments

Introduced in C# 8.0, the using-declaration language enhancement eliminates nested using-statements. The following code:

using System.IO;
class Program
{
  static void Main(string[] args)
  {
    var filename = "hello.txt";
    using (var stream = new FileStream(filename, FileMode.Create))
    {
      using (var writer = new StreamWriter(stream))
      {
        writer.WriteLine("Hello, World!");
      }
    }
  }
}

is improved with using declarations to the following:

using System.IO;
class Program
{
  static void Main(string[] args)
  {
    var filename = "hello.txt";
    using var stream = new FileStream(filename, FileMode.Create);
    using var writer = new StreamWriter(stream);

    writer.WriteLine("Hello, World!");
  }
}

Encrypting /home on Dell XPS 13 7390

November 28th, 2019
Posted in Security | 1 Comment

The following procedure adds encryption to pre-installed Ubuntu 18.04 on Dell XPS 13 7390:

  1. Within a console or terminal, sudo into root.
  2. $ sudo su -

  3. Create LUKS encrypted file container (20,000 Megabytes or 20GB, for example).
  4. # dd status=progress if=/dev/zero bs=1M count=20000 of=/.hostname-home.img
    # cryptsetup luksFormat /.hostname-home.img

  5. Open LUKS encrypted file container.
  6. # cryptsetup luksOpen /.hostname-home.img hostname-home

  7. Format encrypted filesystem.
  8. # mkfs.ext4 /dev/mapper/hostname-home

  9. Move original /home content to temporary location.
  10. # mkdir /root/home
    # mv /home/* /root/home/.

  11. Mount the encrypted filesystem.
  12. # mount /dev/mapper/hostname-home /home

  13. Move /home content into encrypted filesystem.
  14. # mv /root/home/* /home/.
    # rmdir /root/home

  15. Unmount the encrypted container, potentially flushing (writing) pending data to disk.
  16. # umount /home

  17. Close the LUKS encrypted file container, potentially flushing (writing) pending data to disk.
  18. # cryptsetup luksClose hostname-home

  19. Add entry into /etc/crypttab.
  20. # echo \
    "hostname-home /.hostname-home.img - tries=0" \
    >> /etc/crypttab

  21. Add entry into /etc/fstab.
  22. # echo \
    "/dev/mapper/hostname-home /home ext4 defaults 0 0" \
    >> /etc/fstab

I recently received my Dell XPS 13 7390 with pre-installed Ubuntu 18.04. My top concern is securing data such as private SSH keys and passwords saved by Internet browsers from the real possibility of losing my laptop to absent-mindedness or theft. My purist side insists on configuring full disk encryption by performing a fresh install from a publicly available Ubuntu download. My pragmatic side pushed me toward adopting the above procedure. Without the needed transparency from Dell on their additions to Ubuntu, it is difficult to determine whether a publicly available Ubuntu download will fully support the features of my new Dell XPS 7390. The above procedure encrypts any data writable by unprivileged users while remaining unprivileged. It introduces a basic layer of security while allowing enjoyment of a system configured by Dell.

Dell XPS 13 7390

November 8th, 2019

As the holiday season nears, a new laptop for developing skills and personal projects is worth considering. The Dell XPS 13 7390, with an Intel® Core™ i7-10710U processor, is really enticing. Windows 10 Pro, an M.2 PCIe NVMe SDD, and non-touch display are motivating as well. As with other big purchases, a decision will require more than a month’s consideration.

Specifications:

  • Processor: 10th Generation Intel® Core™ i7-10710U Processor (12MB Cache, up to 4.7GHz, 6 cores)
  • Operating System: Microsoft Windows 10 Pro
  • Memory: 16GB LPDDR3 2133MHz
  • Hard Drive: 512GB M.2 PCIe NVMe SSD
  • Display: 13.3″ FHD (1920×1080) Non-Touch Display

Cross-Thread Manipulation of Windows Forms Controls

November 5th, 2019
Posted in Windows | No Comments

System.InvalidOperationException: Cross-thread operation not valid. Control "textBox1" accessed from a thread other than the thread it was created on.

The above exception was encountered while placing a function call with long execution time on a separate thread and having that thread update a TextBox with status updates. The issue arises, because “access to Windows Forms controls isn’t inherently thread-safe.”1

Documentation by Microsoft discusses the following solutions:

  • calling the Control.Invoke() method
  • using a BackgroundWorker component
  • setting Control.CheckforIllegalCrossThreadCalls property to false (unsafe)

Invoke() Method

This approach checks whether the currently running thread is the same thread that created the control. If the threads are different, then Invoke() is called to allow running a delegate in the control’s owner thread. Otherwise, the currently running thread is the owner of the control, and the control’s properties can be manipulated directly. This method is demonstrated by the following code snippet:

if (textBox1.InvokeRequired)
   textBox1.Invoke(
      new MethodInvoker(
         () => {textBox1.Text = "abc";} ) );
else
    textBox1.Text = "abc";

Using BackgroundWorker

BackgroundWorker raises three events: DoWork, ProgressChanged, and RunWorkerCompleted.

A DoWork event handler is where long duration functions are called away from the main thread. It runs in a thread separate from the thread that created the BackgroundWorker instance. Modifying a control’s properties from a DoWork event handler will throw System.InvalidOperationException().

The main thread usually creates user interface controls. It also maintains UI responsiveness typically by creating worker threads for lengthy functions. Because BackgroundWorker is likely created from the thread that creates user interface controls, and ProgressChanged and RunWorkerCompleted event handlers execute in the thread that creates BackgroundWorker, it is safe to modify UI controls from ProgressChanged and RunWorkerCompleted event handlers.

With the BackgroundWorker’s WorkerReportsProgress property set to true, event handlers for the BackgroundWorker’s DoWork event can call ReportProgress() to indirectly modify UI controls. ReportProgress() raises the ProgressChanged event, which causes calling of event handlers in the thread that created the BackgroundWorker.

The ReportProgress() method is overloaded. One version of ReportProgress() accepts an integer, which is typically used to represent a percentage of completion. The second version of ReportProgress() accepts an object as well as a percentage of completion. The version of ReportProgress() that accepts an object can be used by the DoWork event handler to send detailed data useful for updating UI controls.

A ProgressChanged event handler added to the BackgroundWorker by the main thread, can inspect the UserState property of the ProgressChangedEventArgs. This property is set to the object provided in the ReportProgress(int, object) call. To set textBox1.Text in the ongoing example, the DoWork event handler can call ReportProgress(0, “abc”) and the ProgressChanged event handler can cast the UserState property to a string and assign it to textBox1.Text:

private void backgroundWorker_ProgressChanged(
   object sender, ProgressChangedEventArgs e)
{
   string s = e.UserState as string;
   textBox1.Text = s;
}

Setting Control.CheckForIllegalCrossThreadCalls to false

Let’s not.

Using BackgroundWorker or the Invoke() method can be applied for different situations. The Invoke() method may be used by a worker thread to show a Modal dialog or MessageBox that prevents the main application form from receiving input while the dialog or MessageBox are displayed. BackgroundWorker allows lengthy methods to run in worker threads while providing feedback to the main thread. Both methods are acceptable mechanisms for cross-thread manipulation of Windows Forms.