<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.8" -->
<?xml-stylesheet href="http://wiki.nathancampos.me/lib/exe/css.php?s=feed" type="text/css"?>
<rdf:RDF
    xmlns="http://purl.org/rss/1.0/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel rdf:about="http://wiki.nathancampos.me/feed.php">
        <title>Nathan&#039;s KB</title>
        <description>Hello</description>
        <link>http://wiki.nathancampos.me/</link>
        <image rdf:resource="http://wiki.nathancampos.me/lib/exe/fetch.php?media=wiki:dokuwiki.svg" />
       <dc:date>2026-05-13T08:27:39+00:00</dc:date>
        <items>
            <rdf:Seq>
                <rdf:li rdf:resource="http://wiki.nathancampos.me/doku.php?id=log:openssl-self-ca"/>
                <rdf:li rdf:resource="http://wiki.nathancampos.me/doku.php?id=comp:8-inch-chinese-laptop"/>
                <rdf:li rdf:resource="http://wiki.nathancampos.me/doku.php?id=start"/>
                <rdf:li rdf:resource="http://wiki.nathancampos.me/doku.php?id=devnotes:msvc-porting"/>
                <rdf:li rdf:resource="http://wiki.nathancampos.me/doku.php?id=notes:change-uid"/>
                <rdf:li rdf:resource="http://wiki.nathancampos.me/doku.php?image=log%3Asoftether-securenat-prefs.png&amp;ns=log&amp;do=media"/>
                <rdf:li rdf:resource="http://wiki.nathancampos.me/doku.php?image=log%3Aiis7-php5-handler-config.png&amp;ns=log&amp;do=media"/>
                <rdf:li rdf:resource="http://wiki.nathancampos.me/doku.php?image=devnotes%3Anstableview-plus-minus-toolbar.png&amp;ns=devnotes&amp;do=media"/>
            </rdf:Seq>
        </items>
    </channel>
    <image rdf:about="http://wiki.nathancampos.me/lib/exe/fetch.php?media=wiki:dokuwiki.svg">
        <title>Nathan's KB</title>
        <link>http://wiki.nathancampos.me/</link>
        <url>http://wiki.nathancampos.me/lib/exe/fetch.php?media=wiki:dokuwiki.svg</url>
    </image>
    <item rdf:about="http://wiki.nathancampos.me/doku.php?id=log:openssl-self-ca">
        <dc:format>text/html</dc:format>
        <dc:date>2026-05-02T08:19:58+00:00</dc:date>
        <dc:creator>nathanpc (nathanpc@undisclosed.example.com)</dc:creator>
        <title>openssl-self-ca - [Windows] </title>
        <link>http://wiki.nathancampos.me/doku.php?id=log:openssl-self-ca</link>
        <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;self-hosted_root_ca_using_openssl&quot;&gt;Self-hosted Root CA using OpenSSL&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Do you hate how modern web browsers complain about using HTTP as if it&amp;#039;s actually insecure to read plain text? It&amp;#039;s extremely dumb to think that self-hosted infrastructure is insecure and must be accessed via HTTPS, especially when it&amp;#039;s only accessible locally or via a VPN, but here we are.
&lt;/p&gt;

&lt;p&gt;
Modern browsers block these “insecure” websites from accessing your camera, microphone, and even the clipboard, and some of these features may be important for some homelab applications. Thus the need for you becoming your own Root CA arrises.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Self-hosted Root CA using OpenSSL&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;self-hosted_root_ca_using_openssl&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-587&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;building_the_certificate_authority&quot;&gt;Building the Certificate Authority&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
This is how you can run your own CA infrastructure easily using only the default install of &lt;a href=&quot;https://www.openbsd.org/&quot; class=&quot;urlextern&quot; title=&quot;https://www.openbsd.org/&quot; rel=&quot;ugc nofollow&quot;&gt;OpenBSD 7&lt;/a&gt;. Unless otherwise noted all steps taken here assume the root folder of the CA resides in the &lt;code&gt;/ca&lt;/code&gt; directory at the root of your system drive.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Building the Certificate Authority&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;building_the_certificate_authority&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;588-912&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit3&quot; id=&quot;creating_the_folder_structure&quot;&gt;Creating the Folder Structure&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
A Trusted Root Certificate Authority is a serious business, so you should be serious about the organization of your operation, for this I have created the following folder structure to ensure the CA infrastructure that is built is actually scalable and organized:
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;ca        &lt;span class=&quot;co0&quot;&gt;# The root of our CA infrastructure.&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;ca&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;root   &lt;span class=&quot;co0&quot;&gt;# Stores the Root Certificate.&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;ca&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;certs  &lt;span class=&quot;co0&quot;&gt;# Stores the self-signed domain certificates we issue.&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;ca&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;utils  &lt;span class=&quot;co0&quot;&gt;# Contains utility scripts to manage our operation.&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
If you&amp;#039;re following this guide, this folder structure is expected to be in place.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Creating the Folder Structure&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;creating_the_folder_structure&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;913-1565&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;getting_a_root_certificate&quot;&gt;Getting a Root Certificate&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The root certificate will be responsible for creating the chain of trust of all your issued certificates. It&amp;#039;s also &lt;strong&gt;the only one that will have to be installed&lt;/strong&gt; in your clients to allow them to accept your self-signed certificates for all your locally-hosted websites. To create a root certificate you&amp;#039;ll have to do the following:
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;ca&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;root
openssl genrsa &lt;span class=&quot;re5&quot;&gt;-des3&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-out&lt;/span&gt; root.key &lt;span class=&quot;nu0&quot;&gt;2048&lt;/span&gt;
openssl req &lt;span class=&quot;re5&quot;&gt;-x509&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-new&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-nodes&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-key&lt;/span&gt; root.key &lt;span class=&quot;re5&quot;&gt;-sha256&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-days&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;3650&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-out&lt;/span&gt; root.pem&lt;/pre&gt;

&lt;p&gt;
I won&amp;#039;t pretend to understand exactly the implications of my decisions here in terms of parameters, but this should create a root certificate that will be good for 10 years.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Getting a Root Certificate&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;getting_a_root_certificate&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;1566-2263&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit5&quot; id=&quot;generating_openssl_configuration&quot;&gt;Generating OpenSSL Configuration&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The next step in achieving your status as a Trusted Certificate Authority is to create the OpenSSL configuration files used when generating new certificate requests. The OpenSSL certificate creation process must always go through a signing request procedure, even if you&amp;#039;re doing so on the same machine.
&lt;/p&gt;

&lt;p&gt;
This configuration file is the base of every certificate we generate and most of its contents are the same for every new request, so I have built this handy Perl script that takes care of the configuration file generation for you:
&lt;/p&gt;
&lt;pre class=&quot;code perl&quot;&gt;&lt;span class=&quot;co1&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;# Save this script to /ca/utils/make-config.pl&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;coMULTI&quot;&gt;=head1 DESCRIPTION
&amp;nbsp;
Builds the OpenSSL configuration file to request a certificate for a domain.
&amp;nbsp;
=cut&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;use&lt;/span&gt; warnings&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;use&lt;/span&gt; strict&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;use&lt;/span&gt; autodie&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;use&lt;/span&gt; File&lt;span class=&quot;sy0&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;me2&quot;&gt;Basename&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;# Main entry point.&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;sub&lt;/span&gt; main &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://perldoc.perl.org/functions/scalar.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;scalar&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;a href=&quot;http://perldoc.perl.org/functions/die.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;die&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;The domain name of the certificate must be provided.&lt;span class=&quot;es0&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;co1&quot;&gt;# Get the domain name.&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$domain&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$ARGV&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;co1&quot;&gt;# Remind the user that this tool always generates wild card certs.&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://perldoc.perl.org/functions/substr.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;substr&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$domain&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;*&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;a href=&quot;http://perldoc.perl.org/functions/die.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;die&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;This tool generates wildcard certificates. Remove *.&lt;span class=&quot;es0&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;co1&quot;&gt;# Make the folder and write the configuration file.&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$cldomain&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$folder&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; make_folder&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$domain&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;a href=&quot;http://perldoc.perl.org/functions/open.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;open&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$fh&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;&amp;gt;&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;$folder/openssl.conf&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;a href=&quot;http://perldoc.perl.org/functions/print.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;print&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;re0&quot;&gt;$fh&lt;/span&gt; build_config&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$domain&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;a href=&quot;http://perldoc.perl.org/functions/close.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;close&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;re0&quot;&gt;$fh&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;a href=&quot;http://perldoc.perl.org/functions/print.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;print&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;$cldomain&lt;span class=&quot;es0&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;# Creates the folder for the certificate and config, and returns its path.&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;sub&lt;/span&gt; make_folder &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$domain&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;co5&quot;&gt;@_&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$cld&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$domain&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;co1&quot;&gt;# Get the path to the certificate folder and make it.&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$folder&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; dirname&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;dirname&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;__FILE__&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;/certs/$cld&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;a href=&quot;http://perldoc.perl.org/functions/mkdir.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;mkdir&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;re0&quot;&gt;$folder&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;a href=&quot;http://perldoc.perl.org/functions/return.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;return&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$cld&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$folder&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;# Builds the configuration for the certificate.&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;sub&lt;/span&gt; build_config &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$domain&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;co5&quot;&gt;@_&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;a href=&quot;http://perldoc.perl.org/functions/return.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;return&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;co4&quot;&gt;&amp;lt;&amp;lt;&amp;quot;CONFIG&amp;quot;;
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = XX
ST = Your State
L = Your Neighbourhood
O = Your Totally Legit Company
OU = CA
CN = *.$domain
[v3_req]
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = \@alt_names
[alt_names]
DNS.1 = $domain
DNS.2 = *.$domain
&amp;nbsp;
CONFIG&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
main&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;__END__&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;coMULTI&quot;&gt;=head1 AUTHOR
&amp;nbsp;
Nathan Campos &amp;lt;nathan@innoveworkshop.com&amp;gt;
&amp;nbsp;
=head1 COPYRIGHT
&amp;nbsp;
Copyright (c) 2024- Nathan Campos.
&amp;nbsp;
=cut&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
You should edit the contents of the configuration template just below the &lt;code&gt;[req_distinguished_name]&lt;/code&gt; line to suit your environment. Be sure to be clever when populating these values in.
&lt;/p&gt;

