unit PlugInServ;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, ActiveX, Classes, ComObj, SysUtils, Math,
  CM2AutoUpdateInterface, CM2EditorSupportInterface, CM2GenInterface,
  Filter, MBM5Shared;

type
  TCM2GENMBM = class(TComObject, ICM2GENPLUG, ICM2AutoUpdate, ICM2EditorSupport10)
  private
    LastErrorMsg: Pchar;
    ConvertToF: Boolean;
    Decimal: Integer;
    Procedure Parser(Param: String);
  public
   // Declare Basics
    Function Name(OUT Name: Pchar): HResult; stdcall;
    Function Version(OUT Version: word): HResult; stdcall;
    Function RequiredCoreVersion(OUT RCV: Word): HResult; stdcall;
    Function SetParentHandle(Handle: THandle): HResult; stdcall;
   // Declare Error commands
    Function GetLastErrorMsg(OUT Msg: PChar): HResult; stdcall;
   // Declare Info system
    Function GetInfoCount(OUT InfoCount: Integer): HResult; stdcall;
    Function GetInfo(Index: Integer; OUT InfoName: PChar; OUT InfoVar: PChar): HResult; stdcall;
   // Declare Sensor system
    Function GetSensorCount(OUT SensorCount: Integer): HResult; stdcall;
    Function GetSensorNameOnly(Index: Integer; OUT SensorName: PChar; OUT SensorStyle: Byte): HResult; stdcall;
    Function GetSensor(Index: Integer; Parameters: PChar; OUT SensorName: PChar; OUT SensorStyle: byte; OUT SensorString: PChar; OUT SensorValue: Double): HResult; stdcall;
   // Declare "Event" functions
    Function Init: HResult; stdcall;
    Function Terminating: HResult; stdcall;
    Function Setup: HResult; stdcall;
  // Declare Support types
   // Default (Required)
    Function GetDefaultCount(SensorIndex: Integer; OUT DefaultCount: Integer): HResult; stdcall;
    Function GetDefault(SensorIndex: Integer; Index: Integer; OUT Name: Pchar; OUT Value: PChar; OUT Description: PChar): HResult; stdcall;
   // Optional
    Function GetOptionalCount(SensorIndex: Integer; OUT OptionalCount: Integer): HResult; stdcall;
    Function GetOptional(SensorIndex: Integer; Index: Integer; OUT Name: Pchar; OUT Value: PChar; OUT Description: PChar): HResult; stdcall;
   // Auto Update
    Function UpdateFileURL(OUT URL: Pchar): HResult; stdcall;
   // Editor support
    Function ShowSensor(Index: Integer; OUT ShowAt: Byte): HResult; stdcall;
    Function ObjIns(SensorIndex: Integer; ParameterName: PChar; OUT ValueType: Byte; OUT ValueRange: PChar): HResult; stdcall;
  end;

const
  Class_CM2GENMBM: TGUID = '{65D6F480-001E-4BD9-A2C7-C4C3BA6BD9B5}';
  AutoUpdateFile = 'http://www.coolmon.org/update/mbm.upd';
  ReqCoreVersion = 0470;
  PluginVersion = 0500;

implementation

uses ComServ;

{ --- ACTUAL PLUGIN CODE --- }

function TCM2GENMBM.Name(out Name: Pchar): HResult;
begin
  Result := S_OK;
  Name := 'MBM5';
end;

function TCM2GENMBM.Version(out Version: word): HResult;
begin
  Result := S_OK;
  Version := PluginVersion;
end;

function TCM2GENMBM.RequiredCoreVersion(out RCV: Word): HResult;
begin
  Result := S_OK;
  RCV := ReqCoreVersion;
end;

function TCM2GENMBM.SetParentHandle(Handle: THandle): HResult;
begin
 result := S_OK;
end;

function TCM2GENMBM.GetLastErrorMsg(OUT Msg: PChar): HResult;
begin
  Result := S_OK;
  if LastErrorMsg = '' then Msg := 'No error'
    else Msg := LastErrorMsg;
end;

function TCM2GENMBM.GetInfoCount(out InfoCount: Integer): HResult;
begin
  Result := S_OK;
  InfoCount := 5;
end;

function TCM2GENMBM.GetInfo(Index: Integer; out InfoName, InfoVar: PChar): HResult;
begin
  Result := S_OK;
  case Index of
    0: begin
         InfoName := 'Programmed By';
         InfoVar := 'C. Aaangel & Blert';
       end;
    1: begin
         InfoName := 'Created';
         InfoVar := 'Sep, 18 2003';
       end;
    2: begin
         InfoName := 'Requires';
         InfoVar := 'MBM 5.3.0.0 or higher';
       end;
    3: begin
         InfoName := 'Updated';
         InfoVar := 'September 19th 2004';
       end;
    4: begin
         InfoName := 'Copyright';
         InfoVar := '(c) 2003 - 2004, The CoolMon Project';
       end;
    else Result := E_FAIL;
  end;
end;

