/*static char *SCCSID = "@(#)peekq.c    6.6 91/11/07";*/
/****************************************************************************/
/*                                                                          */
/*                       IBM/Microsoft Confidential                         */
/*                                                                          */
/*                 Copyright (c) IBM Corporation  1987, 1990                */
/*                 Copyright (c) Microsoft Corp.  1987, 1990                */
/*                           All Rights Reserved                            */
/*                                                                          */
/****************************************************************************/

/*
 *      This code will implement DosPeekQueue
 */

#include        <dos.h>
#include        <error.h>
#include        <error2.h>
#include        <doscalls.h>
#include        <infoseg.h>
#include        <ipcqueue.h>

unsigned int E_Locate(unsigned int far *, struct Q_ENTRY far *, struct E_ENTRY far * far *);
unsigned far pascal w_DOSPEEKQUEUE(unsigned, struct LOCATION far *, unsigned long far *, unsigned long far *, unsigned far *, unsigned short, unsigned char far *, unsigned long, unsigned short far *);

/********************** START OF SPECIFICATIONS *********************/
/*                                                                  */
/* SOURCE FILE NAME: peekq.c                                        */
/*                                                                  */
/* DESCRIPTIVE NAME: DosPeekQueue                                   */
/*                                                                  */
/* STATUS: RELEASE 1 LEVEL 0                                        */
/*                                                                  */
/* FUNCTION: DosPeekQueue will read an element from the specified   */
/*           queue without removing it from the chain.              */
/*                                                                  */
/* NOTES:                                                           */
/*    DEPENDENCIES:                                                 */
/*    RESTRICTIONS:                                                 */
/*                                                                  */
/* ENTRY POINTS:        DosPeekQueue                                */
/*                                                                  */
/* INTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*             E_Locate:NEAR                                        */
/*             w_DosPeekQueue:FAR                                   */
/*                                                                  */
/* EXTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*             OPEN16EVENTSEM:FAR                                   */
/*             CLOSE16EVENTSEM:FAR                                  */
/*             queues_sys_trace:NEAR                                */
/*             FuncFree:NEAR                                        */
/*             FuncInit:NEAR                                        */
/*             Q_Scan:NEAR                                          */
/*             Q_Empty:NEAR                                         */
/*                                                                  */
/*********************** END OF SPECIFICATIONS **********************/

#if defined(MMIOPH)
extern void queues_sys_trace(
unsigned,                                       /* que_major_code */
unsigned,                                       /* int que_data_len */
unsigned,                                       /* que_minor_code */
char far *);                                    /* que_data */
#endif

/********************** START OF SPECIFICATIONS *********************/
/*                                                                  */
/* SUBROUTINE NAME: E_Locate                                        */
/*                                                                  */
/* DESCRIPTIVE NAME: E_Locate                                       */
/*                                                                  */
/* FUNCTION: Locate the "next" Element in the Queue.                */
/*                                                                  */
/* NOTES:                                                           */
/*                                                                  */
/* ENTRY POINT: E_Locate                                            */
/*    LINKAGE:  near at pl 2                                        */
/*                                                                  */
/* INPUT:                                                           */
/*      DW     Element Code            ;Element Parm on Stack       */
/*      DD     Queue Address           ;Address of Queue Entry      */
/*      DD     Element Address         ;Pointer to Element          */
/*                                                                  */
/* EXIT-NORMAL:                                                     */
/*             AX = 0                                               */
/*             Element Address                                      */
/*                                                                  */
/* EXIT-ERROR: AX != 0                                              */
/*             'ELEMENT DOES NOT EXIST'                             */
/*             'PREVIOUS ELEMENT WAS AT END OF QUEUE'               */
/*                                                                  */
/* EFFECTS:                                                         */
/*                                                                  */
/* INTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*                                                                  */
/* EXTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*                                                                  */
/*********************** END OF SPECIFICATIONS **********************/

