OS/2, eCS & ArcaOS - Technical > Programming

Observing if a program uses vio calls

(1/9) > >>

Martin Vieregg:
In the german forum os2.org I started a thread with a problem for my PM commandline frontend, which only supports stdin and stdout, but no VIO calls. If a program writes directly into the screen buffer, my PM window does not show it. So the user has to switch between VIO and PM stdout window - I have got a button in my PM window doing that. It would be useful if the program recognizes automatically if a program which is executed via cmd.exe writes VIO output, so the VIO window could get visible automatically.

My first idea was to analyse the EXE binary and search the string VIOCALLS. In the thread, I was told that there is a better way. The program exehdr.exe from the OS/2 2.45 Toolkit in combination with the following rexx script

--- Code: ---/* analyse executable import viocalls */
parse upper arg efn SuperfluousArguments
if (efn == '') then return

ifn = 'exehdr.txt'

'@e:\os2ddk\base32\tools\os2.386\bin\exehdr /v 'efn' > 'ifn

needle = ' imp '
do while lines(ifn) <> 0
  haystack = linein(ifn)
  there = pos(needle,haystack)
  if (there > 0) then do
    line = substr(haystack,there+length(needle))
    if (left(line,8)=='VIOCALLS') then say line
    end
  end

return

--- End code ---

shows not only the fact that a program uses VIO calls, it shows also the number. The list of VIO calls is here:

