|
|
#ifndef _INC_IFAXOS
#define _INC_IFAXOS
#ifdef __cplusplus
extern "C" { #endif
// add SHIP_BUILD from Win95fax retail builds
#ifndef DEBUG
#ifdef WIN32
#define SHIP_BUILD
#endif
#endif
// -------------------------- Include Files ------------------------------------
#ifdef IFBGPROC
// Remove appropriate parts of windows.h
// #define NOKERNEL
#ifndef WANTGDI
#define NOGDI
#endif
// #define NOUSER
#define NOSOUND
// #define NOCOMM
// #define NODRIVERS
// #define NOMINMAX
// #define NOLOGERROR
// #define NOPROFILER
// #define NOMEMMGR
// #define NOLFILEIO
// #define NOOPENFILE
// #define NORESOURCE
// #define NOATOM
// #define NOLANGUAGE
// #define NOLSTRING
// #define NODBCS
#define NOKEYBOARDINFO
#define NOGDICAPMASKS
#define NOCOLOR
#ifndef WANTGDI
#define NOGDIOBJ
#define NOBITMAP
#endif
#define NODRAWTEXT
#define NOTEXTMETRIC
#define NOSCALABLEFONT
#define NORASTEROPS
#define NOMETAFILE
#define NOSYSMETRICS
#define NOSYSTEMPARAMSINFO
// #define NOMSG
#define NOWINSTYLES
#define NOWINOFFSETS
// #define NOSHOWWINDOW
#define NODEFERWINDOWPOS
#define NOVIRTUALKEYCODES
#define NOKEYSTATES
#define NOWH
#define NOMENUS
#define NOSCROLL
#define NOCLIPBOARD
#define NOICONS
#define NOMB
#define NOSYSCOMMANDS
#define NOMDI
#define NOCTLMGR
#define NOWINMESSAGES
#define NOHELP
#endif
// put strict type checking on ... and get rid of multiple define warnings
#ifndef STRICT
#define STRICT
#endif
#ifndef WINDRV
# ifdef WIN32
# define _INC_OLE
# endif
# include <windows.h>
# ifdef WIN32
# include <windowsx.h>
# endif
#endif
#ifdef WIN32
#define DECLSPEC_IMPORT __declspec(dllimport)
#endif
#ifndef WIN32
// Define WINBASE to avoid mapi including some duplicate definitions
#define _WINBASE_
#endif
//-------------------------- General Defines ---------------------
#ifndef WIN32
#define STATIC static
#define CONST const
#define CHAR char
#define UCHAR BYTE
#define INT int
typedef short SHORT; typedef unsigned long ULONG; typedef unsigned short USHORT; typedef CHAR *PCHAR; typedef VOID *PVOID; #endif
typedef CHAR FAR *LPCHAR; typedef CHAR NEAR *NPCHAR;
#define CARRAIGE_RETURN 0x0D
#define LINEFEED 0x0A
#define BACKSPACE 0x08
#define CNULL 0x00
#ifndef WIN32
#ifndef MAKEWORD
# define MAKEWORD(low, high) ((WORD)(((BYTE)(low)) | (((WORD)((BYTE)(high))) << 8)))
#endif
# define EXPORT_DLL
# define IMPORT_DLL
#else
# ifndef HTASK
# define HTASK HANDLE
# endif
# define __export __declspec( dllexport )
# define _export __declspec( dllexport )
# define IMPORT_DLL __declspec( dllimport )
# define EXPORT_DLL __declspec( dllexport )
#endif
// --------------- RESOURCE management -------------------------------
// Always define this for now ...
#ifndef SHIP_BUILD
// #if defined(VALIDATE) || defined(DEBUGAPI) || defined(DEBUG)
/********
@doc EXTERNAL RESOURCE IFAXOS
@type VOID | RESOURCE_ALLOC_FLAGS | Lists the resource management options for OS resource accounting.
@emem RES_ALLOC_TASK | This flag indicates that the resource in question is being allocated on behalf of the current process. The resource should not be directly passed on to any other process context. It should be freed by this process before termination - else the kernel will free it when the process dies (if running in debug). Ownership automatically gets transferred between tasks when standard IPC methods like pipes are used to transfer resources like Buffers.
@emem RES_ALLOC_NONE | This flag is used to allocate resources which should not be accounted to any system module. The calling party essentially undertakes full responsibility for freeing this object. This is mainly to be used for resource allocated on behalf of messages in the store since their ownership is transferred to the current process which has the message open.
@emem HINSTANCE_DLL | If the allocated resource is to be assigned to the calling DLL, the hinstance of the DLL should be passed in as the value of the ResourceFlags Word. These resources will be freed (in the debug version) when the DLL terminates. They will not be assigned to any particular process context.
@xref <f IFBufAlloc> <f IFMemAlloc> <f CreateMutex> <f CreateEvent> <f IFPipeCreate> <f IFProcSetResFlags> ********/
#define RES_ALLOC_TASK 0x0000
#define RES_ALLOC_NONE 0x0001
#define RES_ALLOC_INTERNAL 0x0002
#define RES_ALLOC_CRITSEC 0x0003
#if defined(WFW) || defined(WIN32)
#define IFProcSetResFlags(wResFlags) (0)
#else
extern EXPORT_DLL VOID WINAPI IFProcSetResFlags(WORD wResFlags);
#endif
#else
#define IFProcSetResFlags(p1) (0)
#endif
// --------------- ERROR Handling ------------------------------------
#include <errormod.h>
/********
@doc EXTERNAL ERROR IFAXOS
@api DWORD | IFErrAssemble | Forms an IFAX Error dword out of its components.
@parm BYTE | bProcessID | Identifies the process in whose context the error occured. Must be one of the predefined system process ID's - see <t SYSTEM_PROCESSES> for the list. This field does not need to be filled in until an error is propagated across a process boundary. If not being set to a valid PROCID, this should be initilialized to one of the following values: @flag PROCID_WIN32 | if <p bModuleID> is set to MODID_WIN32. @flag PROCID_NONE | for all other cases.
@parm BYTE | bModuleID | Identifies the module reporting the error. MUST be one of the predefined system module ID's - see <t SYSTEM_MODULES> for the list.
@parm WORD | wApiCode | Identifies the API code for the error in the module indicated by <p bModuleID>. All Api codes should be defined in the file errormod.h. Api codes should be defined so that the low 6 bits are zero. This allows both the <p wApiCode> and the <p wErrorCode> to be logical OR'ed together and stored as a single word.
@parm WORD | wErrorCode | Identifies the error code. The format of this is module dependent. For uniformity however, it is highly encouraged that all IFAX modules use a standard format for this error word. This standard format reserves the first 6 bits for an error code, and the high 10 bits for an API identifier.
If the IFAX format is being used, the <p wApiCode> parameter should be used to pass in the high 10 bits, and the <p wErrorCode> (This parameter!) should be used to pass in the 6 bit error code. Values upto ERR_FUNCTION_START are reserved for standard system errors - see <t SYSTEM_ERROR_VALUES> for the list. Error values should be positive and less than 64.
Other modules like the filesystem conform completely to the Win32 Error space. These should set <p wErrorCode> to standard Win32 errors (use all 16 bits) and leave the <p wApiCode> as API_WIN32.
Still others need to use all 16 bits in a custom manner - like the Printer Drivers. These *must* set the <p bModuleID> correctly so that the error can be interpreted appropriately. Standard processes like the UI have to understand these error codes, so only inbuilt system modules which they have knowledge about can use custom codes. These should set the wApiCode to API_NONE.
@rdesc Returns the DWORD representation for this error. This allows this to be directly passed in as input to <f SetLastError>.
@ex Example usage |
SetLastError(IFErrAssemble(PROCID_NONE,MODID_IFKERNEL,API_IFK_POSTMESSAGE,ERR_INVALID_PARAM));
@xref <f IFErrGetModule> <f IFErrGetProcess> <f GetIFErrorErrcode> <f SetLastError> <f GetIFErrorApicode> <t SYSTEM_MODULES> <t SYSTEM_PROCESSES> <t SYSTEM_ERROR_VALUES> <f GetLastError> <f IFNVRamSetError> <f GetIFErrorCustomErrcode> ********/
#define IFErrAssemble(process,module,call,error) \
MAKELONG((WORD)call|(WORD)error, MAKEWORD((BYTE)module, (BYTE)process))
/*********
@doc EXTERNAL ERROR IFAXOS
@api BYTE | IFErrGetModule | Retrieves the module ID from an IFAX Error.
@parm DWORD | errvar | The error value.
@rdesc Returns the module ID. This will be from the list specified in <t SYSTEM_MODULES>.
@xref <f IFErrAssemble> <t SYSTEM_MODULES> <f IFErrSetModule>
@api BYTE | IFErrGetProcess | Retrieves the process ID from an IFAX Error.
@parm DWORD | errvar | The error value.
@rdesc Returns the process ID. This will be from the list specified in <t SYSTEM_PROCESSES>.
@xref <f IFErrAssemble> <t SYSTEM_PROCESSES> <f IFErrSetProcess>
@api WORD | GetIFErrorErrcode | Retrieves the error code from an IFAX Error.
@parm DWORD | errvar | The error value.
@rdesc Returns the error code. If less than ERR_FUNCTION_START, this is from the list in <t SYSTEM_ERROR_VALUES>.
@xref <f IFErrAssemble> <t SYSTEM_ERROR_VALUES>
@api WORD | GetIFErrorCustomErrcode | Retrieves a custom 16 bit error code from an IFAX Error.
@parm DWORD | errvar | The error value.
@rdesc Returns the error code. This might be a Win32 error code if the module ID was MODID_WIN32, or a custom error code.
@xref <f IFErrAssemble> <t SYSTEM_ERROR_VALUES>
@api WORD | GetIFErrorApicode | Retrieves the API code from an IFAX Error.
@parm DWORD | errvar | The error value.
@rdesc Returns the API code. API codes for all the system modules are documented in the file errormod.h
@xref <f IFErrAssemble> <t SYSTEM_MODULES>
@api DWORD | IFErrSetModule | Sets the module ID in an IFAX Error.
@parm DWORD | errvar | The error value. It's value is not changed by the call.
@parm BYTE | bModule | The module ID to be set from the list in <t SYSTEM_MODULES>.
@rdesc Returns the DWORD representation of the new error code.
@xref <f IFErrAssemble> <t SYSTEM_MODULES> <f IFErrGetModule>
@api DWORD | IFErrSetProcess | Sets the Process ID in an IFAX Error.
@parm DWORD | errvar | The error value. Its value is not changed by the call.
@parm BYTE | bProcess | The Process ID to be set from the list in <t SYSTEM_PROCESSES>.
@rdesc Returns the DWORD representation of the new error code.
@xref <f IFErrAssemble> <t SYSTEM_PROCESSES> <f IFErrGetProcess>
********/ #define IFErrSetModule(errvar,module) \
MAKELONG(LOWORD((DWORD)errvar),MAKEWORD((BYTE)module, HIBYTE(HIWORD((DWORD)errvar)))) #define IFErrSetProcess(errvar,process) \
MAKELONG(LOWORD((DWORD)errvar),MAKEWORD(LOBYTE(HIWORD((DWORD)errvar)), (BYTE)process)) #define IFErrGetModule(errvar) LOBYTE(HIWORD((DWORD)errvar))
#define IFErrGetProcess(errvar) HIBYTE(HIWORD((DWORD)errvar))
#define GetIFErrorErrcode(errvar) (LOWORD((DWORD)errvar) & 0x003F)
#define GetIFErrorApicode(errvar) (LOWORD((DWORD)errvar) & 0xFFC0)
#define GetIFErrorCustomErrcode(errvar) LOWORD((DWORD)errvar)
/********
@doc EXTERNAL DEFINES ERROR IFAXOS
@type VOID | SYSTEM_MODULES | Identifiers for all the standard system modules.
@emem MODID_NONE | Use this if you are not setting the module ID. DONT USE ZERO !! @emem MODID_WIN32 | Set for modules returning standard Win32 system error codes @emem MODID_BOSS | ID = 1 Error in BOSS @emem MODID_WINMODULE | ID = 2 All windows modules including UER/GDI/KERNEL @emem MODID_IFKERNEL | ID = 3 @emem MODID_IFFILESYS | ID = 4 @emem MODID_MSGSTORE | ID = 5 @emem MODID_LINEARIZER | ID = 6 @emem MODID_SECURITY | ID = 7 @emem MODID_IFPRINT | ID = 8 High level Printer Driver @emem MODID_IFSCAN | ID = 9 High level Scanner Driver @emem MODID_IFSIPX | ID = 10 SPX/IPX Stack @emem MODID_REND_SERVER | ID = 11 Rendering Server @emem MODID_FORMAT_RES | ID = 12 Format Resolution @emem MODID_IFFILE | ID = 13 IFFiles @emem MODID_TEXTRENDERER | ID = 14 Ascii Renderer @emem MODID_DIGCOVPAGE | ID = 15 Digital Coverpage @emem MODID_AWBRANDER | ID = 16 Fax Brander @emem MODID_MSGSVR | ID = 17 Message Server @emem MODID_MSGHNDLR | ID = 18 Per-Connection message handler @emem MODID_MODEMDRV | ID = 19 Modem driver @emem MODID_PSIFAX | ID = 20 PSI Fax protocol @emem MODID_AWT30 | ID = 21 @emem MODID_PSIFAXBG | ID = 22 @emem MODID_AWNSF | ID = 23 @emem MODID_FAXCODEC | ID = 24 @emem MODID_MSGPUMP | ID = 25 @emem MODID_AWREPORT | ID = 26 @emem MODID_MSGSVRD | ID = 27
@emem MODID_CUSTOM | ID = 160 Beyond this are custom/installable modules
@xref <f IFErrAssemble> <f IFErrGetModule> ********/ // System Module IDs
#define MODID_WIN32 0
#define MODID_BOSS 1
#define MODID_WINMODULE 2
#define MODID_IFKERNEL 3
#define MODID_IFFILESYS 4
#define MODID_MSGSTORE 5
#define MODID_LINEARIZER 6
#define MODID_SECURITY 7
#define MODID_IFPRINT 8
#define MODID_IFSCAN 9
#define MODID_IFSIPX 10
#define MODID_REND_SERVER 11
#define MODID_FORMAT_RES 12
#define MODID_IFFILE 13
#define MODID_TEXTRENDERER 14
#define MODID_DIGCOVPAGE 15
#define MODID_AWBRANDER 16
#define MODID_MSGSVR 17
#define MODID_MSGHNDLR 18
#define MODID_MODEMDRV 19
#define MODID_PSIFAX 20
#define MODID_AWT30 21
#define MODID_PSIFAXBG 22
#define MODID_AWNSF 23
#define MODID_FAXCODEC 24
#define MODID_MSGPUMP 25
#define MODID_AWREPORT 26
#define MODID_MSGSVRD 27
#define MAXMODID 26
#define MODID_NONE 159
// Special module ID's
#define MODID_CUSTOM 160
// Strings used in debug version for friendly display
#define SYSMODULESTRINGS \
{ "Win32", "Boss", "Windows", "IFKernel", "FileSystem", "Msg Store", "Linearizer", \ "Security", "HLPrintDriver", "HLScanDriver", "IPX/SPX", "RendServer", \ "Format Res", "IFFile", "AsciiRenderer","DigCovPage","AWBrander", \ "Msg Server", "Msg Handler", "Modem Driver", "PSIFAX", "AWT30", \ "PSIFAXBG", "AWNSF", "Fax Codec", "Msg Pump" , "Awreport" \ }
/********
@doc EXTERNAL DEFINES ERROR IFAXOS
@type VOID | SYSTEM_PROCESSES | Identifiers for all the standard system processes.
@emem PROCID_WIN32 | Used to initialize for Win32 modules. @emem PROCID_NONE | Used when process context does not need to be set. @emem PROCID_MSGSCHED | ID = 0x21 @emem PROCID_JOBPROCESS | ID = 0x22 @emem PROCID_UI | ID = 0x23 @emem PROCID_PRINTER | ID = 0x24 @emem PROCID_SCANNER | ID = 0x25 @emem PROCID_MSGSVR | ID = 0x26 @emem PROCID_GRRENDER | ID = 0x27 @emem PROCID_MSGHNDLR | ID = 0x28 @emem PROCID_PARADEV | ID = 0x29 @emem PROCID_UIBGPROC | ID = 0x30
@comm All Process ID's need to have the 6th bit set to be compatible with the standard Win32 error definitions.
@xref <f IFErrAssemble> <f IFErrGetProcess> ********/ // System Process IDs
#define PROCID_WIN32 0x00
#define PROCID_NONE 0x20
#define PROCID_MSGSCHED 0x21
#define PROCID_JOBPROCESS 0x22
#define PROCID_UI 0x23
#define PROCID_PRINTER 0x24
#define PROCID_SCANNER 0x25
#define PROCID_MSGSVR 0x26
#define PROCID_GRRENDER 0x27
#define PROCID_MSGHNDLR 0x28
#define PROCID_PARADEV 0x29
#define PROCID_UIBGPROC 0x30
// Strings used in debug version for friendly display
#define MAXPROCID 11
#define SYSPROCESSSTRINGS \
{"None", "Msg Scheduler", "Job Process", "UI Process", "Printer", "Scanner", \ "Msg Transport", "GR Renderer", "Msg Handler", "Para Dev", "UIBGProc" }
/********
@doc EXTERNAL DEFINES ERROR IFAXOS
@type VOID | SYSTEM_ERROR_VALUES | This defines all the standard system error values.
@emem ERR_NOT_ENOUGH_MEM | Value = 0x0001 : Indicates an out of memory condition.
@emem ERR_INVALID_PARAM | Value = 0x0002 : Indicates that any one of the parameters passed to the function was invalid.
@emem ERR_FUNCTION_START | Value = 0x0010 : Any error value above this had been custom defined by the called function. If you need a custom error value, you can define it starting from this value.
@xref <f IFErrAssemble> ********/
// System Error values
#define ERR_NOT_ENOUGH_MEM 0x0001
#define ERR_INVALID_PARAM 0x0002
#define ERR_FUNCTION_START 0x0010
// Strings used in debug version for friendly display
#define SYSERRORSTRINGS \
{"None", "Out Of Memory", "Invalid Param", "Unused", "Unused", "Unused", \ "Unused", "Unused", "Unused", "Unused", "Unused", "Unused", \ "Unused", "Unused", "Unused", "Unused" }
// Functions
#if !defined(SHIP_BUILD) && !defined(WIN32)
VOID WINAPI RestoreLastError (DWORD dwErrVal); #else
#define RestoreLastError(dw) SetLastError(dw)
#endif
#ifndef WIN32
VOID WINAPI SetLastError (DWORD dwErrVal); DWORD WINAPI GetLastError (VOID); #endif
//----------------------------- MESSAGING -------------------------
// Message type definitions - below 0x0400 is reserved by windows,
// between 0x0400 and 0x0800 is reserved by the IFAX OS
#define IF_START WM_USER+0x0300
#define IF_TASK_START IF_START+0x0001
#define IF_TASK_END IF_START+0x0020
#define IF_DEBUG_START IF_START+0x0021
#define IF_DEBUG_END IF_START+0x0040
#define IF_PIPES_START IF_START+0x0041
#define IF_PIPES_END IF_START+0x0060
#define IF_TIMER_START IF_START+0x0081
#define IF_TIMER_END IF_START+0x0090
#define IF_USER IF_START+0x0400
//messages for printer and scanner
#define IF_SCANNER_START IF_START+0x0200
#define IF_SCANNER_END IF_START+0x0220
//messages for the graphics renderer
#define IF_GRRENDER_START IF_START+0x0221
#define IF_GRRENDER_END IF_START+0x0230
//messages for the faxcodec renderer
#define IF_FAXREND_START IF_START+0x0231
#define IF_FAXREND_END IF_START+0x0235
//messages for the message pump
#define IF_MSGPUMP_START (IF_START+0x0250)
#define IF_MSGPUMP_END (IF_START+0x029F)
//messages for devices
#define IF_DEVICE_START (IF_START+0x02B0)
#define IF_DEVICE_END (IF_START+0x02CF)
// Message for UI Init
#define IF_UI_START (IF_START+0x2F0)
#define IF_UI_END (IF_START+0x300)
// Status
#define IF_STATUS_START (IF_START+0x301)
#define IF_STATUS_END (IF_START+0x310)
// Config
#define IF_CONFIG_START (IF_START+0x311)
#define IF_CONFIG_END (IF_START+0x320)
// Modem
#define IF_MODEM_START (IF_START+0x321)
#define IF_MODEM_END (IF_START+0x325)
// PSIBG
#define IF_PSIBG_START (IF_START+0x330)
#define IF_PSIBG_END (IF_START+0x339)
// PSIFAX
#define IF_PSIFAX_START (IF_START+0x340)
#define IF_PSIFAX_END (IF_START+0x349)
// MSGSVR
#define IF_MSGSVR_START (IF_START+0x350)
#define IF_MSGSVR_END (IF_START+0x369)
// OEM
#define IF_OEM_START (IF_START+0x370)
#define IF_OEM_END (IF_START+0x379)
// SOS
#define IF_SOS_START (IF_START+0x380)
#define IF_SOS_END (IF_START+0x38F)
// uiutil
#define IF_UU_START (IF_START+0x390)
#define IF_UU_END (IF_START+0x39F)
// parallel device
#define IF_PD_START (IF_START+0x3A0)
#define IF_PD_END (IF_START+0x3BF)
// RPC layer
#define IF_RPC_START (IF_START+0x3C0)
#define IF_RPC_END (IF_START+0x3CF)
//UIBGProc
#define IF_UIBGPROC_START (IF_START+0x3D0)
#define IF_UIBGPROC_END (IF_START+0x3DF)
// services
#define IF_SERVICE_START (IF_START+0x3E0)
#define IF_SERVICE_END (IF_START+0x3EF)
/********
@doc EXTERNAL MESSAGES PROCESS IFAXOS
@msg IF_INIT_STATUS | This message should be posted by all devices after initialization is complete to indicate success/failure. Typically, the device process will send an IF_INIT_STATUS message for every device it initializes and one for its own initilization. This message should be posted to the UISHELL process. Use <f IFProcGetInfo> to obtain the appropriate window handle.
@parm WPARAM | wParam | 16 bit device error. @parm LPARAM | lParam | Is formed as MAKELPARAM(MAKEWORD (ucInitStatus,ucMinorDevId),MAKEWORD(ucMajorDevId,ucProcId)) @flag INIT_NO_ERROR | There was no error. @flag INIT_FATAL_ERROR| There was a fatal error. System should reboot. @flag INIT_WARNING_ERROR | There were some errors, but the system doesnt need to reboot.
@parm LPARAM | lParam | Contains a standard IFAX Error code. See <f IFErrAssemble> for details.
@xref <f IFProcGetInfo> <f IFErrAssemble> ********/ #define INIT_NO_ERROR 0x00
#define INIT_FATAL_ERROR 0x01
#define INIT_WARNING_ERROR 0x02
#define IF_INIT_STATUS IF_UI_START
/********
@doc EXTERNAL MESSAGES PROCESS IFAXOS @msg IF_DEVREINIT | This message will be posted by the uishell to device process that handle user errors if the initialization fails due to user errors.
@parm WPARAM | wParam | MAKEWORD(ucMinorDevId,ucMajorDevId)
@xref <f IFProcGetInfo> <f IFErrAssemble> ********/
#define IF_DEVREINIT IF_UI_START+1
// Functions --------
BOOL WINAPI BroadcastMessage (UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL WINAPI BroadcastMessageEx (UINT uMsg, WPARAM wParam, LPARAM lParam);
// Dispatch message for BG Procs
/********
@doc EXTERNAL MESSAGE MACROS IFAXOS
@api VOID | DispatchMessage | Dispatches a message to your windows procedure.
@parm LPMSG | lpMsg | Ptr to a message struct which is to be dispatched. This parameter *must* be &msg for all IFAX background processes - i.e you must have a declared variable called "msg" into which you have previsouly retrieved the message using <f GetMessage>.
@comm This function dispatches a message to your windows procedure. For foreground processes this works exactly the way the standard Windows DispatchMessage works. For background processes (which dont have any explicit windows) the message is sent to a procedure called BGWindowProc. You *must* have a callback defined as this - see BGWindowProc for details.
@cb LRESULT BGCALLBACK | BGWindowProc | This is the window procedure for all IFAX background processes. The functions *must* be called by this exact name. This callback is not relevant for foreground processes.
@parm HWND | hwnd | contains the handle of the window to which the message is being dispatched. For Background processes this will always be the same as that returned from <f IFProcGetInfo>.
@parm UINT | message | the message id
@parm WPARAM | wParam | the first parameter associated with the message
@parm LPARAM | lParam | The second parameter associated with the message
@rdesc The return value depends on the message being processed.
@comm A protoype for this is already declared in ifaxos.h. You should process all your messages inside this window procedure. Your main application loop should thus look like
while (GetMessage(&msg,NULL,0,0)) { DispatchMessage(&msg); } return;
You should *not* export this procedure in your .def file.
@xref <f GetMessage> ********/
#ifdef IFBGPROC
#define DispatchMessage(pmsg) BGWindowProc((pmsg)->hwnd,(pmsg)->message,(pmsg)->wParam,(pmsg)->lParam)
#define BGCALLBACK PASCAL
LRESULT BGCALLBACK BGWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); #endif
//----------------------------- TASK MANAGEMENT--------------------
/********
@doc EXTERNAL PROCESS MACROS IFAXOS
@api VOID | ENTER_INT_CRIT_SECTION | Macro to enter an interrupt critical section.
@comm This is an inline assembly macro which turns interrupts off. Needless to say, this must be used with extreme caution. There must be a matching call to <f EXIT_INT_CRIT_SECTION>. Nested pairs of calls to these are permitted as long as they are not within the same invocation of the function. The function relies on being able to save the previous state of the flags in a unique local variable called __wIntFlags. This might affect some optimization options in your function due to being inline assembly. You might want to declare a local function which calls this macro internally. This way you can get global optimzations in the calling functions.
@xref <f EXIT_INT_CRIT_SECTION> <f IFProcEnterCritSec> <f IFProcExitCritSec> ********/
// Macros --------
#define ENTER_INT_CRIT_SECTION \
{ \ _asm pushf \ _asm cli \ _asm pop __wIntFlags \ }
/********
@doc EXTERNAL PROCESS MACROS IFAXOS
@api VOID | EXIT_INT_CRIT_SECTION | Macro to exit an interrupt critical section.
@comm This is an inline assembly macro which sets the interrupt flag state back to its state before the last call to <f ENTER_INT_CRIT_SECTION>. This function relies on the appropriate flags to have been saved in a local variable with the name __wIntFlags.
@xref <f ENTER_INT_CRIT_SECTION> <f IFProcEnterCritSec> <f IFProcExitCritSec> ********/
// defined this way so that it works with windows enhanced mode
// refer guide to programming pg 14-15
#define EXIT_INT_CRIT_SECTION \
{ \ _asm mov ax, __wIntFlags \ _asm test ah,2 \ _asm jz $+3 \ _asm sti \ _asm NOP \ }
/********
@doc EXTERNAL DEFINES ERROR IFAXOS
@type VOID | PRIORITY DEFINES | System defined priority levels @emem PROC_PRIORITY_CRITICALRT | This should be used very sparingly for tasks which have very critical real time constraints (less than 200ms). These processes should typically be very low bandwidth since they can easily starve other processes. @emem PROC_PRIORITY_HIGHRT | Tasks with latency requirements of less than a second. Should not be high bandwidth to avoid starvation of processes. @emem PROC_PRIORITY_MEDRT | Tasks with latency requirements of 1-3 secs. Should not be high bandwidth to avoid starvation of processes. @emem PROC_PRIORITY_LOWRT | Tasks with latencies of 3-30secs. Should not be high bandwidth. @emem PROC_PRIORITY_DEFAULT | The default priority tasks start out at. These processes have none or very low real time requirements. They should in general not have high bandwidth. @emem PROC_PRIORITY_NONRT_USERVISIBLE | Non real time tasks which have visibility at the user level. Can be high bandwidth. An example on a fax machine is a copy job. @emem PROC_PRIORITY_NONRT_USERHIDDEN | Non real time tasks which have very little visibility at the user level. Examples on a fax machine are local jobs not involving devices. Can be high bandwidth. @comm Processes should be VERY careful in setting their priorities. The way the current scheduling works it is very easy to cause starvation of low priority processes. In particular, processes which are "high bandwidth" - ie those which can consume huge amounts of CPU time if given, should be very careful - and should in general be at a priority level lower than the default. Processes higher than the default should have some sontrols on how much cpu time they can use up. On the fax machine, such controls are mostly in the form of device througputs - like the phone line. @xref <f IFProcSetPriority> <f IFProcGetPriority> ********/ #define PROC_PRIORITY_MIN 31
#define PROC_PRIORITY_MAX 1
#define PROC_PRIORITY_CRITICALRT 3
#define PROC_PRIORITY_HIGHRT 6
#define PROC_PRIORITY_MEDRT 9
#define PROC_PRIORITY_LOWRT 12
#define PROC_PRIORITY_DEFAULT 15
#define PROC_PRIORITY_NONRT_USERVISIBLE 18
#define PROC_PRIORITY_NONRT_USERHIDDEN 21
#define UAE_BOX 0
#define NO_UAE_BOX 1
///// Specific priorities used by standard processes ////
//
// We want the following relations to hold
// PSIFAXBG > everything else, cause it's low-latency, low-bandwidth
// ModemJob related (med bandwidth) > all other high/med bandwith jobs
// DeviceJob related (high bandwidth, NO latency reqs) < all other jobs except Spool jobs
// SpoolJobs (high bandwidth NO latency reqs, not user-visible) < everything
// MSCHED is as high as ModemJob prio when it is on critical path, otherwise
// it stays at default. Higher than Dev & Spool jobs, lower than all else
// COMMSRV (pretty low latency reqs, high bandwidth) is slightly higher than
// default (Higher than MSCHED & Dev/Spool jobs, lower than modem jobs)
// RPCHNDLR (pretty lax latency reqs, high bandwidth) dynamic
// Same prio as MSCHED while working, same as COMMSRV during accept
// MSGSVR & RPCSRV (lowish latency reqs, very low bandwidth) roundrobin
// with ModemJob, higher than all else
// REPORT bg proc slightly lower than default.
// PSIFAXBG prio is highest
#define PRIO_PSIFAXBG_ACTIVE PROC_PRIORITY_CRITICALRT
#define PRIO_PSIFAXBG_IDLE PROC_PRIORITY_DEFAULT
// ModemJob is 2nd highest
#define PRIO_MODEMJOB PROC_PRIORITY_MEDRT
// Spooljob is LOWEST, Device jobs are second lowest
#define PRIO_SPOOLJOB PROC_PRIORITY_NONRT_USERHIDDEN
#define PRIO_DEVICEJOB PROC_PRIORITY_NONRT_USERVISIBLE
// PSINET jobs are same prio as SPOOL jobs
#define PRIO_PSINETJOB PRIO_SPOOLJOB
// MSCHED's prio when it is NOT on a MODEMJOB critical path
#define PRIO_MSCHED PROC_PRIORITY_DEFAULT
// COMMSRV is between MODEMJOB & MSCHED
#define PRIO_COMMSRV PROC_PRIORITY_LOWRT
// RPCHNDLR is same as MSCHED while working
#define PRIO_RPCHNDLR_ACCEPT PROC_PRIORITY_LOWRT
#define PRIO_RPCHNDLR_WORKING PROC_PRIORITY_DEFAULT
// RPCSRV is same as MODEMJOB. It should NOT consume much CPU at this level!
#define PRIO_RPCSRV PROC_PRIORITY_MEDRT
// MSGSVR is same as MODEMJOB, except when processing recovery msgs
#define PRIO_MSGSVR_WAITMSG PROC_PRIORITY_MEDRT
#define PRIO_MSGSVR_RECOVERY PROC_PRIORITY_NONRT_USERVISIBLE
// Report process is real low prio when doing background info assimilation
// slightly higher when doing work on user request.
#define PRIO_UIBGPROC PROC_PRIORITY_NONRT_USERHIDDEN
#define PRIO_UIBGPROC_USERREQUEST PROC_PRIORITY_NONRT_USERVISIBLE
/********
@doc EXTERNAL MESSAGES PROCESS IFAXOS
@msg IF_QUIT | This is the message which forces <f GetMessage> to return FALSE causing the process to exit its main message processing loop and terminate. Typically a process should post itself this message in response to a <m IF_EXIT> message.
@parm WPARAM | wParam | NULL
@parm LPARAM | lParam | NULL
@rdesc none
@xref <m IF_EXIT>
@msg IF_EXIT | This message is sent to a process to request it to terminate. An application should clean up any resources it has allocated and then post itself a <m IF_QUIT> message directly.
@parm WPARAM | wParam | NULL
@parm LPARAM | lParam | NULL
@rdesc none
@xref <m IF_QUIT> ********/
// Messages
#define IF_QUIT IF_TASK_START
#define IF_EXIT IF_TASK_START+1
// Functions -----------
#ifndef WIN32
HTASK WINAPI GetWindowTask(HWND hwnd); #ifndef SHIP_BUILD
DWORD WINAPI IFProcProfile(HTASK hTask, BOOL fStart); #else
#define IFProcProfile(HTASK,FSTART) (0)
#endif
#else
// Remove calls to Profile ..
#define IFProcProfile(x,y) (DWORD)(0)
#endif
HTASK WINAPI IFProcCreate (LPSTR lpszAppName, UINT fuCmdShow); VOID WINAPI IFProcTerminate (HTASK hTask, WORD wFlags); VOID WINAPI IFProcEnterCritSec(VOID); VOID WINAPI IFProcExitCritSec(VOID); BOOL WINAPI IFProcChangeToFG(VOID); BOOL WINAPI IFProcChangeToBG(VOID); HWND WINAPI IFProcGetInfo (HTASK FAR *lphTask, LPSTR lpszModule, HINSTANCE FAR *lphInst); BOOL WINAPI IFProcRegisterWindow (HWND hwnd); WORD WINAPI IFProcGetPriority (HTASK hTask); BOOL WINAPI IFProcSetPriority (HTASK hTask, WORD wPriority);
#ifndef NOBUFFERS
//----------------------------- BUFFERS -------------------------
// Moved BUFFER typedef and standard meta-data values to buffers.h! -RajeevD
#include <buffers.h>
#ifdef VALIDATE
#define BUF_SENTINELPOS 30
#endif
// Error values
#define ERR_DATA_SMALL ERR_FUNCTION_START
// Functions
extern LPBUFFER IFBufAlloc (LONG lBufSize); extern BOOL IFBufFree (LPBUFFER lpbf); extern EXPORT_DLL LPBUFFER WINAPI IFBufMakeWritable (LPBUFFER lpbf); extern EXPORT_DLL LPBUFFER WINAPI IFBufShare (LPBUFFER lpbf); extern EXPORT_DLL LPBUFFER WINAPI IFBufSplit (LPBUFFER lpbf, LPBYTE lpb);
//----------------------------- PIPES ----------------------------
#ifndef WIN32
// types
typedef struct _PIPE NEAR *HPIPE;
// Parameter
#define IFPIPE_READ_MODE 0x0001
#define IFPIPE_WRITE_MODE 0x0002
#define REQREAD_REMOVE_DATA 0x0003
#define REQREAD_NOREMOVE_DATA 0x0004
// Error values
#define ERR_TOO_MANY_OPENS ERR_FUNCTION_START
#define ERR_TOO_MANY_PENDING_WRITES ERR_FUNCTION_START+1
#define ERR_PIPE_STILL_OPEN ERR_FUNCTION_START+2
/********
@doc EXTERNAL MESSAGES IFPIPES IFAXOS
@msg IF_PIPE_DATA_WRITTEN | This message is sent to notify a process that a previous write request using <f IFPipeReqWrite> has been successfully concluded. On reciept of this message the process can issue another write request on the same pipe.
@parm WPARAM | wParam | The <p wContext> parameter passed to the <f IFPipeOpen> call.
@parm LPARAM | lParam | NULL
@rdesc none
@xref <f IFPipeReqWrite>
@msg IF_PIPE_DATA_ARRIVED | This message is sent to a process which previsouly issued a read request to a pipe, intimating it that the buffer it requested is now available.
@parm WPARAM | wParam | The <p wContext> parameter passed to the <f IFPipeOpen> call.
@parm LPARAM | lParam | Contains a far ptr to a <t BUFFER> structure which has the requested data. On receipt of this message the process can issue another read request on the same pipe.
@rdesc none
@xref <f IFPipeReqRead> ********/
// Messages
#define IF_PIPE_DATA_WRITTEN IF_PIPES_START
#define IF_PIPE_DATA_ARRIVED IF_PIPES_START+1
// Functions
HPIPE WINAPI IFPipeCreate (WORD wSize); BOOL WINAPI IFPipeDelete (HPIPE hpipe); BOOL WINAPI IFPipeOpen (HPIPE hPipe, HWND hwnd, WORD wMode, WPARAM wContext); BOOL WINAPI IFPipeClose (HPIPE hPipe, WORD wMode); BOOL WINAPI IFPipeReqRead (HPIPE hPipe, WORD fwRemove); BOOL WINAPI IFPipeReqWrite (HPIPE hPipe, LPBUFFER lpbf); BOOL WINAPI IFPipeGetInfo (HPIPE hPipe, LPWORD lpwSize, LPWORD lpwcBufs);
#else // !WIN32
DECLARE_HANDLE32(HPIPE);
#endif // !WIN32
#endif // NOBUFFERS
//----------------------------- DEBUG SERVICES -------------------------
// Debug typedefs. These dont do any harm to anyone. Define them if there is
// anyone who might need them.
#if defined(DEBUG) || defined(IFKINTERNAL)
/********
@doc EXTERNAL DATATYPES DEBUG IFAXOS
@types DBGPARAM | Structure containing the debug settings for any module in the system.
@field CHAR[32] | lpszName | Specifies the name of the module. This is how your module will appear in the IFAX controller. Must be less than 32 characters long, and NULL terminated.
@field HWND | hwnd | Specifies the primary window handle associated with this module IF the module is a process. For DLL's this value should always be NULL. Background processes should set it to their own ID using <f IFProcGetInfo> and <f GetCurrentTask> at initialization time. Foreground processes should set it to the window handle of their client window.
@field CHAR[16][32] | rglpszZones | Stores a list of 16 strings which describe the zones associated with the lower 16 bits of zone mask. The module must decide and define its own zones for these bits - any bits not used should be left as "Not Used". These strings will be displayed by the IFAX controller to assist users in choosing the zones to be set for your module. Each string should not be more than 32 characters long, and should be NULL terminated.
@field ULONG | ulZoneMask | This is the mask which stores the current zone settings for the module. The IFAX controller will set this field according to what the user specifies. This field should be initialized to something which makes sense for your module - as that will be the default till the user changes it.
@comm This structure should be passed to <f IFDbgSetParams> at intialization time to enable the user to control the trace options.
**VERY IMPORTANT NOTE** This structure MUST be declared with a variable name of dpCurSettings to allow the system zones to function correctly.
@tagname _DBGPARAM
@xref <f IFDbgSetParams>
********/
typedef struct _DBGPARAM { CHAR lpszName[32]; // name of module
HWND hwnd; // Primary window Handle if task, NULL otherwise
CHAR rglpszZones[16][32]; // names of zones for first 16 bits
ULONG ulZoneMask; // Zone Mask
} DBGPARAM, FAR *LPDBGPARAM;
// Debug functions
BOOL WINAPI IFDbgOut (LPSTR lpszStatus); WORD WINAPI IFDbgIn (LPSTR lpszPrompt, LPSTR lpszReply, WORD wBufSize); extern EXPORT_DLL VOID WINAPI IFDbgSetParams (LPDBGPARAM lpdpParam, BOOL fEntry); extern VOID FAR IFDbgPrintf(LPSTR lpszFmt, ...); extern EXPORT_DLL BOOL WINAPI IFDbgCheck(VOID);
// Encourage people to use the correct variable
extern DBGPARAM dpCurSettings;
// Special UI communication stuff
// Functions
DWORD WINAPI DebugUIMessage (UINT wMsg, WPARAM wParam, DWORD lParam);
// Messages to the UI proc
#define IF_DISP_STRING IF_DEBUG_START
#define IF_INP_REQUEST IF_DEBUG_START+1
#define IF_NEW_SETTING IF_DEBUG_START+2
#define IF_DEL_SETTING IF_DEBUG_START+3
#define IF_NEW_TASK IF_DEBUG_START+4
#define IF_DEL_TASK IF_DEBUG_START+5
#define IF_FILELOG_POLL IF_DEBUG_START+6
// Messages from the UI proc
#define REGISTER_UI_TASK 1
#define SET_LOG_MODE 2
#define DEBUG_OUT_DONE 3
#define DEBUG_IN_DONE 4
#define DEREGISTER_UI_TASK 5
#endif
// Debug Macros. These should be defined only if the module is being compiled
// in debug
#ifdef DEBUG
/********
@doc EXTERNAL IFAXOS DEBUG MACROS
@api BOOL | DEBUGMSG | Prints a trace message on the debug console depending on enable flags set by the user.
@parm <lt>c_expression<gt> | cond | Boolean condition which is evaluated to decide whether or not to print the message.
@parm <lt>printfexp<gt> | printf_exp | Printf parameters for the message to be displayed. Must be enclosed in a single pair of parentheses.
@rdesc TRUE if the message is printed, and FALSE if it is not.
@comm The condition should consist of a boolean expression testing whether the relevant zones are on or off. Each module has a current zone mask which identifies which of the possible 32 zones is currently on. The top 16 bits of these are reserved for use for system defined zones - like ZONE_FUNC_ENTRY which is defined as
#define ZONE_FUNC_ENTRY (0x00010000&dpCurSettings.ulZoneMask)
Modules should take care to see that they print out trace messages which are meaningful and conform to some pattern - remember that other people than you have to see and make sense of your messages. The general format I have been following is :
<lt>Task ID<gt> : <lt>ModuleName<gt>:<lt>SubModule<gt>:<lt>Function<gt>:<lt>msg<gt>
The task ID is useful to sort out the output of multiple tasks running in the system. The example call above yields this kind of output.
The various predefined system zones are: ZONE_FUNC_ENTRY : To be used for all function entry and exit messages. By convention, the parameters should be printed on entry, and the return value should be printed on exit. Any values printed in hexadecimal should be preceded by a 0x ZONE_INT_FUNC : To be used for any other traces at interesting points within a function.
All trace messages are disabled in a non debug build.
@ex Example Definition & Use |
#define ZONE_CUSTOM (0x00000001&dpCurSettings.ulZoneMask)
DEBUGMSG (ZONE_FUNC_ENTRY && ZONE_CUSTOM, ("0x%04X:IFK:Buffers:GenericFunction:Entry\r\n", GetCurrentTask()));
This will print a trace message only if the user has turned the function entry zone and the custom zone on.
@xref <f IFDbgPrintf> ********/
#if 0
#define DEBUGMSG(cond,printf_exp) \
((cond)?(IFDbgPrintf printf_exp),1:0) #endif
#define DEBUGMSG(cond, printf_exp) \
(IFDbgPrintf printf_exp)
// Standard Debug zones
#define ZONE_FUNC_ENTRY (0x00010000&dpCurSettings.ulZoneMask)
#define ZONE_INT_FUNC (0x00020000&dpCurSettings.ulZoneMask)
/********
@doc EXTERNAL IFAXOS DEBUG MACROS
@api BOOL | ERRORMSG | Prints an error message on the debug console.
@parm <lt>printfexp<gt> | printf_exp | Printf parameters for the message to be displayed. Must be enclosed in a single pair of parentheses.
@comm Should be used to display Error messages.
@ex Example Definition & Use |
ERRORMSG (("0x%04X:JOB Failed !!\r\n", GetCurrentTask()));
This will print a trace message like:
ERROR: Job Process: 0x2346: JOB Failed !!
@xref <f IFDbgPrintf> ********/ #ifndef WIN32
#define ERRORMSG(printf_exp) \
(IFProcEnterCritSec(), \ IFDbgPrintf("ERROR:(0x%04X):%s:",GetCurrentTask(),(LPSTR)(dpCurSettings.lpszName)), \ IFDbgPrintf printf_exp ,\ IFProcExitCritSec(), \ 1) #else
#define ERRORMSG(printf_exp) \
(IFDbgPrintf("ERROR:(0x%08lX):%s:",GetCurrentProcessId(),(LPSTR)(dpCurSettings.lpszName)), \ IFDbgPrintf printf_exp ,\ 1) #endif
/********
@doc EXTERNAL IFAXOS DEBUG MACROS
@api BOOL | RETAILMSG | Prints a message on the debug console even for retail builds.
@parm <lt>printfexp<gt> | printf_exp | Printf parameters for the message to be displayed. Must be enclosed in a single pair of parentheses.
@comm Should be used to display debugging messages which are desired in the retail build. For obvious reasons this should be used sparingly. The benefit is that all such messages can be turned off for the shipping build by simply changing the macro in ifaxos.h
@ex Example Definition & Use |
RETAILMSG (("0x%04X:Scanner Opened !!\r\n", GetCurrentTask()));
This will print a trace message like:
0x4567:Scanner Opened !!
@xref <f IFDbgPrintf> ********/ #define RETAILMSG(printf_exp) (IFDbgPrintf printf_exp)
/********
@doc EXTERNAL IFAXOS DEBUG MACROS
@api BOOL | WARNINGMSG | Prints a warning message on the debug console even for retail builds.
@parm <lt>printfexp<gt> | printf_exp | Printf parameters for the message to be displayed. Must be enclosed in a single pair of parentheses.
@comm Should be used to display debugging messages which are desired in the retail build. For obvious reasons this should be used sparingly. The benefit is that all such messages can be turned off for the shipping build by simply changing the macro in ifaxos.h
@ex Example Definition & Use |
WARNINGMSG (("0x%04X:Scanner Opened !!\r\n", GetCurrentTask()));
This will print a trace message like:
WARNING: 0x4567:Scanner Opened !!
@xref <f IFDbgPrintf> <f ERRORMSG> ********/ #ifndef WIN32
#define WARNINGMSG(printf_exp) \
(IFProcEnterCritSec(), \ IFDbgPrintf("WARNING:(0x%04X):%s:",GetCurrentTask(),(LPSTR)(dpCurSettings.lpszName)), \ IFDbgPrintf printf_exp ,\ IFProcExitCritSec(), \ 1) #else
#define WARNINGMSG(printf_exp) \
(IFDbgPrintf("WARNING:(0x%08lX):%s:",GetCurrentProcessId(),(LPSTR)(dpCurSettings.lpszName)), \ IFDbgPrintf printf_exp ,\ 1) #endif
/********
@doc EXTERNAL IFAXOS DEBUG MACROS
@api BOOL | DEBUGCHK | Macro implementing an assert.
@parm <lt>c_exp<gt> | exp | Expression to be checked.
@rdesc Returns TRUE if the expression was non zero, and FALSE if not.
@comm This is a macro which implements functionality similar to the assert statement in C. The expression argument is evaluated, and no action is taken if it evaluates to true. If false, a debug message is printed out giving the File name and line number where the check failed, along with the module name which was registered in the <t DBGPARAM> structure. Because of this, you *must* register your debug settings using <f IFDbgSetParams> before you can use the DEBUGCHK macro. After this the function <f IFDbgCheck> is called to generate an assert.
This statement disappears when the DEBUG option is turned off.
@xref <f IFDbgCheck> ********/
#define BG_CHK(exp) \
((exp)?1:( \ IFDbgPrintf ("DEBUGCHK failed in file %s at line %d \r\n", \ (LPSTR) __FILE__ , __LINE__ ), 1 \ ))
#ifndef DEBUGCHK_UNSAFE_IN_WFWBG
#define DBGCHK(module,exp) \
((exp)?1:( \ IFDbgPrintf ("%s: DEBUGCHK failed in file %s at line %d \r\n", \ (LPSTR) module, (LPSTR) __FILE__ , __LINE__ ), \ IFDbgCheck() \ ))
#define DEBUGCHK(exp) DBGCHK(dpCurSettings.lpszName, exp)
#endif
/********
@doc EXTERNAL IFAXOS DEBUG MACROS
@api BOOL | DEBUGSTMT | Evaluates the expression in debug mode.
@parm <lt>c_exp<gt> | exp | Expression to be evaluated.
@rdesc Returns the value returned by the expression.
@comm This macro is provided for convenience and code readability purposes to replace a construct of the form
#ifdef DEBUG
exp; #endif
It evaluates to zero in a non debug build.
********/
#define DEBUGSTMT(exp) exp
#else // NOT DEBUG
// Let debugmsg's through currently
#ifndef SHIP_BUILD
//#ifndef FOOBAR
// Non DEBUG MODE
extern EXPORT_DLL VOID FAR CDECL IFDbgPrintf(LPSTR lpszFmt, ...); extern EXPORT_DLL BOOL WINAPI IFDbgCheck(VOID);
#ifndef WIN32
#define ERRORMSG(printf_exp) \
(IFProcEnterCritSec(), \ IFDbgPrintf("ERROR:(0x%04X):",GetCurrentTask()), \ IFDbgPrintf printf_exp ,\ IFProcExitCritSec(), \ 1) #define WARNINGMSG(printf_exp) \
(IFProcEnterCritSec(), \ IFDbgPrintf("WARNING:(0x%04X):",GetCurrentTask()), \ IFDbgPrintf printf_exp ,\ IFProcExitCritSec(), \ 1) #define RETAILMSG(printf_exp) (IFDbgPrintf printf_exp)
#else //Win32 -- NO MESSAGES OF ANY SORT IN NON-DEBUG WIN32
#define RETAILMSG(printf_exp) (0)
#define ERRORMSG(printf_exp) (0)
#define WARNINGMSG(printf_exp) (0)
#endif
#else
#define RETAILMSG(printf_exp) (0)
#define ERRORMSG(printf_exp) (0)
#define WARNINGMSG(printf_exp) (0)
#endif
// These are to macro out all debug stuff in retail/ship builds
#define DEBUGMSG(cond,expr) (0)
#define DBGCHK(module,exp) (0)
#define DEBUGCHK(exp) (0)
#define BG_CHK(exp) (0)
#define DEBUGSTMT(exp) (0)
// Macros for direct function calls made ..
#ifndef IFKINTERNAL
#define IFDbgOut(lpszStatus) (0)
#define IFDbgIn(lpszPrompt,lpszReply,wBufSize) (0)
#define IFDbgSetParams(lpdpParam,fEntry) (0)
#define DebugUIMessage(wMsg,wParam,lParam) (0)
#endif
#endif
/********
@doc EXTERNAL IFAXOS MACROS
@api BOOL | UIEVENT | Prints a status string in the UI
@parm LPSTR | string | String to be printed.
@comm This macro is provided in both the retail & debug builds to allow some limited set of status strings to be printed in the UI. You must format a string yourself - you can use wsprintf() to create a complex one if desired. The maximum string length allowed is 64 bytes. ********/ #define IF_SYS_EVENT IF_UI_START+1
// UI Event messages
#define UIEVENT(string) \
{ \ CHAR szUIShell[] = "UISHELL"; \ DEBUGCHK(lstrlen(string) < 64); \ PostMessage (IFProcGetInfo(NULL, szUIShell, NULL), IF_SYS_EVENT, \ NULL, MAKELPARAM(GlobalAddAtom(string),0)); \ }
// --------------- Synchronization services --------------------------------------
// Dont provide any for win32.
#ifndef WIN32
typedef struct _SYNC NEAR *HSYNC;
// Error returns
#define ERR_MUTEX_NOT_FREE ERR_FUNCTION_START
#define ERR_EVENT_NOT_FREE ERR_FUNCTION_START+1
#define ERR_TOO_MANY_EVENTWAITS ERR_FUNCTION_START+2
// generic functions
DWORD WINAPI WaitForSingleObject (HSYNC hsc, DWORD dwTime);
// Mutex functions
HSYNC WINAPI CreateMutex (LPVOID lpvAttribs, BOOL fInitial,LPSTR lpszName); BOOL WINAPI ReleaseMutex (HSYNC hsc);
// Event Functions
HSYNC WINAPI CreateEvent (LPVOID lpvAttribs, BOOL bManualReset, BOOL bInitialState, LPSTR lpszName);
BOOL WINAPI SetEvent (HSYNC hsc); BOOL WINAPI ResetEvent (HSYNC hsc); BOOL WINAPI FreeSyncObject (HSYNC hsc); BOOL WINAPI GetSetEventParam (HSYNC hsc, BOOL fSetParam, LPDWORD lpdwParam);
#else // !WIN32
DECLARE_HANDLE32(HSYNC);
#endif // !WIN32
/********
@doc EXTERNAL DEFINES ERROR IFAXOS
@type VOID | SYSTEM_MODULE_NAMES | Strings to be passed to IFProcGetInfo to get handles to standard IFAX modules
@emem MODNAME_UISHELL | UI Shell @emem MODNAME_MSCHED | Message Scheduler @emem MODNAME_MSGSVR | Message Server a.k.a. Message Transport
@xref <f IFProcGetInfo> ********/
// IFAX Module names
#define MODNAME_UISHELL "UISHELL"
#define MODNAME_MSCHED "MSCHED"
#define MODNAME_MSGSVR "MSGSVR"
// --------------- Timer Services -----------------------------------------
#ifndef WIN32
/********
@doc EXTERNAL IFAXOS MESSAGES TIMER
@msg IF_TIMER | This message is sent to notify a process of the expiration of a timer set using <f IFTimerSet>.
@parm WPARAM | wParam | Contains the timer id set int he <f IFTimerSet> call.
@parm LPARAM | lParam | Contains the lParam passed into the IFTimerSet call.
@rdesc none
@xref <f IFTimerSet> ********/
// messages
#define IF_TIMER IF_TIMER_START
// flags
#define TIME_ONESHOT 0
#define TIME_PERIODIC 1
// functions
VOID WINAPI IFProcSleep (WORD wSleepPeriod); WORD WINAPI IFTimerSet (HWND hwnd, WORD idTimer, WORD wTimeout, TIMERPROC tmprc, WORD wFlags, LPARAM lContext); BOOL WINAPI IFTimerKill (HWND hwnd, UINT idTimer);
#endif
// --------------- Global Pool Management ----------------------------------
/********
@doc EXTERNAL IFAXOS DEFINES GLOBMEM
@type VOID | STANDARD_BLOCK_SIZES | This defines all the standard global memory block sizes. As far as possible all memory allocations should be for one of these sizes. Any other size will be much more inefficient and couls cause fragmentation of system memory.
@emem ONLY_HEADER_SIZE| This will allocate a buffer with no data associated with it. This can be used to pass metadata between processes - eg an END_OF_JOB buffer marker.
@emem SMALL_HEADER_SIZE| This currently defines a 32 byte memory block. It is used for all buffer headers, and can be used for things like protocol headers, structure headers etc.
@emem COMPRESS_DATA_SIZE | This defines a 1Kb memory block which should be used to store any compressed data form. This is the general purpose data storage size. Any buffer which could be around for a long time should contain compressed data in this size of buffer.
@emem RAW_DATA_SIZE | This defines a large buffer size (currently 8Kb) for use by renderers as frame buffers. They should be used only to store raw bitmap data which is being sent directly to a consumer device like the printer. There are very few of these - so they should be used only for this short lived purpose.
@emem BAND_BUFFER_SIZE| This defines a jumbo buffer of 64K for use by the resource-based renderer. There may be only one such buffer in the global pool. (NOT IMPLEMENTED YET)
@xref <f IFMemAlloc> <f IFBufAlloc> ********/
// Std block sizes
#define ONLY_HEADER_SIZE 0 // No data
#define SMALL_HEADER_SIZE -1 // 32b
#define COMPRESS_DATA_SIZE -2 // 1Kb
//
#define RAW_DATA_SIZE -3 // 8Kb
// Special size for modem ECM frame
#define BYTE_265_SIZE -4 // 265 bytes
#define BYTE_265_ACTUALSIZE 265
// Number of sizes
#define MAX_POOL_INDEX -4 // For parameter validation
// Not available yet!
#define BAND_BUFFER_SIZE 30720 // 64Kb
// Flag to force global alloc. Uses a windows flag which is ignored/defunct in
// the 3.1 kernel (and the boss kernel)
#define IFMEM_USEGLOBALALLOC GMEM_NOT_BANKED
// Functions
extern LPVOID IFMemAlloc (UINT fuAlloc, LONG lAllocSize, LPWORD lpwActualSize); extern BOOL IFMemFree (LPVOID lpvMem);
/********
@doc EXTERNAL IFAXOS
@api HIPCMEM | IFMemGetIPCHandle | Returns an opaque 32 bit handle which is portable across process contexts.
@parm LPVOID | lpvMem | A ptr to global memory allocated using <f IFMemAlloc>.
@rdesc Opaque 32 bit none zero handle if succesfull. 0 if the memory ptr passed in is invalid.
@comm This function should be used by any DLL or process before trying to pass this memory to another process context. Only handles returned by this API should cross context boundaries, and the receiving context should call <f IFMemMapIPCHandle> to get back a valid memory ptr in its new context.
This applies even for DLL's which might allocate a piece of global memory and access it in different process contexts. They should use these functions to map them so that they are portable.
For Win16/IFAX implementations, this is essentially a NOP.
@xref <f IFMemAlloc> <f IFMemMapIPCHandle>
@type DWORD | HIPCMEM | Opaque 32 bit handle to global memory block.
@xref <f IFMemMapIPCHandle> <f IFMemGetIPCHandle> *********/ typedef DWORD HIPCMEM; #define IFMemGetIPCHandle(par1) ((HIPCMEM)par1)
/********
@doc EXTERNAL IFAXOS
@api DWORD | IFMemMapIPCHandle | Maps a piece of memory into the current tasks address space.
@parm HIPCMEM | hMemHandle | A memory handle returned from a call to <f IFMemGetIPCHandle> previously.
@rdesc Valid ptr to memory in the context of the calling process if succesful. NULL if it fails.
@comm See comments in <f IFMemMapIPCHandle>.
@xref <f IFMemAlloc> <f IFMemMapIPCHandle> *********/ #define IFMemMapIPCHandle(par1) ((LPVOID)par1)
// --------------- Time API's ----------------------------------------------
/********
@doc EXTERNAL IFAXOS SRVRDLL
@types SYSTEMTIME | Structure describing the time in terms of roman calendar.
@field WORD | wYear | The year @field WORD | wMonth | The month from 1-12 @field WORD | wDayOfWeek | Day of week with Sunday = 0 @field WORD | wDay | The day of the month, from 1-31 @field WORD | wHour | The hour from 0-23 @field WORD | wMinute | Minutes from 0-59 @field WORD | wSecond | Seconds from 0-50 @field WORD | wMilliseconds | Milliseconds from 0-99
@comm This is the format used for dislaying time to the user etc.
@xref <f SystemTimeToFileTime> <t FILETIME> <f FileTimeToSystemTime> ********/ #ifndef WIN32
typedef struct _SYSTEMTIME { WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds; } SYSTEMTIME, FAR *LPSYSTEMTIME;
#endif
/********
@doc EXTERNAL IFAXOS
@types FILETIME | Structure used to store time internally and for mathematical operations.
@field DWORD | dwLowDateTime | Low 32 bits of the time.
@field DWORD | dwHighDateTime | High 32 bits of the time.
@comm Absolute time in IFAX is represented by a 64-bit large integer accurate to 100ns resolution. The smallest time resolution used by this package is One millisecond. The basis for this time is the start of 1601 which was chosen because it is the start of a new quadricentury. Some facts to note are:
o At 100ns resolution 32 bits is good for about 429 seconds (or 7 minutes)
o At 100ns resolution a large integer (i.e., 63 bits) is good for about 29,247 years, or around 10,682,247 days.
o At 1 second resolution 31 bits is good for about 68 years
o At 1 second resolution 32 bits is good for about 136 years
o 100ns Time (ignoring time less than a millisecond) can be expressed as two values, Days and Milliseconds. Where Days is the number of whole days and Milliseconds is the number of milliseconds for the partial day. Both of these values are ULONG.
@xref <f SystemTimeToFileTime> <t SYSTEMTIME> <f FileTimeToSystemTime> ********/ #ifndef WIN32
// If sos property.h has been included this will cause a redefinition
#ifndef PROPERTY_H
#ifndef _FILETIME_
#define _FILETIME_
typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME, FAR *LPFILETIME;
#endif // _FILETIME_
#endif // Property_H
BOOL WINAPI FileTimeToSystemTime(LPFILETIME lpTime,LPSYSTEMTIME lpTimeFields);
BOOL WINAPI SystemTimeToFileTime(LPSYSTEMTIME lpTimeFields,LPFILETIME lpTime);
BOOL WINAPI FileTimeToLocalFileTime(LPFILETIME lpft, LPFILETIME lpftLocal);
BOOL WINAPI LocalFileTimeToFileTime(LPFILETIME lpftLocal, LPFILETIME lpft);
BOOL WINAPI SetLocalTime(LPSYSTEMTIME lpstLocal);
VOID WINAPI GetLocalTime(LPSYSTEMTIME lpstLocal); #endif // Win32
// --------------- NVRAM API's ----------------------------------------------
typedef struct ERRORLOGPOINTER { WORD wNextEntryPtr ; WORD wNumEntries ; } ERRORLOGPOINTER , FAR * LPERRORLOGPOINTER ;
#define MAX_ERRORLOG_ENTRIES 30
#define MAX_OEMERRBUF_SIZE 16
/********
@doc EXTERNAL IFAXOS
@types ERRORLOGENTRY | Used to store Log Entries.
@field DWORD | dwErrorCode | This is the IFAX error code corresponding to the error being retrieved. See <f IFErrAssemble> for details of the format of this dword.
@field DWORD | dwTimeStamp | The time at which this error was logged into NVRam. The various fields are: @flag Bits 0-4 | Second divided by 2 @flag Bits 5-10| Minute (0-59) @flag Bits 11-15 | Hour (0-23 on a 24 hour clock) @flag Bits 16-20 | Day of the month (1-31) @flag Bits 21-24 | Month (1 = January, 2 = February, etc.) @flag Bits 25-31 | Year offset from COUNTER_YEAR_OFFSET (add COUNTER_YEAR_OFFSET to get actual year)
@field CHAR | oemErrBuf | The buffer in which the application specific custom data/extended error corresponding to this error is retrieved.
@comm Used as a parameter to IFNvramGetError. This will typically be used for diagnostic functions.
@xref <f IFNvramGetError> ********/
#define COUNTER_YEAR_OFFSET (1970)
typedef struct tagERRORLOGENTRY { DWORD dwErrorCode; DWORD dwTimeStamp; char oemErrBuf[MAX_OEMERRBUF_SIZE]; } ERRORLOGENTRY, FAR *LPERRORLOGENTRY;
typedef DWORD ERRORLOGSENTINEL , FAR * LPERRORLOGSENTINEL ;
// Set to the current version number (12.19)
#define SENTINEL_SET 0x00000C13UL
#define MAX_COUNTERS 30
#define OEM_NVRAM_COUNTER_START 12
// Special system counter which indicates the # of times the machine has rebooted
// It is a 4 byte counter with a timestamp
// If this value is 1 then this is the first time the machine has ever been rebooted.
// - This value cannot be set by any user application!
#define BOOT_COUNTER 0
// specific counter numbers assigned for various logical counters
#define TXCALL_COUNTER 1
#define RXCALL_COUNTER 2
// ****************************************************************************
//
// An HHSOS owned counter.
// This is the number of bad boots we have suffered (meaning the HHSOS could not
// successfully init). When this number gets too big, we stop trying to init.
// This will cause AWCHKSOS to alert the user of the problem.
//
#define BAD_BOOTS_COUNTER 3
//
// ****************************************************************************
// These values for wFlags (in IFSetCounterValue) - some are mutually exclusive
// If CLEARSET is set the value is cleared before being added - otherwise it is just added
// Currently you cannot request a double long and a timestamp
// For now the interrupt has no context but in the future it might be useful
#define COUNTER_CLEARSET 0x0001
#define COUNTER_DOUBLE_LONG 0x0002
#define COUNTER_UPDATE_TIMESTAMP 0x0004
#define COUNTER_INTERRUPT_CONTEXT 0x1000
// Only here temporarily until everything gets moved to new values
#define COUNTER_VALUESET (COUNTER_CLEARSET | COUNTER_UPDATE_TIMESTAMP)
#define COUNTER_ADDVALUE 0x0100
#define COUNTER_TIMESTAMP 0x0200
#define COUNTER_NOTIMESTAMP COUNTER_DOUBLE_LONG
#define PROCESS_CONTEXT 0x0300
#define INTERRUPT_CONTEXT COUNTER_INTERRUPT_CONTEXT
/********
@doc EXTERNAL IFAXOS
@types COUNTERENTRY | Used to store 4 and 8 byte Counters.
@field DWORD | dwCounterVal1 | For a 4 byte counter, the value of the counter. For an 8 byte counter, the low order 4 bytes of the value of the counter.
@field DWORD | dwTimeStamp | For a 4 byte counter, the time at which the counter was last reset. The fields in the timestamp are: @flag Bits 0-4 | Second divided by 2 @flag Bits 5-10| Minute (0-59) @flag Bits 11-15 | Hour (0-23 on a 24 hour clock) @flag Bits 16-20 | Day of the month (1-31) @flag Bits 21-24 | Month (1 = January, 2 = February, etc.) @flag Bits 25-31 | Year offset from 1980 (add 1980 to get actual year)
For an 8 byte counter, dwTimeStamp is the high order 4 bytes of the counter value.
@comm Used by the IFNvramGetCounterValue function.
@xref <f IFNvramGetCounterValue> ********/ typedef struct tagCOUNTERENTRY { DWORD dwCounterVal1; DWORD dwTimeStamp; } COUNTERENTRY, FAR *LPCOUNTERENTRY;
//-------------------------- Prototypes ----------------------------------
#if defined(WFW) || defined(WIN32)
#define IFNvramSetError(dw,lpb,w) (0)
#define IFNvramSetErrorInterrupt(dw,lpb,w) (0)
#define IFNvramGetError(lperrlog,lpwMaxEntries) (0)
#define IFNvramSetCounterValue(p1,p2,p3,p4) (0)
#define IFNvramGetCounterValue(w1,lpentry) (0)
#define IFNvramAllocScratchBuf(wSize) (NULL)
#else
BOOL WINAPI IFNvramSetError(DWORD, LPBYTE, WORD); BOOL WINAPI IFNvramSetErrorInterrupt(DWORD, LPBYTE, WORD); BOOL FAR CDECL IFNvramvSetError(DWORD dwError,WORD nErrs,...) ; BOOL WINAPI IFNvramGetError(LPERRORLOGENTRY lperrlog,LPWORD lpwMaxEntries) ; BOOL WINAPI IFNvramSetCounterValue(WORD, DWORD, DWORD, WORD); BOOL WINAPI IFNvramGetCounterValue(WORD, LPCOUNTERENTRY); BOOL WINAPI IFNvramFlushToFileLog(VOID) ; BOOL WINAPI IFNvramInitFileLog(VOID) ; LPBYTE WINAPI IFNvramAllocScratchBuf(WORD wSize);
#endif
/********
@doc EXTERNAL IFAXOS
@api BOOL | _lflush | Flushes all pending writes to a file handle.
@parm HFILE | hf | A file handle obtained from _lopen or OpenFile
@rdesc Returns TRUE for success, FALSE for failure.
@comm This function will flush all pending writes to disk.
For Win16 implementations, this currently always fails. *********/
BOOL WINAPI _lflush(HFILE hf);
// the following is for service messages
#define IF_ST_END_SOSBK (IF_SERVICE_START+0)
#define IF_ST_END_SOSRST (IF_SERVICE_START+1)
#ifdef __cplusplus
} // extern "C" {
#endif
#endif // _INC_IFAXOS
|