/*E_Locate                                                          */
/*                                                                  */
/*      if (queue contains no elements)                             */
/*        return with           'ELEMENT NOT EXIST'                 */
/*      else                                                        */
/*        if (queue uses LIFO prio.)                                */
/*          if (first element != element code)                      */
/*            return with       'PREV AT END'                       */
/*          else                                                    */
/*            if (element code != NULL)                             */
/*              while (element code not found and element chain     */
/*                     not exhausted)                               */
/*                e_off = e_off.e_prev                              */
/*              endwhile                                            */
/*              if (element code found)                             */
/*                e_off = e_off.e_prev                              */
/*              else                                                */
/*                return with   'ELEMENT NOT EXIST'                 */
/*              endif                                               */
/*            endif                                                 */
/*          endif                                                   */
/*        else                                                      */
/*          if (last element != element code)                       */
/*            return with       'PREV AT END'                       */
/*          else                                                    */
/*            if (element code != NULL)                             */
/*              while (element code not found and element chain     */
/*                     not exhausted)                               */
/*                e_off = e_off.e_next                              */
/*              endwhile                                            */
/*              if (element code found)                             */
/*                e_off = e_off.e_next                              */
/*              else                                                */
/*                return with   'ELEMENT NOT EXIST'                 */
/*              endif                                               */
/*            endif                                                 */
/*          endif                                                   */
/*        endif                                                     */
/*      endif                                                       */
/*      eoff = e_off                                                */
/*      return with             'NO ERROR'                          */

unsigned int
E_Locate(ecode,qoff,eoff)
unsigned int    far *ecode;
struct  Q_ENTRY far     *qoff;
struct E_ENTRY far * far *eoff;
{
        extern  struct  STATDATA        statseg;
        struct E_ENTRY far *e_off;
        struct E_ENTRY far *qu_off;
        register unsigned int   el_off;

        e_off = (*qoff).q_fst;
        if (e_off == NULL)
                return(ERROR_QUE_ELEMENT_NOT_EXIST);
        if ((*qoff).q_prio == LIFO_PRIO)
        {
                e_off = (*qoff).q_lst;
                qu_off = (*qoff).q_fst;
                if (*ecode == FP_OFF(qu_off))
                        return(ERROR_QUE_PREV_AT_END);
                else
                {
                        if (*ecode != NULL)
                        {
                                while ((*ecode != FP_OFF(e_off)) && (e_off != NULL))
                                {
                                        e_off = (*e_off).e_prev;
                                }
                                if (*ecode == FP_OFF(e_off))
                                {
                                        e_off = (*e_off).e_prev;
                                }
                                else
                                        return(ERROR_QUE_ELEMENT_NOT_EXIST);
                        }
                }
        }
        else
        {
                qu_off = (*qoff).q_lst;
                if (*ecode == FP_OFF(qu_off))
                        return(ERROR_QUE_PREV_AT_END);
                else
                {
                        if (*ecode != NULL)
                        {
                                while ((*ecode != FP_OFF(e_off)) && (e_off != NULL))
                                {
                                        e_off = (*e_off).e_next;
                                }
                                if (*ecode == FP_OFF(e_off))
                                {
                                        e_off = (*e_off).e_next;
                                }
                                else
                                        return(ERROR_QUE_ELEMENT_NOT_EXIST);
                        }
                }
        }
        *eoff = e_off;
        return(NO_ERROR);
}