--- Code: ---VIOENDPOPUP             VIOCALLS   1
VIO16ENDPOPUP           VIOCALLS   1
VIOGETPHYSBUF           VIOCALLS   2
VIO16GETPHYSBUF         VIOCALLS   2
VIOGETANSI              VIOCALLS   3
VIO16GETANSI            VIOCALLS   3
VIOSETANSI              VIOCALLS   5
VIO16SETANSI            VIOCALLS   5
VIODEREGISTER           VIOCALLS   6
VIO16DEREGISTER         VIOCALLS   6
VIOSCROLLUP             VIOCALLS   7
VIO16SCROLLUP           VIOCALLS   7
VIOPRTSC                VIOCALLS   8
VIO16PRTSC              VIOCALLS   8
VIOGETCURPOS            VIOCALLS   9
VIO16GETCURPOS          VIOCALLS   9
VIOWRTCELLSTR           VIOCALLS  10
VIO16WRTCELLSTR         VIOCALLS  10
VIOPOPUP                VIOCALLS  11
VIO16POPUP              VIOCALLS  11
VIOSCROLLRT             VIOCALLS  12
VIO16SCROLLRT           VIOCALLS  12
VIOWRTCHARSTR           VIOCALLS  13
VIO16WRTCHARSTR         VIOCALLS  13
VIOSETCURPOS            VIOCALLS  15
VIO16SETCURPOS          VIOCALLS  15
VIOSCRUNLOCK            VIOCALLS  18
VIO16SCRUNLOCK          VIOCALLS  18
VIOWRTTTY               VIOCALLS  19
VIO16WRTTTY             VIOCALLS  19
VIOGETMODE              VIOCALLS  21
VIO16GETMODE            VIOCALLS  21
VIOSETMODE              VIOCALLS  22
VIO16SETMODE            VIOCALLS  22
VIOSCRLOCK              VIOCALLS  23
VIO16SCRLOCK            VIOCALLS  23
VIOREADCELLSTR          VIOCALLS  24
VIO16READCELLSTR        VIOCALLS  24
VIOSAVREDRAWWAIT        VIOCALLS  25
VIO16SAVREDRAWWAIT      VIOCALLS  25
VIOWRTNATTR             VIOCALLS  26
VIO16WRTNATTR           VIOCALLS  26
VIOGETCURTYPE           VIOCALLS  27
VIO16GETCURTYPE         VIOCALLS  27
VIOSAVREDRAWUNDO        VIOCALLS  28
VIO16SAVREDRAWUNDO      VIOCALLS  28
VIOGETFONT              VIOCALLS  29
VIO16GETFONT            VIOCALLS  29
VIOREADCHARSTR          VIOCALLS  30
VIO16READCHARSTR        VIOCALLS  30
VIOGETBUF               VIOCALLS  31
VIO16GETBUF             VIOCALLS  31
VIOSETCURTYPE           VIOCALLS  32
VIO16SETCURTYPE         VIOCALLS  32
VIOSETFONT              VIOCALLS  33
VIO16SETFONT            VIOCALLS  33
VIOMODEUNDO             VIOCALLS  35
VIO16MODEUNDO           VIOCALLS  35
VIOMODEWAIT             VIOCALLS  37
VIO16MODEWAIT           VIOCALLS  37
VIOGETCP                VIOCALLS  40
VIO16GETCP              VIOCALLS  40
VIOSETCP                VIOCALLS  42
VIO16SETCP              VIOCALLS  42
VIOSHOWBUF              VIOCALLS  43
VIO16SHOWBUF            VIOCALLS  43
VIOSCROLLLF             VIOCALLS  44
VIO16SCROLLLF           VIOCALLS  44
VIOREGISTER             VIOCALLS  45
VIO16REGISTER           VIOCALLS  45
VIOGETCONFIG            VIOCALLS  46
VIO16GETCONFIG          VIOCALLS  46
VIOSCROLLDN             VIOCALLS  47
VIO16SCROLLDN           VIOCALLS  47
VIOWRTCHARSTRATT        VIOCALLS  48
VIO16WRTCHARSTRATT      VIOCALLS  48
VIOGETSTATE             VIOCALLS  49
VIO16GETSTATE           VIOCALLS  49
VIOPRTSCTOGGLE          VIOCALLS  50
VIO16PRTSCTOGGLE        VIOCALLS  50
VIOSETSTATE             VIOCALLS  51
VIO16SETSTATE           VIOCALLS  51
VIOWRTNCELL             VIOCALLS  52
VIO16WRTNCELL           VIOCALLS  52
VIOWRTNCHAR             VIOCALLS  53
VIO16WRTNCHAR           VIOCALLS  53
VIOASSOCIATE            VIOCALLS  55
VIO16ASSOCIATE          VIOCALLS  55
VIOCREATEPS             VIOCALLS  56
VIO16CREATEPS           VIOCALLS  56
VIODELETESETID          VIOCALLS  57
VIO16DELETESETID        VIOCALLS  57
VIOGETDEVICECELLSIZE    VIOCALLS  58
VIO16GETDEVICECELLSIZE  VIOCALLS  58
VIOGETORG               VIOCALLS  59
VIO16GETORG             VIOCALLS  59
VIOCREATELOGFONT        VIOCALLS  60
VIO16CREATELOGFONT      VIOCALLS  60
VIODESTROYPS            VIOCALLS  61
VIO16DESTROYPS          VIOCALLS  61
VIOQUERYSETIDS          VIOCALLS  62
VIO16QUERYSETIDS        VIOCALLS  62
VIOSETORG               VIOCALLS  63
VIO16SETORG             VIOCALLS  63
VIOQUERYFONTS           VIOCALLS  64
VIO16QUERYFONTS         VIOCALLS  64
VIOSETDEVICECELLSIZE    VIOCALLS  65
VIO16SETDEVICECELLSIZE  VIOCALLS  65
VIOSHOWPS               VIOCALLS  66
VIO16SHOWPS             VIOCALLS  66
VIOGETPSADDRESS         VIOCALLS  67
VIO16GETPSADDRESS       VIOCALLS  67
VIOGLOBALREG            VIOCALLS  70
VIO16GLOBALREG          VIOCALLS  70
XVIOSETCASTATE          VIOCALLS  71
XVIO16SETCASTATE        VIOCALLS  71
XVIOCHECKCHARTYPE       VIOCALLS  72
XVIO16CHECKCHARTYPE     VIOCALLS  72
XVIODESTROYCA           VIOCALLS  73
XVIO16DESTROYCA         VIOCALLS  73
XVIOCREATECA            VIOCALLS  74
XVIO16CREATECA          VIOCALLS  74
VIOCHECKCHARTYPE        VIOCALLS  75
VIO16CHECKCHARTYPE      VIOCALLS  75
XVIOGETCASTATE          VIOCALLS  76
XVIO16GETCASTATE        VIOCALLS  76

--- End code ---

But this solution anlyses only the program code and I do not know if the API calls are really exeuted. For example, XCOPY uses VIO calls, but only in very special circumstances I have not found out yet.

