HP3000-L Archives

May 1996, Week 2

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Reply To:
Date:
Fri, 10 May 1996 13:35:45 GMT
Content-Type:
text/plain
Parts/Attachments:
text/plain (407 lines)
Stan Sieler ([log in to unmask]) wrote:
: Larry writes:
 
: NOTE:  No AIF:PE intercept of any IMAGE intrinsic will catch any calls
: from CM!!!!
 
: This is because CM IMAGE intrinsics switch to NM and call something
: *below* the DBUPDATE/DB... intrinsic (e.g., on the order of: nmdbupdate,
: which is the real worker for dbupdate.  THis linkage is somewhat
: hardwired, and difficult to intercept.  I did some research a year or
: two ago, and developed a method of intercepting the common routine that
: the CM IMAGE intrinsics call on their way to the "worker" IMAGE
: routine, but didn't do robust testing.
 
: I started to urge HP to provide a more useful "hook" for intercepting
: *all* IAMGE calls a few years ago, but the concept got lost in the
: work on jumbo datasets.  With mostly documentation work, it would be
: fairly easy to allow all IMAGE calls to be intercepted via AIF:PE
: by documenting & "marking" a small set of routines, ala what AIF:PE
: did for selected routines within NL.PUB.SYS.
 
: --
: Stan Sieler                                          [log in to unmask]
:                                      http://www.allegro.com/sieler.html
 
While Stan's description of what is happening during the CM to NM switch is
accurate, there is a way to trap CM IMAGE intrinsics.
 
The routine you would enable a trap for is "nmtw_fs_stub" in XL.PUB.SYS.  This
is not a convientent method, like Stan, I also would prefer a more useful hook
but so far it has not happened.
 
Below I have include the CM section of some IMAGE trap procedures I wrote
for a customer.  If you have any questions please feel free to e-mail me.
 
 
program pascal_database_traps;
 
$page$
{ ----------------------------------------------------------------------------
}
{                                                                              }
{                                                                              }
{ ----------------------------------------------------------------------------
}
 
const
  PC_DBOPEN           = 401;
  PC_DBINFO           = 402;
  PC_DBCLOSE          = 403;
  PC_DBFIND           = 404;
  PC_DBGET            = 405;
  PC_DBUPDATE         = 406;
  PC_DBPUT            = 407;
  PC_DBDELETE         = 408;
  PC_DBLOCK           = 409;
  PC_DBUNLOCK         = 410;
  PC_DBCONTROL        = 411;
  PC_DBBEGIN          = 412;
  PC_DBEND            = 413;
  PC_DBMEMO           = 414;
  PC_DBEXPLAIN        = 418;
  PC_DBERROR          = 419;
  PC_DBXBEGIN         = 420;
  PC_DBXEND           = 421;
  PC_DBXUNDO          = 422;
 
  Q_MINUS_4           = -(4 * 2);
  Q_MINUS_5           = -(5 * 2);
  Q_MINUS_6           = -(6 * 2);
 
  TI_MAX_DATA_ENTRIES = 255;
  TI_MAX_DATA_ITEMS   = 1023;
  TI_MAX_DATA_SETS    = 199;
 
$page$
{ ----------------------------------------------------------------------------
}
{                                                                              }
{                                                                              }
{ ----------------------------------------------------------------------------
}
type
  pac2    = packed array [1..2]   of char;
  pac4    = packed array [1..4]   of char;
  pac8    = packed array [1..8]   of char;
  pac10   = packed array [1..10]  of char;
  pac16   = packed array [1..16]  of char;
  pac18   = packed array [1..18]  of char;
  pac26   = packed array [1..26]  of char;
  pac34   = packed array [1..34]  of char;
  pac37   = packed array [1..37]  of char;
  pac200  = packed array [1..200] of char;
  pac800  = packed array [1..800] of char;
  pac1024 = packed array [1..1024] of char;
  pac2048 = packed array [1..2048] of char;
 
  aifpe_filename_t = pac37;
  aifpe_procname_t = pac34;
  aifpe_prodname_t = pac4;
 
  bit8  = 0..255;
  bit16 = 0..65535;
 
  cm_parm_area_t =
    record
      db              : globalanyptr;
      q               : localanyptr;
      cm_global_addr  : localanyptr;
    end;
 
  db_address_t   = array [ 1..8 ] of localanyptr;
 
  dbbuffer_t     = $ALIGNMENT 2$ pac1024;
  dbbuffer_ptr_t = ^dbbuffer_t;
 
  dblist_t       =
    record case boolean of
      TRUE       : (items    : pac2048);
      FALSE      : (nbritems : shortint;
                    itemno   : array [1..TI_MAX_DATA_ENTRIES] of shortint);
    end;
 
  dblist_ptr_t   = ^dblist_t;
 
  dbmode_t       = shortint;
  dbmode_ptr_t   = ^dbmode_t;
 
  dbname_t       =
    packed record
      fileno     : shortint;
      name       : pac26;
    end;
  dbname_ptr_t   = ^dbname_t;
 
  dbpass_t       = pac8;
  dbpass_ptr_t   = ^dbpass_t;
 
  dbset_t        =
    record case boolean of
      TRUE       : (setname : pac16);
      FALSE      : (setnbr  : shortint);
    end;
 
  dbset_ptr_t    = ^dbset_t;
 
{ Due to some PASCAL alignment nightmares in 4.0, we had to   }
{ make the dbstatus data type CRUNCHED to try and force byte  }
{ alignment.  In 5.0 this does not seem to be a problem so    }
{ you do not need to make this CRUNCHED.  But test it to make }
{ sure.                                                       }
{ ----------------------------------------------------------- }
  dbstatus_t     =
    crunched record
      word1      : shortint;
      word2      : shortint;
      word3_4    : integer;
      word5      : shortint;
      word6      : shortint;
      word7      : shortint;
      word8      : shortint;
      word9      : shortint;
      word10     : shortint;
    end;
 
  dbstatus_ptr_t = ^dbstatus_t;
 
  dbdelete_parms_t =
    record
      dbstatus_ptr : dbstatus_ptr_t;
      dbmode_ptr   : dbmode_ptr_t;
      dbset_ptr    : dbset_ptr_t;
      dbname_ptr   : dbname_ptr_t;
    end;
  dbdelete_parms_ptr_t = ^dbdelete_parms_t;
 
  dbopen_parms_t =
    record
      dbstatus_ptr : dbstatus_ptr_t;
      dbmode_ptr   : dbmode_ptr_t;
      dbpass_ptr   : dbpass_ptr_t;
      dbname_ptr   : dbname_ptr_t;
    end;
  dbopen_parms_ptr_t = ^dbopen_parms_t;
 
  dbput_parms_t =
    record
      dbbuffer_ptr  :  dbbuffer_ptr_t;
      dblist_ptr    :  dblist_ptr_t;
      dbstatus_ptr  :  dbstatus_ptr_t;
      dbmode_ptr    :  dbmode_ptr_t;
      dbset_ptr     :  dbset_ptr_t;
      dbname_ptr    :  dbname_ptr_t;
    end;
  dbput_parms_ptr_t = ^dbput_parms_t;
 
 
  dbupdate_parms_t =
    record
      dbbuffer_ptr  :  dbbuffer_ptr_t;
      dblist_ptr    :  dblist_ptr_t;
      dbstatus_ptr  :  dbstatus_ptr_t;
      dbmode_ptr    :  dbmode_ptr_t;
      dbset_ptr     :  dbset_ptr_t;
      dbname_ptr    :  dbname_ptr_t;
    end;
  dbupdate_parms_ptr_t = ^dbupdate_parms_t;
 
  dbset_info_t =
    packed record
      name         : pac16;
      typ          : pac2;
      entry_length : shortint;
      block_factor : shortint;
      filler_12    : shortint;
      filler_13    : shortint;
      nbr_entries  : integer;
      capacity     : integer;
    end;
 
  q_address_t = array [ 1..8 ] of ^shortint;
 
  status_t =
    record
      case boolean of
        TRUE    : (all    : integer);
        FALSE   : (info   : shortint;
                   subsys : shortint);
    end;
 
$page$
{ ----------------------------------------------------------------------------
}
{                                                                              }
{                                                                              }
{ ----------------------------------------------------------------------------
}
procedure nmtw_fs_stub (cm_global_addr  : localanyptr;
                        q_sub           : localanyptr;
                        db_addr         : globalanyptr);
external;
 
$page$
{ ----------------------------------------------------------------------------
}
{
}
{ ----------------------------------------------------------------------------
} procedure pe_cm_dbtrap (     bindid          : integer;
                         var  stubout         : boolean;
                              parms_area      : localanyptr
                        ) option extensible 3;
$call_privilege 3$
$exec_privilege 2$
 
var
  cm_parm_area          : ^cm_parm_area_t;
  db_address            :  db_address_t;
  i                     :  integer;
  num_parms             :  integer;
  proc_code             :  integer;
  q_address             :  q_address_t;
  q_4                   : ^bit16;
  q_5                   : ^bit16;
  user_priv_level       :  integer;
 
begin
 
{ All CM Image intrinsics will be trapped since we may not be interested in }
{ all of them we will default with not stubbing out the call.               }
{ ------------------------------------------------------------------------- }
  stubout := FALSE;
 
$push, type_coercion 'Representation'$
{ Grab the pointer to the parameters passed }
{ ----------------------------------------- }
  cm_parm_area := ADDTOPOINTER (parms_area, -SIZEOF (cm_parm_area_t));
 
{ Get the pointer to CM Q-4, this contains the callers privilege level }
{ -------------------------------------------------------------------- }
  q_4 := ADDTOPOINTER (cm_parm_area^.q, Q_MINUS_4);
  user_priv_level := q_4^;
 
{ Get the pointer to CM Q-5, this contains the id number of the intrinsic }
{ ----------------------------------------------------------------------- }
  q_5 := ADDTOPOINTER (cm_parm_area^.q, Q_MINUS_5);
  proc_code := q_5^;
 
{ Continue only if we are interested in the trapped intrinsic }
{ ----------------------------------------------------------- }
  if (proc_code in [PC_DBOPEN, PC_DBPUT, PC_DBUPDATE, PC_DBDELETE]) then
    begin
  { Now we need to know how many paramters are really passed to the intrinisc }
  { ------------------------------------------------------------------------- }
      case proc_code of
        PC_DBBEGIN,
        PC_DBEND,
        PC_DBMEMO ,
        PC_DBINFO,
        PC_DBXBEGIN,
        PC_DBXEND,
        PC_DBXUNDO : num_parms := 5;
 
        PC_DBCLOSE,
        PC_DBCONTROL,
        PC_DBDELETE,
        PC_DBLOCK,
        PC_DBOPEN,
        PC_DBUNLOCK: num_parms := 4;
 
        PC_DBFIND,
        PC_DBPUT,
        PC_DBUPDATE: num_parms := 6;
 
        PC_DBGET   : num_parms := 7;
 
        otherwise    num_parms := 0;
      end;
 
    { We need to get the pointers to the parameters passed.  To do this the }
    { pointer to the correct location in the Q area must be obtained.  This }
    { pointer contains an offset that must be added to the CM DB area.      }
    { --------------------------------------------------------------------- }
      for i := 1 to num_parms do
        begin
          q_address [ i ] := ADDTOPOINTER (cm_parm_area^.q, -2 * (5 + i));
          db_address[ i ] := ADDTOPOINTER (cm_parm_area^.db,
                                           2 * (q_address[ i ]^));
        end;
 
    { Check to see if this call needs to be processed locally. }
    { -------------------------------------------------------- }
      case proc_code of
        PC_DBOPEN:
          begin
          {  Perform any processing before the call.  }
 
            nmtw_fs_stub (cm_parm_area^.cm_global_addr,
                          cm_parm_area^.q,
                          cm_parm_area^.db);
 
          {  Perform andy processing after the call here.  }
 
            stubout := TRUE;
          end;
        PC_DBDELETE:
          begin
          {  Perform any processing before the call here.  }
 
            nmtw_fs_stub (cm_parm_area^.cm_global_addr,
                          cm_parm_area^.q,
                          cm_parm_area^.db);
 
          {  Perform andy processing after the call here.  }
 
            stubout := TRUE;
          end;
        PC_DBPUT:
          begin
          {  Perform any processing before the call here.  }
 
            nmtw_fs_stub (cm_parm_area^.cm_global_addr,
                          cm_parm_area^.q,
                          cm_parm_area^.db);
 
          {  Perform andy processing after the call here.  }
 
            stubout := TRUE;
          end;
        PC_DBUPDATE:
          begin
          {  Perform any processing before the call here.  }
 
            nmtw_fs_stub (cm_parm_area^.cm_global_addr,
                          cm_parm_area^.q,
                          cm_parm_area^.db);
 
          {  Perform andy processing after the call here.  }
 
            stubout := TRUE;
          end;
        otherwise
          begin
          end;
      end;
  end;
$pop$
end;
 
$page$
{ ----------------------------------------------------------------------------
}
begin
end.
--
+----------------------------+------------------------------------------+
| Barry Lemrow               |  Disclaimer:                             |
| Technical Consultant       |    "Opinions expressed are mine and not  |
| SAP National Practice      |     necessarily those of my employer,    |
| Hewlett-Packard            |     family, or friends!"                 |
| [log in to unmask]                                          |
+----------------------------+------------------------------------------+
| You can't have something for nothing.  You can't get freedom for free.|
| You won't get wise with the sleep still in your eyes, no matter what  |
| your dream might be! -- N. Peart, "Something for Nothing"             |
+----------------------------+------------------------------------------+

ATOM RSS1 RSS2