&lt;p&gt;
This script should be placed in the &lt;code&gt;/ca/utils&lt;/code&gt; directory with the name &lt;code&gt;make-config.pl&lt;/code&gt; so that the certificate issuing script can make use of it.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Generating OpenSSL Configuration&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;generating_openssl_configuration&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;2264-5015&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit6&quot; id=&quot;issuing_certificates&quot;&gt;Issuing Certificates&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Issuing a certificate using OpenSSL is a painful process and extremely easy to get wrong or simply get bored of typing a bunch of commands for something that you just want to get over with. Just like I did with the configuration file, here&amp;#039;s a shell script that should automate the whole process for you:
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;co0&quot;&gt;#!/usr/local/bin/bash&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Ensure we stop on error.&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-e&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Ensure we have the right amount of command-line arguments.&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;re4&quot;&gt;$#&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-ne&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;; &lt;span class=&quot;kw1&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;usage: $0 &amp;lt;domain&amp;gt; &amp;lt;desc&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;
    &lt;span class=&quot;kw3&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;fi&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Create certificate directory and configuration file.&lt;/span&gt;
&lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Creating the configuration for the certificate request...&amp;quot;&lt;/span&gt;
&lt;span class=&quot;re2&quot;&gt;CLDOMAIN&lt;/span&gt;=$&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;.&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;utils&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;make-config.pl &lt;span class=&quot;re4&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;re2&quot;&gt;CERTDESC&lt;/span&gt;=&lt;span class=&quot;re4&quot;&gt;$2&lt;/span&gt;
&lt;span class=&quot;kw3&quot;&gt;pushd&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;certs/&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;&amp;quot;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Create the certificate request.&lt;/span&gt;
&lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Building private key and certificate request for $1 as &lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;&amp;quot;&lt;/span&gt;
openssl genrsa &lt;span class=&quot;re5&quot;&gt;-out&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.key&amp;quot;&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2048&lt;/span&gt;
&lt;span class=&quot;co0&quot;&gt;#openssl genrsa -des3 -out &amp;quot;$CLDOMAIN.key&amp;quot; 2048&lt;/span&gt;
openssl req &lt;span class=&quot;re5&quot;&gt;-new&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-out&lt;/span&gt; request.csr &lt;span class=&quot;re5&quot;&gt;-key&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.key&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-config&lt;/span&gt; openssl.conf
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Create signed certificate.&lt;/span&gt;
&lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Signing certificate for 5 years...&amp;quot;&lt;/span&gt;
openssl x509 &lt;span class=&quot;re5&quot;&gt;-req&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-in&lt;/span&gt; request.csr &lt;span class=&quot;re5&quot;&gt;-CA&lt;/span&gt; ..&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;..&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;root&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;root.pem &lt;span class=&quot;re5&quot;&gt;-CAkey&lt;/span&gt; ..&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;..&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;root&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;root.key \
    &lt;span class=&quot;re5&quot;&gt;-CAcreateserial&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-out&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.crt&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-days&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1827&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-sha256&lt;/span&gt; \
    &lt;span class=&quot;re5&quot;&gt;-extensions&lt;/span&gt; v3_req &lt;span class=&quot;re5&quot;&gt;-extfile&lt;/span&gt; openssl.conf
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Packaging the certificate.&lt;/span&gt;
&lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Packaging the certificate in PKCS#12 format...&amp;quot;&lt;/span&gt;
openssl pkcs12 &lt;span class=&quot;re5&quot;&gt;-export&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-out&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.p12&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-inkey&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.key&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-in&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.crt&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-certfile&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.crt&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CERTDESC&lt;/span&gt;&amp;quot;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Extracting keys in SSH format.&lt;/span&gt;
&lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Extracting keys in SSH format...&amp;quot;&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.key&amp;quot;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;|&lt;/span&gt; openssl rsa &lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt; id_rsa
openssl rsa &lt;span class=&quot;re5&quot;&gt;-in&lt;/span&gt; id_rsa &lt;span class=&quot;re5&quot;&gt;-pubout&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;ssh-keygen&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;dev&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;stdin &lt;span class=&quot;re5&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-m&lt;/span&gt; PKCS8 &lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt; id_rsa.pub
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Check our certificate.&lt;/span&gt;
&lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Checking the generated certificate...&amp;quot;&lt;/span&gt;
openssl verify &lt;span class=&quot;re5&quot;&gt;-CAfile&lt;/span&gt; ..&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;..&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;root&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;root.pem &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.crt&amp;quot;&lt;/span&gt;
openssl x509 &lt;span class=&quot;re5&quot;&gt;-text&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-noout&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-in&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.crt&amp;quot;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-14&lt;/span&gt;
&lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;...&amp;quot;&lt;/span&gt;
openssl x509 &lt;span class=&quot;re5&quot;&gt;-text&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-noout&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-in&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es2&quot;&gt;$CLDOMAIN&lt;/span&gt;.crt&amp;quot;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;grep&lt;/span&gt; DNS
&amp;nbsp;
&lt;span class=&quot;kw3&quot;&gt;popd&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
This script should issue certificates that are valid for 5 years and exports the public and private keys to every format that you may need, so the generated certificate can be used for web servers, SSH, and basically anything under the sun.
&lt;/p&gt;

&lt;p&gt;
As can be inferred from the usage line in the script, it takes a domain and a description. The description is a bit of text that&amp;#039;s associated with the certificate and can be viewed by visitors of your website. The &lt;code&gt;domain&lt;/code&gt; argument should not contain a wildcard since the &lt;code&gt;make-config.pl&lt;/code&gt; script should take care of this automatically for you.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Issuing Certificates&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;issuing_certificates&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;5016-7572&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit7&quot; id=&quot;adding_ssl_to_your_servers&quot;&gt;Adding SSL to Your Servers&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The next logical step is to ensure that your servers can actually serve content with your self-signed certificates.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Adding SSL to Your Servers&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;adding_ssl_to_your_servers&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;7573-7729&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit8&quot; id=&quot;nginx_proxy_manager&quot;&gt;Nginx Proxy Manager&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
I like my home servers to be as easy to configure and maintain as possible, not to be the most secure or follow enterprise-grade best practices, so I use the humble &lt;a href=&quot;https://nginxproxymanager.com/&quot; class=&quot;urlextern&quot; title=&quot;https://nginxproxymanager.com/&quot; rel=&quot;ugc nofollow&quot;&gt;Nginx Proxy Manager&lt;/a&gt; as the &lt;a href=&quot;https://en.wikipedia.org/wiki/Reverse_proxy&quot; class=&quot;urlextern&quot; title=&quot;https://en.wikipedia.org/wiki/Reverse_proxy&quot; rel=&quot;ugc nofollow&quot;&gt;reverse proxy&lt;/a&gt; for all my self-hosted applications.
&lt;/p&gt;

&lt;p&gt;
To add your self-signed certificates to your NPM instance you&amp;#039;ll need to download the &lt;code&gt;domain.crt&lt;/code&gt; and &lt;code&gt;domain.key&lt;/code&gt; files from the CA server.
&lt;/p&gt;

&lt;p&gt;
Inside NPM you&amp;#039;ll navigate to the &lt;strong&gt;SSL Certificates&lt;/strong&gt; tab and click &lt;strong&gt;Add SSL Certificate&lt;/strong&gt; and select &lt;code&gt;Custom&lt;/code&gt;. Now all you have to do is fill in the form with the following:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Name: Whatever you want&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Certificate Key: &lt;code&gt;domain.key&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Certificate: &lt;code&gt;domain.crt&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The last step is to associate the newly added SSL certificate to the domain it belongs to in the Proxy Hosts page by selecting the proxy host you want to edit and going to the SSL tab.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Nginx Proxy Manager&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;nginx_proxy_manager&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;7730-8697&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit9&quot; id=&quot;getting_clients_to_trust_you&quot;&gt;Getting Clients to Trust You&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Having your own CA is all well and good, but you need to ensure that your clients trust your self-signed certificates, for this you&amp;#039;ll have to add the &lt;code&gt;root.cer&lt;/code&gt; Root Certificate to the list of trusted sources in your clients, and this process is extremely different from system to system, and even may require you to add the certificate to individual applications such as web browsers.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Getting Clients to Trust You&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;getting_clients_to_trust_you&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:9,&amp;quot;range&amp;quot;:&amp;quot;8698-9129&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit10&quot; id=&quot;chromium_and_chromeos&quot;&gt;Chromium and ChromeOS&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
On &lt;a href=&quot;https://en.wikipedia.org/wiki/Chromium_(web_browser)#Browsers_based_on_Chromium&quot; class=&quot;urlextern&quot; title=&quot;https://en.wikipedia.org/wiki/Chromium_(web_browser)#Browsers_based_on_Chromium&quot; rel=&quot;ugc nofollow&quot;&gt;Chromium-based browsers&lt;/a&gt; and &lt;a href=&quot;https://chromeos.google/&quot; class=&quot;urlextern&quot; title=&quot;https://chromeos.google/&quot; rel=&quot;ugc nofollow&quot;&gt;ChromeOS&lt;/a&gt;, you can add your Root Certificate by navigating to the Certificate Manager located at chrome://certificate-manager/localcerts and in the &lt;strong&gt;Custom&lt;/strong&gt; section, click on the &lt;strong&gt;Installed by you&lt;/strong&gt; card.
&lt;/p&gt;

&lt;p&gt;
In the next window, you should import the &lt;code&gt;root.cer&lt;/code&gt; certificate file to the &lt;strong&gt;Trusted Certificates&lt;/strong&gt; section. You should now be able to access your self-hosted services using the needlessly complex HTTPS.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Chromium and ChromeOS&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;chromium_and_chromeos&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:10,&amp;quot;range&amp;quot;:&amp;quot;9130-9727&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit11&quot; id=&quot;windows&quot;&gt;Windows&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Adding the generated root certificate under Windows involves opening the &lt;code&gt;certlm.msc&lt;/code&gt; MMC Plug-In and right-clicking the &lt;strong&gt;Trusted Root Certification Authorities&lt;/strong&gt; folder. In the context menu, you should select &lt;strong&gt;All Tasks &amp;gt; Import…&lt;/strong&gt; and follow the wizard, eventually browsing to the &lt;code&gt;root.cer&lt;/code&gt; certificate file and importing it. While in the wizard, ensure that the “Local Machine” option is selected as the Store Location, since this will ensure that the Root Certificate Authority is trusted system-wide.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Windows&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;windows&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:11,&amp;quot;range&amp;quot;:&amp;quot;9728-10262&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit12&quot; id=&quot;linux&quot;&gt;Linux&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
First make sure you rename the &lt;code&gt;root.cer&lt;/code&gt; file to &lt;code&gt;root.crt&lt;/code&gt;, since it&amp;#039;s required to have the &lt;code&gt;crt&lt;/code&gt; extension for it to be picked up by the certificate manager. Then run the following commands as &lt;code&gt;root&lt;/code&gt; to move the file to its appropriate place and reload the certificate store:
&lt;/p&gt;
&lt;pre class=&quot;code sh&quot;&gt;mkdir -p /usr/local/share/ca-certificates/homelab
cp root.crt /usr/local/share/ca-certificates/homelab/
update-ca-certificates&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Linux&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;linux&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:12,&amp;quot;range&amp;quot;:&amp;quot;10263-&amp;quot;} --&gt;</description>
    </item>
    <item rdf:about="http://wiki.nathancampos.me/doku.php?id=comp:8-inch-chinese-laptop">
        <dc:format>text/html</dc:format>
        <dc:date>2026-05-02T07:26:01+00:00</dc:date>
        <dc:creator>nathanpc (nathanpc@undisclosed.example.com)</dc:creator>
        <title>8-inch-chinese-laptop - [Fixing the keyboard] </title>
        <link>http://wiki.nathancampos.me/doku.php?id=comp:8-inch-chinese-laptop</link>
        <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;chinese_laptop&quot;&gt;8&amp;quot; Chinese Laptop&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
