Reputation: 35
an Ada application which will write in to windows event logs? i have tried to use system call in Ada but its not working this is main.adb
with System;
with Interfaces.C;
use Interfaces.C;
with Ada.Text_IO;
use Ada.Text_IO;
with Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;
with c_interface;
use c_interface;
with Interfaces.C.Strings;
use Interfaces.C.Strings;
with Ada.Strings.Unbounded;
use Ada.Strings.Unbounded;
with Ada.Strings.Unbounded.Text_IO;
use Ada.Strings.Unbounded.Text_IO;
procedure main is
begin
System_even("error",888,"Demo","this is serious");
--Put_Line("hello");
delay 2.0;
end main;
and it's using package c_interface.ads
with Interfaces.C;
use Interfaces.C;
with Interfaces.C.Strings;
use Interfaces.C.Strings;
package c_interface is use Interfaces;
procedure System_even (EventCreate : String;
ID : Integer;
Application : String;
Source : String);
private
pragma Import (C, System_even,"system");
end c_interface;
Upvotes: 0
Views: 176
Reputation: 3641
Jacob already covered the discussion, but I ended up generating a quick binding on top of the system call. I was able to generate application events in Windows 10 using GPS to compile and run it:
Windows_Event_Log.ads
package Windows_Event_Log is
type Event_Type is
(Error,
Warning,
Information,
Success_Audit,
Failure_Audit);
type Event_Category is
(Application,
System);
-- Calls command
procedure Event_Create
(Type_Of_Event : Event_Type;
ID : Positive;
Category : Event_Category;
Source : String;
Message : String);
-- For Debug
function Make_Event_String
(Type_Of_Event : Event_Type;
ID : Positive;
Category : Event_Category;
Source : String;
Message : String)
return String;
end Windows_Event_Log;
Windows_Event_Log.adb
with Interfaces.C.Strings;
with Ada.Characters.Latin_1;
with Ada.Containers.Indefinite_Holders;
package body Windows_Event_Log is
package String_Holders is new Ada.Containers.Indefinite_Holders(String);
-- Conversion arrays
Type_String : constant array(Event_Type) of String_Holders.Holder :=
(Error => String_Holders.To_Holder("ERROR"),
Warning => String_Holders.To_Holder("WARNING"),
Information => String_Holders.To_Holder("INFORMATION"),
Success_Audit => String_Holders.To_Holder("SUCCESSAUDIT"),
Failure_Audit => String_Holders.To_Holder("FAILUREAUDIT"));
Category_String : constant array(Event_Category) of String_Holders.Holder :=
(Application => String_Holders.To_Holder("APPLICATION"),
System => String_Holders.To_Holder("SYSTEM"));
function Make_Event_String
(Type_Of_Event : Event_Type;
ID : Positive;
Category : Event_Category;
Source : String;
Message : String)
return String
is begin
return
"EventCreate /t "
& Type_String(Type_Of_Event).Element
& " /id "
& Positive'Image(ID)
& " /l "
& Category_String(Category).Element
& " /so "
& Source
& " /d """
& Message
& """ >nul 2>&1"; -- Suppress output and error
end Make_Event_String;
-- Thin binding to the system call
function System(Str : Interfaces.C.Strings.chars_ptr) return Interfaces.C.int
with
Import,
Convention => C,
External_Name => "system";
procedure Event_Create
(Type_Of_Event : Event_Type;
ID : Positive;
Category : Event_Category;
Source : String;
Message : String)
is
Event_String : String := Make_Event_String
(Type_Of_Event => Type_Of_Event,
ID => ID,
Category => Category,
Source => Source,
Message => Message)
& Ada.Characters.Latin_1.NUL; -- needed for C strings
Event_Chars_Ptr : Interfaces.C.Strings.chars_ptr :=
Interfaces.C.Strings.New_String(Event_String); --allocates memory
-- This line actually makes the system call
Result : Interfaces.C.int := System(Event_Chars_Ptr);
begin
-- Free the allocated memory from New_String
Interfaces.C.Strings.Free(Event_Chars_Ptr);
end;
end Windows_Event_Log;
main.adb
with Windows_Event_Log;
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
Event_Type : Windows_Event_Log.Event_Type := Windows_Event_Log.Warning;
ID : Positive := 458;
Category : Windows_Event_Log.Event_Category := Windows_Event_Log.Application;
Source : String := "SomeString";
Message : String := "This is another joke";
begin
-- Debug print
Put_Line
("Generated Command => "
& Windows_Event_Log.Make_Event_String
(Type_Of_Event => Event_Type,
ID => ID,
Category => Category,
Source => Source,
Message => Message));
-- Actual Command Sent
Windows_Event_Log.Event_Create
(Type_Of_Event => Event_Type,
ID => ID,
Category => Category,
Source => Source,
Message => Message);
end Main;
I only tested a few of the input cases, so it is far from fully tested, but I wanted to give you an example of making a quick binding for it. It was compiled and tested using GNAT GPL 2017 for windows
References
Rosetta Code Example in C for how to do it
Upvotes: 0
Reputation: 6611
I'm not a Microsoft expert, but on other operating systems system()
is usually declared as:
int system(const char *command);
That is in no way whatsoever the same as:
procedure System_even (EventCreate : String;
ID : Integer;
Application : String;
Source : String);
Change your import so the profiles match. - Or even better, use gcc -fdump-ada-spec
to have your compiler generate the correct Ada specification for you.
Upvotes: 2