function TCM2GENMBM.GetSensorCount(out SensorCount: Integer): HResult;
begin
  Result := S_OK;
  SensorCount := NumberOfSensors;
  if SensorCount = -1 then
    begin
      Result := E_FAIL;
      LastErrorMsg := 'GetSensorCount: Count failure';
    end;
end;

function TCM2GENMBM.GetSensorNameOnly(Index: Integer; out SensorName: PChar;
  out SensorStyle: byte): HResult;
var
  NSS: TNewSharedSensor;
  WS: WideString;
  S: string;
begin
  Result := S_OK;
  if (Index >= 0) and (Index < NumberOfSensors) then
    begin
      NSS := ReadSharedSensor(Index);
      WS := NSS.ssName;
      S := WS;
      SensorName := PChar(S);
      SensorStyle := 0;
    end
  else
    begin
      Result := E_FAIL;
      LastErrorMsg := 'GetSensorNameOnly: Index out of bounds';
    end;
end;

function TCM2GENMBM.GetSensor(Index: Integer; Parameters: PChar;
  out SensorName: PChar; out SensorStyle: Byte; out SensorString: PChar;
  out SensorValue: Double): HResult;
var
  NSS: TNewSharedSensor;
  WS: WideString;
  S: string;
begin
  Result := S_OK;
  ConvertToF := False;
  Decimal := -1;
  Parser(Parameters);
  if (Index < 0) or (Index >= NumberOfSensors) then
    begin
      Result := E_FAIL;
      LastErrorMsg := 'GetSensor: Index out of bounds';
      exit;
    end;
  NSS := ReadSharedSensor(Index);
  WS := NSS.ssName;
  S := WS;
  SensorName := PChar(S);
  SensorStyle := 0;
  SensorValue := NSS.ssCurrent;
  if ConvertToF then SensorValue := (SensorValue * 1.8) + 32;
  if Decimal > -1 then SensorValue := SimpleRoundTo(SensorValue, (Decimal * (-1)));
end;

function TCM2GENMBM.Init: HResult;
var
  hndl: cardinal;
begin
  result := S_OK;
  hndl := OpenFileMapping(FILE_MAP_READ, False, '$M$B$M$5$S$D$');
  if hndl = 0 then LoadStarter
    else CloseHandle(hndl);
end;

function TCM2GENMBM.Terminating: HResult;
begin
  Result := S_OK;
  { If you unload the starter all Hell will break loose.
    It will unload automatically at termination if necessary. }
  //UnloadStarter;
end;

function TCM2GENMBM.Setup: HResult;
begin
  result := E_NOTIMPL;
end;

function TCM2GENMBM.GetDefaultCount(SensorIndex: Integer;
  out DefaultCount: Integer): HResult;
begin
  Result := S_OK;
  DefaultCount := 0;
end;

function TCM2GENMBM.GetDefault(SensorIndex, Index: Integer; out Name,
  Value, Description: PChar): HResult;
begin
  Result := S_OK;
end;

function TCM2GENMBM.GetOptionalCount(SensorIndex: Integer;
  out OptionalCount: Integer): HResult;
begin
  Result := S_OK;
  OptionalCount := 2;
end;

function TCM2GENMBM.GetOptional(SensorIndex, Index: Integer; out Name,
  Value, Description: PChar): HResult;
begin
  Result := S_OK;
  case Index of
    0: begin
         Name := 'Decimals';
         Value := '2';
         Description := pchar('Cut down the amount of decimals to #');
       end;
    1: begin
         Name := 'Output';
         Value := 'C';
         Description := pchar('Use "F" or "C", if "F" it will convert to Fahrenheit');
       end;
  end;
end;

function TCM2GENMBM.UpdateFileURL(out URL: Pchar): HResult;
begin
  Result := S_OK;
  URL := PChar(AutoUpdateFile);
end;

Function TCM2GENMBM.ShowSensor(Index: Integer; OUT ShowAt: Byte): HResult; stdcall;
begin
  Result := S_OK;
end;

Function TCM2GENMBM.ObjIns(SensorIndex: Integer; ParameterName: PChar; OUT ValueType: Byte; OUT ValueRange: PChar): HResult; stdcall;
begin
  Result := S_OK;
end;

procedure TCM2GENMBM.Parser(Param: String);
Var
  I: Integer;
  S, N, V: String;
begin
  for I := 0 to Countfilt(Param, '|') do
    begin
      S := GetFilt(Param, I, '|');
      N := Uppercase(GetFilt(S, 1, '='));
      V := GetFilt(S, 2, '=');
      if (N = 'DECIMAL') or (N = 'DECIMALS') then
        begin
          try
            Decimal := StrToInt(V);
          except
          end;
        end;
      if (N = 'OUTPUT') then
        begin
          V := Uppercase(V);
          if (V = 'CELCIUS') or (V = 'C') then ConvertToF := False;
          if (V = 'FAHRENHEIT') or (V = 'F') then ConvertToF := True;
        end;
    end;
end;

initialization
  TComObjectFactory.Create(ComServer, TCM2GENMBM, Class_CM2GENMBM,
    'CM2GENMBM', 'CoolMon 2 General PlugIn - Motherboard Monitor', ciMultiInstance, tmApartment);
end.