A tiny 8“ Intel-based laptop from China that comes in a box with no description and can be bought for very cheap on Amazon and AliExpress. It&amp;#039;s the pinnacle of modern computing, the successor to the VAIO P-series, the closest thing that we can have to a modern HPC.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;8\&amp;quot; Chinese Laptop&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;chinese_laptop&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-300&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;fixing_the_keyboard&quot;&gt;Fixing the keyboard&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Upon closer inspection you will notice that, due to it&amp;#039;s tiny size, the keyboard layout is absolutely insane. Not only that, but some decisions regarding the button placement are absolutely maddening. To fix these issues under &lt;code&gt;X11&lt;/code&gt;, the following can be added to the &lt;code&gt;~/.xmodmap&lt;/code&gt; file:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;clear lock
keycode 66 = Tab
keycode 23 = Caps_Lock
keycode 22 = Delete
keycode 119 = BackSpace&lt;/pre&gt;

&lt;p&gt;
If you&amp;#039;re on Wayland, use &lt;a href=&quot;https://github.com/sezanzeb/input-remapper&quot; class=&quot;urlextern&quot; title=&quot;https://github.com/sezanzeb/input-remapper&quot; rel=&quot;ugc nofollow&quot;&gt;Input Remapper&lt;/a&gt; to easily remap the keys listed above.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Fixing the keyboard&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;fixing_the_keyboard&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;301-863&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;fixing_rotated_console&quot;&gt;Fixing rotated console&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Upon first boot you will notice that the boot logs are rotated to the vertical position, since the firmware of this laptop is most likely based on a tablet form-factor. This makes no sense, so change the following in the &lt;code&gt;/etc/defaults/grub&lt;/code&gt; to make the boot console landscape:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;GRUB_CMDLINE_LINUX=&amp;quot;fbcon=rotate:1&amp;quot;&lt;/pre&gt;

&lt;p&gt;
Don&amp;#039;t forget to run &lt;code&gt;update-grub&lt;/code&gt; for the changes to actually take effect.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Fixing rotated console&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;fixing_rotated_console&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;864-&amp;quot;} --&gt;</description>
    </item>
    <item rdf:about="http://wiki.nathancampos.me/doku.php?id=start">
        <dc:format>text/html</dc:format>
        <dc:date>2026-05-02T06:37:40+00:00</dc:date>
        <dc:creator>nathanpc (nathanpc@undisclosed.example.com)</dc:creator>
        <title>start - [Computers] </title>
        <link>http://wiki.nathancampos.me/doku.php?id=start</link>
        <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;nathan_s_knowledge_base&quot;&gt;Nathan&amp;#039;s Knowledge Base&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Welcome to the place where all of the information gathered by &lt;a href=&quot;http://nathancampos.me/&quot; class=&quot;urlextern&quot; title=&quot;http://nathancampos.me/&quot; rel=&quot;ugc nofollow&quot;&gt;Nathan Campos&lt;/a&gt; in his adventures through the depths of programming, software, and hardware ends up. Keep in mind that this is supposed to be a living &lt;a href=&quot;https://en.wikipedia.org/wiki/Knowledge_base&quot; class=&quot;urlextern&quot; title=&quot;https://en.wikipedia.org/wiki/Knowledge_base&quot; rel=&quot;ugc nofollow&quot;&gt;knowledge base&lt;/a&gt; that is updated while he&amp;#039;s researching a specific topic or working on a specific project.
&lt;/p&gt;

&lt;p&gt;
Since he rarely has time to organize the topics into nice category pages, we recommend that, to get a taste of what this wiki has to offer, you should check out its sitemap.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Nathan&amp;#039;s Knowledge Base&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;nathan_s_knowledge_base&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-608&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;programming&quot;&gt;Programming&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Programming&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;programming&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;609-633&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit3&quot; id=&quot;development_notes&quot;&gt;Development Notes&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Some programming notes that are filled with quirks and information gathered from projects.
&lt;/p&gt;

&lt;/div&gt;

&lt;h4 id=&quot;projects&quot;&gt;Projects&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=devnotes:groundlift&quot; class=&quot;wikilink1&quot; title=&quot;devnotes:groundlift&quot; data-wiki-id=&quot;devnotes:groundlift&quot;&gt;GroundLift&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=devnotes:shortcircuit&quot; class=&quot;wikilink1&quot; title=&quot;devnotes:shortcircuit&quot; data-wiki-id=&quot;devnotes:shortcircuit&quot;&gt;Shortcircuit&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;

&lt;h4 id=&quot;platforms&quot;&gt;Platforms&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=devnotes:msvc-porting&quot; class=&quot;wikilink1&quot; title=&quot;devnotes:msvc-porting&quot; data-wiki-id=&quot;devnotes:msvc-porting&quot;&gt;Porting to Microsoft Visual C++&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=devnotes:netaddr&quot; class=&quot;wikilink1&quot; title=&quot;devnotes:netaddr&quot; data-wiki-id=&quot;devnotes:netaddr&quot;&gt;Network Addressing Programatically&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=devnotes:unity&quot; class=&quot;wikilink1&quot; title=&quot;devnotes:unity&quot; data-wiki-id=&quot;devnotes:unity&quot;&gt;Unity Game Engine&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=devnotes:macos&quot; class=&quot;wikilink1&quot; title=&quot;devnotes:macos&quot; data-wiki-id=&quot;devnotes:macos&quot;&gt;Mac OS X Development Notes&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Development Notes&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;development_notes&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;634-1088&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;programming_languages&quot;&gt;Programming Languages&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
A collection of best practices and resources specific to certain programming languages.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=lang:cpp&quot; class=&quot;wikilink1&quot; title=&quot;lang:cpp&quot; data-wiki-id=&quot;lang:cpp&quot;&gt;C++&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=lang:python&quot; class=&quot;wikilink1&quot; title=&quot;lang:python&quot; data-wiki-id=&quot;lang:python&quot;&gt;Python&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Some snippets that are useful for a variety of occasions:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=snippets:win32&quot; class=&quot;wikilink1&quot; title=&quot;snippets:win32&quot; data-wiki-id=&quot;snippets:win32&quot;&gt;Win32 Programming Snippets&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Programming Languages&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;programming_languages&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;1089-1369&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit5&quot; id=&quot;computers&quot;&gt;Computers&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
A random assortment of computery things and references for me to later never consult.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Computers&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;computers&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;1370-1479&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit6&quot; id=&quot;hardware&quot;&gt;Hardware&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Hardware that&amp;#039;s so special that it might as well be documented in case I may need to ever set it up again.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=comp:8-inch-chinese-laptop&quot; class=&quot;wikilink1&quot; title=&quot;comp:8-inch-chinese-laptop&quot; data-wiki-id=&quot;comp:8-inch-chinese-laptop&quot;&gt;8&amp;quot; Chinese Laptop&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Hardware&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;hardware&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;1480-1662&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit7&quot; id=&quot;windows&quot;&gt;Windows&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=comp:win7&quot; class=&quot;wikilink1&quot; title=&quot;comp:win7&quot; data-wiki-id=&quot;comp:win7&quot;&gt;Windows 7 and Server 2008 R2&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=comp:setup-sbs2011&quot; class=&quot;wikilink1&quot; title=&quot;comp:setup-sbs2011&quot; data-wiki-id=&quot;comp:setup-sbs2011&quot;&gt;Setting up SBS 2011 in 2025&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=comp:win11:windows_11_iot_enterprise_ltsc&quot; class=&quot;wikilink1&quot; title=&quot;comp:win11:windows_11_iot_enterprise_ltsc&quot; data-wiki-id=&quot;comp:win11:windows_11_iot_enterprise_ltsc&quot;&gt;Windows 11 IoT Enterprise LTSC&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Windows&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;windows&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;1663-1833&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit8&quot; id=&quot;unix&quot;&gt;Unix&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=comp:ubuntu-lucid&quot; class=&quot;wikilink1&quot; title=&quot;comp:ubuntu-lucid&quot; data-wiki-id=&quot;comp:ubuntu-lucid&quot;&gt;Ubuntu 10.04 Lucid Lynx&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=comp:macos&quot; class=&quot;wikilink1&quot; title=&quot;comp:macos&quot; data-wiki-id=&quot;comp:macos&quot;&gt;Mac OS X&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=notes:fix-unix-perms&quot; class=&quot;wikilink1&quot; title=&quot;notes:fix-unix-perms&quot; data-wiki-id=&quot;notes:fix-unix-perms&quot;&gt;Fixing UNIX Permissions&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=notes:change-uid&quot; class=&quot;wikilink1&quot; title=&quot;notes:change-uid&quot; data-wiki-id=&quot;notes:change-uid&quot;&gt;Changing a User&amp;#039;s UID&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Unix&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;unix&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;1834-2028&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit9&quot; id=&quot;projects1&quot;&gt;Projects&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Some of the projects that we are either currently working on have worked on in the past.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=projects:groundlift&quot; class=&quot;wikilink1&quot; title=&quot;projects:groundlift&quot; data-wiki-id=&quot;projects:groundlift&quot;&gt;GroundLift&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=projects:remindmate&quot; class=&quot;wikilink1&quot; title=&quot;projects:remindmate&quot; data-wiki-id=&quot;projects:remindmate&quot;&gt;RedmindMate&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Projects&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;projects1&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:9,&amp;quot;range&amp;quot;:&amp;quot;2029-2220&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit10&quot; id=&quot;ideas&quot;&gt;Ideas&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Some of the ideas that we have for future projects that have yet to materialize.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=idea:emacs-cheatsheet&quot; class=&quot;wikilink1&quot; title=&quot;idea:emacs-cheatsheet&quot; data-wiki-id=&quot;idea:emacs-cheatsheet&quot;&gt;Emacs Cheatsheet&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=idea:tonw&quot; class=&quot;wikilink1&quot; title=&quot;idea:tonw&quot; data-wiki-id=&quot;idea:tonw&quot;&gt;The Old New Web&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Ideas&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;ideas&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:10,&amp;quot;range&amp;quot;:&amp;quot;2221-2401&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit11&quot; id=&quot;solar-powered_windows_server&quot;&gt;Solar-powered Windows Server&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
One of the weirdest things I&amp;#039;ve done in my life, but it sure is fun to have your own website hosted in a bizarre, sustainable, and mostly self-sufficient manner. Here are some of the things I&amp;#039;ve documented along the way:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=log:php-windows&quot; class=&quot;wikilink1&quot; title=&quot;log:php-windows&quot; data-wiki-id=&quot;log:php-windows&quot;&gt;PHP 5.6 on Windows Server 2008 and IIS&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=log:public-local-server&quot; class=&quot;wikilink1&quot; title=&quot;log:public-local-server&quot; data-wiki-id=&quot;log:public-local-server&quot;&gt;Exposing a Local Server to the Public Internet Safely&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=log:uz801-openwrt&quot; class=&quot;wikilink1&quot; title=&quot;log:uz801-openwrt&quot; data-wiki-id=&quot;log:uz801-openwrt&quot;&gt;Running OpenWRT on a UZ801 USB 4G Modem&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Solar-powered Windows Server&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;solar-powered_windows_server&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:11,&amp;quot;range&amp;quot;:&amp;quot;2402-2879&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit12&quot; id=&quot;self-hosted_certificate_authority&quot;&gt;Self-hosted Certificate Authority&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
I guess every homelab owner has had the urge to become a CA and start issuing certificates for internal domains to use HTTPS and quiet down modern browsers.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.nathancampos.me/doku.php?id=log:openssl-self-ca&quot; class=&quot;wikilink1&quot; title=&quot;log:openssl-self-ca&quot; data-wiki-id=&quot;log:openssl-self-ca&quot;&gt;Homelab Root CA using OpenSSL&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Self-hosted Certificate Authority&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;self-hosted_certificate_authority&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:12,&amp;quot;range&amp;quot;:&amp;quot;2880-&amp;quot;} --&gt;</description>
    </item>
    <item rdf:about="http://wiki.nathancampos.me/doku.php?id=devnotes:msvc-porting">
        <dc:format>text/html</dc:format>
        <dc:date>2026-02-01T16:49:55+00:00</dc:date>
        <dc:creator>nathanpc (nathanpc@undisclosed.example.com)</dc:creator>
        <title>msvc-porting - [SO_RCVTIMEO Timeout Argument] </title>
        <link>http://wiki.nathancampos.me/doku.php?id=devnotes:msvc-porting</link>
        <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;porting_to_microsoft_visual_c&quot;&gt;Porting to Microsoft Visual C++&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Microsoft&amp;#039;s compiler is filled with weird quirks and was literally &lt;a href=&quot;https://stackoverflow.com/questions/48615184/does-visual-studio-2017-fully-support-c99&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/questions/48615184/does-visual-studio-2017-fully-support-c99&quot; rel=&quot;ugc nofollow&quot;&gt;not C99-compliant until 2019&lt;/a&gt;, which means it is quite difficult to port software meant for a more standards-compliant compiler to it. This page means to compile everything that we may want or need to know in order to port our code to this awful compiler.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Porting to Microsoft Visual C++&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;porting_to_microsoft_visual_c&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-461&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;installing_on_modern_systems&quot;&gt;Installing on Modern Systems&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Since Visual Studio 6.0 is extremely old it&amp;#039;s expected that you may encounter some roadblocks when trying to install it on more modern systems. If you&amp;#039;re on Windows XP or earlier you don&amp;#039;t have to do anything, simply install as usual and everything should work out-of-the-box.
