/************************************************************************\
* The enclosed files, "the software," is provided by
* Microsoft Corporation "as is" without warranty of any kind.
* MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.  You assume all risks of
* using the software.
*
* The software is Copyright (c) 1992 Microsoft Corporation.
* Original Author: John M. Hall, Microsoft SDE  9/1/92
*
* You are granted the right to freely distribute this software.
* You are granted the right to make changes provided this comment block
* is retained without modification and you acknowledge the changes.
*
\************************************************************************/
/************************************************************************\
*
*                               QUEUE.H
*
\************************************************************************/

#ifndef QUEUE_DLL_H
#define QUEUE_DLL_H

/************************************************************************\
*                         SYMBOLIC CONSTANTS
\************************************************************************/

#define ERROR_QUE_INVALID_NAME      1000
#define ERROR_QUE_NO_MEMORY         1001
#define ERROR_QUE_NAME_NOT_EXIST    1002
#define ERROR_QUE_ELEMENT_NOT_EXIST 1003
#define ERROR_QUE_INVALID_HANDLE    1004
#define ERROR_QUE_EMPTY             1005

#define QUE_FIFO           1
#define QUE_LIFO           2
#define QUE_PRIORITY       3

#define DCWW_NOWAIT        FALSE
#define DCWW_WAIT          TRUE

#ifdef QUEUE_DLL_C
#define INFINITE    0xFFFFFFFF
#define MUNGE       37
#define MAGIC       0x4a6d4800
#define MAX_QUEUES  32
#define QUEUE_LIMIT 100


/************************************************************************\
*                          GLOBAL SHARED VARIABLES
\************************************************************************/

DWORD dwProcesses;
int   iQueues;

/************************************************************************\
*                          GLOBAL NON-Shared VARIABLES
\************************************************************************/

HANDLE hMod       = NULL;
HANDLE hGlobalSem = NULL;
HANDLE hControl = NULL;
LPVOID lpCtrlBase = NULL;
DWORD  dwProcessID = 0;
FILE *fp_log = NULL;
LPBYTE lpBase = NULL;

/************************************************************************\
*                          MACROS
\************************************************************************/
#define MAKE_PTR(a,b)  ((LPVOID)((DWORD)(a) + (b)))
#define MUNGEIT(a) ( ((a)+1)* MUNGE)
#define UNMUNGE(a) ( ((a)/MUNGE)-1)

#ifdef DEBUG
#define AssertBox(a,b) if (!(a)) MyAssertBox((b), #a, __FILE__, __LINE__)
#else
#define AssertBox(a,b)
#endif

#endif // QUEUE_DLL_C
/************************************************************************\
*                          STRUCTURES
\************************************************************************/

typedef struct _queue_elem {
    DWORD  dwWriterId;
    HGLOBAL dwShrHandle;
    DWORD  dwEventCode;
    DWORD  dwPriority;

} Q_ELEMENT;
typedef Q_ELEMENT *PQ_ELEMENT;

#ifdef QUEUE_DLL_C
typedef struct {
    DWORD  dwMagic;
    DWORD  dwProcId;
    HANDLE hEvent;
    HANDLE hSem;
    int    iIndex;
} QUEUE;
typedef QUEUE *HQUEUE;
typedef HQUEUE *PHQUEUE;

typedef struct _queue_data {
    DWORD  dwCreator;
    WORD   wType;
    ATOM   aQueueName;
    short  sElements;
    Q_ELEMENT  elem[QUEUE_LIMIT];
} QUEUE_DATA;
typedef QUEUE_DATA *PQUEUE_DATA;

#else

typedef DWORD  HQUEUE;
typedef HQUEUE *PHQUEUE;

#endif

/************************************************************************\
*                         FLAGS
\************************************************************************/

/************************************************************************\
*                         FUNCTION PROTOTYPES
\************************************************************************/
VOID    MyAssertBox( const char *, const char *, const char *, int);

BOOL    QueueEntry (HANDLE hDLL, DWORD dwReason, LPVOID lpReserved);
BOOL attach_ctl();
BOOL IsValidHqueue( HQUEUE hqueue);
DWORD CreateQueue( PHQUEUE phq, int fQueueOrder, LPTSTR pszName);
DWORD CloseQueue( HQUEUE hq);
DWORD OpenQueue(LPDWORD ppid, PHQUEUE phq, LPTSTR pszName);
void push_down( int iIndex, int jj);
void push_up( int iIndex, int jj);
DWORD WriteQueue(HQUEUE hq, DWORD dwEventCode, HGLOBAL dwShrHandle, DWORD dwPriority);
DWORD ReadQueue(HQUEUE hq, PQ_ELEMENT pqe, int iElement, BOOL fWait);
DWORD QueryQueue(HQUEUE hq, LPINT piElement);
HANDLE GetQueueEventHandle( HQUEUE hqueue);
DWORD  ShrFree(DWORD);
DWORD PeekQueue(HQUEUE hq, PQ_ELEMENT pqe, int *piElement, BOOL fWait);
DWORD QueryQueue(HQUEUE hq, LPINT piElements);


#endif // QUEUE_DLL_H
