WindowsApiException
This commit is contained in:
parent
6c52ff9fd2
commit
10ea159606
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[submodule "lib/closeable-state"]
|
||||
path = lib/closeable-state
|
||||
url = https://git.landgrafhomyak.ru/LanguageUtilities/closeable-state.kt
|
||||
[submodule "lib/highlevel-try-finally"]
|
||||
path = lib/highlevel-try-finally
|
||||
url = https://git.landgrafhomyak.ru/xomrk/highlevel-try-finally.kt
|
||||
@ -11,6 +11,8 @@ repositories {
|
||||
}
|
||||
|
||||
kotlin {
|
||||
explicitApi()
|
||||
|
||||
mingwX64()
|
||||
|
||||
linuxX64()
|
||||
@ -23,6 +25,7 @@ kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation("ru.landgrafhomyak.utility:highlevel-try-finally:0.6")
|
||||
implementation("ru.landgrafhomyak.utility:closeable-state-1:1.1")
|
||||
}
|
||||
}
|
||||
|
||||
1
lib/closeable-state
Submodule
1
lib/closeable-state
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit bdb1fe56fa79e50850e8072db0b857955d48b479
|
||||
1
lib/highlevel-try-finally
Submodule
1
lib/highlevel-try-finally
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 6cfa6bddd04a041ae02ec8098c478762313c71de
|
||||
@ -1,2 +1,4 @@
|
||||
rootProject.name = "kotlin-native-stdlib-1"
|
||||
rootProject.name = "kotlin-native-interop-stdlib-0"
|
||||
|
||||
includeBuild("lib/closeable-state")
|
||||
includeBuild("lib/highlevel-try-finally")
|
||||
@ -0,0 +1,10 @@
|
||||
package ru.landgrafhomyak.utility.kotlin_native_interop_stdlib_0
|
||||
|
||||
public abstract class OsException : RuntimeException {
|
||||
public constructor() : super()
|
||||
public constructor(message: String?) : super(message)
|
||||
public constructor(message: String?, cause: Throwable?) : super(message, cause)
|
||||
public constructor(cause: Throwable?) : super(cause)
|
||||
|
||||
abstract override fun toString(): String
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
package ru.landgrafhomyak.utility.kotlin_native_interop_stdlib_0
|
||||
|
||||
import kotlinx.cinterop.ByteVar
|
||||
import kotlinx.cinterop.CPointerVar
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
import kotlinx.cinterop.alloc
|
||||
import kotlinx.cinterop.memScoped
|
||||
import kotlinx.cinterop.ptr
|
||||
import kotlinx.cinterop.reinterpret
|
||||
import kotlinx.cinterop.toKString
|
||||
import kotlinx.cinterop.value
|
||||
import platform.windows.FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
import platform.windows.FORMAT_MESSAGE_FROM_SYSTEM
|
||||
import platform.windows.FORMAT_MESSAGE_IGNORE_INSERTS
|
||||
import platform.windows.FormatMessageA
|
||||
import platform.windows.GetLastError
|
||||
import platform.windows.LocalFree
|
||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
||||
|
||||
public class WindowsApiException : OsException {
|
||||
private val errno: UInt
|
||||
private val nativeMessage: String?
|
||||
|
||||
public constructor(errno: UInt, nativeMessage: String?) : super() {
|
||||
this.errno = errno
|
||||
this.nativeMessage = nativeMessage
|
||||
}
|
||||
|
||||
public constructor(errno: UInt, nativeMessage: String?, customMessage: String?) : super(customMessage) {
|
||||
this.errno = errno
|
||||
this.nativeMessage = nativeMessage
|
||||
}
|
||||
|
||||
public constructor(errno: UInt, nativeMessage: String?, customMessage: String?, cause: Throwable?) : super(customMessage, cause) {
|
||||
this.errno = errno
|
||||
this.nativeMessage = nativeMessage
|
||||
}
|
||||
|
||||
public constructor(errno: UInt, nativeMessage: String?, cause: Throwable?) : super(cause) {
|
||||
this.errno = errno
|
||||
this.nativeMessage = nativeMessage
|
||||
}
|
||||
|
||||
override fun toString(): String =
|
||||
"<windows api exception errno=${this.errno}>"
|
||||
|
||||
public companion object {
|
||||
public fun throwFromLastWindowsErr(): Nothing {
|
||||
throw this.formatFromLastWindowsErr()
|
||||
}
|
||||
|
||||
public fun throwFromWindowsErrCode(code: UInt): Nothing {
|
||||
throw this.formatFromWindowsErrCode(code)
|
||||
}
|
||||
|
||||
public fun formatFromLastWindowsErr(): WindowsApiException = this.formatFromWindowsErrCode(GetLastError())
|
||||
|
||||
public fun formatFromWindowsErrCode(code: UInt): WindowsApiException {
|
||||
var err = WindowsApiException(errno = code, nativeMessage = null, customMessage = "[errno=${code}]")
|
||||
try {
|
||||
val nativeMessage = this.getNativeMessageByErrno(code)
|
||||
err = WindowsApiException(errno = code, nativeMessage = nativeMessage, "[errno=${err}] ${nativeMessage}")
|
||||
} catch (newErr: Throwable) {
|
||||
err.addSuppressed(newErr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
public fun getNativeMessageByErrno(code: UInt): String {
|
||||
memScoped {
|
||||
var buffer = alloc<CPointerVar<ByteVar>>()
|
||||
val result = FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER.toUInt() or FORMAT_MESSAGE_FROM_SYSTEM.toUInt() or FORMAT_MESSAGE_IGNORE_INSERTS.toUInt(),
|
||||
null,
|
||||
code,
|
||||
0u, // MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
buffer.ptr.reinterpret(),
|
||||
0u,
|
||||
null
|
||||
)
|
||||
|
||||
if (result == 0u) {
|
||||
val newErrno = GetLastError()
|
||||
throw WindowsApiException(errno = newErrno, nativeMessage = null, customMessage = "[errno=${newErrno}]")
|
||||
}
|
||||
|
||||
safeAutoClose1(
|
||||
action = {
|
||||
return buffer.value!!.toKString() // todo handle nullablity
|
||||
},
|
||||
finally = {
|
||||
LocalFree(buffer.value)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user