Files
ShotRDP/grdp/plugin/addins.go

329 lines
8.3 KiB
Go

// +build ignore
// addins.go
package plugin
import (
"strings"
"sync/atomic"
"syscall"
"unsafe"
)
var (
openHandleSeq uint32
freerdpClient2 = syscall.NewLazyDLL("freerdp-client2.dll")
winpr2 = syscall.NewLazyDLL("winpr2.dll")
freerdp2 = syscall.NewLazyDLL("freerdp2.dll")
)
var (
virtualChannelEntry = freerdpClient2.NewProc("VirtualChannelEntry")
virtualChannelEntryEx = freerdpClient2.NewProc("VirtualChannelEntryEx")
)
func VirtualChannelEntryEx(ex *ChannelEntryPointsEx, pInitHandle interface{}) (err error) {
r0, _, ec := virtualChannelEntryEx.Call(uintptr(unsafe.Pointer(ex)),
uintptr(unsafe.Pointer(&pInitHandle)))
if r0 == 0 {
err = error(ec)
}
return
}
func ChannelsClientLoadEx(cs *rdpChannels) {
var client ChannelClientData
client.entryEx = VIRTUALCHANNELENTRYEX(VirtualChannelEntryEx)
cs.clientDataList = append(cs.clientDataList, client)
cs.clientDataCount++
var init ChannelInitData
init.channels = cs
init.openDataMap = make(map[uint32]*ChannelOpenData)
cs.initDataList = append(cs.initDataList, init)
cs.initDataCount++
ex := NewChannelEntryPointsEx()
ex.PVirtualChannelInitEx = VIRTUALCHANNELINITEX(RdpVirtualChannelInitEx)
ex.PVirtualChannelOpenEx = VIRTUALCHANNELOPENEX(RdpVirtualChannelOpenEx)
ex.PVirtualChannelCloseEx = VIRTUALCHANNELCLOSEEX(RdpVirtualChannelCloseEx)
ex.PVirtualChannelWriteEx = VIRTUALCHANNELWRITEEX(RdpVirtualChannelWriteEx)
client.entryEx(ex, uintptr(unsafe.Pointer(&init)))
}
type ChannelClientData struct {
//PVIRTUALCHANNELENTRY entry;
entryEx VIRTUALCHANNELENTRYEX
// pChannelInitEventProc *CHANNEL_INIT_EVENT_FN
pChannelInitEventProcEx CHANNEL_INIT_EVENT_EX_FN
pInitHandle interface{}
lpUserParam interface{}
}
type ChannelOpenData struct {
name string
OpenHandle uint32
options uint32
flags int
pInterface interface{}
channels *rdpChannels
lpUserParam interface{}
//pChannelOpenEventProc *CHANNEL_OPEN_EVENT_FN
pChannelOpenEventProcEx *CHANNEL_OPEN_EVENT_EX_FN
}
type ChannelInitData struct {
channels *rdpChannels
pInterface interface{}
openDataMap map[uint32]*ChannelOpenData
}
type rdpChannels struct {
clientDataCount int
clientDataList []ChannelClientData
openDataCount int
openDataList []ChannelOpenData
initDataCount int
initDataList []ChannelInitData
/* control for entry into MyVirtualChannelInit */
can_call_init bool
/* true once freerdp_channels_post_connect is called */
connected bool
/* used for locating the channels for a given instance */
//freerdp* instance;
//wMessageQueue* queue;
//DrdynvcClientContext* drdynvc;
//CRITICAL_SECTION channelsLock;
}
type ChannelOpenEvent struct {
Data interface{}
DataLength uint32
UserData interface{}
pChannelOpenData *ChannelOpenData
}
func RdpVirtualChannelInitEx(lpUserParam interface{}, clientContext interface{},
pInitHandle interface{}, pChannel []ChannelDef,
channelCount int, versionRequested uint32,
pChannelInitEventProcEx CHANNEL_INIT_EVENT_EX_FN) uint {
var (
//rdpSettings* settings;
pChannelInitData *ChannelInitData
pChannelClientData *ChannelClientData
channels *rdpChannels
)
if pInitHandle == nil {
return CHANNEL_RC_BAD_INIT_HANDLE
}
if pChannel == nil {
return CHANNEL_RC_BAD_CHANNEL
}
if (channelCount <= 0) || pChannelInitEventProcEx == nil {
return CHANNEL_RC_INITIALIZATION_ERROR
}
pChannelInitData = pInitHandle.(*ChannelInitData)
//WINPR_ASSERT(pChannelInitData);
channels = pChannelInitData.channels
//WINPR_ASSERT(channels);
if !channels.can_call_init {
return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY
}
if (channels.openDataCount + channelCount) > 30 {
return CHANNEL_RC_TOO_MANY_CHANNELS
}
if channels.connected {
return CHANNEL_RC_ALREADY_CONNECTED
}
if versionRequested != VIRTUAL_CHANNEL_VERSION_WIN2000 {
}
for i := range pChannel {
pChannelDef := &pChannel[i]
if getChannelOpenDataByName(channels, pChannelDef.Name) == nil {
return CHANNEL_RC_BAD_CHANNEL
}
}
pChannelClientData = &channels.clientDataList[channels.clientDataCount]
pChannelClientData.pChannelInitEventProcEx = pChannelInitEventProcEx
pChannelClientData.pInitHandle = pInitHandle
pChannelClientData.lpUserParam = lpUserParam
channels.clientDataCount++
//WINPR_ASSERT(channels->instance);
//WINPR_ASSERT(channels->instance->context);
//settings = channels.instance.context.settings
//WINPR_ASSERT(settings);
for i := range pChannel {
pChannelDef := &pChannel[i]
var pChannelOpenData ChannelOpenData
//WINPR_ASSERT(pChannelOpenData)
pChannelOpenData.OpenHandle = atomic.AddUint32(&openHandleSeq, 1)
pChannelOpenData.channels = channels
pChannelOpenData.lpUserParam = lpUserParam
if _, ok := pChannelInitData.openDataMap[pChannelOpenData.OpenHandle]; ok {
return CHANNEL_RC_INITIALIZATION_ERROR
}
pChannelInitData.pInterface = clientContext
pChannelOpenData.flags = 1
pChannelOpenData.name = pChannelDef.Name
pChannelOpenData.options = pChannelDef.Options
pChannelInitData.openDataMap[pChannelOpenData.OpenHandle] = &pChannelOpenData
channels.openDataList = append(channels.openDataList, pChannelOpenData)
channels.openDataCount++
/*
if settings.ChannelCount < 30 {
channel := freerdp_settings_get_pointer_array_writable(
settings, FreeRDP_ChannelDefArray, settings.ChannelCount)
channel.name = pChannelDef.Name
channel.options = pChannelDef.Options
settings.ChannelCount++
}*/
channels.openDataCount++
}
return CHANNEL_RC_OK
}
func getChannelOpenDataByName(channel *rdpChannels, name string) *ChannelOpenData {
for _, v := range channel.openDataList {
if strings.EqualFold(name, v.name) {
return &v
}
}
return nil
}
func RdpVirtualChannelOpenEx(pInitHandle interface{}, pOpenHandle *uint32, pChannelName string,
pChannelOpenEventProcEx *CHANNEL_OPEN_EVENT_EX_FN) uint {
pChannelInitData := pInitHandle.(*ChannelInitData)
channels := pChannelInitData.channels
pInterface := pChannelInitData.pInterface
if pOpenHandle == nil {
return CHANNEL_RC_BAD_CHANNEL_HANDLE
}
if pChannelOpenEventProcEx == nil {
return CHANNEL_RC_BAD_PROC
}
if !channels.connected {
return CHANNEL_RC_NOT_CONNECTED
}
pChannelOpenData := getChannelOpenDataByName(channels, pChannelName)
if pChannelOpenData == nil {
return CHANNEL_RC_UNKNOWN_CHANNEL_NAME
}
if pChannelOpenData.flags == 2 {
return CHANNEL_RC_ALREADY_OPEN
}
pChannelOpenData.flags = 2 /* open */
pChannelOpenData.pInterface = pInterface
pChannelOpenData.pChannelOpenEventProcEx = pChannelOpenEventProcEx
*pOpenHandle = pChannelOpenData.OpenHandle
return CHANNEL_RC_OK
}
func RdpVirtualChannelCloseEx(pInitHandle interface{}, openHandle uint32) uint {
if pInitHandle == nil {
return CHANNEL_RC_BAD_INIT_HANDLE
}
pChannelInitData := pInitHandle.(*ChannelInitData)
pChannelOpenData := pChannelInitData.openDataMap[openHandle]
if pChannelOpenData == nil {
return CHANNEL_RC_BAD_CHANNEL_HANDLE
}
if pChannelOpenData.flags != 2 {
return CHANNEL_RC_NOT_OPEN
}
pChannelOpenData.flags = 0
return CHANNEL_RC_OK
}
func RdpVirtualChannelWriteEx(pInitHandle interface{}, openHandle uint32,
pData interface{}, dataLength uint32,
pUserData interface{}) uint {
//wMessage message;
if pInitHandle == nil {
return CHANNEL_RC_BAD_INIT_HANDLE
}
pChannelInitData := pInitHandle.(*ChannelInitData)
channels := pChannelInitData.channels
if channels == nil {
return CHANNEL_RC_BAD_CHANNEL_HANDLE
}
pChannelOpenData := pChannelInitData.openDataMap[openHandle]
if pChannelOpenData == nil {
return CHANNEL_RC_BAD_CHANNEL_HANDLE
}
if !channels.connected {
return CHANNEL_RC_NOT_CONNECTED
}
if pData == nil {
return CHANNEL_RC_NULL_DATA
}
if dataLength == 0 {
return CHANNEL_RC_ZERO_LENGTH
}
if pChannelOpenData.flags != 2 {
return CHANNEL_RC_NOT_OPEN
}
pChannelOpenEvent := new(ChannelOpenEvent)
if pChannelOpenEvent == nil {
return CHANNEL_RC_NO_MEMORY
}
pChannelOpenEvent.Data = pData
pChannelOpenEvent.DataLength = dataLength
pChannelOpenEvent.UserData = pUserData
pChannelOpenEvent.pChannelOpenData = pChannelOpenData
/*message.context = channels;
message.id = 0;
message.wParam = pChannelOpenEvent;
message.lParam = NULL;
message.Free = channel_queue_message_free;
if (!MessageQueue_Dispatch(channels->queue, &message))
{
free(pChannelOpenEvent);
return CHANNEL_RC_NO_MEMORY;
}*/
return CHANNEL_RC_OK
}