&lt;/p&gt;

&lt;p&gt;
If you are on Windows Vista or 7, as per &lt;a href=&quot;https://www.itwriting.com/blog/167-visual-studio-6-on-vista.html&quot; class=&quot;urlextern&quot; title=&quot;https://www.itwriting.com/blog/167-visual-studio-6-on-vista.html&quot; rel=&quot;ugc nofollow&quot;&gt;this blog post&lt;/a&gt;, you should deselect the &lt;code&gt;Tools | OLE/COM Object Viewer&lt;/code&gt; when installing, otherwise the installation will fail with an “RegCreateKey failed for \Interface\OLEViewerIViewerCLSID. Access is denied” error. Now if you are on Windows 8, 10 or later you should &lt;a href=&quot;https://www.codeproject.com/Articles/1191047/Install-Visual-Studio-6-0-on-Windows-10&quot; class=&quot;urlextern&quot; title=&quot;https://www.codeproject.com/Articles/1191047/Install-Visual-Studio-6-0-on-Windows-10&quot; rel=&quot;ugc nofollow&quot;&gt;follow these instructions&lt;/a&gt; and at the time can only install Visual Basic 6, no Visual C++ 6 yet.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Installing on Modern Systems&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;installing_on_modern_systems&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;462-1349&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;unicode&quot;&gt;Unicode&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The most dreaded aspect of programming for Windows… Having to use UTF-16 for Unicode is just awful, but sadly it&amp;#039;s what was available at the time that Microsoft needed strings that could represent characters from all over the world. This horrible decision in the past means that today where we live in a more civilized, UTF-8 society, we have to be constantly performing conversions between &lt;code&gt;MBCS&lt;/code&gt; and &lt;code&gt;WCHAR&lt;/code&gt; when programming for Windows, this can be easily done with a couple of helper functions since Microsoft&amp;#039;s &lt;abbr title=&quot;Application Programming Interface&quot;&gt;API&lt;/abbr&gt; for this is absolutely awful:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/**
 * Converts a UTF-8 multibyte string into an UTF-16 wide-character string.
 * @warning This function allocates memory that must be free&#039;d by you!
 *
 * @param str UTF-8 string to be converted.
 *
 * @return UTF-16 wide-character converted string or NULL if an error occurred.
 */&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;wchar_t&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;utf16_mbstowcs&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;str&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
	&lt;span class=&quot;kw4&quot;&gt;wchar_t&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;wstr&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co2&quot;&gt;#ifdef _WIN32&lt;/span&gt;
	&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; nLen&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Get required buffer size and allocate some memory for it. */&lt;/span&gt;
	wstr &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	nLen &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; MultiByteToWideChar&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;GL_CODEPAGE&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; str&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;nLen &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;goto&lt;/span&gt; failure&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	wstr &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;wchar_t&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;malloc&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;nLen &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;wchar_t&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;wstr &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; NULL&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Perform the conversion. */&lt;/span&gt;
	nLen &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; MultiByteToWideChar&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;GL_CODEPAGE&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; str&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; wstr&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; nLen&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;nLen &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
failure&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
		MessageBox&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;NULL&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; _T&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;Failed to convert UTF-8 string to UTF-16.&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
			_T&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;String Conversion Failure&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; MB_ICONERROR &lt;span class=&quot;sy0&quot;&gt;|&lt;/span&gt; MB_OK&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;wstr&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
			&lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/free.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;free&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;wstr&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#else&lt;/span&gt;
	&lt;span class=&quot;kw4&quot;&gt;size_t&lt;/span&gt; len&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Allocate some memory for our converted string. */&lt;/span&gt;
	len &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; mbstowcs&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;NULL&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; str&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	wstr &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;wchar_t&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;malloc&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;len &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;wchar_t&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;wstr &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; NULL&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Perform the string conversion. */&lt;/span&gt;
	len &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; mbstowcs&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;wstr&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; str&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; len&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;len &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;size_t&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		&lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/free.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;free&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;wstr&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif /* _WIN32 */&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; wstr&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;coMULTI&quot;&gt;/**
 * Converts a UTF-16 wide-character string into a UTF-8 multibyte string.
 * @warning This function allocates memory that must be free&#039;d by you!
 *
 * @param wstr UTF-16 string to be converted.
 *
 * @return UTF-8 multibyte converted string or NULL if an error occurred.
 */&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;utf16_wcstombs&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;wchar_t&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;wstr&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
	&lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;str&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co2&quot;&gt;#ifdef _WIN32&lt;/span&gt;
	&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; nLen&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Get required buffer size and allocate some memory for it. */&lt;/span&gt;
	nLen &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; WideCharToMultiByte&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;GL_CODEPAGE&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; wstr&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; NULL&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;nLen &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;goto&lt;/span&gt; failure&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	str &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;malloc&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;nLen &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;str &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; NULL&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Perform the conversion. */&lt;/span&gt;
	nLen &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; WideCharToMultiByte&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;GL_CODEPAGE&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; wstr&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; str&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; nLen&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
							   NULL&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;nLen &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
failure&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
		MessageBox&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;NULL&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; _T&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;Failed to convert UTF-16 string to UTF-8.&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
			_T&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;String Conversion Failure&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; MB_ICONERROR &lt;span class=&quot;sy0&quot;&gt;|&lt;/span&gt; MB_OK&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#else&lt;/span&gt;
	&lt;span class=&quot;kw4&quot;&gt;size_t&lt;/span&gt; len&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Allocate some memory for our converted string. */&lt;/span&gt;
	len &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; wcstombs&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;NULL&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; wstr&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	str &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;malloc&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;len &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;str &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; NULL&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Perform the string conversion. */&lt;/span&gt;
	len &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; wcstombs&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;str&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; wstr&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; len&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;len &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;size_t&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		&lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/free.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;free&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;str&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; NULL&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif /* _WIN32 */&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; str&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Unicode&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;unicode&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;1350-4489&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;setting_up_a_project&quot;&gt;Setting up a Project&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Also by default if you&amp;#039;re using an old compiler like Visual C++ 6 you need to manually set up the project to use Unicode and be compatible with more modern versions of Windows. In order to do this you simply have to follow the following steps:
