ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSFinger/CCSFinger.cs
(Generate patch)

Comparing CCSFinger/CCSFinger.cs (file contents):
Revision 724 by douglas, 2006-03-30T21:33:30-08:00 vs.
Revision 725 by douglas, 2006-03-31T04:13:36-08:00

# Line 9 | Line 9 | using System.Collections.Generic;
9   using System.IO;
10   using System.Net;
11   using System.Net.Sockets;
12 + using System.Runtime.InteropServices;
13   using System.ServiceProcess;
14   using System.Text;
15   using System.Threading;
16  
17   public class CCSFinger : ServiceBase
18   {
19 <        private class Finger
19 >        public enum CurrentState : uint
20          {
21 <                private class Login
22 <                {
23 <                        private Net.USER_INFO_11 info;
24 <                        private uint id;
25 <                        private string session;
26 <                        private string client;
27 <                        private Wts.WTS_PROTOCOL_TYPE protocol;
28 <                        private Wts.WTS_CONNECTSTATE_CLASS status;
28 <                        private DateTime logon = DateTime.MinValue;
29 <
30 <                        public Login(string login)
31 <                        {
32 <                                Net.UserGetInfo(null, login, 11, out info);
33 <
34 <                                this.id = uint.MaxValue;
35 <                        }
36 <
37 <                        public Login(string login, uint id, string session, string client, Wts.WTS_PROTOCOL_TYPE protocol, Wts.WTS_CONNECTSTATE_CLASS status)
38 <                        {
39 <                                Net.UserGetInfo(null, login, 11, out info);
40 <
41 <                                this.id = id;
42 <                                this.session = session;
43 <                                this.client = client;
44 <                                this.protocol = protocol;
45 <                                this.status = status;
46 <                        }
47 <
48 <                        public string Client
49 <                        {
50 <                                get { return protocol == Wts.WTS_PROTOCOL_TYPE.WTS_PROTOCOL_TYPE_CONSOLE ? "the Console" : client; }
51 <                        }
52 <
53 <                        public string Directory
54 <                        {
55 <                                get { return @"\\Zweihander\" + info.usri11_name; }
56 <                        }
57 <
58 <                        public uint Id
59 <                        {
60 <                                get { return id; }
61 <                        }
62 <
63 <                        public DateTime LastLogon
64 <                        {
65 <                                get
66 <                                {
67 <                                        if (logon == DateTime.MinValue)
68 <                                                logon = new DateTime(1970, 1, 1) + new TimeSpan((long)info.usri11_last_logon * 10000000);
69 <
70 <                                        return logon;
71 <                                }
72 <                        }
73 <
74 <                        public string Name
75 <                        {
76 <                                get { return info.usri11_full_name; }
77 <                        }
78 <
79 <                        public string Session
80 <                        {
81 <                                get { return session; }
82 <                        }
83 <
84 <                        public string Status
85 <                        {
86 <                                get { return status.ToString().Substring(3); }
87 <                        }
88 <                }
89 <
90 <                private StreamWriter writer;
91 <                private SortedDictionary<string, List<Login>> logins = new SortedDictionary<string, List<Login>>();
92 <                private bool forward = false;
93 <                private List<string> nots = new List<string>();
94 <
95 <                private void Full()
96 <                {
97 <                        if (forward)
98 <                                writer.Write("finger: forwarding service denied\r\n");
99 <
100 <                        foreach (string not in nots)
101 <                                writer.Write("finger: {0}: no such user\r\n", not);
102 <
103 <                        bool first = true;
104 <
105 <                        foreach (KeyValuePair<string, List<Login>> login in logins)
106 <                        {
107 <                                if (first)
108 <                                        first = false;
109 <                                else
110 <                                        writer.Write("\r\n");
111 <
112 <                                writer.Write("Login: {0,-32} Name: {1}\r\nDirectory: {2}\r\n", login.Key, login.Value[0].Name, login.Value[0].Directory);
113 <
114 <                                foreach (Login login_ in login.Value)
115 <                                        if (login_.Id != uint.MaxValue)
116 <                                                writer.Write("{0} on {1}, from {2}\r\n", login_.Status, login_.Id, login_.Client);
117 <
118 <                                if (login.Value[0].LastLogon != new DateTime(1970, 1, 1))
119 <                                        writer.Write("Last login {0:ddd MMM dd HH:mm} ({1})\r\n", login.Value[0].LastLogon.ToLocalTime(), login.Value[0].LastLogon.ToLocalTime().IsDaylightSavingTime() ? "PDT" : "PST");
120 <                                else
121 <                                        writer.Write("Never logged in.\r\n");
21 >                SERVICE_STOPPED = 0x1,
22 >                SERVICE_START_PENDING = 0x2,
23 >                SERVICE_STOP_PENDING = 0x3,
24 >                SERVICE_RUNNING = 0x4,
25 >                SERVICE_CONTINUE_PENDING = 0x5,
26 >                SERVICE_PAUSE_PENDING = 0x6,
27 >                SERVICE_PAUSED = 0x7
28 >        }
29  
30 <                                writer.Write("No Mail.\r\n");
30 >        [StructLayout(LayoutKind.Sequential)]
31 >        public struct SERVICE_STATUS
32 >        {
33 >                public uint dwServiceType;
34 >                public CurrentState dwCurrentState;
35 >                public uint dwControlsAccepted;
36 >                public uint dwWin32ExitCode;
37 >                public uint dwServiceSpecificExitCode;
38 >                public uint dwCheckPoint;
39 >                public uint dwWaitHint;
40 >        }
41  
42 <                                string[] files = { ".project", ".plan" };
42 >        private Thread thread;
43  
44 <                                foreach (string file in files)
45 <                                        try
46 <                                        {
47 <                                                StreamReader reader = new StreamReader(new FileStream(Directory.GetFiles(login.Value[0].Directory, file)[0], FileMode.Open, FileAccess.Read));
131 <
132 <                                                switch (file)
133 <                                                {
134 <                                                        case ".project":
135 <                                                                writer.Write("Project:\r\n");
136 <                                                                break;
137 <                                                        case ".plan":
138 <                                                                writer.Write("Plan:\r\n");
139 <                                                                break;
140 <                                                }
141 <
142 <                                                writer.Write("{0}", reader.ReadToEnd());
143 <                                        }
144 <                                        catch (Exception)
145 <                                        {
146 <                                                if (file == ".plan")
147 <                                                        writer.Write("No Plan.\r\n");
148 <                                        }
149 <                        }
150 <                }
44 >        public CCSFinger()
45 >        {
46 >                ServiceName = "CCSFinger";
47 >        }
48  
49 <                private void Sessions(IDictionary<string, List<Login>> logins)
50 <                {
154 <                        Wts.WTS_SESSION_INFO[] sessions;
155 <                        uint count;
49 >        [DllImport("Advapi32.dll", EntryPoint = "SetServiceStatus")]
50 >        public static extern bool SetServiceStatus(IntPtr hServiceStatus, SERVICE_STATUS lpServiceStatus);
51  
52 <                        Wts.EnumerateSessions(IntPtr.Zero, 0, 1, out sessions, out count);
52 >        [DllImport("Advapi32.dll", EntryPoint = "QueryServiceStatus")]
53 >        public static extern bool QueryServiceStatus(IntPtr hService, out SERVICE_STATUS lpServiceStatus);
54  
55 <                        for (uint index = 0; index != count; ++index)
56 <                        {
57 <                                string name;
162 <                                uint size;
55 >        protected override void OnStart(string[] args)
56 >        {
57 >                SERVICE_STATUS status;
58  
59 <                                Wts.QuerySessionInformation(IntPtr.Zero, sessions[index].SessionId, Wts.WTS_INFO_CLASS.WTSUserName, out name, out size);
59 >                QueryServiceStatus(ServiceHandle, out status);
60  
61 <                                if (name.Length > 0)
167 <                                {
168 <                                        string session, client;
169 <                                        Wts.WTS_PROTOCOL_TYPE protocol;
170 <                                        Wts.WTS_CONNECTSTATE_CLASS status;
171 <
172 <                                        Wts.QuerySessionInformation(IntPtr.Zero, sessions[index].SessionId, Wts.WTS_INFO_CLASS.WTSWinStationName, out session, out size);
173 <                                        Wts.QuerySessionInformation(IntPtr.Zero, sessions[index].SessionId, Wts.WTS_INFO_CLASS.WTSClientName, out client, out size);
174 <                                        Wts.QuerySessionInformation(IntPtr.Zero, sessions[index].SessionId, Wts.WTS_INFO_CLASS.WTSClientProtocolType, out protocol, out size);
175 <                                        Wts.QuerySessionInformation(IntPtr.Zero, sessions[index].SessionId, Wts.WTS_INFO_CLASS.WTSConnectState, out status, out size);
61 >                status.dwCurrentState = CurrentState.SERVICE_START_PENDING;
62  
63 <                                        if (!logins.ContainsKey(name))
178 <                                                logins.Add(string.Copy(name), new List<Login>());
63 >                SetServiceStatus(ServiceHandle, status);
64  
65 <                                        logins[name].Add(new Login(name, sessions[index].SessionId, session, client, protocol, status));
181 <                                }
182 <                        }
183 <                }
65 >                thread = new Thread(new ThreadStart(Do));
66  
67 <                public Finger(StreamWriter writer, bool full)
186 <                {
187 <                        this.writer = writer;
67 >                thread.Start();
68  
69 <                        Sessions(logins);
69 >                ExitCode = 0;
70  
71 <                        if (logins.Count < 1)
192 <                                writer.Write("No one logged on.\r\n");
193 <                        else if (full)
194 <                                Full();
195 <                        else
196 <                        {
197 <                                writer.Write("Login           Name                 Id     Session       Status\r\n");
71 >                QueryServiceStatus(ServiceHandle, out status);
72  
73 <                                foreach (KeyValuePair<string, List<Login>> login_ in logins)
200 <                                        foreach (Login login in login_.Value)
201 <                                                writer.Write("{0,-15} {1,-20} {2,-6} {3,-13} {4}\r\n", login_.Key, login.Name.Length > 20 ? login.Name.Substring(0, 20) : login.Name, login.Id, login.Session, login.Status);
202 <                        }
203 <                }
73 >                status.dwCurrentState = CurrentState.SERVICE_RUNNING;
74  
75 <                public Finger(StreamWriter writer, ICollection<string> names)
76 <                {
207 <                        this.writer = writer;
75 >                SetServiceStatus(ServiceHandle, status);
76 >        }
77  
78 <                        uint count;
79 <                        Net.NET_DISPLAY_USER[] users;
78 >        protected override void OnStop()
79 >        {
80 >                SERVICE_STATUS status;
81  
82 <                        Net.QueryDisplayInformation(null, 1, 0, 100, uint.MaxValue, out count, out users);
82 >                QueryServiceStatus(ServiceHandle, out status);
83  
84 <                        Dictionary<string, List<Login>> logins_ = new Dictionary<string, List<Login>>();
84 >                status.dwCurrentState = CurrentState.SERVICE_STOP_PENDING;
85  
86 <                        Sessions(logins_);
86 >                thread.Abort();
87 >                thread.Join();
88  
89 <                        foreach (string name in names)
219 <                                if (name.Contains("@"))
220 <                                        forward = true;
221 <                                else
222 <                                {
223 <                                        bool not = true;
89 >                ExitCode = 0;
90  
91 <                                        for (uint index = 0; index != count; ++index)
226 <                                                if (users[index].usri1_name.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1 || users[index].usri1_full_name.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1)
227 <                                                        try
228 <                                                        {
229 <                                                                logins.Add(users[index].usri1_name, new List<Login>());
230 <
231 <                                                                logins[users[index].usri1_name].Add(new Login(users[index].usri1_name));
232 <
233 <                                                                if (logins_.ContainsKey(users[index].usri1_name))
234 <                                                                        logins[users[index].usri1_name].AddRange(logins_[users[index].usri1_name]);
235 <                                                        }
236 <                                                        catch (ArgumentException) {}
237 <                                                        finally
238 <                                                        {
239 <                                                                not = false;
240 <                                                        }
241 <
242 <                                        if (not)
243 <                                                nots.Add(name);
244 <                                }
91 >                QueryServiceStatus(ServiceHandle, out status);
92  
93 <                        Full();
247 <                }
93 >                status.dwCurrentState = CurrentState.SERVICE_STOPPED;
94          }
95  
96 <        private static void Do()
96 >        private void Do()
97          {
98                  TcpListener listener = null;
99  
# Line 272 | Line 118 | public class CCSFinger : ServiceBase
118                  {
119                          Console.Error.WriteLine(exception);
120                  }
121 +                catch (ThreadAbortException) {}
122                  finally
123                  {
124                          listener.Stop();
125                  }
126          }
127  
128 <        private static void Do(object socket_)
128 >        private void Do(object socket_)
129          {
130                  Socket socket = (Socket)socket_;
131                  NetworkStream stream = new NetworkStream(socket);
# Line 319 | Line 166 | public class CCSFinger : ServiceBase
166  
167          public static int Main(string[] args)
168          {
169 <                Do();
169 >                ServiceBase.Run(new ServiceBase[] { new CCSFinger() });
170  
171                  return 0;
172          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines