mirror of
https://github.com/make-42/hayai.git
synced 2025-01-18 18:47:10 +01:00
305 lines
8.2 KiB
Go
305 lines
8.2 KiB
Go
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package w32
|
|
|
|
import (
|
|
"fmt"
|
|
// "github.com/davecgh/go-spew/spew"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
var (
|
|
modntdll = syscall.NewLazyDLL("ntdll.dll")
|
|
|
|
procAlpcGetMessageAttribute = modntdll.NewProc("AlpcGetMessageAttribute")
|
|
procNtAlpcAcceptConnectPort = modntdll.NewProc("NtAlpcAcceptConnectPort")
|
|
procNtAlpcCancelMessage = modntdll.NewProc("NtAlpcCancelMessage")
|
|
procNtAlpcConnectPort = modntdll.NewProc("NtAlpcConnectPort")
|
|
procNtAlpcCreatePort = modntdll.NewProc("NtAlpcCreatePort")
|
|
procNtAlpcDisconnectPort = modntdll.NewProc("NtAlpcDisconnectPort")
|
|
procNtAlpcSendWaitReceivePort = modntdll.NewProc("NtAlpcSendWaitReceivePort")
|
|
procRtlCreateUnicodeStringFromAsciiz = modntdll.NewProc("RtlCreateUnicodeStringFromAsciiz")
|
|
)
|
|
|
|
//func RtlCreateUnicodeStringFromAsciiz(s string) (us UNICODE_STRING, e error) {
|
|
//
|
|
// cs := C.CString(s)
|
|
// defer C.free(unsafe.Pointer(cs))
|
|
//
|
|
// ret, _, lastErr := procRtlCreateUnicodeStringFromAsciiz.Call(
|
|
// uintptr(unsafe.Pointer(&us)),
|
|
// uintptr(unsafe.Pointer(cs)),
|
|
// )
|
|
//
|
|
// if ret != 1 { // ret is a BOOL ( I think )
|
|
// e = lastErr
|
|
// }
|
|
//
|
|
// return
|
|
//}
|
|
|
|
//func newUnicodeString(s string) (us UNICODE_STRING, e error) {
|
|
// // TODO probably not the most efficient way to do this, but I couldn't
|
|
// // work out how to manually initialize the UNICODE_STRING struct in a way
|
|
// // that the ALPC subsystem liked.
|
|
// us, e = RtlCreateUnicodeStringFromAsciiz(s)
|
|
// return
|
|
//}
|
|
|
|
// (this is a macro)
|
|
// VOID InitializeObjectAttributes(
|
|
// [out] POBJECT_ATTRIBUTES InitializedAttributes,
|
|
// [in] PUNICODE_STRING ObjectName,
|
|
// [in] ULONG Attributes,
|
|
// [in] HANDLE RootDirectory,
|
|
// [in, optional] PSECURITY_DESCRIPTOR SecurityDescriptor
|
|
// )
|
|
//func InitializeObjectAttributes(
|
|
// name string,
|
|
// attributes uint32,
|
|
// rootDir HANDLE,
|
|
// pSecurityDescriptor *SECURITY_DESCRIPTOR,
|
|
//) (oa OBJECT_ATTRIBUTES, e error) {
|
|
//
|
|
// oa = OBJECT_ATTRIBUTES{
|
|
// RootDirectory: rootDir,
|
|
// Attributes: attributes,
|
|
// SecurityDescriptor: pSecurityDescriptor,
|
|
// }
|
|
// oa.Length = uint32(unsafe.Sizeof(oa))
|
|
//
|
|
// if len(name) > 0 {
|
|
// us, err := newUnicodeString(name)
|
|
// if err != nil {
|
|
// e = err
|
|
// return
|
|
// }
|
|
// oa.ObjectName = &us
|
|
// }
|
|
//
|
|
// return
|
|
//}
|
|
|
|
// NTSTATUS
|
|
// NtAlpcCreatePort(
|
|
// __out PHANDLE PortHandle,
|
|
// __in POBJECT_ATTRIBUTES ObjectAttributes,
|
|
// __in_opt PALPC_PORT_ATTRIBUTES PortAttributes
|
|
// );
|
|
func NtAlpcCreatePort(pObjectAttributes *OBJECT_ATTRIBUTES, pPortAttributes *ALPC_PORT_ATTRIBUTES) (hPort HANDLE, e error) {
|
|
|
|
ret, _, _ := procNtAlpcCreatePort.Call(
|
|
uintptr(unsafe.Pointer(&hPort)),
|
|
uintptr(unsafe.Pointer(pObjectAttributes)),
|
|
uintptr(unsafe.Pointer(pPortAttributes)),
|
|
)
|
|
|
|
if ret != ERROR_SUCCESS {
|
|
return hPort, fmt.Errorf("0x%x", ret)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// NTSTATUS
|
|
// NtAlpcConnectPort(
|
|
// __out PHANDLE PortHandle,
|
|
// __in PUNICODE_STRING PortName,
|
|
// __in POBJECT_ATTRIBUTES ObjectAttributes,
|
|
// __in_opt PALPC_PORT_ATTRIBUTES PortAttributes,
|
|
// __in ULONG Flags,
|
|
// __in_opt PSID RequiredServerSid,
|
|
// __inout PPORT_MESSAGE ConnectionMessage,
|
|
// __inout_opt PULONG BufferLength,
|
|
// __inout_opt PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes,
|
|
// __inout_opt PALPC_MESSAGE_ATTRIBUTES InMessageAttributes,
|
|
// __in_opt PLARGE_INTEGER Timeout
|
|
// );
|
|
//func NtAlpcConnectPort(
|
|
// destPort string,
|
|
// pClientObjAttrs *OBJECT_ATTRIBUTES,
|
|
// pClientAlpcPortAttrs *ALPC_PORT_ATTRIBUTES,
|
|
// flags uint32,
|
|
// pRequiredServerSid *SID,
|
|
// pConnMsg *AlpcShortMessage,
|
|
// pBufLen *uint32,
|
|
// pOutMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
|
|
// pInMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
|
|
// timeout *int64,
|
|
//) (hPort HANDLE, e error) {
|
|
//
|
|
// destPortU, e := newUnicodeString(destPort)
|
|
// if e != nil {
|
|
// return
|
|
// }
|
|
//
|
|
// ret, _, _ := procNtAlpcConnectPort.Call(
|
|
// uintptr(unsafe.Pointer(&hPort)),
|
|
// uintptr(unsafe.Pointer(&destPortU)),
|
|
// uintptr(unsafe.Pointer(pClientObjAttrs)),
|
|
// uintptr(unsafe.Pointer(pClientAlpcPortAttrs)),
|
|
// uintptr(flags),
|
|
// uintptr(unsafe.Pointer(pRequiredServerSid)),
|
|
// uintptr(unsafe.Pointer(pConnMsg)),
|
|
// uintptr(unsafe.Pointer(pBufLen)),
|
|
// uintptr(unsafe.Pointer(pOutMsgAttrs)),
|
|
// uintptr(unsafe.Pointer(pInMsgAttrs)),
|
|
// uintptr(unsafe.Pointer(timeout)),
|
|
// )
|
|
//
|
|
// if ret != ERROR_SUCCESS {
|
|
// e = fmt.Errorf("0x%x", ret)
|
|
// }
|
|
// return
|
|
//}
|
|
|
|
// NTSTATUS
|
|
// NtAlpcAcceptConnectPort(
|
|
// __out PHANDLE PortHandle,
|
|
// __in HANDLE ConnectionPortHandle,
|
|
// __in ULONG Flags,
|
|
// __in POBJECT_ATTRIBUTES ObjectAttributes,
|
|
// __in PALPC_PORT_ATTRIBUTES PortAttributes,
|
|
// __in_opt PVOID PortContext,
|
|
// __in PPORT_MESSAGE ConnectionRequest,
|
|
// __inout_opt PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes,
|
|
// __in BOOLEAN AcceptConnection
|
|
// );
|
|
func NtAlpcAcceptConnectPort(
|
|
hSrvConnPort HANDLE,
|
|
flags uint32,
|
|
pObjAttr *OBJECT_ATTRIBUTES,
|
|
pPortAttr *ALPC_PORT_ATTRIBUTES,
|
|
pContext *AlpcPortContext,
|
|
pConnReq *AlpcShortMessage,
|
|
pConnMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
|
|
accept uintptr,
|
|
) (hPort HANDLE, e error) {
|
|
|
|
ret, _, _ := procNtAlpcAcceptConnectPort.Call(
|
|
uintptr(unsafe.Pointer(&hPort)),
|
|
uintptr(hSrvConnPort),
|
|
uintptr(flags),
|
|
uintptr(unsafe.Pointer(pObjAttr)),
|
|
uintptr(unsafe.Pointer(pPortAttr)),
|
|
uintptr(unsafe.Pointer(pContext)),
|
|
uintptr(unsafe.Pointer(pConnReq)),
|
|
uintptr(unsafe.Pointer(pConnMsgAttrs)),
|
|
accept,
|
|
)
|
|
|
|
if ret != ERROR_SUCCESS {
|
|
e = fmt.Errorf("0x%x", ret)
|
|
}
|
|
return
|
|
}
|
|
|
|
// NTSTATUS
|
|
// NtAlpcSendWaitReceivePort(
|
|
// __in HANDLE PortHandle,
|
|
// __in ULONG Flags,
|
|
// __in_opt PPORT_MESSAGE SendMessage,
|
|
// __in_opt PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes,
|
|
// __inout_opt PPORT_MESSAGE ReceiveMessage,
|
|
// __inout_opt PULONG BufferLength,
|
|
// __inout_opt PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes,
|
|
// __in_opt PLARGE_INTEGER Timeout
|
|
// );
|
|
func NtAlpcSendWaitReceivePort(
|
|
hPort HANDLE,
|
|
flags uint32,
|
|
sendMsg *AlpcShortMessage, // Should actually point to PORT_MESSAGE + payload
|
|
sendMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
|
|
recvMsg *AlpcShortMessage,
|
|
recvBufLen *uint32,
|
|
recvMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
|
|
timeout *int64, // use native int64
|
|
) (e error) {
|
|
|
|
ret, _, _ := procNtAlpcSendWaitReceivePort.Call(
|
|
uintptr(hPort),
|
|
uintptr(flags),
|
|
uintptr(unsafe.Pointer(sendMsg)),
|
|
uintptr(unsafe.Pointer(sendMsgAttrs)),
|
|
uintptr(unsafe.Pointer(recvMsg)),
|
|
uintptr(unsafe.Pointer(recvBufLen)),
|
|
uintptr(unsafe.Pointer(recvMsgAttrs)),
|
|
uintptr(unsafe.Pointer(timeout)),
|
|
)
|
|
|
|
if ret != ERROR_SUCCESS {
|
|
e = fmt.Errorf("0x%x", ret)
|
|
}
|
|
return
|
|
}
|
|
|
|
// NTSYSAPI
|
|
// PVOID
|
|
// NTAPI
|
|
// AlpcGetMessageAttribute(
|
|
// __in PALPC_MESSAGE_ATTRIBUTES Buffer,
|
|
// __in ULONG AttributeFlag
|
|
// );
|
|
|
|
// This basically returns a pointer to the correct struct for whichever
|
|
// message attribute you asked for. In Go terms, it returns unsafe.Pointer
|
|
// which you should then cast. Example:
|
|
|
|
// ptr := AlpcGetMessageAttribute(&recvMsgAttrs, ALPC_MESSAGE_CONTEXT_ATTRIBUTE)
|
|
// if ptr != nil {
|
|
// context := (*ALPC_CONTEXT_ATTR)(ptr)
|
|
// }
|
|
func AlpcGetMessageAttribute(buf *ALPC_MESSAGE_ATTRIBUTES, attr uint32) unsafe.Pointer {
|
|
|
|
ret, _, _ := procAlpcGetMessageAttribute.Call(
|
|
uintptr(unsafe.Pointer(buf)),
|
|
uintptr(attr),
|
|
)
|
|
return unsafe.Pointer(ret)
|
|
}
|
|
|
|
// NTSYSCALLAPI
|
|
// NTSTATUS
|
|
// NTAPI
|
|
// NtAlpcCancelMessage(
|
|
// __in HANDLE PortHandle,
|
|
// __in ULONG Flags,
|
|
// __in PALPC_CONTEXT_ATTR MessageContext
|
|
// );
|
|
func NtAlpcCancelMessage(hPort HANDLE, flags uint32, pMsgContext *ALPC_CONTEXT_ATTR) (e error) {
|
|
|
|
ret, _, _ := procNtAlpcCancelMessage.Call(
|
|
uintptr(hPort),
|
|
uintptr(flags),
|
|
uintptr(unsafe.Pointer(pMsgContext)),
|
|
)
|
|
|
|
if ret != ERROR_SUCCESS {
|
|
e = fmt.Errorf("0x%x", ret)
|
|
}
|
|
return
|
|
}
|
|
|
|
// NTSYSCALLAPI
|
|
// NTSTATUS
|
|
// NTAPI
|
|
// NtAlpcDisconnectPort(
|
|
// __in HANDLE PortHandle,
|
|
// __in ULONG Flags
|
|
// );
|
|
func NtAlpcDisconnectPort(hPort HANDLE, flags uint32) (e error) {
|
|
|
|
ret, _, _ := procNtAlpcDisconnectPort.Call(
|
|
uintptr(hPort),
|
|
uintptr(flags),
|
|
)
|
|
|
|
if ret != ERROR_SUCCESS {
|
|
e = fmt.Errorf("0x%x", ret)
|
|
}
|
|
return
|
|
}
|