&lt;/p&gt;
&lt;ol&gt;
&lt;li class=&quot;level1 node&quot;&gt;&lt;div class=&quot;li&quot;&gt; Define the &lt;code&gt;UNICODE&lt;/code&gt; and &lt;code&gt;_UNICODE&lt;/code&gt; preprocessor symbols:&lt;/div&gt;
&lt;ol&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Select &lt;strong&gt;Project→Settings&lt;/strong&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Click the &lt;strong&gt;C/C++&lt;/strong&gt; tab.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Add the following symbols to the &lt;strong&gt;Preprocessor definitions&lt;/strong&gt; text box: &lt;code&gt;UNICODE&lt;/code&gt;,&lt;code&gt;_UNICODE&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li class=&quot;level1 node&quot;&gt;&lt;div class=&quot;li&quot;&gt; Choose the entry point for Unicode:&lt;/div&gt;
&lt;ol&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; While still in the &lt;strong&gt;Project Settings&lt;/strong&gt; dialog box, click the &lt;strong&gt;Link&lt;/strong&gt; tab.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; From the &lt;strong&gt;Category&lt;/strong&gt; drop-down list, select &lt;strong&gt;Output&lt;/strong&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2 node&quot;&gt;&lt;div class=&quot;li&quot;&gt; In the &lt;strong&gt;Entry-point symbol&lt;/strong&gt; field, type the appropriate entry point for Unicode:&lt;/div&gt;
&lt;ol&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; For a &lt;abbr title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/abbr&gt; Unicode application, the entry point is &lt;code&gt;wWinMainCRTStartup&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; For a console application, the entry point is &lt;code&gt;wmainCRTStartup&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li class=&quot;level1 node&quot;&gt;&lt;div class=&quot;li&quot;&gt; Set the debugger to display Unicode strings:&lt;/div&gt;
&lt;ol&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Select &lt;strong&gt;Tools→Options&lt;/strong&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Click the &lt;strong&gt;Debug&lt;/strong&gt; tab.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Make sure the &lt;strong&gt;Display unicode strings&lt;/strong&gt; check box is checked.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Setting up a Project&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;setting_up_a_project&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;4490-5655&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit5&quot; id=&quot;special_folders&quot;&gt;Special Folders&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Sometimes we want to have access to “special folders” like the Desktop, My Documents, AppData, just to name a few. Most of these have environment variables associated with them, but expanding environment variables in a program seems very bad, thankfully Microsoft provides a couple of interesting functions for us to use in order to fetch these paths.
&lt;/p&gt;

&lt;p&gt;
If we are targeting Windows 95+ (with the Internet Explorer upgrade) we must use the &lt;code&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetspecialfolderpathw&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetspecialfolderpathw&quot; rel=&quot;ugc nofollow&quot;&gt;SHGetSpecialFolderPath&lt;/a&gt;&lt;/code&gt; function. If we are targeting Windows 2000+, or can install a redistributable, the recommendation is to use &lt;code&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetfolderlocation&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetfolderlocation&quot; rel=&quot;ugc nofollow&quot;&gt;SHGetFolderLocation&lt;/a&gt;&lt;/code&gt; since the previous function call has been deprecated in this version. If we are targeting Windows Vista+ then we can use the even fancier &lt;code&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath&quot; rel=&quot;ugc nofollow&quot;&gt;SHGetKnownFolderPath&lt;/a&gt;&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Here are some examples of how to use these functions:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://stackoverflow.com/questions/54297253/is-there-a-new-replacement-for-shgetspecialfolderlocation/54297607#54297607&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/questions/54297253/is-there-a-new-replacement-for-shgetspecialfolderlocation/54297607#54297607&quot; rel=&quot;ugc nofollow&quot;&gt;Showing how to use all of the functions described above&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://stackoverflow.com/questions/17933917/get-the-users-desktop-folder-using-windows-api/17935926#17935926&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/questions/17933917/get-the-users-desktop-folder-using-windows-api/17935926#17935926&quot; rel=&quot;ugc nofollow&quot;&gt;Specially focused on how to use SHGetSpecialFolderPath&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Special Folders&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;special_folders&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;5656-7174&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit6&quot; id=&quot;shims&quot;&gt;Shims&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
A collection of functions that may require a bit of shimming if you come from the saner world of POSIX:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;&lt;a href=&quot;https://man7.org/linux/man-pages/man3/basename.3.html&quot; class=&quot;urlextern&quot; title=&quot;https://man7.org/linux/man-pages/man3/basename.3.html&quot; rel=&quot;ugc nofollow&quot;&gt;basename&lt;/a&gt;&lt;/code&gt; equivalent is &lt;code&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathfindfilenamea&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathfindfilenamea&quot; rel=&quot;ugc nofollow&quot;&gt;PathFindFileName&lt;/a&gt;&lt;/code&gt; (requires linking against &lt;code&gt;shlwapi.lib&lt;/code&gt;)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;&lt;a href=&quot;https://man7.org/linux/man-pages/man3/snprintf.3p.html&quot; class=&quot;urlextern&quot; title=&quot;https://man7.org/linux/man-pages/man3/snprintf.3p.html&quot; rel=&quot;ugc nofollow&quot;&gt;snprintf&lt;/a&gt;&lt;/code&gt; equivalent is &lt;code&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=msvc-170&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=msvc-170&quot; rel=&quot;ugc nofollow&quot;&gt;_snprintf&lt;/a&gt;&lt;/code&gt; (can&amp;#039;t count the number of bytes required for allocation)&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Shims&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;shims&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;7175-7842&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit7&quot; id=&quot;multithreading&quot;&gt;Multithreading&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
As usual, when it comes to Windows, multithreading is not as simple or easy as under a POSIX system. Microsoft made sure to implement their multithreading &lt;abbr title=&quot;Application Programming Interface&quot;&gt;API&lt;/abbr&gt; in multiple ways, one you can use the CRT, the other one you can&amp;#039;t. In any case, just ignore everything and follow these instructions.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Multithreading&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;multithreading&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;7843-8165&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit8&quot; id=&quot;mutexes&quot;&gt;Mutexes&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
One of the most used capabilities when dealing with parallel operations are mutexes, they allow us to ensure that resources that are shared between multiple processes can be safely guarded against race conditions. Windows has the concept of mutexes, but they are &lt;a href=&quot;https://stackoverflow.com/questions/800383/what-is-the-difference-between-mutex-and-critical-section/800422#800422&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/questions/800383/what-is-the-difference-between-mutex-and-critical-section/800422#800422&quot; rel=&quot;ugc nofollow&quot;&gt;extremely bad in terms of performance&lt;/a&gt;, although they have the “benefit” of working across processes. Usually what you want to use is the &lt;code&gt;CRITICAL_SECTION&lt;/code&gt; and its &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/sync/using-critical-section-objects&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/sync/using-critical-section-objects&quot; rel=&quot;ugc nofollow&quot;&gt;associated functions&lt;/a&gt;, these resemble much of the pthreads &lt;abbr title=&quot;Application Programming Interface&quot;&gt;API&lt;/abbr&gt;, although with that characteristic Win32 &lt;abbr title=&quot;Application Programming Interface&quot;&gt;API&lt;/abbr&gt; flavor, and are very lightweight.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Mutexes&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;mutexes&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;8166-8962&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit9&quot; id=&quot;windows_ce&quot;&gt;Windows CE&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
As with everything in Win32 land the Windows CE implementation of multithreading suffered a lot, especially when dealing with PocketPCs and non-Handheld PCs. We can understand that this was done due to the lack of resources of such devices, but still. Here are some online resources on the subject:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://sourceware.org/pub/pthreads-win32/pthreads-dll-2002-11-04/WinCE-PORT&quot; class=&quot;urlextern&quot; title=&quot;https://sourceware.org/pub/pthreads-win32/pthreads-dll-2002-11-04/WinCE-PORT&quot; rel=&quot;ugc nofollow&quot;&gt;WinCE pthreads port&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://web.archive.org/web/20090624190949/http://world.std.com/~jmhart/wince.htm&quot; class=&quot;urlextern&quot; title=&quot;https://web.archive.org/web/20090624190949/http://world.std.com/~jmhart/wince.htm&quot; rel=&quot;ugc nofollow&quot;&gt;Notes on Windows CE&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Windows CE&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;windows_ce&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:9,&amp;quot;range&amp;quot;:&amp;quot;8963-9500&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit10&quot; id=&quot;additional_resources&quot;&gt;Additional Resources&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Here are some resources that were used as references to write this section. These will most likely go into greater detail on the subject and give you a greater understanding of the &lt;abbr title=&quot;Application Programming Interface&quot;&gt;API&lt;/abbr&gt; instead of just providing a reference.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/parallel/multithreading-with-c-and-win32?view=msvc-170&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/cpp/parallel/multithreading-with-c-and-win32?view=msvc-170&quot; rel=&quot;ugc nofollow&quot;&gt;MSDN: Multithreading with C and Win32&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/parallel/sample-multithread-c-program?view=msvc-170&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/cpp/parallel/sample-multithread-c-program?view=msvc-170&quot; rel=&quot;ugc nofollow&quot;&gt;MSDN: Sample Multithread C Program&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Why-Pthreads-are-better-than-Win32-threads/td-p/990131&quot; class=&quot;urlextern&quot; title=&quot;https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Why-Pthreads-are-better-than-Win32-threads/td-p/990131&quot; rel=&quot;ugc nofollow&quot;&gt;Why Pthreads are better than Win32 threads&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://stackoverflow.com/questions/331536/windows-threading-beginthread-vs-beginthreadex-vs-createthread-c&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/questions/331536/windows-threading-beginthread-vs-beginthreadex-vs-createthread-c&quot; rel=&quot;ugc nofollow&quot;&gt;Windows threading: _beginthread vs _beginthreadex vs CreateThread&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://locklessinc.com/articles/pthreads_on_windows/&quot; class=&quot;urlextern&quot; title=&quot;https://locklessinc.com/articles/pthreads_on_windows/&quot; rel=&quot;ugc nofollow&quot;&gt;Pthreads on Microsoft Windows&lt;/a&gt; (probably the best resource on the subject of multithreading under Windows)&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Additional Resources&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;additional_resources&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:10,&amp;quot;range&amp;quot;:&amp;quot;9501-10547&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit11&quot; id=&quot;windows_server_2003_platform_sdk&quot;&gt;Windows Server 2003 Platform SDK&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
If you want to have proper compatibility with every single 32-bit Intel-based Windows release ever made since Windows 95 you are required to use Microsoft&amp;#039;s Visual C++ 6, which is a whole can of worms, but it is what you need to do in order to have full backward compatibility. Something that alleviates a bit of the pain of using this toolchain is the Windows Server 2003 Platform SDK, which can be downloaded using the &lt;a href=&quot;https://social.msdn.microsoft.com/Forums/windowsapps/en-US/e1147034-9b0b-4494-a5bc-6dfebb6b7eb1/download-and-install-microsoft-platform-sdk-febuary-2003-last-version-with-vc6-support?forum=windowssdk&quot; class=&quot;urlextern&quot; title=&quot;https://social.msdn.microsoft.com/Forums/windowsapps/en-US/e1147034-9b0b-4494-a5bc-6dfebb6b7eb1/download-and-install-microsoft-platform-sdk-febuary-2003-last-version-with-vc6-support?forum=windowssdk&quot; rel=&quot;ugc nofollow&quot;&gt;following instructions&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
You may need to install each SDK individually from the &lt;code&gt;setup&lt;/code&gt; folder instead of running &lt;code&gt;setup.exe&lt;/code&gt;, since this may cause issues if you&amp;#039;re running a more modern version of Internet Explorer.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Windows Server 2003 Platform SDK&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;windows_server_2003_platform_sdk&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:11,&amp;quot;range&amp;quot;:&amp;quot;10548-11440&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit12&quot; id=&quot;sockets_and_network_programming&quot;&gt;Sockets and Network Programming&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Porting an application from the standard in UNIX land Berkley sockets to WinSock might be a bit of a nightmare, depending on the architecture of the project. If your application was developed with portability in mind, even going as far as wrapping every single socket function, you can more easily port your code to Winsock, but you may still run into problems.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Sockets and Network Programming&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;sockets_and_network_programming&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:12,&amp;quot;range&amp;quot;:&amp;quot;11441-11848&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit13&quot; id=&quot;missing_functions_and_types&quot;&gt;Missing Functions and Types&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
As soon as we try to compile any piece of code that was made for a more standardized sockets implementation, one thing will become extremely apparent: You&amp;#039;ll be missing a lot of stuff. In order to get a saner environment for socket programming under Windows, it&amp;#039;s required to install the &lt;a href=&quot;#windows_server_2003_platform_sdk&quot; title=&quot;devnotes:msvc-porting ↵&quot; class=&quot;wikilink1&quot;&gt;Windows Server 2003 Platform SDK&lt;/a&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Missing Functions and Types&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;missing_functions_and_types&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:13,&amp;quot;range&amp;quot;:&amp;quot;11849-12248&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit14&quot; id=&quot;headers&quot;&gt;Headers&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
According to Microsoft&amp;#039;s documentation, you should not include &lt;code&gt;windows.h&lt;/code&gt; when you are using Winsock2 since it tries to include the old Winsock 1.1 stuff, which generates loads of conflicts with the redefinitions in the Winsock2 headers. In order to get around this, since your application or libraries might be including &lt;code&gt;windows.h&lt;/code&gt; you should define globally (in the project&amp;#039;s settings) the &lt;code&gt;WIN32_LEAN_AND_MEAN&lt;/code&gt; preprocessor definition.
&lt;/p&gt;

&lt;p&gt;
A usual set of includes for Winsock2 should look like this:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co2&quot;&gt;#define WIN32_LEAN_AND_MEAN&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#include &amp;lt;windows.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#include &amp;lt;winsock2.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#include &amp;lt;ws2tcpip.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#include &amp;lt;wspiapi.h&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Headers&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;headers&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:14,&amp;quot;range&amp;quot;:&amp;quot;12249-12908&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit15&quot; id=&quot;setsockopt_parameters&quot;&gt;setsockopt() Parameters&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Another difference from other platforms is that the &lt;code&gt;setsockopt()&lt;/code&gt; function takes its &lt;code&gt;optval&lt;/code&gt; parameter as a &lt;code&gt;const char *&lt;/code&gt; instead of the more common &lt;code&gt;void *&lt;/code&gt;, requiring your parameters to be redefined just for Windows.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;setsockopt() Parameters&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;setsockopt_parameters&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:15,&amp;quot;range&amp;quot;:&amp;quot;12909-13174&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit16&quot; id=&quot;error_handling&quot;&gt;Error Handling&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Whenever you must catch errors from resulting socket interactions, where under a POSIX system you simply check the contents of the &lt;code&gt;errno&lt;/code&gt; variable after a function returns &lt;code&gt;-1&lt;/code&gt;, under Winsock2 you must instead check if the function returned &lt;code&gt;SOCKET_ERROR&lt;/code&gt;, and then call and store the return value of &lt;code&gt;WSAGetLastError()&lt;/code&gt; and compare against Microsoft&amp;#039;s WSA-prefixed error code definitions. This is all described in Microsoft&amp;#039;s &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/winsock/return-values-on-function-failure-2&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/winsock/return-values-on-function-failure-2&quot; rel=&quot;ugc nofollow&quot;&gt;Return Values on Function Failure&lt;/a&gt; MSDN article. For more in-depth information on the subject of how to deal with Winsock2 errors, read MSDN articles &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/winsock/handling-winsock-errors&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/winsock/handling-winsock-errors&quot; rel=&quot;ugc nofollow&quot;&gt;Handling Winsock Errors&lt;/a&gt; and &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/winsock/error-codes-errno-h-errno-and-wsagetlasterror-2&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/winsock/error-codes-errno-h-errno-and-wsagetlasterror-2&quot; rel=&quot;ugc nofollow&quot;&gt;Error Codes - errno, h_errno and WSAGetLastError&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Another interesting quirk of Winsock error codes seems to be the fact that it doesn&amp;#039;t have a &lt;code&gt;EAGAIN&lt;/code&gt; definition, and that for situations where &lt;code&gt;EAGAIN&lt;/code&gt; would&amp;#039;ve been used &lt;a href=&quot;https://lists.gnu.org/archive/html/bug-gnulib/2008-10/msg00068.html&quot; class=&quot;urlextern&quot; title=&quot;https://lists.gnu.org/archive/html/bug-gnulib/2008-10/msg00068.html&quot; rel=&quot;ugc nofollow&quot;&gt;it&amp;#039;s suggested&lt;/a&gt; to instead use &lt;code&gt;WSAEWOULDBLOCK&lt;/code&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Error Handling&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;error_handling&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:16,&amp;quot;range&amp;quot;:&amp;quot;13175-14451&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit17&quot; id=&quot;so_rcvtimeo_timeout_argument&quot;&gt;SO_RCVTIMEO Timeout Argument&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Under all UNIX variants, the &lt;code&gt;SO_RCVTIMEO&lt;/code&gt; option for &lt;code&gt;setsockopt()&lt;/code&gt; receives a pointer to a &lt;code&gt;struct timeval&lt;/code&gt;. This is not the case on Windows, and it does create a whole bunch of weird bugs, since the code technically compiles and may even run depending on the value pointed by the structure in question. Every single time I&amp;#039;m porting a socket application from POSIX to WinSock2, I want to pull my hair out whenever I encounter this bug.
&lt;/p&gt;

&lt;p&gt;
Under WinSock2, the &lt;code&gt;SO_RCVTIMEO&lt;/code&gt; option &lt;a href=&quot;https://stackoverflow.com/a/9859300/126353&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/a/9859300/126353&quot; rel=&quot;ugc nofollow&quot;&gt;requires the timeout value to be passed as a &amp;#039;&amp;#039;DWORD&amp;#039;&amp;#039;&lt;/a&gt;, with the number of milliseconds to timeout, casted to a &lt;code&gt;const char *&lt;/code&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;SO_RCVTIMEO Timeout Argument&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;so_rcvtimeo_timeout_argument&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:17,&amp;quot;range&amp;quot;:&amp;quot;14452-15158&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit18&quot; id=&quot;miscellaneous&quot;&gt;Miscellaneous&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Beware that whenever you&amp;#039;re dealing with &lt;code&gt;in_addr_t&lt;/code&gt;, it isn&amp;#039;t defined and you must instead define it as &lt;code&gt;unsigned long&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Yet another interesting quirk was discovered by us, where if you have a large TCP packet that gets split at the source and must be reassembled at the client, a call to &lt;code&gt;recv()&lt;/code&gt; will fail with a &lt;code&gt;WSAEFAULT&lt;/code&gt; even though the buffer is large enough to hold the received information, requiring us to always set the &lt;code&gt;MSG_WAITALL&lt;/code&gt; flag. This hasn&amp;#039;t been thoroughly tested, and we were unable to pinpoint with great accuracy the real cause of the issue, but at least for now, we&amp;#039;ve attributed it to the partial packet thing. Keep in mind that older versions of the compiler don&amp;#039;t have this flag available, so you&amp;#039;ll need to implement this functionality manually by looping through the &lt;code&gt;recv()&lt;/code&gt; call until all expected bytes have been received.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Miscellaneous&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;miscellaneous&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:18,&amp;quot;range&amp;quot;:&amp;quot;15159-16055&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit19&quot; id=&quot;linking&quot;&gt;Linking&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
At the end of your journey, if all the compilation errors have gone away, be sure to link against the &lt;code&gt;ws2_32.lib&lt;/code&gt; library to avoid the dreaded linker errors.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Linking&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;linking&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:19,&amp;quot;range&amp;quot;:&amp;quot;16056-16236&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit20&quot; id=&quot;initialization_and_cleanup&quot;&gt;Initialization and Cleanup&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Most importantly, after all this, make sure to add the following code to your &lt;code&gt;main()&lt;/code&gt; application entry point:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; main&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; argc&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;**&lt;/span&gt;argv&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#ifdef _WIN32&lt;/span&gt;
	WORD wVersionRequested&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	WSADATA wsaData&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; ret&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif /* _WIN32 */&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co2&quot;&gt;#ifdef _WIN32&lt;/span&gt;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Initialize the Winsock stuff. */&lt;/span&gt;
	wVersionRequested &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; MAKEWORD&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;ret &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; WSAStartup&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;wVersionRequested&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;wsaData&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		&lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/printf.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;printf&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;WSAStartup failed with error %d&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; ret&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif /* _WIN32 */&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Perform everything in your application. */&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/**
	 * If your application exits prematurely, make sure that WSACleanup() gets
	 * called beforehand.
	 */&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co2&quot;&gt;#ifdef _WIN32&lt;/span&gt;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Clean up the Winsock stuff. */&lt;/span&gt;
	WSACleanup&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif /* _WIN32 */&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; ret&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Initialization and Cleanup&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;initialization_and_cleanup&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:20,&amp;quot;range&amp;quot;:&amp;quot;16237-17024&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit21&quot; id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Here are the references that were most likely consulted in order to find all of these issues in real-world codebases and catalog them here:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/winsock/porting-socket-applications-to-winsock&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/winsock/porting-socket-applications-to-winsock&quot; rel=&quot;ugc nofollow&quot;&gt;MSDN: Porting Socket Applications to Winsock&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://handsonnetworkprogramming.com/articles/differences-windows-winsock-linux-unix-bsd-sockets-compatibility/&quot; class=&quot;urlextern&quot; title=&quot;https://handsonnetworkprogramming.com/articles/differences-windows-winsock-linux-unix-bsd-sockets-compatibility/&quot; rel=&quot;ugc nofollow&quot;&gt;Differences Between Socket Programming on Windows, Linux, and macOS&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://umlautllama.com/w2/?action=view&amp;amp;page=Porting%20BSD%20Sockets%20to%20Winsock&quot; class=&quot;urlextern&quot; title=&quot;https://umlautllama.com/w2/?action=view&amp;amp;page=Porting%20BSD%20Sockets%20to%20Winsock&quot; rel=&quot;ugc nofollow&quot;&gt;Porting BSD Sockets to Winsock&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;References&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;references&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:21,&amp;quot;range&amp;quot;:&amp;quot;17025-17648&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit22&quot; id=&quot;getting_a_console&quot;&gt;Getting a Console&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
