c# - Capturing Logon event on local computer as a non-admin. Is there an api? -
as non-admin user, want detect event when user logs in. cannot use system event notification service (senslogon2) since requires user part of administrators group. there api or there permission/privileges can grant current user?
we need detect user logging on terminal via rdp can change application state current user in.
you can next steps info session changes:
- call wtsregistersessionnotification notify_for_all_sessions on form receive wm_wtssession_change message
- override void wndproc(ref message m) of form , filtering wm_wtssession_change (0x2b1)
- extract session id lparam , session state change event wparam
- call wtsquerysessioninformation session id username
here working example pinvoke. have form1 (winform) in project. is:
using system; using system.collections.generic; using system.componentmodel; using system.data; using system.diagnostics; using system.drawing; using system.linq; using system.text; using system.threading.tasks; using system.windows.forms; namespace messageloop { public partial class form1 : form { /// <summary> /// wm_wtssession_change message number filtering in wndproc /// </summary> private const int wm_wtssession_change = 0x2b1; public form1() { initializecomponent(); nativewrapper.wtsregistersessionnotification(this, sessionnotificationtype.notify_for_all_sessions); } protected override void onclosing(canceleventargs e) { nativewrapper.wtsunregistersessionnotification(this); base.onclosing(e); } protected override void wndproc(ref message m) { if (m.msg == wm_wtssession_change) { int eventtype = m.wparam.toint32(); int sessionid = m.lparam.toint32(); wtssessionchange reason = (wtssessionchange)eventtype; trace.writeline(string.format("sessionid: {0}, username: {1}, eventtype: {2}", sessionid, nativewrapper.getusernamebysessionid(sessionid), reason)); } base.wndproc(ref m); } } }
here nativewrapper.cs:
using system; using system.collections.generic; using system.componentmodel; using system.linq; using system.runtime.interopservices; using system.text; using system.threading.tasks; using system.windows.forms; namespace messageloop { public enum wtssessionchange { wts_console_connect = 1, wts_console_disconnect = 2, wts_remote_connect = 3, wts_remote_disconnect = 4, wts_session_logon = 5, wts_session_logoff = 6, wts_session_lock = 7, wts_session_unlock = 8, wts_session_remote_control = 9, wts_session_create = 0xa, wts_session_terminate = 0xb } public enum sessionnotificationtype { notify_for_this_session = 0, notify_for_all_sessions = 1 } public static class nativewrapper { public static void wtsregistersessionnotification(control control, sessionnotificationtype sessionnotificationtype) { if (!native.wtsregistersessionnotification(control.handle, (int)sessionnotificationtype)) throw new win32exception(marshal.getlastwin32error()); } public static void wtsunregistersessionnotification(control control) { if (!native.wtsunregistersessionnotification(control.handle)) throw new win32exception(marshal.getlastwin32error()); } public static string getusernamebysessionid(int sessionid) { intptr buffer; int strlen; var username = "system"; // assume system return "\0" below if (native.wtsquerysessioninformation(intptr.zero, sessionid, native.wts_info_class.wtsusername, out buffer, out strlen) && strlen > 1) { username = marshal.ptrtostringansi(buffer); // don't need length these null terminated strings native.wtsfreememory(buffer); if (native.wtsquerysessioninformation(intptr.zero, sessionid, native.wts_info_class.wtsdomainname, out buffer, out strlen) && strlen > 1) { username = marshal.ptrtostringansi(buffer) + "\\" + username; // prepend domain name native.wtsfreememory(buffer); } } return username; } } }
and last file native.cs
using system; using system.collections.generic; using system.linq; using system.runtime.interopservices; using system.text; using system.threading.tasks; namespace messageloop { public static class native { public enum wts_info_class { wtsinitialprogram, wtsapplicationname, wtsworkingdirectory, wtsoemid, wtssessionid, wtsusername, wtswinstationname, wtsdomainname, wtsconnectstate, wtsclientbuildnumber, wtsclientname, wtsclientdirectory, wtsclientproductid, wtsclienthardwareid, wtsclientaddress, wtsclientdisplay, wtsclientprotocoltype, wtsidletime, wtslogontime, wtsincomingbytes, wtsoutgoingbytes, wtsincomingframes, wtsoutgoingframes, wtsclientinfo, wtssessioninfo } [dllimport("wtsapi32.dll", setlasterror = true)] internal static extern bool wtsregistersessionnotification(intptr hwnd, [marshalas(unmanagedtype.u4)] int dwflags); [dllimport("wtsapi32.dll", setlasterror = true)] internal static extern bool wtsunregistersessionnotification(intptr hwnd); [dllimport("wtsapi32.dll")] internal static extern bool wtsquerysessioninformation(intptr hserver, int sessionid, wts_info_class wtsinfoclass, out intptr ppbuffer, out int pbytesreturned); [dllimport("wtsapi32.dll")] internal static extern void wtsfreememory(intptr pointer); } }
Comments
Post a Comment