*CWDShow >struct 021ea954 id = 0 tskhdl = 7cc020f8 taskname TaskWindow mode solicited fsname ADFS fsnum 8 CSD pathwsf 022909ec <> resofpath 00000000 specialfield 00000000 PSD pathwsf 02290afc <> resofpath 00000000 specialfield 00000000 URD pathwsf 02290c0c <> resofpath 00000000 specialfield 00000000 Lib pathwsf 02290d1c <> resofpath 00000000 specialfield 00000000 registered vars none struct 021f1fe4 id = 1 tskhdl = 7d402100 taskname Alarm mode unsolicited fsname ADFS fsnum 8 CSD pathwsf 0228ec7c <> resofpath 00000000 specialfield 00000000 PSD pathwsf 0228ed8c <> resofpath 00000000 specialfield 00000000 URD pathwsf 0228ee9c <> resofpath 00000000 specialfield 00000000 Lib pathwsf 0228efac <> resofpath 00000000 specialfield 00000000 registered vars name <Alarm$Path> exists Y vartype <0> value <Choices:Alarm.,Resources:$.Apps.!Alarm.,Resources:$.Resources.Alarm.>
The task from which the CWDShow command was issued is marked with a '>' sign at the beginning of the line. Here we find out that the Alarm task (actually the Acorn Alarm application) was registered by using the CWDRegisterCatch Alarm$Path command.
/* This function is a copy routine relevant to FS setting contexts * as managed from inside the module */ static void ctx_cpy(tpathelm *pdest, const tpathelm *psrc) { const ptrdiff_t moff= (char *) pdest - (char *) psrc; strcpy(pdest->pathwithsf, psrc->pathwithsf); pdest->restofpath= psrc->restofpath ? (psrc->restofpath + moff) : NULL; pdest->specialfield= psrc->specialfield ? (psrc->specialfield + moff) : NULL; } static _kernel_oserror *mswp(tfspath *mpt, BOOL getonly, size_t ipath) { _kernel_oserror *p; _kernel_swi_regs r; tpathelm *mptelm= &(mpt->mpaths[ipath]), lelm; /* Read current setting into the lelm struct */ r.r[0]= 54; r.r[1]= (int) &(lelm.pathwithsf); r.r[2]= ipath; r.r[3]= (int) &(mpt->fsname); r.r[5]= sizeof(lelm.pathwithsf); p= osfscontrol(&r); if(p) return p; lelm.pathwithsf[sizeof(lelm.pathwithsf)-r.r[5]]= '\0'; lelm.restofpath= (char *) r.r[1]; lelm.specialfield= (char *) r.r[6]; if(!getonly) { /* Set the current setting from struct pointed by mptelm */ r.r[0]= 53; r.r[1]= (int) mptelm->restofpath; r.r[2]= ipath; r.r[3]= (int) &(mpt->fsname); r.r[6]= (int) mptelm->specialfield; p= osfscontrol(&r); } ctx_cpy(mptelm, &lelm); return p; } /* Swap the FS setting between the task context and the * global context */ _kernel_oserror *setting_switch(ttask *pt, BOOL getonly) { _kernel_oserror *p; _kernel_swi_regs r; struct MinNode *pw; tfspath *mpt; int ipath, curfsnumber= gettempfsnumber(&p); if(p) return p; if(curfsnumber!= pt->fsnumber) { if(!getonly) { r.r[0]= 14; /* Set the current file system */ r.r[1]= pt->fsnumber; p= osfscontrol(&r); } pt->fsnumber= curfsnumber; if(p) return p; } /* Browse through the list of FS known to the task */ for(pw= pt->malfs.mlh_Head; pw->mln_Succ; pw= pw->mln_Succ) { mpt= (tfspath *) ((char *) pw - offsetof(tfspath, mnode)); for(ipath= 0; ipath < NPATHS; ipath++) { p= mswp(mpt, getonly, ipath); if(p) return p; } } return p; } int post_filter_handler(_kernel_swi_regs *pr, void *pw) { ttask *lgpt; if(pr->r[0] == -1) return 1; lgpt= FindTask(pr->r[2], TRUE); if(lgpt == NULL) return 1; gpt= lgpt; post_filt_varjob(lgpt); /* process system variables */ (void) setting_switch(lgpt, FALSE); /* process FS settings */ bact= TRUE; return 1; } int pre_filter_handler(_kernel_swi_regs *pr, void *pw) { ttask *lgpt= FindTask(pr->r[2], TRUE); if(!lgpt) return 1; gpt= NULL; bact= FALSE; validate_and_unify(lgpt); /* manage new FS discoveries */ pre_filt_varjob(lgpt); /* process system variables */ (void) setting_switch(lgpt, FALSE); /* process FS settings */ return 1; }
Another implementation difference from the FS handling is that the allocation of memory for individual variable values is dynamic and thus is able to deal with system variables of type code (which can be of any lengh). The CWDRegVar and CWDRegisterCatch accept patterns in the parameter specification and scans the current system variable setting (just like the Show command) for variable names which satisfies the pattern.
This is not so for the CWDUnregVar which does'nt accept wild chars as parameters.
The latter implies the creation of a post-poll filter for all tasks but with a mask filtering all Wimp events but Wimp_UserMessage and Wimp_UserMessageRecorded.
As such an event occurs, the module is only insterested in message with an action code set to Wimp_MTaskInitialise. As soon as a message of that kind is detected, then the post-filter is removed. Below is the code which illustrates the mechanism.
static BOOL bglob; static char lbuf[256]; static int largc; ... static _kernel_oserror *set_filter( BOOL mount, void *pw) { extern int post_generic( _kernel_swi_regs *, void *); static const int filter_mask = ~(Wimp_Poll_UserMessageMask | Wimp_Poll_UserMessageRecordedMask); static const char fname[]= "CWDcatch"; _kernel_swi_regs r; _kernel_oserror *p; r.r[0]= (int) fname; r.r[1]= (int) post_generic; r.r[2]= (int) pw; /* pw */ r.r[3]= 0; r.r[4]= filter_mask; p= _kernel_swi(mount ? Filter_RegisterPostFilter : Filter_DeRegisterPostFilter, &r, &r); if(!p) bglob= mount; return p; } ... int post_generic_handler( _kernel_swi_regs *pr, void *pw) { WimpUserMessageEvent *pum; ttask *pt; pum= (WimpUserMessageEvent *) pr->r[1]; if(pum->hdr.action_code == Wimp_MTaskInitialise) { pt= sNewtask(pum->hdr.sender, TRUE, pw, NULL); if(pt && largc > 0) traite_insert_strings(lbuf, pt, FALSE, largc); (void) set_filter(FALSE, pw); } return 1; } _kernel_oserror *regcatch_next( void *pw, const char *str, int argc) { _kernel_oserror *p; p= bglob ? NULL : set_filter(TRUE, pw); if(!p) { /* copy arg string to static buffer for future use */ largc= argc; strncpy(lbuf, str, sizeof(lbuf) -1); } return p; }The regcatch_next function is called as part of the CWDRegisterCatch command handling by the module.
As a companion utility, you can download the SYSCSD archive which makes the CLI prompt display the current FS and CSD (just by issuing the command *SetMacro CLI$Prompt <Sys$CSD> * after having run the SysCSD03 utility).
!AAsm source code is included in the archive so that you can check by yourself it is not a virus.