You&amp;#039;ll quickly realize that if your target is a &lt;abbr title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/abbr&gt; Win32 application you won&amp;#039;t have access to a console to print stuff out and quickly debug things. This is due to the way that Windows is architected and its subsystems work. In order to get a console you&amp;#039;ll either need to allocate one and redirect every stream to that one or create an EDIT control anywhere on your application, create a pipe, redirect the streams to your pipe, then read from it and append the text to your EDIT field. Either way here are some resources to get you started:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://stackoverflow.com/a/57241985/126353&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/a/57241985/126353&quot; rel=&quot;ugc nofollow&quot;&gt;Allocating a console and getting stdout redirected - StackOverflow&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://stackoverflow.com/a/573762/126353&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/a/573762/126353&quot; rel=&quot;ugc nofollow&quot;&gt;Piping the output to an EDIT control - StackOverflow&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Getting a Console&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;getting_a_console&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:22,&amp;quot;range&amp;quot;:&amp;quot;17649-18447&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit23&quot; id=&quot;finding_memory_leaks&quot;&gt;Finding Memory Leaks&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Finding memory leaks is always a though thing. &lt;a href=&quot;https://stackoverflow.com/a/60626788&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/a/60626788&quot; rel=&quot;ugc nofollow&quot;&gt;Visual Studio has some tools&lt;/a&gt; which can be extremely useful when trying to find leaks, but you can also do it programmatically on every debug run of your application:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co2&quot;&gt;#ifdef DEBUG&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#include &amp;lt;crtdbg.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif // DEBUG&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; _tmain&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; argc&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; TCHAR&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; argv&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#ifdef DEBUG&lt;/span&gt;
	&lt;span class=&quot;co1&quot;&gt;// Initialize memory leak detection.&lt;/span&gt;
	_CrtMemState snapBegin&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	_CrtMemState snapEnd&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	_CrtMemState snapDiff&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	_CrtMemCheckpoint&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;snapBegin&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif // DEBUG&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;co1&quot;&gt;// TODO: Do stuff here...&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co2&quot;&gt;#ifdef DEBUG&lt;/span&gt;
	&lt;span class=&quot;co1&quot;&gt;// Detect memory leaks.&lt;/span&gt;
	_CrtMemCheckpoint&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;snapEnd&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;_CrtMemDifference&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;snapDiff&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;snapBegin&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;snapEnd&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		OutputDebugString&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;_T&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;MEMORY LEAKS DETECTED&lt;span class=&quot;es1&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		OutputDebugString&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;L&lt;span class=&quot;st0&quot;&gt;&amp;quot;----------- _CrtMemDumpStatistics ---------&lt;span class=&quot;es1&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		_CrtMemDumpStatistics&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;snapDiff&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		OutputDebugString&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;L&lt;span class=&quot;st0&quot;&gt;&amp;quot;----------- _CrtMemDumpAllObjectsSince ---------&lt;span class=&quot;es1&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		_CrtMemDumpAllObjectsSince&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;snapBegin&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		OutputDebugString&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;L&lt;span class=&quot;st0&quot;&gt;&amp;quot;----------- _CrtDumpMemoryLeaks ---------&lt;span class=&quot;es1&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		_CrtDumpMemoryLeaks&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		OutputDebugString&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;_T&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;No memory leaks detected. Congratulations!&lt;span class=&quot;es1&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif // DEBUG&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Finding Memory Leaks&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;finding_memory_leaks&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:23,&amp;quot;range&amp;quot;:&amp;quot;18448-19666&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit24&quot; id=&quot;guidelines&quot;&gt;Guidelines&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
When developing applications for a given operating system it&amp;#039;s always good to know about its standards, defaults, and most importantly its interface guidelines in order to make your application look “native”. In order to get a comprehensive look at Microsoft&amp;#039;s recommendations of what Windows applications should look and feel you must check out their &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/uxguide/vis-layout&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/uxguide/vis-layout&quot; rel=&quot;ugc nofollow&quot;&gt;Layout Guidelines&lt;/a&gt;, most importantly since Visual Studio provides no help in this area, you should check out their &lt;strong&gt;Recommended sizing and spacing&lt;/strong&gt; section which describes in detail how to size and space controls in Win32 applications.
&lt;/p&gt;

&lt;p&gt;
It&amp;#039;s not only important to follow Microsoft&amp;#039;s guidelines for the UI aspects of the application, but also for the developer side of the application, using naming conventions that are accepted by other Windows developers. Here are a collection of articles related to this topic:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/stg/coding-style-conventions&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/stg/coding-style-conventions&quot; rel=&quot;ugc nofollow&quot;&gt;Variable Naming&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/mfc/tn020-id-naming-and-numbering-conventions?view=msvc-170&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/cpp/mfc/tn020-id-naming-and-numbering-conventions?view=msvc-170&quot; rel=&quot;ugc nofollow&quot;&gt;Resource IDs and Numbering&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Guidelines&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;guidelines&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:24,&amp;quot;range&amp;quot;:&amp;quot;19667-20864&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit25&quot; id=&quot;msc_ver&quot;&gt;_MSC_VER&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Since Visual Studio is quite an old application with lots of versions and many changes along the years, one of the most important aspects that you need to know in order to develop a project that can be compiled in multiple versions of this platform is the &lt;code&gt;_MSC_VER&lt;/code&gt; constant that&amp;#039;s defined for every version of the application suite. &lt;a href=&quot;https://dev.to/yumetodo/list-of-mscver-and-mscfullver-8nd&quot; class=&quot;urlextern&quot; title=&quot;https://dev.to/yumetodo/list-of-mscver-and-mscfullver-8nd&quot; rel=&quot;ugc nofollow&quot;&gt;A comprehensive list of these definitions can be found here&lt;/a&gt;, but here are some of the most important ones for us:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Visual Studio 2012: &lt;code&gt;1700&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Visual Studio 2005: &lt;code&gt;1400&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Visual C++ 6.0: &lt;code&gt;1200&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;_MSC_VER&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;msc_ver&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:25,&amp;quot;range&amp;quot;:&amp;quot;20865-21496&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit26&quot; id=&quot;issues_with_stdinth_error_c2733&quot;&gt;Issues with stdint.h (Error C2733)&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
If you&amp;#039;re seeing things like &lt;code&gt;error C2733: second C linkage of overloaded function &amp;#039;wmemchr&amp;#039; not allowed&lt;/code&gt; when trying to compile an application under Visual C++ 6 using the official &lt;code&gt;stdint.h&lt;/code&gt; shim it means that you haven&amp;#039;t paid attention to the comments in the file itself:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// For Visual Studio 6 in C++ mode and for many Visual Studio versions when&lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// compiling for ARM we should wrap &amp;lt;wchar.h&amp;gt; include with &#039;extern &amp;quot;C++&amp;quot; {}&#039;&lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// or compiler give many errors like this:&lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;//   error C2733: second C linkage of overloaded function &#039;wmemchr&#039; not allowed&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#ifdef __cplusplus&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;C&amp;quot;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#  include &amp;lt;wchar.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#ifdef __cplusplus&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Changing from &lt;code&gt;extern “C”&lt;/code&gt; to &lt;code&gt;extern “C++”&lt;/code&gt; should fix all your issues.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Issues with stdint.h (Error C2733)&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;issues_with_stdinth_error_c2733&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:26,&amp;quot;range&amp;quot;:&amp;quot;21497-22284&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit27&quot; id=&quot;registry_functions&quot;&gt;Registry Functions&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
It&amp;#039;s extremely important to note that, only under eMbedded Visual C++ 3, all registry-related functions such as &lt;code&gt;RegOpenKeyEx&lt;/code&gt; and &lt;code&gt;RegQueryValueEx&lt;/code&gt; return &lt;code&gt;ERROR_INVALID_PARAMETER&lt;/code&gt; instead of &lt;code&gt;ERROR_INVALID_PARAMETER&lt;/code&gt; when a key hasn&amp;#039;t yet been created. Also the &lt;code&gt;lpdwDisposition&lt;/code&gt; parameter of &lt;code&gt;RegCreateKeyEx&lt;/code&gt; is mandatory under the same compiler, not including it will result in an Access Violation error.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Registry Functions&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;registry_functions&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:5,&amp;quot;secid&amp;quot;:27,&amp;quot;range&amp;quot;:&amp;quot;22285-22738&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit28&quot; id=&quot;image_lists&quot;&gt;Image Lists&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
&lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/controls/image-lists&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/controls/image-lists&quot; rel=&quot;ugc nofollow&quot;&gt;ImageLists&lt;/a&gt; are a crucial component from the CommonControls library. They allow us to add icons to our applications in a much easier manner and lets us associate indexes with them, but they do have some gotchas that are nice to know in order to take full advantage of them, specially when developing with multiple versions of Windows in mind.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Image Lists&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;image_lists&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:5,&amp;quot;secid&amp;quot;:28,&amp;quot;range&amp;quot;:&amp;quot;22739-23179&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit29&quot; id=&quot;system_metrics&quot;&gt;System Metrics&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Most of the time when building ImageLists we want to use them for standardized icons throughout our application, these usually use the small and large metrics defined by the operating system. In order to get these we can use the &lt;code&gt;GetDeviceMetrics()&lt;/code&gt; function and ask for the &lt;code&gt;SM_CXSMICON&lt;/code&gt; and &lt;code&gt;SM_CYSMICON&lt;/code&gt; for small icons and &lt;code&gt;SM_CXICON&lt;/code&gt; and &lt;code&gt;SM_CYICON&lt;/code&gt; for large icons. The values returned by the function can be directly used to create an ImageList with &lt;code&gt;ImageList_Create()&lt;/code&gt;. To learn more about these metrics consult the &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/menurc/about-icons#icon-sizes&quot; class=&quot;urlextern&quot; title=&quot;https://learn.microsoft.com/en-us/windows/win32/menurc/about-icons#icon-sizes&quot; rel=&quot;ugc nofollow&quot;&gt;About icons page&lt;/a&gt; of the Microsoft documentation.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;System Metrics&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;system_metrics&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:5,&amp;quot;secid&amp;quot;:29,&amp;quot;range&amp;quot;:&amp;quot;23180-23874&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit30&quot; id=&quot;loadicon_in_windows_ce&quot;&gt;LoadIcon in Windows CE&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
When loading icons under Windows CE it&amp;#039;s very important to note that the &lt;code&gt;LoadIcon()&lt;/code&gt; function only loads icons of size &lt;code&gt;SM_CXICON&lt;/code&gt;, if you use these in other size contexts the icon will simply be clipped. As the documentation states:
&lt;/p&gt;
&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
 &lt;code&gt;LoadIcon&lt;/code&gt; can only load an icon whose size conforms to the &lt;code&gt;SM_CXICON&lt;/code&gt; and &lt;code&gt;SM_CYICON&lt;/code&gt; system metric values. Use the &lt;code&gt;LoadImage&lt;/code&gt; function to load icons of other sizes.&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;
