unit rwhod1;
{ rwhod1 - mainunit of rwhodwin
RWhod for Windows
Version 0.30
Copyright (c) 2000 by Ward van Wanrooij <ward@ward.nu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
For more information regarding this license or this program
visit http://www.ward.nu/ or mailto:ward@ward.nu .
Do not remove the above message.
This unit requires TSock by Tom Bradford/Ward van Wanrooij (http://www.ward.nu/computer/tsock)
and antTaskbarIcon by Karpolan (http://karpolan.i.am) in order to compile
successfully.
}
interface
uses
WinTypes, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, IniFiles, ExtCtrls, Registry, WinSock, Menus,
antTaskbarIcon, Sock;
type
TAboutForm = class(TForm)
MyTimer: TTimer;
AboutLabel1: TLabel;
AboutLabel2: TLabel;
AboutLabel3: TLabel;
RWhodLogo: TImage;
TaskbarIcon: TantTaskbarIcon;
TaskbarMenu: TPopupMenu;
Broadcast1: TMenuItem;
N1: TMenuItem;
About1: TMenuItem;
Exit1: TMenuItem;
AboutLabel4: TLabel;
AboutLabel5: TLabel;
OK: TButton;
Socket: TSock;
procedure TransmitUptimeData(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure MyTimerTimer(Sender: TObject);
procedure OKClick(Sender: TObject);
procedure About1Click(Sender: TObject);
procedure Exit1Click(Sender: TObject);
end;
type
Toutmp = record
out_line: array[0..7] of char;
out_name: array[0..7] of char;
out_time: cardinal;
end;
Twhoent = record
we_utmp: Toutmp;
we_idle: cardinal;
end;
Twhod = record
wd_vers: char;
wd_type: char;
wd_fill: array[0..1] of char;
wd_sendtime: cardinal;
wd_recvtime: cardinal;
wd_hostname: array[0..31] of char;
wd_loadav: array[0..2] of cardinal;
wd_boottime: cardinal;
wd_we: array[0..41] of Twhoent;
end;
var
AboutForm: TAboutForm;
Whod: Twhod;
Whoent: Twhoent;
Outtmp: Toutmp;
MyRegistry: TRegistry;
CpuUsage: array[0..89] of array[0..3] of Char;
Subnetmask, Port: string;
NumberOfUsers: Integer;
implementation
{$R *.DFM}
procedure TAboutForm.TransmitUptimeData(Sender: TObject);
var
I, TempInt: Integer;
CurrentTime: Int64;
TimeZoneInfo: TTimeZoneInformation;
begin
// Original version:
// CurrentTime:=Trunc(((Double(Now)-Double(EncodeDate(1970,1,1)))*24*60+TimeZoneInfo.Bias)*60);
TempInt:=0;
for I:=0 to 4 do
TempInt:=TempInt+Integer(CpuUsage[I+85]);
Whod.wd_loadav[0]:=HToNL(Trunc(TempInt/5));
TempInt:=0;
for I:=0 to 29 do
TempInt:=TempInt+Integer(CpuUsage[I+60]);
Whod.wd_loadav[1]:=HToNL(Trunc(TempInt/30));
TempInt:=0;
for I:=0 to 89 do
TempInt:=TempInt+Integer(CpuUsage[I]);
Whod.wd_loadav[2]:=HToNL(Trunc(TempInt/90));
GetTimeZoneInformation(TimeZoneInfo);
CurrentTime:=Trunc(((Double(Now)-25569)*1440+TimeZoneInfo.Bias)*60);
Whod.wd_sendtime:=HToNL(CurrentTime);
Socket.HostName:=SubnetMask;
Socket.PortName:=Port;
Socket.Open;
Socket.Stream.Write(Whod, 60+NumberOfUsers*24);
Socket.Close;
end;
procedure TAboutForm.FormCreate(Sender: TObject);
var
I: Integer;
CurrentTime: Int64;
BootTime: Int64;
HostName: array[0..31] of Char;
TimeZoneInfo: TTimeZoneInformation;
begin
NumberOfUsers:=1;
GetTimeZoneInformation(TimeZoneInfo);
CurrentTime:=Trunc(((Double(Now)-25569)*1440+TimeZoneInfo.Bias)*60);
BootTime:=Trunc(CurrentTime-GetTickCount()/1000);
Whod.wd_boottime:=HToNL(BootTime);
Outtmp.out_time:=HToNL(BootTime);
for I:=0 to 31 do
HostName[I]:=Chr(0);
GetHostname(@HostName,32);
StrMove(Whod.wd_hostname,HostName,Length(HostName));
Outtmp.out_line:='pts/0';
Outtmp.out_name:='windows';
Whoent.we_utmp:=Outtmp;
Whoent.we_idle:=HToNL(3660); // 1 hour, 1 minute
Whod.wd_vers:=Chr(1); // who protocol version
Whod.wd_type:=Chr(1); // status: 1=up
Whod.wd_fill[0]:=Chr(0);
Whod.wd_fill[1]:=Chr(0);
Whod.wd_recvtime:=0;
Whod.wd_we[0]:=Whoent;
MyRegistry:=TRegistry.Create;
MyRegistry.RootKey:=HKEY_LOCAL_MACHINE;
try
MyRegistry.OpenKey('Software\Ward\rwhodwin',False);
Subnetmask:=MyRegistry.ReadString('Subnetmask');
Port:=MyRegistry.ReadString('Port');
except
Application.MessageBox('The configuration entries could not be found. For more information visit http://www.ward.nu/ .','Fatal error', MB_OK);
TaskbarIcon.Visible:=False;
MyRegistry.Free;
Application.ProcessMessages;
Halt;
end;
MyRegistry.CloseKey;
MyRegistry.RootKey:=HKEY_DYN_DATA;
MyRegistry.OpenKey('PerfStats\StartStat',False); // Why Microsoft, why? Why do we have to open a registrykey in order to trigger a VxD?
MyRegistry.ReadBinaryData('KERNEL\CPUUsage',CpuUsage[0],4); // CpuUsage serves as a temporary variable here.
MyRegistry.CloseKey;
MyRegistry.OpenKey('PerfStats\StatData',False);
for I:=0 to 89 do
MyRegistry.ReadBinaryData('KERNEL\CPUUsage',CpuUsage[I],4);
TransmitUptimeData(Self);
MyTimer.Enabled:=True;
end;
procedure TAboutForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
MyRegistry.CloseKey;
MyRegistry.OpenKey('PerfStats\StopStat',False); // Why #2
MyRegistry.ReadBinaryData('KERNEL\CPUUsage',CpuUsage[0],4);
MyRegistry<