There is a program os2trace  which excatly makes the job I need: Observing an application and journaling which API calls it calls.

The perfect solution would be if my PM program observes the EXE file which is executed via cmd.exe in the known session which is controlled by my program like os2trace does. Is the author Dave Blaschke still acitive? Perhaps he or someone can explain or help me with the code I need. I would need a simple C or Pascal commandline program which observes a specific binary and gets an output "VIOCALL used!" if a VIOcall is sent. Then I could copy these lines into my PM program in an own thread.

Laurence Pithie:
Looking at the documentaion for os2trace I found this.

--- Quote ---The  first  feat,   trace  enabling,   is  accomplished  by
                 processing  each  entry in  the table of strings within the
                 executable  file that  contains the  names of  the imported
                 DLLs.  If the entry  represents one  of the  supported OS/2
                 DLLs and the  user requested  enablement of API tracing for
                 this  DLL,  the  entry is  replaced  with the  name  of the
                 appropriate  trace  DLL.   
--- End quote ---


--- Quote ---   NOTE:  Trace enablement alters the contents of the table of
                 strings within the executable file  that contains the names
                 of the imported DLLs.  Although this action does not affect
                 the  functionality of  the executable,  it does  affect its
                 date and time stamp unless the -P option is specified.

--- End quote ---

This behaviour is fine if I'm debugging something, it's not something I'd expect an application, particularly a text editor, to be doing behind my back. It'll also give an antivirus program conniptions. If all you want is to check if an arbitrary application uses only vio calls for output then what you are trying to detect is
a) Is there any output on stdio (some programs use overlaying of vio and standard i/o in which case you don't care about vio)
b) If there is no output on stdio has the program written to the screen using vio calls
in case b if the program has written to the screen using vio calls the cursor will have moved.

So, something along these lines would give you the behaviour you want.
1 Get current cursor position (VioGetCurPos) and save it
2 Write command to pipe
3 Check for output on stdout, if there is you're done
4 If there isn't check the cursor position and compare it to the original, if it's different pop up the vio window, otherwise there was no output.

You can, and indeed you should, check for the case where there's no output on stdout but there is on stderr and take apropriate action(popping up the vio window at a minimum). While it's possible that an application might use vio calls exclusively for error output rather than writing to stderr I've never seen it, nor can I think of a case where it would be sensible.

Martin Vieregg:
Laurence,

yes, that idea is very useful for my purpose ! VioGetCurPos requires a VIO handle. I have got a window handle and a session ID. How can I get the VIO handle?

Laurence Pithie:

--- Quote ---VioHandle (HVIO) - input
Presentation-space handle.

This must be zero, unless the caller is a Presentation Manager application; in this case, it must be the value returned by VioCreatePS

--- End quote ---
Your helper application isn't a presentation manager application, so the VioHandle should be zero.

Martin Vieregg:

--- Quote ---Your helper application isn't a presentation manager application, so the VioHandle should be zero.
--- End quote ---

Ah, yes, the helper application! Then I can simply use semaphores again. So I see three ways for doing the job:

(1) I create a thread in the helper program which always queries VioGetCurPos (e.g. 4 times every second, with a DosSleep in the loop) and observes the changes of the cursor position. If a change has been observed, it sends a message via semaphores to the PM application.

(2) The timer (not an additional thread) is in the PM application and it sends a query to the helper via semaphores. This query is only sent if some conditions are true
(a) a command is running (not prompt state)
(b) the application uses VIO calls
(c) no output is received for e.g. 1/4 or 1/2 seconds.
I think it won't be necessary to check all conditions. The helper remembers the last query and compares it with the new query. The helper sends the result back to the PM application via semaphores.

(3) In the case of the possibility that the PM helper can query directly the VIO handle (from "outside"), I would prefer the short way without helper app because it is easier to program.

But anyway, it seems that a clean solution will be definitely possible! What solution would be preferable in your opinion? Option (2) has different possibilities. So we have to discuss (b) if a VIO call analyzation of the binary is still necessary or can be resigned, because the curorpos query via helper needs less processor power.  Also condition (c) is to discuss. If a program generates both VIO output and stdout, it would be better to show both windows? It can happen that an application creates very fast some lines of VIO output and ends again. Perhaps some user settings would be helpful.

Navigation

[0] Message Index

[#] Next page

Go to full version