/********************** START OF SPECIFICATIONS *********************/
/*                                                                  */
/* SUBROUTINE NAME: w_DosPeekQueue                                  */
/*                                                                  */
/* DESCRIPTIVE NAME: DosPeekQueue Worker                            */
/*                                                                  */
/* FUNCTION: Main routine for 16 bit DosPeekQueue                   */
/*                                                                  */
/* NOTES:                                                           */
/*                                                                  */
/* ENTRY POINT: w_DosPeekQueue                                      */
/*    LINKAGE:  far at pl 2                                         */
/*                                                                  */
/* INPUT:                                                           */
/*      DW     Queue Handle            ;Handle of desired queue     */
/*      DW,DD  Request                 ;sender PID, appl. code      */
/*      DD     @Data Length             ;Length of packet           */
/*      DD     @Data Address            ;Address of Data            */
/*      DW     @Element Code           ;element identifier          */
/*      DW     NoWait                  ;Wait or NoWait              */
/*      DB     @Element Priority       ;priority 0 - 15             */
/*      DD     RamSemaphore            ;semaphore handle            */
/*      DW     @flag                   ;flag to 32-bit app          */
/*                                                                  */
/* EXIT-NORMAL:                                                     */
/*             AX = 0                                               */
/*             Request                                              */
/*             Data Address                                         */
/*             Data Length                                          */
/*             Element Code                                         */
/*             Element Priority                                     */
/*                                                                  */
/* EXIT-ERROR: AX != 0                                              */
/*             'CURRENT PROCESS DOES NOT OWN QUEUE'                 */
/*             'ELEMENT DOES NOT EXIST'                             */
/*             'INVALID QUEUE HANDLE'                               */
/*             'INVALID WAIT'                                       */
/*             'QUEUE IS EMPTY'                                     */
/*             'INVALID PARAMETER'                                  */
/*             'SYS ERROR'                                          */
/*                                                                  */
/* EFFECTS:                                                         */
/*                                                                  */
/* INTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*             E_Locate:NEAR                                        */
/*                                                                  */
/* EXTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*             OPEN16EVENTSEM:FAR                                   */
/*             CLOSE16EVENTSEM:FAR                                  */
/*             queues_sys_trace:NEAR                                */
/*             FuncFree:NEAR                                        */
/*             FuncInit:NEAR                                        */
/*             Q_Scan:NEAR                                          */
/*             Q_Empty:NEAR                                         */
/*                                                                  */
/*********************** END OF SPECIFICATIONS **********************/

/********************************************************************/
/*                                                                  */
/*w_DosPeekQueue acts as the entry point and main line control for  */
/*DosPeekQueue.  It first checks for proper initialization, then    */
/*attempts to locate the Queue.  If the entry can be found it       */
/*compares the Queue PID with the requestor's PID to insure legal   */
/*access. If the queue is empty and nowait specified an error will  */
/*result; if empty and wait has been specified, the thread will     */
/*be put to sleep.  When a valid Peek occurs exists an attempt      */
/*will be made to locate the next Element.  If this happens         */
/*the return parameters will be filled.                             */
/*                                                                  */
/********************************************************************/
/*                                                                  */
/* w_DosPeekQueue:                                                  */
/*                                                                  */
/*      initialize error        'NO ERROR'                          */
/*      if (tracing active)                                         */
/*        call queues_sys_trace                                     */
/*      endif                                                       */
/*      call FuncInit                                               */
/*      if (FuncInit returns in error) then                         */
/*        set error code        'SYS ERROR'                         */
/*      else                                                        */
/*        if (invalid prio.)                                        */
/*          set error           'INVALID WAIT'                      */
/*        else                                                      */
/*          call Q_Scan                                             */
/*          if (Q_Scan returns in error) then                       */
/*            set error code      'INVALID QUEUE HANDLE'            */
/*          else                                                    */
/*            if (offset.q_pid != static.st_pid) then               */
/*              set error code    'CURRENT PROCESS DOES NOT OWN QUEUE'*/
/*            else                                                  */
/*              if NoWait and 32-bit call                           */
/*                if invalid semaphore                              */
/*                  set error code  'INVALID PARAMETER'             */
/*                else if first no wait call                        */
/*                  open semaphore                                  */
/*                  if open unsuccessful                            */
/*                    set error code  'INVALID PARAMETER'           */
/*                  else                                            */
/*                    close semaphore                               */
/*                  endif                                           */
/*                endif                                             */
/*              endif                                               */
/*              if (NO ERROR and queue count == null)               */
/*                call Q_Empty                                      */
/*              else                                                */
/*                call E_Locate                                     */
/*                if (E_Locate returns in error) then               */
/*                  set error code 'ELEMENT DOES NOT EXIST'         */
/*                else                                              */
/*                  if (minor tracing active)                       */
/*                    call queues_sys_trace                         */
/*                  endif                                           */
/*                  emt.e_len in address specified on stack (length)*/
/*                  emt.e_spid, emt.e_apfld in address specified on */
/*                      stack (request)                             */
/*                  emt.e_addr in address specified on stack (addr.)*/
/*                  emt.e_prio in address specified on stack (prio.)*/
/*                  emt in address specified on stack (element code)*/
/*                  if (32-bit element or thunking desired)         */
/*                    set flag to 32-bit thunk routine              */
/*                  endif                                           */
/*                  set good return                                 */
/*                endif                                             */
/*              endif                                               */
/*            endif                                                 */
/*          endif                                                   */
/*        endif                                                     */
/*        call FuncFree                                             */
/*        if (FuncFree returns in error and error is not set)       */
/*          set error code        'SYS ERROR'                       */
/*        endif                                                     */
/*      endif                                                       */
/*      if (tracing active)                                         */
/*        call queues_sys_trace                                     */
/*      endif                                                       */
/*      return                                                      */

