mirror of
https://github.com/snltty/linker.git
synced 2025-11-01 21:13:04 +08:00
删除客户端的bug
This commit is contained in:
@@ -45,7 +45,7 @@ export default {
|
|||||||
const showSelectUsername = computed(() => !!!globalData.value.username && globalData.value.connected);
|
const showSelectUsername = computed(() => !!!globalData.value.username && globalData.value.connected);
|
||||||
const showPort = computed(() => globalData.value.connected == false && state.showPort);
|
const showPort = computed(() => globalData.value.connected == false && state.showPort);
|
||||||
|
|
||||||
watch(() => globalData.value.updateFlag, () => {
|
watch(() => globalData.value.updateRuleFlag, () => {
|
||||||
_getRules();
|
_getRules();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -65,9 +65,7 @@ export default {
|
|||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
subWebsocketState((state) => {
|
subWebsocketState((state) => {
|
||||||
if (state) {
|
if (state) globalData.value.updateRuleFlag = Date.now();
|
||||||
_getRules();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -83,9 +81,9 @@ export default {
|
|||||||
}
|
}
|
||||||
const handleChange = (value) => {
|
const handleChange = (value) => {
|
||||||
addName(value).then(() => {
|
addName(value).then(() => {
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ export default {
|
|||||||
Desc: state.desc
|
Desc: state.desc
|
||||||
}
|
}
|
||||||
}).then((error) => {
|
}).then((error) => {
|
||||||
globalData.value.updateFlag = Date.now();
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
ElMessage.success('操作成功');
|
ElMessage.success('操作成功');
|
||||||
state.show = false;
|
state.show = false;
|
||||||
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(`操作失败:${error}`);
|
ElMessage.error(`操作失败:${error}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
globalData.value.updateFlag = Date.now();
|
|
||||||
if (state.items.length == 1) {
|
if (state.items.length == 1) {
|
||||||
let item = state.items[0];
|
let item = state.items[0];
|
||||||
state.currentPrivate = state.privateExes.filter(c => item.DisallowRunIds.indexOf(c.ID) >= 0);
|
state.currentPrivate = state.privateExes.filter(c => item.DisallowRunIds.indexOf(c.ID) >= 0);
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export default {
|
|||||||
ElMessage.error(error);
|
ElMessage.error(error);
|
||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
@@ -108,7 +108,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
state.showEdit = false;
|
state.showEdit = false;
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
|
|||||||
@@ -38,10 +38,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const globalData = injectGlobalData();;
|
const globalData = injectGlobalData();
|
||||||
onMounted(() => {
|
|
||||||
globalData.value.updateFlag = Date.now();
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
state.show = false;
|
state.show = false;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export default {
|
|||||||
ElMessage.error(error);
|
ElMessage.error(error);
|
||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
@@ -119,7 +119,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
state.showEdit = false;
|
state.showEdit = false;
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
|
|||||||
@@ -56,13 +56,13 @@ export default {
|
|||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
state.show = false;
|
state.show = false;
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateDeviceFlag = Date.now();
|
||||||
}
|
}
|
||||||
const handleDel = (name) => {
|
const handleDel = (name) => {
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
delDevice(name).then(() => {
|
delDevice(name).then(() => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateDeviceFlag = Date.now();
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
});
|
});
|
||||||
@@ -78,7 +78,7 @@ export default {
|
|||||||
devices: _devices.map(c => c.MachineName)
|
devices: _devices.map(c => c.MachineName)
|
||||||
}).then((error) => {
|
}).then((error) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateDeviceFlag = Date.now();
|
||||||
if (error) {
|
if (error) {
|
||||||
ElMessage.error(error);
|
ElMessage.error(error);
|
||||||
} else {
|
} else {
|
||||||
@@ -92,7 +92,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateDeviceFlag = Date.now();
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export default {
|
|||||||
ElMessage.error(error);
|
ElMessage.error(error);
|
||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
@@ -111,7 +111,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
state.showEdit = false;
|
state.showEdit = false;
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
|
|||||||
@@ -38,10 +38,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const globalData = injectGlobalData();;
|
const globalData = injectGlobalData();
|
||||||
onMounted(() => {
|
|
||||||
globalData.value.updateFlag = Date.now();
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
state.show = false;
|
state.show = false;
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default {
|
|||||||
ElMessage.error(error);
|
ElMessage.error(error);
|
||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
@@ -153,7 +153,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
state.showEdit = false;
|
state.showEdit = false;
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export default {
|
|||||||
ElMessage.error(error);
|
ElMessage.error(error);
|
||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
@@ -111,7 +111,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
ElMessage.success('操作成功!');
|
ElMessage.success('操作成功!');
|
||||||
state.showEdit = false;
|
state.showEdit = false;
|
||||||
globalData.value.updateFlag = Date.now();
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ export default {
|
|||||||
if (error) {
|
if (error) {
|
||||||
ElMessage.error(error);
|
ElMessage.error(error);
|
||||||
} else {
|
} else {
|
||||||
globalData.value.updateFlag = Date.now();
|
|
||||||
ElMessage.success('操作成功');
|
ElMessage.success('操作成功');
|
||||||
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const globalData = injectGlobalData();
|
const globalData = injectGlobalData();
|
||||||
|
watch(() => globalData.value.updateDeviceFlag, () => {
|
||||||
|
getData();
|
||||||
|
})
|
||||||
|
|
||||||
const getData = () => {
|
const getData = () => {
|
||||||
getList().then((res) => {
|
getList().then((res) => {
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ export const provideGlobalData = () => {
|
|||||||
publicUserName: 'snltty',
|
publicUserName: 'snltty',
|
||||||
usernames: {},
|
usernames: {},
|
||||||
connected: false,
|
connected: false,
|
||||||
updateFlag: 0,
|
updateRuleFlag: 0,
|
||||||
|
updateDeviceFlag: 0,
|
||||||
allDevices: [],
|
allDevices: [],
|
||||||
devices: computed(() => {
|
devices: computed(() => {
|
||||||
const user = globalData.value.usernames[globalData.value.username];
|
const user = globalData.value.usernames[globalData.value.username];
|
||||||
@@ -17,7 +18,6 @@ export const provideGlobalData = () => {
|
|||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}),
|
}),
|
||||||
latestReportNames: [],
|
|
||||||
reportNames: []
|
reportNames: []
|
||||||
});
|
});
|
||||||
provide(globalDataSymbol, globalData);
|
provide(globalDataSymbol, globalData);
|
||||||
|
|||||||
@@ -49,13 +49,13 @@ namespace cmonitor
|
|||||||
|
|
||||||
//读取参数
|
//读取参数
|
||||||
Dictionary<string, string> dic = ArgumentParser.Parse(args, out string error);
|
Dictionary<string, string> dic = ArgumentParser.Parse(args, out string error);
|
||||||
//#if RELEASE
|
#if RELEASE
|
||||||
//提权
|
//提权
|
||||||
if (dic.ContainsKey("elevated") == false)
|
if (dic.ContainsKey("elevated") == false)
|
||||||
{
|
{
|
||||||
Win32Interop.RelaunchElevated();
|
Win32Interop.RelaunchElevated();
|
||||||
}
|
}
|
||||||
//#endif
|
#endif
|
||||||
//初始化配置文件
|
//初始化配置文件
|
||||||
Config config = new Config();
|
Config config = new Config();
|
||||||
InitConfig(config, dic);
|
InitConfig(config, dic);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace cmonitor.server.api.services
|
|||||||
for (int i = 0; i < updateinfo.Names.Length; i++)
|
for (int i = 0; i < updateinfo.Names.Length; i++)
|
||||||
{
|
{
|
||||||
bool connectionRes = (signCaching.Get(updateinfo.Names[i], out SignCacheInfo cache) && cache.Connected);
|
bool connectionRes = (signCaching.Get(updateinfo.Names[i], out SignCacheInfo cache) && cache.Connected);
|
||||||
|
if (connectionRes == false) continue;
|
||||||
bool reportTimeRes = cache.GetReport(config.ReportDelay) && Interlocked.CompareExchange(ref cache.ReportFlag, 0, 1) == 1;
|
bool reportTimeRes = cache.GetReport(config.ReportDelay) && Interlocked.CompareExchange(ref cache.ReportFlag, 0, 1) == 1;
|
||||||
|
|
||||||
if (connectionRes && (reportTimeRes || updateinfo.ReportType == ReportType.Full))
|
if (connectionRes && (reportTimeRes || updateinfo.ReportType == ReportType.Full))
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace cmonitor.server.api.services
|
|||||||
for (int i = 0; i < report.Names.Length; i++)
|
for (int i = 0; i < report.Names.Length; i++)
|
||||||
{
|
{
|
||||||
bool connectionRes = signCaching.Get(report.Names[i], out SignCacheInfo cache) && cache.Connected;
|
bool connectionRes = signCaching.Get(report.Names[i], out SignCacheInfo cache) && cache.Connected;
|
||||||
|
if (connectionRes == false) continue;
|
||||||
bool reportRes = cache.GetScreen(config.ScreenDelay) && Interlocked.CompareExchange(ref cache.ScreenFlag, 0, 1) == 1;
|
bool reportRes = cache.GetScreen(config.ScreenDelay) && Interlocked.CompareExchange(ref cache.ScreenFlag, 0, 1) == 1;
|
||||||
|
|
||||||
if (connectionRes && reportRes)
|
if (connectionRes && reportRes)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Linq;
|
|
||||||
using static cmonitor.server.client.reports.screen.winapis.ADVAPI32;
|
using static cmonitor.server.client.reports.screen.winapis.ADVAPI32;
|
||||||
using static cmonitor.server.client.reports.screen.winapiss.User32;
|
using static cmonitor.server.client.reports.screen.winapiss.User32;
|
||||||
|
|
||||||
@@ -17,58 +16,6 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
{
|
{
|
||||||
private static nint _lastInputDesktop;
|
private static nint _lastInputDesktop;
|
||||||
|
|
||||||
public static List<WindowsSession> GetActiveSessions()
|
|
||||||
{
|
|
||||||
var sessions = new List<WindowsSession>();
|
|
||||||
var consoleSessionId = Kernel32.WTSGetActiveConsoleSessionId();
|
|
||||||
sessions.Add(new WindowsSession()
|
|
||||||
{
|
|
||||||
Id = consoleSessionId,
|
|
||||||
Type = WindowsSessionType.Console,
|
|
||||||
Name = "Console",
|
|
||||||
Username = GetUsernameFromSessionId(consoleSessionId)
|
|
||||||
});
|
|
||||||
|
|
||||||
nint ppSessionInfo = nint.Zero;
|
|
||||||
var count = 0;
|
|
||||||
var enumSessionResult = WTSAPI32.WTSEnumerateSessions(WTSAPI32.WTS_CURRENT_SERVER_HANDLE, 0, 1, ref ppSessionInfo, ref count);
|
|
||||||
var dataSize = Marshal.SizeOf(typeof(WTSAPI32.WTS_SESSION_INFO));
|
|
||||||
var current = ppSessionInfo;
|
|
||||||
|
|
||||||
if (enumSessionResult != 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
var wtsInfo = Marshal.PtrToStructure(current, typeof(WTSAPI32.WTS_SESSION_INFO));
|
|
||||||
if (wtsInfo is null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var sessionInfo = (WTSAPI32.WTS_SESSION_INFO)wtsInfo;
|
|
||||||
current += dataSize;
|
|
||||||
if (sessionInfo.State == WTSAPI32.WTS_CONNECTSTATE_CLASS.WTSActive && sessionInfo.SessionID != consoleSessionId)
|
|
||||||
{
|
|
||||||
|
|
||||||
sessions.Add(new WindowsSession()
|
|
||||||
{
|
|
||||||
Id = sessionInfo.SessionID,
|
|
||||||
Name = sessionInfo.pWinStationName,
|
|
||||||
Type = WindowsSessionType.RDP,
|
|
||||||
Username = GetUsernameFromSessionId(sessionInfo.SessionID)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetCommandLine()
|
|
||||||
{
|
|
||||||
var commandLinePtr = Kernel32.GetCommandLine();
|
|
||||||
return Marshal.PtrToStringAuto(commandLinePtr) ?? string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool GetCurrentDesktop(out string desktopName)
|
public static bool GetCurrentDesktop(out string desktopName)
|
||||||
{
|
{
|
||||||
var inputDesktop = OpenInputDesktop();
|
var inputDesktop = OpenInputDesktop();
|
||||||
@@ -89,7 +36,51 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
CloseDesktop(inputDesktop);
|
CloseDesktop(inputDesktop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static List<WindowsSession> GetActiveSessions()
|
||||||
|
{
|
||||||
|
List<WindowsSession> sessions = new List<WindowsSession>();
|
||||||
|
uint consoleSessionId = Kernel32.WTSGetActiveConsoleSessionId();
|
||||||
|
sessions.Add(new WindowsSession()
|
||||||
|
{
|
||||||
|
Id = consoleSessionId,
|
||||||
|
Type = WindowsSessionType.Console,
|
||||||
|
Name = "Console",
|
||||||
|
Username = GetUsernameFromSessionId(consoleSessionId)
|
||||||
|
});
|
||||||
|
|
||||||
|
nint ppSessionInfo = nint.Zero;
|
||||||
|
int count = 0;
|
||||||
|
int enumSessionResult = WTSAPI32.WTSEnumerateSessions(WTSAPI32.WTS_CURRENT_SERVER_HANDLE, 0, 1, ref ppSessionInfo, ref count);
|
||||||
|
int dataSize = Marshal.SizeOf(typeof(WTSAPI32.WTS_SESSION_INFO));
|
||||||
|
nint current = ppSessionInfo;
|
||||||
|
|
||||||
|
if (enumSessionResult != 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
object wtsInfo = Marshal.PtrToStructure(current, typeof(WTSAPI32.WTS_SESSION_INFO));
|
||||||
|
if (wtsInfo is null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
WTSAPI32.WTS_SESSION_INFO sessionInfo = (WTSAPI32.WTS_SESSION_INFO)wtsInfo;
|
||||||
|
current += dataSize;
|
||||||
|
if (sessionInfo.State == WTSAPI32.WTS_CONNECTSTATE_CLASS.WTSActive && sessionInfo.SessionID != consoleSessionId)
|
||||||
|
{
|
||||||
|
|
||||||
|
sessions.Add(new WindowsSession()
|
||||||
|
{
|
||||||
|
Id = sessionInfo.SessionID,
|
||||||
|
Name = sessionInfo.pWinStationName,
|
||||||
|
Type = WindowsSessionType.RDP,
|
||||||
|
Username = GetUsernameFromSessionId(sessionInfo.SessionID)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessions;
|
||||||
|
}
|
||||||
public static string GetUsernameFromSessionId(uint sessionId)
|
public static string GetUsernameFromSessionId(uint sessionId)
|
||||||
{
|
{
|
||||||
var username = string.Empty;
|
var username = string.Empty;
|
||||||
@@ -107,123 +98,6 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
{
|
{
|
||||||
return User32.OpenInputDesktop(0, true, ACCESS_MASK.GENERIC_ALL);
|
return User32.OpenInputDesktop(0, true, ACCESS_MASK.GENERIC_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CreateInteractiveSystemProcess(
|
|
||||||
string commandLine,
|
|
||||||
int targetSessionId,
|
|
||||||
bool forceConsoleSession,
|
|
||||||
string desktopName,
|
|
||||||
bool hiddenWindow,
|
|
||||||
out PROCESS_INFORMATION procInfo)
|
|
||||||
{
|
|
||||||
uint winlogonPid = 0;
|
|
||||||
var hUserTokenDup = nint.Zero;
|
|
||||||
var hPToken = nint.Zero;
|
|
||||||
var hProcess = nint.Zero;
|
|
||||||
|
|
||||||
procInfo = new PROCESS_INFORMATION();
|
|
||||||
|
|
||||||
// If not force console, find target session. If not present,
|
|
||||||
// use last active session.
|
|
||||||
var dwSessionId = Kernel32.WTSGetActiveConsoleSessionId();
|
|
||||||
if (!forceConsoleSession)
|
|
||||||
{
|
|
||||||
var activeSessions = GetActiveSessions();
|
|
||||||
if (activeSessions.Any(x => x.Id == targetSessionId))
|
|
||||||
{
|
|
||||||
dwSessionId = (uint)targetSessionId;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dwSessionId = activeSessions.Last().Id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain the process ID of the winlogon process that is running within the currently active session.
|
|
||||||
var processes = Process.GetProcessesByName("winlogon");
|
|
||||||
foreach (Process p in processes)
|
|
||||||
{
|
|
||||||
if ((uint)p.SessionId == dwSessionId)
|
|
||||||
{
|
|
||||||
winlogonPid = (uint)p.Id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Obtain a handle to the winlogon process.
|
|
||||||
hProcess = Kernel32.OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
|
|
||||||
|
|
||||||
// Obtain a handle to the access token of the winlogon process.
|
|
||||||
if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken))
|
|
||||||
{
|
|
||||||
Kernel32.CloseHandle(hProcess);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser.
|
|
||||||
var sa = new SECURITY_ATTRIBUTES();
|
|
||||||
sa.Length = Marshal.SizeOf(sa);
|
|
||||||
|
|
||||||
// Copy the access token of the winlogon process; the newly created token will be a primary token.
|
|
||||||
if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out hUserTokenDup))
|
|
||||||
{
|
|
||||||
Kernel32.CloseHandle(hProcess);
|
|
||||||
Kernel32.CloseHandle(hPToken);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// By default, CreateProcessAsUser creates a process on a non-interactive window station, meaning
|
|
||||||
// the window station has a desktop that is invisible and the process is incapable of receiving
|
|
||||||
// user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user
|
|
||||||
// interaction with the new process.
|
|
||||||
var si = new STARTUPINFO();
|
|
||||||
si.cb = Marshal.SizeOf(si);
|
|
||||||
si.lpDesktop = @"winsta0\" + desktopName;
|
|
||||||
|
|
||||||
// Flags that specify the priority and creation method of the process.
|
|
||||||
uint dwCreationFlags;
|
|
||||||
if (hiddenWindow)
|
|
||||||
{
|
|
||||||
dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW;
|
|
||||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
|
||||||
si.wShowWindow = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new process in the current user's logon session.
|
|
||||||
var result = CreateProcessAsUser(
|
|
||||||
hUserTokenDup,
|
|
||||||
null,
|
|
||||||
commandLine,
|
|
||||||
ref sa,
|
|
||||||
ref sa,
|
|
||||||
false,
|
|
||||||
dwCreationFlags,
|
|
||||||
nint.Zero,
|
|
||||||
null,
|
|
||||||
ref si,
|
|
||||||
out procInfo);
|
|
||||||
uint code = Kernel32.GetLastError();
|
|
||||||
|
|
||||||
// Invalidate the handles.
|
|
||||||
Kernel32.CloseHandle(hProcess);
|
|
||||||
Kernel32.CloseHandle(hPToken);
|
|
||||||
Kernel32.CloseHandle(hUserTokenDup);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetMonitorState(MonitorState state)
|
|
||||||
{
|
|
||||||
SendMessage(0xFFFF, 0x112, 0xF170, (int)state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MessageBoxResult ShowMessageBox(nint owner, string message, string caption, MessageBoxType messageBoxType)
|
|
||||||
{
|
|
||||||
return (MessageBoxResult)MessageBox(owner, message, caption, (long)messageBoxType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool SwitchToInputDesktop()
|
public static bool SwitchToInputDesktop()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -264,23 +138,93 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetConsoleWindowVisibility(bool isVisible)
|
|
||||||
{
|
|
||||||
var handle = Kernel32.GetConsoleWindow();
|
|
||||||
|
|
||||||
if (isVisible)
|
private static uint GetWinLogonPid(uint dwSessionId)
|
||||||
{
|
{
|
||||||
ShowWindow(handle, (int)SW.SW_SHOW);
|
uint winlogonPid = 0;
|
||||||
|
Process[] processes = Process.GetProcessesByName("winlogon");
|
||||||
|
foreach (Process p in processes)
|
||||||
|
{
|
||||||
|
if ((uint)p.SessionId == dwSessionId)
|
||||||
|
{
|
||||||
|
winlogonPid = (uint)p.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return winlogonPid;
|
||||||
|
}
|
||||||
|
private static uint GetDwSessionId(int targetSessionId, bool forceConsoleSession)
|
||||||
|
{
|
||||||
|
uint dwSessionId = Kernel32.WTSGetActiveConsoleSessionId();
|
||||||
|
if (forceConsoleSession == false)
|
||||||
|
{
|
||||||
|
List<WindowsSession> activeSessions = GetActiveSessions();
|
||||||
|
if (activeSessions.Any(x => x.Id == targetSessionId))
|
||||||
|
{
|
||||||
|
dwSessionId = (uint)targetSessionId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShowWindow(handle, (int)SW.SW_HIDE);
|
dwSessionId = activeSessions.Last().Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dwSessionId;
|
||||||
|
}
|
||||||
|
private static STARTUPINFO GetStartUpInfo(bool hiddenWindow, string desktopName, out uint dwCreationFlags)
|
||||||
|
{
|
||||||
|
STARTUPINFO si = new STARTUPINFO();
|
||||||
|
si.cb = Marshal.SizeOf(si);
|
||||||
|
si.lpDesktop = @"winsta0\" + desktopName;
|
||||||
|
if (hiddenWindow)
|
||||||
|
{
|
||||||
|
dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW;
|
||||||
|
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
|
si.wShowWindow = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE;
|
||||||
|
}
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
public static bool CreateInteractiveSystemProcess(string commandLine, int targetSessionId, bool forceConsoleSession, string desktopName, bool hiddenWindow, out PROCESS_INFORMATION procInfo)
|
||||||
|
{
|
||||||
|
nint hPToken = nint.Zero;
|
||||||
|
procInfo = new PROCESS_INFORMATION();
|
||||||
|
|
||||||
|
uint dwSessionId = GetDwSessionId(targetSessionId, forceConsoleSession);
|
||||||
|
uint winlogonPid = GetWinLogonPid(dwSessionId);
|
||||||
|
|
||||||
|
nint hProcess = Kernel32.OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
|
||||||
|
if (OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken) == false)
|
||||||
|
{
|
||||||
|
Kernel32.CloseHandle(hProcess);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel32.CloseHandle(handle);
|
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
|
||||||
|
sa.Length = Marshal.SizeOf(sa);
|
||||||
|
if (DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out nint hUserTokenDup) == false)
|
||||||
|
{
|
||||||
|
Kernel32.CloseHandle(hProcess);
|
||||||
|
Kernel32.CloseHandle(hPToken);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STARTUPINFO si = GetStartUpInfo(hiddenWindow, desktopName, out uint dwCreationFlags);
|
||||||
|
bool result = CreateProcessAsUser(hUserTokenDup, null, commandLine, ref sa, ref sa, false, dwCreationFlags, nint.Zero, null, ref si, out procInfo);
|
||||||
|
|
||||||
|
Kernel32.CloseHandle(hProcess);
|
||||||
|
Kernel32.CloseHandle(hPToken);
|
||||||
|
Kernel32.CloseHandle(hUserTokenDup);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetCommandLine()
|
||||||
|
{
|
||||||
|
nint commandLinePtr = Kernel32.GetCommandLine();
|
||||||
|
return Marshal.PtrToStringAuto(commandLinePtr) ?? string.Empty;
|
||||||
|
}
|
||||||
public static void RelaunchElevated()
|
public static void RelaunchElevated()
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsWindows() == false) return;
|
if (OperatingSystem.IsWindows() == false) return;
|
||||||
@@ -294,8 +238,8 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string commandLine = Win32Interop.GetCommandLine();
|
string commandLine = GetCommandLine();
|
||||||
bool result = Win32Interop.CreateInteractiveSystemProcess($"{commandLine} --elevated", -1, false, "default", true, out PROCESS_INFORMATION procInfo);
|
bool result = CreateInteractiveSystemProcess($"{commandLine} --elevated", -1, false, "default", true, out PROCESS_INFORMATION procInfo);
|
||||||
uint code = Kernel32.GetLastError();
|
uint code = Kernel32.GetLastError();
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
@@ -306,7 +250,6 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddTokenPrivilege()
|
public static void AddTokenPrivilege()
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
||||||
@@ -316,7 +259,6 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
$"ntrights +r SeAssignPrimaryTokenPrivilege -u {windowsIdentity.Name}"
|
$"ntrights +r SeAssignPrimaryTokenPrivilege -u {windowsIdentity.Name}"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -347,13 +289,13 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
int returnLength;
|
int returnLength;
|
||||||
if (GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, 0, out returnLength) || returnLength == 0)
|
if (GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, 0, out returnLength) || returnLength == 0)
|
||||||
{
|
{
|
||||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenInformation = Marshal.AllocHGlobal(returnLength);
|
tokenInformation = Marshal.AllocHGlobal(returnLength);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, tokenInformation, returnLength, out returnLength))
|
if (GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, tokenInformation, returnLength, out returnLength) == false)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,14 +69,14 @@ public static class WTSAPI32
|
|||||||
[DllImport("wtsapi32.dll", SetLastError = true)]
|
[DllImport("wtsapi32.dll", SetLastError = true)]
|
||||||
static extern nint WTSOpenServer(string pServerName);
|
static extern nint WTSOpenServer(string pServerName);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct WTS_SESSION_INFO
|
public struct WTS_SESSION_INFO
|
||||||
{
|
{
|
||||||
public uint SessionID;
|
public uint SessionID;
|
||||||
[MarshalAs(UnmanagedType.LPStr)]
|
[MarshalAs(UnmanagedType.LPStr)]
|
||||||
public string pWinStationName;
|
public string pWinStationName;
|
||||||
public WTS_CONNECTSTATE_CLASS State;
|
public WTS_CONNECTSTATE_CLASS State;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("Wtsapi32.dll")]
|
[DllImport("Wtsapi32.dll")]
|
||||||
public static extern bool WTSQueryUserToken(int sessionId, out IntPtr token);
|
public static extern bool WTSQueryUserToken(int sessionId, out IntPtr token);
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=0"><link rel="icon" href="/favicon.ico"><title>cmonitor.web</title><script defer="defer" src="/js/chunk-vendors.93db0d1d.js"></script><script defer="defer" src="/js/app.6eec6bd6.js"></script><link href="/css/chunk-vendors.faad7142.css" rel="stylesheet"><link href="/css/app.9c6b579f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but cmonitor.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=0"><link rel="icon" href="/favicon.ico"><title>cmonitor.web</title><script defer="defer" src="/js/chunk-vendors.93db0d1d.js"></script><script defer="defer" src="/js/app.3d096398.js"></script><link href="/css/chunk-vendors.faad7142.css" rel="stylesheet"><link href="/css/app.9c6b579f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but cmonitor.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||||
File diff suppressed because one or more lines are too long
1
cmonitor/web/js/492.e527bc9a.js
Normal file
1
cmonitor/web/js/492.e527bc9a.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user