diff --git a/BeefLibs/corlib/src/System/Result.bf b/BeefLibs/corlib/src/System/Result.bf index 91689bde..15725a3c 100644 --- a/BeefLibs/corlib/src/System/Result.bf +++ b/BeefLibs/corlib/src/System/Result.bf @@ -59,10 +59,37 @@ namespace System return default(T); } + [SkipCall] + public void Dispose() + { + + } + + [SkipCall] + static void NoDispose() + { + + } + + static void NoDispose() where TVal : IDisposable + { + Internal.FatalError("Result must be disposed", 1); + } + public void ReturnValueDiscarded() { if (this case .Err(let err)) Internal.FatalError("Unhandled error in result", 1); + NoDispose(); + } + } + + extension Result where T : IDisposable + { + public void Dispose() + { + if (this case .Ok(var val)) + val.Dispose(); } } @@ -116,12 +143,60 @@ namespace System return default(T); } + [SkipCall] + public void Dispose() + { + + } + + [SkipCall] + static void NoDispose() + { + + } + + static void NoDispose() where TVal : IDisposable + { + Internal.FatalError("Result must be disposed", 1); + } + public void ReturnValueDiscarded() { if (this case .Err(var err)) { Internal.FatalError(scope String()..AppendF("Unhandled error in result:\n ", err), 1); } + NoDispose(); + NoDispose(); + } + } + + extension Result where T : IDisposable + { + public void Dispose() + { + if (this case .Ok(var val)) + val.Dispose(); + } + } + + extension Result where TErr : IDisposable + { + public void Dispose() + { + if (this case .Err(var err)) + err.Dispose(); + } + } + + extension Result where T : IDisposable where TErr : IDisposable + { + public void Dispose() + { + if (this case .Ok(var val)) + val.Dispose(); + else if (this case .Err(var err)) + err.Dispose(); } } } diff --git a/BeefLibs/corlib/src/System/Windows.bf b/BeefLibs/corlib/src/System/Windows.bf index eedc8d9f..1c956814 100644 --- a/BeefLibs/corlib/src/System/Windows.bf +++ b/BeefLibs/corlib/src/System/Windows.bf @@ -55,6 +55,12 @@ namespace System { case OK; + public const HResult NOERROR = (.)0; + public const HResult E_INVALIDARG = (.)0x80000003L; + public const HResult E_ABORT = (.)0x80004004L; + public const HResult E_FAIL = (.)0x80004005L; + public const HResult E_ACCESSDENIED = (.)0x80070005L; + public bool Failed { get @@ -186,6 +192,10 @@ namespace System public const int32 REG_QWORD = 11; // 64-bit number public const int32 REG_QWORD_LITTLE_ENDIAN = 11; // 64-bit number (same as REG_QWORD) + public const int32 REG_OPTION_NON_VOLATILE = 0; + + public const int32 KEY_ALL_ACCESS = 0x000f003f; + public const int32 MB_YESNO = 4; public const int32 MB_ICONHAND = 0x10; public const int32 MB_ICONQUESTION = 0x20; @@ -338,7 +348,7 @@ namespace System public Result GetValue(StringView name, String outData) { bool gotData = false; - GetValue(name, scope [&] (regType, regData) => + Try!(GetValue(name, scope [&] (regType, regData) => { if ((regType == Windows.REG_SZ) || (regType == Windows.REG_EXPAND_SZ)) { @@ -348,7 +358,7 @@ namespace System span.RemoveFromEnd(1); outData.Append(span); } - }); + })); if (!gotData) return .Err; return .Ok; @@ -358,14 +368,14 @@ namespace System { bool gotData = false; int sizeofT = sizeof(T); - GetValue(name, scope [&] (regType, regData) => + Try!(GetValue(name, scope [&] (regType, regData) => { if ((regType == Windows.REG_BINARY) && (regData.Length == sizeofT)) { Internal.MemCpy(&data, regData.Ptr, sizeofT); gotData = true; } - }); + })); if (!gotData) return .Err; return .Ok; @@ -421,6 +431,15 @@ namespace System //return Variant.Create(1234); } + public Result SetValue(StringView name, uint32 val) + { + var val; + let result = Windows.RegSetValueExA(this, name.ToScopeCStr!(), 0, Windows.REG_DWORD, &val, 4); + if (result != 0) + return .Err; + return .Ok; + } + public Result SetValue(StringView name, StringView strValue) { let result = Windows.RegSetValueExA(this, name.ToScopeCStr!(), 0, Windows.REG_SZ, strValue.ToScopeCStr!(), (uint32)strValue.Length + 1); @@ -831,6 +850,7 @@ namespace System public const int32 ERROR_INVALID_FUNCTION = 0x1; public const int32 ERROR_FILE_NOT_FOUND = 0x2; public const int32 ERROR_PATH_NOT_FOUND = 0x3; + public const int32 ERROR_ACCESS_DENIED = 0x5; public const int32 ERROR_INVALID_HANDLE = 0x6; public const int32 ERROR_NOT_ENOUGH_MEMORY = 0x8; public const int32 ERROR_INVALID_DATA = 0xd; @@ -1107,9 +1127,19 @@ namespace System [Import("advapi32.lib"), CLink, StdCall] public static extern int32 RegOpenKeyExA(HKey hKey, char8* lpSubKey, uint32 ulOptions, uint32 samDesired, out HKey phkResult); + [Import("advapi32.lib"), CLink, StdCall] + public static extern int32 RegCreateKeyExW(HKey hKey, char16* lpSubKey, uint32 reserved, char16* lpClass, uint32 dwOptions, uint32 samDesired, + SecurityAttributes* lpSecurityAttributes, out HKey phkResult, uint32* lpdwDisposition); + [Import("advapi32.lib"), CLink, StdCall] public static extern int32 RegCloseKey(HKey hKey); + [Import("advapi32.lib"), CLink, StdCall] + public static extern int32 RegDeleteKeyA(HKey hKey, char8* lpSubKey); + + [Import("advapi32.lib"), CLink, StdCall] + public static extern int32 RegDeleteValueA(HKey hKey, char8* lpSubKey); + [Import("advapi32.lib"), CLink, StdCall] public static extern int32 RegQueryValueExW(HKey hKey, char16* lpValueName, uint32* lpReserved, uint32* lpType, void* lpData, uint32* lpcbData); @@ -1421,6 +1451,9 @@ namespace System public static extern IntBool GetFileMUIPath(uint32 dwFlags, char16* pcwszFilePath, char16* pwszLanguage, uint32* pcchLanguage, char16* pwszFileMUIPath, uint32* pcchFileMUIPath, uint64* pululEnumerator); + [CLink, StdCall] + public static extern IntBool SetDllDirectoryW(char16* libFileName); + [CLink, StdCall] public static extern HInstance LoadLibraryW(char16* libFileName); diff --git a/BeefySysLib/platform/PlatformInterface.h b/BeefySysLib/platform/PlatformInterface.h index d77a3112..161be12b 100644 --- a/BeefySysLib/platform/PlatformInterface.h +++ b/BeefySysLib/platform/PlatformInterface.h @@ -45,7 +45,8 @@ enum BfpResult BfpResult_AccessError, BfpResult_PartialData, BfpResult_TempFileError, - BfpResult_Timeout + BfpResult_Timeout, + BfpResult_NotEmpty }; enum BfpSystemResult @@ -67,7 +68,8 @@ enum BfpFileResult BfpFileResult_AccessError = BfpResult_AccessError, BfpFileResult_PartialData = BfpResult_PartialData, BfpFileResult_InsufficientBuffer = BfpResult_InsufficientBuffer, - BfpFileResult_Timeout = BfpResult_Timeout + BfpFileResult_Timeout = BfpResult_Timeout, + BfpFileResult_NotEmpty = BfpResult_NotEmpty }; typedef void(*BfpCrashInfoFunc)(); @@ -283,6 +285,7 @@ enum BfpSysDirectoryKind BfpSysDirectoryKind_Home, BfpSysDirectoryKind_System, BfpSysDirectoryKind_Desktop, + BfpSysDirectoryKind_Desktop_Common, BfpSysDirectoryKind_AppData_Local, BfpSysDirectoryKind_AppData_LocalLow, BfpSysDirectoryKind_AppData_Roaming, diff --git a/IDE/mintest/minlib/src/System/Result.bf b/IDE/mintest/minlib/src/System/Result.bf index bd8a6d98..23cdb249 100644 --- a/IDE/mintest/minlib/src/System/Result.bf +++ b/IDE/mintest/minlib/src/System/Result.bf @@ -50,10 +50,37 @@ namespace System return default(T); } + [SkipCall] + public void Dispose() + { + + } + + [SkipCall] + public static void NoDispose() + { + + } + + public static void NoDispose() where TVal : IDisposable + { + Internal.FatalError("Result must be disposed", 1); + } + public void ReturnValueDiscarded() { if (this case .Err) Internal.FatalError("Unhandled error in result", 1); + NoDispose(); + } + } + + extension Result where T : IDisposable + { + public void Dispose() + { + if (this case .Ok(var val)) + val.Dispose(); } } @@ -111,6 +138,23 @@ namespace System return default(T); } + [SkipCall] + public void Dispose() + { + + } + + [SkipCall] + public static void NoDispose() + { + + } + + public static void NoDispose() where TVal : IDisposable + { + Internal.FatalError("Result must be disposed", 1); + } + public void ReturnValueDiscarded() { if (this case .Err(var err)) @@ -121,6 +165,36 @@ namespace System showErr.ConcatInto("Unhandled error in result:\n ", errStr); Internal.FatalError(showErr, 1); } + NoDispose(); + } + } + + extension Result where T : IDisposable + { + public void Dispose() + { + if (this case .Ok(var val)) + val.Dispose(); + } + } + + extension Result where TErr : IDisposable + { + public void Dispose() + { + if (this case .Err(var err)) + err.Dispose(); + } + } + + extension Result where T : IDisposable where TErr : IDisposable + { + public void Dispose() + { + if (this case .Ok(var val)) + val.Dispose(); + else if (this case .Err(var err)) + err.Dispose(); } } }