Given this explanation we can substitute our uses of &lt;code&gt;LoadIcon()&lt;/code&gt; with the following to get a different resolution:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;HICON&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;LoadImage&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;m_hInst&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; MAKEINTRESOURCE&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;IDI_ICONRES&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; IMAGE_ICON&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; SM_CXSMICON&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; SM_CXSMICON&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
The issue now is that we need to keep the &lt;code&gt;HICON&lt;/code&gt; handles in a list somewhere so that we can call &lt;code&gt;DestroyIcon()&lt;/code&gt; on them when its time to dispose of them. This was done automatically when we used &lt;code&gt;LoadIcon()&lt;/code&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;LoadIcon in Windows CE&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;loadicon_in_windows_ce&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:5,&amp;quot;secid&amp;quot;:30,&amp;quot;range&amp;quot;:&amp;quot;23875-24780&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit31&quot; id=&quot;bit_depth&quot;&gt;Bit Depth&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Throughout the many versions of Windows, specially in the XP and pre-XP days, it was common for computers to not be capable of rendering in 24-bit or 32-bit colors, so whenever we are creating ImageLists we have to take this into consideration. One easy cop out from this situation is instead of passing a specific bit depth for the &lt;code&gt;ImageList_Create()&lt;/code&gt; function we pass the &lt;code&gt;ILC_COLORDDB&lt;/code&gt; flag. There was &lt;a href=&quot;https://stackoverflow.com/questions/19016115/mfc-image-list-create-ilc-colorddb-messing-up-highlight&quot; class=&quot;urlextern&quot; title=&quot;https://stackoverflow.com/questions/19016115/mfc-image-list-create-ilc-colorddb-messing-up-highlight&quot; rel=&quot;ugc nofollow&quot;&gt;this interesting discussion&lt;/a&gt; on when to use this flag.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Bit Depth&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;bit_depth&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:6,&amp;quot;secid&amp;quot;:31,&amp;quot;range&amp;quot;:&amp;quot;24781-25371&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit32&quot; id=&quot;c_stl_for_embedded_visual_c&quot;&gt;C++ STL for eMbedded Visual C++&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
If you think you could have a sane standard library for C++ under Microsoft&amp;#039;s eMbedded Visual C++ you are completely wrong. For some reason they shipped it with one that was missing some bits and in some cases it was completely different from the published standard back in the day. You can get a much better and standards-compliant STL (based on SGI&amp;#039;s work) from &lt;a href=&quot;https://users.libero.it/g.govi/stlport_ce_en.html&quot; class=&quot;urlextern&quot; title=&quot;https://users.libero.it/g.govi/stlport_ce_en.html&quot; rel=&quot;ugc nofollow&quot;&gt;STL for eMbedded Visual C++&lt;/a&gt;. Also you should read the &lt;a href=&quot;https://users.libero.it/g.govi/info_ce_en.html&quot; class=&quot;urlextern&quot; title=&quot;https://users.libero.it/g.govi/info_ce_en.html&quot; rel=&quot;ugc nofollow&quot;&gt;additional information on limitations and usage&lt;/a&gt; to learn more about it.
&lt;/p&gt;

&lt;p&gt;
To install this we just have to decompress it either in the project&amp;#039;s folder or somewhere else, go to &lt;code&gt;Tools/Options…/Directories&lt;/code&gt; and add the folder where it was decompressed to the includes path for all targets.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;C++ STL for eMbedded Visual C++&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;c_stl_for_embedded_visual_c&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:6,&amp;quot;secid&amp;quot;:32,&amp;quot;range&amp;quot;:&amp;quot;25372-&amp;quot;} --&gt;</description>
    </item>
    <item rdf:about="http://wiki.nathancampos.me/doku.php?id=notes:change-uid">
        <dc:format>text/html</dc:format>
        <dc:date>2025-10-11T13:48:27+00:00</dc:date>
        <dc:creator>nathanpc (nathanpc@undisclosed.example.com)</dc:creator>
        <title>change-uid - [Linux] </title>
        <link>http://wiki.nathancampos.me/doku.php?id=notes:change-uid</link>
        <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;changing_a_user_s_uid&quot;&gt;Changing a User&amp;#039;s UID&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Having consistency of UID and GID on UNIX is extremely important if you have multiple servers and clients that you want to maintain a consistent identity on. Be it for &lt;a href=&quot;https://en.wikipedia.org/wiki/Network_File_System&quot; class=&quot;urlextern&quot; title=&quot;https://en.wikipedia.org/wiki/Network_File_System&quot; rel=&quot;ugc nofollow&quot;&gt;NFS&lt;/a&gt;, &lt;a href=&quot;https://git-scm.com/&quot; class=&quot;urlextern&quot; title=&quot;https://git-scm.com/&quot; rel=&quot;ugc nofollow&quot;&gt;Git&lt;/a&gt;, or any other administrative task. Having the same IDs for your users across different computers really helps.
&lt;/p&gt;

&lt;p&gt;
Sadly, almost no &lt;abbr title=&quot;Operating System&quot;&gt;OS&lt;/abbr&gt; install utilities allow you to specify the UID/GID of the default user that&amp;#039;s created during setup, which means we have to do this afterward, thus this tutorial exists to give me and everyone a clear path to UID consistency.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Changing a User&amp;#039;s UID&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;changing_a_user_s_uid&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-651&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;linux&quot;&gt;Linux&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
I almost always run &lt;a href=&quot;https://www.debian.org/&quot; class=&quot;urlextern&quot; title=&quot;https://www.debian.org/&quot; rel=&quot;ugc nofollow&quot;&gt;Debian&lt;/a&gt; on my Linux machines, thus I can&amp;#039;t say this is the right way of doing it in other distros, I can&amp;#039;t see why it wouldn&amp;#039;t apply to others as well.
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;co0&quot;&gt;# Ensure no processes are running from the old user.&lt;/span&gt;
pkill &lt;span class=&quot;re5&quot;&gt;-U&lt;/span&gt; &lt;span class=&quot;re1&quot;&gt;$OLD_UID&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Change UID/GID using usermod.&lt;/span&gt;
usermod &lt;span class=&quot;re5&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;re1&quot;&gt;$NEW_UID&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-g&lt;/span&gt; &lt;span class=&quot;re1&quot;&gt;$NEW_GID&lt;/span&gt; &lt;span class=&quot;re1&quot;&gt;$USERNAME&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co0&quot;&gt;# Fix file permissions to use the new UID.&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-uid&lt;/span&gt; &lt;span class=&quot;re1&quot;&gt;$OLD_UID&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-exec&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;chown&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-h&lt;/span&gt; &lt;span class=&quot;re1&quot;&gt;$NEW_UID&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; +
&lt;span class=&quot;kw2&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-gid&lt;/span&gt; &lt;span class=&quot;re1&quot;&gt;$OLD_UID&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-exec&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;chgrp&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-h&lt;/span&gt; &lt;span class=&quot;re1&quot;&gt;$NEW_GID&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; +&lt;/pre&gt;

&lt;p&gt;
If you&amp;#039;re using a Raspberry Pi with its graphical desktop environment, you should use &lt;code&gt;raspi-config&lt;/code&gt; to disable booting straight to X.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Linux&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;linux&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;652-&amp;quot;} --&gt;</description>
    </item>
    <item rdf:about="http://wiki.nathancampos.me/doku.php?image=log%3Asoftether-securenat-prefs.png&amp;ns=log&amp;do=media">
        <dc:format>text/html</dc:format>
        <dc:date>2025-08-17T12:56:43+00:00</dc:date>
        <dc:creator>nathanpc (nathanpc@undisclosed.example.com)</dc:creator>
        <title>softether-securenat-prefs.png - created</title>
        <link>http://wiki.nathancampos.me/doku.php?image=log%3Asoftether-securenat-prefs.png&amp;ns=log&amp;do=media</link>
        <description>&lt;img src=&quot;http://wiki.nathancampos.me/lib/exe/fetch.php?w=500&amp;amp;h=500&amp;amp;tok=bcb87f&amp;amp;media=log:softether-securenat-prefs.png&quot; alt=&quot;softether-securenat-prefs.png&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;500&quot; /&gt;</description>
    </item>
    <item rdf:about="http://wiki.nathancampos.me/doku.php?image=log%3Aiis7-php5-handler-config.png&amp;ns=log&amp;do=media">
        <dc:format>text/html</dc:format>
        <dc:date>2025-07-24T10:45:40+00:00</dc:date>
        <dc:creator>nathanpc (nathanpc@undisclosed.example.com)</dc:creator>
        <title>iis7-php5-handler-config.png - created</title>
        <link>http://wiki.nathancampos.me/doku.php?image=log%3Aiis7-php5-handler-config.png&amp;ns=log&amp;do=media</link>
        <description>&lt;img src=&quot;http://wiki.nathancampos.me/lib/exe/fetch.php?w=500&amp;amp;h=500&amp;amp;tok=32af83&amp;amp;media=log:iis7-php5-handler-config.png&quot; alt=&quot;iis7-php5-handler-config.png&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;500&quot; /&gt;</description>
    </item>
    <item rdf:about="http://wiki.nathancampos.me/doku.php?image=devnotes%3Anstableview-plus-minus-toolbar.png&amp;ns=devnotes&amp;do=media">
        <dc:format>text/html</dc:format>
        <dc:date>2024-07-08T18:42:08+00:00</dc:date>
        <dc:creator>nathanpc (nathanpc@undisclosed.example.com)</dc:creator>
        <title>nstableview-plus-minus-toolbar.png - created</title>
        <link>http://wiki.nathancampos.me/doku.php?image=devnotes%3Anstableview-plus-minus-toolbar.png&amp;ns=devnotes&amp;do=media</link>
        <description>&lt;img src=&quot;http://wiki.nathancampos.me/lib/exe/fetch.php?w=500&amp;amp;h=500&amp;amp;tok=8eac49&amp;amp;media=devnotes:nstableview-plus-minus-toolbar.png&quot; alt=&quot;nstableview-plus-minus-toolbar.png&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;500&quot; /&gt;</description>
    </item>
</rdf:RDF>