/*********/
extern unsigned far OPEN16EVENTSEM(unsigned long);
extern unsigned far CLOSE16EVENTSEM(unsigned long);
/*********/

unsigned far pascal w_DOSPEEKQUEUE(QHnd,Request,E_Length,E_Addr,E_Code,No_Wait,E_Prio,SemHnd,flag)
unsigned QHnd;
struct LOCATION far     *Request;
unsigned long   far     *E_Length;
unsigned long   far     *E_Addr;
unsigned far    *E_Code;
register unsigned short  No_Wait;
unsigned char   far     *E_Prio;
unsigned long   SemHnd;
unsigned short  far     *flag;
{
        extern  struct  InfoSegGDT far  *globptr;
        extern  struct  STATDATA        statseg;
        struct  Q_ENTRY far *q_offset;
        struct  Q_ENTRY far *q_prev;
        struct  E_ENTRY far *e_offset;
        struct  LOCATION emt_req;
        register unsigned int rc;
#if defined(MMIOPH)
        struct RAS_PRE_PEEK {
                unsigned long rp_hnd;
                unsigned long rp_ecode;
                unsigned long rp_sem;
                unsigned long rp_nowait;
        } ras_pre_peek;
        struct RAS_PEEK_EVENT {
                unsigned long re_len;
                long re_addr;
                unsigned re_ecode;
        } ras_peek_event;
        struct RAS_POST_PEEK {
                unsigned long rp_rc;
                struct LOCATION_MMIOPH rp_req;
                unsigned long rp_addr;
                unsigned long rp_len;
                unsigned long rp_ecod;
                unsigned char rp_prio;
        } ras_post_peek;
#endif

        PUSHALL_DS();
        rc = NO_ERROR;
        #if (cdbug)
        krnldbug();
        #endif

/***DT DosPeekQueue - Pre-Invocation Dynamic Trace
 *     TRACE MINOR =0x0004,
 *           TP=@
 *           TYPE  =(PRE,API),
 *           DESC  ="(OS) DosPeekQueue Pre-Invocation",
 *           FMT   ="Handle=%pw  Element Code=%pw",
 *           FMT   ="Semaphore Handle=%pd  No Wait Flag=%pb%i1 ",
 *           MEM   =(.QHnd,d,2),
 *           MEM   =(.E_Code,i,2),
 *           MEM   =(.SemHnd,d,4),
 *           MEM   =(.No_Wait,d,2)
 */

#if defined(MMIOPH)
        if (((*globptr).mec_table[17] & 0x80) != NULL)
        {
                ras_pre_peek.rp_hnd = (unsigned long)QHnd;
                ras_pre_peek.rp_ecode = (unsigned long)*E_Code;
                ras_pre_peek.rp_nowait = (unsigned long)No_Wait;
                ras_pre_peek.rp_sem = (unsigned long)SemHnd;
                queues_sys_trace(((unsigned) 0x88),sizeof(struct RAS_PRE_PEEK),((unsigned) 4),(char far *) &ras_pre_peek);
        }
#endif

        if ((FuncInit()) != NO_ERROR)
        {
                rc = ERROR_SYS_INTERNAL;
        }
        else
        {
                if (No_Wait > NO_WAIT)
                        rc = ERROR_QUE_INVALID_WAIT;
                else
                {
                        if ((Q_Scan((struct Q_ENTRY far * far *) &q_offset,(struct Q_ENTRY far * far *) &q_prev,QHnd)) != NO_ERROR)
                                rc = ERROR_QUE_INVALID_HANDLE;
                        else
                        {
                                if ((*q_offset).q_pid != statseg.st_pid)
                                        rc = ERROR_QUE_PROC_NOT_OWNED;
                                else
                                {
                                        if ((No_Wait == NO_WAIT) && ((*q_offset).q_flags & Q_BIT32))
                                        {
                                                if (SemHnd == NULL)
                                                {
                                                        rc = ERROR_INVALID_PARAMETER;
                                                }
                                                else if ((*q_offset).q_semhnd == NULL)
                                                {
                                                        if (OPEN16EVENTSEM(SemHnd) != NO_ERROR)
                                                        {
                                                                rc = ERROR_INVALID_PARAMETER;
                                                        }
                                                        else
                                                        {
                                                                CLOSE16EVENTSEM(SemHnd);          /* Defect 65343 D.B. */
                                                                (*q_offset).q_semhnd = SemHnd;
                                                        }
                                                }
                                                else if ((*q_offset).q_semhnd != SemHnd)
                                                {
                                                        rc = ERROR_INVALID_PARAMETER;
                                                }
                                        }
                                        if (rc == NO_ERROR && (*q_offset).q_cnt == NULL)
                                                rc = Q_Empty((unsigned char)No_Wait,SemHnd,q_offset);
                                        if (rc == NO_ERROR)
                                        {
                                                if ((E_Locate(E_Code,q_offset,(struct E_ENTRY far * far *) &e_offset)) != NO_ERROR)
                                                        rc = ERROR_QUE_ELEMENT_NOT_EXIST;
                                                else
                                                {

                                                     #if defined(MMIOPH)
                                                        if (((*globptr).mec_table[17] & 0x40) != NULL)
                                                        {
                                                                ras_peek_event.re_len = (*e_offset).e_len;
                                                                ras_peek_event.re_addr = (unsigned long) (*e_offset).e_addr;
                                                                ras_peek_event.re_ecode = FP_OFF(e_offset);
                                                                queues_sys_trace(((unsigned) 0x89),sizeof(struct RAS_PEEK_EVENT),
                                                                        ((unsigned) 3),(char far *) &ras_peek_event);
                                                        }
                                                     #endif
                                                        *E_Length = (*e_offset).e_len;
                                                        emt_req.process_id = (*e_offset).e_spid;
                                                        emt_req.request_data = (*e_offset).e_apfld;
                                                        (*Request).process_id = emt_req.process_id;
                                                        (*Request).request_data = emt_req.request_data;
                                                        *E_Addr = (unsigned long) (*e_offset).e_addr;
                                                        *E_Prio = (unsigned char)(*e_offset).e_prio;
                                                        *E_Code = FP_OFF(e_offset);

                                                        if (((*e_offset).e_flags & E_BIT32) ||
                                                            ((*q_offset).q_flags & Q_THUNK))
                                                        {
                                                                *flag = CONVERT_ADDR;
                                                        }

/***DT DosPeekQueue - Internal Dynamic Trace
 *     TRACE MINOR =0x0009,
 *           TP=@
 *           TYPE  =(INT),
 *           DESC  ="(OS) Peek Data Packet From Queue",
 *           FMT   ="Length=%p%w  Address=%p%a  Element Code=%p%w",
 *           MEM   =(.E_Length,i,2),
 *           MEM   =(.E_Addr,i,4),
 *           MEM   =(.E_Code,i,2)
 */

                                                }
                                        }
                                }
                        }
                }
                if ((FuncFree() != NO_ERROR) && (rc == NO_ERROR))
                        rc = ERROR_SYS_INTERNAL;
        }

/***DT DosPeekQueue - Post-Invocation Dynamic Trace
 *     TRACE MINOR =0x8004,
 *           TP=@
 *           TYPE  =(POST,API),
 *           DESC  ="(OS) DosPeekQueue Post-Invocation",
 *           FMT   ="Return Code=%pw  Request=%p%w%d  Address=%p%a  Length=%p%d",
 *           FMT   ="Element Code=%p%w  Priority=%p%b"
 *           MEM   =(.rc,d,2),
 *           MEM   =(.Request,i,6),
 *           MEM   =(.E_Addr,i,4),
 *           MEM   =(.E_Length,i,4),
 *           MEM   =(.E_Code,i,2),
 *           MEM   =(.E_Prio,i,1)
 */

#if defined(MMIOPH)
        if (((*globptr).mec_table[17] & 0x80) != NULL)
        {
                ras_post_peek.rp_rc = (unsigned long)rc;
                ras_post_peek.rp_req.process_id = (unsigned long)
                                                  ((*Request).process_id);
                ras_post_peek.rp_req.request_data = (*Request).request_data;
                ras_post_peek.rp_addr = (unsigned long)*E_Addr;
                ras_post_peek.rp_len = (unsigned long)*E_Length;
                ras_post_peek.rp_prio = (unsigned char)*E_Prio;
                ras_post_peek.rp_ecod = (unsigned long)*E_Code;
                queues_sys_trace(((unsigned) 0x88),sizeof(struct RAS_POST_PEEK),((unsigned) 0x84),(char far *) &ras_post_peek);
        }
#endif

        return(POPALL(rc));
}

