Skip to content

Commit 35d19cc

Browse files
committed
Added registry helpers
1 parent f4283f6 commit 35d19cc

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed

src/Files.App.CsWin32/NativeMethods.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,6 @@ QITIPF_FLAGS
225225
GetKeyboardState
226226
MapVirtualKey
227227
GetKeyboardLayout
228+
RegOpenKeyExW
229+
HKEY_CLASSES_ROOT
230+
RegEnumKeyEx
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
namespace Files.App.Storage
5+
{
6+
public partial class ShellNewItem
7+
{
8+
}
9+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.Win32;
5+
using Windows.Win32;
6+
using Windows.Win32.Foundation;
7+
using Windows.Win32.System.Registry;
8+
9+
namespace Files.App.Storage
10+
{
11+
public static partial class ShellNewManager
12+
{
13+
public static IEnumerable<ShellNewItem> GetItems()
14+
{
15+
var newMenuItems = new List<ShellNewItem>();
16+
string[] extensionsExcluded = [ ".contact", ".library-ms", ".url", ".lnk" ];
17+
18+
// Get a handle of HKEY_CLASSES_ROOT
19+
bool fRes = WindowsStorableHelpers.OpenRegistryKey(HKEY.HKEY_CLASSES_ROOT, string.Empty, REG_SAM_FLAGS.KEY_READ, out HKEY hKey);
20+
if (!fRes)
21+
{
22+
if (!hKey.IsNull) PInvoke.RegCloseKey(hKey);
23+
yield break;
24+
}
25+
26+
foreach (string keyName in WindowsStorableHelpers.EnumerateRegistryKeyNames(hKey).Where(x => x.StartsWith('.') &&
27+
!extensionsExcluded.Contains(x, StringComparer.OrdinalIgnoreCase)))
28+
{
29+
fRes = WindowsStorableHelpers.OpenRegistryKey(HKEY.HKEY_CLASSES_ROOT, keyName, REG_SAM_FLAGS.KEY_READ, out HKEY hSubKey);
30+
if (!fRes)
31+
{
32+
if (!hKey.IsNull) PInvoke.RegCloseKey(hKey);
33+
if (!hSubKey.IsNull) PInvoke.RegCloseKey(hSubKey);
34+
yield break;
35+
}
36+
37+
// TODO: Get an entry
38+
yield return new();
39+
}
40+
41+
// TODO: Add .txt if necessary
42+
43+
if (!hKey.IsNull) PInvoke.RegCloseKey(hKey);
44+
}
45+
}
46+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using Windows.Win32;
5+
using Windows.Win32.Foundation;
6+
using Windows.Win32.System.Registry;
7+
8+
namespace Files.App.Storage
9+
{
10+
public unsafe static partial class WindowsStorableHelpers
11+
{
12+
public static bool OpenRegistryKey(HKEY hRootKey, string subKey, REG_SAM_FLAGS flags, out HKEY hKey)
13+
{
14+
hKey = default;
15+
16+
HKEY hResultKey = default;
17+
WIN32_ERROR dwResult = default;
18+
19+
fixed (char* pszSubKey = subKey)
20+
dwResult = PInvoke.RegOpenKeyEx(hRootKey, pszSubKey, 0, flags, &hResultKey);
21+
22+
hKey = hResultKey;
23+
24+
return dwResult is WIN32_ERROR.ERROR_SUCCESS;
25+
}
26+
27+
public static string[] EnumerateRegistryKeyNames(HKEY hKey)
28+
{
29+
WIN32_ERROR dwResult = default;
30+
uint dwIndex = 0U;
31+
char* pszName = stackalloc char[256]; // 255 chars + null terminator
32+
uint cchName = 256U;
33+
string[] keyNames = [];
34+
35+
while ((dwResult = PInvoke.RegEnumKeyEx(hKey, dwIndex, pszName, &cchName, null, null, null, null)) is not WIN32_ERROR.ERROR_NO_MORE_ITEMS)
36+
{
37+
if (dwResult is WIN32_ERROR.ERROR_SUCCESS)
38+
{
39+
// Double the capacity of the array if necessary
40+
if (dwIndex >= keyNames.Length)
41+
Array.Resize(ref keyNames, keyNames.Length < 10 ? 10 : keyNames.Length * 2);
42+
43+
keyNames[dwIndex++] = new string(pszName);
44+
}
45+
else
46+
{
47+
// An error occurred, handle it accordingly
48+
break;
49+
}
50+
}
51+
52+
// Fit the array if necessary
53+
if (dwIndex < keyNames.Length)
54+
Array.Resize(ref keyNames, (int)dwIndex);
55+
56+
return keyNames;
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)