home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
mswindws
/
journ201.arc
/
JOURNAL.C
< prev
next >
Wrap
Text File
|
1988-02-23
|
12KB
|
362 lines
/******************************************************************************
*
* JOURNAL.C Journal records and plays back Windows input along with the
* associated timing information. The following keys are used
* to control Journal:
*
* F7 Remove Journal from core
* F8 Prompt for a save file and begin recording
* F9 Stop recording and close the save file
* F10 Prompt for a save file and replay it
*
* This is a modified version of the original Journal program uploaded
* by Microsoft. Most of the information relating to the journalling
* filter functions was obtained by dissassembling the Windows 1.04
* kernel, and will probably change in the next version of Windows.
*
* Modified by Daniel Smith Aug 18 1987
* Golden Software
* 807 14th Street
* Golden, Colorado 80401
*
* Modified for Windows 2.01 Feb 23 1988
*
* This code will only work under Windows 2.01 or possibly higher.
* It will NOT work with Windows 1.x since all the callback function
* arguments have changed.
*
******************************************************************************/
#include <windows.h>
#include <winexp.h>
#include <direct.h>
#include <string.h>
#include "journal.h"
#define CEVENTSMAX 500 /* Number of events to buffer */
typedef struct { /* Structure stored and saved */
unsigned message; /* during record and playback */
WORD wParam1;
WORD wParam2;
long dt;
} EVENT;
/* Function declarations */
int PASCAL WinMain(HANDLE,HANDLE,LPSTR,int);
void ProcessCmd(WORD);
int FAR PASCAL KeyHook(WORD,WORD,long);
void FAR PASCAL Record(WORD,WORD,EVENT FAR *);
DWORD FAR PASCAL Playback(WORD,WORD,EVENT FAR *);
BOOL FAR PASCAL Dlgfn(HWND,unsigned,WORD,long);
int WriteBuf(void);
int ReadBuf(void);
void Error(char *,char *);
char FileName[60]; /* File to read and store events */
long nbytesread;
int bCmdLine; /* True if a command line was entered */
BOOL fTurbo; /* TRUE if in turbo mode */
HANDLE hJournalTask; /* Task handle for this program */
HANDLE hInst;
FARPROC lpfnKeyHook,lpfnKeyNext; /* Keyboard hook for command keys */
FARPROC lpfnRecord,lpfnRecordNext; /* Journal hook for recording */
FARPROC lpfnPlayback,lpfnPlaybackNext; /* Journal hook for playing back */
FARPROC lpfnDlg;
BOOL fFirstRead;
DWORD timeLastRead;
EVENT *pevtRead,*pevtWrite;
EVENT *pevtReadStop;
BOOL fFirstWrite;
DWORD timeLastWrite;
EVENT rgevtJournal[CEVENTSMAX]; /* Buffer for events */
/******************************************************************************
*
* Main window function for journal
*
******************************************************************************/
int PASCAL WinMain(hInstance,hPrevInstance,CmdLine,CmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR CmdLine;
int CmdShow;
{
MSG msg;
bCmdLine = *CmdLine;
if(hPrevInstance && !bCmdLine) return(0);
if(bCmdLine) lstrcpy(FileName,CmdLine);
hInst = hInstance;
hJournalTask = GetCurrentTask();
fTurbo = FALSE;
lpfnDlg = MakeProcInstance((FARPROC)Dlgfn,hInstance);
lpfnRecord = MakeProcInstance((FARPROC)Record,hInstance);
lpfnPlayback = MakeProcInstance((FARPROC)Playback,hInstance);
lpfnKeyHook = MakeProcInstance((FARPROC)KeyHook,hInstance);
lpfnKeyNext = SetWindowsHook(WH_KEYBOARD,lpfnKeyHook);
/* If program was started with a file name, assume it is a */
/* previously created save file, and pass it on to the */
/* playback code in the main loop. */
if(bCmdLine) PostAppMessage(hJournalTask,WM_COMMAND,VK_F10,0L);
while(GetMessage(&msg,0,0,0)){
if(msg.message == WM_COMMAND) ProcessCmd(msg.wParam);
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return(msg.wParam);
}
/******************************************************************************
*
* Handles all WM_COMMAND messages sent to the application.
*
******************************************************************************/
void ProcessCmd(cmd)
WORD cmd;
{
int fh;
switch(cmd){
/* Prompt for save filename and start recording */
case VK_F8:
if(pevtRead==0 && pevtWrite==0){
if(DialogBox(hInst,MAKEINTRESOURCE(1),0,lpfnDlg)){
if((fh = _lcreat((LPSTR)FileName,0)) == -1)
Error("Journal Record","Unable to create file");
else {
pevtWrite = &rgevtJournal[0];
fFirstWrite = TRUE;
lpfnRecordNext = SetWindowsHook(WH_JOURNALRECORD,lpfnRecord);
}
}
}
break;
/* Stop recording and close save file */
case VK_F9:
if(pevtWrite != 0){ /* Ignore if not recording */
WriteBuf();
pevtWrite = 0;
SetWindowsHook(WH_JOURNALRECORD,0L);
}
break;
/* Prompt for save filename and playback events */
case VK_F10:
if(pevtRead==0 && pevtWrite==0){
nbytesread = 0;
fFirstRead = TRUE;
if(bCmdLine || DialogBox(hInst,MAKEINTRESOURCE(2),0,lpfnDlg)){
if(ReadBuf()){
pevtRead = &rgevtJournal[0];
lpfnPlaybackNext = SetWindowsHook(WH_JOURNALPLAYBACK,lpfnPlayback);
}
}
}
break;
/* Remove hooks and terminate */
case VK_F7:
SetWindowsHook(WH_KEYBOARD,0L);
PostQuitMessage(0);
break;
}
}
/******************************************************************************
*
* Intercepts command keys from any application and sends the appropriate
* command to this application.
*
******************************************************************************/
int FAR PASCAL KeyHook(code,wParam,lParam)
WORD code,wParam;
LONG lParam;
{
if(HIWORD(lParam) & 0x8000){ /* Up transition of key */
switch(wParam){
case VK_F8:
case VK_F9:
case VK_F10:
case VK_F7:
PostAppMessage(hJournalTask,WM_COMMAND,wParam,0L);
return(1);
}
}
return(0);
}
/******************************************************************************
*
* Filter function to record all input events and save in a file
*
******************************************************************************/
void FAR PASCAL Record(dum1,dum2,lpevt)
WORD dum1,dum2;
EVENT FAR *lpevt;
{
int fh;
if(pevtWrite >= &rgevtJournal[CEVENTSMAX]){
if(!WriteBuf()){
SetWindowsHook(WH_JOURNALRECORD,0L);
pevtWrite = 0;
return;
}
}
*pevtWrite = *lpevt;
if(fFirstWrite){
fFirstWrite = FALSE;
timeLastWrite = pevtWrite->dt;
}
pevtWrite->dt -= timeLastWrite; /* Map to delta time */
timeLastWrite = lpevt->dt; /* Remember time of last write */
pevtWrite++;
}
/******************************************************************************
*
* Filter function to insert an event into the Windows system queue
*
******************************************************************************/
DWORD FAR PASCAL Playback(code,lotime,lpevt)
WORD code,lotime;
EVENT FAR *lpevt;
{
long dt;
switch(code){
case 1: /* Called from GetNextSysMsg */
if(fFirstRead){ /* Save current start time */
timeLastRead = lpevt->dt;
fFirstRead = FALSE;
}
dt = pevtRead->dt - (lpevt->dt - timeLastRead);
*lpevt = *pevtRead; /* Copy event to Windows buffer */
if(!fTurbo && dt>0) return(dt); /* Not ready yet: return time left */
lpevt->dt += timeLastRead; /* Convert relative to absolute time */
return(0L); /* Time to process event */
break;
case 2: /* Called from SkipSysMsg */
timeLastRead += pevtRead->dt; /* Update current time */
pevtRead++; /* Point to next event */
if(pevtRead == pevtReadStop){ /* End of stored events */
if(ReadBuf()){
pevtRead = &rgevtJournal[0];
} else {
pevtRead = 0;
SetWindowsHook(WH_JOURNALPLAYBACK,0L);
if(bCmdLine)
PostAppMessage(hJournalTask,WM_COMMAND,VK_F7,0L);
}
}
return(0L); /* Not used by this function call */
break;
default:
Error("Journal Playback", "Unknown code");
return(0L);
}
}
/******************************************************************************
*
* Handles the open and save dialog boxes for journal.
*
******************************************************************************/
BOOL FAR PASCAL Dlgfn(hDlg,message,wParam,lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
char tempbuf[49];
if(message == WM_COMMAND){ /* If OK was pressed */
if(wParam==IDOK || wParam==IDTURBO){
GetDlgItemText(hDlg,IDCONST,FileName,30);
getcwd(tempbuf,49);
if(tempbuf[strlen(tempbuf)-1] != '\\') lstrcat(tempbuf,"\\");
lstrcat(tempbuf,FileName);
lstrcpy(FileName,tempbuf);
fTurbo = (wParam == IDTURBO);
EndDialog(hDlg,TRUE);
return(TRUE);
}
if(wParam == IDCANCEL){
EndDialog(hDlg,FALSE);
return(TRUE);
}
} else if(message == WM_INITDIALOG) return(TRUE);
else return(FALSE);
}
/******************************************************************************
*
* Writes the event buffer to the disk file
*
******************************************************************************/
int WriteBuf()
{
int fh;
if((fh = _lopen(FileName,READ_WRITE)) == -1){
Error("Journal Record","Unable to open file");
return(0);
}
_llseek(fh,0L,2); /* Go to end of file... */
_lwrite(fh,(LPSTR)&rgevtJournal[0],
(pevtWrite-&rgevtJournal[0])*sizeof(EVENT));
_lclose(fh);
pevtWrite = &rgevtJournal[0];
return(1);
}
/******************************************************************************
*
* Fills the event buffer from the playback file
*
******************************************************************************/
int ReadBuf()
{
int fh,nbr;
if((fh = _lopen(FileName,READ)) != -1){
nbytesread = _llseek(fh,(LONG)nbytesread,0);
nbr = _lread(fh,(LPSTR)&rgevtJournal[0],CEVENTSMAX*sizeof(EVENT));
_lclose(fh);
if(nbr == -1) goto error;
pevtReadStop = &rgevtJournal[nbr/sizeof(EVENT)]; /* One beyond last */
nbytesread += nbr;
return(nbr);
}
error:
Error("Journal Playback","Unable to Read File");
return(0);
}
/******************************************************************************
*
* Displays an error message in a message box
*
******************************************************************************/
void Error(pszcap,pszmsg)
char *pszcap;
char *pszmsg;
{
MessageBox(0,pszmsg,pszcap,MB_SYSTEMMODAL | MB_OK | MB_ICONEXCLAMATION);
}