Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / dll / appcompat / apphelp / layer.c
diff --git a/reactos/dll/appcompat/apphelp/layer.c b/reactos/dll/appcompat/apphelp/layer.c
deleted file mode 100644 (file)
index 36f9e86..0000000
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * PROJECT:     ReactOS Application compatibility module
- * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
- * PURPOSE:     Registry layer manipulation functions
- * COPYRIGHT:   Copyright 2015-2017 Mark Jansen (mark.jansen@reactos.org)
- */
-
-#define WIN32_NO_STATUS
-#include "windef.h"
-#include "winbase.h"
-#include "strsafe.h"
-#include <ntndk.h>
-#include "apphelp.h"
-
-#define GPLK_USER                   1
-#define GPLK_MACHINE                2
-#define MAX_LAYER_LENGTH            256
-#define LAYER_APPLY_TO_SYSTEM_EXES  1
-#define LAYER_UNK_FLAG2             2
-
-#ifndef REG_SZ
-#define REG_SZ                      1
-#endif
-
-#if defined(__GNUC__)
-#define APPCOMPAT_LAYER_KEY     (const WCHAR[]){'\\','S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ','N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','A','p','p','C','o','m','p','a','t','F','l','a','g','s','\\','L','a','y','e','r','s',0}
-#define REGISTRY_MACHINE        (const WCHAR[]){'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e',0}
-#define SPACE_ONLY              (const WCHAR[]){' ',0}
-#define DISALLOWED_LAYER_CHARS  (const WCHAR[]){' ','#','!',0}
-#define LAYER_SEPARATORS        (const WCHAR[]){' ','\t',0}
-#define SIGN_MEDIA_FMT          (const WCHAR[]){'S','I','G','N','.','M','E','D','I','A','=','%','X',' ','%','s',0}
-
-#else
-#define APPCOMPAT_LAYER_KEY     L"\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"
-#define REGISTRY_MACHINE        L"\\Registry\\Machine"
-#define SPACE_ONLY              L" "
-#define DISALLOWED_LAYER_CHARS  L" #!"
-#define LAYER_SEPARATORS        L" \t"
-#define SIGN_MEDIA_FMT          L"SIGN.MEDIA=%X %s"
-#endif
-
-/* Fixme: use RTL_UNICODE_STRING_BUFFER */
-typedef struct SDB_TMP_STR
-{
-    UNICODE_STRING Str;
-    WCHAR FixedBuffer[MAX_PATH];
-} SDB_TMP_STR, *PSDB_TMP_STR;
-
-void SdbpInitTempStr(PSDB_TMP_STR String)
-{
-    String->Str.Buffer = String->FixedBuffer;
-    String->Str.Length = 0;
-    String->Str.MaximumLength = sizeof(String->FixedBuffer);
-}
-
-void SdbpFreeTempStr(PSDB_TMP_STR String)
-{
-    if (String->Str.Buffer != String->FixedBuffer)
-    {
-        SdbFree(String->Str.Buffer);
-    }
-}
-
-void SdbpResizeTempStr(PSDB_TMP_STR String, WORD newLength)
-{
-    if (newLength > String->Str.MaximumLength)
-    {
-        SdbpFreeTempStr(String);
-        String->Str.MaximumLength = newLength * sizeof(WCHAR);
-        String->Str.Buffer = SdbAlloc(String->Str.MaximumLength);
-        String->Str.Length = 0;
-    }
-}
-
-BOOL SdbpGetLongPathName(PCWSTR wszPath, PSDB_TMP_STR Result)
-{
-    DWORD max = Result->Str.MaximumLength / 2;
-    DWORD ret = GetLongPathNameW(wszPath, Result->Str.Buffer, max);
-    if (ret)
-    {
-        if (ret >= max)
-        {
-            SdbpResizeTempStr(Result, ret);
-            max = Result->Str.MaximumLength / 2;
-            ret = GetLongPathNameW(wszPath, Result->Str.Buffer, max);
-        }
-        if (ret && ret < max)
-        {
-            Result->Str.Length = ret * 2;
-            return TRUE;
-        }
-    }
-    SHIM_ERR("Failed to convert short path to long path error 0x%lx\n", GetLastError());
-    return FALSE;
-}
-
-BOOL SdbpIsPathOnRemovableMedia(PCWSTR Path)
-{
-    WCHAR tmp[] = { 'A',':','\\',0 };
-    ULONG type;
-    if (!Path || Path[0] == UNICODE_NULL)
-    {
-        SHIM_ERR("Invalid argument\n");
-        return FALSE;
-    }
-    switch (Path[1])
-    {
-    case L':':
-        break;
-    case L'\\':
-        SHIM_INFO("\"%S\" is a network path.\n", Path);
-        return FALSE;
-    default:
-        SHIM_INFO("\"%S\" not a full path we can operate on.\n", Path);
-        return FALSE;
-    }
-    tmp[0] = Path[0];
-    type = GetDriveTypeW(tmp);
-
-    return type == DRIVE_REMOVABLE || type == DRIVE_CDROM;
-}
-
-/* Convert a path on removable media to 'SIGN.MEDIA=%X filename' */
-BOOL SdbpBuildSignMediaId(PSDB_TMP_STR LongPath)
-{
-    SDB_TMP_STR Scratch;
-    PWCHAR Ptr;
-
-    SdbpInitTempStr(&Scratch);
-    SdbpResizeTempStr(&Scratch, LongPath->Str.Length / sizeof(WCHAR) + 30);
-    StringCbCopyNW(Scratch.Str.Buffer, Scratch.Str.MaximumLength, LongPath->Str.Buffer, LongPath->Str.Length);
-    Ptr = wcsrchr(LongPath->Str.Buffer, '\\');
-    if (Ptr)
-    {
-        HANDLE FindHandle;
-        WIN32_FIND_DATAW FindData;
-        Ptr[1] = '*';
-        Ptr[2] = '\0';
-        FindHandle = FindFirstFileW(LongPath->Str.Buffer, &FindData);
-        if (FindHandle != INVALID_HANDLE_VALUE)
-        {
-            DWORD SignMedia = 0;
-            do
-            {
-                if (!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && FindData.nFileSizeLow)
-                    SignMedia = SignMedia << 1 ^ FindData.nFileSizeLow;
-            } while (FindNextFileW(FindHandle, &FindData));
-
-            FindClose(FindHandle);
-            SdbpResizeTempStr(LongPath, (LongPath->Str.Length >> 1) + 20);
-            StringCbPrintfW(LongPath->Str.Buffer, LongPath->Str.MaximumLength, SIGN_MEDIA_FMT, SignMedia, Scratch.Str.Buffer + 3);
-            LongPath->Str.Length = (USHORT)SdbpStrlen(LongPath->Str.Buffer) * sizeof(WCHAR);
-            SdbpFreeTempStr(&Scratch);
-            return TRUE;
-        }
-    }
-    SdbpFreeTempStr(&Scratch);
-    SdbpFreeTempStr(LongPath);
-    return FALSE;
-}
-
-/* Convert a given path to a long or media path */
-BOOL SdbpResolvePath(PSDB_TMP_STR LongPath, PCWSTR wszPath)
-{
-    SdbpInitTempStr(LongPath);
-    if (!SdbpGetLongPathName(wszPath, LongPath))
-    {
-        SdbpFreeTempStr(LongPath);
-        return FALSE;
-    }
-    if (SdbpIsPathOnRemovableMedia(LongPath->Str.Buffer))
-    {
-        return SdbpBuildSignMediaId(LongPath);
-    }
-    return TRUE;
-}
-
-static ACCESS_MASK g_QueryFlag = 0xffffffff;
-ACCESS_MASK QueryFlag(void)
-{
-    if (g_QueryFlag == 0xffffffff)
-    {
-        ULONG_PTR wow64_ptr = 0;
-        NTSTATUS Status = NtQueryInformationProcess(NtCurrentProcess(), ProcessWow64Information, &wow64_ptr, sizeof(wow64_ptr), NULL);
-        g_QueryFlag = (NT_SUCCESS(Status) && wow64_ptr != 0) ? KEY_WOW64_64KEY : 0;
-    }
-    return g_QueryFlag;
-}
-
-NTSTATUS SdbpOpenKey(PUNICODE_STRING FullPath, BOOL bMachine, ACCESS_MASK Access, PHANDLE KeyHandle)
-{
-    UNICODE_STRING BasePath;
-    const WCHAR* LayersKey = APPCOMPAT_LAYER_KEY;
-    OBJECT_ATTRIBUTES ObjectLayer = RTL_INIT_OBJECT_ATTRIBUTES(FullPath, OBJ_CASE_INSENSITIVE);
-    NTSTATUS Status;
-    FullPath->Buffer = NULL;
-    FullPath->Length = FullPath->MaximumLength = 0;
-    if (bMachine)
-    {
-        RtlInitUnicodeString(&BasePath, REGISTRY_MACHINE);
-    }
-    else
-    {
-        Status = RtlFormatCurrentUserKeyPath(&BasePath);
-        if (!NT_SUCCESS(Status))
-        {
-            SHIM_ERR("Unable to acquire user registry key, Error: 0x%lx\n", Status);
-            return Status;
-        }
-    }
-    FullPath->MaximumLength = (USHORT)(BasePath.Length + SdbpStrsize(LayersKey));
-    FullPath->Buffer = SdbAlloc(FullPath->MaximumLength);
-    FullPath->Length = 0;
-    RtlAppendUnicodeStringToString(FullPath, &BasePath);
-    if (!bMachine)
-        RtlFreeUnicodeString(&BasePath);
-    RtlAppendUnicodeToString(FullPath, LayersKey);
-
-    Status = NtOpenKey(KeyHandle, Access | QueryFlag(), &ObjectLayer);
-    if (!NT_SUCCESS(Status))
-    {
-        SHIM_ERR("Unable to open Key  \"%wZ\" Status 0x%lx\n", FullPath, Status);
-        SdbFree(FullPath->Buffer);
-        FullPath->Buffer = NULL;
-    }
-    return Status;
-}
-
-
-BOOL SdbpGetPermLayersInternal(PUNICODE_STRING FullPath, PWSTR pwszLayers, PDWORD pdwBytes, BOOL bMachine)
-{
-    UNICODE_STRING FullKey;
-    ULONG ValueBuffer[(MAX_LAYER_LENGTH * sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG) - 1) / sizeof(ULONG)];
-    PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)ValueBuffer;
-    ULONG Length = 0;
-    HANDLE KeyHandle;
-    NTSTATUS Status;
-
-    Status = SdbpOpenKey(&FullKey, bMachine, KEY_QUERY_VALUE, &KeyHandle);
-    if (NT_SUCCESS(Status))
-    {
-        Status = NtQueryValueKey(KeyHandle, FullPath, KeyValuePartialInformation, PartialInfo, sizeof(ValueBuffer), &Length);
-        if (NT_SUCCESS(Status))
-        {
-            StringCbCopyNW(pwszLayers, *pdwBytes, (PCWSTR)PartialInfo->Data, PartialInfo->DataLength);
-            *pdwBytes = PartialInfo->DataLength;
-        }
-        else
-        {
-            SHIM_INFO("Failed to read value info from Key \"%wZ\" Status 0x%lx\n", &FullKey, Status);
-        }
-        NtClose(KeyHandle);
-        SdbFree(FullKey.Buffer);
-    }
-    return NT_SUCCESS(Status);
-}
-
-BOOL SdbDeletePermLayerKeys(PCWSTR wszPath, BOOL bMachine)
-{
-    UNICODE_STRING FullKey;
-    SDB_TMP_STR LongPath;
-    HANDLE KeyHandle;
-    NTSTATUS Status;
-
-    if (!SdbpResolvePath(&LongPath, wszPath))
-        return FALSE;
-
-    Status = SdbpOpenKey(&FullKey, bMachine, KEY_SET_VALUE, &KeyHandle);
-    if (NT_SUCCESS(Status))
-    {
-        Status = NtDeleteValueKey(KeyHandle, &LongPath.Str);
-        if (!NT_SUCCESS(Status))
-        {
-            SHIM_INFO("Failed to delete value from Key \"%wZ\" Status 0x%lx\n", &FullKey, Status);
-            /* This is what we want, so if the key didnt exist, we should not fail :) */
-            if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
-                Status = STATUS_SUCCESS;
-        }
-        NtClose(KeyHandle);
-        SdbFree(FullKey.Buffer);
-    }
-    SdbpFreeTempStr(&LongPath);
-    return NT_SUCCESS(Status);
-}
-
-BOOL SdbpMatchLayer(PCWSTR start, PCWSTR end, PCWSTR compare)
-{
-    size_t len;
-    if (!end)
-        return !wcsicmp(start, compare);
-    len = end - start;
-    return wcslen(compare) == len && !_wcsnicmp(start, compare, len);
-}
-
-BOOL SdbpAppendLayer(PWSTR target, DWORD len, PCWSTR layer, PCWSTR end)
-{
-    NTSTATUS Status = STATUS_SUCCESS;
-    if (target[0])
-        Status = StringCbCatW(target, len, SPACE_ONLY);
-
-    if (NT_SUCCESS(Status))
-    {
-        if (end)
-            Status = StringCbCatNW(target, len, layer, (end - layer) * sizeof(WCHAR));
-        else
-            Status = StringCbCatW(target, len, layer);
-    }
-
-    return NT_SUCCESS(Status);
-}
-
-
-/**
- * Determine if we allow permission layers to apply on this file.
- *
- * @param [in]  Path    Full pathname of the file, only the drive part is used.
- *
- * @return  TRUE if we allow permission layer, FALSE if not.
- */
-BOOL WINAPI AllowPermLayer(PCWSTR Path)
-{
-    WCHAR tmp[] = { 'A',':','\\', 0 };
-    ULONG type;
-    if (!Path)
-    {
-        SHIM_ERR("Invalid argument\n");
-        return FALSE;
-    }
-    switch (Path[1])
-    {
-    case L':':
-        break;
-    case L'\\':
-        SHIM_INFO("\"%S\" is a network path.\n", Path);
-        return FALSE;
-    default:
-        SHIM_INFO("\"%S\" not a full path we can operate on.\n", Path);
-        return FALSE;
-    }
-    tmp[0] = Path[0];
-    type = GetDriveTypeW(tmp);
-    if (type == DRIVE_REMOTE)
-    {
-        /* The logging here indicates that it does not like a CDROM or removable media, but it only
-            seems to bail out on a media that reports it is remote...
-            I have included correct logging, I doubt anyone would parse the logging, so this shouldnt break anything. */
-        SHIM_INFO("\"%S\" is on a remote drive.\n", Path);
-        return FALSE;
-    }
-    return TRUE;
-}
-
-/**
- * Read the layers specified for the application.
- *
- * @param [in]  wszPath     Full pathname of the file.
- * @param [out] pwszLayers  On return, the layers set on the file.
- * @param   pdwBytes        The size of the pwszLayers buffer in bytes, and on return the size of
- *                          the data written (in bytes)
- * @param [in]  dwFlags     The flags, [GPLK_USER | GPLK_MACHINE].
- *
- * @return  TRUE if it succeeds, FALSE if it fails.
- */
-BOOL WINAPI SdbGetPermLayerKeys(PCWSTR wszPath, PWSTR pwszLayers, PDWORD pdwBytes, DWORD dwFlags)
-{
-    BOOL Result = FALSE;
-    SDB_TMP_STR LongPath;
-    DWORD dwBytes, dwTotal = 0;
-    if (!wszPath || !pdwBytes)
-    {
-        SHIM_ERR("NULL parameter passed for wszPath or pdwBytes.\n");
-        return FALSE;
-    }
-
-    if (!SdbpResolvePath(&LongPath, wszPath))
-        return FALSE;
-    dwBytes = *pdwBytes;
-    if (dwFlags & GPLK_MACHINE)
-    {
-        if (SdbpGetPermLayersInternal(&LongPath.Str, pwszLayers, &dwBytes, TRUE))
-        {
-            Result = TRUE;
-            dwTotal = dwBytes - sizeof(WCHAR); /* Compensate for the nullterm. */
-            pwszLayers += dwTotal / sizeof(WCHAR);
-            dwBytes = *pdwBytes - dwBytes;
-            if (dwFlags & GPLK_USER)
-            {
-                *(pwszLayers++) = L' ';
-                *pwszLayers = L'\0';
-                dwBytes -= sizeof(WCHAR);
-                dwTotal += sizeof(WCHAR);
-            }
-        }
-    }
-    if (dwFlags & GPLK_USER)
-    {
-        if (SdbpGetPermLayersInternal(&LongPath.Str, pwszLayers, &dwBytes, FALSE))
-        {
-            Result = TRUE;
-            dwTotal += dwBytes - sizeof(WCHAR); /* Compensate for the nullterm. */
-        }
-        else if (dwTotal > 0 && pwszLayers[-1] == L' ')
-        {
-            pwszLayers[-1] = '\0';
-            dwTotal -= sizeof(WCHAR);
-        }
-    }
-    if (dwTotal)
-        dwTotal += sizeof(WCHAR);
-    *pdwBytes = dwTotal;
-    SdbpFreeTempStr(&LongPath);
-    return Result;
-}
-
-/**
- * Set or clear the Layer key.
- *
- * @param [in]  wszPath     Full pathname of the file.
- * @param [in]  wszLayers   The layers to add (space separated), or an empty string / NULL to
- *                          remove all layers.
- * @param [in]  bMachine    TRUE to machine.
- *
- * @return  TRUE if it succeeds, FALSE if it fails.
- */
-BOOL WINAPI SdbSetPermLayerKeys(PCWSTR wszPath, PCWSTR wszLayers, BOOL bMachine)
-{
-    UNICODE_STRING FullKey;
-    SDB_TMP_STR LongPath;
-    HANDLE KeyHandle;
-    NTSTATUS Status;
-
-    if (!wszLayers || *wszLayers == '\0')
-        return SdbDeletePermLayerKeys(wszPath, bMachine);
-
-    if (!SdbpResolvePath(&LongPath, wszPath))
-        return FALSE;
-
-    Status = SdbpOpenKey(&FullKey, bMachine, KEY_SET_VALUE, &KeyHandle);
-    if (NT_SUCCESS(Status))
-    {
-        Status = NtSetValueKey(KeyHandle, &LongPath.Str, 0, REG_SZ, (PVOID)wszLayers, SdbpStrsize(wszLayers));
-        if (!NT_SUCCESS(Status))
-        {
-            SHIM_INFO("Failed to write a value to Key \"%wZ\" Status 0x%lx\n", &FullKey, Status);
-            if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
-                Status = STATUS_SUCCESS;
-        }
-        NtClose(KeyHandle);
-        SdbFree(FullKey.Buffer);
-    }
-    SdbpFreeTempStr(&LongPath);
-    return NT_SUCCESS(Status);
-}
-
-/**
- * Adds or removes a single layer entry.
- *
- * @param [in]  wszPath     Full pathname of the file.
- * @param [in]  wszLayer    The layer to add or remove.
- * @param [in]  dwFlags     Additional flags to add / remove [LAYER_APPLY_TO_SYSTEM_EXES | ???].
- * @param [in]  bMachine    When TRUE, the setting applies to all users, when FALSE only applies
- *                          to the current user.
- * @param [in]  bEnable     TRUE to enable, FALSE to disable a layer / flag specified.
- *
- * @return  TRUE if it succeeds, FALSE if it fails.
- */
-BOOL WINAPI SetPermLayerState(PCWSTR wszPath, PCWSTR wszLayer, DWORD dwFlags, BOOL bMachine, BOOL bEnable)
-{
-    WCHAR fullLayer[MAX_LAYER_LENGTH] = { 0 };
-    WCHAR newLayer[MAX_LAYER_LENGTH] = { 0 };
-    DWORD dwBytes = sizeof(fullLayer), dwWriteFlags = 0;
-    PWSTR start, p;
-
-    if (!wszLayer)
-    {
-        SHIM_ERR("Invalid argument\n");
-        return FALSE;
-    }
-    if (dwFlags & ~(LAYER_APPLY_TO_SYSTEM_EXES | LAYER_UNK_FLAG2))
-    {
-        SHIM_ERR("Invalid flags\n");
-        return FALSE;
-    }
-    p = wcspbrk(wszLayer, DISALLOWED_LAYER_CHARS);
-    if (p)
-    {
-        switch (*p)
-        {
-        case ' ':
-            SHIM_ERR("Only one layer can be passed in at a time.\n");
-            return FALSE;
-        case '#':
-        case '!':
-            SHIM_ERR("Flags cannot be passed in with the layer name.\n");
-            return FALSE;
-        }
-    }
-    if (!SdbGetPermLayerKeys(wszPath, fullLayer, &dwBytes, bMachine ? GPLK_MACHINE : GPLK_USER))
-    {
-        fullLayer[0] = '\0';
-        dwBytes = sizeof(fullLayer);
-    }
-
-    start = fullLayer;
-    while (*start == '!' || *start == '#' || *start == ' ' || *start == '\t')
-    {
-        if (*start == '#')
-            dwWriteFlags |= LAYER_APPLY_TO_SYSTEM_EXES;
-        else if (*start == '!')
-            dwWriteFlags |= LAYER_UNK_FLAG2;
-        start++;
-    }
-    if (bEnable)
-        dwWriteFlags |= dwFlags;
-    else
-        dwWriteFlags &= ~dwFlags;
-
-    p = newLayer;
-    if (dwWriteFlags & LAYER_UNK_FLAG2)
-        *(p++) = '!';
-    if (dwWriteFlags & LAYER_APPLY_TO_SYSTEM_EXES)
-        *(p++) = '#';
-
-    do
-    {
-        while (*start == ' ' || *start == '\t')
-            ++start;
-
-        if (*start == '\0')
-            break;
-        p = wcspbrk(start, LAYER_SEPARATORS);
-        if (!SdbpMatchLayer(start, p, wszLayer))
-        {
-            SdbpAppendLayer(newLayer, sizeof(newLayer), start, p);
-        }
-        start = p + 1;
-    } while (p);
-
-    if (bEnable && wszLayer[0])
-    {
-        SdbpAppendLayer(newLayer, sizeof(newLayer), wszLayer, NULL);
-    }
-
-    return SdbSetPermLayerKeys(wszPath, newLayer, bMachine);
-}