Repository: microsoft/terminal
File: src/inc/conpty-universal.h (C/C++)

Code before:
//   ```

#include <windows.h>
#include <string>
#include <sstream>
#include <strsafe.h>
#include <memory>
#pragma once

const unsigned int PTY_SIGNAL_RESIZE_WINDOW = 8u;

// A case-insensitive wide-character map is used to store environment variables
// due to documented requirements:
//
//      "All strings in the environment block must be sorted alphabetically by name.
//      The sort is case-insensitive, Unicode order, without regard to locale.
//      Because the equal sign is a separator, it must not be used in the name of
//      an environment variable."
//      https://docs.microsoft.com/en-us/windows/desktop/ProcThread/changing-environment-variables
//
struct WStringCaseInsensitiveCompare
{
    bool operator()(const std::wstring& lhs, const std::wstring& rhs) const
    {
        return (::_wcsicmp(lhs.c_str(), rhs.c_str()) < 0);
    }
};

using EnvironmentVariableMapW = std::map<std::wstring, std::wstring, WStringCaseInsensitiveCompare>;

HRESULT CreateConPty(const std::wstring& cmdline,                       // _In_
                     const unsigned short w,                            // _In_
                     const unsigned short h,                            // _In_
                     HANDLE* const hInput,                              // _Out_
                     HANDLE* const hOutput,                             // _Out_
                     HANDLE* const hSignal,                             // _Out_
                     PROCESS_INFORMATION* const piPty,                  // _Out_
                     const EnvironmentVariableMapW& extraEnvVars = {}); // _In_

bool SignalResizeWindow(const HANDLE hSignal,
                        const unsigned short w,
                        const unsigned short h);

HRESULT UpdateEnvironmentMapW(EnvironmentVariableMapW& map);

HRESULT EnvironmentMapToEnvironmentStringsW(EnvironmentVariableMapW& map, std::vector<wchar_t>& newEnvVars);

// Function Description:
// - Updates an EnvironmentVariableMapW with the current process's unicode
//   environment variables ignoring ones already set in the provided map.
// Arguments:

Review comment (suggestion):
I don't believe that we can use `_wcsicmp()` if we want to eventually be a UWP application. I'm not sure how important that is for now, @DHowett-MSFT opinions?

https://docs.microsoft.com/en-us/cpp/cppcx/crt-functions-not-supported-in-universal-windows-platform-apps?view=vs-2019

Code after:
//   ```

#include <windows.h>
#include <string>
#include <sstream>
#include <strsafe.h>
#include <memory>
#pragma once

const unsigned int PTY_SIGNAL_RESIZE_WINDOW = 8u;

// A case-insensitive wide-character map is used to store environment variables
// due to documented requirements:
//
//      "All strings in the environment block must be sorted alphabetically by name.
//      The sort is case-insensitive, Unicode order, without regard to locale.
//      Because the equal sign is a separator, it must not be used in the name of
//      an environment variable."
//      https://docs.microsoft.com/en-us/windows/desktop/ProcThread/changing-environment-variables
//
struct WStringCaseInsensitiveCompare
{
    [[nodiscard]]
    bool operator()(const std::wstring& lhs, const std::wstring& rhs) const noexcept
    {
        return (::_wcsicmp(lhs.c_str(), rhs.c_str()) < 0);
    }
};

using EnvironmentVariableMapW = std::map<std::wstring, std::wstring, WStringCaseInsensitiveCompare>;

[[nodiscard]]
HRESULT CreateConPty(const std::wstring& cmdline,
                     const unsigned short w,
                     const unsigned short h,
                     HANDLE* const hInput,
                     HANDLE* const hOutput,
                     HANDLE* const hSignal,
                     PROCESS_INFORMATION* const piPty,
                     const EnvironmentVariableMapW& extraEnvVars = {}) noexcept;

bool SignalResizeWindow(const HANDLE hSignal,
                        const unsigned short w,
                        const unsigned short h);

[[nodiscard]]
HRESULT UpdateEnvironmentMapW(EnvironmentVariableMapW& map) noexcept;

[[nodiscard]]
HRESULT EnvironmentMapToEnvironmentStringsW(EnvironmentVariableMapW& map, std::vector<wchar_t>& newEnvVars) noexcept;