/********************** START OF SPECIFICATIONS *********************/
/*                                                                  */
/* SUBROUTINE NAME: DosPeekQueue                                    */
/*                                                                  */
/* DESCRIPTIVE NAME: DosPeekQueue                                   */
/*                                                                  */
/* FUNCTION: Parent routine for 16 bit DosPeek Queue                */
/*                                                                  */
/* NOTES:                                                           */
/*                                                                  */
/* ENTRY POINT: DosPeekQueue                                        */
/*    LINKAGE:  far at pl 2                                         */
/*                                                                  */
/* INPUT:                                                           */
/*      DW     Queue Handle            ;Handle of desired queue     */
/*      DD     Request                 ;sender PID, appl. code      */
/*      DD     @Data Length             ;Length of packet           */
/*      DD     @Data Address            ;Address of Data            */
/*      DD     Element Code            ;element identifier          */
/*      DW     NoWait                  ;Wait or NoWait              */
/*      DB     @Element Priority       ;priority 0 - 15             */
/*      DD     RamSemaphore            ;semaphore handle            */
/*                                                                  */
/* EXIT-NORMAL:                                                     */
/*             AX = 0                                               */
/*             Request                                              */
/*             Data Address                                         */
/*             Data Length                                          */
/*             Element Code                                         */
/*             Element Priority                                     */
/*                                                                  */
/* EXIT-ERROR: AX != 0                                              */
/*             'CURRENT PROCESS DOES NOT OWN QUEUE'                 */
/*             'ELEMENT DOES NOT EXIST'                             */
/*             'INVALID QUEUE HANDLE'                               */
/*             'INVALID WAIT'                                       */
/*             'QUEUE IS EMPTY'                                     */
/*             'SYS ERROR'                                          */
/*                                                                  */
/* EFFECTS:                                                         */
/*                                                                  */
/* INTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*             w_DosPeekQueue:NEAR                                  */
/*                                                                  */
/* EXTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*                                                                  */
/*********************** END OF SPECIFICATIONS **********************/

