/*static char *SCCSID = "@(#)purgeq.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 DosPurgeQueue
 */

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

/********************** START OF SPECIFICATIONS *********************/
/*                                                                  */
/* SOURCE FILE NAME: purgeq.c                                       */
/*                                                                  */
/* DESCRIPTIVE NAME: DosPurgeQueue                                  */
/*                                                                  */
/* STATUS: RELEASE 1 LEVEL 0                                        */
/*                                                                  */
/* FUNCTION: DosPurgeQueue will purge a queue of all elements.      */
/*                                                                  */
/* NOTES:                                                           */
/*    DEPENDENCIES:                                                 */
/*    RESTRICTIONS:                                                 */
/*                                                                  */
/* ENTRY POINTS:        DosPurgeQueue                               */
/*                                                                  */
/* INTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*                                                                  */
/* EXTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*             queues_sys_trace:NEAR                                */
/*             El_Delete:NEAR                                       */
/*             FuncInit:NEAR                                        */
/*             FuncFree: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: DosPurgeQueue                                   */
/*                                                                  */
/* DESCRIPTIVE NAME: DosPurgeQueue                                  */
/*                                                                  */
/* FUNCTION: Main line control for DosPurgeQueue.                   */
/*                                                                  */
/* NOTES:                                                           */
/*                                                                  */
/* ENTRY POINT: DosPurgeQueue                                       */
/*    LINKAGE:  far at pl 2                                         */
/*                                                                  */
/* INPUT:                                                           */
/*      DW     Queue Handle            ;Handle of desired queue     */
/*                                                                  */
/* EXIT-NORMAL:                                                     */
/*             AX = 0                                               */
/*                                                                  */
/* EXIT-ERROR:                                                      */
/*             AX != 0                                              */
/*             'CURRENT PROCESS DOES NOT OWN QUEUE'                 */
/*             'INVALID QUEUE HANDLE'                               */
/*             'SYS ERROR'                                          */
/*                                                                  */
/* EFFECTS:    Deletes all Element Structures from a Queue          */
/*                                                                  */
/* INTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*                                                                  */
/* EXTERNAL REFERENCES:                                             */
/*    ROUTINES:                                                     */
/*             queues_sys_trace:NEAR                                */
/*             El_Delete:NEAR                                       */
/*             FuncInit:NEAR                                        */
/*             FuncFree:NEAR                                        */
/*             Q_Scan:NEAR                                          */
/*                                                                  */
/*********************** END OF SPECIFICATIONS **********************/

/********************************************************************/
/*                                                                  */
/*DosPurgeQueue acts as the entry point and main line control for   */
/*DosPurgeQueue.  It first checks for proper initialization, then   */
/*attempts to locate the Queue entry.  If the entry can be found, it*/
/*compares the Queue PID with the requestor's PID to insure legal   */
/*access. If the queue has elements they will be deleted and the    */
/*queue entry will be updated.                                      */
/*                                                                  */
/********************************************************************/
/*                                                                  */
/* DosPurgeQueue:                                                   */
/*                                                                  */
/*      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 (offset.q_pid != static.st_pid) then                 */
/*            set error code    'CURRENT PROCESS DOES NOT OWN QUEUE'*/
/*          else                                                    */
/*            if (offset.q_fst != 0) then                           */
/*              call El_Delete                                      */
/*              if (El_Delete returns in error)                     */
/*                set error code        from El_Delete              */
/*              else                                                */
/*                offset.q_cnt = 0                                  */
/*                offset.q_fst = 0                                  */
/*                offset.q_lst = 0                                  */
/*                set good return                                   */
/*              endif                                               */
/*            endif                                                 */
/*          endif                                                   */
/*        endif                                                     */
/*        call FuncFree                                             */
/*        if (FuncFree returns in error and no error set)           */
/*          set error code        'SYS ERROR'                       */
/*        endif                                                     */
/*      endif                                                       */
/*      if (tracing active)                                         */
/*        call queues_sys_trace                                     */
/*      endif                                                       */
/*      return                                                      */

unsigned far pascal
DOSPURGEQUEUE(QHnd)
register unsigned QHnd;
{
        extern  struct  InfoSegGDT far  *globptr;
        extern  struct  STATDATA        statseg;
        struct  Q_ENTRY far *q_offset;
        struct  Q_ENTRY far *q_prev;
        register unsigned int rc;
#if defined(MMIOPH)
        struct RAS_PRE_PURGE {
                unsigned long rp_hnd;
        } ras_pre_purge;
        struct RAS_POST_PURGE {
                unsigned long rp_rc;
        } ras_post_purge;
#endif

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

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

#if defined(MMIOPH)
        if (((*globptr).mec_table[17] & 0x80) != NULL)
        {
                ras_pre_purge.rp_hnd = (unsigned long)QHnd;
                queues_sys_trace(((unsigned) 0x88),sizeof(struct RAS_PRE_PURGE),((unsigned) 5),(char far *) &ras_pre_purge);
        }
#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 ((*q_offset).q_pid != statseg.st_pid)
                                rc = ERROR_QUE_PROC_NOT_OWNED;
                        else
                        {
                                if ((*q_offset).q_cnt != 0)
                                        rc = El_Delete(q_offset);
                        }
                }
                if ((FuncFree() != NO_ERROR) && (rc == NO_ERROR))
                        rc = ERROR_SYS_INTERNAL;
        }

/***DT DosPurgeQueue - Post-Invocation Dynamic Trace
 *     TRACE MINOR =0x8005,
 *           TP=@
 *           TYPE  =(POST,API),
 *           DESC  ="(OS) DosPurgeQueue Post-Invocation",
 *           FMT   ="Return Code=%pw",
 *           MEM   =(.rc,d,2)
 */

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

        return(POPALL(rc));
}
