/*static char *SCCSID = "@(#)queryq.c	6.2 91/03/29";*/
/****************************************************************************/
/*                                                                          */
/*                       IBM/Microsoft Confidential                         */
/*                                                                          */
/*                 Copyright (c) IBM Corporation  1987, 1990                */
/*                 Copyright (c) Microsoft Corp.  1987, 1990                */
/*                           All Rights Reserved                            */
/*                                                                          */
/****************************************************************************/

/*
 *      This code will implement DosQueryQueue
 */

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

/********************** START OF SPECIFICATIONS *********************/
/*                                                                  */
/* SOURCE FILE NAME: queryq.c                                       */
/*                                                                  */
/* DESCRIPTIVE NAME: DosQueryQueue                                  */
/*                                                                  */
/* STATUS: RELEASE 1 LEVEL 0                                        */
/*                                                                  */
/* FUNCTION:   DosQueryQueue will return the number of elements in  */
/*             a Queue.                                             */
/*                                                                  */
/* NOTES:                                                           */
/*    DEPENDENCIES:                                                 */
/*    RESTRICTIONS:                                                 */
/*                                                                  */
/* ENTRY POINTS:        DosQueryQueue                               */
/*                                                                  */
/* INTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*                                                                  */
/* EXTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*             queues_sys_trace:NEAR                                */
/*             FuncFree:NEAR                                        */
/*             FuncInit:NEAR                                        */
/*             L_Find:NEAR                                          */
/*             Q_Scan: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: DosQueryQueue                                   */
/*                                                                  */
/* DESCRIPTIVE NAME: DosQueryQueue                                  */
/*                                                                  */
/* FUNCTION: Main line control for DosQueryQueue.                   */
/*                                                                  */
/* NOTES:                                                           */
/*                                                                  */
/* ENTRY POINT: DosQueryQueue                                       */
/*    LINKAGE:  far at pl 2                                         */
/*                                                                  */
/* INPUT:                                                           */
/*      DW     Queue Handle            ;Handle of desired queue     */
/*      DD     Number Elements         ;address of Element count    */
/*                                                                  */
/* EXIT-NORMAL:                                                     */
/*             AX = 0                                               */
/*             Number Elements                                      */
/*                                                                  */
/* EXIT-ERROR:                                                      */
/*             AX != 0                                              */
/*             'INVALID QUEUE HANDLE'                               */
/*             'SYS ERROR'                                          */
/*                                                                  */
/* EFFECTS:                                                         */
/*                                                                  */
/* INTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*                                                                  */
/* EXTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*             queues_sys_trace:NEAR                                */
/*             FuncFree:NEAR                                        */
/*             FuncInit:NEAR                                        */
/*             L_Find:NEAR                                          */
/*             Q_Scan:NEAR                                          */
/*                                                                  */
/*********************** END OF SPECIFICATIONS **********************/

/********************************************************************/
/*                                                                  */
/*   DosQueryQueue acts as the entry point and main line control for*/
/*   DosQueryQueue.  It first checks for proper initialization, then*/
/*   attempts to locate the Queue entry.  If the entry can be found,*/
/*   it will load the number of elements into the count parameter.  */
/*                                                                  */
/********************************************************************/
/*                                                                  */
/* DosQueryQueue:                                                   */
/*                                                                  */
/*      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                                                        */
/*        call Q_Scan                                               */
/*        if (Q_Scan returns in error) then                         */
/*          set error code      'INVALID QUEUE HANDLE'              */
/*        else                                                      */
/*          if (statseg.st_pid != q_offset.q_pid)                   */
/*            call L_Find                                           */
/*            if (L_Find returns in error)                          */
/*              set error       'INVALID HANDLE'                    */
/*            endif                                                 */
/*          endif                                                   */
/*          if (no error)                                           */
/*            set count = q_offset.q_cnt                            */
/*          endif                                                   */
/*        endif                                                     */
/*        call FuncFree                                             */
/*        if (FuncFree returns in error) then                       */
/*          set error code        'SYS ERROR'                       */
/*        endif                                                     */
/*      endif                                                       */
/*      if (tracing active)                                         */
/*        call queues_sys_trace                                     */
/*      endif                                                       */
/*      return                                                      */

unsigned far pascal
DOSQUERYQUEUE(QHnd,ECnt)
register unsigned QHnd;
unsigned far    *ECnt;
{
        extern  struct  InfoSegGDT far  *globptr;
        extern  struct  STATDATA        statseg;
        struct  Q_ENTRY far *q_offset;
        struct  Q_ENTRY far *q_prev;
        struct  L_ENTRY far *l_offset;
        struct  L_ENTRY far *l_prev;
        register unsigned int rc;
#if defined(MMIOPH)
        struct RAS_PRE_QUERY {
                unsigned long rp_hnd;
        } ras_pre_query;
        struct RAS_POST_QUERY {
                unsigned long rp_rc;
                unsigned long rp_cnt;
        } ras_post_query;
#endif

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

/***DT DosQueryQueue - Pre-Invocation Dynamic Trace
 *     TRACE MINOR =0x0006,
 *           TP=@
 *           TYPE  =(PRE,API),
 *           DESC  ="(OS) DosQueryQueue Pre-Invocation",
 *           FMT   ="Handle=%pw",
 *           MEM   =(.QHnd,d,2)
 */

#if defined(MMIOPH)
        if (((*globptr).mec_table[17] & 0x80) != NULL)
        {
                ras_pre_query.rp_hnd = (unsigned long)QHnd;
                queues_sys_trace(((unsigned) 0x88),sizeof(struct RAS_PRE_QUERY),((unsigned) 6),(char far *) &ras_pre_query);
        }
#endif

        if ((FuncInit()) != NO_ERROR)
                rc = ERROR_SYS_INTERNAL;
        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 (statseg.st_pid != (*q_offset).q_pid)
                        {
                                if ((L_Find(QHnd,(struct L_ENTRY far * far *) &l_offset,(struct L_ENTRY far * far *) &l_prev))
                                        != NO_ERROR)
                                        rc = ERROR_QUE_INVALID_HANDLE;
                        }
                        if (rc == NO_ERROR)
                                *ECnt = (*q_offset).q_cnt;
                }
                if ((FuncFree() != NO_ERROR) && (rc == NO_ERROR))
                        rc = ERROR_SYS_INTERNAL;
        }

/***DT DosQueryQueue - Post-Invocation Dynamic Trace
 *     TRACE MINOR =0x8006,
 *           TP=@
 *           TYPE  =(POST,API),
 *           DESC  ="(OS) DosQueryQueue Post-Invocation",
 *           FMT   ="Return Code=%pw  Number of Elements=%pw",
 *           MEM   =(.rc,d,2),
 *           MEM   =(.ECnt,i,2)
 */

#if defined(MMIOPH)
        if (((*globptr).mec_table[17] & 0x80) != NULL)
        {
                ras_post_query.rp_rc = (unsigned long)rc;
                ras_post_query.rp_cnt = (unsigned long)*ECnt;
                queues_sys_trace(((unsigned) 0x88),sizeof(struct RAS_POST_QUERY),((unsigned) 0x86),(char far *) &ras_post_query);
        }
#endif

        return(POPALL(rc));
}