/********************************************************************/
/*                                                                  */
/* DosPeekQueue:                                                    */
/*                                                                  */
/*      call w_DosPeekQueue                                         */
/*      return                                                      */

unsigned far pascal
DOSPEEKQUEUE(QHnd,Request,E_Length,E_Addr,E_Code,No_Wait,E_Prio,SemHnd)
unsigned QHnd;
unsigned long   far     *Request;
unsigned far    *E_Length;
unsigned long   far     *E_Addr;
unsigned far    *E_Code;
unsigned char   No_Wait;
unsigned char   far     *E_Prio;
unsigned long   SemHnd;
{
unsigned rc;
unsigned long element_length;
struct LOCATION request_field;
PUSHALL_DS();
if (Request != NULL) {
  request_field.process_id=*(unsigned far *)Request;
  request_field.request_data=*(((unsigned far *)(Request))+1);
  }
if (E_Length != NULL) {
  element_length = *E_Length;
  }
rc = w_DOSPEEKQUEUE(QHnd,(struct LOCATION far *)&request_field,(unsigned long far *)&element_length,E_Addr,E_Code,(unsigned short)No_Wait,(unsigned char far *)E_Prio,SemHnd,(unsigned short far *)NULL);
if (rc == 0) {
  if (Request != NULL) {
    *(unsigned far *)Request=request_field.process_id;
    *(((unsigned far *)(Request))+1)=(unsigned)request_field.request_data;
    }
  if (E_Length != NULL) {
    *E_Length = (unsigned)element_length;
    }
  }
return(POPALL(rc));
}
