mirror of
https://github.com/yv1ing/ShotRDP.git
synced 2025-09-16 15:10:57 +08:00
基本适应win7,win10,win server 08,win server 12,win server 16的截图
This commit is contained in:
328
grdp/plugin/addins.go
Normal file
328
grdp/plugin/addins.go
Normal file
@@ -0,0 +1,328 @@
|
||||
// +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
|
||||
}
|
||||
Reference in New Issue
Block a user